summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pimd/pim6_stubs.c37
-rw-r--r--pimd/pim_register.c135
-rw-r--r--pimd/subdir.am2
3 files changed, 120 insertions, 54 deletions
diff --git a/pimd/pim6_stubs.c b/pimd/pim6_stubs.c
index cf61685fb1..f799f04f33 100644
--- a/pimd/pim6_stubs.c
+++ b/pimd/pim6_stubs.c
@@ -37,21 +37,6 @@ void pim_nht_bsr_del(struct pim_instance *pim, struct in_addr addr)
{
}
-/*
- * PIM register
- */
-void pim_register_join(struct pim_upstream *up)
-{
-}
-
-void pim_null_register_send(struct pim_upstream *up)
-{
-}
-
-void pim_reg_del_on_couldreg_fail(struct interface *ifp)
-{
-}
-
bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
{
return false;
@@ -80,25 +65,3 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
{
return 0;
}
-
-void pim_register_send(const uint8_t *buf, int buf_size, pim_addr src,
- struct pim_rpf *rpg, int null_register,
- struct pim_upstream *up)
-{
-}
-
-void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg, pim_addr src,
- pim_addr originator)
-{
-}
-
-int pim_register_recv(struct interface *ifp, pim_addr dest_addr,
- pim_addr src_addr, uint8_t *tlv_buf, int tlv_buf_size)
-{
- return 0;
-}
-
-int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)
-{
- return 0;
-}
diff --git a/pimd/pim_register.c b/pimd/pim_register.c
index 45bcad3c26..fef5339749 100644
--- a/pimd/pim_register.c
+++ b/pimd/pim_register.c
@@ -44,6 +44,7 @@
#include "pim_util.h"
#include "pim_ssm.h"
#include "pim_vxlan.h"
+#include "pim_addr.h"
struct thread *send_test_packet_timer = NULL;
@@ -64,8 +65,8 @@ void pim_register_join(struct pim_upstream *up)
pim_vxlan_update_sg_reg_state(pim, up, true);
}
-void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg,
- struct in_addr src, struct in_addr originator)
+void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg, pim_addr src,
+ pim_addr originator)
{
struct pim_interface *pinfo;
unsigned char buffer[10000];
@@ -74,7 +75,7 @@ void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg,
uint8_t *b1;
if (PIM_DEBUG_PIM_REG) {
- zlog_debug("Sending Register stop for %pSG to %pI4 on %s", sg,
+ zlog_debug("Sending Register stop for %pSG to %pPA on %s", sg,
&originator, ifp->name);
}
@@ -218,7 +219,7 @@ int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)
return 0;
}
-void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
+void pim_register_send(const uint8_t *buf, int buf_size, pim_addr src,
struct pim_rpf *rpg, int null_register,
struct pim_upstream *up)
{
@@ -226,11 +227,11 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
unsigned char *b1;
struct pim_interface *pinfo;
struct interface *ifp;
+ pim_addr dst = pim_addr_from_prefix(&rpg->rpf_addr);
if (PIM_DEBUG_PIM_REG) {
- zlog_debug("Sending %s %sRegister Packet to %pI4", up->sg_str,
- null_register ? "NULL " : "",
- &rpg->rpf_addr.u.prefix4);
+ zlog_debug("Sending %s %sRegister Packet to %pPA", up->sg_str,
+ null_register ? "NULL " : "", &dst);
}
ifp = rpg->source_nexthop.interface;
@@ -250,9 +251,9 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
}
if (PIM_DEBUG_PIM_REG) {
- zlog_debug("%s: Sending %s %sRegister Packet to %pI4 on %s",
+ zlog_debug("%s: Sending %s %sRegister Packet to %pPA on %s",
__func__, up->sg_str, null_register ? "NULL " : "",
- &rpg->rpf_addr.u.prefix4, ifp->name);
+ &dst, ifp->name);
}
memset(buffer, 0, 10000);
@@ -262,14 +263,13 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
memcpy(b1, (const unsigned char *)buf, buf_size);
- pim_msg_build_header(src, rpg->rpf_addr.u.prefix4, buffer,
- buf_size + PIM_MSG_REGISTER_LEN,
+ pim_msg_build_header(src, dst, buffer, buf_size + PIM_MSG_REGISTER_LEN,
PIM_MSG_TYPE_REGISTER, false);
++pinfo->pim_ifstat_reg_send;
- if (pim_msg_send(pinfo->pim_sock_fd, src, rpg->rpf_addr.u.prefix4,
- buffer, buf_size + PIM_MSG_REGISTER_LEN, ifp->name)) {
+ if (pim_msg_send(pinfo->pim_sock_fd, src, dst, buffer,
+ buf_size + PIM_MSG_REGISTER_LEN, ifp->name)) {
if (PIM_DEBUG_PIM_TRACE) {
zlog_debug(
"%s: could not send PIM register message on interface %s",
@@ -279,12 +279,13 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
}
}
+#if PIM_IPV == 4
void pim_null_register_send(struct pim_upstream *up)
{
struct ip ip_hdr;
struct pim_interface *pim_ifp;
struct pim_rpf *rpg;
- struct in_addr src;
+ pim_addr src;
pim_ifp = up->rpf.source_nexthop.interface->info;
if (!pim_ifp) {
@@ -323,9 +324,71 @@ void pim_null_register_send(struct pim_upstream *up)
return;
}
}
- pim_register_send((uint8_t *)&ip_hdr, sizeof(struct ip),
- src, rpg, 1, up);
+ pim_register_send((uint8_t *)&ip_hdr, sizeof(struct ip), src, rpg, 1,
+ up);
}
+#else
+void pim_null_register_send(struct pim_upstream *up)
+{
+ struct ip6_hdr ip6_hdr;
+ struct pim_msg_header pim_msg_header;
+ struct pim_interface *pim_ifp;
+ struct pim_rpf *rpg;
+ pim_addr src;
+ unsigned char buffer[sizeof(ip6_hdr) + sizeof(pim_msg_header)];
+ struct ipv6_ph ph;
+
+ pim_ifp = up->rpf.source_nexthop.interface->info;
+ if (!pim_ifp) {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug(
+ "Cannot send null-register for %s no valid iif",
+ up->sg_str);
+ return;
+ }
+
+ rpg = RP(pim_ifp->pim, up->sg.grp);
+ if (!rpg) {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug(
+ "Cannot send null-register for %s no RPF to the RP",
+ up->sg_str);
+ return;
+ }
+
+ memset(&ip6_hdr, 0, sizeof(ip6_hdr));
+ ip6_hdr.ip6_nxt = PIM_IP_PROTO_PIM;
+ ip6_hdr.ip6_plen = PIM_MSG_HEADER_LEN;
+ ip6_hdr.ip6_vfc = 6 << 4;
+ ip6_hdr.ip6_hlim = MAXTTL;
+ ip6_hdr.ip6_src = up->sg.src;
+ ip6_hdr.ip6_dst = up->sg.grp;
+
+ memset(buffer, 0, (sizeof(ip6_hdr) + sizeof(pim_msg_header)));
+ memcpy(buffer, &ip6_hdr, sizeof(ip6_hdr));
+
+ pim_msg_header.ver = 0;
+ pim_msg_header.type = 0;
+ pim_msg_header.reserved = 0;
+
+ pim_msg_header.checksum = 0;
+
+ ph.src = up->sg.src;
+ ph.dst = up->sg.grp;
+ ph.ulpl = htonl(PIM_MSG_HEADER_LEN);
+ ph.next_hdr = IPPROTO_PIM;
+ pim_msg_header.checksum =
+ in_cksum_with_ph6(&ph, &pim_msg_header, PIM_MSG_HEADER_LEN);
+
+ memcpy(buffer + sizeof(ip6_hdr), &pim_msg_header, PIM_MSG_HEADER_LEN);
+
+
+ src = pim_ifp->primary_address;
+ pim_register_send((uint8_t *)buffer,
+ sizeof(ip6_hdr) + PIM_MSG_HEADER_LEN, src, rpg, 1,
+ up);
+}
+#endif
/*
* 4.4.2 Receiving Register Messages at the RP
@@ -425,6 +488,46 @@ int pim_register_recv(struct interface *ifp, pim_addr dest_addr,
memset(&sg, 0, sizeof(sg));
sg = pim_sgaddr_from_iphdr(ip_hdr);
+#if PIM_IPV == 6
+ /*
+ * According to RFC section 4.9.3, If Dummy PIM Header is included
+ * in NULL Register as a payload there would be two PIM headers.
+ * The inner PIM Header's checksum field should also be validated
+ * in addition to the outer PIM Header's checksum. Validation of
+ * inner PIM header checksum is done here.
+ */
+ if ((*bits & PIM_REGISTER_NR_BIT) &&
+ ((tlv_buf_size - PIM_MSG_REGISTER_BIT_RESERVED_LEN) >
+ (int)sizeof(struct ip6_hdr))) {
+ uint16_t computed_checksum;
+ uint16_t received_checksum;
+ struct ipv6_ph ph;
+ struct pim_msg_header *header;
+
+ header = (struct pim_msg_header
+ *)(tlv_buf +
+ PIM_MSG_REGISTER_BIT_RESERVED_LEN +
+ sizeof(struct ip6_hdr));
+ ph.src = sg.src;
+ ph.dst = sg.grp;
+ ph.ulpl = htonl(PIM_MSG_HEADER_LEN);
+ ph.next_hdr = IPPROTO_PIM;
+
+ received_checksum = header->checksum;
+
+ header->checksum = 0;
+ computed_checksum = in_cksum_with_ph6(
+ &ph, header, htonl(PIM_MSG_HEADER_LEN));
+
+ if (computed_checksum != received_checksum) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "Ignoring Null Register message%pSG from %pPA due to bad checksum in Encapsulated dummy PIM header",
+ &sg, &src_addr);
+ return 0;
+ }
+ }
+#endif
i_am_rp = I_am_RP(pim, sg.grp);
if (PIM_DEBUG_PIM_REG)
diff --git a/pimd/subdir.am b/pimd/subdir.am
index 41fc6dc632..9dd6961d92 100644
--- a/pimd/subdir.am
+++ b/pimd/subdir.am
@@ -57,6 +57,7 @@ pim_common = \
pimd/pim_zebra.c \
pimd/pim_zlookup.c \
pimd/pim_vxlan.c \
+ pimd/pim_register.c \
pimd/pimd.c \
# end
@@ -74,7 +75,6 @@ pimd_pimd_SOURCES = \
pimd/pim_msdp.c \
pimd/pim_msdp_packet.c \
pimd/pim_msdp_socket.c \
- pimd/pim_register.c \
pimd/pim_signals.c \
pimd/pim_zpthread.c \
pimd/pim_mroute_msg.c \