]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/vrf.c
Merge pull request #4847 from vivek-cumulus/evpn-route-import-fix
[mirror_frr.git] / lib / vrf.c
index ab47f242fd0468afa7457908bcab9c7cb3a236c2..229f19f29ae877a2f2b02ae7c9b65c27e36ae634 100644 (file)
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -56,6 +56,7 @@ struct vrf_id_head vrfs_by_id = RB_INITIALIZER(&vrfs_by_id);
 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;
 
@@ -63,7 +64,7 @@ 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 {
@@ -361,9 +362,9 @@ struct vrf_bit_set {
        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;
 }
@@ -541,38 +542,9 @@ 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. */
 int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
-              char *interfacename)
+              const char *interfacename)
 {
        int ret, save_errno, ret2;
 
@@ -581,13 +553,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)",
                             __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();
@@ -613,12 +578,15 @@ int vrf_is_backend_netns(void)
 
 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,
@@ -892,7 +860,6 @@ void vrf_cmd_init(int (*writefunc)(struct vty *vty),
 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);
@@ -903,13 +870,7 @@ void vrf_set_default_name(const char *default_name, bool force)
                           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)
@@ -940,13 +901,19 @@ vrf_id_t vrf_get_default_id(void)
                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);
@@ -999,7 +966,7 @@ int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
 }
 
 int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
-                        char *interfacename)
+                        const char *interfacename)
 {
        int ret, save_errno, ret2;