0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-23 02:01:55 +00:00

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.
This commit is contained in:
Maria Matejka 2023-02-01 12:10:34 +01:00
parent 6e035a9a8c
commit 64e0877525
4 changed files with 24 additions and 23 deletions

View File

@ -10,6 +10,7 @@
#define _BIRD_IFACE_H_ #define _BIRD_IFACE_H_
#include "lib/lists.h" #include "lib/lists.h"
#include "lib/tlists.h"
#include "lib/ip.h" #include "lib/ip.h"
extern list iface_list; extern list iface_list;
@ -126,6 +127,7 @@ void if_recalc_all_preferred_addresses(void);
typedef struct neighbor { typedef struct neighbor {
node n; /* Node in neighbor hash table chain */ node n; /* Node in neighbor hash table chain */
node if_n; /* Node in per-interface neighbor list */ node if_n; /* Node in per-interface neighbor list */
TLIST_NODE(proto_neigh, struct neighbor) proto_n;
ip_addr addr; /* Address of the neighbor */ ip_addr addr; /* Address of the neighbor */
struct ifa *ifa; /* Ifa on related iface */ struct ifa *ifa; /* Ifa on related iface */
struct iface *iface; /* Interface it's connected to */ struct iface *iface; /* Interface it's connected to */
@ -138,6 +140,13 @@ typedef struct neighbor {
SCOPE_HOST when it's our own address */ SCOPE_HOST when it's our own address */
} neighbor; } 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_STICKY 1
#define NEF_ONLINK 2 #define NEF_ONLINK 2
#define NEF_IFACE 4 /* Entry for whole iface */ #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(neighbor *);
void neigh_dump_all(void); void neigh_dump_all(void);
void neigh_prune(void); void neigh_prune(struct proto *);
void neigh_if_up(struct iface *); void neigh_if_up(struct iface *);
void neigh_if_down(struct iface *); void neigh_if_down(struct iface *);
void neigh_if_link(struct iface *); void neigh_if_link(struct iface *);

View File

@ -256,6 +256,7 @@ neigh_find(struct proto *p, ip_addr a, struct iface *iface, uint flags)
n = sl_allocz(neigh_slab); n = sl_allocz(neigh_slab);
add_tail(&neigh_hash_table[h], &n->n); add_tail(&neigh_hash_table[h], &n->n);
add_tail((scope >= 0) ? &iface->neighbors : &sticky_neigh_list, &n->if_n); add_tail((scope >= 0) ? &iface->neighbors : &sticky_neigh_list, &n->if_n);
proto_neigh_add_tail(&p->neighbors, n);
n->addr = a; n->addr = a;
n->ifa = addr; n->ifa = addr;
n->iface = iface; n->iface = iface;
@ -308,7 +309,7 @@ neigh_dump_all(void)
static inline void static inline void
neigh_notify(neighbor *n) 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); n->proto->neigh_notify(n);
} }
@ -343,8 +344,12 @@ neigh_down(neighbor *n)
static inline void static inline void
neigh_free(neighbor *n) neigh_free(neighbor *n)
{ {
proto_neigh_rem_node(&n->proto->neighbors, n);
n->proto = NULL;
rem_node(&n->n); rem_node(&n->n);
rem_node(&n->if_n); rem_node(&n->if_n);
sl_free(n); sl_free(n);
} }
@ -519,15 +524,6 @@ neigh_ifa_down(struct ifa *a)
neigh_update(n, i); 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 * neigh_prune - prune neighbor cache
* *
@ -536,16 +532,10 @@ neigh_prune_one(neighbor *n)
* is shut down to get rid of all its heritage. * is shut down to get rid of all its heritage.
*/ */
void void
neigh_prune(void) neigh_prune(struct proto *p)
{ {
neighbor *n; while (!EMPTY_TLIST(proto_neigh, &p->neighbors))
node *m; neigh_free(THEAD(proto_neigh, &p->neighbors));
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);
} }
/** /**

View File

@ -1877,7 +1877,7 @@ static void
proto_do_down(struct proto *p) proto_do_down(struct proto *p)
{ {
p->down_code = 0; p->down_code = 0;
neigh_prune(); neigh_prune(p);
rfree(p->pool); rfree(p->pool);
p->pool = NULL; p->pool = NULL;

View File

@ -9,9 +9,10 @@
#ifndef _BIRD_PROTOCOL_H_ #ifndef _BIRD_PROTOCOL_H_
#define _BIRD_PROTOCOL_H_ #define _BIRD_PROTOCOL_H_
#include "lib/lists.h" #include "lib/tlists.h"
#include "lib/resource.h" #include "lib/resource.h"
#include "lib/event.h" #include "lib/event.h"
#include "nest/iface.h"
#include "nest/route.h" #include "nest/route.h"
#include "conf/conf.h" #include "conf/conf.h"
@ -169,6 +170,7 @@ struct proto {
struct channel *main_channel; /* Primary channel */ struct channel *main_channel; /* Primary channel */
struct rte_src *main_source; /* Primary route source */ struct rte_src *main_source; /* Primary route source */
struct iface *vrf; /* Related VRF instance, NULL if global */ 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 debug; /* Debugging flags */