]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_vrf.c
Merge pull request #4269 from donaldsharp/other_tables
[mirror_frr.git] / zebra / zebra_vrf.c
index 1f2ff63286489b17d9a491d7c426d4ca67b82aa3..fdf0cbc693fc282b4570c443333f0d639baee37e 100644 (file)
@@ -48,6 +48,8 @@ static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
 static void zebra_rnhtable_node_cleanup(struct route_table *table,
                                        struct route_node *node);
 
+DEFINE_MTYPE_STATIC(ZEBRA, OTHER_TABLE, "Other Table");
+
 /* VRF information update. */
 static void zebra_vrf_add_update(struct zebra_vrf *zvrf)
 {
@@ -94,6 +96,9 @@ static int zebra_vrf_new(struct vrf *vrf)
        zvrf = zebra_vrf_alloc();
        vrf->info = zvrf;
        zvrf->vrf = vrf;
+
+       otable_init(&zvrf->other_tables);
+
        router_id_init(zvrf);
        return 0;
 }
@@ -235,6 +240,7 @@ static int zebra_vrf_disable(struct vrf *vrf)
 static int zebra_vrf_delete(struct vrf *vrf)
 {
        struct zebra_vrf *zvrf = vrf->info;
+       struct other_route_table *otable;
        struct route_table *table;
        afi_t afi;
        safi_t safi;
@@ -283,11 +289,22 @@ static int zebra_vrf_delete(struct vrf *vrf)
                        route_table_finish(zvrf->import_check_table[afi]);
        }
 
+       otable = otable_pop(&zvrf->other_tables);
+       while (otable) {
+               zebra_router_release_table(zvrf, otable->table_id,
+                                          otable->afi, otable->safi);
+               XFREE(MTYPE_OTHER_TABLE, otable);
+
+               otable = otable_pop(&zvrf->other_tables);
+       }
+
        /* Cleanup EVPN states for vrf */
        zebra_vxlan_vrf_delete(zvrf);
 
        list_delete_all_node(zvrf->rid_all_sorted_list);
        list_delete_all_node(zvrf->rid_lo_sorted_list);
+
+       otable_fini(&zvrf->other_tables);
        XFREE(MTYPE_ZEBRA_VRF, zvrf);
        vrf->info = NULL;
 
@@ -329,25 +346,34 @@ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
                                                  vrf_id_t vrf_id,
                                                  uint32_t table_id)
 {
-       struct route_table *table = NULL;
+       struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
+       struct other_route_table ort, *otable;
+       struct route_table *table;
+
+       if (!zvrf)
+               return NULL;
 
        if (afi >= AFI_MAX || safi >= SAFI_MAX)
                return NULL;
 
-       if (vrf_id == VRF_DEFAULT) {
-               if (table_id == RT_TABLE_MAIN)
-                       table = zebra_vrf_table(afi, safi, vrf_id);
-               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 = 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);
+       if (table_id == zvrf->table_id)
+               return zebra_vrf_table(afi, safi, vrf_id);
+
+       ort.afi = afi;
+       ort.safi = safi;
+       ort.table_id = table_id;
+       otable = otable_find(&zvrf->other_tables, &ort);
+       if (otable)
+               return otable->table;
+
+       table = zebra_router_get_table(zvrf, table_id, afi, safi);
+
+       otable = XCALLOC(MTYPE_OTHER_TABLE, sizeof(*otable));
+       otable->afi = afi;
+       otable->safi = safi;
+       otable->table_id = table_id;
+       otable->table = table;
+       otable_add(&zvrf->other_tables, otable);
 
        return table;
 }
@@ -447,32 +473,6 @@ struct route_table *zebra_vrf_table(afi_t afi, safi_t safi, vrf_id_t vrf_id)
        return zvrf->table[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;
-
-       zvrf = vrf_info_lookup(vrf_id);
-       if (!zvrf)
-               return NULL;
-
-       if (afi >= AFI_MAX)
-               return NULL;
-
-       if (table_id != RT_TABLE_MAIN) {
-               if (zvrf->table_id == RT_TABLE_MAIN) {
-                       /* 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];
-}
-
 static int vrf_config_write(struct vty *vty)
 {
        struct vrf *vrf;