summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2023-02-01 12:10:34 +0100
committerMaria Matejka <mq@ucw.cz>2023-02-02 14:40:00 +0100
commit64e08775251960a2b009fc35a084610c9c4c4909 (patch)
treee481e54e3636283fed9f4ca261f272f9fb6a82af /nest
parent6e035a9a8c7c943ea5b58932a2bd4c9b733d91ff (diff)
Proto: Adding a list of associated neighbors
This makes for safer and faster pruning and notifying as protocol now on its shutdown prunes only its neighbors and nothing else.
Diffstat (limited to 'nest')
-rw-r--r--nest/iface.h11
-rw-r--r--nest/neighbor.c28
-rw-r--r--nest/proto.c2
-rw-r--r--nest/protocol.h6
4 files changed, 24 insertions, 23 deletions
diff --git a/nest/iface.h b/nest/iface.h
index 287f3d96..fb27f99e 100644
--- a/nest/iface.h
+++ b/nest/iface.h
@@ -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 *);
diff --git a/nest/neighbor.c b/nest/neighbor.c
index 81da24d5..c27db989 100644
--- a/nest/neighbor.c
+++ b/nest/neighbor.c
@@ -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));
}
/**
diff --git a/nest/proto.c b/nest/proto.c
index 0ca72ead..2614943c 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -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;
diff --git a/nest/protocol.h b/nest/protocol.h
index fef2cb91..9fbe9158 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -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 */