diff --git a/ldpd/interface.c b/ldpd/interface.c index bbcea9f553..b25be43a5c 100644 --- a/ldpd/interface.c +++ b/ldpd/interface.c @@ -306,8 +306,11 @@ if_reset(struct iface *iface, int af) ia = iface_af_get(iface, af); if_stop_hello_timer(ia); - while ((adj = RB_ROOT(ia_adj_head, &ia->adj_tree)) != NULL) + while (!RB_EMPTY(ia_adj_head, &ia->adj_tree)) { + adj = RB_ROOT(ia_adj_head, &ia->adj_tree); + adj_del(adj, S_SHUTDOWN); + } /* try to cleanup */ switch (af) { diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c index f638d6a65b..1cfeae3092 100644 --- a/ldpd/l2vpn.c +++ b/ldpd/l2vpn.c @@ -76,16 +76,21 @@ l2vpn_del(struct l2vpn *l2vpn) struct l2vpn_if *lif; struct l2vpn_pw *pw; - while ((lif = RB_ROOT(l2vpn_if_head, &l2vpn->if_tree)) != NULL) { + while (!RB_EMPTY(l2vpn_if_head, &l2vpn->if_tree)) { + lif = RB_ROOT(l2vpn_if_head, &l2vpn->if_tree); + RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif); free(lif); } - while ((pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree)) != NULL) { + while (!RB_EMPTY(l2vpn_pw_head, &l2vpn->pw_tree)) { + pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree); + RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw); free(pw); } - while ((pw = RB_ROOT(l2vpn_pw_head, - &l2vpn->pw_inactive_tree)) != NULL) { + while (!RB_EMPTY(l2vpn_pw_head, &l2vpn->pw_inactive_tree)) { + pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_inactive_tree); + RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); free(pw); } diff --git a/ldpd/lde.c b/ldpd/lde.c index a70b97d06b..5aa53fd39e 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -1324,8 +1324,11 @@ lde_nbr_clear(void) { struct lde_nbr *ln; - while ((ln = RB_ROOT(nbr_tree, &lde_nbrs)) != NULL) + while (!RB_EMPTY(nbr_tree, &lde_nbrs)) { + ln = RB_ROOT(nbr_tree, &lde_nbrs); + lde_nbr_del(ln); + } } static void diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c index 18c8c0a122..28e455c7a5 100644 --- a/ldpd/lde_lib.c +++ b/ldpd/lde_lib.c @@ -129,7 +129,9 @@ fec_clear(struct fec_tree *fh, void (*free_cb)(void *)) { struct fec *f; - while ((f = RB_ROOT(fec_tree, fh)) != NULL) { + while (!RB_EMPTY(fec_tree, fh)) { + f = RB_ROOT(fec_tree, fh); + fec_remove(fh, f); free_cb(f); } diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c index 76c602afbb..382b006884 100644 --- a/ldpd/ldp_vty_conf.c +++ b/ldpd/ldp_vty_conf.c @@ -1475,18 +1475,23 @@ l2vpn_del_api(struct ldpd_conf *conf, struct l2vpn *l2vpn) struct l2vpn_if *lif; struct l2vpn_pw *pw; - while ((lif = RB_ROOT(l2vpn_if_head, &l2vpn->if_tree)) != NULL) { + while (!RB_EMPTY(l2vpn_if_head, &l2vpn->if_tree)) { + lif = RB_ROOT(l2vpn_if_head, &l2vpn->if_tree); + QOBJ_UNREG(lif); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif); free(lif); } - while ((pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree)) != NULL) { + while (!RB_EMPTY(l2vpn_pw_head, &l2vpn->pw_tree)) { + pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree); + QOBJ_UNREG(pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw); free(pw); } - while ((pw = RB_ROOT(l2vpn_pw_head, - &l2vpn->pw_inactive_tree)) != NULL) { + while (!RB_EMPTY(l2vpn_pw_head, &l2vpn->pw_inactive_tree)) { + pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_inactive_tree); + QOBJ_UNREG(pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); free(pw); diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index 12aeb1fff3..255febeb60 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -1066,13 +1066,17 @@ ldp_config_reset_main(struct ldpd_conf *conf) struct iface *iface; struct nbr_params *nbrp; - while ((iface = RB_ROOT(iface_head, &conf->iface_tree)) != NULL) { + while (!RB_EMPTY(iface_head, &conf->iface_tree)) { + iface = RB_ROOT(iface_head, &conf->iface_tree); + QOBJ_UNREG(iface); RB_REMOVE(iface_head, &conf->iface_tree, iface); free(iface); } - while ((nbrp = RB_ROOT(nbrp_head, &conf->nbrp_tree)) != NULL) { + while (!RB_EMPTY(nbrp_head, &conf->nbrp_tree)) { + nbrp = RB_ROOT(nbrp_head, &conf->nbrp_tree); + QOBJ_UNREG(nbrp); RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp); free(nbrp); @@ -1128,20 +1132,25 @@ ldp_config_reset_l2vpns(struct ldpd_conf *conf) struct l2vpn_if *lif; struct l2vpn_pw *pw; - while ((l2vpn = RB_ROOT(l2vpn_head, &conf->l2vpn_tree)) != NULL) { - while ((lif = RB_ROOT(l2vpn_if_head, - &l2vpn->if_tree)) != NULL) { + while (!RB_EMPTY(l2vpn_head, &conf->l2vpn_tree)) { + l2vpn = RB_ROOT(l2vpn_head, &conf->l2vpn_tree); + while (!RB_EMPTY(l2vpn_if_head, &l2vpn->if_tree)) { + lif = RB_ROOT(l2vpn_if_head, &l2vpn->if_tree); + QOBJ_UNREG(lif); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif); free(lif); } - while ((pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree)) != NULL) { + while (!RB_EMPTY(l2vpn_pw_head, &l2vpn->pw_tree)) { + pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree); + QOBJ_UNREG(pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw); free(pw); } - while ((pw = RB_ROOT(l2vpn_pw_head, - &l2vpn->pw_inactive_tree)) != NULL) { + while (!RB_EMPTY(l2vpn_pw_head, &l2vpn->pw_inactive_tree)) { + pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_inactive_tree); + QOBJ_UNREG(pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); free(pw); @@ -1160,19 +1169,27 @@ ldp_clear_config(struct ldpd_conf *xconf) struct nbr_params *nbrp; struct l2vpn *l2vpn; - while ((iface = RB_ROOT(iface_head, &xconf->iface_tree)) != NULL) { + while (!RB_EMPTY(iface_head, &xconf->iface_tree)) { + iface = RB_ROOT(iface_head, &xconf->iface_tree); + RB_REMOVE(iface_head, &xconf->iface_tree, iface); free(iface); } - while ((tnbr = RB_ROOT(tnbr_head, &xconf->tnbr_tree)) != NULL) { + while (!RB_EMPTY(tnbr_head, &xconf->tnbr_tree)) { + tnbr = RB_ROOT(tnbr_head, &xconf->tnbr_tree); + RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr); free(tnbr); } - while ((nbrp = RB_ROOT(nbrp_head, &xconf->nbrp_tree)) != NULL) { + while (!RB_EMPTY(nbrp_head, &xconf->nbrp_tree)) { + nbrp = RB_ROOT(nbrp_head, &xconf->nbrp_tree); + RB_REMOVE(nbrp_head, &xconf->nbrp_tree, nbrp); free(nbrp); } - while ((l2vpn = RB_ROOT(l2vpn_head, &xconf->l2vpn_tree)) != NULL) { + while (!RB_EMPTY(l2vpn_head, &xconf->l2vpn_tree)) { + l2vpn = RB_ROOT(l2vpn_head, &xconf->l2vpn_tree); + RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, l2vpn); l2vpn_del(l2vpn); } diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c index 9d00bcd2b6..56af76d94e 100644 --- a/ldpd/ldpe.c +++ b/ldpd/ldpe.c @@ -219,8 +219,11 @@ ldpe_shutdown(void) assert(if_addr != LIST_FIRST(&global.addr_list)); free(if_addr); } - while ((adj = RB_ROOT(global_adj_head, &global.adj_tree)) != NULL) + while (!RB_EMPTY(global_adj_head, &global.adj_tree)) { + adj = RB_ROOT(global_adj_head, &global.adj_tree); + adj_del(adj, S_SHUTDOWN); + } /* clean up */ if (iev_lde) diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c index 39860a1859..1c3f650dff 100644 --- a/ldpd/neighbor.c +++ b/ldpd/neighbor.c @@ -316,7 +316,9 @@ nbr_del(struct nbr *nbr) mapping_list_clr(&nbr->release_list); mapping_list_clr(&nbr->abortreq_list); - while ((adj = RB_ROOT(nbr_adj_head, &nbr->adj_tree)) != NULL) { + while (!RB_EMPTY(nbr_adj_head, &nbr->adj_tree)) { + adj = RB_ROOT(nbr_adj_head, &nbr->adj_tree); + adj->nbr = NULL; RB_REMOVE(nbr_adj_head, &nbr->adj_tree, adj); } diff --git a/lib/if.c b/lib/if.c index 7866ddb8c4..12d123a8fa 100644 --- a/lib/if.c +++ b/lib/if.c @@ -1064,7 +1064,7 @@ ifaddr_ipv4_lookup (struct in_addr *addr, ifindex_t ifindex) rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p); if (! rn) return NULL; - + ifp = rn->info; route_unlock_node (rn); return ifp; @@ -1078,7 +1078,9 @@ void if_terminate(struct vrf *vrf) { struct interface *ifp; - while ((ifp = RB_ROOT(if_name_head, &vrf->ifaces_by_name)) != NULL) { + while (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) { + ifp = RB_ROOT(if_name_head, &vrf->ifaces_by_name); + if (ifp->node) { ifp->node->info = NULL; route_unlock_node(ifp->node); diff --git a/lib/ns.c b/lib/ns.c index fdf93d0742..0b2a3bec78 100644 --- a/lib/ns.c +++ b/lib/ns.c @@ -424,8 +424,11 @@ void ns_terminate(void) { struct ns *ns; - while ((ns = RB_ROOT(ns_head, &ns_tree)) != NULL) + while (!RB_EMPTY(ns_head, &ns_tree)) { + ns = RB_ROOT(ns_head, &ns_tree); + ns_delete(ns); + } } /* Create a socket for the NS. */ diff --git a/lib/vrf.c b/lib/vrf.c index 2e15fa2f5c..02946df2bc 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -419,12 +419,17 @@ void vrf_terminate(void) zlog_debug("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__); - while ((vrf = RB_ROOT(vrf_id_head, &vrfs_by_id)) != NULL) { + while (!RB_EMPTY(vrf_id_head, &vrfs_by_id)) { + vrf = RB_ROOT(vrf_id_head, &vrfs_by_id); + /* Clear configured flag and invoke delete. */ UNSET_FLAG(vrf->status, VRF_CONFIGURED); vrf_delete(vrf); } - while ((vrf = RB_ROOT(vrf_name_head, &vrfs_by_name)) != NULL) { + + while (!RB_EMPTY(vrf_name_head, &vrfs_by_name)) { + vrf = RB_ROOT(vrf_name_head, &vrfs_by_name); + /* Clear configured flag and invoke delete. */ UNSET_FLAG(vrf->status, VRF_CONFIGURED); vrf_delete(vrf); diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index f02cf7ed31..a807c69c60 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -85,9 +85,11 @@ static void *if_list_clean(struct pim_interface *pim_ifp) if (pim_ifp->sec_addr_list) list_delete_and_null(&pim_ifp->sec_addr_list); - while ((ch = RB_ROOT(pim_ifchannel_rb, - &pim_ifp->ifchannel_rb)) != NULL) + while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) { + ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb); + pim_ifchannel_delete(ch); + } XFREE(MTYPE_PIM_INTERFACE, pim_ifp); @@ -250,9 +252,11 @@ void pim_if_delete(struct interface *ifp) if (pim_ifp->boundary_oil_plist) XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist); - while ((ch = RB_ROOT(pim_ifchannel_rb, - &pim_ifp->ifchannel_rb)) != NULL) + while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) { + ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb); + pim_ifchannel_delete(ch); + } XFREE(MTYPE_PIM_INTERFACE, pim_ifp); diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 7d3b783adf..4d564e5046 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -211,8 +211,9 @@ void pim_ifchannel_delete_all(struct interface *ifp) if (!pim_ifp) return; - while ((ch = RB_ROOT(pim_ifchannel_rb, - &pim_ifp->ifchannel_rb)) != NULL) { + while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) { + ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb); + pim_ifchannel_delete(ch); } } diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index c48a6f7bd8..1715881f7e 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -34,8 +34,25 @@ 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,79 @@ int zebra_ns_enable(ns_id_t ns_id, void **info) return 0; } +struct route_table *zebra_ns_find_table(struct zebra_ns *zns, + uint32_t tableid, afi_t afi) +{ + struct zebra_ns_table finder; + struct zebra_ns_table *znst; + + 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; + else + return NULL; +} + +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 void 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); +} + 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 (!RB_EMPTY(zebra_ns_table_head, &zns->ns_tables)) { + znst = RB_ROOT(zebra_ns_table_head, &zns->ns_tables); + + RB_REMOVE(zebra_ns_table_head, &zns->ns_tables, znst); + zebra_ns_free_table(znst); + } route_table_finish(zns->if_table); zebra_vxlan_ns_disable(zns); #if defined(HAVE_RTADV) @@ -72,6 +158,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)); diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h index 5d90b9be67..765f2c6893 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -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,10 @@ 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_find_table(struct zebra_ns *zns, + uint32_t tableid, afi_t afi); +extern struct route_table *zebra_ns_get_table(struct zebra_ns *zns, + struct zebra_vrf *zvrf, + uint32_t tableid, afi_t afi); #endif diff --git a/zebra/zebra_pw.c b/zebra/zebra_pw.c index bbd01a759e..96bee36be6 100644 --- a/zebra/zebra_pw.c +++ b/zebra/zebra_pw.c @@ -294,8 +294,11 @@ void zebra_pw_exit(struct zebra_vrf *zvrf) { struct zebra_pw *pw; - while ((pw = RB_ROOT(zebra_pw_head, &zvrf->pseudowires)) != NULL) + while (!RB_EMPTY(zebra_pw_head, &zvrf->pseudowires)) { + pw = RB_ROOT(zebra_pw_head, &zvrf->pseudowires); + zebra_pw_del(zvrf, pw); + } } DEFUN_NOSH (pseudowire_if, diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 967bc92850..b5ce17d9f8 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1150,7 +1150,8 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re) */ hook_call(rib_update, rn, "uninstalling from kernel"); kernel_route_rib(rn, p, src_p, re, NULL); - zvrf->removals++; + if (zvrf) + zvrf->removals++; return; } diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index b9b3048486..80553d5c5f 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -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. */ @@ -236,7 +229,8 @@ static int zebra_vrf_disable(struct vrf *vrf) struct route_node *rnode; rib_dest_t *dest; - for (ALL_LIST_ELEMENTS(zebrad.mq->subq[i], lnode, nnode, rnode)) { + for (ALL_LIST_ELEMENTS(zebrad.mq->subq[i], + lnode, nnode, rnode)) { dest = rib_dest_from_rnode(rnode); if (dest && rib_dest_vrf(dest) == zvrf) { route_unlock_node(rnode); @@ -258,17 +252,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 +265,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 +310,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 +381,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,34 +519,20 @@ 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; - if (afi >= AFI_MAX) - return NULL; + zns = zvrf->zns; - if (table_id >= ZEBRA_KERNEL_TABLE_MAX) + 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]; diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index d3a5316b9d..4d53eee093 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -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 diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 269244f768..d2248f4fbb 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -1235,46 +1235,21 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, } } -static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, - safi_t safi, bool use_fib, u_char use_json, - route_tag_t tag, - const struct prefix *longer_prefix_p, - bool supernets_only, int type, - u_short ospf_instance_id) +static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, + struct route_table *table, afi_t afi, + bool use_fib, route_tag_t tag, + const struct prefix *longer_prefix_p, + bool supernets_only, int type, + u_short ospf_instance_id, u_char use_json) { - struct route_table *table; - rib_dest_t *dest; struct route_node *rn; struct route_entry *re; int first = 1; - struct zebra_vrf *zvrf = NULL; - char buf[BUFSIZ]; + rib_dest_t *dest; json_object *json = NULL; json_object *json_prefix = NULL; - u_int32_t addr; - - if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) { - if (use_json) - vty_out(vty, "{}\n"); - else - vty_out(vty, "vrf %s not defined\n", vrf_name); - return CMD_SUCCESS; - } - - if (zvrf_id(zvrf) == VRF_UNKNOWN) { - if (use_json) - vty_out(vty, "{}\n"); - else - vty_out(vty, "vrf %s inactive\n", vrf_name); - return CMD_SUCCESS; - } - - table = zebra_vrf_table(afi, safi, zvrf_id(zvrf)); - if (!table) { - if (use_json) - vty_out(vty, "{}\n"); - return CMD_SUCCESS; - } + uint32_t addr; + char buf[BUFSIZ]; if (use_json) json = json_object_new_object(); @@ -1352,6 +1327,67 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } +} + +static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, + safi_t safi, bool use_fib, u_char use_json, + route_tag_t tag, + const struct prefix *longer_prefix_p, + bool supernets_only, int type, + u_short ospf_instance_id) +{ + struct route_table *table; + struct zebra_vrf *zvrf = NULL; + + if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) { + if (use_json) + vty_out(vty, "{}\n"); + else + vty_out(vty, "vrf %s not defined\n", vrf_name); + return CMD_SUCCESS; + } + + if (zvrf_id(zvrf) == VRF_UNKNOWN) { + if (use_json) + vty_out(vty, "{}\n"); + else + vty_out(vty, "vrf %s inactive\n", vrf_name); + return CMD_SUCCESS; + } + + table = zebra_vrf_table(afi, safi, zvrf_id(zvrf)); + if (!table) { + if (use_json) + vty_out(vty, "{}\n"); + return CMD_SUCCESS; + } + + do_show_route_helper(vty, zvrf, table, afi, use_fib, tag, + longer_prefix_p, supernets_only, type, + ospf_instance_id, use_json); + + return CMD_SUCCESS; +} + +DEFPY (show_route_table, + show_route_table_cmd, + "show route table (1-4294967295)$table [json$json]", + SHOW_STR + IP_STR + IP6_STR + "IP routing table\n" + "Table to display\n" + "The table number to display, if available\n" + JSON_STR) +{ + afi_t afi = ipv4 ? AFI_IP : AFI_IP6; + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + struct route_table *t; + + t = zebra_ns_find_table(zvrf->zns, table, afi); + if (t) + do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false, + 0, 0, !!json); return CMD_SUCCESS; } @@ -3341,6 +3377,7 @@ void zebra_vty_init(void) install_element(VIEW_NODE, &show_vrf_cmd); install_element(VIEW_NODE, &show_vrf_vni_cmd); install_element(VIEW_NODE, &show_route_cmd); + install_element(VIEW_NODE, &show_route_table_cmd); install_element(VIEW_NODE, &show_route_detail_cmd); install_element(VIEW_NODE, &show_route_summary_cmd); install_element(VIEW_NODE, &show_ip_nht_cmd);