From 988ba0ba4c35234dc11879fc97fa053d4a6c1a3b Mon Sep 17 00:00:00 2001 From: claudio Date: Mon, 13 Feb 2023 18:07:53 +0000 Subject: [PATCH] Pass struct rib_entry to rde_generate_updates() instead of struct rib. With this the newbest and oldbest arguments can go since the infromation is part of the rib_entry. Especially the prefix in the rib_entry is always valid so simplify some code in various functions below to use this information. OK tb@ --- usr.sbin/bgpd/rde.c | 9 ++--- usr.sbin/bgpd/rde.h | 14 +++---- usr.sbin/bgpd/rde_decide.c | 12 +++--- usr.sbin/bgpd/rde_peer.c | 42 ++++++-------------- usr.sbin/bgpd/rde_update.c | 81 ++++++++++++++++---------------------- 5 files changed, 59 insertions(+), 99 deletions(-) diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index 3a251628b54..9cb68ef9865 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.592 2023/02/09 13:43:23 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.593 2023/02/13 18:07:53 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -3888,14 +3888,11 @@ rde_softreconfig_in(struct rib_entry *re, void *bula) static void rde_softreconfig_out(struct rib_entry *re, void *arg) { - struct rib *rib = arg; - struct prefix *p; - - if ((p = prefix_best(re)) == NULL) + if (prefix_best(re) == NULL) /* no valid path for prefix */ return; - rde_generate_updates(rib, p, NULL, NULL, NULL, EVAL_RECONF); + rde_generate_updates(re, NULL, NULL, EVAL_RECONF); } static void diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 2e996435280..d9f728ae270 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.282 2023/02/09 13:43:23 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.283 2023/02/13 18:07:53 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker and @@ -392,9 +392,6 @@ void rde_pftable_add(uint16_t, struct prefix *); void rde_pftable_del(uint16_t, struct prefix *); int rde_evaluate_all(void); -void rde_generate_updates(struct rib *, struct prefix *, - struct prefix *, struct prefix *, struct prefix *, - enum eval_mode); uint32_t rde_local_as(void); int rde_decisionflags(void); void rde_peer_send_rrefresh(struct rde_peer *, uint8_t, uint8_t); @@ -412,6 +409,9 @@ struct rde_peer *peer_get(uint32_t); struct rde_peer *peer_match(struct ctl_neighbor *, uint32_t); struct rde_peer *peer_add(uint32_t, struct peer_config *); +void rde_generate_updates(struct rib_entry *, struct prefix *, + struct prefix *, enum eval_mode); + void peer_up(struct rde_peer *, struct session_up *); void peer_down(struct rde_peer *, void *); void peer_flush(struct rde_peer *, uint8_t, time_t); @@ -729,11 +729,11 @@ int nexthop_compare(struct nexthop *, struct nexthop *); /* rde_update.c */ void up_init(struct rde_peer *); void up_generate_updates(struct filter_head *, struct rde_peer *, - struct prefix *, struct prefix *); + struct rib_entry *); void up_generate_addpath(struct filter_head *, struct rde_peer *, - struct prefix *, struct prefix *); + struct rib_entry *); void up_generate_addpath_all(struct filter_head *, - struct rde_peer *, struct prefix *, struct prefix *, + struct rde_peer *, struct rib_entry *, struct prefix *, struct prefix *); void up_generate_default(struct filter_head *, struct rde_peer *, uint8_t); diff --git a/usr.sbin/bgpd/rde_decide.c b/usr.sbin/bgpd/rde_decide.c index b9d7860627b..9f0646703a1 100644 --- a/usr.sbin/bgpd/rde_decide.c +++ b/usr.sbin/bgpd/rde_decide.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_decide.c,v 1.98 2022/09/23 15:49:20 claudio Exp $ */ +/* $OpenBSD: rde_decide.c,v 1.99 2023/02/13 18:07:53 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker @@ -556,10 +556,9 @@ prefix_evaluate(struct rib_entry *re, struct prefix *new, struct prefix *old) * but remember that newbest may be NULL aka ineligible. * Additional decision may be made by the called functions. */ - rde_generate_updates(rib, newbest, oldbest, new, old, - EVAL_DEFAULT); if ((rib->flags & F_RIB_NOFIB) == 0) rde_send_kroute(rib, newbest, oldbest); + rde_generate_updates(re, new, old, EVAL_DEFAULT); return; } @@ -570,8 +569,7 @@ prefix_evaluate(struct rib_entry *re, struct prefix *new, struct prefix *old) */ if (rde_evaluate_all()) if ((new != NULL && prefix_eligible(new)) || old != NULL) - rde_generate_updates(rib, newbest, NULL, new, old, - EVAL_ALL); + rde_generate_updates(re, new, old, EVAL_ALL); } void @@ -630,9 +628,9 @@ prefix_evaluate_nexthop(struct prefix *p, enum nexthop_state state, * but remember that newbest may be NULL aka ineligible. * Additional decision may be made by the called functions. */ - rde_generate_updates(rib, newbest, oldbest, p, p, EVAL_DEFAULT); if ((rib->flags & F_RIB_NOFIB) == 0) rde_send_kroute(rib, newbest, oldbest); + rde_generate_updates(re, p, p, EVAL_DEFAULT); return; } @@ -642,5 +640,5 @@ prefix_evaluate_nexthop(struct prefix *p, enum nexthop_state state, * rde_generate_updates() will then take care of distribution. */ if (rde_evaluate_all()) - rde_generate_updates(rib, newbest, NULL, p, p, EVAL_ALL); + rde_generate_updates(re, p, p, EVAL_ALL); } diff --git a/usr.sbin/bgpd/rde_peer.c b/usr.sbin/bgpd/rde_peer.c index 040d1e96ba1..6d58de17301 100644 --- a/usr.sbin/bgpd/rde_peer.c +++ b/usr.sbin/bgpd/rde_peer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_peer.c,v 1.28 2023/02/09 13:43:23 claudio Exp $ */ +/* $OpenBSD: rde_peer.c,v 1.29 2023/02/13 18:07:53 claudio Exp $ */ /* * Copyright (c) 2019 Claudio Jeker @@ -207,23 +207,13 @@ peer_cmp(struct rde_peer *a, struct rde_peer *b) RB_GENERATE(peer_tree, rde_peer, entry, peer_cmp); static void -peer_generate_update(struct rde_peer *peer, uint16_t rib_id, - struct prefix *newbest, struct prefix *oldbest, +peer_generate_update(struct rde_peer *peer, struct rib_entry *re, struct prefix *newpath, struct prefix *oldpath, enum eval_mode mode) { uint8_t aid; - if (newbest != NULL) - aid = newbest->pt->aid; - else if (oldbest != NULL) - aid = oldbest->pt->aid; - else if (newpath != NULL) - aid = newpath->pt->aid; - else if (oldpath != NULL) - aid = oldpath->pt->aid; - else - return; + aid = re->prefix->aid; /* skip ourself */ if (peer == peerself) @@ -231,7 +221,7 @@ peer_generate_update(struct rde_peer *peer, uint16_t rib_id, if (peer->state != PEER_UP) return; /* skip peers using a different rib */ - if (peer->loc_rib_id != rib_id) + if (peer->loc_rib_id != re->rib_id) return; /* check if peer actually supports the address family */ if (peer->capa.mp[aid] == 0) @@ -248,37 +238,27 @@ peer_generate_update(struct rde_peer *peer, uint16_t rib_id, /* handle peers with add-path */ if (peer_has_add_path(peer, aid, CAPA_AP_SEND)) { if (peer->eval.mode == ADDPATH_EVAL_ALL) - up_generate_addpath_all(out_rules, peer, newbest, + up_generate_addpath_all(out_rules, peer, re, newpath, oldpath); else - up_generate_addpath(out_rules, peer, newbest, oldbest); + up_generate_addpath(out_rules, peer, re); return; } /* skip regular peers if the best path didn't change */ if (mode == EVAL_ALL && (peer->flags & PEERFLAG_EVALUATE_ALL) == 0) return; - up_generate_updates(out_rules, peer, newbest, oldbest); + up_generate_updates(out_rules, peer, re); } void -rde_generate_updates(struct rib *rib, struct prefix *newbest, - struct prefix *oldbest, struct prefix *newpath, struct prefix *oldpath, - enum eval_mode mode) +rde_generate_updates(struct rib_entry *re, struct prefix *newpath, + struct prefix *oldpath, enum eval_mode mode) { struct rde_peer *peer; - /* - * If oldbest is != NULL we know it was active and should be removed. - * If newbest is != NULL we know it is reachable and then we should - * generate an update. - */ - if (oldbest == NULL && newbest == NULL) - return; - RB_FOREACH(peer, peer_tree, &peertable) - peer_generate_update(peer, rib->id, newbest, oldbest, newpath, - oldpath, mode); + peer_generate_update(peer, re, newpath, oldpath, mode); } /* @@ -389,7 +369,7 @@ rde_up_dump_upcall(struct rib_entry *re, void *ptr) if ((p = prefix_best(re)) == NULL) /* no eligible prefix, not even for 'evaluate all' */ return; - peer_generate_update(peer, re->rib_id, p, NULL, NULL, NULL, 0); + peer_generate_update(peer, re, NULL, NULL, 0); } static void diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c index 60437202312..808c5c728ff 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.155 2023/02/11 08:50:43 claudio Exp $ */ +/* $OpenBSD: rde_update.c,v 1.156 2023/02/13 18:07:53 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker @@ -206,22 +206,18 @@ up_process_prefix(struct filter_head *rules, struct rde_peer *peer, void up_generate_updates(struct filter_head *rules, struct rde_peer *peer, - struct prefix *new, struct prefix *old) + struct rib_entry *re) { struct bgpd_addr addr; - struct prefix *p; + struct prefix *new, *p; uint8_t prefixlen; - if (new == NULL) { - pt_getaddr(old->pt, &addr); - prefixlen = old->pt->prefixlen; - } else { - pt_getaddr(new->pt, &addr); - prefixlen = new->pt->prefixlen; - } + pt_getaddr(re->prefix, &addr); + prefixlen = re->prefix->prefixlen; p = prefix_adjout_lookup(peer, &addr, prefixlen); + new = prefix_best(re); while (new != NULL) { switch (up_process_prefix(rules, peer, new, p, &addr, prefixlen)) { @@ -255,21 +251,16 @@ done: */ void up_generate_addpath(struct filter_head *rules, struct rde_peer *peer, - struct prefix *new, struct prefix *old) + struct rib_entry *re) { struct bgpd_addr addr; - struct prefix *head, *p; + struct prefix *head, *new, *p; uint8_t prefixlen; int maxpaths = 0, extrapaths = 0, extra; int checkmode = 1; - if (new == NULL) { - pt_getaddr(old->pt, &addr); - prefixlen = old->pt->prefixlen; - } else { - pt_getaddr(new->pt, &addr); - prefixlen = new->pt->prefixlen; - } + pt_getaddr(re->prefix, &addr); + prefixlen = re->prefix->prefixlen; head = prefix_adjout_lookup(peer, &addr, prefixlen); @@ -278,11 +269,8 @@ up_generate_addpath(struct filter_head *rules, struct rde_peer *peer, p->flags |= PREFIX_FLAG_STALE; /* update paths */ - for ( ; new != NULL; new = TAILQ_NEXT(new, entry.list.rib)) { - /* since list is sorted, stop at first invalid prefix */ - if (!prefix_eligible(new)) - break; - + new = prefix_best(re); + while (new != NULL) { /* check limits and stop when a limit is reached */ if (peer->eval.maxpaths != 0 && maxpaths >= peer->eval.maxpaths) @@ -337,6 +325,11 @@ up_generate_addpath(struct filter_head *rules, struct rde_peer *peer, /* just give up */ return; } + + /* only allow valid prefixes */ + new = TAILQ_NEXT(new, entry.list.rib); + if (new == NULL || !prefix_eligible(new)) + break; } /* withdraw stale paths */ @@ -352,55 +345,39 @@ up_generate_addpath(struct filter_head *rules, struct rde_peer *peer, */ void up_generate_addpath_all(struct filter_head *rules, struct rde_peer *peer, - struct prefix *best, struct prefix *new, struct prefix *old) + struct rib_entry *re, struct prefix *new, struct prefix *old) { struct bgpd_addr addr; - struct prefix *p, *next, *head = NULL; + 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 */ - pt_getaddr(best->pt, &addr); - prefixlen = best->pt->prefixlen; - head = prefix_adjout_lookup(peer, &addr, prefixlen); for (p = head; p != NULL; p = prefix_adjout_next(peer, p)) p->flags |= PREFIX_FLAG_STALE; - new = best; + new = prefix_best(re); all = 1; } if (old != NULL) { /* withdraw stale paths */ - pt_getaddr(old->pt, &addr); - p = prefix_adjout_get(peer, old->path_id_tx, &addr, - old->pt->prefixlen); + p = prefix_adjout_get(peer, old->path_id_tx, &addr, prefixlen); if (p != NULL) prefix_adjout_withdraw(p); } - if (new != NULL) { - pt_getaddr(new->pt, &addr); - prefixlen = new->pt->prefixlen; - } - /* add new path (or multiple if all is set) */ - for (; new != NULL; new = next) { - if (all) - next = TAILQ_NEXT(new, entry.list.rib); - else - next = NULL; - - /* only allow valid prefixes */ - if (!prefix_eligible(new)) - break; - + while (new != NULL) { switch (up_process_prefix(rules, peer, new, (void *)-1, &addr, prefixlen)) { case UP_OK: @@ -411,6 +388,14 @@ up_generate_addpath_all(struct filter_head *rules, struct rde_peer *peer, /* just give up */ return; } + + if (!all) + break; + + /* only allow valid prefixes */ + new = TAILQ_NEXT(new, entry.list.rib); + if (new == NULL || !prefix_eligible(new)) + break; } if (all) { -- 2.20.1