From 1e6dccedb95d16e211a5994c0bf9346ba12444e0 Mon Sep 17 00:00:00 2001 From: claudio Date: Wed, 29 Mar 2023 10:46:11 +0000 Subject: [PATCH] Switch prefix_adjout_get and new prefix_adjout_first to use a pt_entry as argument instead of the bgpd_addr + prefixlen. Do the same with prefix_adjout_update but leave prefix_adjout_lookup and prefix_adjout_match since those are used by bgpctl code that does not use pt_entry structs. With this most of the update code no longer needs struct bgpd_addr and pt_getaddr(). OK tb@ --- usr.sbin/bgpd/rde.h | 13 ++++---- usr.sbin/bgpd/rde_rib.c | 35 ++++++++++++---------- usr.sbin/bgpd/rde_update.c | 61 ++++++++++++++------------------------ 3 files changed, 50 insertions(+), 59 deletions(-) diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 1d6abfcd1e7..cd33d5f2b1b 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.288 2023/03/28 15:17:34 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.289 2023/03/29 10:46:11 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker and @@ -580,19 +580,20 @@ void path_put(struct rde_aspath *); struct prefix *prefix_get(struct rib *, struct rde_peer *, uint32_t, struct bgpd_addr *, int); struct prefix *prefix_adjout_get(struct rde_peer *, uint32_t, - struct bgpd_addr *, int); -struct prefix *prefix_match(struct rde_peer *, struct bgpd_addr *); -struct prefix *prefix_adjout_match(struct rde_peer *, struct bgpd_addr *); + struct pt_entry *); +struct prefix *prefix_adjout_first(struct rde_peer *, struct pt_entry *); +struct prefix *prefix_adjout_next(struct rde_peer *, struct prefix *); struct prefix *prefix_adjout_lookup(struct rde_peer *, struct bgpd_addr *, int); -struct prefix *prefix_adjout_next(struct rde_peer *, struct prefix *); +struct prefix *prefix_adjout_match(struct rde_peer *, struct bgpd_addr *); +struct prefix *prefix_match(struct rde_peer *, struct bgpd_addr *); int prefix_update(struct rib *, struct rde_peer *, uint32_t, uint32_t, struct filterstate *, struct bgpd_addr *, int); int prefix_withdraw(struct rib *, struct rde_peer *, uint32_t, struct bgpd_addr *, int); void prefix_add_eor(struct rde_peer *, uint8_t); void prefix_adjout_update(struct prefix *, struct rde_peer *, - struct filterstate *, struct bgpd_addr *, int, uint32_t); + struct filterstate *, struct pt_entry *, uint32_t); void prefix_adjout_withdraw(struct prefix *); void prefix_adjout_destroy(struct prefix *); void prefix_adjout_dump(struct rde_peer *, void *, diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c index bc4ae021540..99c7119f7a3 100644 --- a/usr.sbin/bgpd/rde_rib.c +++ b/usr.sbin/bgpd/rde_rib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_rib.c,v 1.256 2023/03/28 15:17:34 claudio Exp $ */ +/* $OpenBSD: rde_rib.c,v 1.257 2023/03/29 10:46:11 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker @@ -873,12 +873,12 @@ prefix_get(struct rib *rib, struct rde_peer *peer, uint32_t path_id, */ struct prefix * prefix_adjout_get(struct rde_peer *peer, uint32_t path_id_tx, - struct bgpd_addr *prefix, int prefixlen) + struct pt_entry *pte) { struct prefix xp; memset(&xp, 0, sizeof(xp)); - xp.pt = pt_fill(prefix, prefixlen); + xp.pt = pte; xp.path_id_tx = path_id_tx; return RB_FIND(prefix_index, &peer->adj_rib_out, &xp); @@ -889,13 +889,12 @@ prefix_adjout_get(struct rde_peer *peer, uint32_t path_id_tx, * Returns NULL if not found. */ struct prefix * -prefix_adjout_lookup(struct rde_peer *peer, struct bgpd_addr *prefix, - int prefixlen) +prefix_adjout_first(struct rde_peer *peer, struct pt_entry *pte) { struct prefix xp, *np; memset(&xp, 0, sizeof(xp)); - xp.pt = pt_fill(prefix, prefixlen); + xp.pt = pte; np = RB_NFIND(prefix_index, &peer->adj_rib_out, &xp); if (np == NULL || pt_prefix_cmp(np->pt, xp.pt) != 0) @@ -917,6 +916,16 @@ prefix_adjout_next(struct rde_peer *peer, struct prefix *p) return np; } +/* + * Lookup addr/prefixlen in the peer prefix_index. Returns first match. + * Returns NULL if not found. + */ +struct prefix * +prefix_adjout_lookup(struct rde_peer *peer, struct bgpd_addr *addr, int plen) +{ + return prefix_adjout_first(peer, pt_fill(addr, plen)); +} + /* * Lookup addr in the peer prefix_index. Returns first match. * Returns NULL if not found. @@ -1124,8 +1133,7 @@ prefix_add_eor(struct rde_peer *peer, uint8_t aid) */ void prefix_adjout_update(struct prefix *p, struct rde_peer *peer, - struct filterstate *state, struct bgpd_addr *prefix, int prefixlen, - uint32_t path_id_tx) + struct filterstate *state, struct pt_entry *pte, uint32_t path_id_tx) { struct rde_aspath *asp; struct rde_community *comm; @@ -1135,10 +1143,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer, /* initially mark DEAD so code below is skipped */ p->flags |= PREFIX_FLAG_ADJOUT | PREFIX_FLAG_DEAD; - p->pt = pt_get(prefix, prefixlen); - if (p->pt == NULL) - p->pt = pt_add(prefix, prefixlen); - pt_ref(p->pt); + p->pt = pt_ref(pte); p->peer = peer; p->path_id_tx = path_id_tx; @@ -1170,7 +1175,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer, /* if pending update unhook it before it is unlinked */ if (p->flags & PREFIX_FLAG_UPDATE) { - RB_REMOVE(prefix_tree, &peer->updates[prefix->aid], p); + RB_REMOVE(prefix_tree, &peer->updates[pte->aid], p); peer->stats.pending_update--; } @@ -1179,7 +1184,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer, peer->stats.prefix_out_cnt--; } if (p->flags & PREFIX_FLAG_WITHDRAW) { - RB_REMOVE(prefix_tree, &peer->withdraws[prefix->aid], p); + RB_REMOVE(prefix_tree, &peer->withdraws[pte->aid], p); peer->stats.pending_withdraw--; } @@ -1213,7 +1218,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer, if (p->flags & PREFIX_FLAG_MASK) fatalx("%s: bad flags %x", __func__, p->flags); p->flags |= PREFIX_FLAG_UPDATE; - if (RB_INSERT(prefix_tree, &peer->updates[prefix->aid], p) != NULL) + if (RB_INSERT(prefix_tree, &peer->updates[pte->aid], p) != NULL) fatalx("%s: RB tree invariant violated", __func__); peer->stats.pending_update++; } diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c index dc4bf1e9673..9667b4fcd4b 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.160 2023/03/28 15:17:34 claudio Exp $ */ +/* $OpenBSD: rde_update.c,v 1.161 2023/03/29 10:46:11 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker @@ -150,10 +150,10 @@ up_enforce_open_policy(struct rde_peer *peer, struct filterstate *state, * - UP_EXCLUDED if prefix was excluded because of up_test_update() */ static enum up_state -up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p, - struct bgpd_addr *addr, uint8_t plen) +up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p) { struct filterstate state; + struct bgpd_addr addr; int excluded = 0; /* @@ -166,14 +166,15 @@ up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p, excluded = 1; rde_filterstate_prep(&state, new); - if (rde_filter(peer->out_rules, peer, prefix_peer(new), addr, plen, - &state) == ACTION_DENY) { + pt_getaddr(new->pt, &addr); + if (rde_filter(peer->out_rules, peer, prefix_peer(new), &addr, + new->pt->prefixlen, &state) == ACTION_DENY) { rde_filterstate_clean(&state); return UP_FILTERED; } /* Open Policy Check: acts like an output filter */ - if (up_enforce_open_policy(peer, &state, addr->aid)) { + if (up_enforce_open_policy(peer, &state, new->pt->aid)) { rde_filterstate_clean(&state); return UP_FILTERED; } @@ -185,10 +186,10 @@ up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p, /* from here on we know this is an update */ if (p == (void *)-1) - p = prefix_adjout_get(peer, new->path_id_tx, addr, plen); + p = prefix_adjout_get(peer, new->path_id_tx, new->pt); - up_prep_adjout(peer, &state, addr->aid); - prefix_adjout_update(p, peer, &state, addr, plen, new->path_id_tx); + up_prep_adjout(peer, &state, new->pt->aid); + prefix_adjout_update(p, peer, &state, new->pt, new->path_id_tx); rde_filterstate_clean(&state); /* max prefix checker outbound */ @@ -208,18 +209,13 @@ up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p, void up_generate_updates(struct rde_peer *peer, struct rib_entry *re) { - struct bgpd_addr addr; struct prefix *new, *p; - uint8_t prefixlen; - pt_getaddr(re->prefix, &addr); - prefixlen = re->prefix->prefixlen; - - p = prefix_adjout_lookup(peer, &addr, prefixlen); + p = prefix_adjout_first(peer, re->prefix); new = prefix_best(re); while (new != NULL) { - switch (up_process_prefix(peer, new, p, &addr, prefixlen)) { + switch (up_process_prefix(peer, new, p)) { case UP_OK: case UP_ERR_LIMIT: return; @@ -251,16 +247,11 @@ done: void up_generate_addpath(struct rde_peer *peer, struct rib_entry *re) { - struct bgpd_addr addr; struct prefix *head, *new, *p; - uint8_t prefixlen; int maxpaths = 0, extrapaths = 0, extra; int checkmode = 1; - pt_getaddr(re->prefix, &addr); - prefixlen = re->prefix->prefixlen; - - head = prefix_adjout_lookup(peer, &addr, prefixlen); + head = prefix_adjout_first(peer, re->prefix); /* mark all paths as stale */ for (p = head; p != NULL; p = prefix_adjout_next(peer, p)) @@ -310,8 +301,7 @@ up_generate_addpath(struct rde_peer *peer, struct rib_entry *re) } } - switch (up_process_prefix(peer, new, (void *)-1, &addr, - prefixlen)) { + switch (up_process_prefix(peer, new, (void *)-1)) { case UP_OK: maxpaths++; extrapaths += extra; @@ -345,21 +335,16 @@ void up_generate_addpath_all(struct rde_peer *peer, struct rib_entry *re, struct prefix *new, struct prefix *old) { - struct bgpd_addr addr; struct prefix *p, *head = NULL; - uint8_t prefixlen; int all = 0; - pt_getaddr(re->prefix, &addr); - prefixlen = re->prefix->prefixlen; - /* * if old and new are NULL then insert all prefixes from best, * clearing old routes in the process */ if (old == NULL && new == NULL) { /* mark all paths as stale */ - head = prefix_adjout_lookup(peer, &addr, prefixlen); + head = prefix_adjout_first(peer, re->prefix); for (p = head; p != NULL; p = prefix_adjout_next(peer, p)) p->flags |= PREFIX_FLAG_STALE; @@ -369,15 +354,14 @@ up_generate_addpath_all(struct rde_peer *peer, struct rib_entry *re, if (old != NULL) { /* withdraw stale paths */ - p = prefix_adjout_get(peer, old->path_id_tx, &addr, prefixlen); + p = prefix_adjout_get(peer, old->path_id_tx, old->pt); if (p != NULL) prefix_adjout_withdraw(p); } /* add new path (or multiple if all is set) */ while (new != NULL) { - switch (up_process_prefix(peer, new, (void *)-1, &addr, - prefixlen)) { + switch (up_process_prefix(peer, new, (void *)-1)) { case UP_OK: case UP_FILTERED: case UP_EXCLUDED: @@ -405,10 +389,6 @@ up_generate_addpath_all(struct rde_peer *peer, struct rib_entry *re, } } -struct rib_entry *rib_add(struct rib *, struct bgpd_addr *, int); -void rib_remove(struct rib_entry *); -int rib_empty(struct rib_entry *); - /* send a default route to the specified peer */ void up_generate_default(struct rde_peer *peer, uint8_t aid) @@ -417,6 +397,7 @@ up_generate_default(struct rde_peer *peer, uint8_t aid) struct filterstate state; struct rde_aspath *asp; struct prefix *p; + struct pt_entry *pte; struct bgpd_addr addr; if (peer->capa.mp[aid] == 0) @@ -447,7 +428,11 @@ up_generate_default(struct rde_peer *peer, uint8_t aid) } up_prep_adjout(peer, &state, addr.aid); - prefix_adjout_update(p, peer, &state, &addr, 0, 0); + /* can't use pt_fill here since prefix_adjout_update keeps a ref */ + pte = pt_get(&addr, 0); + if (pte == NULL) + pte = pt_add(&addr, 0); + prefix_adjout_update(p, peer, &state, pte, 0); rde_filterstate_clean(&state); /* max prefix checker outbound */ -- 2.20.1