net-misc/bird: Apply the whole v3.0.0...thread-next
Signed-off-by: Alarig Le Lay <alarig@swordarmor.fr>
This commit is contained in:
parent
55c7e2755c
commit
2f8e55449b
6 changed files with 1759 additions and 370 deletions
|
@ -37,10 +37,7 @@ FILECAPS=(
|
|||
)
|
||||
|
||||
PATCHES=(
|
||||
"${FILESDIR}"/${P}-proto-lock.patch
|
||||
"${FILESDIR}"/${P}-nest-rt-table.c.patch
|
||||
"${FILESDIR}"/${P}-rt-table.c.patch
|
||||
"${FILESDIR}"/${P}-bgp-med.patch
|
||||
"${FILESDIR}"/${P}_p20250107.patch
|
||||
)
|
||||
|
||||
src_prepare() {
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
From c5b07695ce810e4345ed1811eadfce935c83b324 Mon Sep 17 00:00:00 2001
|
||||
From: Maria Matejka <mq@ucw.cz>
|
||||
Date: Tue, 7 Jan 2025 11:08:04 +0100
|
||||
Subject: [PATCH] BGP: fixed deterministic med crashes
|
||||
|
||||
There were several places of forgotten NULL checks.
|
||||
|
||||
Thanks to Alarig Le Lay <alarig@swordarmor.fr> for reporting:
|
||||
https://trubka.network.cz/pipermail/bird-users/2024-December/017990.html
|
||||
---
|
||||
nest/rt-table.c | 14 ++++++++++++--
|
||||
proto/bgp/attrs.c | 8 ++++----
|
||||
2 files changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/nest/rt-table.c b/nest/rt-table.c
|
||||
index 05191d743..fc6d0d4e0 100644
|
||||
--- a/nest/rt-table.c
|
||||
+++ b/nest/rt-table.c
|
||||
@@ -2024,12 +2024,22 @@ rte_recalculate(struct rtable_private *table, struct rt_import_hook *c, struct n
|
||||
do_recalculate:
|
||||
/* Add the new route to the list right behind the old one */
|
||||
if (new_stored)
|
||||
+ {
|
||||
+ /* There is the same piece of code several lines farther. Needs refactoring.
|
||||
+ * The old_stored check is needed because of the possible jump from deterministic med */
|
||||
+ if (old_stored)
|
||||
{
|
||||
atomic_store_explicit(&new_stored->next, atomic_load_explicit(&old_stored->next, memory_order_relaxed), memory_order_release);
|
||||
atomic_store_explicit(&old_stored->next, new_stored, memory_order_release);
|
||||
-
|
||||
- table->rt_count++;
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ atomic_store_explicit(&new_stored->next, NULL, memory_order_release);
|
||||
+ atomic_store_explicit(last_ptr, new_stored, memory_order_release);
|
||||
+ }
|
||||
+
|
||||
+ table->rt_count++;
|
||||
+ }
|
||||
|
||||
/* Find a new optimal route (if there is any) */
|
||||
struct rte_storage * _Atomic *bp = &local_sentinel.next;
|
||||
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
|
||||
index 5dc06be51..db6542343 100644
|
||||
--- a/proto/bgp/attrs.c
|
||||
+++ b/proto/bgp/attrs.c
|
||||
@@ -2689,10 +2689,10 @@ bgp_rte_recalculate(struct rtable_private *table, net *net,
|
||||
struct rte_storage *new_stored, struct rte_storage *old_stored, struct rte_storage *old_best_stored)
|
||||
{
|
||||
struct rte_storage *key_stored = new_stored ? new_stored : old_stored;
|
||||
- const struct rte *new = &new_stored->rte,
|
||||
- *old = &old_stored->rte,
|
||||
- *old_best = &old_best_stored->rte,
|
||||
- *key = &key_stored->rte;
|
||||
+ const struct rte *new = RTE_OR_NULL(new_stored),
|
||||
+ *old = RTE_OR_NULL(old_stored),
|
||||
+ *old_best = RTE_OR_NULL(old_best_stored),
|
||||
+ *key = RTE_OR_NULL(key_stored);
|
||||
|
||||
u32 lpref = rt_get_preference(key);
|
||||
u32 lasn = bgp_get_neighbor(key);
|
||||
--
|
||||
GitLab
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
From b6caccfd45fb639b6dd3a8d140d3c5ba4cc79311 Mon Sep 17 00:00:00 2001
|
||||
From: Maria Matejka <mq@ucw.cz>
|
||||
Date: Thu, 19 Dec 2024 11:00:15 +0100
|
||||
Subject: [PATCH] Kernel: Fix crash for merge paths on if no route is in BIRD
|
||||
|
||||
There was a missing check for a NULL return value.
|
||||
Also fixed an indenting error.
|
||||
|
||||
Thanks to Radu Anghel for reporting it:
|
||||
https://bird.network.cz/pipermail/bird-users/2024-December/017977.html
|
||||
---
|
||||
nest/rt-table.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/nest/rt-table.c b/nest/rt-table.c
|
||||
index fd8bb50dd..05191d743 100644
|
||||
--- a/nest/rt-table.c
|
||||
+++ b/nest/rt-table.c
|
||||
@@ -5265,14 +5265,14 @@ krt_export_net(struct channel *c, const net_addr *a, linpool *lp)
|
||||
if (c->ra_mode == RA_MERGED)
|
||||
{
|
||||
struct rt_export_feed *feed = rt_net_feed(c->table, a, NULL);
|
||||
- if (!feed->count_routes)
|
||||
+ if (!feed || !feed->count_routes)
|
||||
return NULL;
|
||||
|
||||
if (!bmap_test(&c->export_accepted_map, feed->block[0].id))
|
||||
return NULL;
|
||||
|
||||
return rt_export_merged(c, feed, lp, 1);
|
||||
- }
|
||||
+ }
|
||||
|
||||
static _Thread_local rte best;
|
||||
best = rt_net_best(c->table, a);
|
||||
--
|
||||
GitLab
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
From 6779e5da698feb9b9e02411859ad81885ba46c01 Mon Sep 17 00:00:00 2001
|
||||
From: Maria Matejka <mq@ucw.cz>
|
||||
Date: Fri, 20 Dec 2024 11:28:00 +0100
|
||||
Subject: [PATCH] BGP: fix locking order error on dynamic protocol spawn
|
||||
|
||||
We missed that the protocol spawner violates the prescribed
|
||||
locking order. When the rtable level is locked, no new protocol can be
|
||||
started, thus we need to:
|
||||
|
||||
* create the protocol from a clean mainloop context
|
||||
* in protocol start hook, take the socket
|
||||
|
||||
Testsuite: cf-bgp-autopeer
|
||||
Fixes: #136
|
||||
|
||||
Thanks to Job Snijders <job@fastly.com> for reporting:
|
||||
https://trubka.network.cz/pipermail/bird-users/2024-December/017980.html
|
||||
---
|
||||
nest/proto.c | 19 +++++++++++++++++++
|
||||
nest/protocol.h | 2 ++
|
||||
proto/bgp/bgp.c | 46 +++++++++++++++++++++++++++++++++++-----------
|
||||
3 files changed, 56 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/nest/proto.c b/nest/proto.c
|
||||
index dded84f51..678697d69 100644
|
||||
--- a/nest/proto.c
|
||||
+++ b/nest/proto.c
|
||||
@@ -1867,6 +1867,25 @@ proto_spawn(struct proto_config *cf, uint disabled)
|
||||
return p;
|
||||
}
|
||||
|
||||
+bool
|
||||
+proto_disable(struct proto *p)
|
||||
+{
|
||||
+ ASSERT_DIE(birdloop_inside(&main_birdloop));
|
||||
+ bool changed = !p->disabled;
|
||||
+ p->disabled = 1;
|
||||
+ proto_rethink_goal(p);
|
||||
+ return changed;
|
||||
+}
|
||||
+
|
||||
+bool
|
||||
+proto_enable(struct proto *p)
|
||||
+{
|
||||
+ ASSERT_DIE(birdloop_inside(&main_birdloop));
|
||||
+ bool changed = p->disabled;
|
||||
+ p->disabled = 0;
|
||||
+ proto_rethink_goal(p);
|
||||
+ return changed;
|
||||
+}
|
||||
|
||||
/**
|
||||
* DOC: Graceful restart recovery
|
||||
diff --git a/nest/protocol.h b/nest/protocol.h
|
||||
index 25ed6f553..cf7ecb898 100644
|
||||
--- a/nest/protocol.h
|
||||
+++ b/nest/protocol.h
|
||||
@@ -78,6 +78,8 @@ void proto_build(struct protocol *); /* Called from protocol to register itself
|
||||
void protos_preconfig(struct config *);
|
||||
void protos_commit(struct config *new, struct config *old, int type);
|
||||
struct proto * proto_spawn(struct proto_config *cf, uint disabled);
|
||||
+bool proto_disable(struct proto *p);
|
||||
+bool proto_enable(struct proto *p);
|
||||
void protos_dump_all(struct dump_request *);
|
||||
|
||||
#define GA_UNKNOWN 0 /* Attribute not recognized */
|
||||
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
|
||||
index 5fc2b5fff..3170e3a42 100644
|
||||
--- a/proto/bgp/bgp.c
|
||||
+++ b/proto/bgp/bgp.c
|
||||
@@ -378,8 +378,6 @@ bgp_startup(struct bgp_proto *p)
|
||||
if (p->postponed_sk)
|
||||
{
|
||||
/* Apply postponed incoming connection */
|
||||
- sk_reloop(p->postponed_sk, p->p.loop);
|
||||
-
|
||||
bgp_setup_conn(p, &p->incoming_conn);
|
||||
bgp_setup_sk(&p->incoming_conn, p->postponed_sk);
|
||||
bgp_send_open(&p->incoming_conn);
|
||||
@@ -583,6 +581,9 @@ bgp_graceful_close_conn(struct bgp_conn *conn, int subcode, byte *data, uint len
|
||||
static void
|
||||
bgp_down(struct bgp_proto *p)
|
||||
{
|
||||
+ /* Check that the dynamic BGP socket has been picked up */
|
||||
+ ASSERT_DIE(p->postponed_sk == NULL);
|
||||
+
|
||||
if (bgp_start_state(p) > BSS_PREPARE)
|
||||
{
|
||||
bgp_setup_auth(p, 0);
|
||||
@@ -617,8 +618,8 @@ bgp_decision(void *vp)
|
||||
bgp_down(p);
|
||||
}
|
||||
|
||||
-static struct bgp_proto *
|
||||
-bgp_spawn(struct bgp_proto *pp, ip_addr remote_ip)
|
||||
+static void
|
||||
+bgp_spawn(struct bgp_proto *pp, struct birdsock *sk)
|
||||
{
|
||||
struct symbol *sym;
|
||||
char fmt[SYM_MAX_LEN];
|
||||
@@ -635,9 +636,16 @@ bgp_spawn(struct bgp_proto *pp, ip_addr remote_ip)
|
||||
cfg_mem = NULL;
|
||||
|
||||
/* Just pass remote_ip to bgp_init() */
|
||||
- ((struct bgp_config *) sym->proto)->remote_ip = remote_ip;
|
||||
+ ((struct bgp_config *) sym->proto)->remote_ip = sk->daddr;
|
||||
+
|
||||
+ /* Create the protocol disabled initially */
|
||||
+ SKIP_BACK_DECLARE(struct bgp_proto, p, p, proto_spawn(sym->proto, 1));
|
||||
|
||||
- return (void *) proto_spawn(sym->proto, 0);
|
||||
+ /* Pass the socket */
|
||||
+ p->postponed_sk = sk;
|
||||
+
|
||||
+ /* And enable the protocol */
|
||||
+ proto_enable(&p->p);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1489,10 +1497,15 @@ bgp_incoming_connection(sock *sk, uint dummy UNUSED)
|
||||
/* For dynamic BGP, spawn new instance and postpone the socket */
|
||||
if (bgp_is_dynamic(p))
|
||||
{
|
||||
- p = bgp_spawn(p, sk->daddr);
|
||||
- p->postponed_sk = sk;
|
||||
- rmove(sk, p->p.pool);
|
||||
- goto leave;
|
||||
+ UNLOCK_DOMAIN(rtable, bgp_listen_domain);
|
||||
+
|
||||
+ /* The dynamic protocol must be in the START state */
|
||||
+ ASSERT_DIE(p->p.proto_state == PS_START);
|
||||
+ birdloop_leave(p->p.loop);
|
||||
+
|
||||
+ /* Now we have a clean mainloop */
|
||||
+ bgp_spawn(p, sk);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
rmove(sk, p->p.pool);
|
||||
@@ -1806,7 +1819,6 @@ bgp_start(struct proto *P)
|
||||
p->incoming_conn.state = BS_IDLE;
|
||||
p->neigh = NULL;
|
||||
p->bfd_req = NULL;
|
||||
- p->postponed_sk = NULL;
|
||||
p->gr_ready = 0;
|
||||
p->gr_active_num = 0;
|
||||
|
||||
@@ -1848,6 +1860,16 @@ bgp_start(struct proto *P)
|
||||
channel_graceful_restart_lock(&c->c);
|
||||
}
|
||||
|
||||
+ /* Now it's the last chance to move the postponed socket to this BGP,
|
||||
+ * as bgp_start is the only hook running from main loop. */
|
||||
+ if (p->postponed_sk)
|
||||
+ {
|
||||
+ LOCK_DOMAIN(rtable, bgp_listen_domain);
|
||||
+ rmove(p->postponed_sk, p->p.pool);
|
||||
+ sk_reloop(p->postponed_sk, p->p.loop);
|
||||
+ UNLOCK_DOMAIN(rtable, bgp_listen_domain);
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Before attempting to create the connection, we need to lock the port,
|
||||
* so that we are the only instance attempting to talk with that neighbor.
|
||||
@@ -1999,6 +2021,8 @@ bgp_init(struct proto_config *CF)
|
||||
p->remote_ip = cf->remote_ip;
|
||||
p->remote_as = cf->remote_as;
|
||||
|
||||
+ p->postponed_sk = NULL;
|
||||
+
|
||||
/* Hack: We use cf->remote_ip just to pass remote_ip from bgp_spawn() */
|
||||
if (cf->c.parent)
|
||||
cf->remote_ip = IPA_NONE;
|
||||
--
|
||||
GitLab
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
From 2e14832d36c83b2ab5b7fb28b701de554fa5fdd9 Mon Sep 17 00:00:00 2001
|
||||
From: Maria Matejka <mq@ucw.cz>
|
||||
Date: Tue, 7 Jan 2025 12:13:57 +0100
|
||||
Subject: [PATCH] Table: old best route refeed fix
|
||||
|
||||
When refeeding with RA_OPTIMAL, the old best routes weren't announced,
|
||||
leading to weird behavior of protocols, mostly kernel. Fixed.
|
||||
---
|
||||
nest/rt-table.c | 30 ++++++++++++++++++++++++++----
|
||||
1 file changed, 26 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/nest/rt-table.c b/nest/rt-table.c
|
||||
index fc6d0d4e0..18a445a62 100644
|
||||
--- a/nest/rt-table.c
|
||||
+++ b/nest/rt-table.c
|
||||
@@ -1485,11 +1485,18 @@ channel_notify_basic(void *_channel)
|
||||
rte *new = &u->feed->block[i];
|
||||
rte *old = NULL;
|
||||
for (uint o = oldpos; o < u->feed->count_routes; o++)
|
||||
- if (new->src == u->feed->block[o].src)
|
||||
+ if ((c->ra_mode == RA_ANY) && (new->src == u->feed->block[o].src))
|
||||
{
|
||||
old = &u->feed->block[o];
|
||||
break;
|
||||
}
|
||||
+ else if ((c->ra_mode == RA_OPTIMAL) && (
|
||||
+ bmap_test(&c->export_accepted_map, u->feed->block[o].id) ||
|
||||
+ bmap_test(&c->export_rejected_map, u->feed->block[o].id)))
|
||||
+ {
|
||||
+ ASSERT_DIE(!old);
|
||||
+ old = &u->feed->block[o];
|
||||
+ }
|
||||
|
||||
rt_notify_basic(c, new, old);
|
||||
|
||||
@@ -2542,10 +2549,14 @@ rt_feed_net_best(struct rt_exporter *e, struct rcu_unwinder *u, u32 index, bool
|
||||
last_in_net = atomic_load_explicit(&n->best.last, memory_order_acquire);
|
||||
first = rt_net_feed_validate_first(tr, first_in_net, last_in_net, first);
|
||||
|
||||
- uint ecnt = 0;
|
||||
+ uint ecnt = 0, ocnt = 0;
|
||||
for (const struct rt_pending_export *rpe = first; rpe;
|
||||
rpe = atomic_load_explicit(&rpe->next, memory_order_acquire))
|
||||
+ {
|
||||
ecnt++;
|
||||
+ if (rpe->it.old)
|
||||
+ ocnt++;
|
||||
+ }
|
||||
|
||||
if (ecnt) {
|
||||
const net_addr *a = (first->it.new ?: first->it.old)->net;
|
||||
@@ -2558,10 +2569,11 @@ rt_feed_net_best(struct rt_exporter *e, struct rcu_unwinder *u, u32 index, bool
|
||||
if (!ecnt && (!best || prefilter && !prefilter(f, best->rte.net)))
|
||||
return NULL;
|
||||
|
||||
- struct rt_export_feed *feed = rt_alloc_feed(!!best, ecnt);
|
||||
+ struct rt_export_feed *feed = rt_alloc_feed(!!best + ocnt, ecnt);
|
||||
+ uint bpos = 0;
|
||||
if (best)
|
||||
{
|
||||
- feed->block[0] = best->rte;
|
||||
+ feed->block[bpos++] = best->rte;
|
||||
feed->ni = NET_TO_INDEX(best->rte.net);
|
||||
}
|
||||
else
|
||||
@@ -2575,8 +2587,18 @@ rt_feed_net_best(struct rt_exporter *e, struct rcu_unwinder *u, u32 index, bool
|
||||
if (e >= ecnt)
|
||||
RT_READ_RETRY(tr);
|
||||
else
|
||||
+ {
|
||||
feed->exports[e++] = rpe->it.seq;
|
||||
+ if (rpe->it.old)
|
||||
+ {
|
||||
+ ASSERT_DIE(bpos < !!best + ocnt);
|
||||
+ feed->block[bpos] = *rpe->it.old;
|
||||
+ feed->block[bpos].flags |= REF_OBSOLETE;
|
||||
+ bpos++;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ ASSERT_DIE(bpos == !!best + ocnt);
|
||||
ASSERT_DIE(e == ecnt);
|
||||
}
|
||||
|
||||
--
|
||||
GitLab
|
||||
|
1758
net-misc/bird/files/bird-3.0.0_p20250107.patch
Normal file
1758
net-misc/bird/files/bird-3.0.0_p20250107.patch
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue