From: claudio Date: Mon, 21 Mar 2022 17:35:56 +0000 (+0000) Subject: Remove the active prefix cache in struct rib_entry. I need the space X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=8bf5540b3f935e190fa04dc4cb5958fbe5bb65e9;p=openbsd Remove the active prefix cache in struct rib_entry. I need the space and it also makes less sense to track this with ECMP or add-path. Replace the re->active access with prefix_best(re) which does the check on the spot. Feedback and OK tb@ --- diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index e220e105624..6d857333807 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.542 2022/03/21 13:33:20 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.543 2022/03/21 17:35:56 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -2400,7 +2400,7 @@ rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp, pid_t pid, int flags, rib.validation_state = p->validation_state; rib.flags = 0; re = prefix_re(p); - if (re != NULL && re->active == p) + if (re != NULL && prefix_best(re) == p) rib.flags |= F_PREF_BEST; if (!peer->conf.ebgp) rib.flags |= F_PREF_INTERNAL; @@ -2502,7 +2502,7 @@ rde_dump_filter(struct prefix *p, struct ctl_show_rib_request *req, int adjout) re = prefix_re(p); if (asp == NULL) /* skip pending withdraw in Adj-RIB-Out */ return; - if ((req->flags & F_CTL_BEST) && re != NULL && re->active != p) + if ((req->flags & F_CTL_BEST) && re != NULL && prefix_best(re) != p) return; if ((req->flags & F_CTL_INVALID) && (asp->flags & F_ATTR_PARSE_ERR) == 0) @@ -3713,11 +3713,11 @@ rde_softreconfig_in(struct rib_entry *re, void *bula) static void rde_softreconfig_out(struct rib_entry *re, void *bula) { - struct prefix *p = re->active; + struct prefix *p; struct rde_peer *peer; uint8_t aid = re->prefix->aid; - if (p == NULL) + if ((p = prefix_best(re)) == NULL) /* no valid path for prefix */ return; @@ -3750,12 +3750,10 @@ rde_softreconfig_sync_reeval(struct rib_entry *re, void *arg) if (p->flags & PREFIX_NEXTHOP_LINKED) nexthop_unlink(p); } - re->active = NULL; return; } /* evaluation process is turned on, so evaluate all prefixes again */ - re->active = NULL; prefixes = re->prefix_h; LIST_INIT(&re->prefix_h); @@ -3777,8 +3775,10 @@ rde_softreconfig_sync_reeval(struct rib_entry *re, void *arg) static void rde_softreconfig_sync_fib(struct rib_entry *re, void *bula) { - if (re->active) - rde_send_kroute(re_rib(re), re->active, NULL); + struct prefix *p; + + if ((p = prefix_best(re)) != NULL) + rde_send_kroute(re_rib(re), p, NULL); } static void diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index eebe96aeb32..09c0871358a 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.249 2022/03/21 13:33:20 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.250 2022/03/21 17:35:56 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker and @@ -43,7 +43,6 @@ RB_HEAD(rib_tree, rib_entry); struct rib_entry { RB_ENTRY(rib_entry) rib_e; struct prefix_list prefix_h; - struct prefix *active; /* for fast access */ struct pt_entry *prefix; uint16_t rib_id; uint16_t lock; @@ -499,8 +498,10 @@ communities_unref(struct rde_community *comm) int community_to_rd(struct community *, uint64_t *); /* rde_decide.c */ -int prefix_eligible(struct prefix *); -void prefix_evaluate(struct rib_entry *, struct prefix *, struct prefix *); +int prefix_eligible(struct prefix *); +struct prefix *prefix_best(struct rib_entry *); +void prefix_evaluate(struct rib_entry *, struct prefix *, + struct prefix *); /* rde_filter.c */ void rde_apply_set(struct filter_set_head *, struct rde_peer *, diff --git a/usr.sbin/bgpd/rde_decide.c b/usr.sbin/bgpd/rde_decide.c index a28d98188f6..0c88165e23d 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.89 2022/03/03 13:06:15 claudio Exp $ */ +/* $OpenBSD: rde_decide.c,v 1.90 2022/03/21 17:35:56 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker @@ -443,6 +443,23 @@ prefix_eligible(struct prefix *p) return 1; } +struct prefix * +prefix_best(struct rib_entry *re) +{ + struct prefix *xp; + struct rib *rib; + + rib = re_rib(re); + if (rib->flags & F_RIB_NOEVALUATE) + /* decision process is turned off */ + return NULL; + + xp = LIST_FIRST(&re->prefix_h); + if (xp != NULL && !prefix_eligible(xp)) + xp = NULL; + return xp; +} + /* * Find the correct place to insert the prefix in the prefix list. * If the active prefix has changed we need to send an update also special @@ -453,7 +470,7 @@ prefix_eligible(struct prefix *p) void prefix_evaluate(struct rib_entry *re, struct prefix *new, struct prefix *old) { - struct prefix *xp; + struct prefix *xp, *active; struct rib *rib; rib = re_rib(re); @@ -463,19 +480,11 @@ prefix_evaluate(struct rib_entry *re, struct prefix *new, struct prefix *old) LIST_REMOVE(old, entry.list.rib); if (new != NULL) LIST_INSERT_HEAD(&re->prefix_h, new, entry.list.rib); - if (re->active) { - /* - * During reloads it is possible that the decision - * process is turned off but prefixes are still - * active. Clean up now to ensure that the RIB - * is consistant. - */ - rde_generate_updates(rib, NULL, re->active, 0); - re->active = NULL; - } return; } + active = prefix_best(re); + if (old != NULL) prefix_remove(old, re); @@ -490,16 +499,15 @@ prefix_evaluate(struct rib_entry *re, struct prefix *new, struct prefix *old) * If the active prefix changed or the active prefix was removed * and added again then generate an update. */ - if (re->active != xp || (old != NULL && xp == old)) { + if (active != xp || (old != NULL && xp == old)) { /* * Send update withdrawing re->active and adding xp * but remember that xp may be NULL aka ineligible. * Additional decision may be made by the called functions. */ - rde_generate_updates(rib, xp, re->active, 0); + rde_generate_updates(rib, xp, active, 0); if ((rib->flags & F_RIB_NOFIB) == 0) - rde_send_kroute(rib, xp, re->active); - re->active = xp; + rde_send_kroute(rib, xp, active); return; } @@ -510,5 +518,5 @@ 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, re->active, NULL, 1); + rde_generate_updates(rib, prefix_best(re), NULL, 1); } diff --git a/usr.sbin/bgpd/rde_peer.c b/usr.sbin/bgpd/rde_peer.c index c3c0647537e..94148550c27 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.13 2022/02/06 09:51:19 claudio Exp $ */ +/* $OpenBSD: rde_peer.c,v 1.14 2022/03/21 17:35:56 claudio Exp $ */ /* * Copyright (c) 2019 Claudio Jeker @@ -308,6 +308,7 @@ static void rde_up_dump_upcall(struct rib_entry *re, void *ptr) { struct rde_peer *peer = ptr; + struct prefix *p; if (peer->state != PEER_UP) return; @@ -319,10 +320,10 @@ rde_up_dump_upcall(struct rib_entry *re, void *ptr) aid2str(re->prefix->aid)); /* no eligible prefix, not even for 'evaluate all' */ - if (re->active == NULL) + if ((p = prefix_best(re)) == NULL) return; - up_generate_updates(out_rules, peer, re->active, NULL); + up_generate_updates(out_rules, peer, p, NULL); } static void diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c index 0be448ce6f5..0ccdffdd39e 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.235 2022/03/21 13:33:20 claudio Exp $ */ +/* $OpenBSD: rde_rib.c,v 1.236 2022/03/21 17:35:56 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker @@ -1523,7 +1523,7 @@ prefix_evaluate_all(struct prefix *p, enum nexthop_state state, */ if (state == NEXTHOP_REACH) { if ((re_rib(re)->flags & F_RIB_NOFIB) == 0 && - p == re->active) + p == prefix_best(re)) rde_send_kroute(re_rib(re), p, NULL); } return;