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:
Donald Sharp 2019-02-01 11:54:59 -05:00
parent 41e8603bfa
commit 0556fc33c7

View file

@ -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();