diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2022-03-27 12:04:39 +0200 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2022-03-28 14:13:23 +0200 |
commit | 721c7be3b20a45ab99cc9e94d92a1e9d9cd5f3bb (patch) | |
tree | e03a9b339c337236cb235b2413febba9a42817eb /pimd/pim_pim.c | |
parent | pim6d: include IPv6 pseudoheader in TX checksums (diff) | |
download | frr-721c7be3b20a45ab99cc9e94d92a1e9d9cd5f3bb.tar.xz frr-721c7be3b20a45ab99cc9e94d92a1e9d9cd5f3bb.zip |
pim6d: include IPv6 pseudoheader in RX checksums
A lot simpler than the TX code.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'pimd/pim_pim.c')
-rw-r--r-- | pimd/pim_pim.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index b9867d3c4..3336a0e26 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -152,6 +152,7 @@ static bool pim_pkt_dst_addr_ok(enum pim_msg_type type, pim_addr addr) int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len, pim_sgaddr sg) { + struct iovec iov[2], *iovp = iov; #if PIM_IPV == 4 struct ip *ip_hdr = (struct ip *)buf; size_t ip_hlen; /* ip header length in bytes */ @@ -179,11 +180,26 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len, pim_msg = buf + ip_hlen; pim_msg_len = len - ip_hlen; #else + struct ipv6_ph phdr = { + .src = sg.src, + .dst = sg.grp, + .ulpl = htonl(len), + .next_hdr = IPPROTO_PIM, + }; + + iovp->iov_base = &phdr; + iovp->iov_len = sizeof(phdr); + iovp++; + /* NB: header is not included in IPv6 RX */ pim_msg = buf; pim_msg_len = len; #endif + iovp->iov_base = pim_msg; + iovp->iov_len = pim_msg_len; + iovp++; + header = (struct pim_msg_header *)pim_msg; if (pim_msg_len < PIM_PIM_MIN_LEN) { if (PIM_DEBUG_PIM_PACKETS) @@ -215,10 +231,21 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len, pim_msg_len, PIM_MSG_REGISTER_LEN); return -1; } + +#if PIM_IPV == 6 + phdr.ulpl = htonl(PIM_MSG_REGISTER_LEN); +#endif /* First 8 byte header checksum */ - checksum = in_cksum(pim_msg, PIM_MSG_REGISTER_LEN); + iovp[-1].iov_len = PIM_MSG_REGISTER_LEN; + checksum = in_cksumv(iov, iovp - iov); + if (checksum != pim_checksum) { - checksum = in_cksum(pim_msg, pim_msg_len); +#if PIM_IPV == 6 + phdr.ulpl = htonl(pim_msg_len); +#endif + iovp[-1].iov_len = pim_msg_len; + + checksum = in_cksumv(iov, iovp - iov); if (checksum != pim_checksum) { if (PIM_DEBUG_PIM_PACKETS) zlog_debug( @@ -230,7 +257,7 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len, } } } else { - checksum = in_cksum(pim_msg, pim_msg_len); + checksum = in_cksumv(iov, iovp - iov); if (checksum != pim_checksum) { if (PIM_DEBUG_PIM_PACKETS) zlog_debug( |