]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/vrf.c
isisd: implemented the 'sequence-number-skipped' notification
[mirror_frr.git] / lib / vrf.c
index 8778d93f0593828314c26c0c3422f93528ec026a..8409a1c9a13ed5e9bb4febd561d3c0e637ef8cd2 100644 (file)
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -39,7 +39,7 @@
 
 /* default VRF ID value used when VRF backend is not NETNS */
 #define VRF_DEFAULT_INTERNAL 0
-#define VRF_DEFAULT_NAME_INTERNAL "Default-IP-Routing-Table"
+#define VRF_DEFAULT_NAME_INTERNAL "default"
 
 DEFINE_MTYPE_STATIC(LIB, VRF, "VRF")
 DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
@@ -71,6 +71,7 @@ struct vrf_master {
        int (*vrf_delete_hook)(struct vrf *);
        int (*vrf_enable_hook)(struct vrf *);
        int (*vrf_disable_hook)(struct vrf *);
+       int (*vrf_update_name_hook)(struct vrf *vrf);
 } vrf_master = {
        0,
 };
@@ -167,6 +168,13 @@ struct vrf *vrf_get(vrf_id_t vrf_id, const char *name)
         */
        if (name)
                vrf = vrf_lookup_by_name(name);
+       if (vrf && vrf_id != VRF_UNKNOWN
+           && vrf->vrf_id != VRF_UNKNOWN
+           && vrf->vrf_id != vrf_id) {
+               zlog_debug("VRF_GET: avoid %s creation(%u), same name exists (%u)",
+                          name, vrf_id, vrf->vrf_id);
+               return NULL;
+       }
        /* Try to find VRF both by ID and name */
        if (!vrf && vrf_id != VRF_UNKNOWN)
                vrf = vrf_lookup_by_id(vrf_id);
@@ -358,7 +366,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;
@@ -447,10 +455,8 @@ static void vrf_autocomplete(vector comps, struct cmd_token *token)
 {
        struct vrf *vrf = NULL;
 
-       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
-               if (vrf->vrf_id != VRF_DEFAULT)
-                       vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
-       }
+       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
+               vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
 }
 
 static const struct cmd_variable_handler vrf_var_handlers[] = {
@@ -463,7 +469,8 @@ static const struct cmd_variable_handler vrf_var_handlers[] = {
 
 /* Initialize VRF module. */
 void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
-             int (*disable)(struct vrf *), int (*delete)(struct vrf *))
+             int (*disable)(struct vrf *), int (*delete)(struct vrf *),
+             int ((*update)(struct vrf *)))
 {
        struct vrf *default_vrf;
 
@@ -477,19 +484,29 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
        vrf_master.vrf_enable_hook = enable;
        vrf_master.vrf_disable_hook = disable;
        vrf_master.vrf_delete_hook = delete;
+       vrf_master.vrf_update_name_hook = update;
 
        /* 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()) {
+               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);
        }
 
@@ -559,7 +576,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)) {
@@ -573,7 +590,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;
@@ -613,7 +630,8 @@ int vrf_handler_create(struct vty *vty, const char *vrfname,
                                "%% VRF name %s invalid: length exceeds %d bytes\n",
                                vrfname, VRF_NAMSIZ);
                else
-                       zlog_warn(
+                       flog_warn(
+                               EC_LIB_VRF_LENGTH,
                                "%% VRF name %s invalid: length exceeds %d bytes\n",
                                vrfname, VRF_NAMSIZ);
                return CMD_WARNING_CONFIG_FAILED;
@@ -642,7 +660,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname,
                                "VRF %u is already configured with VRF %s\n",
                                vrf->vrf_id, vrf->name);
                else
-                       zlog_warn("VRF %u is already configured with VRF %s\n",
+                       zlog_info("VRF %u is already configured with VRF %s\n",
                                  vrf->vrf_id, vrf->name);
                return CMD_WARNING_CONFIG_FAILED;
        }
@@ -654,7 +672,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname,
                                        "VRF %u already configured with NETNS %s\n",
                                        vrf->vrf_id, ns->name);
                        else
-                               zlog_warn(
+                               zlog_info(
                                        "VRF %u already configured with NETNS %s",
                                        vrf->vrf_id, ns->name);
                        return CMD_WARNING_CONFIG_FAILED;
@@ -672,7 +690,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname,
                                " with VRF %u(%s)\n",
                                ns->name, vrf2->vrf_id, vrf2->name);
                else
-                       zlog_warn("NS %s is already configured with VRF %u(%s)",
+                       zlog_info("NS %s is already configured with VRF %u(%s)",
                                  ns->name, vrf2->vrf_id, vrf2->name);
                return CMD_WARNING_CONFIG_FAILED;
        }
@@ -688,7 +706,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname,
                        vty_out(vty, "Can not associate NS %u with NETNS %s\n",
                                ns->ns_id, ns->name);
                else
-                       zlog_warn("Can not associate NS %u with NETNS %s",
+                       zlog_info("Can not associate NS %u with NETNS %s",
                                  ns->ns_id, ns->name);
                return CMD_WARNING_CONFIG_FAILED;
        }
@@ -700,8 +718,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;
 }
 
@@ -878,13 +894,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)",
@@ -894,11 +917,15 @@ 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);
                strlcpy(def_vrf->name, vrf_default_name, sizeof(def_vrf->name));
                RB_INSERT(vrf_name_head, &vrfs_by_name, def_vrf);
+               if (vrf_master.vrf_update_name_hook)
+                       (*vrf_master.vrf_update_name_hook)(def_vrf);
        }
 }
 
@@ -942,13 +969,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;
@@ -961,7 +988,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;
        }
@@ -969,7 +996,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;
@@ -983,13 +1010,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;
@@ -1003,3 +1030,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;
+}