mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-18 17:18:42 +00:00
Asynchronous neighbor notifications fixes
This commit is contained in:
parent
0f6ea95754
commit
127862f626
@ -153,6 +153,7 @@ typedef struct neighbor {
|
|||||||
#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 */
|
||||||
|
#define NEF_NOTIFY_MAIN 0x100 /* Notify from main_birdloop context */
|
||||||
|
|
||||||
|
|
||||||
neighbor *neigh_find(struct proto *p, ip_addr a, struct iface *ifa, uint flags);
|
neighbor *neigh_find(struct proto *p, ip_addr a, struct iface *ifa, uint flags);
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
static slab *neigh_slab;
|
static slab *neigh_slab;
|
||||||
static list neigh_hash_table[NEIGH_HASH_SIZE], sticky_neigh_list;
|
static list neigh_hash_table[NEIGH_HASH_SIZE], sticky_neigh_list;
|
||||||
static void neigh_do_notify(void *);
|
static void neigh_do_notify(void *);
|
||||||
|
static void neigh_do_notify_main(void *);
|
||||||
|
|
||||||
static inline uint
|
static inline uint
|
||||||
neigh_hash(struct proto *p, ip_addr a, struct iface *i)
|
neigh_hash(struct proto *p, ip_addr a, struct iface *i)
|
||||||
@ -270,15 +271,29 @@ neigh_find(struct proto *p, ip_addr a, struct iface *iface, uint flags)
|
|||||||
n->proto = p;
|
n->proto = p;
|
||||||
n->flags = flags;
|
n->flags = flags;
|
||||||
n->scope = scope;
|
n->scope = scope;
|
||||||
n->event = (event) { .hook = neigh_do_notify, .data = n };
|
|
||||||
ASSERT_DIE(birdloop_inside(p->loop));
|
ASSERT_DIE(birdloop_inside(p->loop));
|
||||||
|
|
||||||
if (p->loop == &main_birdloop)
|
if (flags & NEF_NOTIFY_MAIN)
|
||||||
n->event.list = &global_event_list;
|
n->event = (event) {
|
||||||
|
.hook = neigh_do_notify_main,
|
||||||
|
.data = n,
|
||||||
|
.list = &global_event_list,
|
||||||
|
};
|
||||||
|
else if (p->loop == &main_birdloop)
|
||||||
|
n->event = (event) {
|
||||||
|
.hook = neigh_do_notify,
|
||||||
|
.data = n,
|
||||||
|
.list = &global_event_list,
|
||||||
|
};
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
birdloop_link(p->loop);
|
birdloop_link(p->loop);
|
||||||
n->event.list = birdloop_event_list(p->loop);
|
n->event = (event) {
|
||||||
|
.hook = neigh_do_notify,
|
||||||
|
.data = n,
|
||||||
|
.list = birdloop_event_list(p->loop),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
IFACE_UNLOCK;
|
IFACE_UNLOCK;
|
||||||
@ -340,6 +355,14 @@ neigh_notify(neighbor *n)
|
|||||||
ev_send(n->event.list, &n->event);
|
ev_send(n->event.list, &n->event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
neigh_do_notify_main(void *data)
|
||||||
|
{
|
||||||
|
neighbor *n = data;
|
||||||
|
PROTO_LOCKED_FROM_MAIN(n->proto)
|
||||||
|
neigh_do_notify(data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
neigh_do_notify(void *data)
|
neigh_do_notify(void *data)
|
||||||
{
|
{
|
||||||
@ -382,10 +405,18 @@ neigh_down(neighbor *n)
|
|||||||
static inline void
|
static inline void
|
||||||
neigh_free(neighbor *n)
|
neigh_free(neighbor *n)
|
||||||
{
|
{
|
||||||
|
ASSERT_DIE(birdloop_inside(n->proto->loop));
|
||||||
|
|
||||||
|
if (n->flags & NEF_NOTIFY_MAIN)
|
||||||
|
ASSERT_DIE(birdloop_inside(&main_birdloop));
|
||||||
|
|
||||||
rem_node(&n->n);
|
rem_node(&n->n);
|
||||||
rem_node(&n->if_n);
|
rem_node(&n->if_n);
|
||||||
ev_postpone(&n->event);
|
|
||||||
|
if (n->event.list != &global_event_list)
|
||||||
birdloop_unlink(n->proto->loop);
|
birdloop_unlink(n->proto->loop);
|
||||||
|
|
||||||
|
ev_postpone(&n->event);
|
||||||
sl_free(neigh_slab, n);
|
sl_free(neigh_slab, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1541,7 +1541,7 @@ bgp_start_locked(struct object_lock *lock)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
neighbor *n = neigh_find(&p->p, p->remote_ip, cf->iface, NEF_STICKY);
|
neighbor *n = neigh_find(&p->p, p->remote_ip, cf->iface, NEF_STICKY | NEF_NOTIFY_MAIN);
|
||||||
if (!n)
|
if (!n)
|
||||||
{
|
{
|
||||||
log(L_ERR "%s: Invalid remote address %I%J", p->p.name, p->remote_ip, cf->iface);
|
log(L_ERR "%s: Invalid remote address %I%J", p->p.name, p->remote_ip, cf->iface);
|
||||||
|
@ -498,7 +498,9 @@ void
|
|||||||
birdloop_unlink(struct birdloop *loop)
|
birdloop_unlink(struct birdloop *loop)
|
||||||
{
|
{
|
||||||
ASSERT_DIE(birdloop_inside(loop));
|
ASSERT_DIE(birdloop_inside(loop));
|
||||||
loop->links--;
|
ASSERT_DIE(loop->links);
|
||||||
|
if (!--loop->links)
|
||||||
|
birdloop_ping(loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -541,7 +543,7 @@ birdloop_main(void *arg)
|
|||||||
|
|
||||||
birdloop_enter(loop);
|
birdloop_enter(loop);
|
||||||
|
|
||||||
if (loop->stopped)
|
if (loop->stopped && !loop->links)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
loop_begin = current_time();
|
loop_begin = current_time();
|
||||||
|
Loading…
Reference in New Issue
Block a user