]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Proto: Adding a list of associated neighbors
authorMaria Matejka <mq@ucw.cz>
Wed, 1 Feb 2023 11:10:34 +0000 (12:10 +0100)
committerMaria Matejka <mq@ucw.cz>
Thu, 2 Feb 2023 13:40:00 +0000 (14:40 +0100)
This makes for safer and faster pruning and notifying as protocol now on
its shutdown prunes only its neighbors and nothing else.

nest/iface.h
nest/neighbor.c
nest/proto.c
nest/protocol.h

index 287f3d96399bf78df9e49fc739c54972d880a4c5..fb27f99eaf6e76a433f1eb8cee2f941fff08e191 100644 (file)
@@ -10,6 +10,7 @@
 #define _BIRD_IFACE_H_
 
 #include "lib/lists.h"
+#include "lib/tlists.h"
 #include "lib/ip.h"
 
 extern list iface_list;
@@ -126,6 +127,7 @@ void if_recalc_all_preferred_addresses(void);
 typedef struct neighbor {
   node n;                              /* Node in neighbor hash table chain */
   node if_n;                           /* Node in per-interface neighbor list */
+  TLIST_NODE(proto_neigh, struct neighbor) proto_n;
   ip_addr addr;                                /* Address of the neighbor */
   struct ifa *ifa;                     /* Ifa on related iface */
   struct iface *iface;                 /* Interface it's connected to */
@@ -138,6 +140,13 @@ typedef struct neighbor {
                                           SCOPE_HOST when it's our own address */
 } neighbor;
 
+#define TLIST_PREFIX proto_neigh
+#define TLIST_TYPE struct neighbor
+#define TLIST_ITEM proto_n
+#define TLIST_WANT_WALK
+#define TLIST_WANT_ADD_TAIL
+#include "lib/tlists.h"
+
 #define NEF_STICKY     1
 #define NEF_ONLINK     2
 #define NEF_IFACE      4               /* Entry for whole iface */
@@ -147,7 +156,7 @@ neighbor *neigh_find(struct proto *p, ip_addr a, struct iface *ifa, uint flags);
 
 void neigh_dump(neighbor *);
 void neigh_dump_all(void);
-void neigh_prune(void);
+void neigh_prune(struct proto *);
 void neigh_if_up(struct iface *);
 void neigh_if_down(struct iface *);
 void neigh_if_link(struct iface *);
index 81da24d5b5867f9872babda5da197bced5939962..c27db98947a4bb45f5fc16727d99a8497f0cde44 100644 (file)
@@ -256,6 +256,7 @@ neigh_find(struct proto *p, ip_addr a, struct iface *iface, uint flags)
   n = sl_allocz(neigh_slab);
   add_tail(&neigh_hash_table[h], &n->n);
   add_tail((scope >= 0) ? &iface->neighbors : &sticky_neigh_list, &n->if_n);
+  proto_neigh_add_tail(&p->neighbors, n);
   n->addr = a;
   n->ifa = addr;
   n->iface = iface;
@@ -308,7 +309,7 @@ neigh_dump_all(void)
 static inline void
 neigh_notify(neighbor *n)
 {
-  if (n->proto->neigh_notify && (n->proto->proto_state != PS_STOP))
+  if (n->proto && n->proto->neigh_notify && (n->proto->proto_state != PS_STOP))
     n->proto->neigh_notify(n);
 }
 
@@ -343,8 +344,12 @@ neigh_down(neighbor *n)
 static inline void
 neigh_free(neighbor *n)
 {
+  proto_neigh_rem_node(&n->proto->neighbors, n);
+  n->proto = NULL;
+
   rem_node(&n->n);
   rem_node(&n->if_n);
+
   sl_free(n);
 }
 
@@ -519,15 +524,6 @@ neigh_ifa_down(struct ifa *a)
       neigh_update(n, i);
 }
 
-static inline void
-neigh_prune_one(neighbor *n)
-{
-  if (n->proto->proto_state != PS_DOWN)
-    return;
-
-  neigh_free(n);
-}
-
 /**
  * neigh_prune - prune neighbor cache
  *
@@ -536,16 +532,10 @@ neigh_prune_one(neighbor *n)
  * is shut down to get rid of all its heritage.
  */
 void
-neigh_prune(void)
+neigh_prune(struct proto *p)
 {
-  neighbor *n;
-  node *m;
-  int i;
-
-  DBG("Pruning neighbors\n");
-  for(i=0; i<NEIGH_HASH_SIZE; i++)
-    WALK_LIST_DELSAFE(n, m, neigh_hash_table[i])
-      neigh_prune_one(n);
+  while (!EMPTY_TLIST(proto_neigh, &p->neighbors))
+    neigh_free(THEAD(proto_neigh, &p->neighbors));
 }
 
 /**
index 0ca72ead20f285771a4bb85ada002dc400d49e12..2614943cbcb32bf385a83f3b8d1bbe294446822c 100644 (file)
@@ -1877,7 +1877,7 @@ static void
 proto_do_down(struct proto *p)
 {
   p->down_code = 0;
-  neigh_prune();
+  neigh_prune(p);
   rfree(p->pool);
   p->pool = NULL;
 
index fef2cb917a441efb0497e5a3c637f6d381b26764..9fbe9158c3c9470312b54fb3d0d5615ad1355839 100644 (file)
@@ -9,9 +9,10 @@
 #ifndef _BIRD_PROTOCOL_H_
 #define _BIRD_PROTOCOL_H_
 
-#include "lib/lists.h"
+#include "lib/tlists.h"
 #include "lib/resource.h"
 #include "lib/event.h"
+#include "nest/iface.h"
 #include "nest/route.h"
 #include "conf/conf.h"
 
@@ -169,8 +170,9 @@ struct proto {
   struct channel *main_channel;                /* Primary channel */
   struct rte_src *main_source;         /* Primary route source */
   struct iface *vrf;                   /* Related VRF instance, NULL if global */
+  TLIST_LIST(proto_neigh) neighbors;   /* List of neighbor structures */
 
-  const char *name;                            /* Name of this instance (== cf->name) */
+  const char *name;                    /* Name of this instance (== cf->name) */
   u32 debug;                           /* Debugging flags */
   u32 mrtdump;                         /* MRTDump flags */
   uint active_channels;                        /* Number of active channels */