summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-02-01 14:54:03 +0100
committerMaria Matejka <mq@ucw.cz>2022-02-03 10:30:33 +0100
commit09380db594e1befb991be626b36783cae525d823 (patch)
tree5d25786a91ba65b2f2a0f011a45549ba64b37308
parentc019008383a439b5e5cf46dc71f902f335a0a9df (diff)
Neighbor prune fixup
-rw-r--r--nest/iface.h2
-rw-r--r--nest/neighbor.c17
-rw-r--r--nest/proto.c2
3 files changed, 10 insertions, 11 deletions
diff --git a/nest/iface.h b/nest/iface.h
index 6e8c8448..87ad86cf 100644
--- a/nest/iface.h
+++ b/nest/iface.h
@@ -160,7 +160,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 *p);
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 e4d42b4d..7b951366 100644
--- a/nest/neighbor.c
+++ b/nest/neighbor.c
@@ -61,6 +61,7 @@ static slab *neigh_slab;
static list neigh_hash_table[NEIGH_HASH_SIZE], sticky_neigh_list;
static void neigh_do_notify(void *);
static void neigh_do_notify_main(void *);
+static void neigh_free(neighbor *n);
static inline uint
neigh_hash(struct proto *p, ip_addr a, struct iface *i)
@@ -372,6 +373,9 @@ neigh_do_notify(void *data)
if (n->proto->proto_state != PS_STOP)
n->proto->neigh_notify(n);
+
+ if ((n->scope < 0) && !(n->flags & NEF_STICKY))
+ neigh_free(n);
}
static void
@@ -402,7 +406,7 @@ neigh_down(neighbor *n)
neigh_notify(n);
}
-static inline void
+static void
neigh_free(neighbor *n)
{
ASSERT_DIE(birdloop_inside(n->proto->loop));
@@ -480,12 +484,6 @@ neigh_update(neighbor *n, struct iface *iface)
if (n->scope >= 0)
neigh_down(n);
- if ((n->scope < 0) && !(n->flags & NEF_STICKY))
- {
- neigh_free(n);
- return;
- }
-
if (scope >= 0)
neigh_up(n, iface, ifa, scope);
}
@@ -630,7 +628,7 @@ 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;
@@ -641,7 +639,8 @@ neigh_prune(void)
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);
+ if (n->proto == p)
+ neigh_prune_one(n);
IFACE_UNLOCK;
}
diff --git a/nest/proto.c b/nest/proto.c
index 1e7f5560..3ba8ac5c 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -2434,7 +2434,7 @@ static void
proto_do_down(struct proto *p)
{
p->down_code = 0;
- neigh_prune();
+ neigh_prune(p);
/* Shutdown is finished in the protocol event */
if (proto_is_done(p))