Pass struct rib_entry to rde_generate_updates() instead of struct rib.
authorclaudio <claudio@openbsd.org>
Mon, 13 Feb 2023 18:07:53 +0000 (18:07 +0000)
committerclaudio <claudio@openbsd.org>
Mon, 13 Feb 2023 18:07:53 +0000 (18:07 +0000)
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
usr.sbin/bgpd/rde.h
usr.sbin/bgpd/rde_decide.c
usr.sbin/bgpd/rde_peer.c
usr.sbin/bgpd/rde_update.c

index 3a25162..9cb68ef 100644 (file)
@@ -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 <henning@openbsd.org>
@@ -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
index 2e99643..d9f728a 100644 (file)
@@ -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 <claudio@openbsd.org> 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);
index b9d7860..9f06467 100644 (file)
@@ -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 <claudio@openbsd.org>
@@ -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);
 }
index 040d1e9..6d58de1 100644 (file)
@@ -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 <claudio@openbsd.org>
@@ -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
index 6043720..808c5c7 100644 (file)
@@ -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 <claudio@openbsd.org>
@@ -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) {