]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Move zvrf->other_tables into zns
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 14 Feb 2018 01:25:11 +0000 (20:25 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 23 Feb 2018 12:08:36 +0000 (07:08 -0500)
The other_tables data structure does not belong to a vrf.
It belongs to the zns.  This is because each vrf does not
need to have copies of each of other_tables.

Additionally move the array into a RB_TREE.  This will allow
us to sort quickly and easily expand the number of tables
we can support to beyond the ZEBRA_KERNEL_TABLE_MAX define.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
zebra/zebra_ns.c
zebra/zebra_ns.h
zebra/zebra_vrf.c
zebra/zebra_vrf.h

index c48a6f7bd8ad377e8b7e882281a5f0f8cc147ea1..91dbd34387d023b2d88201f0b4865f73e554b902 100644 (file)
 
 DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space")
 
+static __inline int
+zebra_ns_table_entry_compare(const struct zebra_ns_table *e1,
+                            const struct zebra_ns_table *e2);
+
+RB_GENERATE(zebra_ns_table_head, zebra_ns_table, zebra_ns_table_entry,
+           zebra_ns_table_entry_compare);
+
 static struct zebra_ns *dzns;
 
+static __inline int
+zebra_ns_table_entry_compare(const struct zebra_ns_table *e1,
+                            const struct zebra_ns_table *e2)
+{
+       if (e1->tableid == e2->tableid)
+               return (e1->afi - e2->afi);
+
+       return e1->tableid - e2->tableid;
+}
+
 struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id)
 {
        return dzns;
@@ -57,10 +74,61 @@ int zebra_ns_enable(ns_id_t ns_id, void **info)
        return 0;
 }
 
+struct route_table *zebra_ns_get_table(struct zebra_ns *zns,
+                                      struct zebra_vrf *zvrf, uint32_t tableid,
+                                      afi_t afi)
+{
+       struct zebra_ns_table finder;
+       struct zebra_ns_table *znst;
+       rib_table_info_t *info;
+
+       memset(&finder, 0, sizeof(finder));
+       finder.afi = afi;
+       finder.tableid = tableid;
+       znst = RB_FIND(zebra_ns_table_head, &zns->ns_tables, &finder);
+
+       if (znst)
+               return znst->table;
+
+       znst = XCALLOC(MTYPE_ZEBRA_NS, sizeof(*znst));
+       znst->tableid = tableid;
+       znst->afi = afi;
+       znst->table =
+               (afi == AFI_IP6) ? srcdest_table_init() : route_table_init();
+
+       info = XCALLOC(MTYPE_RIB_TABLE_INFO, sizeof(*info));
+       info->zvrf = zvrf;
+       info->afi = afi;
+       info->safi = SAFI_UNICAST;
+       znst->table->info = info;
+       znst->table->cleanup = zebra_rtable_node_cleanup;
+
+       RB_INSERT(zebra_ns_table_head, &zns->ns_tables, znst);
+       return znst->table;
+}
+
+static struct zebra_ns_table *zebra_ns_free_table(struct zebra_ns_table *znst)
+{
+       void *table_info;
+       rib_close_table(znst->table);
+
+       table_info = znst->table->info;
+       route_table_finish(znst->table);
+       XFREE(MTYPE_RIB_TABLE_INFO, table_info);
+       XFREE(MTYPE_ZEBRA_NS, znst);
+       return NULL;
+}
+
 int zebra_ns_disable(ns_id_t ns_id, void **info)
 {
+       struct zebra_ns_table *znst;
        struct zebra_ns *zns = (struct zebra_ns *)(*info);
 
+       while ((znst = RB_ROOT(zebra_ns_table_head, &zns->ns_tables))
+              != NULL) {
+               RB_REMOVE(zebra_ns_table_head, &zns->ns_tables, znst);
+               znst = zebra_ns_free_table(znst);
+       }
        route_table_finish(zns->if_table);
        zebra_vxlan_ns_disable(zns);
 #if defined(HAVE_RTADV)
@@ -72,6 +140,7 @@ int zebra_ns_disable(ns_id_t ns_id, void **info)
        return 0;
 }
 
+
 int zebra_ns_init(void)
 {
        dzns = XCALLOC(MTYPE_ZEBRA_NS, sizeof(struct zebra_ns));
index 5d90b9be67d3737ffed0c8f8797de72ee2455de6..29905ccad38e1f321e6a7d6f396af77bc1ad9feb 100644 (file)
@@ -34,6 +34,18 @@ struct nlsock {
 };
 #endif
 
+struct zebra_ns_table {
+       RB_ENTRY(zebra_ns_table) zebra_ns_table_entry;
+
+       uint32_t tableid;
+       afi_t afi;
+
+       struct route_table *table;
+};
+RB_HEAD(zebra_ns_table_head, zebra_ns_table);
+RB_PROTOTYPE(zebra_ns_table_head, zebra_ns_table, zebra_ns_table_entry,
+            zebra_ns_table_entry_compare)
+
 struct zebra_ns {
        /* net-ns name.  */
        char name[VRF_NAMSIZ];
@@ -55,6 +67,8 @@ struct zebra_ns {
 #if defined(HAVE_RTADV)
        struct rtadv rtadv;
 #endif /* HAVE_RTADV */
+
+       struct zebra_ns_table_head ns_tables;
 };
 
 struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id);
@@ -62,4 +76,8 @@ struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id);
 int zebra_ns_init(void);
 int zebra_ns_enable(ns_id_t ns_id, void **info);
 int zebra_ns_disable(ns_id_t ns_id, void **info);
+
+extern struct route_table *zebra_ns_get_table(struct zebra_ns *zns,
+                                             struct zebra_vrf *zvrf,
+                                             uint32_t tableid, afi_t afi);
 #endif
index b9b3048486f7132b94d5dade28790c2a3624c77c..a0c7929b44ddf59603f95d2c1003ef9b14795f0d 100644 (file)
@@ -174,7 +174,6 @@ static int zebra_vrf_disable(struct vrf *vrf)
        struct static_route *si;
        struct route_table *table;
        struct interface *ifp;
-       u_int32_t table_id;
        afi_t afi;
        safi_t safi;
        unsigned i;
@@ -213,12 +212,6 @@ static int zebra_vrf_disable(struct vrf *vrf)
        for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
                for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
                        rib_close_table(zvrf->table[afi][safi]);
-
-               if (vrf->vrf_id == VRF_DEFAULT)
-                       for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX;
-                            table_id++)
-                               if (zvrf->other_table[afi][table_id])
-                                       rib_close_table(zvrf->other_table[afi][table_id]);
        }
 
        /* Cleanup Vxlan, MPLS and PW tables. */
@@ -258,17 +251,6 @@ static int zebra_vrf_disable(struct vrf *vrf)
                        zvrf->table[afi][safi] = NULL;
                }
 
-               if (vrf->vrf_id == VRF_DEFAULT)
-                       for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX;
-                            table_id++)
-                               if (zvrf->other_table[afi][table_id]) {
-                                       table = zvrf->other_table[afi][table_id];
-                                       table_info = table->info;
-                                       route_table_finish(table);
-                                       XFREE(MTYPE_RIB_TABLE_INFO, table_info);
-                                       zvrf->other_table[afi][table_id] = NULL;
-                               }
-
                route_table_finish(zvrf->rnh_table[afi]);
                zvrf->rnh_table[afi] = NULL;
                route_table_finish(zvrf->import_check_table[afi]);
@@ -282,7 +264,6 @@ static int zebra_vrf_delete(struct vrf *vrf)
 {
        struct zebra_vrf *zvrf = vrf->info;
        struct route_table *table;
-       u_int32_t table_id;
        afi_t afi;
        safi_t safi;
        unsigned i;
@@ -328,14 +309,6 @@ static int zebra_vrf_delete(struct vrf *vrf)
                        route_table_finish(table);
                }
 
-               for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
-                       if (zvrf->other_table[afi][table_id]) {
-                               table = zvrf->other_table[afi][table_id];
-                               table_info = table->info;
-                               route_table_finish(table);
-                               XFREE(MTYPE_RIB_TABLE_INFO, table_info);
-                       }
-
                route_table_finish(zvrf->rnh_table[afi]);
                route_table_finish(zvrf->import_check_table[afi]);
        }
@@ -407,8 +380,8 @@ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
        return table;
 }
 
-static void zebra_rtable_node_cleanup(struct route_table *table,
-                                     struct route_node *node)
+void zebra_rtable_node_cleanup(struct route_table *table,
+                              struct route_node *node)
 {
        struct route_entry *re, *next;
 
@@ -545,13 +518,14 @@ struct route_table *zebra_vrf_other_route_table(afi_t afi, u_int32_t table_id,
                                                vrf_id_t vrf_id)
 {
        struct zebra_vrf *zvrf;
-       rib_table_info_t *info;
-       struct route_table *table;
+       struct zebra_ns *zns;
 
        zvrf = vrf_info_lookup(vrf_id);
        if (!zvrf)
                return NULL;
 
+       zns = zvrf->zns;
+
        if (afi >= AFI_MAX)
                return NULL;
 
@@ -560,19 +534,7 @@ struct route_table *zebra_vrf_other_route_table(afi_t afi, u_int32_t table_id,
 
        if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN)
            && (table_id != zebrad.rtm_table_default)) {
-               if (zvrf->other_table[afi][table_id] == NULL) {
-                       table = (afi == AFI_IP6) ? srcdest_table_init()
-                                                : route_table_init();
-                       info = XCALLOC(MTYPE_RIB_TABLE_INFO, sizeof(*info));
-                       info->zvrf = zvrf;
-                       info->afi = afi;
-                       info->safi = SAFI_UNICAST;
-                       table->info = info;
-                       table->cleanup = zebra_rtable_node_cleanup;
-                       zvrf->other_table[afi][table_id] = table;
-               }
-
-               return (zvrf->other_table[afi][table_id]);
+               return zebra_ns_get_table(zns, zvrf, table_id, afi);
        }
 
        return zvrf->table[afi][SAFI_UNICAST];
index d3a5316b9d4571b53b74c1349cedf43d0d829266..4d53eee093fe0787c76a58d9aeaeb76bebc944fc 100644 (file)
@@ -62,9 +62,6 @@ struct zebra_vrf {
        /* Import check table (used mostly by BGP */
        struct route_table *import_check_table[AFI_MAX];
 
-       /* Routing tables off of main table for redistribute table */
-       struct route_table *other_table[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
-
        /* 2nd pointer type used primarily to quell a warning on
         * ALL_LIST_ELEMENTS_RO
         */
@@ -154,4 +151,7 @@ extern struct route_table *
 zebra_vrf_other_route_table(afi_t afi, u_int32_t table_id, vrf_id_t vrf_id);
 extern int zebra_vrf_has_config(struct zebra_vrf *zvrf);
 extern void zebra_vrf_init(void);
+
+extern void zebra_rtable_node_cleanup(struct route_table *table,
+                                     struct route_node *node);
 #endif