This diff changes prefix_adjout_withdraw() to take a prefix pointer
as argument. So instead of doing the lookup in the withdraw function the
caller may need to do it.

With this one call to up_generate_updates() can be replaced with a direct
call to prefix_adjout_withdraw(). rde_up_flush_upcall() tries to withdraw
every prefix in the Adj-RIB-Out of a peer. The indirection via
up_generate_updates() makes little sense here.

-- 
:wq Claudio

Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.538
diff -u -p -r1.538 rde.c
--- rde.c       28 Feb 2022 12:52:38 -0000      1.538
+++ rde.c       2 Mar 2022 11:50:19 -0000
@@ -3050,9 +3050,7 @@ rde_generate_updates(struct rib *rib, st
 static void
 rde_up_flush_upcall(struct prefix *p, void *ptr)
 {
-       struct rde_peer *peer = ptr;
-
-       up_generate_updates(out_rules, peer, NULL, p);
+       prefix_adjout_withdraw(p);
 }
 
 u_char queue_buf[4096];
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.244
diff -u -p -r1.244 rde.h
--- rde.h       25 Feb 2022 11:36:54 -0000      1.244
+++ rde.h       2 Mar 2022 11:49:59 -0000
@@ -596,8 +596,7 @@ int          prefix_withdraw(struct rib *, stru
 void            prefix_add_eor(struct rde_peer *, uint8_t);
 int             prefix_adjout_update(struct rde_peer *, struct filterstate *,
                    struct bgpd_addr *, int, uint8_t);
-int             prefix_adjout_withdraw(struct rde_peer *, struct bgpd_addr *,
-                   int);
+int             prefix_adjout_withdraw(struct prefix *);
 void            prefix_adjout_destroy(struct prefix *p);
 void            prefix_adjout_dump(struct rde_peer *, void *,
                    void (*)(struct prefix *, void *));
Index: rde_rib.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
retrieving revision 1.230
diff -u -p -r1.230 rde_rib.c
--- rde_rib.c   1 Mar 2022 09:39:36 -0000       1.230
+++ rde_rib.c   2 Mar 2022 11:49:39 -0000
@@ -1252,21 +1252,19 @@ prefix_adjout_update(struct rde_peer *pe
  * the prefix in the RIB linked to the peer withdraw list.
  */
 int
-prefix_adjout_withdraw(struct rde_peer *peer, struct bgpd_addr *prefix,
-    int prefixlen)
+prefix_adjout_withdraw(struct prefix *p)
 {
-       struct prefix *p;
-
-       p = prefix_adjout_get(peer, 0, prefix, prefixlen);
-       if (p == NULL)          /* Got a dummy withdrawn request. */
-               return (0);
+       struct rde_peer *peer = prefix_peer(p);
 
        if ((p->flags & PREFIX_FLAG_ADJOUT) == 0)
                fatalx("%s: prefix without PREFIX_FLAG_ADJOUT hit", __func__);
 
-       /* already a withdraw, error */
-       if (p->flags & PREFIX_FLAG_WITHDRAW)
-               log_warnx("%s: prefix already withdrawed", __func__);
+       /* already a withdraw, shortcut */
+       if (p->flags & PREFIX_FLAG_WITHDRAW) {
+               p->lastchange = getmonotime();
+               p->flags &= ~PREFIX_FLAG_STALE;
+               return (0);
+       }
        /* pending update just got withdrawn */
        if (p->flags & PREFIX_FLAG_UPDATE)
                RB_REMOVE(prefix_tree, &peer->updates[p->pt->aid], p);
@@ -1279,7 +1277,7 @@ prefix_adjout_withdraw(struct rde_peer *
        p->lastchange = getmonotime();
 
        p->flags |= PREFIX_FLAG_WITHDRAW;
-       if (RB_INSERT(prefix_tree, &peer->withdraws[prefix->aid], p) != NULL)
+       if (RB_INSERT(prefix_tree, &peer->withdraws[p->pt->aid], p) != NULL)
                fatalx("%s: RB tree invariant violated", __func__);
        return (1);
 }
Index: rde_update.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v
retrieving revision 1.134
diff -u -p -r1.134 rde_update.c
--- rde_update.c        1 Mar 2022 09:53:42 -0000       1.134
+++ rde_update.c        2 Mar 2022 11:49:39 -0000
@@ -102,6 +102,7 @@ up_generate_updates(struct filter_head *
 {
        struct filterstate      state;
        struct bgpd_addr        addr;
+       struct prefix           *p;
        int                     need_withdraw;
        uint8_t                 prefixlen;
 
@@ -119,7 +120,9 @@ up_generate_updates(struct filter_head *
 again:
        if (new == NULL) {
                /* withdraw prefix */
-               if (prefix_adjout_withdraw(peer, &addr, prefixlen) == 1) {
+               if ((p = prefix_adjout_get(peer, 0, &addr, prefixlen)) == NULL)
+                       return;
+               if (prefix_adjout_withdraw(p) == 1) {
                        peer->prefix_out_cnt--;
                        peer->up_wcnt++;
                }

Reply via email to