Skip to content

Commit 82b3fae

Browse files
committed
bgpd: add neighbor ip-transparent
Implement a per‑neighbor flag that sets IP_TRANSPARENT for the underlying TCP socket. With this flag bgpd can accept or initiate a session to/from an address that is not present on the host. Typical use‑cases: - running bgpd inside a container without configuring the router loopback address inside that netns. - hitless switchover of a keepalived/VRRP VIP: the standby bgpd can pre‑bind and come up instantly after takeover. - BGP speakers when the IP address is not set (transparent firewall). - others... It is safeguarded by a CAP_NET_ADMIN. Signed-off-by: Vincent Jardin <[email protected]>
1 parent bb7289c commit 82b3fae

File tree

5 files changed

+51
-0
lines changed

5 files changed

+51
-0
lines changed

bgpd/bgp_network.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,14 @@ enum connect_result bgp_connect(struct peer_connection *connection)
829829
if (CHECK_FLAG(peer->flags, PEER_FLAG_TCP_MSS))
830830
sockopt_tcp_mss_set(connection->fd, peer->tcp_mss);
831831

832+
/* Neighbor's bind() as a source address when ip transparent is used */
833+
if (CHECK_FLAG(peer->flags, PEER_FLAG_IP_TRANSPARENT) &&
834+
CHECK_FLAG(peer->flags, PEER_FLAG_UPDATE_SOURCE)) {
835+
frr_with_privs (&bgpd_privs) {
836+
sockopt_ip_transparent(connection->fd);
837+
}
838+
}
839+
832840
bgp_socket_set_buffer_size(connection->fd);
833841

834842
/* Set TCP keepalive when TCP keepalive is enabled */

bgpd/bgp_vty.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18427,6 +18427,34 @@ DEFUN(no_neighbor_tcp_mss, no_neighbor_tcp_mss_cmd,
1842718427
return peer_tcp_mss_vty(vty, argv[peer_index]->arg, NULL);
1842818428
}
1842918429

18430+
DEFPY(neighbor_ip_transparent,
18431+
neighbor_ip_transparent_cmd,
18432+
"[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor ip-transparent",
18433+
NO_STR
18434+
NEIGHBOR_STR
18435+
NEIGHBOR_ADDR_STR2
18436+
"Enable IP_TRANSPARENT on the BGP TCP socket\n")
18437+
{
18438+
struct peer *peer;
18439+
int ret;
18440+
18441+
peer = peer_and_group_lookup_vty(vty, neighbor);
18442+
if (!peer)
18443+
return CMD_WARNING_CONFIG_FAILED;
18444+
18445+
if (!peergroup_flag_check(peer, PEER_FLAG_UPDATE_SOURCE)) {
18446+
vty_out(vty, "%% Missing update-source\n");
18447+
return CMD_WARNING_CONFIG_FAILED;
18448+
}
18449+
18450+
if (no)
18451+
ret = peer_flag_unset_vty(vty, neighbor, PEER_FLAG_IP_TRANSPARENT);
18452+
else
18453+
ret = peer_flag_set_vty(vty, neighbor, PEER_FLAG_IP_TRANSPARENT);
18454+
18455+
return bgp_vty_return(vty, ret);
18456+
}
18457+
1843018458
DEFPY(bgp_retain_route_target, bgp_retain_route_target_cmd,
1843118459
"[no$no] bgp retain route-target all",
1843218460
NO_STR BGP_STR
@@ -19027,6 +19055,10 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
1902719055
peer->update_if);
1902819056
}
1902919057

19058+
/* ip-transparent on/off */
19059+
if (peergroup_flag_check(peer, PEER_FLAG_IP_TRANSPARENT))
19060+
vty_out(vty, " neighbor %s ip-transparent\n", addr);
19061+
1903019062
/* advertisement-interval */
1903119063
if (peergroup_flag_check(peer, PEER_FLAG_ROUTEADV))
1903219064
vty_out(vty, " neighbor %s advertisement-interval %u\n", addr,
@@ -22220,6 +22252,8 @@ void bgp_vty_init(void)
2222022252
install_element(BGP_NODE, &neighbor_tcp_mss_cmd);
2222122253
install_element(BGP_NODE, &no_neighbor_tcp_mss_cmd);
2222222254

22255+
install_element(BGP_NODE, &neighbor_ip_transparent_cmd);
22256+
2222322257
/* srv6 commands */
2222422258
install_element(VIEW_NODE, &show_bgp_srv6_cmd);
2222522259
install_element(BGP_NODE, &bgp_segment_routing_srv6_cmd);

bgpd/bgpd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4979,6 +4979,7 @@ static const struct peer_flag_action peer_flag_action_list[] = {
49794979
{PEER_FLAG_CAPABILITY_LINK_LOCAL, 0, peer_change_none},
49804980
{PEER_FLAG_BFD_STRICT, 0, peer_change_none},
49814981
{PEER_FLAG_SEND_NHC_ATTRIBUTE, 0, peer_change_none},
4982+
{PEER_FLAG_IP_TRANSPARENT, 0, peer_change_reset},
49824983
{0, 0, 0}};
49834984

49844985
static const struct peer_flag_action peer_af_flag_action_list[] = {

bgpd/bgpd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,7 @@ struct peer {
17031703
#define PEER_FLAG_BFD_STRICT (1ULL << 43)
17041704
/* https://datatracker.ietf.org/doc/html/draft-ietf-idr-entropy-label */
17051705
#define PEER_FLAG_SEND_NHC_ATTRIBUTE (1ULL << 44)
1706+
#define PEER_FLAG_IP_TRANSPARENT (1ULL << 45) /* ip-transparent */
17061707

17071708
/*
17081709
*GR-Disabled mode means unset PEER_FLAG_GRACEFUL_RESTART

doc/user/bgp.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,13 @@ Configuring Peers
17661766
neighbor foo update-source 192.168.0.1
17671767
neighbor bar update-source lo0
17681768
1769+
.. clicmd:: neighbor PEER ip-transparent
1770+
1771+
Use this command when you need to establish a BGP session with a
1772+
neighbor using an IP address that you do *not* own. Some typical use
1773+
cases include running BGP in a container without configuring the
1774+
address on a loopback interface, peering over a virtual (floating)
1775+
IP (VIP), or operating as a transparent IP firewall.
17691776

17701777
.. clicmd:: neighbor PEER default-originate [route-map WORD]
17711778

0 commit comments

Comments
 (0)