Remove the active prefix cache in struct rib_entry. I need the space
authorclaudio <claudio@openbsd.org>
Mon, 21 Mar 2022 17:35:56 +0000 (17:35 +0000)
committerclaudio <claudio@openbsd.org>
Mon, 21 Mar 2022 17:35:56 +0000 (17:35 +0000)
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@

usr.sbin/bgpd/rde.c
usr.sbin/bgpd/rde.h
usr.sbin/bgpd/rde_decide.c
usr.sbin/bgpd/rde_peer.c
usr.sbin/bgpd/rde_rib.c

index e220e10..6d85733 100644 (file)
@@ -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 <henning@openbsd.org>
@@ -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
index eebe96a..09c0871 100644 (file)
@@ -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 <claudio@openbsd.org> 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 *,
index a28d981..0c88165 100644 (file)
@@ -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 <claudio@openbsd.org>
@@ -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);
 }
index c3c0647..9414855 100644 (file)
@@ -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 <claudio@openbsd.org>
@@ -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
index 0be448c..0ccdffd 100644 (file)
@@ -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 <claudio@openbsd.org>
@@ -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;