Commit 76c333d2e8 for frr
commit 76c333d2e828e65f03128f2db3cfc115db69cc93
Author: Chenlang Li <lichenlang@catalystovo.com>
Date: Fri Nov 6 23:26:36 2026 +0800
ospf6d: track the neighbor's seqnumber_mismatch/bad_lsreq events
seqnumber_mismatch() and bad_lsreq() are queued with event_add_event()
and the neighbor as the event argument, with NULL as the event handle.
Nothing can cancel them by hand, so if the neighbor is deleted before
they run - a link state request or a bad sequence number arriving in the
same event batch as an interface teardown - the callback reads the freed
neighbor.
Give the neighbor a handle for each of them, pass it at every queue site
and cancel both in ospf6_neighbor_delete(), next to the other per-
neighbor handles. event_cancel() before re-arming keeps at most one
event pending per handle, and _event_add_event() refuses a second one
while the handle is set, so an earlier event cannot be orphaned.
Signed-off-by: Chenlang Li <lichenlang@catalystovo.com>
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c
index 9d3ca5284d..62412a026c 100644
--- a/ospf6d/ospf6_flood.c
+++ b/ospf6d/ospf6_flood.c
@@ -1155,7 +1155,8 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
new->name);
/* BadLSReq */
- event_add_event(master, bad_lsreq, from, 0, NULL);
+ event_cancel(&from->thread_bad_lsreq);
+ event_add_event(master, bad_lsreq, from, 0, &from->thread_bad_lsreq);
ospf6_lsa_delete(new);
return;
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index aa39a95cb2..c5fdd37e65 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -691,24 +691,27 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
zlog_warn(
"DbDesc recv: Master/Slave bit mismatch Nbr %s",
on->name);
+ event_cancel(&on->thread_seqnumber_mismatch);
event_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ &on->thread_seqnumber_mismatch);
return;
}
if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)) {
zlog_warn("DbDesc recv: Initialize bit mismatch Nbr %s",
on->name);
+ event_cancel(&on->thread_seqnumber_mismatch);
event_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ &on->thread_seqnumber_mismatch);
return;
}
if (memcmp(on->options, dbdesc->options, sizeof(on->options))) {
zlog_warn("DbDesc recv: Option field mismatch Nbr %s",
on->name);
+ event_cancel(&on->thread_seqnumber_mismatch);
event_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ &on->thread_seqnumber_mismatch);
return;
}
@@ -717,8 +720,9 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
"DbDesc recv: Sequence number mismatch Nbr %s (received %#lx, %#lx expected)",
on->name, (unsigned long)ntohl(dbdesc->seqnum),
(unsigned long)on->dbdesc_seqnum);
+ event_cancel(&on->thread_seqnumber_mismatch);
event_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ &on->thread_seqnumber_mismatch);
return;
}
break;
@@ -738,7 +742,8 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
zlog_warn(
"DbDesc recv: Not duplicate dbdesc in state %s Nbr %s",
ospf6_neighbor_state_str[on->state], on->name);
- event_add_event(master, seqnumber_mismatch, on, 0, NULL);
+ event_cancel(&on->thread_seqnumber_mismatch);
+ event_add_event(master, seqnumber_mismatch, on, 0, &on->thread_seqnumber_mismatch);
return;
default:
@@ -784,8 +789,9 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
zlog_debug(
"SeqNumMismatch (E-bit mismatch), discard");
ospf6_lsa_delete(his);
+ event_cancel(&on->thread_seqnumber_mismatch);
event_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ &on->thread_seqnumber_mismatch);
return;
}
@@ -914,8 +920,9 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
zlog_warn(
"DbDesc slave recv: Master/Slave bit mismatch Nbr %s",
on->name);
+ event_cancel(&on->thread_seqnumber_mismatch);
event_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ &on->thread_seqnumber_mismatch);
return;
}
@@ -923,8 +930,9 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
zlog_warn(
"DbDesc slave recv: Initialize bit mismatch Nbr %s",
on->name);
+ event_cancel(&on->thread_seqnumber_mismatch);
event_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ &on->thread_seqnumber_mismatch);
return;
}
@@ -932,8 +940,9 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
zlog_warn(
"DbDesc slave recv: Option field mismatch Nbr %s",
on->name);
+ event_cancel(&on->thread_seqnumber_mismatch);
event_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ &on->thread_seqnumber_mismatch);
return;
}
@@ -942,8 +951,9 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
"DbDesc slave recv: Sequence number mismatch Nbr %s (received %#lx, %#lx expected)",
on->name, (unsigned long)ntohl(dbdesc->seqnum),
(unsigned long)on->dbdesc_seqnum + 1);
+ event_cancel(&on->thread_seqnumber_mismatch);
event_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ &on->thread_seqnumber_mismatch);
return;
}
break;
@@ -966,7 +976,8 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
zlog_warn(
"DbDesc slave recv: Not duplicate dbdesc in state %s Nbr %s",
ospf6_neighbor_state_str[on->state], on->name);
- event_add_event(master, seqnumber_mismatch, on, 0, NULL);
+ event_cancel(&on->thread_seqnumber_mismatch);
+ event_add_event(master, seqnumber_mismatch, on, 0, &on->thread_seqnumber_mismatch);
return;
default:
@@ -1008,8 +1019,9 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
zlog_debug("E-bit mismatch with LSA Headers");
ospf6_lsa_delete(his);
+ event_cancel(&on->thread_seqnumber_mismatch);
event_add_event(master, seqnumber_mismatch, on, 0,
- NULL);
+ &on->thread_seqnumber_mismatch);
return;
}
@@ -1160,7 +1172,8 @@ static void ospf6_lsreq_recv(struct in6_addr *src, struct in6_addr *dst,
"Can't find requested lsa [%s Id:%pI4 Adv:%pI4] send badLSReq",
ospf6_lstype_name(e->type), &e->id,
&e->adv_router);
- event_add_event(master, bad_lsreq, on, 0, NULL);
+ event_cancel(&on->thread_bad_lsreq);
+ event_add_event(master, bad_lsreq, on, 0, &on->thread_bad_lsreq);
return;
}
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index 4d079afb1a..fad77861e3 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -194,6 +194,10 @@ void ospf6_neighbor_delete(struct ospf6_neighbor *on)
event_cancel(&on->gr_helper_info.t_grace_timer);
bfd_sess_free(&on->bfd_session);
+
+ event_cancel(&on->thread_seqnumber_mismatch);
+ event_cancel(&on->thread_bad_lsreq);
+
XFREE(MTYPE_OSPF6_NEIGHBOR, on);
}
diff --git a/ospf6d/ospf6_neighbor.h b/ospf6d/ospf6_neighbor.h
index 38ddb46f64..343294dd9d 100644
--- a/ospf6d/ospf6_neighbor.h
+++ b/ospf6d/ospf6_neighbor.h
@@ -137,6 +137,8 @@ struct ospf6_neighbor {
struct event *thread_exchange_done;
struct event *thread_adj_ok;
struct event *event_loading_done;
+ struct event *thread_seqnumber_mismatch;
+ struct event *thread_bad_lsreq;
/* BFD information */
struct bfd_session_params *bfd_session;