]> git.puffer.fish Git - mirror/frr.git/commitdiff
pim6d: Register message send handling 10742/head
authorplsaranya <saranya_panjarathina@dell.com>
Mon, 7 Mar 2022 04:38:31 +0000 (10:08 +0530)
committerplsaranya <saranya_panjarathina@dell.com>
Fri, 29 Apr 2022 05:35:57 +0000 (11:05 +0530)
Register and Null register send handling
In IPv6 PIM Null Register message if dummy PIM Header is included as
data, this dummy PIM header checksum needs to be valuated

Signed-off-by: plsaranya <Saranya_Panjarathina@dell.com>
pimd/pim6_stubs.c
pimd/pim_register.c
pimd/subdir.am

index cf61685fb14e0f714d42264c3b0c56f82337ea96..f799f04f3356160f639109da7e8e05bd616649b4 100644 (file)
@@ -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;
-}
index 45bcad3c2650a137177703a31912b2f11fbca885..fef5339749cf1023b5f0bff6de27345bea20e8a6 100644 (file)
@@ -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)
index 41fc6dc6325b7a17210a9f42a6b9da0adca27c3f..9dd6961d92e1a18e3c7f3c29bce3ec6d81381e03 100644 (file)
@@ -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 \