summaryrefslogtreecommitdiff
path: root/net/bird3/files/patch-08-kernel-feed-only-once
diff options
context:
space:
mode:
Diffstat (limited to 'net/bird3/files/patch-08-kernel-feed-only-once')
-rw-r--r--net/bird3/files/patch-08-kernel-feed-only-once274
1 files changed, 0 insertions, 274 deletions
diff --git a/net/bird3/files/patch-08-kernel-feed-only-once b/net/bird3/files/patch-08-kernel-feed-only-once
deleted file mode 100644
index 33a98cbc4795..000000000000
--- a/net/bird3/files/patch-08-kernel-feed-only-once
+++ /dev/null
@@ -1,274 +0,0 @@
-From 0fa80d7c79428e5370740a2eba5605b65131ebd6 Mon Sep 17 00:00:00 2001
-From: Maria Matejka <mq@ucw.cz>
-Date: Mon, 23 Dec 2024 11:58:05 +0100
-Subject: [PATCH] Kernel: feed only once during startup
-
-There was an inefficiency in the initial scan state machine,
-causing routes to be fed several times instead of just once.
-Now the export startup is postponed until first krt_scan()
-finishes and we actually can do the pruning with full information.
----
- nest/proto.c | 4 ++-
- nest/protocol.h | 2 ++
- sysdep/unix/krt.c | 69 ++++++++++++++++++++++++++++-------------------
- sysdep/unix/krt.h | 5 ++--
- 4 files changed, 48 insertions(+), 32 deletions(-)
-
-diff --git a/nest/proto.c b/nest/proto.c
-index 678697d69..6fa74e9f1 100644
---- nest/proto.c
-+++ nest/proto.c
-@@ -676,9 +676,11 @@ void channel_notify_basic(void *);
- void channel_notify_accepted(void *);
- void channel_notify_merged(void *);
-
--static void
-+void
- channel_start_export(struct channel *c)
- {
-+ ASSERT_DIE(birdloop_inside(c->proto->loop));
-+
- if (rt_export_get_state(&c->out_req) != TES_DOWN)
- bug("%s.%s: Attempted to start channel's already started export", c->proto->name, c->name);
-
-diff --git a/nest/protocol.h b/nest/protocol.h
-index cf7ecb898..2bfa1628a 100644
---- nest/protocol.h
-+++ nest/protocol.h
-@@ -747,6 +747,8 @@ int proto_configure_channel(struct proto *p, struct channel **c, struct channel_
-
- void channel_set_state(struct channel *c, uint state);
-
-+void channel_start_export(struct channel *c);
-+
- void channel_add_obstacle(struct channel *c);
- void channel_del_obstacle(struct channel *c);
-
-diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c
-index 34882b88f..1658dd6fe 100644
---- sysdep/unix/krt.c
-+++ sysdep/unix/krt.c
-@@ -342,6 +342,8 @@ krt_learn_async(struct krt_proto *p, rte *e, int new)
- /* Hook defined in nest/rt-table.c ... to be refactored away later */
- rte *krt_export_net(struct channel *c, const net_addr *a, linpool *lp);
-
-+static void krt_rt_notify(struct proto *P, struct channel *ch, const net_addr *net, rte *new, const rte *old);
-+
- static int
- krt_same_dest(rte *k, rte *e)
- {
-@@ -361,6 +363,11 @@ krt_same_dest(rte *k, rte *e)
- void
- krt_got_route(struct krt_proto *p, rte *e, s8 src)
- {
-+ /* If we happen to get an asynchronous route notification
-+ * before initialization, we wait for the scan. */
-+ if (p->sync_state == KPS_INIT)
-+ return;
-+
- rte *new = NULL;
- e->pflags = 0;
-
-@@ -391,10 +398,6 @@ krt_got_route(struct krt_proto *p, rte *e, s8 src)
-
- /* The rest is for KRT_SRC_BIRD (or KRT_SRC_UNKNOWN) */
-
-- /* We wait for the initial feed to have correct installed state */
-- if (!p->ready)
-- goto ignore;
--
- /* Get the exported version */
- new = krt_export_net(p->p.main_channel, e->net, krt_filter_lp);
-
-@@ -423,10 +426,6 @@ aseen:
- krt_trace_in(p, e, "already seen");
- goto done;
-
--ignore:
-- krt_trace_in(p, e, "ignored");
-- goto done;
--
- update:
- krt_trace_in(p, new, "updating");
- krt_replace_rte(p, e->net, new, e);
-@@ -447,12 +446,21 @@ krt_init_scan(struct krt_proto *p)
- {
- switch (p->sync_state)
- {
-+ case KPS_INIT:
-+ /* Allow exports now */
-+ p->p.rt_notify = krt_rt_notify;
-+ channel_start_export(p->p.main_channel);
-+ rt_refresh_begin(&p->p.main_channel->in_req);
-+ p->sync_state = KPS_FIRST_SCAN;
-+ return 1;
-+
- case KPS_IDLE:
- rt_refresh_begin(&p->p.main_channel->in_req);
- bmap_reset(&p->seen_map, 1024);
- p->sync_state = KPS_SCANNING;
- return 1;
-
-+ case KPS_FIRST_SCAN:
- case KPS_SCANNING:
- bug("Kernel scan double-init");
-
-@@ -470,14 +478,17 @@ krt_prune(struct krt_proto *p)
- {
- switch (p->sync_state)
- {
-+ case KPS_INIT:
- case KPS_IDLE:
- bug("Kernel scan prune without scan");
-
- case KPS_SCANNING:
-+ channel_request_full_refeed(p->p.main_channel);
-+ /* fall through */
-+ case KPS_FIRST_SCAN:
- p->sync_state = KPS_PRUNING;
- KRT_TRACE(p, D_EVENTS, "Pruning table %s", p->p.main_channel->table->name);
- rt_refresh_end(&p->p.main_channel->in_req);
-- channel_request_full_refeed(p->p.main_channel);
- break;
-
- case KPS_PRUNING:
-@@ -549,7 +560,7 @@ krt_scan_all(timer *t UNUSED)
- krt_do_scan(NULL);
-
- WALK_LIST2(p, n, krt_proto_list, krt_node)
-- if (p->sync_state == KPS_SCANNING)
-+ if ((p->sync_state == KPS_SCANNING) || (p->sync_state == KPS_FIRST_SCAN))
- krt_prune(p);
- }
-
-@@ -644,6 +655,9 @@ krt_scan_timer_kick(struct krt_proto *p)
- static int
- krt_preexport(struct channel *C, rte *e)
- {
-+ /* The export should not start before proper sync */
-+ ASSERT_DIE(SKIP_BACK(struct krt_proto, p, C->proto)->sync_state != KPS_INIT);
-+
- if (e->src->owner == &C->proto->sources)
- #ifdef CONFIG_SINGLE_ROUTE
- return 1;
-@@ -659,15 +673,6 @@ krt_preexport(struct channel *C, rte *e)
- return -1;
- }
-
-- /* Before first scan we don't touch the routes */
-- if (!SKIP_BACK(struct krt_proto, p, C->proto)->ready)
-- {
-- if (C->debug & D_ROUTES)
-- log(L_TRACE "%s.%s not ready yet to accept route for %N",
-- C->proto->name, C->name, e->net);
-- return -1;
-- }
--
- return 0;
- }
-
-@@ -685,18 +690,24 @@ krt_rt_notify(struct proto *P, struct channel *ch, const net_addr *net,
-
- switch (p->sync_state)
- {
-+ case KPS_INIT:
-+ bug("Routes in init state should have been rejected by preexport.");
-+
- case KPS_IDLE:
- case KPS_PRUNING:
- if (new && bmap_test(&p->seen_map, new->id))
-+ {
- if (ch->debug & D_ROUTES)
- {
- /* Already installed and seen in the kernel dump */
- log(L_TRACE "%s.%s: %N already in kernel",
- P->name, ch->name, net);
-- return;
- }
-+ return;
-+ }
-
- /* fall through */
-+ case KPS_FIRST_SCAN:
- case KPS_SCANNING:
- /* Actually replace the route */
- krt_replace_rte(p, net, new, old);
-@@ -732,7 +743,6 @@ krt_reload_routes(struct channel *C, struct rt_feeding_request *rfr)
-
- if (KRT_CF->learn)
- {
-- p->reload = 1;
- krt_scan_timer_kick(p);
- }
-
-@@ -749,15 +759,18 @@ krt_export_fed(struct channel *C)
- {
- struct krt_proto *p = (void *) C->proto;
-
-- p->ready = 1;
-- p->initialized = 1;
--
- switch (p->sync_state)
- {
-+ case KPS_INIT:
-+ bug("KRT export started before scan");
-+
- case KPS_IDLE:
- krt_scan_timer_kick(p);
- break;
-
-+ case KPS_FIRST_SCAN:
-+ bug("KRT export done before first scan");
-+
- case KPS_SCANNING:
- break;
-
-@@ -831,7 +844,8 @@ krt_init(struct proto_config *CF)
- p->p.main_channel = proto_add_channel(&p->p, proto_cf_main_channel(CF));
-
- p->p.preexport = krt_preexport;
-- p->p.rt_notify = krt_rt_notify;
-+ /* Not setting rt_notify here to not start exports, must wait for the first scan
-+ * and then we can start exports manually */
- p->p.iface_sub.if_notify = krt_if_notify;
- p->p.reload_routes = krt_reload_routes;
- p->p.export_fed = krt_export_fed;
-@@ -887,7 +901,7 @@ krt_shutdown(struct proto *P)
- return PS_FLUSH;
-
- /* FIXME we should flush routes even when persist during reconfiguration */
-- if (p->initialized && !KRT_CF->persist && (P->down_code != PDC_CMD_GR_DOWN))
-+ if ((p->sync_state != KPS_INIT) && !KRT_CF->persist && (P->down_code != PDC_CMD_GR_DOWN))
- {
- struct rt_export_feeder req = (struct rt_export_feeder)
- {
-@@ -922,8 +936,7 @@ krt_shutdown(struct proto *P)
- static void
- krt_cleanup(struct krt_proto *p)
- {
-- p->ready = 0;
-- p->initialized = 0;
-+ p->sync_state = KPS_INIT;
-
- krt_sys_shutdown(p);
- rem_node(&p->krt_node);
-diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h
-index 394e74010..14be715f8 100644
---- sysdep/unix/krt.h
-+++ sysdep/unix/krt.h
-@@ -59,10 +59,9 @@ struct krt_proto {
- struct bmap seen_map; /* Routes seen during last periodic scan */
- node krt_node; /* Node in krt_proto_list */
- byte af; /* Kernel address family (AF_*) */
-- byte ready; /* Initial feed has been finished */
-- byte initialized; /* First scan has been finished */
-- byte reload; /* Next scan is doing reload */
- PACKED enum krt_prune_state {
-+ KPS_INIT,
-+ KPS_FIRST_SCAN,
- KPS_IDLE,
- KPS_SCANNING,
- KPS_PRUNING,
---
-GitLab
-