In one case (when a peer changes RIB) the RDE needs to withdraw all
prefixes of that peer and then during softreconfig it will load the
prefixes freshly form the new RIB. Since we now have a list of all
prefixes that have been sent to the peer use that one instead of doing a
full table walk over the old RIB.

-- 
:wq Claudio

Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.433
diff -u -p -r1.433 rde.c
--- rde.c       3 Oct 2018 11:36:39 -0000       1.433
+++ rde.c       3 Oct 2018 12:37:28 -0000
@@ -96,7 +96,6 @@ static void    rde_softreconfig_out_done(v
 static void     rde_softreconfig_done(void);
 static void     rde_softreconfig_out(struct rib_entry *, void *);
 static void     rde_softreconfig_in(struct rib_entry *, void *);
-static void     rde_softreconfig_unload_peer(struct rib_entry *, void *);
 void            rde_up_dump_upcall(struct rib_entry *, void *);
 void            rde_update_queue_runner(void);
 void            rde_update6_queue_runner(u_int8_t);
@@ -2929,8 +2928,7 @@ rde_reload_done(void)
                peer->reconf_out = 0;
                peer->reconf_rib = 0;
                if (peer->rib != rib_find(peer->conf.rib)) {
-                       rib_dump(peer->rib, rde_softreconfig_unload_peer, peer,
-                           AID_UNSPEC);
+                       up_withdraw_all(peer);
                        peer->rib = rib_find(peer->conf.rib);
                        if (peer->rib == NULL)
                                fatalx("King Bula's peer met an unknown RIB");
@@ -3226,32 +3224,6 @@ rde_softreconfig_out(struct rib_entry *r
                if (peer->rib == re_rib(re) && peer->reconf_out)
                        rde_softreconfig_out_peer(re, peer);
        }
-}
-
-static void
-rde_softreconfig_unload_peer(struct rib_entry *re, void *ptr)
-{
-       struct filterstate       ostate;
-       struct rde_peer         *peer = ptr;
-       struct prefix           *p = re->active;
-       struct pt_entry         *pt;
-       struct bgpd_addr         addr;
-
-       pt = re->prefix;
-       pt_getaddr(pt, &addr);
-
-       /* check if prefix was announced */
-       if (up_test_update(peer, p) != 1)
-               return;
-
-       rde_filterstate_prep(&ostate, prefix_aspath(p), prefix_nexthop(p),
-           prefix_nhflags(p));
-       if (rde_filter(out_rules_tmp, peer, p, &ostate) != ACTION_DENY) {
-               /* send withdraw */
-               up_rib_remove(peer, re);
-               up_generate(peer, NULL, &addr, pt->prefixlen);
-       }
-       rde_filterstate_clean(&ostate);
 }
 
 /*
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.196
diff -u -p -r1.196 rde.h
--- rde.h       1 Oct 2018 23:09:53 -0000       1.196
+++ rde.h       3 Oct 2018 12:37:15 -0000
@@ -555,6 +555,7 @@ void                 up_init(struct rde_peer *);
 void            up_down(struct rde_peer *);
 int             up_rib_remove(struct rde_peer *, struct rib_entry *);
 void            up_rib_add(struct rde_peer *, struct rib_entry *);
+void            up_withdraw_all(struct rde_peer *);
 int             up_test_update(struct rde_peer *, struct prefix *);
 int             up_generate(struct rde_peer *, struct filterstate *,
                     struct bgpd_addr *, u_int8_t);
Index: rde_update.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v
retrieving revision 1.100
diff -u -p -r1.100 rde_update.c
--- rde_update.c        29 Sep 2018 07:43:36 -0000      1.100
+++ rde_update.c        3 Oct 2018 12:38:28 -0000
@@ -245,6 +245,22 @@ up_rib_add(struct rde_peer *peer, struct
                free(ur);
 }
 
+void
+up_withdraw_all(struct rde_peer *peer)
+{
+       struct bgpd_addr addr;
+       struct update_rib *ur, *nur;
+
+       RB_FOREACH_SAFE(ur, uptree_rib, &peer->up_rib, nur) {
+               RB_REMOVE(uptree_rib, &peer->up_rib, ur);
+
+               /* withdraw prefix */
+               pt_getaddr(ur->re->prefix, &addr);
+               up_generate(peer, NULL, &addr, ur->re->prefix->prefixlen);
+               free(ur);
+       }
+}
+
 int
 up_add(struct rde_peer *peer, struct update_prefix *p, struct update_attr *a)
 {

Reply via email to