Skip to content

Commit

Permalink
pim6d: include IPv6 pseudoheader in TX checksums
Browse files Browse the repository at this point in the history
Lots of passing src/dst around, but it is what it is.

Signed-off-by: David Lamparter <[email protected]>
  • Loading branch information
eqvinox committed Mar 28, 2022
1 parent b6d9ad2 commit 145e4c3
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 29 deletions.
5 changes: 4 additions & 1 deletion pimd/pim_assert.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
17 changes: 11 additions & 6 deletions pimd/pim_bsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
13 changes: 9 additions & 4 deletions pimd/pim_join.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
46 changes: 33 additions & 13 deletions pimd/pim_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,36 @@
#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
Expand All @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions pimd/pim_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
4 changes: 3 additions & 1 deletion pimd/pim_pim.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions pimd/pim_register.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 145e4c3

Please sign in to comment.