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>
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;
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)
return 0;
}
+
int zebra_ns_init(void)
{
dzns = XCALLOC(MTYPE_ZEBRA_NS, sizeof(struct zebra_ns));
};
#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];
#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);
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
struct static_route *si;
struct route_table *table;
struct interface *ifp;
- u_int32_t table_id;
afi_t afi;
safi_t safi;
unsigned i;
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. */
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]);
{
struct zebra_vrf *zvrf = vrf->info;
struct route_table *table;
- u_int32_t table_id;
afi_t afi;
safi_t safi;
unsigned i;
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]);
}
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;
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;
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];
/* 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
*/
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