Switch from a LIST to TAILQ for the structure to store prefixes on a
authorclaudio <claudio@openbsd.org>
Tue, 22 Mar 2022 10:53:08 +0000 (10:53 +0000)
committerclaudio <claudio@openbsd.org>
Tue, 22 Mar 2022 10:53:08 +0000 (10:53 +0000)
rib_entry. Mostly mechanical, this simplifies prefix_insert() and
prefix_remove() since the redo queue can now just use TAILQ_INSERT_TAIL().
rde_softreconfig_sync_reeval() needs to use TAILQ_CONCAT() to move
the list of prefixes over to the local TAILQ_HEAD to reapply them later.
OK tb@

usr.sbin/bgpd/mrt.c
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
usr.sbin/bgpd/rde_update.c

index de258c9..f129e82 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mrt.c,v 1.106 2022/02/06 09:51:19 claudio Exp $ */
+/*     $OpenBSD: mrt.c,v 1.107 2022/03/22 10:53:08 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -620,7 +620,7 @@ mrt_dump_entry_v2_rib(struct rib_entry *re, struct ibuf **nb, struct ibuf **apb,
        *np = 0;
        *app = 0;
 
-       LIST_FOREACH(p, &re->prefix_h, entry.list.rib) {
+       TAILQ_FOREACH(p, &re->prefix_h, entry.list.rib) {
                struct nexthop          *nexthop;
                struct bgpd_addr        *nh;
                struct ibuf             *tbuf;
@@ -895,7 +895,7 @@ mrt_dump_upcall(struct rib_entry *re, void *ptr)
         * dumps the table so we do the same. If only the active route should
         * be dumped p should be set to p = pt->active.
         */
-       LIST_FOREACH(p, &re->prefix_h, entry.list.rib) {
+       TAILQ_FOREACH(p, &re->prefix_h, entry.list.rib) {
                if (mrtbuf->type == MRT_TABLE_DUMP)
                        mrt_dump_entry(mrtbuf, p, mrtbuf->seqnum++,
                            prefix_peer(p));
index 6d85733..bb8c2dc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.c,v 1.543 2022/03/21 17:35:56 claudio Exp $ */
+/*     $OpenBSD: rde.c,v 1.544 2022/03/22 10:53:08 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -2536,7 +2536,7 @@ rde_dump_upcall(struct rib_entry *re, void *ptr)
        struct rde_dump_ctx     *ctx = ptr;
        struct prefix           *p;
 
-       LIST_FOREACH(p, &re->prefix_h, entry.list.rib)
+       TAILQ_FOREACH(p, &re->prefix_h, entry.list.rib)
                rde_dump_filter(p, &ctx->req, 0);
 }
 
@@ -2557,14 +2557,14 @@ rde_dump_prefix_upcall(struct rib_entry *re, void *ptr)
                        return;
                if (!prefix_compare(&ctx->req.prefix, &addr,
                    ctx->req.prefixlen))
-                       LIST_FOREACH(p, &re->prefix_h, entry.list.rib)
+                       TAILQ_FOREACH(p, &re->prefix_h, entry.list.rib)
                                rde_dump_filter(p, &ctx->req, 0);
        } else {
                if (ctx->req.prefixlen < pt->prefixlen)
                        return;
                if (!prefix_compare(&addr, &ctx->req.prefix,
                    pt->prefixlen))
-                       LIST_FOREACH(p, &re->prefix_h, entry.list.rib)
+                       TAILQ_FOREACH(p, &re->prefix_h, entry.list.rib)
                                rde_dump_filter(p, &ctx->req, 0);
        }
 }
@@ -3673,7 +3673,7 @@ rde_softreconfig_in(struct rib_entry *re, void *bula)
 
        pt = re->prefix;
        pt_getaddr(pt, &prefix);
-       LIST_FOREACH(p, &re->prefix_h, entry.list.rib) {
+       TAILQ_FOREACH(p, &re->prefix_h, entry.list.rib) {
                asp = prefix_aspath(p);
                peer = prefix_peer(p);
 
@@ -3736,7 +3736,7 @@ rde_softreconfig_out(struct rib_entry *re, void *bula)
 static void
 rde_softreconfig_sync_reeval(struct rib_entry *re, void *arg)
 {
-       struct prefix_list      prefixes;
+       struct prefix_queue     prefixes = TAILQ_HEAD_INITIALIZER(prefixes);
        struct prefix           *p, *next;
        struct rib              *rib = arg;
 
@@ -3746,7 +3746,7 @@ rde_softreconfig_sync_reeval(struct rib_entry *re, void *arg)
                 * all dependent adj-rib-out were already flushed
                 * unlink nexthop if it was linked
                 */
-               LIST_FOREACH(p, &re->prefix_h, entry.list.rib) {
+               TAILQ_FOREACH(p, &re->prefix_h, entry.list.rib) {
                        if (p->flags & PREFIX_NEXTHOP_LINKED)
                                nexthop_unlink(p);
                }
@@ -3754,8 +3754,7 @@ rde_softreconfig_sync_reeval(struct rib_entry *re, void *arg)
        }
 
        /* evaluation process is turned on, so evaluate all prefixes again */
-       prefixes = re->prefix_h;
-       LIST_INIT(&re->prefix_h);
+       TAILQ_CONCAT(&prefixes, &re->prefix_h, entry.list.rib);
 
        /*
         * TODO: this code works but is not optimal. prefix_evaluate()
@@ -3763,9 +3762,9 @@ rde_softreconfig_sync_reeval(struct rib_entry *re, void *arg)
         * to resort the list once and then call rde_generate_updates()
         * and rde_send_kroute() once.
         */
-       LIST_FOREACH_SAFE(p, &prefixes, entry.list.rib, next) {
+       TAILQ_FOREACH_SAFE(p, &prefixes, entry.list.rib, next) {
                /* need to re-link the nexthop if not already linked */
-               LIST_REMOVE(p, entry.list.rib);
+               TAILQ_REMOVE(&prefixes, p, entry.list.rib);
                if ((p->flags & PREFIX_NEXTHOP_LINKED) == 0)
                        nexthop_link(p);
                prefix_evaluate(re, p, NULL);
@@ -3818,7 +3817,7 @@ rde_roa_softreload(struct rib_entry *re, void *bula)
 
        pt = re->prefix;
        pt_getaddr(pt, &prefix);
-       LIST_FOREACH(p, &re->prefix_h, entry.list.rib) {
+       TAILQ_FOREACH(p, &re->prefix_h, entry.list.rib) {
                asp = prefix_aspath(p);
                peer = prefix_peer(p);
 
@@ -4163,7 +4162,7 @@ network_dump_upcall(struct rib_entry *re, void *ptr)
        struct bgpd_addr         addr;
        struct rde_dump_ctx     *ctx = ptr;
 
-       LIST_FOREACH(p, &re->prefix_h, entry.list.rib) {
+       TAILQ_FOREACH(p, &re->prefix_h, entry.list.rib) {
                asp = prefix_aspath(p);
                if (!(asp->flags & F_PREFIX_ANNOUNCED))
                        continue;
index 09c0871..252dbc3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.h,v 1.250 2022/03/21 17:35:56 claudio Exp $ */
+/*     $OpenBSD: rde.h,v 1.251 2022/03/22 10:53:08 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -38,11 +38,12 @@ enum peer_state {
 };
 
 LIST_HEAD(prefix_list, prefix);
+TAILQ_HEAD(prefix_queue, prefix);
 RB_HEAD(rib_tree, rib_entry);
 
 struct rib_entry {
        RB_ENTRY(rib_entry)      rib_e;
-       struct prefix_list       prefix_h;
+       struct prefix_queue      prefix_h;
        struct pt_entry         *prefix;
        uint16_t                 rib_id;
        uint16_t                 lock;
@@ -315,7 +316,8 @@ struct pt_entry_vpn6 {
 struct prefix {
        union {
                struct {
-                       LIST_ENTRY(prefix)       rib, nexthop;
+                       TAILQ_ENTRY(prefix)      rib;
+                       LIST_ENTRY(prefix)       nexthop;
                        struct rib_entry        *re;
                } list;
                struct {
index 0c88165..1dbb4a5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_decide.c,v 1.90 2022/03/21 17:35:56 claudio Exp $ */
+/*     $OpenBSD: rde_decide.c,v 1.91 2022/03/22 10:53:08 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -301,16 +301,16 @@ prefix_cmp(struct prefix *p1, struct prefix *p2, int *testall)
 void
 prefix_insert(struct prefix *new, struct prefix *ep, struct rib_entry *re)
 {
-       struct prefix_list redo = LIST_HEAD_INITIALIZER(redo);
-       struct prefix *xp, *np, *tailp = NULL, *insertp = ep;
+       struct prefix_queue redo = TAILQ_HEAD_INITIALIZER(redo);
+       struct prefix *xp, *np, *insertp = ep;
        int testall, selected = 0;
 
        /* start scan at the entry point (ep) or the head if ep == NULL */
        if (ep == NULL)
-               ep = LIST_FIRST(&re->prefix_h);
+               ep = TAILQ_FIRST(&re->prefix_h);
 
        for (xp = ep; xp != NULL; xp = np) {
-               np = LIST_NEXT(xp, entry.list.rib);
+               np = TAILQ_NEXT(xp, entry.list.rib);
 
                if (prefix_cmp(new, xp, &testall) > 0) {
                        /* new is preferred over xp */
@@ -321,14 +321,8 @@ prefix_insert(struct prefix *new, struct prefix *ep, struct rib_entry *re)
                                 * MED inversion, take out prefix and
                                 * put it onto redo queue.
                                 */
-                               LIST_REMOVE(xp, entry.list.rib);
-                               if (tailp == NULL)
-                                       LIST_INSERT_HEAD(&redo, xp,
-                                           entry.list.rib);
-                               else
-                                       LIST_INSERT_AFTER(tailp, xp,
-                                           entry.list.rib);
-                               tailp = xp;
+                               TAILQ_REMOVE(&re->prefix_h, xp, entry.list.rib);
+                               TAILQ_INSERT_TAIL(&redo, xp, entry.list.rib);
                        } else {
                                /*
                                 * lock insertion point and
@@ -355,14 +349,14 @@ prefix_insert(struct prefix *new, struct prefix *ep, struct rib_entry *re)
        }
 
        if (insertp == NULL)
-               LIST_INSERT_HEAD(&re->prefix_h, new, entry.list.rib);
+               TAILQ_INSERT_HEAD(&re->prefix_h, new, entry.list.rib);
        else
-               LIST_INSERT_AFTER(insertp, new, entry.list.rib);
+               TAILQ_INSERT_AFTER(&re->prefix_h, insertp, new, entry.list.rib);
 
        /* Fixup MED order again. All elements are < new */
-       while (!LIST_EMPTY(&redo)) {
-               xp = LIST_FIRST(&redo);
-               LIST_REMOVE(xp, entry.list.rib);
+       while (!TAILQ_EMPTY(&redo)) {
+               xp = TAILQ_FIRST(&redo);
+               TAILQ_REMOVE(&redo, xp, entry.list.rib);
 
                prefix_insert(xp, new, re);
        }
@@ -380,18 +374,18 @@ prefix_insert(struct prefix *new, struct prefix *ep, struct rib_entry *re)
 void
 prefix_remove(struct prefix *old, struct rib_entry *re)
 {
-       struct prefix_list redo = LIST_HEAD_INITIALIZER(redo);
-       struct prefix *xp, *np, *tailp = NULL;
+       struct prefix_queue redo = TAILQ_HEAD_INITIALIZER(redo);
+       struct prefix *xp, *np;
        int testall;
 
-       xp = LIST_NEXT(old, entry.list.rib);
-       LIST_REMOVE(old, entry.list.rib);
+       xp = TAILQ_NEXT(old, entry.list.rib);
+       TAILQ_REMOVE(&re->prefix_h, old, entry.list.rib);
        /* check if a MED inversion could be possible */
        prefix_cmp(old, xp, &testall);
        if (testall > 0) {
                /* maybe MED route, scan tail for other possible routes */
                for (; xp != NULL; xp = np) {
-                       np = LIST_NEXT(xp, entry.list.rib);
+                       np = TAILQ_NEXT(xp, entry.list.rib);
 
                        /* only interested in the testall result */
                        prefix_cmp(old, xp, &testall);
@@ -402,22 +396,16 @@ prefix_remove(struct prefix *old, struct rib_entry *re)
                                 * possible MED inversion, take out prefix and
                                 * put it onto redo queue.
                                 */
-                               LIST_REMOVE(xp, entry.list.rib);
-                               if (tailp == NULL)
-                                       LIST_INSERT_HEAD(&redo, xp,
-                                           entry.list.rib);
-                               else
-                                       LIST_INSERT_AFTER(tailp, xp,
-                                           entry.list.rib);
-                               tailp = xp;
+                               TAILQ_REMOVE(&re->prefix_h, xp, entry.list.rib);
+                               TAILQ_INSERT_TAIL(&redo, xp, entry.list.rib);
                        }
                }
        }
 
        /* Fixup MED order again, reinsert prefixes from the start */
-       while (!LIST_EMPTY(&redo)) {
-               xp = LIST_FIRST(&redo);
-               LIST_REMOVE(xp, entry.list.rib);
+       while (!TAILQ_EMPTY(&redo)) {
+               xp = TAILQ_FIRST(&redo);
+               TAILQ_REMOVE(&redo, xp, entry.list.rib);
 
                prefix_insert(xp, NULL, re);
        }
@@ -454,7 +442,7 @@ prefix_best(struct rib_entry *re)
                /* decision process is turned off */
                return NULL;
 
-       xp = LIST_FIRST(&re->prefix_h);
+       xp = TAILQ_FIRST(&re->prefix_h);
        if (xp != NULL && !prefix_eligible(xp))
                xp = NULL;
        return xp;
@@ -477,9 +465,9 @@ prefix_evaluate(struct rib_entry *re, struct prefix *new, struct prefix *old)
        if (rib->flags & F_RIB_NOEVALUATE) {
                /* decision process is turned off */
                if (old != NULL)
-                       LIST_REMOVE(old, entry.list.rib);
+                       TAILQ_REMOVE(&re->prefix_h, old, entry.list.rib);
                if (new != NULL)
-                       LIST_INSERT_HEAD(&re->prefix_h, new, entry.list.rib);
+                       TAILQ_INSERT_HEAD(&re->prefix_h, new, entry.list.rib);
                return;
        }
 
@@ -491,7 +479,7 @@ prefix_evaluate(struct rib_entry *re, struct prefix *new, struct prefix *old)
        if (new != NULL)
                prefix_insert(new, NULL, re);
 
-       xp = LIST_FIRST(&re->prefix_h);
+       xp = TAILQ_FIRST(&re->prefix_h);
        if (xp != NULL && !prefix_eligible(xp))
                xp = NULL;
 
index 9414855..4ed02e2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_peer.c,v 1.14 2022/03/21 17:35:56 claudio Exp $ */
+/*     $OpenBSD: rde_peer.c,v 1.15 2022/03/22 10:53:08 claudio Exp $ */
 
 /*
  * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
@@ -248,7 +248,7 @@ peer_flush_upcall(struct rib_entry *re, void *arg)
 
        pt_getaddr(re->prefix, &addr);
        prefixlen = re->prefix->prefixlen;
-       LIST_FOREACH_SAFE(p, &re->prefix_h, entry.list.rib, np) {
+       TAILQ_FOREACH_SAFE(p, &re->prefix_h, entry.list.rib, np) {
                if (peer != prefix_peer(p))
                        continue;
                if (staletime && p->lastchange > staletime)
index 0ccdffd..e09a66d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_rib.c,v 1.236 2022/03/21 17:35:56 claudio Exp $ */
+/*     $OpenBSD: rde_rib.c,v 1.237 2022/03/22 10:53:08 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -252,7 +252,7 @@ rib_free(struct rib *rib)
                 * an empty check in prefix_destroy() it is not possible to
                 * use the default for loop.
                 */
-               while ((p = LIST_FIRST(&re->prefix_h))) {
+               while ((p = TAILQ_FIRST(&re->prefix_h))) {
                        struct rde_aspath *asp = prefix_aspath(p);
                        if (asp && asp->pftableid)
                                rde_pftable_del(asp->pftableid, p);
@@ -353,7 +353,7 @@ rib_add(struct rib *rib, struct bgpd_addr *prefix, int prefixlen)
        if ((re = calloc(1, sizeof(*re))) == NULL)
                fatal("rib_add");
 
-       LIST_INIT(&re->prefix_h);
+       TAILQ_INIT(&re->prefix_h);
        re->prefix = pt_ref(pte);
        re->rib_id = rib->id;
 
@@ -391,7 +391,7 @@ rib_remove(struct rib_entry *re)
 int
 rib_empty(struct rib_entry *re)
 {
-       return LIST_EMPTY(&re->prefix_h);
+       return TAILQ_EMPTY(&re->prefix_h);
 }
 
 static struct rib_entry *
@@ -1496,7 +1496,7 @@ prefix_bypeer(struct rib_entry *re, struct rde_peer *peer, uint32_t path_id)
 {
        struct prefix   *p;
 
-       LIST_FOREACH(p, &re->prefix_h, entry.list.rib)
+       TAILQ_FOREACH(p, &re->prefix_h, entry.list.rib)
                if (prefix_peer(p) == peer && p->path_id == path_id)
                        return (p);
        return (NULL);
index fe72cb0..eb56875 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_update.c,v 1.137 2022/03/15 16:50:29 claudio Exp $ */
+/*     $OpenBSD: rde_update.c,v 1.138 2022/03/22 10:53:08 claudio Exp $ */
 
 /*
  * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -154,7 +154,7 @@ again:
                    prefixlen, prefix_vstate(new), &state) == ACTION_DENY) {
                        rde_filterstate_clean(&state);
                        if (peer->flags & PEERFLAG_EVALUATE_ALL)
-                               new = LIST_NEXT(new, entry.list.rib);
+                               new = TAILQ_NEXT(new, entry.list.rib);
                        else
                                new = NULL;
                        if (new != NULL && !prefix_eligible(new))