forked from Mirror/frr
lib: Allow bgp to always create a listen socket for the vrf
If tcp_l3mdev_accept = 0, then creating a socket for a vrf for communication is allowed. On the other hand if it is =1 then the vrf_socket() code assumes that we have created a listen socket in the default vrf. This is a bad assumption in that it is perfectly valid to create a bgp instance like this: router bgp 99 vrf BLUE <configuration> ! But not to create a default bgp instance. As such when BGP would call the vrf_socket to create the listener for that vrf the code was dissallowing it. This code is incorrect behavior. If we are passing in a interface to bind the socket to, it is not the correct behavior to just not bind, especially if the interface passed in is not a vrf name. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
41e8603bfa
commit
0556fc33c7
36
lib/vrf.c
36
lib/vrf.c
|
@ -541,35 +541,6 @@ void vrf_terminate(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vrf_default_accepts_vrf(int type)
|
|
||||||
{
|
|
||||||
const char *fname = NULL;
|
|
||||||
char buf[32] = {0x0};
|
|
||||||
int ret = 0;
|
|
||||||
FILE *fd = NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TCP & UDP services running in the default VRF context (ie., not bound
|
|
||||||
* to any VRF device) can work across all VRF domains by enabling the
|
|
||||||
* tcp_l3mdev_accept and udp_l3mdev_accept sysctl options:
|
|
||||||
* sysctl -w net.ipv4.tcp_l3mdev_accept=1
|
|
||||||
* sysctl -w net.ipv4.udp_l3mdev_accept=1
|
|
||||||
*/
|
|
||||||
if (type == SOCK_STREAM)
|
|
||||||
fname = "/proc/sys/net/ipv4/tcp_l3mdev_accept";
|
|
||||||
else if (type == SOCK_DGRAM)
|
|
||||||
fname = "/proc/sys/net/ipv4/udp_l3mdev_accept";
|
|
||||||
else
|
|
||||||
return ret;
|
|
||||||
fd = fopen(fname, "r");
|
|
||||||
if (fd == NULL)
|
|
||||||
return ret;
|
|
||||||
fgets(buf, 32, fd);
|
|
||||||
ret = atoi(buf);
|
|
||||||
fclose(fd);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create a socket for the VRF. */
|
/* Create a socket for the VRF. */
|
||||||
int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
|
int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
|
||||||
char *interfacename)
|
char *interfacename)
|
||||||
|
@ -581,13 +552,6 @@ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
|
||||||
flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
|
flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
|
||||||
__func__, vrf_id, safe_strerror(errno));
|
__func__, vrf_id, safe_strerror(errno));
|
||||||
|
|
||||||
if (ret > 0 && interfacename && vrf_default_accepts_vrf(type)) {
|
|
||||||
zlog_err("VRF socket not used since net.ipv4.%s_l3mdev_accept != 0",
|
|
||||||
(type == SOCK_STREAM ? "tcp" : "udp"));
|
|
||||||
errno = EEXIST; /* not sure if this is the best error... */
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = socket(domain, type, protocol);
|
ret = socket(domain, type, protocol);
|
||||||
save_errno = errno;
|
save_errno = errno;
|
||||||
ret2 = vrf_switchback_to_initial();
|
ret2 = vrf_switchback_to_initial();
|
||||||
|
|
Loading…
Reference in a new issue