summaryrefslogtreecommitdiffstats
path: root/pimd/pim_pim.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2022-03-27 12:04:39 +0200
committerDavid Lamparter <equinox@opensourcerouting.org>2022-03-28 14:13:23 +0200
commit721c7be3b20a45ab99cc9e94d92a1e9d9cd5f3bb (patch)
treee03a9b339c337236cb235b2413febba9a42817eb /pimd/pim_pim.c
parentpim6d: include IPv6 pseudoheader in TX checksums (diff)
downloadfrr-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.c33
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(