summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJafar Al-Gharaibeh <jafar@atcorp.com>2025-01-25 11:12:45 -0600
committerGitHub <noreply@github.com>2025-01-25 11:12:45 -0600
commit273dc49b7390d9aa02ed6341caa43b128e08c6b2 (patch)
tree27d6e2a5a7c48b3b006cbdaa74e0d6df686b1b43
parent3ff48febe7b95d69fec6e14e686c9497ec517dfd (diff)
parent186b59e4179aca8160ac24f067eb7d2f0db3fdd9 (diff)
Merge pull request #17923 from donaldsharp/backport_17229_some_to_10_1
Backport 17229 some to 10 1
-rw-r--r--bgpd/bgp_fsm.c10
-rw-r--r--bgpd/bgp_fsm.h1
-rw-r--r--bgpd/bgp_packet.c60
-rw-r--r--bgpd/bgpd.h2
-rw-r--r--zebra/kernel_netlink.c2
5 files changed, 42 insertions, 33 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index cd2faa4777..7605501754 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -178,6 +178,7 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
EVENT_OFF(going_away->t_delayopen);
EVENT_OFF(going_away->t_connect_check_r);
EVENT_OFF(going_away->t_connect_check_w);
+ EVENT_OFF(going_away->t_stop_with_notify);
EVENT_OFF(keeper->t_routeadv);
EVENT_OFF(keeper->t_connect);
EVENT_OFF(keeper->t_delayopen);
@@ -1483,6 +1484,8 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection)
EVENT_OFF(connection->t_connect_check_r);
EVENT_OFF(connection->t_connect_check_w);
+ EVENT_OFF(connection->t_stop_with_notify);
+
/* Stop all timers. */
EVENT_OFF(connection->t_start);
EVENT_OFF(connection->t_connect);
@@ -3178,3 +3181,10 @@ void bgp_peer_gr_flags_update(struct peer *peer)
}
}
}
+
+void bgp_event_stop_with_notify(struct event *event)
+{
+ struct peer_connection *connection = EVENT_ARG(event);
+
+ bgp_stop_with_notify(connection, BGP_NOTIFY_SEND_HOLD_ERR, 0);
+}
diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h
index bcdd49193f..4cdded8b47 100644
--- a/bgpd/bgp_fsm.h
+++ b/bgpd/bgp_fsm.h
@@ -109,6 +109,7 @@ enum bgp_fsm_state_progress {
extern void bgp_fsm_nht_update(struct peer_connection *connection,
struct peer *peer, bool has_valid_nexthops);
extern void bgp_event(struct event *event);
+extern void bgp_event_stop_with_notify(struct event *event);
extern int bgp_event_update(struct peer_connection *connection,
enum bgp_fsm_events event);
extern enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection);
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 010a31a3a8..2f8c2f326a 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -122,42 +122,38 @@ static void bgp_packet_add(struct peer_connection *connection,
peer->last_sendq_ok = monotime(NULL);
stream_fifo_push(connection->obuf, s);
+ }
- delta = monotime(NULL) - peer->last_sendq_ok;
+ delta = monotime(NULL) - peer->last_sendq_ok;
- if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
- holdtime = atomic_load_explicit(&peer->holdtime,
- memory_order_relaxed);
- else
- holdtime = peer->bgp->default_holdtime;
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
+ holdtime = atomic_load_explicit(&peer->holdtime, memory_order_relaxed);
+ else
+ holdtime = peer->bgp->default_holdtime;
- sendholdtime = holdtime * 2;
+ sendholdtime = holdtime * 2;
- /* Note that when we're here, we're adding some packet to the
- * OutQ. That includes keepalives when there is nothing to
- * do, so there's a guarantee we pass by here once in a while.
- *
- * That implies there is no need to go set up another separate
- * timer that ticks down SendHoldTime, as we'll be here sooner
- * or later anyway and will see the checks below failing.
- */
- if (!holdtime) {
- /* no holdtime, do nothing. */
- } else if (delta > sendholdtime) {
- flog_err(
- EC_BGP_SENDQ_STUCK_PROPER,
- "%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session",
- peer, sendholdtime);
- bgp_stop_with_notify(connection,
- BGP_NOTIFY_SEND_HOLD_ERR, 0);
- } else if (delta > (intmax_t)holdtime &&
- monotime(NULL) - peer->last_sendq_warn > 5) {
- flog_warn(
- EC_BGP_SENDQ_STUCK_WARN,
- "%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?",
- peer, holdtime);
- peer->last_sendq_warn = monotime(NULL);
- }
+ /* Note that when we're here, we're adding some packet to the
+ * OutQ. That includes keepalives when there is nothing to
+ * do, so there's a guarantee we pass by here once in a while.
+ *
+ * That implies there is no need to go set up another separate
+ * timer that ticks down SendHoldTime, as we'll be here sooner
+ * or later anyway and will see the checks below failing.
+ */
+ if (!holdtime) {
+ /* no holdtime, do nothing. */
+ } else if (delta > sendholdtime) {
+ flog_err(EC_BGP_SENDQ_STUCK_PROPER,
+ "%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session",
+ peer, sendholdtime);
+ event_add_event(bm->master, bgp_event_stop_with_notify, connection, 0,
+ &connection->t_stop_with_notify);
+ } else if (delta > (intmax_t)holdtime && monotime(NULL) - peer->last_sendq_warn > 5) {
+ flog_warn(EC_BGP_SENDQ_STUCK_WARN,
+ "%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?",
+ peer, holdtime);
+ peer->last_sendq_warn = monotime(NULL);
}
}
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 17ab30f980..8b6bc2d4c5 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -1202,6 +1202,8 @@ struct peer_connection {
struct event *t_process_packet;
struct event *t_process_packet_error;
+ struct event *t_stop_with_notify;
+
union sockunion su;
#define BGP_CONNECTION_SU_UNSPEC(connection) \
(connection->su.sa.sa_family == AF_UNSPEC)
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index d2f1db67ee..561f16609f 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -947,7 +947,7 @@ static int netlink_recv_msg(struct nlsock *nl, struct msghdr *msg)
} while (status == -1 && errno == EINTR);
if (status == -1) {
- if (errno == EWOULDBLOCK || errno == EAGAIN)
+ if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EMSGSIZE)
return 0;
flog_err(EC_ZEBRA_RECVMSG_OVERRUN, "%s recvmsg overrun: %s",
nl->name, safe_strerror(errno));