struct vrf_name_head vrfs_by_name = RB_INITIALIZER(&vrfs_by_name);
static int vrf_backend;
+static int vrf_backend_configured;
static struct zebra_privs_t *vrf_daemon_privs;
static char vrf_default_name[VRF_NAMSIZ] = VRF_DEFAULT_NAME_INTERNAL;
* Turn on/off debug code
* for vrf.
*/
-int debug_vrf = 0;
+static int debug_vrf = 0;
/* Holding VRF hooks */
struct vrf_master {
bool set;
};
-static unsigned int vrf_hash_bitmap_key(void *data)
+static unsigned int vrf_hash_bitmap_key(const void *data)
{
- struct vrf_bit_set *bit = data;
+ const struct vrf_bit_set *bit = data;
return bit->vrf_id;
}
}
}
-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. */
int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
- char *interfacename)
+ const char *interfacename)
{
int ret, save_errno, ret2;
flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
__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);
save_errno = errno;
ret2 = vrf_switchback_to_initial();
int vrf_get_backend(void)
{
+ if (!vrf_backend_configured)
+ return VRF_BACKEND_UNKNOWN;
return vrf_backend;
}
void vrf_configure_backend(int vrf_backend_netns)
{
vrf_backend = vrf_backend_netns;
+ vrf_backend_configured = 1;
}
int vrf_handler_create(struct vty *vty, const char *vrfname,
void vrf_set_default_name(const char *default_name, bool force)
{
struct vrf *def_vrf;
- struct vrf *vrf_with_default_name = NULL;
static bool def_vrf_forced;
def_vrf = vrf_lookup_by_id(VRF_DEFAULT);
def_vrf->vrf_id);
return;
}
- if (vrf_with_default_name && vrf_with_default_name != def_vrf) {
- /* vrf name already used by an other VRF */
- zlog_debug("VRF: %s, avoid changing name to %s, same name exists (%u)",
- vrf_with_default_name->name, default_name,
- vrf_with_default_name->vrf_id);
- return;
- }
+
snprintf(vrf_default_name, VRF_NAMSIZ, "%s", default_name);
if (def_vrf) {
if (force)
return VRF_DEFAULT_INTERNAL;
}
-int vrf_bind(vrf_id_t vrf_id, int fd, char *name)
+int vrf_bind(vrf_id_t vrf_id, int fd, const char *name)
{
int ret = 0;
+ struct interface *ifp;
if (fd < 0 || name == NULL)
return fd;
- if (vrf_is_backend_netns())
+ /* the device should exist
+ * otherwise we should return
+ * case ifname = vrf in netns mode => return
+ */
+ ifp = if_lookup_by_name(name, vrf_id);
+ if (!ifp)
return fd;
#ifdef SO_BINDTODEVICE
ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name)+1);
}
int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
- char *interfacename)
+ const char *interfacename)
{
int ret, save_errno, ret2;