diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2020-03-16 14:47:31 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2020-03-16 14:47:31 +0000 |
commit | 0e6548a3bc2aa39fb4202e3df2a3b9133efafa24 (patch) | |
tree | cad7dd8c18e732e27a9ed3a7ce2f8338a18874cc /usr.sbin | |
parent | 71e5e353a7656d5a43655b48d847fca5a09771e3 (diff) |
The assumption that in roa tables a prefix / source-as combo only appears
once in the input file is not correct. I thought the RPKI validators would
aggreagte these entries but that is not necessarily the case.
There are cases where prefixes show up with the same source-as multiple times
with different maxlen lenght. In those cases merge these multiple entries
and keep the one entry with the longest maxlen length since that is the VRP
which covers all others.
Found by job@ OK benno@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bgpd/parse.y | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index 93aa40da1f5..b5b9db12f3c 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.404 2020/02/14 13:54:31 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.405 2020/03/16 14:47:30 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -4480,7 +4480,7 @@ static void add_roa_set(struct prefixset_item *npsi, u_int32_t as, u_int8_t max) { struct prefixset_item *psi; - struct roa_set rs; + struct roa_set rs, *rsp; /* no prefixlen option in this tree */ npsi->p.op = OP_NONE; @@ -4492,8 +4492,17 @@ add_roa_set(struct prefixset_item *npsi, u_int32_t as, u_int8_t max) if (psi->set == NULL) if ((psi->set = set_new(1, sizeof(rs))) == NULL) fatal("set_new"); - rs.as = as; - rs.maxlen = max; - if (set_add(psi->set, &rs, 1) != 0) - fatal("as_set_new"); + + /* merge sets with same key, longer maxlen wins */ + if ((rsp = set_match(psi->set, as)) != NULL) { + if (rsp->maxlen < max) + rsp->maxlen = max; + } else { + rs.as = as; + rs.maxlen = max; + if (set_add(psi->set, &rs, 1) != 0) + fatal("as_set_new"); + /* prep data so that set_match works */ + set_prep(psi->set); + } } |