From 81ece63e3e63fc43b496beafdd3b46c4cc52839b Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Mon, 18 Sep 2023 22:34:45 +0300 Subject: [PATCH] bgpd: Set TCP min MSS per listener Set only if at least one peer is in passive mode. Signed-off-by: Donatas Abraitis --- bgpd/bgp_network.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ bgpd/bgp_network.h | 1 + bgpd/bgpd.c | 2 ++ 3 files changed, 50 insertions(+) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 3bfdeb1771..f322de7683 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -334,6 +334,53 @@ static int bgp_get_instance_for_inc_conn(int sock, struct bgp **bgp_inst) #endif } +int bgp_tcp_mss_set(struct peer *peer) +{ + struct listnode *node; + int ret = 0; + struct bgp_listener *listener; + uint32_t min_mss = 0; + struct peer *p; + + for (ALL_LIST_ELEMENTS_RO(peer->bgp->peer, node, p)) { + if (!CHECK_FLAG(p->flags, PEER_FLAG_TCP_MSS)) + continue; + + if (!p->tcp_mss) + continue; + + if (!min_mss) + min_mss = p->tcp_mss; + + min_mss = MIN(min_mss, p->tcp_mss); + } + + frr_with_privs(&bgpd_privs) { + for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener)) { + if (listener->su.sa.sa_family != + peer->connection->su.sa.sa_family) + continue; + + if (!listener->bgp) { + if (peer->bgp->vrf_id != VRF_DEFAULT) + continue; + } else if (listener->bgp != peer->bgp) + continue; + + /* Set TCP MSS per listener only if there is at least + * one peer that is in passive mode. Otherwise, TCP MSS + * is set per socket via bgp_connect(). + */ + if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)) + sockopt_tcp_mss_set(listener->fd, min_mss); + + break; + } + } + + return ret; +} + static void bgp_socket_set_buffer_size(const int fd) { if (getsockopt_so_sendbuf(fd) < (int)bm->socket_buffer) diff --git a/bgpd/bgp_network.h b/bgpd/bgp_network.h index f26d64f1f8..7a0b3cc67d 100644 --- a/bgpd/bgp_network.h +++ b/bgpd/bgp_network.h @@ -30,6 +30,7 @@ extern int bgp_md5_unset_prefix(struct bgp *bgp, struct prefix *p); extern int bgp_md5_set(struct peer_connection *connection); extern int bgp_md5_unset(struct peer_connection *connection); extern int bgp_set_socket_ttl(struct peer_connection *connection); +extern int bgp_tcp_mss_set(struct peer *peer); extern int bgp_update_address(struct interface *ifp, const union sockunion *dst, union sockunion *addr); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 895f36f992..585863954c 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -5779,6 +5779,7 @@ void peer_tcp_mss_set(struct peer *peer, uint32_t tcp_mss) { peer->tcp_mss = tcp_mss; SET_FLAG(peer->flags, PEER_FLAG_TCP_MSS); + bgp_tcp_mss_set(peer); } /* Reset the TCP-MSS value in the peer structure, @@ -5789,6 +5790,7 @@ void peer_tcp_mss_unset(struct peer *peer) { UNSET_FLAG(peer->flags, PEER_FLAG_TCP_MSS); peer->tcp_mss = 0; + bgp_tcp_mss_set(peer); } /*