summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/redistribute.c7
-rw-r--r--zebra/zebra_rib.c23
-rw-r--r--zebra/zebra_router.c13
-rw-r--r--zebra/zebra_router.h2
-rw-r--r--zebra/zebra_vrf.c82
-rw-r--r--zebra/zebra_vrf.h35
6 files changed, 92 insertions, 70 deletions
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index fe064f847a..f3155deb14 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -653,7 +653,8 @@ int zebra_import_table(afi_t afi, uint32_t table_id, uint32_t distance,
if (afi >= AFI_MAX)
return (-1);
- table = zebra_vrf_other_route_table(afi, table_id, VRF_DEFAULT);
+ table = zebra_vrf_table_with_table_id(afi, SAFI_UNICAST,
+ table_id, VRF_DEFAULT);
if (table == NULL) {
return 0;
} else if (IS_ZEBRA_DEBUG_RIB) {
@@ -767,8 +768,8 @@ void zebra_import_table_rm_update(const char *rmap)
rmap_name = zebra_get_import_table_route_map(afi, i);
if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0))
continue;
- table = zebra_vrf_other_route_table(afi, i,
- VRF_DEFAULT);
+ table = zebra_vrf_table_with_table_id(afi, SAFI_UNICAST,
+ i, VRF_DEFAULT);
for (rn = route_top(table); rn; rn = route_next(rn)) {
/* For each entry in the non-default
* routing table,
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 72c7385d8a..8d4f49e3ee 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -3208,18 +3208,23 @@ unsigned long rib_score_proto(uint8_t proto, unsigned short instance)
{
struct vrf *vrf;
struct zebra_vrf *zvrf;
+ struct other_route_table *ort;
unsigned long cnt = 0;
- RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
- if ((zvrf = vrf->info) != NULL)
- cnt += rib_score_proto_table(
- proto, instance,
- zvrf->table[AFI_IP][SAFI_UNICAST])
- + rib_score_proto_table(
- proto, instance,
- zvrf->table[AFI_IP6][SAFI_UNICAST]);
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
+ zvrf = vrf->info;
+ if (!zvrf)
+ continue;
- cnt += zebra_router_score_proto(proto, instance);
+ cnt += rib_score_proto_table(proto, instance,
+ zvrf->table[AFI_IP][SAFI_UNICAST])
+ + rib_score_proto_table(
+ proto, instance,
+ zvrf->table[AFI_IP6][SAFI_UNICAST]);
+
+ for_each(otable, &zvrf->other_tables, ort) cnt +=
+ rib_score_proto_table(proto, instance, ort->table);
+ }
return cnt;
}
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index 0ab6946eea..610d51d3ea 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -119,19 +119,6 @@ struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf,
return zrt->table;
}
-unsigned long zebra_router_score_proto(uint8_t proto, unsigned short instance)
-{
- struct zebra_router_table *zrt;
- unsigned long cnt = 0;
-
- RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) {
- if (zrt->ns_id != NS_DEFAULT)
- continue;
- cnt += rib_score_proto_table(proto, instance, zrt->table);
- }
- return cnt;
-}
-
void zebra_router_show_table_summary(struct vty *vty)
{
struct zebra_router_table *zrt;
diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h
index 04421a0f0d..dcbf333b1c 100644
--- a/zebra/zebra_router.h
+++ b/zebra/zebra_router.h
@@ -129,8 +129,6 @@ extern void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
extern int zebra_router_config_write(struct vty *vty);
-extern unsigned long zebra_router_score_proto(uint8_t proto,
- unsigned short instance);
extern void zebra_router_sweep_route(void);
extern void zebra_router_show_table_summary(struct vty *vty);
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 1f2ff63286..fdf0cbc693 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -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;
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index 2dd47b5561..972fe381cc 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -43,6 +43,18 @@ struct zebra_rmap {
struct route_map *map;
};
+PREDECL_RBTREE_UNIQ(otable);
+
+struct other_route_table {
+ struct otable_item next;
+
+ afi_t afi;
+ safi_t safi;
+ uint32_t table_id;
+
+ struct route_table *table;
+};
+
/* Routing table instance. */
struct zebra_vrf {
/* Back pointer */
@@ -69,6 +81,8 @@ struct zebra_vrf {
/* Import check table (used mostly by BGP */
struct route_table *import_check_table[AFI_MAX];
+ struct otable_head other_tables;
+
/* 2nd pointer type used primarily to quell a warning on
* ALL_LIST_ELEMENTS_RO
*/
@@ -196,6 +210,25 @@ static inline bool zvrf_is_active(struct zebra_vrf *zvrf)
return zvrf->vrf->status & VRF_ACTIVE;
}
+static inline int
+zvrf_other_table_compare_func(const struct other_route_table *a,
+ const struct other_route_table *b)
+{
+ if (a->afi != b->afi)
+ return a->afi - b->afi;
+
+ if (a->safi != b->safi)
+ return a->safi - b->safi;
+
+ if (a->table_id != b->table_id)
+ return a->table_id - b->table_id;
+
+ return 0;
+}
+
+DECLARE_RBTREE_UNIQ(otable, struct other_route_table, next,
+ zvrf_other_table_compare_func)
+
struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
vrf_id_t vrf_id,
uint32_t table_id);
@@ -206,8 +239,6 @@ extern struct zebra_vrf *zebra_vrf_lookup_by_name(const char *);
extern struct zebra_vrf *zebra_vrf_alloc(void);
extern struct route_table *zebra_vrf_table(afi_t, safi_t, vrf_id_t);
-extern struct route_table *
-zebra_vrf_other_route_table(afi_t afi, uint32_t table_id, vrf_id_t vrf_id);
extern int zebra_vrf_has_config(struct zebra_vrf *zvrf);
extern void zebra_vrf_init(void);