]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_vrf.c
zebra: delay default vrf name after vrf initialization
[mirror_frr.git] / zebra / zebra_vrf.c
index 76dc5657d41cd3ba2092fab2292ddf5b1a80b8ce..38b8b43d73f45dfb0db3f01afc55994cd409cd76 100644 (file)
 #include "vrf.h"
 #include "vty.h"
 
+#include "zebra/zebra_router.h"
 #include "zebra/debug.h"
-#include "zebra/zserv.h"
+#include "zebra/zapi_msg.h"
 #include "zebra/rib.h"
 #include "zebra/zebra_vrf.h"
 #include "zebra/zebra_rnh.h"
 #include "zebra/router-id.h"
 #include "zebra/zebra_memory.h"
-#include "zebra/zebra_static.h"
 #include "zebra/interface.h"
 #include "zebra/zebra_mpls.h"
 #include "zebra/zebra_vxlan.h"
 #include "zebra/zebra_netns_notify.h"
+#include "zebra/zebra_routemap.h"
 
 extern struct zebra_t zebrad;
 
@@ -134,14 +135,6 @@ static int zebra_vrf_enable(struct vrf *vrf)
                zvrf->import_check_table[afi] = table;
        }
 
-       static_fixup_vrf_ids(zvrf);
-
-       /*
-        * We may have static routes that are now possible to
-        * insert into the appropriate tables
-        */
-       static_config_install_delayed_routes(zvrf);
-
        /* Kick off any VxLAN-EVPN processing. */
        zebra_vxlan_vrf_enable(zvrf);
 
@@ -152,7 +145,6 @@ static int zebra_vrf_enable(struct vrf *vrf)
 static int zebra_vrf_disable(struct vrf *vrf)
 {
        struct zebra_vrf *zvrf = vrf->info;
-       struct route_table *table;
        struct interface *ifp;
        afi_t afi;
        safi_t safi;
@@ -163,8 +155,6 @@ static int zebra_vrf_disable(struct vrf *vrf)
                zlog_debug("VRF %s id %u is now inactive", zvrf_name(zvrf),
                           zvrf_id(zvrf));
 
-       static_cleanup_vrf_ids(zvrf);
-
        /* Stop any VxLAN-EVPN processing. */
        zebra_vxlan_vrf_disable(zvrf);
 
@@ -212,15 +202,16 @@ static int zebra_vrf_disable(struct vrf *vrf)
 
        /* Cleanup (free) routing tables and NHT tables. */
        for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
-               void *table_info;
-
-               for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
-                       table = zvrf->table[afi][safi];
-                       table_info = table->info;
-                       route_table_finish(table);
-                       XFREE(MTYPE_RIB_TABLE_INFO, table_info);
+               /*
+                * Set the table pointer to NULL as that
+                * we no-longer need a copy of it, nor do we
+                * own this data, the zebra_router structure
+                * owns these tables.  Once we've cleaned up the
+                * table, see rib_close_table above
+                * we no-longer need this pointer.
+                */
+               for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
                        zvrf->table[afi][safi] = NULL;
-               }
 
                route_table_finish(zvrf->rnh_table[afi]);
                zvrf->rnh_table[afi] = NULL;
@@ -272,13 +263,10 @@ static int zebra_vrf_delete(struct vrf *vrf)
                for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
                        table = zvrf->table[afi][safi];
                        if (table) {
-                               table_info = table->info;
+                               table_info = route_table_get_info(table);
                                route_table_finish(table);
                                XFREE(MTYPE_RIB_TABLE_INFO, table_info);
                        }
-
-                       table = zvrf->stable[afi][safi];
-                       route_table_finish(table);
                }
 
                route_table_finish(zvrf->rnh_table[afi]);
@@ -296,30 +284,25 @@ static int zebra_vrf_delete(struct vrf *vrf)
        return 0;
 }
 
+static int zebra_vrf_update(struct vrf *vrf)
+{
+       struct zebra_vrf *zvrf = vrf->info;
+
+       assert(zvrf);
+       if (IS_ZEBRA_DEBUG_EVENT)
+               zlog_debug("VRF %s id %u, name updated", vrf->name,
+                          zvrf_id(zvrf));
+       zebra_vrf_add_update(zvrf);
+       return 0;
+}
+
+
 /* Return if this VRF has any FRR configuration or not.
  * IMPORTANT: This function needs to be updated when additional configuration
  * is added for a VRF.
  */
 int zebra_vrf_has_config(struct zebra_vrf *zvrf)
 {
-       afi_t afi;
-       safi_t safi;
-       struct route_table *stable;
-
-       /* NOTE: This is a don't care for the default VRF, but we go through
-        * the motions to keep things consistent.
-        */
-       /* Any static routes? */
-       for (afi = AFI_IP; afi < AFI_MAX; afi++) {
-               for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
-                       stable = zvrf->stable[afi][safi];
-                       if (!stable)
-                               continue;
-                       if (route_table_count(stable))
-                               return 1;
-               }
-       }
-
        /* EVPN L3-VNI? */
        if (zvrf->l3vni)
                return 1;
@@ -328,7 +311,9 @@ int zebra_vrf_has_config(struct zebra_vrf *zvrf)
 }
 
 /* Lookup the routing table in a VRF based on both VRF-Id and table-id.
- * NOTE: Table-id is relevant only in the Default VRF.
+ * NOTE: Table-id is relevant on two modes:
+ * - case VRF backend is default : on default VRF only
+ * - case VRF backend is netns : on all VRFs
  */
 struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
                                                  vrf_id_t vrf_id,
@@ -346,6 +331,13 @@ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
                else
                        table = zebra_vrf_other_route_table(afi, table_id,
                                                            vrf_id);
+       } else if (vrf_is_backend_netns()) {
+               if (table_id == RT_TABLE_MAIN
+                   || table_id == zebrad.rtm_table_default)
+                       table = zebra_vrf_table(afi, safi, vrf_id);
+               else
+                       table = zebra_vrf_other_route_table(afi, table_id,
+                                                           vrf_id);
        } else
                table = zebra_vrf_table(afi, safi, vrf_id);
 
@@ -365,18 +357,6 @@ void zebra_rtable_node_cleanup(struct route_table *table,
                XFREE(MTYPE_RIB_DEST, node->info);
 }
 
-static void zebra_stable_node_cleanup(struct route_table *table,
-                                     struct route_node *node)
-{
-       struct static_route *si, *next;
-
-       if (node->info)
-               for (si = node->info; si; si = next) {
-                       next = si->next;
-                       XFREE(MTYPE_STATIC_ROUTE, si);
-               }
-}
-
 static void zebra_rnhtable_node_cleanup(struct route_table *table,
                                        struct route_node *node)
 {
@@ -395,46 +375,31 @@ static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
 
        assert(!zvrf->table[afi][safi]);
 
-       if (afi == AFI_IP6)
-               table = srcdest_table_init();
-       else
-               table = route_table_init();
+       table = zebra_router_get_table(zvrf, zvrf->table_id, afi, safi);
+
        table->cleanup = zebra_rtable_node_cleanup;
        zvrf->table[afi][safi] = table;
 
+       XFREE(MTYPE_RIB_TABLE_INFO, table->info);
        info = XCALLOC(MTYPE_RIB_TABLE_INFO, sizeof(*info));
        info->zvrf = zvrf;
        info->afi = afi;
        info->safi = safi;
-       table->info = info;
+       route_table_set_info(table, info);
 }
 
 /* Allocate new zebra VRF. */
 struct zebra_vrf *zebra_vrf_alloc(void)
 {
        struct zebra_vrf *zvrf;
-       afi_t afi;
-       safi_t safi;
-       struct route_table *table;
 
        zvrf = XCALLOC(MTYPE_ZEBRA_VRF, sizeof(struct zebra_vrf));
 
-       /* Allocate table for static route configuration. */
-       for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
-               for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
-                       if (afi == AFI_IP6)
-                               table = srcdest_table_init();
-                       else
-                               table = route_table_init();
-                       table->cleanup = zebra_stable_node_cleanup;
-                       zvrf->stable[afi][safi] = table;
-               }
-       }
-
        zebra_vxlan_init_tables(zvrf);
        zebra_mpls_init_tables(zvrf);
        zebra_pw_init(zvrf);
-
+       zvrf->table_id = RT_TABLE_MAIN;
+       /* by default table ID is default one */
        return zvrf;
 }
 
@@ -473,37 +438,29 @@ struct route_table *zebra_vrf_table(afi_t afi, safi_t safi, vrf_id_t vrf_id)
        return zvrf->table[afi][safi];
 }
 
-/* Lookup the static routing table in a VRF. */
-struct route_table *zebra_vrf_static_table(afi_t afi, safi_t safi,
-                                          struct zebra_vrf *zvrf)
-{
-       if (!zvrf)
-               return NULL;
-
-       if (afi >= AFI_MAX || safi >= SAFI_MAX)
-               return NULL;
-
-       return zvrf->stable[afi][safi];
-}
-
 struct route_table *zebra_vrf_other_route_table(afi_t afi, uint32_t table_id,
                                                vrf_id_t vrf_id)
 {
        struct zebra_vrf *zvrf;
-       struct zebra_ns *zns;
 
        zvrf = vrf_info_lookup(vrf_id);
        if (!zvrf)
                return NULL;
 
-       zns = zvrf->zns;
-
        if (afi >= AFI_MAX)
                return NULL;
 
-       if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN)
+       if ((table_id != RT_TABLE_MAIN)
            && (table_id != zebrad.rtm_table_default)) {
-               return zebra_ns_get_table(zns, zvrf, table_id, afi);
+               if (zvrf->table_id == RT_TABLE_MAIN ||
+                   zvrf->table_id == zebrad.rtm_table_default) {
+                       /* this VRF use default table
+                        * so in all cases, it does not use specific table
+                        * so it is possible to configure tables in this VRF
+                        */
+                       return zebra_router_get_table(zvrf, table_id, afi,
+                                                     SAFI_UNICAST);
+               }
        }
 
        return zvrf->table[afi][SAFI_UNICAST];
@@ -523,11 +480,8 @@ static int vrf_config_write(struct vty *vty)
                if (zvrf_id(zvrf) == VRF_DEFAULT) {
                        if (zvrf->l3vni)
                                vty_out(vty, "vni %u\n", zvrf->l3vni);
-                       vty_out(vty, "!\n");
-               }
-
-               if (vrf_is_user_cfged(vrf)) {
-                       vty_out(vty, "vrf %s\n", zvrf_name(zvrf));
+               } else {
+                       vty_frame(vty, "vrf %s\n", zvrf_name(zvrf));
                        if (zvrf->l3vni)
                                vty_out(vty, " vni %u%s\n", zvrf->l3vni,
                                        is_l3vni_for_prefix_routes_only(
@@ -537,11 +491,11 @@ static int vrf_config_write(struct vty *vty)
                        zebra_ns_config_write(vty, (struct ns *)vrf->ns_ctxt);
                }
 
-               static_config(vty, zvrf, AFI_IP, SAFI_UNICAST, "ip route");
-               static_config(vty, zvrf, AFI_IP, SAFI_MULTICAST, "ip mroute");
-               static_config(vty, zvrf, AFI_IP6, SAFI_UNICAST, "ipv6 route");
+               zebra_routemap_config_write_protocol(vty, zvrf);
 
-               if (vrf->vrf_id != VRF_DEFAULT)
+               if (zvrf_id(zvrf) != VRF_DEFAULT)
+                       vty_endframe(vty, " exit-vrf\n!\n");
+               else
                        vty_out(vty, "!\n");
        }
        return 0;
@@ -551,7 +505,7 @@ static int vrf_config_write(struct vty *vty)
 void zebra_vrf_init(void)
 {
        vrf_init(zebra_vrf_new, zebra_vrf_enable, zebra_vrf_disable,
-                zebra_vrf_delete);
+                zebra_vrf_delete, zebra_vrf_update);
 
        vrf_cmd_init(vrf_config_write, &zserv_privs);
 }