Skip to content

Commit 8f05c96

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 331ea2a commit 8f05c96

File tree

5 files changed

+48
-0
lines changed

5 files changed

+48
-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: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18356,6 +18356,31 @@ 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+
int ret;
18369+
18370+
peer = peer_and_group_lookup_vty(vty, neighbor);
18371+
if (!peer)
18372+
return CMD_WARNING_CONFIG_FAILED;
18373+
18374+
if (!peergroup_flag_check(peer, PEER_FLAG_UPDATE_SOURCE)) {
18375+
vty_out(vty, "%% Missing update-source\n");
18376+
return CMD_WARNING_CONFIG_FAILED;
18377+
}
18378+
18379+
ret = peer_flag_modify_vty(vty, neighbor, PEER_FLAG_IP_TRANSPARENT, no == NULL);
18380+
18381+
return bgp_vty_return(vty, ret);
18382+
}
18383+
1835918384
DEFPY(bgp_retain_route_target, bgp_retain_route_target_cmd,
1836018385
"[no$no] bgp retain route-target all",
1836118386
NO_STR BGP_STR
@@ -18945,6 +18970,10 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
1894518970
peer->update_if);
1894618971
}
1894718972

18973+
/* ip-transparent on/off */
18974+
if (peergroup_flag_check(peer, PEER_FLAG_IP_TRANSPARENT))
18975+
vty_out(vty, " neighbor %s ip-transparent\n", addr);
18976+
1894818977
/* advertisement-interval */
1894918978
if (peergroup_flag_check(peer, PEER_FLAG_ROUTEADV))
1895018979
vty_out(vty, " neighbor %s advertisement-interval %u\n", addr,
@@ -22134,6 +22163,8 @@ void bgp_vty_init(void)
2213422163
install_element(BGP_NODE, &neighbor_tcp_mss_cmd);
2213522164
install_element(BGP_NODE, &no_neighbor_tcp_mss_cmd);
2213622165

22166+
install_element(BGP_NODE, &neighbor_ip_transparent_cmd);
22167+
2213722168
/* srv6 commands */
2213822169
install_element(VIEW_NODE, &show_bgp_srv6_cmd);
2213922170
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
@@ -4954,6 +4954,7 @@ static const struct peer_flag_action peer_flag_action_list[] = {
49544954
{PEER_FLAG_TCP_MSS, 0, peer_change_none},
49554955
{PEER_FLAG_CAPABILITY_LINK_LOCAL, 0, peer_change_none},
49564956
{PEER_FLAG_BFD_STRICT, 0, peer_change_none},
4957+
{PEER_FLAG_IP_TRANSPARENT, 0, peer_change_reset},
49574958
{0, 0, 0}};
49584959

49594960
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
@@ -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)