From 00d833503e2654131fa16df4558102cba7eb2804 Mon Sep 17 00:00:00 2001 From: claudio Date: Thu, 20 Apr 2023 15:44:45 +0000 Subject: [PATCH] Rework the way transit provider AID masks are built and sent to the RDE. ASPA provider AS sets can include optional limitations to inet/inet6 these limits are represented in the TAS_AID bit masks (2bits per AS). Introduce a TAS_AID_SIZE() makro that returns the size in bytes of this bit mask (rounded to the next uint32_t). Without this change aspa objects with AID specific elements trigger a fatal error condition when the config is loaded. OK tb@ job@ --- usr.sbin/bgpd/bgpd.h | 3 ++- usr.sbin/bgpd/rde.c | 11 ++++++----- usr.sbin/bgpd/rde_aspa.c | 9 +++++---- usr.sbin/bgpd/rtr.c | 27 ++++++++++++++++++--------- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index d0dd9850f65..181746b7ac1 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.474 2023/04/20 12:53:27 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.475 2023/04/20 15:44:45 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -1273,6 +1273,7 @@ struct aspa_set { uint8_t *tas_aid; RB_ENTRY(aspa_set) entry; }; +#define TAS_AID_SIZE(n) (((n) + 15) / 16 * sizeof(uint32_t)) struct aspa_prep { size_t datasize; diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index 1fecf6c5151..8d51ec20b12 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.604 2023/04/20 12:53:27 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.605 2023/04/20 15:44:45 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -1312,7 +1312,7 @@ rde_dispatch_imsg_rtr(struct imsgbuf *ibuf) if (aspa == NULL) fatalx("unexpected IMSG_RECONF_ASPA_TAS"); if (imsg.hdr.len - IMSG_HEADER_SIZE != - aspa->num * sizeof(uint32_t)) + aspa->num * sizeof(uint32_t)) fatalx("IMSG_RECONF_ASPA_TAS bad len"); aspa->tas = reallocarray(NULL, aspa->num, sizeof(uint32_t)); @@ -1325,12 +1325,13 @@ rde_dispatch_imsg_rtr(struct imsgbuf *ibuf) if (aspa == NULL) fatalx("unexpected IMSG_RECONF_ASPA_TAS_AID"); if (imsg.hdr.len - IMSG_HEADER_SIZE != - (aspa->num + 15) / 16) + TAS_AID_SIZE(aspa->num)) fatalx("IMSG_RECONF_ASPA_TAS_AID bad len"); - aspa->tas_aid = malloc((aspa->num + 15) / 16); + aspa->tas_aid = malloc(TAS_AID_SIZE(aspa->num)); if (aspa->tas_aid == NULL) fatal("IMSG_RECONF_ASPA_TAS_AID"); - memcpy(aspa->tas_aid, imsg.data, (aspa->num + 15) / 16); + memcpy(aspa->tas_aid, imsg.data, + TAS_AID_SIZE(aspa->num)); break; case IMSG_RECONF_ASPA_DONE: if (aspa_new == NULL) diff --git a/usr.sbin/bgpd/rde_aspa.c b/usr.sbin/bgpd/rde_aspa.c index 10602b68be7..da1746adfe4 100644 --- a/usr.sbin/bgpd/rde_aspa.c +++ b/usr.sbin/bgpd/rde_aspa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_aspa.c,v 1.3 2023/01/24 11:28:41 claudio Exp $ */ +/* $OpenBSD: rde_aspa.c,v 1.4 2023/04/20 15:44:45 claudio Exp $ */ /* * Copyright (c) 2022 Claudio Jeker @@ -445,12 +445,13 @@ aspa_add_set(struct rde_aspa *ra, uint32_t cas, const uint32_t *pas, /* nobody in their right mind has per afi specific data */ if (pas_aid != NULL) { /* 2 bits per entry rounded to next uint32_t */ - if (ra->maxdata - ra->curdata < (pascnt * 2 + 31) / 32) + if (ra->maxdata - ra->curdata < + TAS_AID_SIZE(pascnt) / sizeof(ra->data[0])) fatalx("aspa set data overflow"); aspa->pas_aid = ra->data + ra->curdata; - for (i = 0; i < (pascnt * 2 + 31) / 32; i++) - ra->data[ra->curdata++] = pas_aid[i]; + memcpy(aspa->pas_aid, pas_aid, TAS_AID_SIZE(pascnt)); + ra->curdata += TAS_AID_SIZE(pascnt) / sizeof(ra->data[0]); } } diff --git a/usr.sbin/bgpd/rtr.c b/usr.sbin/bgpd/rtr.c index 2c3b18cc9c7..e30d0c4a7b9 100644 --- a/usr.sbin/bgpd/rtr.c +++ b/usr.sbin/bgpd/rtr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtr.c,v 1.13 2023/03/28 12:15:23 claudio Exp $ */ +/* $OpenBSD: rtr.c,v 1.14 2023/04/20 15:44:45 claudio Exp $ */ /* * Copyright (c) 2020 Claudio Jeker @@ -506,10 +506,15 @@ static size_t rtr_aspa_set_prep(struct aspa_set *aspa) { uint32_t i, mask = 0; + uint8_t *tas_aid; int needafi = 0; size_t s; s = aspa->num * sizeof(uint32_t); + + if ((tas_aid = malloc(TAS_AID_SIZE(aspa->num))) == NULL) + fatal("tas_aid alloc"); + for (i = 0; i < aspa->num; i++) { switch (aspa->tas_aid[i]) { case AID_INET: @@ -525,19 +530,23 @@ rtr_aspa_set_prep(struct aspa_set *aspa) break; } if (i % 16 == 15) { - memcpy(aspa->tas_aid + (i / 16) * sizeof(mask), &mask, + memcpy(tas_aid + (i / 16) * sizeof(mask), &mask, sizeof(mask)); mask = 0; } } + free(aspa->tas_aid); + aspa->tas_aid = NULL; + if (!needafi) { - free(aspa->tas_aid); - aspa->tas_aid = NULL; + free(tas_aid); } else { - memcpy(aspa->tas_aid + (aspa->num / 16) * sizeof(mask), &mask, - sizeof(mask)); - s += (aspa->num + 15) / 16; + if (aspa->num % 16 != 0) + memcpy(tas_aid + (aspa->num / 16) * sizeof(mask), + &mask, sizeof(mask)); + aspa->tas_aid = tas_aid; + s += TAS_AID_SIZE(aspa->num); } return s; @@ -596,8 +605,8 @@ rtr_recalc(void) imsg_compose(ibuf_rde, IMSG_RECONF_ASPA_TAS, 0, 0, -1, aspa->tas, aspa->num * sizeof(*aspa->tas)); if (aspa->tas_aid) - imsg_compose(ibuf_rde, IMSG_RECONF_ASPA_TAS, 0, 0, -1, - aspa->tas_aid, (aspa->num + 15) / 16); + imsg_compose(ibuf_rde, IMSG_RECONF_ASPA_TAS_AID, 0, 0, + -1, aspa->tas_aid, TAS_AID_SIZE(aspa->num)); imsg_compose(ibuf_rde, IMSG_RECONF_ASPA_DONE, 0, 0, -1, NULL, 0); } -- 2.20.1