Switch prefix_adjout_get and new prefix_adjout_first to use a pt_entry
authorclaudio <claudio@openbsd.org>
Wed, 29 Mar 2023 10:46:11 +0000 (10:46 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 29 Mar 2023 10:46:11 +0000 (10:46 +0000)
as argument instead of the bgpd_addr + prefixlen.

Do the same with prefix_adjout_update but leave prefix_adjout_lookup
and prefix_adjout_match since those are used by bgpctl code that does
not use pt_entry structs.

With this most of the update code no longer needs struct bgpd_addr and
pt_getaddr().
OK tb@

usr.sbin/bgpd/rde.h
usr.sbin/bgpd/rde_rib.c
usr.sbin/bgpd/rde_update.c

index 1d6abfc..cd33d5f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.h,v 1.288 2023/03/28 15:17:34 claudio Exp $ */
+/*     $OpenBSD: rde.h,v 1.289 2023/03/29 10:46:11 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -580,19 +580,20 @@ void               path_put(struct rde_aspath *);
 struct prefix  *prefix_get(struct rib *, struct rde_peer *, uint32_t,
                    struct bgpd_addr *, int);
 struct prefix  *prefix_adjout_get(struct rde_peer *, uint32_t,
-                   struct bgpd_addr *, int);
-struct prefix  *prefix_match(struct rde_peer *, struct bgpd_addr *);
-struct prefix  *prefix_adjout_match(struct rde_peer *, struct bgpd_addr *);
+                   struct pt_entry *);
+struct prefix  *prefix_adjout_first(struct rde_peer *, struct pt_entry *);
+struct prefix  *prefix_adjout_next(struct rde_peer *, struct prefix *);
 struct prefix  *prefix_adjout_lookup(struct rde_peer *, struct bgpd_addr *,
                    int);
-struct prefix  *prefix_adjout_next(struct rde_peer *, struct prefix *);
+struct prefix  *prefix_adjout_match(struct rde_peer *, struct bgpd_addr *);
+struct prefix  *prefix_match(struct rde_peer *, struct bgpd_addr *);
 int             prefix_update(struct rib *, struct rde_peer *, uint32_t,
                    uint32_t, struct filterstate *, struct bgpd_addr *, int);
 int             prefix_withdraw(struct rib *, struct rde_peer *, uint32_t,
                    struct bgpd_addr *, int);
 void            prefix_add_eor(struct rde_peer *, uint8_t);
 void            prefix_adjout_update(struct prefix *, struct rde_peer *,
-                   struct filterstate *, struct bgpd_addr *, int, uint32_t);
+                   struct filterstate *, struct pt_entry *, uint32_t);
 void            prefix_adjout_withdraw(struct prefix *);
 void            prefix_adjout_destroy(struct prefix *);
 void            prefix_adjout_dump(struct rde_peer *, void *,
index bc4ae02..99c7119 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_rib.c,v 1.256 2023/03/28 15:17:34 claudio Exp $ */
+/*     $OpenBSD: rde_rib.c,v 1.257 2023/03/29 10:46:11 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -873,12 +873,12 @@ prefix_get(struct rib *rib, struct rde_peer *peer, uint32_t path_id,
  */
 struct prefix *
 prefix_adjout_get(struct rde_peer *peer, uint32_t path_id_tx,
-    struct bgpd_addr *prefix, int prefixlen)
+    struct pt_entry *pte)
 {
        struct prefix xp;
 
        memset(&xp, 0, sizeof(xp));
-       xp.pt = pt_fill(prefix, prefixlen);
+       xp.pt = pte;
        xp.path_id_tx = path_id_tx;
 
        return RB_FIND(prefix_index, &peer->adj_rib_out, &xp);
@@ -889,13 +889,12 @@ prefix_adjout_get(struct rde_peer *peer, uint32_t path_id_tx,
  * Returns NULL if not found.
  */
 struct prefix *
-prefix_adjout_lookup(struct rde_peer *peer, struct bgpd_addr *prefix,
-    int prefixlen)
+prefix_adjout_first(struct rde_peer *peer, struct pt_entry *pte)
 {
        struct prefix xp, *np;
 
        memset(&xp, 0, sizeof(xp));
-       xp.pt = pt_fill(prefix, prefixlen);
+       xp.pt = pte;
 
        np = RB_NFIND(prefix_index, &peer->adj_rib_out, &xp);
        if (np == NULL || pt_prefix_cmp(np->pt, xp.pt) != 0)
@@ -917,6 +916,16 @@ prefix_adjout_next(struct rde_peer *peer, struct prefix *p)
        return np;
 }
 
+/*
+ * Lookup addr/prefixlen in the peer prefix_index. Returns first match.
+ * Returns NULL if not found.
+ */
+struct prefix *
+prefix_adjout_lookup(struct rde_peer *peer, struct bgpd_addr *addr, int plen)
+{
+       return prefix_adjout_first(peer, pt_fill(addr, plen));
+}
+
 /*
  * Lookup addr in the peer prefix_index. Returns first match.
  * Returns NULL if not found.
@@ -1124,8 +1133,7 @@ prefix_add_eor(struct rde_peer *peer, uint8_t aid)
  */
 void
 prefix_adjout_update(struct prefix *p, struct rde_peer *peer,
-    struct filterstate *state, struct bgpd_addr *prefix, int prefixlen,
-    uint32_t path_id_tx)
+    struct filterstate *state, struct pt_entry *pte, uint32_t path_id_tx)
 {
        struct rde_aspath *asp;
        struct rde_community *comm;
@@ -1135,10 +1143,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer,
                /* initially mark DEAD so code below is skipped */
                p->flags |= PREFIX_FLAG_ADJOUT | PREFIX_FLAG_DEAD;
 
-               p->pt = pt_get(prefix, prefixlen);
-               if (p->pt == NULL)
-                       p->pt = pt_add(prefix, prefixlen);
-               pt_ref(p->pt);
+               p->pt = pt_ref(pte);
                p->peer = peer;
                p->path_id_tx = path_id_tx;
 
@@ -1170,7 +1175,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer,
 
                /* if pending update unhook it before it is unlinked */
                if (p->flags & PREFIX_FLAG_UPDATE) {
-                       RB_REMOVE(prefix_tree, &peer->updates[prefix->aid], p);
+                       RB_REMOVE(prefix_tree, &peer->updates[pte->aid], p);
                        peer->stats.pending_update--;
                }
 
@@ -1179,7 +1184,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer,
                peer->stats.prefix_out_cnt--;
        }
        if (p->flags & PREFIX_FLAG_WITHDRAW) {
-               RB_REMOVE(prefix_tree, &peer->withdraws[prefix->aid], p);
+               RB_REMOVE(prefix_tree, &peer->withdraws[pte->aid], p);
                peer->stats.pending_withdraw--;
        }
 
@@ -1213,7 +1218,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer,
        if (p->flags & PREFIX_FLAG_MASK)
                fatalx("%s: bad flags %x", __func__, p->flags);
        p->flags |= PREFIX_FLAG_UPDATE;
-       if (RB_INSERT(prefix_tree, &peer->updates[prefix->aid], p) != NULL)
+       if (RB_INSERT(prefix_tree, &peer->updates[pte->aid], p) != NULL)
                fatalx("%s: RB tree invariant violated", __func__);
        peer->stats.pending_update++;
 }
index dc4bf1e..9667b4f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_update.c,v 1.160 2023/03/28 15:17:34 claudio Exp $ */
+/*     $OpenBSD: rde_update.c,v 1.161 2023/03/29 10:46:11 claudio Exp $ */
 
 /*
  * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -150,10 +150,10 @@ up_enforce_open_policy(struct rde_peer *peer, struct filterstate *state,
  * - UP_EXCLUDED if prefix was excluded because of up_test_update()
  */
 static enum up_state
-up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p,
-    struct bgpd_addr *addr, uint8_t plen)
+up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p)
 {
        struct filterstate state;
+       struct bgpd_addr addr;
        int excluded = 0;
 
        /*
@@ -166,14 +166,15 @@ up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p,
                excluded = 1;
 
        rde_filterstate_prep(&state, new);
-       if (rde_filter(peer->out_rules, peer, prefix_peer(new), addr, plen,
-           &state) == ACTION_DENY) {
+       pt_getaddr(new->pt, &addr);
+       if (rde_filter(peer->out_rules, peer, prefix_peer(new), &addr,
+           new->pt->prefixlen, &state) == ACTION_DENY) {
                rde_filterstate_clean(&state);
                return UP_FILTERED;
        }
 
        /* Open Policy Check: acts like an output filter */
-       if (up_enforce_open_policy(peer, &state, addr->aid)) {
+       if (up_enforce_open_policy(peer, &state, new->pt->aid)) {
                rde_filterstate_clean(&state);
                return UP_FILTERED;
        }
@@ -185,10 +186,10 @@ up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p,
 
        /* from here on we know this is an update */
        if (p == (void *)-1)
-               p = prefix_adjout_get(peer, new->path_id_tx, addr, plen);
+               p = prefix_adjout_get(peer, new->path_id_tx, new->pt);
 
-       up_prep_adjout(peer, &state, addr->aid);
-       prefix_adjout_update(p, peer, &state, addr, plen, new->path_id_tx);
+       up_prep_adjout(peer, &state, new->pt->aid);
+       prefix_adjout_update(p, peer, &state, new->pt, new->path_id_tx);
        rde_filterstate_clean(&state);
 
        /* max prefix checker outbound */
@@ -208,18 +209,13 @@ up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p,
 void
 up_generate_updates(struct rde_peer *peer, struct rib_entry *re)
 {
-       struct bgpd_addr        addr;
        struct prefix           *new, *p;
-       uint8_t                 prefixlen;
 
-       pt_getaddr(re->prefix, &addr);
-       prefixlen = re->prefix->prefixlen;
-
-       p = prefix_adjout_lookup(peer, &addr, prefixlen);
+       p = prefix_adjout_first(peer, re->prefix);
 
        new = prefix_best(re);
        while (new != NULL) {
-               switch (up_process_prefix(peer, new, p, &addr, prefixlen)) {
+               switch (up_process_prefix(peer, new, p)) {
                case UP_OK:
                case UP_ERR_LIMIT:
                        return;
@@ -251,16 +247,11 @@ done:
 void
 up_generate_addpath(struct rde_peer *peer, struct rib_entry *re)
 {
-       struct bgpd_addr        addr;
        struct prefix           *head, *new, *p;
-       uint8_t                 prefixlen;
        int                     maxpaths = 0, extrapaths = 0, extra;
        int                     checkmode = 1;
 
-       pt_getaddr(re->prefix, &addr);
-       prefixlen = re->prefix->prefixlen;
-
-       head = prefix_adjout_lookup(peer, &addr, prefixlen);
+       head = prefix_adjout_first(peer, re->prefix);
 
        /* mark all paths as stale */
        for (p = head; p != NULL; p = prefix_adjout_next(peer, p))
@@ -310,8 +301,7 @@ up_generate_addpath(struct rde_peer *peer, struct rib_entry *re)
                        }
                }
 
-               switch (up_process_prefix(peer, new, (void *)-1, &addr,
-                   prefixlen)) {
+               switch (up_process_prefix(peer, new, (void *)-1)) {
                case UP_OK:
                        maxpaths++;
                        extrapaths += extra;
@@ -345,21 +335,16 @@ void
 up_generate_addpath_all(struct rde_peer *peer, struct rib_entry *re,
     struct prefix *new, struct prefix *old)
 {
-       struct bgpd_addr        addr;
        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 */
-               head = prefix_adjout_lookup(peer, &addr, prefixlen);
+               head = prefix_adjout_first(peer, re->prefix);
                for (p = head; p != NULL; p = prefix_adjout_next(peer, p))
                        p->flags |= PREFIX_FLAG_STALE;
 
@@ -369,15 +354,14 @@ up_generate_addpath_all(struct rde_peer *peer, struct rib_entry *re,
 
        if (old != NULL) {
                /* withdraw stale paths */
-               p = prefix_adjout_get(peer, old->path_id_tx, &addr, prefixlen);
+               p = prefix_adjout_get(peer, old->path_id_tx, old->pt);
                if (p != NULL)
                        prefix_adjout_withdraw(p);
        }
 
        /* add new path (or multiple if all is set) */
        while (new != NULL) {
-               switch (up_process_prefix(peer, new, (void *)-1, &addr,
-                   prefixlen)) {
+               switch (up_process_prefix(peer, new, (void *)-1)) {
                case UP_OK:
                case UP_FILTERED:
                case UP_EXCLUDED:
@@ -405,10 +389,6 @@ up_generate_addpath_all(struct rde_peer *peer, struct rib_entry *re,
        }
 }
 
-struct rib_entry *rib_add(struct rib *, struct bgpd_addr *, int);
-void rib_remove(struct rib_entry *);
-int rib_empty(struct rib_entry *);
-
 /* send a default route to the specified peer */
 void
 up_generate_default(struct rde_peer *peer, uint8_t aid)
@@ -417,6 +397,7 @@ up_generate_default(struct rde_peer *peer, uint8_t aid)
        struct filterstate       state;
        struct rde_aspath       *asp;
        struct prefix           *p;
+       struct pt_entry         *pte;
        struct bgpd_addr         addr;
 
        if (peer->capa.mp[aid] == 0)
@@ -447,7 +428,11 @@ up_generate_default(struct rde_peer *peer, uint8_t aid)
        }
 
        up_prep_adjout(peer, &state, addr.aid);
-       prefix_adjout_update(p, peer, &state, &addr, 0, 0);
+       /* can't use pt_fill here since prefix_adjout_update keeps a ref */
+       pte = pt_get(&addr, 0);
+       if (pte == NULL)
+               pte = pt_add(&addr, 0);
+       prefix_adjout_update(p, peer, &state, pte, 0);
        rde_filterstate_clean(&state);
 
        /* max prefix checker outbound */