[PATCH] babel: Don't try to remove multicast seqno request objects from neighbour list
Toke Høiland-Jørgensen
toke at toke.dk
Thu May 12 14:12:13 CEST 2022
The Babel seqno request code keeps track of which seqno requests are
outstanding for a neighbour by putting them onto a per-neighbour list. When
reusing a seqno request, it will try to remove this node, but if the seqno
request in question was a multicast request with no neighbour attached this
will result in a crash because it tries to remove a list node that wasn't
added to any list.
Fix this by making the list remove conditional. Also add a check so that
seqno requests are only reused if the neighbour also matches, allowing
multiple outstanding requests for the same router ID.
Fixes: ebd5751cdeb4 ("Babel: Seqno requests are properly decoupled from neighbors when the underlying interface disappears")
Reported-by: Stefan Haller <stefan.haller at stha.de>
Signed-off-by: Toke Høiland-Jørgensen <toke at toke.dk>
---
proto/babel/babel.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index 4a7d550f5efe..03f1cb500278 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -304,7 +304,7 @@ babel_add_seqno_request(struct babel_proto *p, struct babel_entry *e,
struct babel_seqno_request *sr;
WALK_LIST(sr, e->requests)
- if (sr->router_id == router_id)
+ if (sr->router_id == router_id && sr->nbr == nbr)
{
/* Found matching or newer */
if (ge_mod64k(sr->seqno, seqno) && seqno_request_valid(sr))
@@ -312,7 +312,8 @@ babel_add_seqno_request(struct babel_proto *p, struct babel_entry *e,
/* Found older */
rem_node(NODE sr);
- rem_node(&sr->nbr_node);
+ if (sr->nbr)
+ rem_node(&sr->nbr_node);
goto found;
}
@@ -349,17 +350,20 @@ static int
babel_satisfy_seqno_request(struct babel_proto *p, struct babel_entry *e,
u64 router_id, u16 seqno)
{
- struct babel_seqno_request *sr;
+ struct babel_seqno_request *sr, *srx;
+ int ret = 0;
- WALK_LIST(sr, e->requests)
+ WALK_LIST_DELSAFE(sr, srx, e->requests)
if ((sr->router_id == router_id) && ge_mod64k(seqno, sr->seqno))
{
- /* Found the request, remove it */
+ /* Found a matching request, remove it; there may be multiple outstanding
+ * requests, so continue looping
+ */
babel_remove_seqno_request(p, sr);
- return 1;
+ ret = 1;
}
- return 0;
+ return ret;
}
static void
--
2.36.1
More information about the Bird-users
mailing list