Download raw body.
bgpd: better limit the maximum number of SPAS in a ASPA record
The MAX_ASPA_SPAS_COUNT handling in bgpd has 2 minor issues.
The merged ASPA table in the rtr process could in theory become bigger
than MAX_ASPA_SPAS_COUNT. This is in itself not an issue, the RDE can
handle that but we want to ensure the message can not overflow the imsg
maximum buffer size. Using the same MAX_ASPA_SPAS_COUNT limit there makes
sense. Also log if this happens, which may be annoying since the merged
table is not persisted and so the warning will pop up over and over again
until the issue is fixed. Since MAX_ASPA_SPAS_COUNT is magnitues bigger
than what is around I do not bother to make this better right now.
merge_aspa_set() in parse.y does the MAX_ASPA_SPAS_COUNT wrong and is off
by 1 afaik. Write this like all other MAX_ASPA_SPAS_COUNT checks and put
MAX_ASPA_SPAS_COUNT on the right hand side of the comparison.
Btw: the biggest record right now is:
customer-as 14789 provider-as { 557, 1680, 2107, 3737, 3741, 4007,
4651, 4775, 4780, 4787, 7459, 8047, 8697, 8866, 8966, 9038, 9329, 9534,
9930, 10075, 10089, 10094, 10118, 10396, 11232, 11260, 12297, 12400, 12735
, 13335, 13576, 14259, 14840, 14988, 15399, 15739, 16010, 16637, 16735,
17072, 1 7451, 17494, 17557, 17639, 17754, 17882, 18001, 18200, 18229,
18678, 20764, 2157 4, 23201, 23674, 23752, 23889, 23951, 24088, 24432,
24499, 24550, 27665, 27775, 27884, 27924, 28118, 28126, 28198, 28283,
29049, 29357, 29555, 30689, 30844, 309 99, 33765, 33779, 33874, 35900,
36947, 36992, 37054, 37105, 37133, 37468, 37645, 37662, 37678, 37705,
37904, 38040, 38082, 38442, 38565, 45430, 45498, 45582, 45 916, 46650,
47589, 48728, 48832, 49800, 52263, 52468, 55805, 55915, 55943, 55944 ,
57324, 58470, 58495, 58682, 58715, 58717, 59318, 59588, 61399, 61580,
63526, 6 4116, 64126, 131267, 132602, 137187, 137491, 138754, 138886,
139009, 139901, 139 922, 141177, 141731, 150748, 199995, 201532, 203214,
203217, 204170, 205140, 206 206, 208407, 210021, 212522, 262186, 262589,
262907, 263073, 263779, 266445, 268 696, 268976, 271253, 271885, 272037,
272806, 327875, 327899, 328578, 328949 }
--
:wq Claudio
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
diff -u -p -r1.492 parse.y
--- parse.y 8 May 2026 12:03:50 -0000 1.492
+++ parse.y 9 May 2026 20:46:57 -0000
@@ -5537,7 +5537,7 @@ merge_aspa_set(uint32_t as, struct aspa_
RB_INSERT(aspa_tree, &conf->aspa, aspa);
}
- if (MAX_ASPA_SPAS_COUNT - aspa->num <= tas->num) {
+ if (tas->num > MAX_ASPA_SPAS_COUNT - aspa->num) {
yyerror("too many providers for customer-as %u", as);
return -1;
}
Index: rtr.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rtr.c,v
diff -u -p -r1.34 rtr.c
--- rtr.c 19 Mar 2026 13:36:50 -0000 1.34
+++ rtr.c 7 May 2026 14:26:22 -0000
@@ -489,10 +489,13 @@ rtr_imsg_compose(int type, uint32_t id,
* At the same time tas_aid is overwritten with the bitmasks or cleared
* if no extra aid masks are needed.
*/
-static size_t
-rtr_aspa_set_size(struct aspa_set *aspa)
+static void
+rtr_aspa_set_size(const struct aspa_set *aspa, struct aspa_prep *ap)
{
- return aspa->num * sizeof(uint32_t);
+ if (aspa->num > MAX_ASPA_SPAS_COUNT)
+ return;
+ ap->datasize += aspa->num * sizeof(uint32_t);
+ ap->entries++;
}
/*
@@ -531,8 +534,7 @@ rtr_recalc(void)
rtr_aspa_merge(&at);
RB_FOREACH(aspa, aspa_tree, &at) {
- ap.datasize += rtr_aspa_set_size(aspa);
- ap.entries++;
+ rtr_aspa_set_size(aspa, &ap);
}
imsg_compose(ibuf_rde, IMSG_RECONF_ASPA_PREP, 0, 0, -1,
@@ -541,6 +543,13 @@ rtr_recalc(void)
/* walk tree in reverse because aspa_add_set requires that */
RB_FOREACH_REVERSE(aspa, aspa_tree, &at) {
struct aspa_set as = { .as = aspa->as, .num = aspa->num };
+
+ if (aspa->num > MAX_ASPA_SPAS_COUNT) {
+ log_warnx("oversized ASPA record after merge: "
+ "implicit withdraw of customerAS %s",
+ log_as(aspa->as));
+ continue;
+ }
imsg_compose(ibuf_rde, IMSG_RECONF_ASPA, 0, 0, -1,
&as, offsetof(struct aspa_set, tas));
bgpd: better limit the maximum number of SPAS in a ASPA record