forked from Mirror/frr
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>
This commit is contained in:
parent
a770da1b1c
commit
cefb7247f0
|
@ -1280,6 +1280,7 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
|
||||||
struct bsm_frag *bsfrag;
|
struct bsm_frag *bsfrag;
|
||||||
struct pim_instance *pim;
|
struct pim_instance *pim;
|
||||||
uint16_t frag_tag;
|
uint16_t frag_tag;
|
||||||
|
pim_addr bsr_addr;
|
||||||
bool empty_bsm = false;
|
bool empty_bsm = false;
|
||||||
|
|
||||||
/* BSM Packet acceptance validation */
|
/* 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;
|
pim->global_scope.hashMasklen = bshdr->hm_len;
|
||||||
frag_tag = ntohs(bshdr->frag_tag);
|
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 */
|
/* Identify empty BSM */
|
||||||
if ((buf_size - PIM_BSM_HDR_LEN - PIM_MSG_HEADER_LEN) < PIM_BSM_GRP_LEN)
|
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 */
|
/* 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)
|
if (PIM_DEBUG_BSM)
|
||||||
zlog_debug("%s : Received a non-preferred BSM",
|
zlog_debug("%s : Received a non-preferred BSM",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -1368,8 +1371,7 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
|
||||||
if (PIM_DEBUG_BSM)
|
if (PIM_DEBUG_BSM)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s : nofwd_bsm received on %pPAs when accpt_nofwd_bsm false",
|
"%s : nofwd_bsm received on %pPAs when accpt_nofwd_bsm false",
|
||||||
__func__,
|
__func__, &bsr_addr);
|
||||||
(pim_addr *)&bshdr->bsr_addr.addr);
|
|
||||||
pim->bsm_dropped++;
|
pim->bsm_dropped++;
|
||||||
pim_ifp->pim_ifstat_ucast_bsm_cfg_miss++;
|
pim_ifp->pim_ifstat_ucast_bsm_cfg_miss++;
|
||||||
return -1;
|
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
|
* match RPF towards the BSR's IP address, or they have
|
||||||
* no-forward set
|
* no-forward set
|
||||||
*/
|
*/
|
||||||
if (!no_fwd && !pim_nht_bsr_rpf_check(pim, bshdr->bsr_addr.addr,
|
if (!no_fwd &&
|
||||||
ifp, sg->src)) {
|
!pim_nht_bsr_rpf_check(pim, bsr_addr, ifp, sg->src)) {
|
||||||
if (PIM_DEBUG_BSM)
|
if (PIM_DEBUG_BSM)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"BSM check: RPF to BSR %pPAs is not %pPA%%%s",
|
"BSM check: RPF to BSR %pPAs is not %pPA%%%s",
|
||||||
(pim_addr *)&bshdr->bsr_addr.addr,
|
&bsr_addr, &sg->src, ifp->name);
|
||||||
&sg->src, ifp->name);
|
|
||||||
pim->bsm_dropped++;
|
pim->bsm_dropped++;
|
||||||
return -1;
|
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 */
|
/* 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) {
|
if (!no_fwd) {
|
||||||
pim_bsm_fwd_whole_sz(pim_ifp->pim, buf, buf_size, sz);
|
pim_bsm_fwd_whole_sz(pim_ifp->pim, buf, buf_size, sz);
|
||||||
|
|
|
@ -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 bsmmsg_rpinfo *bsm_rpinfo;
|
||||||
struct prefix grp;
|
struct prefix grp;
|
||||||
struct bsm_hdr *hdr;
|
struct bsm_hdr *hdr;
|
||||||
|
pim_addr bsr_addr;
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
uint32_t len = 0;
|
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;
|
len -= PIM_MSG_HEADER_LEN;
|
||||||
|
|
||||||
hdr = (struct bsm_hdr *)buf;
|
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 */
|
/* BSM starts with bsr header */
|
||||||
buf += sizeof(struct bsm_hdr);
|
buf += sizeof(struct bsm_hdr);
|
||||||
len -= sizeof(struct bsm_hdr);
|
len -= sizeof(struct bsm_hdr);
|
||||||
|
|
||||||
if (uj) {
|
if (uj) {
|
||||||
json_object_string_addf(
|
json_object_string_addf(json, "BSR address", "%pPA",
|
||||||
json, "BSR address", "%pPA",
|
&bsr_addr);
|
||||||
(pim_addr *)&hdr->bsr_addr.addr);
|
|
||||||
json_object_int_add(json, "BSR priority",
|
json_object_int_add(json, "BSR priority",
|
||||||
hdr->bsr_prio);
|
hdr->bsr_prio);
|
||||||
json_object_int_add(json, "Hashmask Length",
|
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, "------------------\n");
|
||||||
vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
|
vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
|
||||||
"BSR-Priority", "Hashmask-len", "Fragment-Tag");
|
"BSR-Priority", "Hashmask-len", "Fragment-Tag");
|
||||||
vty_out(vty, "%-15pPA %-15d %-15d %-15d\n",
|
vty_out(vty, "%-15pPA %-15d %-15d %-15d\n", &bsr_addr,
|
||||||
(pim_addr *)&hdr->bsr_addr.addr, hdr->bsr_prio,
|
hdr->bsr_prio, hdr->hm_len,
|
||||||
hdr->hm_len, ntohs(hdr->frag_tag));
|
ntohs(hdr->frag_tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
vty_out(vty, "\n");
|
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");
|
"RpAddress HoldTime Priority\n");
|
||||||
|
|
||||||
while (frag_rp_cnt--) {
|
while (frag_rp_cnt--) {
|
||||||
|
pim_addr rp_addr;
|
||||||
|
|
||||||
bsm_rpinfo = (struct bsmmsg_rpinfo *)buf;
|
bsm_rpinfo = (struct bsmmsg_rpinfo *)buf;
|
||||||
|
/* unaligned, again */
|
||||||
|
memcpy(&rp_addr, &bsm_rpinfo->rpaddr,
|
||||||
|
sizeof(rp_addr));
|
||||||
|
|
||||||
buf += sizeof(struct bsmmsg_rpinfo);
|
buf += sizeof(struct bsmmsg_rpinfo);
|
||||||
offset += 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_row = json_object_new_object();
|
||||||
json_object_string_addf(
|
json_object_string_addf(
|
||||||
json_row, "Rp Address", "%pPA",
|
json_row, "Rp Address", "%pPA",
|
||||||
(pim_addr *)&bsm_rpinfo->rpaddr
|
&rp_addr);
|
||||||
.addr);
|
|
||||||
json_object_int_add(
|
json_object_int_add(
|
||||||
json_row, "Rp HoldTime",
|
json_row, "Rp HoldTime",
|
||||||
ntohs(bsm_rpinfo->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);
|
bsm_rpinfo->rp_pri);
|
||||||
json_object_object_addf(
|
json_object_object_addf(
|
||||||
json_group, json_row, "%pPA",
|
json_group, json_row, "%pPA",
|
||||||
(pim_addr *)&bsm_rpinfo->rpaddr
|
&rp_addr);
|
||||||
.addr);
|
|
||||||
} else {
|
} else {
|
||||||
vty_out(vty, "%-15pPA %-12d %d\n",
|
vty_out(vty, "%-15pPA %-12d %d\n",
|
||||||
(pim_addr *)&bsm_rpinfo->rpaddr
|
&rp_addr,
|
||||||
.addr,
|
|
||||||
ntohs(bsm_rpinfo->rp_holdtime),
|
ntohs(bsm_rpinfo->rp_holdtime),
|
||||||
bsm_rpinfo->rp_pri);
|
bsm_rpinfo->rp_pri);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue