Skip to content

Commit a5a96aa

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 2bf0dc8 commit a5a96aa

File tree

4 files changed

+53
-0
lines changed

4 files changed

+53
-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: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18356,6 +18356,37 @@ DEFUN(no_neighbor_tcp_mss, no_neighbor_tcp_mss_cmd,
1835618356
return peer_tcp_mss_vty(vty, argv[peer_index]->arg, NULL);
1835718357
}
1835818358

18359+
DEFPY(neighbor_ip_transparent,
18360+
neighbor_ip_transparent_cmd,
18361+
"[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor ip-transparent",
18362+
NO_STR
18363+
NEIGHBOR_STR
18364+
NEIGHBOR_ADDR_STR2
18365+
"Enable IP_TRANSPARENT on the BGP TCP socket\n")
18366+
{
18367+
struct peer *peer;
18368+
bool oldflag;
18369+
int ret;
18370+
18371+
peer = peer_and_group_lookup_vty(vty, neighbor);
18372+
if (!peer)
18373+
return CMD_WARNING_CONFIG_FAILED;
18374+
18375+
if (!peergroup_flag_check(peer, PEER_FLAG_UPDATE_SOURCE)) {
18376+
vty_out(vty, "%% Missing update-source\n");
18377+
return CMD_WARNING_CONFIG_FAILED;
18378+
}
18379+
18380+
oldflag = peergroup_flag_check(peer, PEER_FLAG_IP_TRANSPARENT);
18381+
ret = peer_flag_modify_vty(vty, neighbor, PEER_FLAG_IP_TRANSPARENT, no == NULL);
18382+
18383+
/* do nothing if no change */
18384+
if (oldflag != peergroup_flag_check(peer, PEER_FLAG_IP_TRANSPARENT))
18385+
bgp_session_reset(peer);
18386+
18387+
return bgp_vty_return(vty, ret);
18388+
}
18389+
1835918390
DEFPY(bgp_retain_route_target, bgp_retain_route_target_cmd,
1836018391
"[no$no] bgp retain route-target all",
1836118392
NO_STR BGP_STR
@@ -18945,6 +18976,10 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
1894518976
peer->update_if);
1894618977
}
1894718978

18979+
/* ip-transparent on/off */
18980+
if (peergroup_flag_check(peer, PEER_FLAG_IP_TRANSPARENT))
18981+
vty_out(vty, " neighbor %s ip-transparent\n", addr);
18982+
1894818983
/* advertisement-interval */
1894918984
if (peergroup_flag_check(peer, PEER_FLAG_ROUTEADV))
1895018985
vty_out(vty, " neighbor %s advertisement-interval %u\n", addr,
@@ -22134,6 +22169,8 @@ void bgp_vty_init(void)
2213422169
install_element(BGP_NODE, &neighbor_tcp_mss_cmd);
2213522170
install_element(BGP_NODE, &no_neighbor_tcp_mss_cmd);
2213622171

22172+
install_element(BGP_NODE, &neighbor_ip_transparent_cmd);
22173+
2213722174
/* srv6 commands */
2213822175
install_element(VIEW_NODE, &show_bgp_srv6_cmd);
2213922176
install_element(BGP_NODE, &bgp_segment_routing_srv6_cmd);

bgpd/bgpd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,6 +1770,7 @@ struct peer {
17701770
#define PEER_FLAG_SEND_EXT_COMMUNITY_RPKI (1ULL << 29)
17711771
#define PEER_FLAG_ADDPATH_RX_PATHS_LIMIT (1ULL << 30)
17721772
#define PEER_FLAG_CONFIG_DAMPENING (1U << 31)
1773+
#define PEER_FLAG_IP_TRANSPARENT (1ULL << 32)
17731774
#define PEER_FLAG_ACCEPT_OWN (1ULL << 63)
17741775

17751776
enum bgp_addpath_strat addpath_type[AFI_MAX][SAFI_MAX];

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)