]> git.proxmox.com Git - mirror_frr.git/commitdiff
pim6d: include IPv6 pseudoheader in TX checksums
authorDavid Lamparter <equinox@opensourcerouting.org>
Sun, 27 Mar 2022 09:50:40 +0000 (11:50 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Mon, 28 Mar 2022 12:13:23 +0000 (14:13 +0200)
Lots of passing src/dst around, but it is what it is.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
pimd/pim_assert.c
pimd/pim_bsm.c
pimd/pim_join.c
pimd/pim_msg.c
pimd/pim_msg.h
pimd/pim_pim.c
pimd/pim_register.c

index e7fff4db6f6c59888b4b78de02616492ceb05969..cbd44388c167fcfd88a2bf7c10eadb34a6355c70 100644 (file)
@@ -338,6 +338,7 @@ int pim_assert_build_msg(uint8_t *pim_msg, int buf_size, struct interface *ifp,
                         uint32_t metric_preference, uint32_t route_metric,
                         uint32_t rpt_bit_flag)
 {
+       struct pim_interface *pim_ifp = ifp->info;
        uint8_t *buf_pastend = pim_msg + buf_size;
        uint8_t *pim_msg_curr;
        int pim_msg_size;
@@ -380,7 +381,9 @@ int pim_assert_build_msg(uint8_t *pim_msg, int buf_size, struct interface *ifp,
          Add PIM header
        */
        pim_msg_size = pim_msg_curr - pim_msg;
-       pim_msg_build_header(pim_msg, pim_msg_size, PIM_MSG_TYPE_ASSERT, false);
+       pim_msg_build_header(pim_ifp->primary_address,
+                            qpim_all_pim_routers_addr, pim_msg, pim_msg_size,
+                            PIM_MSG_TYPE_ASSERT, false);
 
        return pim_msg_size;
 }
index 66c37e7aed9ef800aeb3f7d9a4d6e6c52294f231..0e91773be7654162da1a20faeda8c1375750164c 100644 (file)
@@ -718,6 +718,7 @@ static bool pim_bsm_send_intf(uint8_t *buf, int len, struct interface *ifp,
 static bool pim_bsm_frag_send(uint8_t *buf, uint32_t len, struct interface *ifp,
                              uint32_t pim_mtu, pim_addr dst_addr, bool no_fwd)
 {
+       struct pim_interface *pim_ifp = ifp->info;
        struct bsmmsg_grpinfo *grpinfo, *curgrp;
        uint8_t *firstgrp_ptr;
        uint8_t *pkt;
@@ -836,9 +837,10 @@ static bool pim_bsm_frag_send(uint8_t *buf, uint32_t len, struct interface *ifp,
                                < (PIM_BSM_GRP_LEN + PIM_BSM_RP_LEN))) {
                                /* No space to fit in more rp, send this pkt */
                                this_pkt_len = pim_mtu - this_pkt_rem;
-                               pim_msg_build_header(pak_start, this_pkt_len,
-                                                    PIM_MSG_TYPE_BOOTSTRAP,
-                                                    no_fwd);
+                               pim_msg_build_header(
+                                       pim_ifp->primary_address, dst_addr,
+                                       pak_start, this_pkt_len,
+                                       PIM_MSG_TYPE_BOOTSTRAP, no_fwd);
                                pim_bsm_send_intf(pak_start, this_pkt_len, ifp,
                                                  dst_addr);
 
@@ -873,7 +875,8 @@ static bool pim_bsm_frag_send(uint8_t *buf, uint32_t len, struct interface *ifp,
        /* Send if we have any unsent packet */
        if (pak_pending) {
                this_pkt_len = pim_mtu - this_pkt_rem;
-               pim_msg_build_header(pak_start, this_pkt_len,
+               pim_msg_build_header(pim_ifp->primary_address, dst_addr,
+                                    pak_start, this_pkt_len,
                                     PIM_MSG_TYPE_BOOTSTRAP, no_fwd);
                pim_bsm_send_intf(pak_start, (pim_mtu - this_pkt_rem), ifp,
                                  dst_addr);
@@ -920,7 +923,8 @@ static void pim_bsm_fwd_whole_sz(struct pim_instance *pim, uint8_t *buf,
                                zlog_debug("%s: pim_bsm_frag_send returned %s",
                                           __func__, ret ? "TRUE" : "FALSE");
                } else {
-                       pim_msg_build_header(buf, len, PIM_MSG_TYPE_BOOTSTRAP,
+                       pim_msg_build_header(pim_ifp->primary_address, dst_addr,
+                                            buf, len, PIM_MSG_TYPE_BOOTSTRAP,
                                             no_fwd);
                        if (!pim_bsm_send_intf(buf, len, ifp, dst_addr)) {
                                if (PIM_DEBUG_BSM)
@@ -999,7 +1003,8 @@ bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
                        }
                } else {
                        /* Pim header needs to be constructed */
-                       pim_msg_build_header(bsfrag->data, bsfrag->size,
+                       pim_msg_build_header(pim_ifp->primary_address, dst_addr,
+                                            bsfrag->data, bsfrag->size,
                                             PIM_MSG_TYPE_BOOTSTRAP, no_fwd);
                        ret = pim_bsm_send_intf(bsfrag->data, bsfrag->size, ifp,
                                                dst_addr);
index 2c11d5d13f897c0ea145c7d54fd6c22dfd3058d5..88078dd366e78412caa8a3ea422f7ce6864d7364 100644 (file)
@@ -488,7 +488,9 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
 
                group_size = pim_msg_get_jp_group_size(group->sources);
                if (group_size > packet_left) {
-                       pim_msg_build_header(pim_msg, packet_size,
+                       pim_msg_build_header(pim_ifp->primary_address,
+                                            qpim_all_pim_routers_addr, pim_msg,
+                                            packet_size,
                                             PIM_MSG_TYPE_JOIN_PRUNE, false);
                        if (pim_msg_send(pim_ifp->pim_sock_fd,
                                         pim_ifp->primary_address,
@@ -544,7 +546,9 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
                grp = (struct pim_jp_groups *)curr_ptr;
                if (packet_left < sizeof(struct pim_jp_groups)
                    || msg->num_groups == 255) {
-                       pim_msg_build_header(pim_msg, packet_size,
+                       pim_msg_build_header(pim_ifp->primary_address,
+                                            qpim_all_pim_routers_addr, pim_msg,
+                                            packet_size,
                                             PIM_MSG_TYPE_JOIN_PRUNE, false);
                        if (pim_msg_send(pim_ifp->pim_sock_fd,
                                         pim_ifp->primary_address,
@@ -564,8 +568,9 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
 
        if (!new_packet) {
                // msg->num_groups = htons (msg->num_groups);
-               pim_msg_build_header(pim_msg, packet_size,
-                                    PIM_MSG_TYPE_JOIN_PRUNE, false);
+               pim_msg_build_header(
+                       pim_ifp->primary_address, qpim_all_pim_routers_addr,
+                       pim_msg, packet_size, PIM_MSG_TYPE_JOIN_PRUNE, false);
                if (pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address,
                                 qpim_all_pim_routers_addr, pim_msg,
                                 packet_size,
index a0653e1a575d60385247ce7b09352d15dfbcde9f..1eda51417f9782954b7854b4125685153940bff2 100644 (file)
 #include "pim_jp_agg.h"
 #include "pim_oil.h"
 
-void pim_msg_build_header(uint8_t *pim_msg, size_t pim_msg_size,
-                         uint8_t pim_msg_type, bool no_fwd)
+void pim_msg_build_header(pim_addr src, pim_addr dst, uint8_t *pim_msg,
+                         size_t pim_msg_size, uint8_t pim_msg_type,
+                         bool no_fwd)
 {
        struct pim_msg_header *header = (struct pim_msg_header *)pim_msg;
+       struct iovec iov[2], *iovp = iov;
+
+       /*
+        * The checksum for Registers is done only on the first 8 bytes of the
+        * packet, including the PIM header and the next 4 bytes, excluding the
+        * data packet portion
+        *
+        * for IPv6, the pseudoheader upper-level protocol length is also
+        * truncated, so let's just set it here before everything else.
+        */
+       if (pim_msg_type == PIM_MSG_TYPE_REGISTER)
+               pim_msg_size = PIM_MSG_REGISTER_LEN;
+
+#if PIM_IPV == 6
+       struct ipv6_ph phdr = {
+               .src = src,
+               .dst = dst,
+               .ulpl = htonl(pim_msg_size),
+               .next_hdr = IPPROTO_PIM,
+       };
+
+       iovp->iov_base = &phdr;
+       iovp->iov_len = sizeof(phdr);
+       iovp++;
+#endif
 
        /*
         * Write header
@@ -51,18 +77,12 @@ void pim_msg_build_header(uint8_t *pim_msg, size_t pim_msg_size,
        header->Nbit = no_fwd;
        header->reserved = 0;
 
-
        header->checksum = 0;
-       /*
-        * The checksum for Registers is done only on the first 8 bytes of the
-        * packet,
-        * including the PIM header and the next 4 bytes, excluding the data
-        * packet portion
-        */
-       if (pim_msg_type == PIM_MSG_TYPE_REGISTER)
-               header->checksum = in_cksum(pim_msg, PIM_MSG_REGISTER_LEN);
-       else
-               header->checksum = in_cksum(pim_msg, pim_msg_size);
+       iovp->iov_base = header;
+       iovp->iov_len = pim_msg_size;
+       iovp++;
+
+       header->checksum = in_cksumv(iov, iovp - iov);
 }
 
 uint8_t *pim_msg_addr_encode_ipv4_ucast(uint8_t *buf, struct in_addr addr)
index 3ad958f097eb18e70d7442cf543481190daa878b..733210af3ae5ca31392dba726b63211eaf392b56 100644 (file)
@@ -216,8 +216,9 @@ static inline pim_sgaddr pim_sgaddr_from_iphdr(const void *iphdr)
 }
 #endif
 
-void pim_msg_build_header(uint8_t *pim_msg, size_t pim_msg_size,
-                         uint8_t pim_msg_type, bool no_fwd);
+void pim_msg_build_header(pim_addr src, pim_addr dst, uint8_t *pim_msg,
+                         size_t pim_msg_size, uint8_t pim_msg_type,
+                         bool no_fwd);
 uint8_t *pim_msg_addr_encode_ipv4_ucast(uint8_t *buf, struct in_addr addr);
 uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf, struct in_addr addr);
 
index 1c8e31212ea66905d8ed460de43493869775638b..b9867d3c493c27195836ab90a3a0610ee4c6c5d2 100644 (file)
@@ -704,7 +704,9 @@ static int hello_send(struct interface *ifp, uint16_t holdtime)
        assert(pim_msg_size >= PIM_PIM_MIN_LEN);
        assert(pim_msg_size <= PIM_PIM_BUFSIZE_WRITE);
 
-       pim_msg_build_header(pim_msg, pim_msg_size, PIM_MSG_TYPE_HELLO, false);
+       pim_msg_build_header(pim_ifp->primary_address,
+                            qpim_all_pim_routers_addr, pim_msg, pim_msg_size,
+                            PIM_MSG_TYPE_HELLO, false);
 
        if (pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address,
                         qpim_all_pim_routers_addr, pim_msg, pim_msg_size,
index 7fa36e5a44a43371834080de24927b869948b18c..45bcad3c2650a137177703a31912b2f11fbca885 100644 (file)
@@ -88,7 +88,8 @@ void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg,
        length = pim_encode_addr_ucast(b1, sg->src);
        b1length += length;
 
-       pim_msg_build_header(buffer, b1length + PIM_MSG_REGISTER_STOP_LEN,
+       pim_msg_build_header(src, originator, buffer,
+                            b1length + PIM_MSG_REGISTER_STOP_LEN,
                             PIM_MSG_TYPE_REG_STOP, false);
 
        pinfo = (struct pim_interface *)ifp->info;
@@ -261,7 +262,8 @@ 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(buffer, buf_size + PIM_MSG_REGISTER_LEN,
+       pim_msg_build_header(src, rpg->rpf_addr.u.prefix4, buffer,
+                            buf_size + PIM_MSG_REGISTER_LEN,
                             PIM_MSG_TYPE_REGISTER, false);
 
        ++pinfo->pim_ifstat_reg_send;