diff options
| -rw-r--r-- | pimd/pim_assert.c | 5 | ||||
| -rw-r--r-- | pimd/pim_bsm.c | 17 | ||||
| -rw-r--r-- | pimd/pim_join.c | 13 | ||||
| -rw-r--r-- | pimd/pim_msg.c | 46 | ||||
| -rw-r--r-- | pimd/pim_msg.h | 5 | ||||
| -rw-r--r-- | pimd/pim_pim.c | 4 | ||||
| -rw-r--r-- | pimd/pim_register.c | 6 |
7 files changed, 67 insertions, 29 deletions
diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c index e7fff4db6f..cbd44388c1 100644 --- a/pimd/pim_assert.c +++ b/pimd/pim_assert.c @@ -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; } diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index 66c37e7aed..0e91773be7 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -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); diff --git a/pimd/pim_join.c b/pimd/pim_join.c index 2c11d5d13f..88078dd366 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -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, diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c index a0653e1a57..1eda51417f 100644 --- a/pimd/pim_msg.c +++ b/pimd/pim_msg.c @@ -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 @@ -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) diff --git a/pimd/pim_msg.h b/pimd/pim_msg.h index 3ad958f097..733210af3a 100644 --- a/pimd/pim_msg.h +++ b/pimd/pim_msg.h @@ -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); diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index 1c8e31212e..b9867d3c49 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -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, diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 7fa36e5a44..45bcad3c26 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -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; |
