diff options
author | Maria Matejka <mq@ucw.cz> | 2023-01-31 13:07:46 +0100 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2023-02-02 15:57:21 +0100 |
commit | c354e8f4c199ca7dec441394156d18badac71b81 (patch) | |
tree | d5a0c43215603bef858699aa49678e27894893f8 /nest/proto.c | |
parent | 64e08775251960a2b009fc35a084610c9c4c4909 (diff) |
Interface updates are asynchronous
Instead of propagating interface updates as they are loaded from kernel,
they are enqueued and all the notifications are called from a
protocol-specific event. This change allows to break the locking loop
between protocols and interfaces.
Anyway, this change is based on v2 branch to keep the changes between v2
and v3 smaller.
Diffstat (limited to 'nest/proto.c')
-rw-r--r-- | nest/proto.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/nest/proto.c b/nest/proto.c index 2614943c..39e8b999 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -57,7 +57,11 @@ static inline void channel_reset_limit(struct channel_limit *l); static inline int proto_is_done(struct proto *p) -{ return (p->proto_state == PS_DOWN) && (p->active_channels == 0); } +{ + return (p->proto_state == PS_DOWN) + && (p->active_channels == 0) + && EMPTY_TLIST(proto_neigh, &p->neighbors); +} static inline int channel_is_active(struct channel *c) { return (c->channel_state == CS_START) || (c->channel_state == CS_UP); } @@ -962,14 +966,18 @@ proto_event(void *ptr) if (p->do_start) { - if_feed_baby(p); + iface_subscribe(&p->iface_sub); p->do_start = 0; } if (p->do_stop) { + iface_unsubscribe(&p->iface_sub); + neigh_prune(p); + p->do_stop = 0; } + if (proto_is_done(p)) { if (p->proto->cleanup) @@ -1860,7 +1868,6 @@ proto_do_stop(struct proto *p) p->down_sched = 0; p->gr_recovery = 0; - if (p->main_source) { rt_unlock_source(p->main_source); @@ -1877,7 +1884,6 @@ static void proto_do_down(struct proto *p) { p->down_code = 0; - neigh_prune(p); rfree(p->pool); p->pool = NULL; |