summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-01-12 14:06:49 +0100
committerMaria Matejka <mq@ucw.cz>2022-02-03 10:30:33 +0100
commitb6c9263543060141d79e205e1b3408099ad1afc4 (patch)
treebada190f4106905ebfd638a1777c8fb255c0e9f9
parentb5155d5cea6af783619144ca49648ad743cf4e38 (diff)
Interfaces and neighbor notifications do properly enter protocol loops
-rw-r--r--nest/iface.c6
-rw-r--r--nest/neighbor.c10
-rw-r--r--nest/proto.c15
-rw-r--r--nest/protocol.h12
4 files changed, 28 insertions, 15 deletions
diff --git a/nest/iface.c b/nest/iface.c
index dd4af243..bd2bb39a 100644
--- a/nest/iface.c
+++ b/nest/iface.c
@@ -166,7 +166,8 @@ ifa_notify_change_(unsigned c, struct ifa *a)
DBG("IFA change notification (%x) for %s:%I\n", c, a->iface->name, a->ip);
WALK_LIST(p, proto_list)
- ifa_send_notify(p, c, a);
+ PROTO_LOCKED_FROM_MAIN(p)
+ ifa_send_notify(p, c, a);
}
static inline void
@@ -226,7 +227,8 @@ if_notify_change(unsigned c, struct iface *i)
ifa_notify_change_(IF_CHANGE_DOWN, a);
WALK_LIST(p, proto_list)
- if_send_notify(p, c, i);
+ PROTO_LOCKED_FROM_MAIN(p)
+ if_send_notify(p, c, i);
if (c & IF_CHANGE_UP)
WALK_LIST(a, i->addrs)
diff --git a/nest/neighbor.c b/nest/neighbor.c
index cb2d1b2b..e10413bd 100644
--- a/nest/neighbor.c
+++ b/nest/neighbor.c
@@ -210,6 +210,8 @@ if_intersect(struct iface *ia, struct iface *ib)
neighbor *
neigh_find(struct proto *p, ip_addr a, struct iface *iface, uint flags)
{
+ ASSERT_DIE(birdloop_inside(&main_birdloop));
+
neighbor *n;
int class, scope = -1;
uint h = neigh_hash(p, a, iface);
@@ -308,8 +310,12 @@ neigh_dump_all(void)
static inline void
neigh_notify(neighbor *n)
{
- if (n->proto->neigh_notify && (n->proto->proto_state != PS_STOP))
- n->proto->neigh_notify(n);
+ if (!n->proto->neigh_notify)
+ return;
+
+ PROTO_LOCKED_FROM_MAIN(n->proto)
+ if (n->proto->proto_state != PS_STOP)
+ n->proto->neigh_notify(n);
}
static void
diff --git a/nest/proto.c b/nest/proto.c
index 341581ab..1e7f5560 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -70,17 +70,6 @@ static inline event_list *proto_work_list(struct proto *p)
static inline void proto_send_event(struct proto *p)
{ ev_send(proto_event_list(p), p->event); }
-#define PROTO_ENTER_FROM_MAIN(p) ({ \
- ASSERT_DIE(birdloop_inside(&main_birdloop)); \
- struct birdloop *_loop = (p)->loop; \
- if (_loop != &main_birdloop) birdloop_enter(_loop); \
- _loop; \
- })
-
-#define PROTO_LEAVE_FROM_MAIN(loop) ({ if (loop != &main_birdloop) birdloop_leave(loop); })
-
-#define PROTO_LOCKED_FROM_MAIN(p) for (struct birdloop *_proto_loop = PROTO_ENTER_FROM_MAIN(p); _proto_loop; PROTO_LEAVE_FROM_MAIN(_proto_loop), (_proto_loop = NULL))
-
static inline int channel_is_active(struct channel *c)
{ return (c->channel_state != CS_DOWN); }
@@ -2389,6 +2378,8 @@ static struct rte_owner_class default_rte_owner_class;
static inline void
proto_do_start(struct proto *p)
{
+ ASSERT_DIE(birdloop_inside(p->loop));
+
p->active = 1;
rt_init_sources(&p->sources, p->name, proto_work_list(p));
@@ -2402,6 +2393,8 @@ proto_do_start(struct proto *p)
static void
proto_do_up(struct proto *p)
{
+ ASSERT_DIE(birdloop_inside(p->loop));
+
if (!p->main_source)
p->main_source = rt_get_source(p, 0);
// Locked automaticaly
diff --git a/nest/protocol.h b/nest/protocol.h
index f07bb4df..a4b6152b 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -268,6 +268,18 @@ struct proto *proto_iterate_named(struct symbol *sym, struct protocol *proto, st
#define PROTO_WALK_CMD(sym,pr,p) for(struct proto *p = NULL; p = proto_iterate_named(sym, pr, p); )
+#define PROTO_ENTER_FROM_MAIN(p) ({ \
+ ASSERT_DIE(birdloop_inside(&main_birdloop)); \
+ struct birdloop *_loop = (p)->loop; \
+ if (_loop != &main_birdloop) birdloop_enter(_loop); \
+ _loop; \
+ })
+
+#define PROTO_LEAVE_FROM_MAIN(loop) ({ if (loop != &main_birdloop) birdloop_leave(loop); })
+
+#define PROTO_LOCKED_FROM_MAIN(p) for (struct birdloop *_proto_loop = PROTO_ENTER_FROM_MAIN(p); _proto_loop; PROTO_LEAVE_FROM_MAIN(_proto_loop), (_proto_loop = NULL))
+
+
#define CMD_RELOAD 0
#define CMD_RELOAD_IN 1
#define CMD_RELOAD_OUT 2