]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/vrf.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / lib / vrf.c
index 1e538a8c53a784580eb55dd643ecfd71528457c6..0c82f6a3cd451a4dda81f4605f62ef544ef47d7a 100644 (file)
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -330,6 +330,8 @@ vrf_id_t vrf_name_to_id(const char *name)
        vrf_id_t vrf_id = VRF_DEFAULT; // Pending: need a way to return invalid
                                       // id/ routine not used.
 
+       if (!name)
+               return vrf_id;
        vrf = vrf_lookup_by_name(name);
        if (vrf)
                vrf_id = vrf->vrf_id;
@@ -366,7 +368,7 @@ static unsigned int vrf_hash_bitmap_key(void *data)
        return bit->vrf_id;
 }
 
-static int vrf_hash_bitmap_cmp(const void *a, const void *b)
+static bool vrf_hash_bitmap_cmp(const void *a, const void *b)
 {
        const struct vrf_bit_set *bit1 = a;
        const struct vrf_bit_set *bit2 = b;
@@ -489,18 +491,24 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
        /* The default VRF always exists. */
        default_vrf = vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME);
        if (!default_vrf) {
-               flog_err(LIB_ERR_VRF_START,
-                         "vrf_init: failed to create the default VRF!");
+               flog_err(EC_LIB_VRF_START,
+                        "vrf_init: failed to create the default VRF!");
                exit(1);
        }
-       if (vrf_is_backend_netns())
+       if (vrf_is_backend_netns()) {
+               struct ns *ns;
+
                strlcpy(default_vrf->data.l.netns_name,
                        VRF_DEFAULT_NAME, NS_NAMSIZ);
+               ns = ns_lookup(ns_get_default_id());
+               ns->vrf_ctxt = default_vrf;
+               default_vrf->ns_ctxt = ns;
+       }
 
        /* Enable the default VRF. */
        if (!vrf_enable(default_vrf)) {
-               flog_err(LIB_ERR_VRF_START,
-                         "vrf_init: failed to enable the default VRF!");
+               flog_err(EC_LIB_VRF_START,
+                        "vrf_init: failed to enable the default VRF!");
                exit(1);
        }
 
@@ -570,7 +578,7 @@ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
 
        ret = vrf_switch_to_netns(vrf_id);
        if (ret < 0)
-               flog_err_sys(LIB_ERR_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));
 
        if (ret > 0 && interfacename && vrf_default_accepts_vrf(type)) {
@@ -584,7 +592,7 @@ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
        save_errno = errno;
        ret2 = vrf_switchback_to_initial();
        if (ret2 < 0)
-               flog_err_sys(LIB_ERR_SOCKET,
+               flog_err_sys(EC_LIB_SOCKET,
                             "%s: Can't switchback from VRF %u (%s)", __func__,
                             vrf_id, safe_strerror(errno));
        errno = save_errno;
@@ -625,7 +633,7 @@ int vrf_handler_create(struct vty *vty, const char *vrfname,
                                vrfname, VRF_NAMSIZ);
                else
                        flog_warn(
-                               LIB_WARN_VRF_LENGTH,
+                               EC_LIB_VRF_LENGTH,
                                "%% VRF name %s invalid: length exceeds %d bytes\n",
                                vrfname, VRF_NAMSIZ);
                return CMD_WARNING_CONFIG_FAILED;
@@ -712,8 +720,6 @@ int vrf_is_mapped_on_netns(struct vrf *vrf)
 {
        if (!vrf || vrf->data.l.netns_name[0] == '\0')
                return 0;
-       if (vrf->vrf_id == VRF_DEFAULT)
-               return 0;
        return 1;
 }
 
@@ -890,14 +896,20 @@ void vrf_cmd_init(int (*writefunc)(struct vty *vty),
        }
 }
 
-void vrf_set_default_name(const char *default_name)
+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);
        assert(default_name);
-       vrf_with_default_name = vrf_lookup_by_name(default_name);
+       if (def_vrf && !force && def_vrf_forced) {
+               zlog_debug("VRF: %s, avoid changing name to %s, previously forced (%u)",
+                          def_vrf->name, default_name,
+                          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)",
@@ -907,6 +919,8 @@ void vrf_set_default_name(const char *default_name)
        }
        snprintf(vrf_default_name, VRF_NAMSIZ, "%s", default_name);
        if (def_vrf) {
+               if (force)
+                       def_vrf_forced = true;
                RB_REMOVE(vrf_name_head, &vrfs_by_name, def_vrf);
                strlcpy(def_vrf->data.l.netns_name,
                        vrf_default_name, NS_NAMSIZ);
@@ -957,13 +971,13 @@ int vrf_getaddrinfo(const char *node, const char *service,
 
        ret = vrf_switch_to_netns(vrf_id);
        if (ret < 0)
-               flog_err_sys(LIB_ERR_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));
        ret = getaddrinfo(node, service, hints, res);
        save_errno = errno;
        ret2 = vrf_switchback_to_initial();
        if (ret2 < 0)
-               flog_err_sys(LIB_ERR_SOCKET,
+               flog_err_sys(EC_LIB_SOCKET,
                             "%s: Can't switchback from VRF %u (%s)", __func__,
                             vrf_id, safe_strerror(errno));
        errno = save_errno;
@@ -976,7 +990,7 @@ int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
 
        ret = vrf_switch_to_netns(vrf_id);
        if (ret < 0) {
-               flog_err_sys(LIB_ERR_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));
                return 0;
        }
@@ -984,7 +998,7 @@ int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
        saved_errno = errno;
        ret = vrf_switchback_to_initial();
        if (ret < 0)
-               flog_err_sys(LIB_ERR_SOCKET,
+               flog_err_sys(EC_LIB_SOCKET,
                             "%s: Can't switchback from VRF %u (%s)", __func__,
                             vrf_id, safe_strerror(errno));
        errno = saved_errno;
@@ -998,13 +1012,13 @@ int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
 
        ret = vrf_switch_to_netns(vrf_id);
        if (ret < 0)
-               flog_err_sys(LIB_ERR_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));
        ret = sockunion_socket(su);
        save_errno = errno;
        ret2 = vrf_switchback_to_initial();
        if (ret2 < 0)
-               flog_err_sys(LIB_ERR_SOCKET,
+               flog_err_sys(EC_LIB_SOCKET,
                             "%s: Can't switchback from VRF %u (%s)", __func__,
                             vrf_id, safe_strerror(errno));
        errno = save_errno;
@@ -1018,3 +1032,10 @@ int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
        }
        return ret;
 }
+
+vrf_id_t vrf_generate_id(void)
+{
+       static int vrf_id_local;
+
+       return ++vrf_id_local;
+}