diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2022-07-12 12:47:46 +0200 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2022-07-12 12:48:04 +0200 |
commit | cefb7247f09b22480919d477f1577c490de936e7 (patch) | |
tree | fab78ad93a68ab8046e51e9250444acf677f736a | |
parent | Merge pull request #11588 from opensourcerouting/fix/babeld_missing_routes (diff) | |
download | frr-cefb7247f09b22480919d477f1577c490de936e7.tar.xz frr-cefb7247f09b22480919d477f1577c490de936e7.zip |
pimd: fix unaligned accesses
These are in packed structs at weird offsets (e.g. 2 bytes), and as such
need a memcpy to get them into proper alignment.
It'd be even better if the pimd code used proper de/serialization, but
let's get this improved one step at a time.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
-rw-r--r-- | pimd/pim_bsm.c | 17 | ||||
-rw-r--r-- | pimd/pim_cmd.c | 28 |
2 files changed, 25 insertions, 20 deletions
diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index 1a13f79e7..1f7dd2f3f 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -1280,6 +1280,7 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf, struct bsm_frag *bsfrag; struct pim_instance *pim; uint16_t frag_tag; + pim_addr bsr_addr; bool empty_bsm = false; /* BSM Packet acceptance validation */ @@ -1330,6 +1331,8 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf, } pim->global_scope.hashMasklen = bshdr->hm_len; frag_tag = ntohs(bshdr->frag_tag); + /* NB: bshdr->bsr_addr.addr is packed/unaligned => memcpy */ + memcpy(&bsr_addr, &bshdr->bsr_addr.addr, sizeof(bsr_addr)); /* Identify empty BSM */ if ((buf_size - PIM_BSM_HDR_LEN - PIM_MSG_HEADER_LEN) < PIM_BSM_GRP_LEN) @@ -1351,7 +1354,7 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf, } /* Drop if bsr is not preferred bsr */ - if (!is_preferred_bsr(pim, bshdr->bsr_addr.addr, bshdr->bsr_prio)) { + if (!is_preferred_bsr(pim, bsr_addr, bshdr->bsr_prio)) { if (PIM_DEBUG_BSM) zlog_debug("%s : Received a non-preferred BSM", __func__); @@ -1368,8 +1371,7 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf, if (PIM_DEBUG_BSM) zlog_debug( "%s : nofwd_bsm received on %pPAs when accpt_nofwd_bsm false", - __func__, - (pim_addr *)&bshdr->bsr_addr.addr); + __func__, &bsr_addr); pim->bsm_dropped++; pim_ifp->pim_ifstat_ucast_bsm_cfg_miss++; return -1; @@ -1381,13 +1383,12 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf, * match RPF towards the BSR's IP address, or they have * no-forward set */ - if (!no_fwd && !pim_nht_bsr_rpf_check(pim, bshdr->bsr_addr.addr, - ifp, sg->src)) { + if (!no_fwd && + !pim_nht_bsr_rpf_check(pim, bsr_addr, ifp, sg->src)) { if (PIM_DEBUG_BSM) zlog_debug( "BSM check: RPF to BSR %pPAs is not %pPA%%%s", - (pim_addr *)&bshdr->bsr_addr.addr, - &sg->src, ifp->name); + &bsr_addr, &sg->src, ifp->name); pim->bsm_dropped++; return -1; } @@ -1446,7 +1447,7 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf, } /* update the scope information from bsm */ - pim_bsm_update(pim, bshdr->bsr_addr.addr, bshdr->bsr_prio); + pim_bsm_update(pim, bsr_addr, bshdr->bsr_prio); if (!no_fwd) { pim_bsm_fwd_whole_sz(pim_ifp->pim, buf, buf_size, sz); diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 813ef4ca3..843b24efd 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -864,6 +864,7 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj) struct bsmmsg_rpinfo *bsm_rpinfo; struct prefix grp; struct bsm_hdr *hdr; + pim_addr bsr_addr; uint32_t offset = 0; uint8_t *buf; uint32_t len = 0; @@ -877,15 +878,16 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj) len -= PIM_MSG_HEADER_LEN; hdr = (struct bsm_hdr *)buf; + /* NB: bshdr->bsr_addr.addr is packed/unaligned => memcpy */ + memcpy(&bsr_addr, &hdr->bsr_addr.addr, sizeof(bsr_addr)); /* BSM starts with bsr header */ buf += sizeof(struct bsm_hdr); len -= sizeof(struct bsm_hdr); if (uj) { - json_object_string_addf( - json, "BSR address", "%pPA", - (pim_addr *)&hdr->bsr_addr.addr); + json_object_string_addf(json, "BSR address", "%pPA", + &bsr_addr); json_object_int_add(json, "BSR priority", hdr->bsr_prio); json_object_int_add(json, "Hashmask Length", @@ -897,9 +899,9 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj) vty_out(vty, "------------------\n"); vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address", "BSR-Priority", "Hashmask-len", "Fragment-Tag"); - vty_out(vty, "%-15pPA %-15d %-15d %-15d\n", - (pim_addr *)&hdr->bsr_addr.addr, hdr->bsr_prio, - hdr->hm_len, ntohs(hdr->frag_tag)); + vty_out(vty, "%-15pPA %-15d %-15d %-15d\n", &bsr_addr, + hdr->bsr_prio, hdr->hm_len, + ntohs(hdr->frag_tag)); } vty_out(vty, "\n"); @@ -957,7 +959,12 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj) "RpAddress HoldTime Priority\n"); while (frag_rp_cnt--) { + pim_addr rp_addr; + bsm_rpinfo = (struct bsmmsg_rpinfo *)buf; + /* unaligned, again */ + memcpy(&rp_addr, &bsm_rpinfo->rpaddr, + sizeof(rp_addr)); buf += sizeof(struct bsmmsg_rpinfo); offset += sizeof(struct bsmmsg_rpinfo); @@ -966,8 +973,7 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj) json_row = json_object_new_object(); json_object_string_addf( json_row, "Rp Address", "%pPA", - (pim_addr *)&bsm_rpinfo->rpaddr - .addr); + &rp_addr); json_object_int_add( json_row, "Rp HoldTime", ntohs(bsm_rpinfo->rp_holdtime)); @@ -976,12 +982,10 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj) bsm_rpinfo->rp_pri); json_object_object_addf( json_group, json_row, "%pPA", - (pim_addr *)&bsm_rpinfo->rpaddr - .addr); + &rp_addr); } else { vty_out(vty, "%-15pPA %-12d %d\n", - (pim_addr *)&bsm_rpinfo->rpaddr - .addr, + &rp_addr, ntohs(bsm_rpinfo->rp_holdtime), bsm_rpinfo->rp_pri); } |