diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2022-07-11 16:55:22 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2022-07-11 16:55:22 +0000 |
commit | 53060c68c15f330b45fe7ff9df53bb40cb446b58 (patch) | |
tree | 83f2f64f0a993f604acab47e2143718c217b9603 /usr.sbin | |
parent | 81bb1204403e620c91969edf04cc96dc058cf1fa (diff) |
Put the RFC9234 open policy handing in its own function
While there fix a spelling mistake and remove an extra check for new == NULL
and old == NULL. The caller make this check already.
OK tb@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bgpd/rde_update.c | 90 |
1 files changed, 48 insertions, 42 deletions
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c index 335884ae014..9332136f757 100644 --- a/usr.sbin/bgpd/rde_update.c +++ b/usr.sbin/bgpd/rde_update.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_update.c,v 1.142 2022/07/08 10:01:52 claudio Exp $ */ +/* $OpenBSD: rde_update.c,v 1.143 2022/07/11 16:55:21 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -96,6 +96,44 @@ up_test_update(struct rde_peer *peer, struct prefix *p) return (1); } +/* RFC9234 open policy handling */ +static int +up_enforce_open_policy(struct rde_peer *peer, struct filterstate *state) +{ + uint8_t role; + + if (!peer_has_open_policy(peer, &role)) + return 0; + + /* + * do not propagate (consider it filtered) if OTC is present and + * neighbor role is peer, provider or rs. + */ + if (role == CAPA_ROLE_PEER || role == CAPA_ROLE_PROVIDER || + role == CAPA_ROLE_RS) + if (state->aspath.flags & F_ATTR_OTC) + return (1); + + /* + * add OTC attribute if not present for peers, customers and rs-clients. + */ + if (role == CAPA_ROLE_PEER || role == CAPA_ROLE_CUSTOMER || + role == CAPA_ROLE_RS_CLIENT) + if ((state->aspath.flags & F_ATTR_OTC) == 0) { + uint32_t tmp; + + tmp = htonl(peer->conf.local_as); + if (attr_optadd(&state->aspath, + ATTR_OPTIONAL|ATTR_TRANSITIVE, ATTR_OTC, + &tmp, sizeof(tmp)) == -1) + log_peer_warnx(&peer->conf, + "failed to add OTC attribute"); + state->aspath.flags |= F_ATTR_OTC; + } + + return 0; +} + void up_generate_updates(struct filter_head *rules, struct rde_peer *peer, struct prefix *new, struct prefix *old) @@ -104,12 +142,9 @@ up_generate_updates(struct filter_head *rules, struct rde_peer *peer, struct bgpd_addr addr; struct prefix *p; int need_withdraw; - uint8_t prefixlen, role; + uint8_t prefixlen; if (new == NULL) { - if (old == NULL) - /* no prefix to update or withdraw */ - return; pt_getaddr(old->pt, &addr); prefixlen = old->pt->prefixlen; } else { @@ -123,7 +158,7 @@ up_generate_updates(struct filter_head *rules, struct rde_peer *peer, need_withdraw = 0; /* * up_test_update() needs to run before the output filters - * else the well known communities wont work properly. + * else the well known communities won't work properly. * The output filters would not be able to add well known * communities. */ @@ -156,43 +191,14 @@ up_generate_updates(struct filter_head *rules, struct rde_peer *peer, break; } - /* RFC9234 open policy handling */ - if (peer_has_open_policy(peer, &role)) { - /* - * do not propagate (consider it filtered) if - * OTC is present and neighbor role is peer, - * provider or rs. - */ - if ((role == CAPA_ROLE_PEER || - role == CAPA_ROLE_PROVIDER || - role == CAPA_ROLE_RS) && - state.aspath.flags & F_ATTR_OTC) { - rde_filterstate_clean(&state); - if (peer->flags & PEERFLAG_EVALUATE_ALL) { - new = TAILQ_NEXT(new, entry.list.rib); - if (new != NULL && prefix_eligible(new)) - continue; - } - break; - } - /* - * add OTC attribute if not present for peers, - * customers and rs-clients. - */ - if ((role == CAPA_ROLE_PEER || - role == CAPA_ROLE_CUSTOMER || - role == CAPA_ROLE_RS_CLIENT) && - (state.aspath.flags & F_ATTR_OTC) == 0) { - uint32_t tmp; - - tmp = htonl(peer->conf.local_as); - if (attr_optadd(&state.aspath, - ATTR_OPTIONAL|ATTR_TRANSITIVE, ATTR_OTC, - &tmp, sizeof(tmp)) == -1) - log_peer_warnx(&peer->conf, - "failed to add OTC attribute"); - state.aspath.flags |= F_ATTR_OTC; + if (up_enforce_open_policy(peer, &state)) { + rde_filterstate_clean(&state); + if (peer->flags & PEERFLAG_EVALUATE_ALL) { + new = TAILQ_NEXT(new, entry.list.rib); + if (new != NULL && prefix_eligible(new)) + continue; } + break; } /* check if this was actually a withdraw */ |