]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/vrf.c
Merge pull request #4810 from qlyoung/fix-pthread-bad-pointer
[mirror_frr.git] / lib / vrf.c
index dd87ed63e810b7cf5a7107ac2330f42f2445ad4b..4c6df797ad49a87ee1678a7bd004c6e997dc5ae7 100644 (file)
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -64,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 {
@@ -199,9 +199,14 @@ struct vrf *vrf_get(vrf_id_t vrf_id, const char *name)
 
        /* Set name */
        if (name && vrf->name[0] != '\0' && strcmp(name, vrf->name)) {
+               /* update the vrf name */
                RB_REMOVE(vrf_name_head, &vrfs_by_name, vrf);
+               strlcpy(vrf->data.l.netns_name,
+                       name, NS_NAMSIZ);
                strlcpy(vrf->name, name, sizeof(vrf->name));
                RB_INSERT(vrf_name_head, &vrfs_by_name, vrf);
+               if (vrf->vrf_id == VRF_DEFAULT)
+                       vrf_set_default_name(vrf->name, false);
        } else if (name && vrf->name[0] == '\0') {
                strlcpy(vrf->name, name, sizeof(vrf->name));
                RB_INSERT(vrf_name_head, &vrfs_by_name, vrf);
@@ -362,9 +367,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;
 }
@@ -542,38 +547,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;
 
@@ -582,13 +558,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();
@@ -791,7 +760,7 @@ DEFUN_NOSH (vrf_netns,
        if (!pathname)
                return CMD_WARNING_CONFIG_FAILED;
 
-       frr_elevate_privs(vrf_daemon_privs) {
+       frr_with_privs(vrf_daemon_privs) {
                ret = vrf_netns_handler_create(vty, vrf, pathname,
                                               NS_UNKNOWN, NS_UNKNOWN);
        }
@@ -896,7 +865,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);
@@ -907,13 +875,8 @@ 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);
+       if (strmatch(vrf_default_name, default_name))
                return;
-       }
        snprintf(vrf_default_name, VRF_NAMSIZ, "%s", default_name);
        if (def_vrf) {
                if (force)
@@ -944,13 +907,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);
@@ -1003,7 +972,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;