diff options
| -rw-r--r-- | zebra/redistribute.c | 7 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 23 | ||||
| -rw-r--r-- | zebra/zebra_router.c | 13 | ||||
| -rw-r--r-- | zebra/zebra_router.h | 2 | ||||
| -rw-r--r-- | zebra/zebra_vrf.c | 82 | ||||
| -rw-r--r-- | zebra/zebra_vrf.h | 35 |
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); |
