diff options
Diffstat (limited to 'net/bird3/files/patch-08-kernel-feed-only-once')
-rw-r--r-- | net/bird3/files/patch-08-kernel-feed-only-once | 274 |
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 - |