From 46e6bac7eb8500ffcb6bcef38dea04d6f5148818 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Mon, 24 Oct 2016 21:53:37 -0200 Subject: [PATCH 01/20] bgpd: use loops to reduce code duplication Signed-off-by: Renato Westphal --- bgpd/bgp_nexthop.c | 51 +++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 6c30fefae5..46ccd06c4b 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -554,17 +554,14 @@ DEFUN (show_ip_bgp_instance_nexthop_detail, void bgp_scan_init (struct bgp *bgp) { - bgp->nexthop_cache_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST); - bgp->connected_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST); - bgp->import_check_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST); + afi_t afi; - bgp->nexthop_cache_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST); - bgp->connected_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST); - bgp->import_check_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST); - - bgp->nexthop_cache_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST); - bgp->connected_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST); - bgp->import_check_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST); + for (afi = AFI_IP; afi < AFI_MAX; afi++) + { + bgp->nexthop_cache_table[afi] = bgp_table_init (afi, SAFI_UNICAST); + bgp->connected_table[afi] = bgp_table_init (afi, SAFI_UNICAST); + bgp->import_check_table[afi] = bgp_table_init (afi, SAFI_UNICAST); + } } void @@ -580,29 +577,19 @@ bgp_scan_vty_init (void) void bgp_scan_finish (struct bgp *bgp) { - /* Only the current one needs to be reset. */ - bgp_nexthop_cache_reset (bgp->nexthop_cache_table[AFI_IP]); + afi_t afi; - bgp_table_unlock (bgp->nexthop_cache_table[AFI_IP]); - bgp->nexthop_cache_table[AFI_IP] = NULL; + for (afi = AFI_IP; afi < AFI_MAX; afi++) + { + /* Only the current one needs to be reset. */ + bgp_nexthop_cache_reset (bgp->nexthop_cache_table[afi]); + bgp_table_unlock (bgp->nexthop_cache_table[afi]); + bgp->nexthop_cache_table[afi] = NULL; - bgp_table_unlock (bgp->connected_table[AFI_IP]); - bgp->connected_table[AFI_IP] = NULL; + bgp_table_unlock (bgp->connected_table[afi]); + bgp->connected_table[afi] = NULL; - bgp_table_unlock (bgp->import_check_table[AFI_IP]); - bgp->import_check_table[AFI_IP] = NULL; - -#ifdef HAVE_IPV6 - /* Only the current one needs to be reset. */ - bgp_nexthop_cache_reset (bgp->nexthop_cache_table[AFI_IP6]); - - bgp_table_unlock (bgp->nexthop_cache_table[AFI_IP6]); - bgp->nexthop_cache_table[AFI_IP6] = NULL; - - bgp_table_unlock (bgp->connected_table[AFI_IP6]); - bgp->connected_table[AFI_IP6] = NULL; - - bgp_table_unlock (bgp->import_check_table[AFI_IP6]); - bgp->import_check_table[AFI_IP6] = NULL; -#endif /* HAVE_IPV6 */ + bgp_table_unlock (bgp->import_check_table[afi]); + bgp->import_check_table[afi] = NULL; + } } From 658bbf6d704a776495dd7914c45efc399f03da52 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 1 Nov 2016 07:37:50 -0200 Subject: [PATCH 02/20] bgpd: optimize copy of strings on peer_xfer_conn() Signed-off-by: Renato Westphal --- bgpd/bgp_fsm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index ab4ea71d61..e669b4f9b7 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -171,8 +171,7 @@ peer_xfer_conn(struct peer *from_peer) peer->hostname = NULL; } - peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, from_peer->hostname); - XFREE(MTYPE_BGP_PEER_HOST, from_peer->hostname); + peer->hostname = from_peer->hostname; from_peer->hostname = NULL; } @@ -184,8 +183,7 @@ peer_xfer_conn(struct peer *from_peer) peer->domainname= NULL; } - peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, from_peer->domainname); - XFREE(MTYPE_BGP_PEER_HOST, from_peer->domainname); + peer->domainname = from_peer->domainname; from_peer->domainname = NULL; } From 235022cbaaf6873f0b745c0e4c5844e5343b824f Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 2 Nov 2016 00:29:46 -0200 Subject: [PATCH 03/20] bgpd: reuse sockunion2hostprefix() on bgp_nht.c Signed-off-by: Renato Westphal --- bgpd/bgp_nht.c | 54 +++++++++----------------------------------------- 1 file changed, 9 insertions(+), 45 deletions(-) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 9aae3e7b33..1ca0483678 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -115,19 +115,7 @@ bgp_unlink_nexthop_by_peer (struct peer *peer) struct bgp_nexthop_cache *bnc; afi_t afi = family2afi(peer->su.sa.sa_family); - if (afi == AFI_IP) - { - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - p.u.prefix4 = peer->su.sin.sin_addr; - } - else if (afi == AFI_IP6) - { - p.family = AF_INET6; - p.prefixlen = IPV6_MAX_BITLEN; - p.u.prefix6 = peer->su.sin6.sin6_addr; - } - else + if (! sockunion2hostprefix (&peer->su, &p)) return; rn = bgp_node_get (peer->bgp->nexthop_cache_table[afi], &p); @@ -168,23 +156,11 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri, } else if (peer) { - if (afi == AFI_IP) - { - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - p.u.prefix4 = peer->su.sin.sin_addr; - } - else if (afi == AFI_IP6) - { - p.family = AF_INET6; - p.prefixlen = IPV6_MAX_BITLEN; - p.u.prefix6 = peer->su.sin6.sin6_addr; + /* Don't register link local NH */ + if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&peer->su.sin6.sin6_addr)) + return 1; - /* Don't register link local NH */ - if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) - return 1; - } - else + if (! sockunion2hostprefix (&peer->su, &p)) { if (BGP_DEBUG(nht, NHT)) { @@ -297,23 +273,11 @@ bgp_delete_connected_nexthop (afi_t afi, struct peer *peer) if (!peer) return; - if (afi == AFI_IP) - { - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - p.u.prefix4 = peer->su.sin.sin_addr; - } - else if (afi == AFI_IP6) - { - p.family = AF_INET6; - p.prefixlen = IPV6_MAX_BITLEN; - p.u.prefix6 = peer->su.sin6.sin6_addr; + /* We don't register link local address for NHT */ + if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&peer->su.sin6.sin6_addr)) + return; - /* We don't register link local address for NHT */ - if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) - return; - } - else + if (! sockunion2hostprefix (&peer->su, &p)) return; rn = bgp_node_lookup(peer->bgp->nexthop_cache_table[family2afi(p.family)], &p); From 37d361e7fd6b35dc4badd7e0124e2f49c4ac9e5e Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 21 Oct 2016 20:13:51 -0200 Subject: [PATCH 04/20] bgpd: plug several memleaks Signed-off-by: Renato Westphal --- bgpd/bgp_nexthop.c | 8 +++++++- bgpd/bgp_zebra.c | 1 + bgpd/bgpd.c | 20 ++++++++++++-------- tests/bgp_mpath_test.c | 2 ++ 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 46ccd06c4b..2d3d8e6a65 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -113,6 +113,12 @@ bgp_address_hash_alloc (void *p) return addr; } +static void +bgp_address_hash_free (void *addr) +{ + XFREE (MTYPE_BGP_ADDR, addr); +} + static unsigned int bgp_address_hash_key_make (void *p) { @@ -142,7 +148,7 @@ bgp_address_destroy (struct bgp *bgp) { if (bgp->address_hash == NULL) return; - hash_clean(bgp->address_hash, NULL); + hash_clean(bgp->address_hash, bgp_address_hash_free); hash_free(bgp->address_hash); bgp->address_hash = NULL; } diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 8ecd025397..3d3bd90f5b 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1792,6 +1792,7 @@ bgp_redist_del (struct bgp *bgp, afi_t afi, u_char type, u_short instance) if (red) { listnode_delete(bgp->redist[afi][type], red); + XFREE (MTYPE_BGP_REDIST, red); if (!bgp->redist[afi][type]->count) { list_free(bgp->redist[afi][type]); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 3ddb465a75..a786271541 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1047,6 +1047,12 @@ peer_free (struct peer *peer) peer->host = NULL; } + if (peer->domainname) + { + XFREE (MTYPE_BGP_PEER_HOST, peer->domainname); + peer->domainname = NULL; + } + if (peer->ifname) { XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname); @@ -3123,6 +3129,7 @@ bgp_delete (struct bgp *bgp) struct peer *peer; struct peer_group *group; struct listnode *node, *next; + struct vrf *vrf; afi_t afi; int i; @@ -3186,8 +3193,6 @@ bgp_delete (struct bgp *bgp) * routes to be processed still referencing the struct bgp. */ listnode_delete (bm->bgp, bgp); - if (list_isempty(bm->bgp)) - bgp_close (); /* Deregister from Zebra, if needed */ if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) @@ -3196,6 +3201,10 @@ bgp_delete (struct bgp *bgp) /* Free interfaces in this instance. */ bgp_if_finish (bgp); + vrf = bgp_vrf_lookup_by_instance_type (bgp); + if (vrf) + bgp_vrf_unlink (bgp, vrf); + thread_master_free_unused(bm->master); bgp_unlock(bgp); /* initial reference */ @@ -3223,7 +3232,6 @@ bgp_free (struct bgp *bgp) { afi_t afi; safi_t safi; - struct vrf *vrf; list_delete (bgp->group); list_delete (bgp->peer); @@ -3245,13 +3253,9 @@ bgp_free (struct bgp *bgp) bgp_table_finish (&bgp->rib[afi][safi]); } + bgp_scan_finish (bgp); bgp_address_destroy (bgp); - /* If Default instance or VRF, unlink from the VRF structure. */ - vrf = bgp_vrf_lookup_by_instance_type (bgp); - if (vrf) - bgp_vrf_unlink (bgp, vrf); - if (bgp->name) XFREE(MTYPE_BGP, bgp->name); diff --git a/tests/bgp_mpath_test.c b/tests/bgp_mpath_test.c index dbcb00a2ef..723f2977d5 100644 --- a/tests/bgp_mpath_test.c +++ b/tests/bgp_mpath_test.c @@ -37,6 +37,7 @@ #include "bgpd/bgp_table.h" #include "bgpd/bgp_route.h" #include "bgpd/bgp_attr.h" +#include "bgpd/bgp_nexthop.h" #include "bgpd/bgp_mpath.h" #define VT100_RESET "\x1b[0m" @@ -116,6 +117,7 @@ bgp_create_fake (as_t *as, const char *name) bgp->maxpaths[afi][safi].maxpaths_ibgp = MULTIPATH_NUM; } + bgp_scan_init (bgp); bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF; bgp->default_holdtime = BGP_DEFAULT_HOLDTIME; bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE; From 0c6262ed6a2941c063aa2cf40107ef6b45d8628a Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 25 Oct 2016 00:04:24 -0200 Subject: [PATCH 05/20] bgpd: release all memory explicitly on exit --- bgpd/bgp_route.c | 94 +++++++++++++++++++++++++----------------------- bgpd/bgp_route.h | 2 +- bgpd/bgpd.c | 4 +-- 3 files changed, 51 insertions(+), 49 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 57e38ce10c..b23a52e1df 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3123,7 +3123,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi, struct bgp_table *table) { struct bgp_node *rn; - + int force = bm->process_main_queue ? 0 : 1; if (! table) table = peer->bgp->rib[afi][safi]; @@ -3134,7 +3134,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi, for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) { - struct bgp_info *ri; + struct bgp_info *ri, *next; struct bgp_adj_in *ain; struct bgp_adj_in *ain_next; @@ -3186,20 +3186,28 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi, ain = ain_next; } - for (ri = rn->info; ri; ri = ri->next) - if (ri->peer == peer) - { - struct bgp_clear_node_queue *cnq; + for (ri = rn->info; ri; ri = next) + { + next = ri->next; + if (ri->peer != peer) + continue; - /* both unlocked in bgp_clear_node_queue_del */ - bgp_table_lock (bgp_node_table (rn)); - bgp_lock_node (rn); - cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE, - sizeof (struct bgp_clear_node_queue)); - cnq->rn = rn; - work_queue_add (peer->clear_node_queue, cnq); - break; - } + if (force) + bgp_info_reap (rn, ri); + else + { + struct bgp_clear_node_queue *cnq; + + /* both unlocked in bgp_clear_node_queue_del */ + bgp_table_lock (bgp_node_table (rn)); + bgp_lock_node (rn); + cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE, + sizeof (struct bgp_clear_node_queue)); + cnq->rn = rn; + work_queue_add (peer->clear_node_queue, cnq); + break; + } + } } return; } @@ -3336,51 +3344,47 @@ bgp_cleanup_table(struct bgp_table *table, safi_t safi) vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri); #endif bgp_zebra_withdraw (&rn->p, ri, safi); + bgp_info_reap (rn, ri); } } } /* Delete all kernel routes. */ void -bgp_cleanup_routes (void) +bgp_cleanup_routes (struct bgp *bgp) { - struct bgp *bgp; - struct listnode *node, *nnode; afi_t afi; - for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp)) + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - for (afi = AFI_IP; afi < AFI_MAX; ++afi) + struct bgp_node *rn; + + bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST); + + /* + * VPN and ENCAP tables are two-level (RD is top level) + */ + for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn; + rn = bgp_route_next (rn)) { - struct bgp_node *rn; - - bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST); - - /* - * VPN and ENCAP tables are two-level (RD is top level) - */ - for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn; - rn = bgp_route_next (rn)) + if (rn->info) { - if (rn->info) - { - bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_MPLS_VPN); - bgp_table_finish ((struct bgp_table **)&(rn->info)); - rn->info = NULL; - bgp_unlock_node(rn); - } + bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_MPLS_VPN); + bgp_table_finish ((struct bgp_table **)&(rn->info)); + rn->info = NULL; + bgp_unlock_node(rn); } + } - for (rn = bgp_table_top(bgp->rib[afi][SAFI_ENCAP]); rn; - rn = bgp_route_next (rn)) + for (rn = bgp_table_top(bgp->rib[afi][SAFI_ENCAP]); rn; + rn = bgp_route_next (rn)) + { + if (rn->info) { - if (rn->info) - { - bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_ENCAP); - bgp_table_finish ((struct bgp_table **)&(rn->info)); - rn->info = NULL; - bgp_unlock_node(rn); - } + bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_ENCAP); + bgp_table_finish ((struct bgp_table **)&(rn->info)); + rn->info = NULL; + bgp_unlock_node(rn); } } } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 6bd54aba13..63b18aa2d8 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -241,7 +241,7 @@ bgp_bump_version (struct bgp_node *node) extern void bgp_process_queue_init (void); extern void bgp_route_init (void); extern void bgp_route_finish (void); -extern void bgp_cleanup_routes (void); +extern void bgp_cleanup_routes (struct bgp *); extern void bgp_announce_route (struct peer *, afi_t, safi_t); extern void bgp_stop_announce_route_timer(struct peer_af *paf); extern void bgp_announce_route_all (struct peer *); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index a786271541..53258880ab 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3186,8 +3186,8 @@ bgp_delete (struct bgp *bgp) #if ENABLE_BGP_VNC rfapi_delete(bgp); - bgp_cleanup_routes(); /* rfapi cleanup can create route entries! */ #endif + bgp_cleanup_routes(bgp); /* Remove visibility via the master list - there may however still be * routes to be processed still referencing the struct bgp. @@ -7601,8 +7601,6 @@ bgp_terminate (void) bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); - bgp_cleanup_routes (); - if (bm->process_main_queue) { work_queue_free (bm->process_main_queue); From 58ac32e2d598b5dc45fa05b7a8a85b107571d697 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 1 Nov 2016 18:57:53 -0200 Subject: [PATCH 06/20] zebra/lib: plug several memleaks Signed-off-by: Renato Westphal --- lib/command.c | 2 ++ lib/qobj.c | 1 + lib/table.c | 4 ++-- lib/table.h | 5 +++++ zebra/interface.c | 16 +++++++++++++++- zebra/main.c | 12 ++++++++++++ zebra/zebra_memory.h | 1 - zebra/zebra_mpls.c | 10 ++++++---- zebra/zebra_ns.c | 13 +++++-------- zebra/zebra_ns.h | 2 +- zebra/zebra_ptm.c | 2 ++ 11 files changed, 51 insertions(+), 17 deletions(-) diff --git a/lib/command.c b/lib/command.c index e8ba637623..acfcf68576 100644 --- a/lib/command.c +++ b/lib/command.c @@ -4436,4 +4436,6 @@ cmd_terminate () XFREE (MTYPE_HOST, host.motdfile); if (host.config) XFREE (MTYPE_HOST, host.config); + + qobj_finish (); } diff --git a/lib/qobj.c b/lib/qobj.c index 65b537f961..f64972e32a 100644 --- a/lib/qobj.c +++ b/lib/qobj.c @@ -78,6 +78,7 @@ void qobj_init (void) void qobj_finish (void) { + hash_clean (nodes, NULL); hash_free (nodes); nodes = NULL; } diff --git a/lib/table.c b/lib/table.c index d0e084ead2..5133ef6974 100644 --- a/lib/table.c +++ b/lib/table.c @@ -494,7 +494,7 @@ route_table_count (const struct route_table *table) * * Default function for creating a route node. */ -static struct route_node * +struct route_node * route_node_create (route_table_delegate_t *delegate, struct route_table *table) { @@ -508,7 +508,7 @@ route_node_create (route_table_delegate_t *delegate, * * Default function for destroying a route node. */ -static void +void route_node_destroy (route_table_delegate_t *delegate, struct route_table *table, struct route_node *node) { diff --git a/lib/table.h b/lib/table.h index e6cdcfef1e..78bf5da748 100644 --- a/lib/table.h +++ b/lib/table.h @@ -169,6 +169,11 @@ extern struct route_node *route_node_match_ipv6 (const struct route_table *, extern unsigned long route_table_count (const struct route_table *); +extern struct route_node *route_node_create (route_table_delegate_t *, + struct route_table *); +extern void route_node_destroy (route_table_delegate_t *, + struct route_table *, struct route_node *); + extern struct route_node * route_table_get_next (const struct route_table *table, struct prefix *p); extern int diff --git a/zebra/interface.c b/zebra/interface.c index b87f61f920..422368852d 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -59,6 +59,20 @@ const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 }; static void if_down_del_nbr_connected (struct interface *ifp); +static void +zebra_if_node_destroy (route_table_delegate_t *delegate, + struct route_table *table, struct route_node *node) +{ + if (node->info) + list_delete (node->info); + route_node_destroy (delegate, table, node); +} + +route_table_delegate_t zebra_if_table_delegate = { + .create_node = route_node_create, + .destroy_node = zebra_if_node_destroy +}; + /* Called when new interface is added. */ static int if_zebra_new_hook (struct interface *ifp) @@ -101,7 +115,7 @@ if_zebra_new_hook (struct interface *ifp) #endif /* HAVE_RTADV */ /* Initialize installed address chains tree. */ - zebra_if->ipv4_subnets = route_table_init (); + zebra_if->ipv4_subnets = route_table_init_with_delegate (&zebra_if_table_delegate); ifp->info = zebra_if; diff --git a/zebra/main.c b/zebra/main.c index 9247d43507..1b41f8deff 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -196,6 +196,18 @@ sigint (void) zns = zebra_ns_lookup (NS_DEFAULT); zebra_ns_disable (0, (void **)&zns); + + access_list_reset (); + prefix_list_reset (); + route_map_finish (); + cmd_terminate (); + vty_terminate (); + zprivs_terminate (&zserv_privs); + list_delete (zebrad.client_list); + thread_master_free (zebrad.master); + if (zlog_default) + closezlog (zlog_default); + exit (0); } diff --git a/zebra/zebra_memory.h b/zebra/zebra_memory.h index fbd8f3261d..c1ac4fe955 100644 --- a/zebra/zebra_memory.h +++ b/zebra/zebra_memory.h @@ -35,6 +35,5 @@ DECLARE_MTYPE(STATIC_ROUTE) DECLARE_MTYPE(RIB_DEST) DECLARE_MTYPE(RIB_TABLE_INFO) DECLARE_MTYPE(RNH) -DECLARE_MTYPE(NETLINK_NAME) #endif /* _QUAGGA_ZEBRA_MEMORY_H */ diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 15e5c330e4..b64cab625d 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -1829,7 +1829,7 @@ zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf, vty_out (vty, "%s", VTY_NEWLINE); } - list_delete_all_node(lsp_list); + list_delete (lsp_list); } /* @@ -1869,7 +1869,7 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf) } } - list_delete_all_node(slsp_list); + list_delete (slsp_list); return (zvrf->slsp_table->count ? 1 : 0); } @@ -1881,9 +1881,11 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf) void zebra_mpls_close_tables (struct zebra_vrf *zvrf) { - if (!zvrf) - return; hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL); + hash_clean(zvrf->lsp_table, NULL); + hash_free(zvrf->lsp_table); + hash_clean(zvrf->slsp_table, NULL); + hash_free(zvrf->slsp_table); } /* diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 41034e1980..4499901021 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -32,7 +32,6 @@ #include "zebra_memory.h" DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space") -DEFINE_MTYPE(ZEBRA, NETLINK_NAME, "Netlink name") struct zebra_ns *dzns; @@ -46,9 +45,6 @@ int zebra_ns_enable (ns_id_t ns_id, void **info) { struct zebra_ns *zns = (struct zebra_ns *) (*info); -#ifdef HAVE_NETLINK - char nl_name[64]; -#endif #if defined (HAVE_RTADV) rtadv_init (zns); @@ -56,13 +52,13 @@ zebra_ns_enable (ns_id_t ns_id, void **info) #ifdef HAVE_NETLINK /* Initialize netlink sockets */ - snprintf (nl_name, 64, "netlink-listen (NS %u)", ns_id); + snprintf (zns->netlink.name, sizeof (zns->netlink.name), + "netlink-listen (NS %u)", ns_id); zns->netlink.sock = -1; - zns->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name); - snprintf (nl_name, 64, "netlink-cmd (NS %u)", ns_id); + snprintf (zns->netlink_cmd.name, sizeof (zns->netlink_cmd.name), + "netlink-cmd (NS %u)", ns_id); zns->netlink_cmd.sock = -1; - zns->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name); #endif zns->if_table = route_table_init (); kernel_init (zns); @@ -77,6 +73,7 @@ zebra_ns_disable (ns_id_t ns_id, void **info) { struct zebra_ns *zns = (struct zebra_ns *) (*info); + route_table_finish (zns->if_table); #if defined (HAVE_RTADV) rtadv_terminate (zns); #endif diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h index 8a821c465a..c50f9249d2 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -32,7 +32,7 @@ struct nlsock int sock; int seq; struct sockaddr_nl snl; - const char *name; + char name[64]; }; #endif diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index ebae1bd4b9..28e6c42ec6 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -140,6 +140,8 @@ zebra_ptm_finish(void) buffer_flush_all(ptm_cb.wb, ptm_cb.ptm_sock); + free (ptm_hdl); + if (ptm_cb.out_data) free(ptm_cb.out_data); From 1fbe3e585ddb0a1c16a870b8112b145732549f45 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 26 Oct 2016 12:58:32 -0200 Subject: [PATCH 07/20] lib: remove unused ns code Signed-off-by: Renato Westphal --- lib/ns.c | 211 ------------------------------------------------------- lib/ns.h | 74 +------------------ 2 files changed, 1 insertion(+), 284 deletions(-) diff --git a/lib/ns.c b/lib/ns.c index 556350ed17..07e6ec5b9a 100644 --- a/lib/ns.c +++ b/lib/ns.c @@ -310,217 +310,6 @@ ns_add_hook (int type, int (*func)(ns_id_t, void **)) } } -/* Return the iterator of the first NS. */ -ns_iter_t -ns_first (void) -{ - struct route_node *rn; - - for (rn = route_top (ns_table); rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* top/next */ - return (ns_iter_t)rn; - } - return NS_ITER_INVALID; -} - -/* Return the next NS iterator to the given iterator. */ -ns_iter_t -ns_next (ns_iter_t iter) -{ - struct route_node *rn = NULL; - - /* Lock it first because route_next() will unlock it. */ - if (iter != NS_ITER_INVALID) - rn = route_next (route_lock_node ((struct route_node *)iter)); - - for (; rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* next */ - return (ns_iter_t)rn; - } - return NS_ITER_INVALID; -} - -/* Return the NS iterator of the given NS ID. If it does not exist, - * the iterator of the next existing NS is returned. */ -ns_iter_t -ns_iterator (ns_id_t ns_id) -{ - struct prefix p; - struct route_node *rn; - - ns_build_key (ns_id, &p); - rn = route_node_get (ns_table, &p); - if (rn->info) - { - /* OK, the NS exists. */ - route_unlock_node (rn); /* get */ - return (ns_iter_t)rn; - } - - /* Find the next NS. */ - for (rn = route_next (rn); rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* next */ - return (ns_iter_t)rn; - } - - return NS_ITER_INVALID; -} - -/* Obtain the NS ID from the given NS iterator. */ -ns_id_t -ns_iter2id (ns_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct ns *)rn->info)->ns_id : NS_DEFAULT; -} - -/* Obtain the data pointer from the given NS iterator. */ -void * -ns_iter2info (ns_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct ns *)rn->info)->info : NULL; -} - -/* Obtain the interface list from the given NS iterator. */ -struct list * -ns_iter2iflist (ns_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct ns *)rn->info)->iflist : NULL; -} - -/* Get the data pointer of the specified NS. If not found, create one. */ -void * -ns_info_get (ns_id_t ns_id) -{ - struct ns *ns = ns_get (ns_id); - return ns->info; -} - -/* Look up the data pointer of the specified NS. */ -void * -ns_info_lookup (ns_id_t ns_id) -{ - struct ns *ns = ns_lookup (ns_id); - return ns ? ns->info : NULL; -} - -/* Look up the interface list in a NS. */ -struct list * -ns_iflist (ns_id_t ns_id) -{ - struct ns * ns = ns_lookup (ns_id); - return ns ? ns->iflist : NULL; -} - -/* Get the interface list of the specified NS. Create one if not find. */ -struct list * -ns_iflist_get (ns_id_t ns_id) -{ - struct ns * ns = ns_get (ns_id); - return ns->iflist; -} - -/* - * NS bit-map - */ - -#define NS_BITMAP_NUM_OF_GROUPS 8 -#define NS_BITMAP_NUM_OF_BITS_IN_GROUP \ - (UINT16_MAX / NS_BITMAP_NUM_OF_GROUPS) -#define NS_BITMAP_NUM_OF_BYTES_IN_GROUP \ - (NS_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */ - -#define NS_BITMAP_GROUP(_id) \ - ((_id) / NS_BITMAP_NUM_OF_BITS_IN_GROUP) -#define NS_BITMAP_BIT_OFFSET(_id) \ - ((_id) % NS_BITMAP_NUM_OF_BITS_IN_GROUP) - -#define NS_BITMAP_INDEX_IN_GROUP(_bit_offset) \ - ((_bit_offset) / CHAR_BIT) -#define NS_BITMAP_FLAG(_bit_offset) \ - (((u_char)1) << ((_bit_offset) % CHAR_BIT)) - -struct ns_bitmap -{ - u_char *groups[NS_BITMAP_NUM_OF_GROUPS]; -}; - -ns_bitmap_t -ns_bitmap_init (void) -{ - return (ns_bitmap_t) XCALLOC (MTYPE_NS_BITMAP, sizeof (struct ns_bitmap)); -} - -void -ns_bitmap_free (ns_bitmap_t bmap) -{ - struct ns_bitmap *bm = (struct ns_bitmap *) bmap; - int i; - - if (bmap == NS_BITMAP_NULL) - return; - - for (i = 0; i < NS_BITMAP_NUM_OF_GROUPS; i++) - if (bm->groups[i]) - XFREE (MTYPE_NS_BITMAP, bm->groups[i]); - - XFREE (MTYPE_NS_BITMAP, bm); -} - -void -ns_bitmap_set (ns_bitmap_t bmap, ns_id_t ns_id) -{ - struct ns_bitmap *bm = (struct ns_bitmap *) bmap; - u_char group = NS_BITMAP_GROUP (ns_id); - u_char offset = NS_BITMAP_BIT_OFFSET (ns_id); - - if (bmap == NS_BITMAP_NULL) - return; - - if (bm->groups[group] == NULL) - bm->groups[group] = XCALLOC (MTYPE_NS_BITMAP, - NS_BITMAP_NUM_OF_BYTES_IN_GROUP); - - SET_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)], - NS_BITMAP_FLAG (offset)); -} - -void -ns_bitmap_unset (ns_bitmap_t bmap, ns_id_t ns_id) -{ - struct ns_bitmap *bm = (struct ns_bitmap *) bmap; - u_char group = NS_BITMAP_GROUP (ns_id); - u_char offset = NS_BITMAP_BIT_OFFSET (ns_id); - - if (bmap == NS_BITMAP_NULL || bm->groups[group] == NULL) - return; - - UNSET_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)], - NS_BITMAP_FLAG (offset)); -} - -int -ns_bitmap_check (ns_bitmap_t bmap, ns_id_t ns_id) -{ - struct ns_bitmap *bm = (struct ns_bitmap *) bmap; - u_char group = NS_BITMAP_GROUP (ns_id); - u_char offset = NS_BITMAP_BIT_OFFSET (ns_id); - - if (bmap == NS_BITMAP_NULL || bm->groups[group] == NULL) - return 0; - - return CHECK_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)], - NS_BITMAP_FLAG (offset)) ? 1 : 0; -} - /* * NS realization with NETNS */ diff --git a/lib/ns.h b/lib/ns.h index 3fac739861..c96f1b2743 100644 --- a/lib/ns.h +++ b/lib/ns.h @@ -30,15 +30,8 @@ typedef u_int16_t ns_id_t; /* The default NS ID */ #define NS_DEFAULT 0 -/* - * The command strings - */ +/* Default netns directory (Linux) */ #define NS_RUN_DIR "/var/run/netns" -#define NS_CMD_STR "logical-router <0-65535>" -#define NS_CMD_HELP_STR "Specify the Logical-Router\nThe Logical-Router ID\n" - -#define NS_ALL_CMD_STR "logical-router all" -#define NS_ALL_CMD_HELP_STR "Specify the logical-router\nAll logical-router's\n" /* * NS hooks @@ -59,71 +52,6 @@ typedef u_int16_t ns_id_t; */ extern void ns_add_hook (int, int (*)(ns_id_t, void **)); -/* - * NS iteration - */ - -typedef void * ns_iter_t; -#define NS_ITER_INVALID NULL /* invalid value of the iterator */ - -/* - * NS iteration utilities. Example for the usage: - * - * ns_iter_t iter = ns_first(); - * for (; iter != NS_ITER_INVALID; iter = ns_next (iter)) - * - * or - * - * ns_iter_t iter = ns_iterator (); - * for (; iter != NS_ITER_INVALID; iter = ns_next (iter)) - */ - -/* Return the iterator of the first NS. */ -extern ns_iter_t ns_first (void); -/* Return the next NS iterator to the given iterator. */ -extern ns_iter_t ns_next (ns_iter_t); -/* Return the NS iterator of the given NS ID. If it does not exist, - * the iterator of the next existing NS is returned. */ -extern ns_iter_t ns_iterator (ns_id_t); - -/* - * NS iterator to properties - */ -extern ns_id_t ns_iter2id (ns_iter_t); -extern void *ns_iter2info (ns_iter_t); -extern struct list *ns_iter2iflist (ns_iter_t); - -/* - * Utilities to obtain the user data - */ - -/* Get the data pointer of the specified NS. If not found, create one. */ -extern void *ns_info_get (ns_id_t); -/* Look up the data pointer of the specified NS. */ -extern void *ns_info_lookup (ns_id_t); - -/* - * Utilities to obtain the interface list - */ - -/* Look up the interface list of the specified NS. */ -extern struct list *ns_iflist (ns_id_t); -/* Get the interface list of the specified NS. Create one if not find. */ -extern struct list *ns_iflist_get (ns_id_t); - -/* - * NS bit-map: maintaining flags, one bit per NS ID - */ - -typedef void * ns_bitmap_t; -#define NS_BITMAP_NULL NULL - -extern ns_bitmap_t ns_bitmap_init (void); -extern void ns_bitmap_free (ns_bitmap_t); -extern void ns_bitmap_set (ns_bitmap_t, ns_id_t); -extern void ns_bitmap_unset (ns_bitmap_t, ns_id_t); -extern int ns_bitmap_check (ns_bitmap_t, ns_id_t); - /* * NS initializer/destructor */ From f30c50b99223be343b7fe1ae9e374602ec0d93d5 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 28 Oct 2016 22:32:07 -0200 Subject: [PATCH 08/20] zebra/lib: move some code around * move netlink code from zebra_nc.c to kernel_netlink.c; * move vrf CLI commands from if.c/interface.c to vrf.c/zebra_vrf.c; * move declaration of the 'ns' structure to a header file. Signed-off-by: Renato Westphal --- lib/if.c | 54 ------------------------------------------ lib/ns.c | 16 ------------- lib/ns.h | 16 +++++++++++++ lib/vrf.c | 54 ++++++++++++++++++++++++++++++++++++++++++ zebra/interface.c | 49 -------------------------------------- zebra/kernel_netlink.c | 15 ++++++++---- zebra/zebra_ns.c | 10 -------- zebra/zebra_vrf.c | 50 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 131 insertions(+), 133 deletions(-) diff --git a/lib/if.c b/lib/if.c index 6ae8500291..70304e584c 100644 --- a/lib/if.c +++ b/lib/if.c @@ -840,60 +840,6 @@ ALIAS (no_interface, "Interface's name\n" VRF_CMD_HELP_STR) -DEFUN (vrf, - vrf_cmd, - "vrf NAME", - "Select a VRF to configure\n" - "VRF's name\n") -{ - struct vrf *vrfp; - size_t sl; - - if ((sl = strlen(argv[0])) > VRF_NAMSIZ) - { - vty_out (vty, "%% VRF name %s is invalid: length exceeds " - "%d characters%s", - argv[0], VRF_NAMSIZ, VTY_NEWLINE); - return CMD_WARNING; - } - - vrfp = vrf_get (VRF_UNKNOWN, argv[0]); - - VTY_PUSH_CONTEXT_COMPAT (VRF_NODE, vrfp); - - return CMD_SUCCESS; -} - -DEFUN_NOSH (no_vrf, - no_vrf_cmd, - "no vrf NAME", - NO_STR - "Delete a pseudo VRF's configuration\n" - "VRF's name\n") -{ - struct vrf *vrfp; - - vrfp = vrf_list_lookup_by_name (argv[0]); - - if (vrfp == NULL) - { - vty_out (vty, "%% VRF %s does not exist%s", argv[0], VTY_NEWLINE); - return CMD_WARNING; - } - - if (CHECK_FLAG (vrfp->status, VRF_ACTIVE)) - { - vty_out (vty, "%% Only inactive VRFs can be deleted%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - vrf_delete(vrfp); - - return CMD_SUCCESS; -} - - /* For debug purpose. */ DEFUN (show_address, show_address_cmd, diff --git a/lib/ns.c b/lib/ns.c index 07e6ec5b9a..904fc6999c 100644 --- a/lib/ns.c +++ b/lib/ns.c @@ -91,22 +91,6 @@ static int have_netns(void) #endif } -struct ns -{ - /* Identifier, same as the vector index */ - ns_id_t ns_id; - /* Name */ - char *name; - /* File descriptor */ - int fd; - - /* Master list of interfaces belonging to this NS */ - struct list *iflist; - - /* User data */ - void *info; -}; - /* Holding NS hooks */ struct ns_master { diff --git a/lib/ns.h b/lib/ns.h index c96f1b2743..74616cd62f 100644 --- a/lib/ns.h +++ b/lib/ns.h @@ -33,6 +33,22 @@ typedef u_int16_t ns_id_t; /* Default netns directory (Linux) */ #define NS_RUN_DIR "/var/run/netns" +struct ns +{ + /* Identifier, same as the vector index */ + ns_id_t ns_id; + /* Name */ + char *name; + /* File descriptor */ + int fd; + + /* Master list of interfaces belonging to this NS */ + struct list *iflist; + + /* User data */ + void *info; +}; + /* * NS hooks */ diff --git a/lib/vrf.c b/lib/vrf.c index 63adea4aec..d87e38ebe8 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -740,6 +740,60 @@ vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id) return ret; } +/* vrf CLI commands */ +DEFUN (vrf, + vrf_cmd, + "vrf NAME", + "Select a VRF to configure\n" + "VRF's name\n") +{ + struct vrf *vrfp; + size_t sl; + + if ((sl = strlen(argv[0])) > VRF_NAMSIZ) + { + vty_out (vty, "%% VRF name %s is invalid: length exceeds " + "%d characters%s", + argv[0], VRF_NAMSIZ, VTY_NEWLINE); + return CMD_WARNING; + } + + vrfp = vrf_get (VRF_UNKNOWN, argv[0]); + + VTY_PUSH_CONTEXT_COMPAT (VRF_NODE, vrfp); + + return CMD_SUCCESS; +} + +DEFUN_NOSH (no_vrf, + no_vrf_cmd, + "no vrf NAME", + NO_STR + "Delete a pseudo VRF's configuration\n" + "VRF's name\n") +{ + struct vrf *vrfp; + + vrfp = vrf_list_lookup_by_name (argv[0]); + + if (vrfp == NULL) + { + vty_out (vty, "%% VRF %s does not exist%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + if (CHECK_FLAG (vrfp->status, VRF_ACTIVE)) + { + vty_out (vty, "%% Only inactive VRFs can be deleted%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + vrf_delete(vrfp); + + return CMD_SUCCESS; +} + /* * Debug CLI for vrf's */ diff --git a/zebra/interface.c b/zebra/interface.c index 422368852d..dd1f8a146b 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1289,33 +1289,6 @@ struct cmd_node interface_node = 1 }; -/* Wrapper hook point for zebra daemon so that ifindex can be set - * DEFUN macro not used as extract.pl HAS to ignore this - * See also interface_cmd in lib/if.c - */ -DEFUN_NOSH (zebra_vrf, - zebra_vrf_cmd, - "vrf NAME", - "Select a VRF to configure\n" - "VRF's name\n") -{ - // VTY_DECLVAR_CONTEXT (vrf, vrfp); - int ret; - - /* Call lib vrf() */ - if ((ret = vrf_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS) - return ret; - - return ret; -} - -struct cmd_node vrf_node = -{ - VRF_NODE, - "%s(config-vrf)# ", - 1 -}; - /* Show all interfaces to vty. */ DEFUN (show_interface, show_interface_cmd, "show interface", @@ -2929,23 +2902,6 @@ if_config_write (struct vty *vty) return 0; } -static int -vrf_config_write (struct vty *vty) -{ - struct listnode *node; - struct zebra_vrf *zvrf; - - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) - { - if (strcmp(zvrf->name, VRF_DEFAULT_NAME)) - { - vty_out (vty, "vrf %s%s", zvrf->name, VTY_NEWLINE); - vty_out (vty, "!%s", VTY_NEWLINE); - } - } - return 0; -} - /* Allocate and initialize interface vector. */ void zebra_if_init (void) @@ -2957,7 +2913,6 @@ zebra_if_init (void) /* Install configuration write function. */ install_node (&interface_node, if_config_write); install_node (&link_params_node, NULL); - install_node (&vrf_node, vrf_config_write); install_element (VIEW_NODE, &show_interface_cmd); install_element (VIEW_NODE, &show_interface_vrf_cmd); @@ -3020,8 +2975,4 @@ zebra_if_init (void) install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd); install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd); install_element(LINK_PARAMS_NODE, &exit_link_params_cmd); - - install_element (CONFIG_NODE, &zebra_vrf_cmd); - install_element (CONFIG_NODE, &no_vrf_cmd); - install_default (VRF_NODE); } diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 378327ab46..9f9a62f384 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -716,11 +716,18 @@ kernel_init (struct zebra_ns *zns) { unsigned long groups; - groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR; -#ifdef HAVE_IPV6 - groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR; -#endif /* HAVE_IPV6 */ + /* Initialize netlink sockets */ + groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR | + RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR; + + snprintf (zns->netlink.name, sizeof (zns->netlink.name), + "netlink-listen (NS %u)", zns->ns_id); + zns->netlink.sock = -1; netlink_socket (&zns->netlink, groups, zns->ns_id); + + snprintf (zns->netlink_cmd.name, sizeof (zns->netlink_cmd.name), + "netlink-cmd (NS %u)", zns->ns_id); + zns->netlink_cmd.sock = -1; netlink_socket (&zns->netlink_cmd, 0, zns->ns_id); /* Register kernel socket. */ diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 4499901021..642d2700a4 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -50,16 +50,6 @@ zebra_ns_enable (ns_id_t ns_id, void **info) rtadv_init (zns); #endif -#ifdef HAVE_NETLINK - /* Initialize netlink sockets */ - snprintf (zns->netlink.name, sizeof (zns->netlink.name), - "netlink-listen (NS %u)", ns_id); - zns->netlink.sock = -1; - - snprintf (zns->netlink_cmd.name, sizeof (zns->netlink_cmd.name), - "netlink-cmd (NS %u)", ns_id); - zns->netlink_cmd.sock = -1; -#endif zns->if_table = route_table_init (); kernel_init (zns); interface_list (zns); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index ab825281e4..a4e5eabbc8 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -23,6 +23,7 @@ #include "log.h" #include "linklist.h" +#include "command.h" #include "memory.h" #include "zebra/debug.h" @@ -427,6 +428,50 @@ zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id) return zvrf->table[afi][SAFI_UNICAST]; } +/* Wrapper hook point for zebra daemon so that ifindex can be set + * DEFUN macro not used as extract.pl HAS to ignore this + * See also interface_cmd in lib/if.c + */ +DEFUN_NOSH (zebra_vrf, + zebra_vrf_cmd, + "vrf NAME", + "Select a VRF to configure\n" + "VRF's name\n") +{ + // VTY_DECLVAR_CONTEXT (vrf, vrfp); + int ret; + + /* Call lib vrf() */ + if ((ret = vrf_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS) + return ret; + + return ret; +} + +static int +vrf_config_write (struct vty *vty) +{ + struct listnode *node; + struct zebra_vrf *zvrf; + + for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) + { + if (strcmp(zvrf->name, VRF_DEFAULT_NAME)) + { + vty_out (vty, "vrf %s%s", zvrf->name, VTY_NEWLINE); + vty_out (vty, "!%s", VTY_NEWLINE); + } + } + return 0; +} + +struct cmd_node vrf_node = +{ + VRF_NODE, + "%s(config-vrf)# ", + 1 +}; + /* Zebra VRF initialization. */ void zebra_vrf_init (void) @@ -439,4 +484,9 @@ zebra_vrf_init (void) zvrf_list = list_new (); vrf_init (); + + install_node (&vrf_node, vrf_config_write); + install_default (VRF_NODE); + install_element (CONFIG_NODE, &zebra_vrf_cmd); + install_element (CONFIG_NODE, &no_vrf_cmd); } From 60f1637a8b35b2968e64dd1619e499033c8068bb Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 28 Oct 2016 16:53:38 -0200 Subject: [PATCH 09/20] lib: fix creation of pre-provisioned VRFs If we configure a VRF that doesn't match any device in the kernel, we'll fall in the first case of the vrf_get() function. In this function, a vrf structure is callocated and it's vrf_id is never set explicitly, which means it's set to zero (the vrf-id of the default VRF). When this happens, commands like "router-id A.B.C.D vrf ..." will act on the default VRF and not on the pre-provisioned VRF. To fix this, always set the vrf_id of pre-provisioned VRFs to VRF_UNKNOWN. Signed-off-by: Renato Westphal --- lib/vrf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/vrf.c b/lib/vrf.c index d87e38ebe8..13884aba62 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -124,6 +124,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) zlog_debug ("VRF(%u) %s is created.", vrf_id, (name) ? name : "(NULL)"); strcpy (vrf->name, name); + vrf->vrf_id = VRF_UNKNOWN; listnode_add_sort (vrf_list, vrf); if_init (&vrf->iflist); QOBJ_REG (vrf, vrf); From 51bdc5f85ceb5d597924fc5f9b550257972a38fd Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 28 Oct 2016 22:26:04 -0200 Subject: [PATCH 10/20] zebra: nuke zvrf_list and always use vrf_list instead zvrf_list doesn't need to exist, it's basically a duplicate version of vrf_list. Also, zebra_vrf_delete() wasn't removing zvrf from zvrf_list, which was a bug. Signed-off-by: Renato Westphal --- zebra/zebra_vrf.c | 24 ++++++++++-------------- zebra/zebra_vrf.h | 2 -- zebra/zebra_vty.c | 22 +++++++++++++++++----- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index a4e5eabbc8..915849c057 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -36,7 +36,6 @@ #include "zebra/zebra_mpls.h" extern struct zebra_t zebrad; -struct list *zvrf_list; /* VRF information update. */ static void @@ -96,7 +95,6 @@ zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info) zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */ *info = (void *)zvrf; router_id_init (zvrf); - listnode_add_sort (zvrf_list, zvrf); } else { @@ -346,21 +344,19 @@ zebra_vrf_lookup (vrf_id_t vrf_id) return vrf_info_lookup (vrf_id); } -/* Lookup the zvrf in the zvrf_list. */ +/* Lookup VRF by name. */ struct zebra_vrf * zebra_vrf_list_lookup_by_name (const char *name) { - struct listnode *node; - struct zebra_vrf *zvrf; + struct vrf *vrf; if (!name) name = VRF_DEFAULT_NAME; - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) - { - if (strcmp(name, zvrf->name) == 0) - return zvrf; - } + vrf = vrf_list_lookup_by_name (name); + if (vrf) + return ((struct zebra_vrf *) vrf->info); + return NULL; } @@ -452,11 +448,13 @@ static int vrf_config_write (struct vty *vty) { struct listnode *node; + struct vrf *vrf; struct zebra_vrf *zvrf; - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) + for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) { - if (strcmp(zvrf->name, VRF_DEFAULT_NAME)) + zvrf = vrf->info; + if (! zvrf || strcmp (zvrf->name, VRF_DEFAULT_NAME)) { vty_out (vty, "vrf %s%s", zvrf->name, VTY_NEWLINE); vty_out (vty, "!%s", VTY_NEWLINE); @@ -481,8 +479,6 @@ zebra_vrf_init (void) vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable); vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete); - zvrf_list = list_new (); - vrf_init (); install_node (&vrf_node, vrf_config_write); diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 0baddc1b6a..8dffe27dcf 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -86,8 +86,6 @@ struct zebra_vrf #define MPLS_FLAG_SCHEDULE_LSPS (1 << 0) }; -extern struct list *zvrf_list; - struct route_table * zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, vrf_id_t vrf_id, u_int32_t table_id); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 9b0fad93e0..74f64dd057 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -3673,13 +3673,18 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd) struct route_node *rn; struct static_route *si; struct route_table *stable; + struct vrf *vrf; struct zebra_vrf *zvrf; char buf[BUFSIZ]; int write =0; struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) + for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) { + zvrf = vrf->info; + if (! zvrf) + continue; + if ((stable = zvrf->stable[AFI_IP][safi]) == NULL) continue; @@ -5782,11 +5787,16 @@ static_config_ipv6 (struct vty *vty) int write = 0; char buf[PREFIX_STRLEN]; struct route_table *stable; + struct vrf *vrf; struct zebra_vrf *zvrf; struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) + for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) { + zvrf = vrf->info; + if (! zvrf) + continue; + if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5874,13 +5884,15 @@ DEFUN (show_vrf, SHOW_STR "VRF\n") { + struct vrf *vrf; struct zebra_vrf *zvrf; struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) + for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) { - if (!zvrf->vrf_id) - continue; + zvrf = vrf->info; + if (! zvrf || ! zvrf->vrf_id) + continue; vty_out (vty, "vrf %s ", zvrf->name); if (zvrf->vrf_id == VRF_UNKNOWN) From c7fdd84f36a262d062a10c1439121df361ab78d3 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 28 Oct 2016 23:03:35 -0200 Subject: [PATCH 11/20] lib: convert namespace code to use red-black trees We definitely need to stop abusing the route table data structure when it's not necessary. Convert the namespace code to use red-black trees instead. This greatly improves code readability. Signed-off-by: Renato Westphal --- lib/ns.c | 81 ++++++++++++++++++++------------------------------------ lib/ns.h | 9 +++++++ 2 files changed, 37 insertions(+), 53 deletions(-) diff --git a/lib/ns.c b/lib/ns.c index 904fc6999c..08432764db 100644 --- a/lib/ns.c +++ b/lib/ns.c @@ -31,8 +31,6 @@ #include "if.h" #include "ns.h" -#include "prefix.h" -#include "table.h" #include "log.h" #include "memory.h" @@ -43,6 +41,13 @@ DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router") DEFINE_MTYPE_STATIC(LIB, NS_NAME, "Logical-Router Name") DEFINE_MTYPE_STATIC(LIB, NS_BITMAP, "Logical-Router bit-map") +static __inline int ns_compare (struct ns *, struct ns *); +static struct ns *ns_lookup (ns_id_t); + +RB_GENERATE (ns_head, ns, entry, ns_compare) + +struct ns_head ns_tree = RB_INITIALIZER (&ns_tree); + #ifndef CLONE_NEWNET #define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */ #endif @@ -100,44 +105,30 @@ struct ns_master int (*ns_disable_hook) (ns_id_t, void **); } ns_master = {0,}; -/* NS table */ -struct route_table *ns_table = NULL; - static int ns_is_enabled (struct ns *ns); static int ns_enable (struct ns *ns); static void ns_disable (struct ns *ns); - -/* Build the table key */ -static void -ns_build_key (ns_id_t ns_id, struct prefix *p) +static __inline int +ns_compare(struct ns *a, struct ns *b) { - p->family = AF_INET; - p->prefixlen = IPV4_MAX_BITLEN; - p->u.prefix4.s_addr = ns_id; + return (a->ns_id - b->ns_id); } /* Get a NS. If not found, create one. */ static struct ns * ns_get (ns_id_t ns_id) { - struct prefix p; - struct route_node *rn; struct ns *ns; - ns_build_key (ns_id, &p); - rn = route_node_get (ns_table, &p); - if (rn->info) - { - ns = (struct ns *)rn->info; - route_unlock_node (rn); /* get */ - return ns; - } + ns = ns_lookup (ns_id); + if (ns) + return (ns); ns = XCALLOC (MTYPE_NS, sizeof (struct ns)); ns->ns_id = ns_id; ns->fd = -1; - rn->info = ns; + RB_INSERT (ns_head, &ns_tree, ns); /* * Initialize interfaces. @@ -172,6 +163,7 @@ ns_delete (struct ns *ns) */ //if_terminate (&ns->iflist); + RB_REMOVE (ns_head, &ns_tree, ns); if (ns->name) XFREE (MTYPE_NS_NAME, ns->name); @@ -182,18 +174,9 @@ ns_delete (struct ns *ns) static struct ns * ns_lookup (ns_id_t ns_id) { - struct prefix p; - struct route_node *rn; - struct ns *ns = NULL; - - ns_build_key (ns_id, &p); - rn = route_node_lookup (ns_table, &p); - if (rn) - { - ns = (struct ns *)rn->info; - route_unlock_node (rn); /* lookup */ - } - return ns; + struct ns ns; + ns.ns_id = ns_id; + return (RB_FIND (ns_head, &ns_tree, &ns)); } /* @@ -414,17 +397,17 @@ static struct cmd_node ns_node = static int ns_config_write (struct vty *vty) { - struct route_node *rn; struct ns *ns; int write = 0; - for (rn = route_top (ns_table); rn; rn = route_next (rn)) - if ((ns = rn->info) != NULL && - ns->ns_id != NS_DEFAULT && ns->name) - { - vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name, VTY_NEWLINE); - write++; - } + RB_FOREACH (ns, ns_head, &ns_tree) { + if (ns->ns_id == NS_DEFAULT || ns->name == NULL) + continue; + + vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name, + VTY_NEWLINE); + write = 1; + } return write; } @@ -435,9 +418,6 @@ ns_init (void) { struct ns *default_ns; - /* Allocate NS table. */ - ns_table = route_table_init (); - /* The default NS always exists. */ default_ns = ns_get (NS_DEFAULT); if (!default_ns) @@ -469,15 +449,10 @@ ns_init (void) void ns_terminate (void) { - struct route_node *rn; struct ns *ns; - for (rn = route_top (ns_table); rn; rn = route_next (rn)) - if ((ns = rn->info) != NULL) - ns_delete (ns); - - route_table_finish (ns_table); - ns_table = NULL; + while ((ns = RB_ROOT (&ns_tree)) != NULL) + ns_delete (ns); } /* Create a socket for the NS. */ diff --git a/lib/ns.h b/lib/ns.h index 74616cd62f..2a7be1ef8a 100644 --- a/lib/ns.h +++ b/lib/ns.h @@ -23,6 +23,7 @@ #ifndef _ZEBRA_NS_H #define _ZEBRA_NS_H +#include "openbsd-tree.h" #include "linklist.h" typedef u_int16_t ns_id_t; @@ -35,10 +36,14 @@ typedef u_int16_t ns_id_t; struct ns { + RB_ENTRY(ns) entry; + /* Identifier, same as the vector index */ ns_id_t ns_id; + /* Name */ char *name; + /* File descriptor */ int fd; @@ -48,6 +53,10 @@ struct ns /* User data */ void *info; }; +RB_HEAD (ns_head, ns); +RB_PROTOTYPE (ns_head, ns, entry, ns_compare) + +extern struct ns_head ns_tree; /* * NS hooks From 1a1a70655c869a1b66e363894e5aba19f4aa08f3 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 29 Oct 2016 14:37:11 -0200 Subject: [PATCH 12/20] lib: convert vrf code to use red-black trees as well Signed-off-by: Renato Westphal --- lib/if.c | 35 +++----- lib/vrf.c | 199 +++++++---------------------------------- lib/vrf.h | 45 ++-------- zebra/interface.c | 31 ++++--- zebra/irdp_main.c | 7 +- zebra/router-id.c | 6 +- zebra/rt_netlink.c | 6 +- zebra/rtadv.c | 6 +- zebra/zebra_ptm.c | 12 +-- zebra/zebra_rib.c | 65 +++++++------- zebra/zebra_routemap.c | 8 +- zebra/zebra_vrf.c | 5 +- zebra/zebra_vty.c | 120 ++++++++++++------------- zebra/zserv.c | 14 ++- 14 files changed, 188 insertions(+), 371 deletions(-) diff --git a/lib/if.c b/lib/if.c index 70304e584c..6df4942296 100644 --- a/lib/if.c +++ b/lib/if.c @@ -308,13 +308,11 @@ if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id) struct interface * if_lookup_by_name_all_vrf (const char *name) { + struct vrf *vrf; struct interface *ifp; - struct vrf *vrf = NULL; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - vrf = vrf_iter2vrf (iter); ifp = if_lookup_by_name_vrf (name, vrf->vrf_id); if (ifp) return ifp; @@ -490,18 +488,16 @@ struct interface * if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id, int vty) { struct interface *ifp; + struct vrf *vrf; struct listnode *node; - struct vrf *vrf = NULL; - vrf_iter_t iter; ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id); if (ifp) return ifp; /* Didn't find the interface on that vrf. Defined on a different one? */ - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - vrf = vrf_iter2vrf(iter); for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf->vrf_id), node, ifp)) { if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0')) @@ -666,14 +662,13 @@ if_dump (const struct interface *ifp) void if_dump_all (void) { - struct list *intf_list; + struct vrf *vrf; struct listnode *node; void *p; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((intf_list = vrf_iter2iflist (iter)) != NULL) - for (ALL_LIST_ELEMENTS_RO (intf_list, node, p)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if (vrf->iflist != NULL) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, p)) if_dump (p); } @@ -885,24 +880,22 @@ DEFUN (show_address_vrf_all, "address\n" VRF_ALL_CMD_HELP_STR) { - struct list *intf_list; + struct vrf *vrf; struct listnode *node; struct listnode *node2; struct interface *ifp; struct connected *ifc; struct prefix *p; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - intf_list = vrf_iter2iflist (iter); - if (!intf_list || !listcount (intf_list)) + if (!vrf->iflist || !listcount (vrf->iflist)) continue; - vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf_iter2id (iter), - VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id, VTY_NEWLINE, + VTY_NEWLINE); - for (ALL_LIST_ELEMENTS_RO (intf_list, node, ifp)) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) { for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc)) { diff --git a/lib/vrf.c b/lib/vrf.c index 13884aba62..79885ff3e3 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -35,6 +35,12 @@ DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map") DEFINE_QOBJ_TYPE(vrf) +static __inline int vrf_id_compare (struct vrf *, struct vrf *); + +RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare) + +struct vrf_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id); + /* * Turn on/off debug code * for vrf. @@ -50,9 +56,6 @@ struct vrf_master int (*vrf_disable_hook) (vrf_id_t, const char *, void **); } vrf_master = {0,}; -/* VRF table */ -struct route_table *vrf_table = NULL; - /* VRF is part of a list too to store it before its actually active */ struct list *vrf_list; @@ -75,13 +78,10 @@ vrf_list_lookup_by_name (const char *name) return NULL; } -/* Build the table key */ -static void -vrf_build_key (vrf_id_t vrf_id, struct prefix *p) +static __inline int +vrf_id_compare (struct vrf *a, struct vrf *b) { - p->family = AF_INET; - p->prefixlen = IPV4_MAX_BITLEN; - p->u.prefix4.s_addr = vrf_id; + return (a->vrf_id - b->vrf_id); } /* Get a VRF. If not found, create one. @@ -94,9 +94,7 @@ vrf_build_key (vrf_id_t vrf_id, struct prefix *p) struct vrf * vrf_get (vrf_id_t vrf_id, const char *name) { - struct prefix p; - struct route_node *rn = NULL; - struct vrf *vrf = NULL; + struct vrf *vrf; if (debug_vrf) zlog_debug ("VRF_GET: %s(%d)", name, vrf_id); @@ -156,17 +154,8 @@ vrf_get (vrf_id_t vrf_id, const char *name) if (vrf->vrf_id == vrf_id) return vrf; - /* - * Now we have a situation where we've had a - * vrf created, but not yet created the vrf_id route - * node, let's do so and match the code up. - */ - vrf_build_key (vrf_id, &p); - rn = route_node_get (vrf_table, &p); - - rn->info = vrf; - vrf->node = rn; vrf->vrf_id = vrf_id; + RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); if (vrf_master.vrf_new_hook) (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); @@ -182,12 +171,9 @@ vrf_get (vrf_id_t vrf_id, const char *name) * We've already been told about the vrf_id * or we haven't. */ - vrf_build_key (vrf_id, &p); - rn = route_node_get (vrf_table, &p); - if (rn->info) + vrf = vrf_lookup (vrf_id); + if (vrf) { - vrf = rn->info; - route_unlock_node (rn); /* * We know at this point that the vrf->name is not * right because we would have caught it above. @@ -209,12 +195,10 @@ vrf_get (vrf_id_t vrf_id, const char *name) else { vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); - - rn->info = vrf; - vrf->node = rn; vrf->vrf_id = vrf_id; strcpy (vrf->name, name); listnode_add_sort (vrf_list, vrf); + RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); if_init (&vrf->iflist); QOBJ_REG (vrf, vrf); if (vrf_master.vrf_new_hook) @@ -237,23 +221,18 @@ vrf_get (vrf_id_t vrf_id, const char *name) */ else if (!name) { - vrf_build_key (vrf_id, &p); - rn = route_node_get (vrf_table, &p); + vrf = vrf_lookup (vrf_id); if (debug_vrf) - zlog_debug("Vrf found: %p", rn->info); + zlog_debug("Vrf found: %p", vrf); - if (rn->info) - { - route_unlock_node (rn); - return (rn->info); - } + if (vrf) + return vrf; else { vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); - rn->info = vrf; - vrf->node = rn; vrf->vrf_id = vrf_id; if_init (&vrf->iflist); + RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); QOBJ_REG (vrf, vrf); if (debug_vrf) zlog_debug("Vrf Created: %p", vrf); @@ -284,12 +263,8 @@ vrf_delete (struct vrf *vrf) QOBJ_UNREG (vrf); if_terminate (&vrf->iflist); - if (vrf->node) - { - vrf->node->info = NULL; - route_unlock_node(vrf->node); - } - + if (vrf->vrf_id != VRF_UNKNOWN) + RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf); listnode_delete (vrf_list, vrf); XFREE (MTYPE_VRF, vrf); @@ -299,18 +274,9 @@ vrf_delete (struct vrf *vrf) struct vrf * vrf_lookup (vrf_id_t vrf_id) { - struct prefix p; - struct route_node *rn; - struct vrf *vrf = NULL; - - vrf_build_key (vrf_id, &p); - rn = route_node_lookup (vrf_table, &p); - if (rn) - { - vrf = (struct vrf *)rn->info; - route_unlock_node (rn); /* lookup */ - } - return vrf; + struct vrf vrf; + vrf.vrf_id = vrf_id; + return (RB_FIND (vrf_id_head, &vrfs_by_id, &vrf)); } /* @@ -401,112 +367,15 @@ vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **)) } } -/* Return the iterator of the first VRF. */ -vrf_iter_t -vrf_first (void) -{ - struct route_node *rn; - - for (rn = route_top (vrf_table); rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* top/next */ - return (vrf_iter_t)rn; - } - return VRF_ITER_INVALID; -} - -/* Return the next VRF iterator to the given iterator. */ -vrf_iter_t -vrf_next (vrf_iter_t iter) -{ - struct route_node *rn = NULL; - - /* Lock it first because route_next() will unlock it. */ - if (iter != VRF_ITER_INVALID) - rn = route_next (route_lock_node ((struct route_node *)iter)); - - for (; rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* next */ - return (vrf_iter_t)rn; - } - return VRF_ITER_INVALID; -} - -/* Return the VRF iterator of the given VRF ID. If it does not exist, - * the iterator of the next existing VRF is returned. */ -vrf_iter_t -vrf_iterator (vrf_id_t vrf_id) -{ - struct prefix p; - struct route_node *rn; - - vrf_build_key (vrf_id, &p); - rn = route_node_get (vrf_table, &p); - if (rn->info) - { - /* OK, the VRF exists. */ - route_unlock_node (rn); /* get */ - return (vrf_iter_t)rn; - } - - /* Find the next VRF. */ - for (rn = route_next (rn); rn; rn = route_next (rn)) - if (rn->info) - { - route_unlock_node (rn); /* next */ - return (vrf_iter_t)rn; - } - - return VRF_ITER_INVALID; -} - -/* Obtain the VRF ID from the given VRF iterator. */ -vrf_id_t -vrf_iter2id (vrf_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT; -} - -struct vrf * -vrf_iter2vrf (vrf_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? (struct vrf *)rn->info : NULL; -} - -/* Obtain the data pointer from the given VRF iterator. */ -void * -vrf_iter2info (vrf_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL; -} - -/* Obtain the interface list from the given VRF iterator. */ -struct list * -vrf_iter2iflist (vrf_iter_t iter) -{ - struct route_node *rn = (struct route_node *) iter; - return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL; -} - /* Look up a VRF by name. */ struct vrf * vrf_lookup_by_name (const char *name) { - struct vrf *vrf = NULL; - vrf_iter_t iter; + struct vrf *vrf; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - { - vrf = vrf_iter2vrf (iter); - if (vrf && !strcmp(vrf->name, name)) - return vrf; - } + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if (!strcmp(vrf->name, name)) + return vrf; return NULL; } @@ -693,9 +562,6 @@ vrf_init (void) vrf_list = list_new (); vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func; - /* Allocate VRF table. */ - vrf_table = route_table_init (); - /* The default VRF always exists. */ default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME); if (!default_vrf) @@ -716,18 +582,13 @@ vrf_init (void) void vrf_terminate (void) { - struct route_node *rn; struct vrf *vrf; if (debug_vrf) zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__); - for (rn = route_top (vrf_table); rn; rn = route_next (rn)) - if ((vrf = rn->info) != NULL) - vrf_delete (vrf); - - route_table_finish (vrf_table); - vrf_table = NULL; + while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL) + vrf_delete (vrf); } /* Create a socket for the VRF. */ diff --git a/lib/vrf.h b/lib/vrf.h index 127b7082e9..f093f4fbd8 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -23,6 +23,7 @@ #ifndef _ZEBRA_VRF_H #define _ZEBRA_VRF_H +#include "openbsd-tree.h" #include "linklist.h" #include "qobj.h" @@ -69,18 +70,18 @@ enum { struct vrf { + RB_ENTRY(vrf) id_entry; + /* Identifier, same as the vector index */ vrf_id_t vrf_id; - /* Name */ + /* Name */ char name[VRF_NAMSIZ + 1]; /* Zebra internal VRF status */ u_char status; #define VRF_ACTIVE (1 << 0) - struct route_node *node; - /* Master list of interfaces belonging to this VRF */ struct list *iflist; @@ -89,9 +90,12 @@ struct vrf QOBJ_FIELDS }; +RB_HEAD (vrf_id_head, vrf); +RB_PROTOTYPE (vrf_id_head, vrf, id_entry, vrf_id_compare) DECLARE_QOBJ_TYPE(vrf) +extern struct vrf_id_head vrfs_by_id; extern struct list *vrf_list; /* @@ -104,13 +108,6 @@ extern struct list *vrf_list; */ extern void vrf_add_hook (int, int (*)(vrf_id_t, const char *, void **)); -/* - * VRF iteration - */ - -typedef void * vrf_iter_t; -#define VRF_ITER_INVALID NULL /* invalid value of the iterator */ - extern struct vrf *vrf_lookup (vrf_id_t); extern struct vrf *vrf_lookup_by_name (const char *); extern struct vrf *vrf_list_lookup_by_name (const char *); @@ -135,34 +132,6 @@ extern vrf_id_t vrf_name_to_id (const char *); (V) = vrf->vrf_id; \ } while (0) -/* - * VRF iteration utilities. Example for the usage: - * - * vrf_iter_t iter = vrf_first(); - * for (; iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - * - * or - * - * vrf_iter_t iter = vrf_iterator (); - * for (; iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - */ - -/* Return the iterator of the first VRF. */ -extern vrf_iter_t vrf_first (void); -/* Return the next VRF iterator to the given iterator. */ -extern vrf_iter_t vrf_next (vrf_iter_t); -/* Return the VRF iterator of the given VRF ID. If it does not exist, - * the iterator of the next existing VRF is returned. */ -extern vrf_iter_t vrf_iterator (vrf_id_t); - -/* - * VRF iterator to properties - */ -extern vrf_id_t vrf_iter2id (vrf_iter_t); -extern struct vrf *vrf_iter2vrf (vrf_iter_t); -extern void *vrf_iter2info (vrf_iter_t); -extern struct list *vrf_iter2iflist (vrf_iter_t); - /* * Utilities to obtain the user data */ diff --git a/zebra/interface.c b/zebra/interface.c index dd1f8a146b..75040a87f0 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1325,15 +1325,15 @@ DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd, "Interface status and configuration\n" VRF_ALL_CMD_HELP_STR) { + struct vrf *vrf; struct listnode *node; struct interface *ifp; - vrf_iter_t iter; interface_update_stats (); /* All interface print. */ - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) if_dump_vty (vty, ifp); return CMD_SUCCESS; @@ -1378,17 +1378,17 @@ DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd, "Interface name\n" VRF_ALL_CMD_HELP_STR) { + struct vrf *vrf; struct interface *ifp; - vrf_iter_t iter; int found = 0; interface_update_stats (); /* All interface print. */ - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { /* Specified interface print. */ - ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter)); + ifp = if_lookup_by_name_vrf (argv[0], vrf->vrf_id); if (ifp) { if_dump_vty (vty, ifp); @@ -1484,15 +1484,14 @@ DEFUN (show_interface_desc_vrf_all, "Interface description\n" VRF_ALL_CMD_HELP_STR) { - vrf_iter_t iter; + struct vrf *vrf; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if (!list_isempty (vrf_iter2iflist (iter))) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if (!list_isempty (vrf->iflist)) { - vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, - vrf_iter2id (iter), - VTY_NEWLINE, VTY_NEWLINE); - if_show_description (vty, vrf_iter2id (iter)); + vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id, + VTY_NEWLINE, VTY_NEWLINE); + if_show_description (vty, vrf->vrf_id); } return CMD_SUCCESS; @@ -2818,14 +2817,14 @@ link_params_config_write (struct vty *vty, struct interface *ifp) static int if_config_write (struct vty *vty) { + struct vrf *vrf; struct listnode *node; struct interface *ifp; - vrf_iter_t iter; zebra_ptm_write (vty); - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) { struct zebra_if *if_data; struct listnode *addrnode; diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index cc3a4abaf3..7fa4ad4cbe 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -304,17 +304,16 @@ void process_solicit (struct interface *ifp) void irdp_finish() { - + struct vrf *vrf; struct listnode *node, *nnode; struct interface *ifp; struct zebra_if *zi; struct irdp_interface *irdp; - vrf_iter_t iter; zlog_info("IRDP: Received shutdown notification."); - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp)) { zi = ifp->info; diff --git a/zebra/router-id.c b/zebra/router-id.c index d5d9652c59..155a8e3939 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -195,11 +195,11 @@ router_id_del_address (struct connected *ifc) void router_id_write (struct vty *vty) { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) if (zvrf->rid_user_assigned.u.prefix4.s_addr) { if (zvrf->vrf_id == VRF_DEFAULT) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index f16fd55c98..b18bf1ef7a 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -98,12 +98,12 @@ Pending: create an efficient table_id (in a tree/hash) based lookup) static vrf_id_t vrf_lookup_by_table (u_int32_t table_id) { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (zvrf->table_id != table_id)) continue; diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 3e0a198702..1ab7ac147c 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -373,7 +373,7 @@ static int rtadv_timer (struct thread *thread) { struct zebra_ns *zns = THREAD_ARG (thread); - vrf_iter_t iter; + struct vrf *vrf; struct listnode *node, *nnode; struct interface *ifp; struct zebra_if *zif; @@ -391,8 +391,8 @@ rtadv_timer (struct thread *thread) rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */); } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp)) { if (if_is_loopback (ifp) || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) || diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 28e6c42ec6..4fc1173241 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -258,15 +258,15 @@ DEFUN (zebra_ptm_enable, "ptm-enable", "Enable neighbor check with specified topology\n") { + struct vrf *vrf; struct listnode *i; struct interface *ifp; struct zebra_if *if_data; - vrf_iter_t iter; ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), i, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp)) if (!ifp->ptm_enable) { if_data = (struct zebra_if *)ifp->info; @@ -1112,13 +1112,13 @@ zebra_ptm_send_status_req(void) void zebra_ptm_reset_status(int ptm_disable) { + struct vrf *vrf; struct listnode *i; struct interface *ifp; int send_linkup; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), i, ifp)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp)) { send_linkup = 0; if (ifp->ptm_enable) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 394469950d..ec7d1e7fde 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2052,24 +2052,24 @@ process_subq (struct list * subq, u_char qindex) static void meta_queue_process_complete (struct work_queue *dummy) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; /* Evaluate nexthops for those VRFs which underwent route processing. This * should limit the evaluation to the necessary VRFs in most common * situations. */ - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if (((zvrf = vrf_iter2info (iter)) != NULL) && - (zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED)) - { - zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED; - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL); - } + zvrf = vrf->info; + if (zvrf == NULL || !(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED)) + continue; + + zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED; + zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); + zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL); } /* Schedule LSPs for processing, if needed. */ @@ -3037,11 +3037,11 @@ rib_weed_table (struct route_table *table) void rib_weed_tables (void) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) { rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]); rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); @@ -3078,11 +3078,11 @@ rib_sweep_table (struct route_table *table) void rib_sweep_route (void) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) { rib_sweep_table (zvrf->table[AFI_IP][SAFI_UNICAST]); rib_sweep_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); @@ -3118,12 +3118,12 @@ rib_score_proto_table (u_char proto, u_short instance, struct route_table *table unsigned long rib_score_proto (u_char proto, u_short instance) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; unsigned long cnt = 0; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + 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]); @@ -3157,20 +3157,20 @@ rib_close_table (struct route_table *table) void rib_close (void) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; struct listnode *node; struct interface *ifp; u_int32_t table_id; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) != NULL) + if ((zvrf = vrf->info) != NULL) { rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]); rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); } - for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp)) + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp); } @@ -3207,17 +3207,16 @@ rib_init (void) static inline int vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p) { - vrf_iter_t iter = vrf_iterator (vrf_id); - struct zebra_vrf *zvrf = vrf_iter2info (iter); + struct vrf *vrf; - /* The same one ? Then find out the next. */ - if (zvrf && (zvrf->vrf_id == vrf_id)) - zvrf = vrf_iter2info (vrf_next (iter)); - - if (zvrf) + vrf = vrf_lookup (vrf_id); + if (vrf) { - *next_id_p = zvrf->vrf_id; - return 1; + vrf = RB_NEXT (vrf_id_head, &vrfs_by_id, vrf); + if (vrf) { + *next_id_p = vrf->vrf_id; + return 1; + } } return 0; diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 25091a3eab..3075a61c4a 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -633,7 +633,7 @@ DEFUN (set_src, struct interface *pif = NULL; int family; struct prefix p; - vrf_iter_t iter; + struct vrf *vrf; if (inet_pton(AF_INET, argv[0], &src.ipv4) != 1) { @@ -660,14 +660,14 @@ DEFUN (set_src, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { if (family == AF_INET) pif = if_lookup_exact_address_vrf ((void *)&src.ipv4, AF_INET, - vrf_iter2id (iter)); + vrf->vrf_id); else if (family == AF_INET6) pif = if_lookup_exact_address_vrf ((void *)&src.ipv6, AF_INET6, - vrf_iter2id (iter)); + vrf->vrf_id); if (pif != NULL) break; diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 915849c057..4c1bbbb1a0 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -68,11 +68,10 @@ void zebra_vrf_update_all (struct zserv *client) { struct vrf *vrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((vrf = vrf_iter2vrf (iter)) && vrf->vrf_id) + if (vrf->vrf_id) zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id)); } } diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 74f64dd057..444d251357 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -2569,11 +2569,11 @@ DEFUN (show_ip_nht_vrf_all, "IP nexthop tracking table\n" VRF_ALL_CMD_HELP_STR) { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) { vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); zebra_print_rnh_table(zvrf->vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE); @@ -2614,11 +2614,11 @@ DEFUN (show_ipv6_nht_vrf_all, "IPv6 nexthop tracking table\n" VRF_ALL_CMD_HELP_STR) { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) { vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); zebra_print_rnh_table(zvrf->vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE); @@ -3287,14 +3287,14 @@ DEFUN (show_ip_route_vrf_all, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3334,8 +3334,8 @@ DEFUN (show_ip_route_vrf_all_tag, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; route_tag_t tag = 0; @@ -3343,9 +3343,9 @@ DEFUN (show_ip_route_vrf_all_tag, if (argv[0]) tag = atol(argv[0]); - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3388,8 +3388,8 @@ DEFUN (show_ip_route_vrf_all_prefix_longer, struct route_node *rn; struct rib *rib; struct prefix p; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int ret; int first = 1; int vrf_header = 1; @@ -3401,9 +3401,9 @@ DEFUN (show_ip_route_vrf_all_prefix_longer, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3443,15 +3443,15 @@ DEFUN (show_ip_route_vrf_all_supernets, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; u_int32_t addr; int first = 1; int vrf_header = 1; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3498,8 +3498,8 @@ DEFUN (show_ip_route_vrf_all_protocol, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; @@ -3510,9 +3510,9 @@ DEFUN (show_ip_route_vrf_all_protocol, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3553,8 +3553,8 @@ DEFUN (show_ip_route_vrf_all_addr, struct prefix_ipv4 p; struct route_table *table; struct route_node *rn; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; ret = str2prefix_ipv4 (argv[0], &p); if (ret <= 0) @@ -3563,9 +3563,9 @@ DEFUN (show_ip_route_vrf_all_addr, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3594,8 +3594,8 @@ DEFUN (show_ip_route_vrf_all_prefix, struct prefix_ipv4 p; struct route_table *table; struct route_node *rn; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; ret = str2prefix_ipv4 (argv[0], &p); if (ret <= 0) @@ -3604,9 +3604,9 @@ DEFUN (show_ip_route_vrf_all_prefix, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -3636,11 +3636,11 @@ DEFUN (show_ip_route_vrf_all_summary, VRF_ALL_CMD_HELP_STR "Summary of all routes\n") { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); return CMD_SUCCESS; @@ -3656,11 +3656,11 @@ DEFUN (show_ip_route_vrf_all_summary_prefix, "Summary of all routes\n" "Prefix routes\n") { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); return CMD_SUCCESS; @@ -5416,14 +5416,14 @@ DEFUN (show_ipv6_route_vrf_all, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5463,8 +5463,8 @@ DEFUN (show_ipv6_route_vrf_all_tag, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; route_tag_t tag = 0; @@ -5472,9 +5472,9 @@ DEFUN (show_ipv6_route_vrf_all_tag, if (argv[0]) tag = atol(argv[0]); - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) continue; @@ -5518,8 +5518,8 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer, struct route_node *rn; struct rib *rib; struct prefix p; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int ret; int first = 1; int vrf_header = 1; @@ -5531,9 +5531,9 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5574,8 +5574,8 @@ DEFUN (show_ipv6_route_vrf_all_protocol, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; int vrf_header = 1; @@ -5586,9 +5586,9 @@ DEFUN (show_ipv6_route_vrf_all_protocol, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5629,8 +5629,8 @@ DEFUN (show_ipv6_route_vrf_all_addr, struct prefix_ipv6 p; struct route_table *table; struct route_node *rn; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; ret = str2prefix_ipv6 (argv[0], &p); if (ret <= 0) @@ -5639,9 +5639,9 @@ DEFUN (show_ipv6_route_vrf_all_addr, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5670,8 +5670,8 @@ DEFUN (show_ipv6_route_vrf_all_prefix, struct prefix_ipv6 p; struct route_table *table; struct route_node *rn; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; ret = str2prefix_ipv6 (argv[0], &p); if (ret <= 0) @@ -5680,9 +5680,9 @@ DEFUN (show_ipv6_route_vrf_all_prefix, return CMD_WARNING; } - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5712,11 +5712,11 @@ DEFUN (show_ipv6_route_vrf_all_summary, VRF_ALL_CMD_HELP_STR "Summary of all IPv6 routes\n") { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); return CMD_SUCCESS; @@ -5733,13 +5733,13 @@ DEFUN (show_ipv6_mroute_vrf_all, struct route_table *table; struct route_node *rn; struct rib *rib; + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) == NULL || + if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) continue; @@ -5768,11 +5768,11 @@ DEFUN (show_ipv6_route_vrf_all_summary_prefix, "Summary of all IPv6 routes\n" "Prefix routes\n") { + struct vrf *vrf; struct zebra_vrf *zvrf; - vrf_iter_t iter; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); return CMD_SUCCESS; diff --git a/zebra/zserv.c b/zebra/zserv.c index 0b69af5124..76fdebb3a5 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1005,18 +1005,16 @@ zsend_router_id_update (struct zserv *client, struct prefix *p, static int zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) { + struct vrf *vrf; struct listnode *ifnode, *ifnnode; - vrf_iter_t iter; struct interface *ifp; - struct zebra_vrf *zvrf_iter; /* Interface information is needed. */ vrf_bitmap_set (client->ifinfo, zvrf->vrf_id); - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - zvrf_iter = vrf_iter2info (iter); - for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf_iter->vrf_id), ifnode, ifnnode, ifp)) + for (ALL_LIST_ELEMENTS (vrf->iflist, ifnode, ifnnode, ifp)) { /* Skip pseudo interface. */ if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) @@ -1724,12 +1722,12 @@ zread_mpls_labels (int command, struct zserv *client, u_short length, static void zebra_client_close_cleanup_rnh (struct zserv *client) { - vrf_iter_t iter; + struct vrf *vrf; struct zebra_vrf *zvrf; - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { - if ((zvrf = vrf_iter2info (iter)) != NULL) + if ((zvrf = vrf->info) != NULL) { zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_NEXTHOP_TYPE); zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_NEXTHOP_TYPE); From 5f3d1bdf3ce8ac030831ee8c4dd6655ce5172431 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 2 Nov 2016 12:16:58 -0200 Subject: [PATCH 13/20] *: rename two vrf functions Since VRFs can be searched by vrf_id or name, make this explicit in the helper functions. s/vrf_lookup/vrf_lookup_by_id/ s/zebra_vrf_lookup/zebra_vrf_lookup_by_id/ Signed-off-by: Renato Westphal --- bgpd/bgp_main.c | 4 ++-- bgpd/bgpd.c | 2 +- bgpd/bgpd.h | 2 +- lib/vrf.c | 14 +++++++------- lib/vrf.h | 2 +- lib/zclient.c | 2 +- zebra/if_netlink.c | 4 ++-- zebra/interface.c | 4 ++-- zebra/zebra_rib.c | 4 ++-- zebra/zebra_rnh.c | 4 ++-- zebra/zebra_static.c | 2 +- zebra/zebra_vrf.c | 4 ++-- zebra/zebra_vrf.h | 2 +- zebra/zserv.c | 2 +- 14 files changed, 26 insertions(+), 26 deletions(-) diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 50ca7eda4c..4e31eb344c 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -332,7 +332,7 @@ bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) struct bgp *bgp; vrf_id_t old_vrf_id; - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (!vrf) // unexpected return -1; @@ -365,7 +365,7 @@ bgp_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) if (vrf_id == VRF_DEFAULT) return 0; - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (!vrf) // unexpected return -1; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 53258880ab..22d4dd8917 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2971,7 +2971,7 @@ bgp_lookup_by_vrf_id (vrf_id_t vrf_id) struct vrf *vrf; /* Lookup VRF (in tree) and follow link. */ - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (!vrf) return NULL; return (vrf->info) ? (struct bgp *)vrf->info : NULL; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index dd6a0fdccf..510082fdc2 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1490,7 +1490,7 @@ bgp_vrf_lookup_by_instance_type (struct bgp *bgp) struct vrf *vrf; if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) - vrf = vrf_lookup (VRF_DEFAULT); + vrf = vrf_lookup_by_id (VRF_DEFAULT); else if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) vrf = vrf_lookup_by_name (bgp->name); else diff --git a/lib/vrf.c b/lib/vrf.c index 79885ff3e3..2d2c55f7a6 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -171,7 +171,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) * We've already been told about the vrf_id * or we haven't. */ - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (vrf) { /* @@ -221,7 +221,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) */ else if (!name) { - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (debug_vrf) zlog_debug("Vrf found: %p", vrf); @@ -272,7 +272,7 @@ vrf_delete (struct vrf *vrf) /* Look up a VRF by identifier. */ struct vrf * -vrf_lookup (vrf_id_t vrf_id) +vrf_lookup_by_id (vrf_id_t vrf_id) { struct vrf vrf; vrf.vrf_id = vrf_id; @@ -405,7 +405,7 @@ vrf_info_get (vrf_id_t vrf_id) void * vrf_info_lookup (vrf_id_t vrf_id) { - struct vrf *vrf = vrf_lookup (vrf_id); + struct vrf *vrf = vrf_lookup_by_id (vrf_id); return vrf ? vrf->info : NULL; } @@ -413,7 +413,7 @@ vrf_info_lookup (vrf_id_t vrf_id) struct list * vrf_iflist (vrf_id_t vrf_id) { - struct vrf * vrf = vrf_lookup (vrf_id); + struct vrf * vrf = vrf_lookup_by_id (vrf_id); return vrf ? vrf->iflist : NULL; } @@ -429,7 +429,7 @@ vrf_iflist_get (vrf_id_t vrf_id) void vrf_iflist_create (vrf_id_t vrf_id) { - struct vrf * vrf = vrf_lookup (vrf_id); + struct vrf * vrf = vrf_lookup_by_id (vrf_id); if (vrf && !vrf->iflist) if_init (&vrf->iflist); } @@ -438,7 +438,7 @@ vrf_iflist_create (vrf_id_t vrf_id) void vrf_iflist_terminate (vrf_id_t vrf_id) { - struct vrf * vrf = vrf_lookup (vrf_id); + struct vrf * vrf = vrf_lookup_by_id (vrf_id); if (vrf && vrf->iflist) if_terminate (&vrf->iflist); } diff --git a/lib/vrf.h b/lib/vrf.h index f093f4fbd8..4ee871b332 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -108,7 +108,7 @@ extern struct list *vrf_list; */ extern void vrf_add_hook (int, int (*)(vrf_id_t, const char *, void **)); -extern struct vrf *vrf_lookup (vrf_id_t); +extern struct vrf *vrf_lookup_by_id (vrf_id_t); extern struct vrf *vrf_lookup_by_name (const char *); extern struct vrf *vrf_list_lookup_by_name (const char *); extern struct vrf *vrf_get (vrf_id_t, const char *); diff --git a/lib/zclient.c b/lib/zclient.c index 84f7314baa..894e0d19ef 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1042,7 +1042,7 @@ zclient_vrf_delete (struct zclient *zclient, vrf_id_t vrf_id) struct vrf *vrf; /* Lookup vrf by vrf_id. */ - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); /* * If a routing protocol doesn't know about a diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index c44219a495..abf1c781a3 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -211,7 +211,7 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name) /* If VRF already exists, we just return; status changes are handled * against the VRF "interface". */ - vrf = vrf_lookup ((vrf_id_t)ifi->ifi_index); + vrf = vrf_lookup_by_id ((vrf_id_t)ifi->ifi_index); if (vrf && vrf->info) return; @@ -250,7 +250,7 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name) if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug ("RTM_DELLINK for VRF %s(%u)", name, ifi->ifi_index); - vrf = vrf_lookup ((vrf_id_t)ifi->ifi_index); + vrf = vrf_lookup_by_id ((vrf_id_t)ifi->ifi_index); if (!vrf) { diff --git a/zebra/interface.c b/zebra/interface.c index 75040a87f0..d5d6ffd9f0 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1038,7 +1038,7 @@ if_dump_vty (struct vty *vty, struct interface *ifp) zebra_ptm_show_status(vty, ifp); - vrf = vrf_lookup(ifp->vrf_id); + vrf = vrf_lookup_by_id (ifp->vrf_id); vty_out (vty, " vrf: %s%s", vrf->name, VTY_NEWLINE); if (ifp->desc) @@ -2833,7 +2833,7 @@ if_config_write (struct vty *vty) struct vrf *vrf; if_data = ifp->info; - vrf = vrf_lookup(ifp->vrf_id); + vrf = vrf_lookup_by_id (ifp->vrf_id); if (ifp->vrf_id == VRF_DEFAULT) vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index ec7d1e7fde..9d9b10457d 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2152,7 +2152,7 @@ rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn) rnode_debug (rn, rib->vrf_id, "queued rn %p into sub-queue %u", (void *)rn, qindex); - zvrf = zebra_vrf_lookup (rib->vrf_id); + zvrf = zebra_vrf_lookup_by_id (rib->vrf_id); if (zvrf) zvrf->flags |= ZEBRA_VRF_RIB_SCHEDULED; } @@ -3209,7 +3209,7 @@ vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p) { struct vrf *vrf; - vrf = vrf_lookup (vrf_id); + vrf = vrf_lookup_by_id (vrf_id); if (vrf) { vrf = RB_NEXT (vrf_id_head, &vrfs_by_id, vrf); diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 8df9277cb3..7df759030d 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -57,7 +57,7 @@ static void copy_state(struct rnh *rnh, struct rib *rib, ({ \ struct zebra_vrf *zvrf; \ struct route_table *t = NULL; \ - zvrf = zebra_vrf_lookup(v); \ + zvrf = zebra_vrf_lookup_by_id(v); \ if (zvrf) \ t = zvrf->rnh_table[family2afi(f)]; \ t; \ @@ -77,7 +77,7 @@ static inline struct route_table *get_rnh_table(vrf_id_t vrfid, int family, struct zebra_vrf *zvrf; struct route_table *t = NULL; - zvrf = zebra_vrf_lookup(vrfid); + zvrf = zebra_vrf_lookup_by_id(vrfid); if (zvrf) switch (type) { diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 298fc4e09d..32ba90ef9a 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -129,7 +129,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro rib->metric = 0; rib->mtu = 0; rib->vrf_id = si->vrf_id; - rib->table = si->vrf_id ? (zebra_vrf_lookup(si->vrf_id))->table_id : zebrad.rtm_table_default; + rib->table = si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default; rib->nexthop_num = 0; rib->tag = si->tag; diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 4c1bbbb1a0..fbb41eb5a8 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -120,7 +120,7 @@ zebra_vrf_static_route_interface_fixup (struct interface *ifp) { afi_t afi; safi_t safi; - struct zebra_vrf *zvrf = zebra_vrf_lookup (ifp->vrf_id); + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id (ifp->vrf_id); struct route_table *stable = NULL; struct route_node *rn = NULL; struct static_route *si = NULL; @@ -338,7 +338,7 @@ zebra_vrf_alloc (vrf_id_t vrf_id, const char *name) /* Lookup VRF by identifier. */ struct zebra_vrf * -zebra_vrf_lookup (vrf_id_t vrf_id) +zebra_vrf_lookup_by_id (vrf_id_t vrf_id) { return vrf_info_lookup (vrf_id); } diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 8dffe27dcf..c7814e6c99 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -92,7 +92,7 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, extern void zebra_vrf_static_route_interface_fixup (struct interface *ifp); extern void zebra_vrf_update_all (struct zserv *client); -extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id); +extern struct zebra_vrf *zebra_vrf_lookup_by_id (vrf_id_t vrf_id); extern struct zebra_vrf *zebra_vrf_list_lookup_by_name (const char *); extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *); extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t); diff --git a/zebra/zserv.c b/zebra/zserv.c index 76fdebb3a5..947e7324db 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1935,7 +1935,7 @@ zebra_client_read (struct thread *thread) client->last_read_time = quagga_monotime(); client->last_read_cmd = command; - zvrf = zebra_vrf_lookup (vrf_id); + zvrf = zebra_vrf_lookup_by_id (vrf_id); if (!zvrf) { if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) From 806f87607e6b41f67cd1550bc8a9b579522fb15c Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 29 Oct 2016 20:30:57 -0200 Subject: [PATCH 14/20] lib/zebra: convert vrf_list to a red-black tree Since we're already using a red-black tree to store VRFs sorted by their vrf_id's, create a new tree to store VRFs sorted by their names. The biggest advantage of doing this is that we reduce the time complexity of vrf_list_lookup_by_name() from O(n) to O(log n). Signed-off-by: Renato Westphal --- lib/vrf.c | 50 +++++++++++++++-------------------------------- lib/vrf.h | 6 ++++-- zebra/zebra_vrf.c | 3 +-- zebra/zebra_vty.c | 9 +++------ 4 files changed, 24 insertions(+), 44 deletions(-) diff --git a/lib/vrf.c b/lib/vrf.c index 2d2c55f7a6..3def16151a 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -36,10 +36,13 @@ DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map") DEFINE_QOBJ_TYPE(vrf) static __inline int vrf_id_compare (struct vrf *, struct vrf *); +static __inline int vrf_name_compare (struct vrf *, struct vrf *); RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare) +RB_GENERATE (vrf_name_head, vrf, name_entry, vrf_name_compare) struct vrf_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id); +struct vrf_name_head vrfs_by_name = RB_INITIALIZER (&vrfs_by_name); /* * Turn on/off debug code @@ -56,9 +59,6 @@ struct vrf_master int (*vrf_disable_hook) (vrf_id_t, const char *, void **); } vrf_master = {0,}; -/* VRF is part of a list too to store it before its actually active */ -struct list *vrf_list; - static int vrf_is_enabled (struct vrf *vrf); static void vrf_disable (struct vrf *vrf); @@ -66,16 +66,9 @@ static void vrf_disable (struct vrf *vrf); struct vrf * vrf_list_lookup_by_name (const char *name) { - struct listnode *node; - struct vrf *vrfp; - - if (name) - for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrfp)) - { - if (strcmp(name, vrfp->name) == 0) - return vrfp; - } - return NULL; + struct vrf vrf; + strlcpy (vrf.name, name, sizeof (vrf.name)); + return (RB_FIND (vrf_name_head, &vrfs_by_name, &vrf)); } static __inline int @@ -84,6 +77,12 @@ vrf_id_compare (struct vrf *a, struct vrf *b) return (a->vrf_id - b->vrf_id); } +static int +vrf_name_compare (struct vrf *a, struct vrf *b) +{ + return strcmp (a->name, b->name); +} + /* Get a VRF. If not found, create one. * Arg: * name - The name of the vrf. May be NULL if unknown. @@ -123,7 +122,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) vrf_id, (name) ? name : "(NULL)"); strcpy (vrf->name, name); vrf->vrf_id = VRF_UNKNOWN; - listnode_add_sort (vrf_list, vrf); + RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); if_init (&vrf->iflist); QOBJ_REG (vrf, vrf); if (vrf_master.vrf_new_hook) @@ -180,7 +179,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) * so let's set it. */ strcpy (vrf->name, name); - listnode_add_sort (vrf_list, vrf); + RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); if (vrf_master.vrf_new_hook) { (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); @@ -197,7 +196,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); vrf->vrf_id = vrf_id; strcpy (vrf->name, name); - listnode_add_sort (vrf_list, vrf); + RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); if_init (&vrf->iflist); QOBJ_REG (vrf, vrf); @@ -265,7 +264,7 @@ vrf_delete (struct vrf *vrf) if (vrf->vrf_id != VRF_UNKNOWN) RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf); - listnode_delete (vrf_list, vrf); + RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf); XFREE (MTYPE_VRF, vrf); } @@ -536,20 +535,6 @@ vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id) VRF_BITMAP_FLAG (offset)) ? 1 : 0; } -/* Compare interface names, returning an integer greater than, equal to, or - * less than 0, (following the strcmp convention), according to the - * relationship between vrfp1 and vrfp2. Interface names consist of an - * alphabetic prefix and a numeric suffix. The primary sort key is - * lexicographic by name, and then numeric by number. No number sorts - * before all numbers. Examples: de0 < de1, de100 < fxp0 < xl0, devpty < - * devpty0, de0 < del0 - */ -static int -vrf_cmp_func (struct vrf *vrfp1, struct vrf *vrfp2) -{ - return if_cmp_name_func (vrfp1->name, vrfp2->name); -} - /* Initialize VRF module. */ void vrf_init (void) @@ -559,9 +544,6 @@ vrf_init (void) if (debug_vrf) zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__); - vrf_list = list_new (); - vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func; - /* The default VRF always exists. */ default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME); if (!default_vrf) diff --git a/lib/vrf.h b/lib/vrf.h index 4ee871b332..9dfaae21fc 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -70,7 +70,7 @@ enum { struct vrf { - RB_ENTRY(vrf) id_entry; + RB_ENTRY(vrf) id_entry, name_entry; /* Identifier, same as the vector index */ vrf_id_t vrf_id; @@ -92,11 +92,13 @@ struct vrf }; RB_HEAD (vrf_id_head, vrf); RB_PROTOTYPE (vrf_id_head, vrf, id_entry, vrf_id_compare) +RB_HEAD (vrf_name_head, vrf); +RB_PROTOTYPE (vrf_name_head, vrf, name_entry, vrf_name_compare) DECLARE_QOBJ_TYPE(vrf) extern struct vrf_id_head vrfs_by_id; -extern struct list *vrf_list; +extern struct vrf_name_head vrfs_by_name; /* * Add a specific hook to VRF module. diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index fbb41eb5a8..e28f97d763 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -446,11 +446,10 @@ DEFUN_NOSH (zebra_vrf, static int vrf_config_write (struct vty *vty) { - struct listnode *node; struct vrf *vrf; struct zebra_vrf *zvrf; - for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; if (! zvrf || strcmp (zvrf->name, VRF_DEFAULT_NAME)) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 444d251357..3aa7ada917 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -3677,9 +3677,8 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd) struct zebra_vrf *zvrf; char buf[BUFSIZ]; int write =0; - struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; if (! zvrf) @@ -5789,9 +5788,8 @@ static_config_ipv6 (struct vty *vty) struct route_table *stable; struct vrf *vrf; struct zebra_vrf *zvrf; - struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; if (! zvrf) @@ -5886,9 +5884,8 @@ DEFUN (show_vrf, { struct vrf *vrf; struct zebra_vrf *zvrf; - struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf)) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; if (! zvrf || ! zvrf->vrf_id) From a62c490110765542690860776f44628657a86169 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 29 Oct 2016 20:44:04 -0200 Subject: [PATCH 15/20] zebra: order VRFs by name on user output Signed-off-by: Renato Westphal --- lib/if.c | 2 +- zebra/interface.c | 8 ++++---- zebra/router-id.c | 2 +- zebra/zebra_ptm.c | 2 +- zebra/zebra_vty.c | 40 ++++++++++++++++++++-------------------- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/lib/if.c b/lib/if.c index 6df4942296..6f892e783e 100644 --- a/lib/if.c +++ b/lib/if.c @@ -887,7 +887,7 @@ DEFUN (show_address_vrf_all, struct connected *ifc; struct prefix *p; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if (!vrf->iflist || !listcount (vrf->iflist)) continue; diff --git a/zebra/interface.c b/zebra/interface.c index d5d6ffd9f0..7fd0259d2a 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1332,7 +1332,7 @@ DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd, interface_update_stats (); /* All interface print. */ - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) if_dump_vty (vty, ifp); @@ -1385,7 +1385,7 @@ DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd, interface_update_stats (); /* All interface print. */ - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { /* Specified interface print. */ ifp = if_lookup_by_name_vrf (argv[0], vrf->vrf_id); @@ -1486,7 +1486,7 @@ DEFUN (show_interface_desc_vrf_all, { struct vrf *vrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if (!list_isempty (vrf->iflist)) { vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id, @@ -2823,7 +2823,7 @@ if_config_write (struct vty *vty) zebra_ptm_write (vty); - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) { struct zebra_if *if_data; diff --git a/zebra/router-id.c b/zebra/router-id.c index 155a8e3939..0799611399 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -198,7 +198,7 @@ router_id_write (struct vty *vty) struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) if (zvrf->rid_user_assigned.u.prefix4.s_addr) { diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 4fc1173241..fe1f6e0e6f 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -265,7 +265,7 @@ DEFUN (zebra_ptm_enable, ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp)) if (!ifp->ptm_enable) { diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 3aa7ada917..d069c31893 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -2572,7 +2572,7 @@ DEFUN (show_ip_nht_vrf_all, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) { vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); @@ -2617,7 +2617,7 @@ DEFUN (show_ipv6_nht_vrf_all, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) { vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); @@ -3292,7 +3292,7 @@ DEFUN (show_ip_route_vrf_all, int first = 1; int vrf_header = 1; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3343,7 +3343,7 @@ DEFUN (show_ip_route_vrf_all_tag, if (argv[0]) tag = atol(argv[0]); - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3401,7 +3401,7 @@ DEFUN (show_ip_route_vrf_all_prefix_longer, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3449,7 +3449,7 @@ DEFUN (show_ip_route_vrf_all_supernets, int first = 1; int vrf_header = 1; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3510,7 +3510,7 @@ DEFUN (show_ip_route_vrf_all_protocol, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3563,7 +3563,7 @@ DEFUN (show_ip_route_vrf_all_addr, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3604,7 +3604,7 @@ DEFUN (show_ip_route_vrf_all_prefix, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -3639,7 +3639,7 @@ DEFUN (show_ip_route_vrf_all_summary, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); @@ -3659,7 +3659,7 @@ DEFUN (show_ip_route_vrf_all_summary_prefix, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); @@ -5420,7 +5420,7 @@ DEFUN (show_ipv6_route_vrf_all, int first = 1; int vrf_header = 1; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5471,7 +5471,7 @@ DEFUN (show_ipv6_route_vrf_all_tag, if (argv[0]) tag = atol(argv[0]); - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) @@ -5530,7 +5530,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5585,7 +5585,7 @@ DEFUN (show_ipv6_route_vrf_all_protocol, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5638,7 +5638,7 @@ DEFUN (show_ipv6_route_vrf_all_addr, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5679,7 +5679,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix, return CMD_WARNING; } - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5714,7 +5714,7 @@ DEFUN (show_ipv6_route_vrf_all_summary, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); @@ -5736,7 +5736,7 @@ DEFUN (show_ipv6_mroute_vrf_all, struct zebra_vrf *zvrf; int first = 1; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { if ((zvrf = vrf->info) == NULL || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) @@ -5770,7 +5770,7 @@ DEFUN (show_ipv6_route_vrf_all_summary_prefix, struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); From 05e8e11e54a38cb9d6ed9c2522b557231197b1bc Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sat, 29 Oct 2016 22:44:06 -0200 Subject: [PATCH 16/20] lib/zebra: put vrf_get() on a diet Also, for some reason we had two functions to search a VRF by its name: zebra_vrf_lookup_by_name() and zebra_vrf_list_lookup_by_name(). The first one would loop through vrf_table and the other one through vrf_list. This is not necessary anymore, so remove zebra_vrf_lookup_by_name() and rename zebra_vrf_list_lookup_by_name() to zebra_vrf_lookup_by_name(). Signed-off-by: Renato Westphal --- lib/vrf.c | 219 +++++++++++---------------------------------- lib/vrf.h | 3 +- zebra/if_netlink.c | 7 -- zebra/zebra_vrf.c | 6 +- zebra/zebra_vrf.h | 2 +- zebra/zebra_vty.c | 8 +- 6 files changed, 62 insertions(+), 183 deletions(-) diff --git a/lib/vrf.c b/lib/vrf.c index 3def16151a..aa1bfeeabd 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -64,7 +64,7 @@ static void vrf_disable (struct vrf *vrf); /* VRF list existance check by name. */ struct vrf * -vrf_list_lookup_by_name (const char *name) +vrf_lookup_by_name (const char *name) { struct vrf vrf; strlcpy (vrf.name, name, sizeof (vrf.name)); @@ -93,157 +93,59 @@ vrf_name_compare (struct vrf *a, struct vrf *b) struct vrf * vrf_get (vrf_id_t vrf_id, const char *name) { - struct vrf *vrf; + struct vrf *vrf = NULL; + int new = 0; if (debug_vrf) zlog_debug ("VRF_GET: %s(%d)", name, vrf_id); - /* - * Nothing to see, move along here - */ + /* Nothing to see, move along here */ if (!name && vrf_id == VRF_UNKNOWN) return NULL; - /* - * Valid vrf name and unknown vrf_id case - * - * This is called when we are configured from - * the cli but we have no kernel information yet. - */ - if (name && vrf_id == VRF_UNKNOWN) - { - vrf = vrf_list_lookup_by_name (name); - if (vrf) - return vrf; + /* Try to find VRF both by ID and name */ + if (vrf_id != VRF_UNKNOWN) + vrf = vrf_lookup_by_id (vrf_id); + if (! vrf && name) + vrf = vrf_lookup_by_name (name); + if (vrf == NULL) + { vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); - if (debug_vrf) - zlog_debug ("VRF(%u) %s is created.", - vrf_id, (name) ? name : "(NULL)"); - strcpy (vrf->name, name); vrf->vrf_id = VRF_UNKNOWN; - RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); if_init (&vrf->iflist); QOBJ_REG (vrf, vrf); - if (vrf_master.vrf_new_hook) - { - (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); + new = 1; - if (debug_vrf && vrf->info) - zlog_info ("zvrf is created."); - } if (debug_vrf) - zlog_debug("Vrf Created: %p", vrf); - return vrf; + zlog_debug ("VRF(%u) %s is created.", + vrf_id, (name) ? name : "(NULL)"); } - /* - * Valid vrf name and valid vrf_id case - * - * This can be passed from the kernel - */ - else if (name && vrf_id != VRF_UNKNOWN) + + /* Set identifier */ + if (vrf_id != VRF_UNKNOWN && vrf->vrf_id == VRF_UNKNOWN) { - vrf = vrf_list_lookup_by_name (name); - if (vrf) - { - /* - * If the passed in vrf_id and name match - * return, nothing to do here. - */ - if (vrf->vrf_id == vrf_id) - return vrf; - - vrf->vrf_id = vrf_id; - RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); - if (vrf_master.vrf_new_hook) - (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); - - if (debug_vrf) - zlog_debug("Vrf found matched stuff up: %p", vrf); - - return vrf; - } - else - { - /* - * We can have 1 of two situations here - * We've already been told about the vrf_id - * or we haven't. - */ - vrf = vrf_lookup_by_id (vrf_id); - if (vrf) - { - /* - * We know at this point that the vrf->name is not - * right because we would have caught it above. - * so let's set it. - */ - strcpy (vrf->name, name); - RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); - if (vrf_master.vrf_new_hook) - { - (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); - - if (debug_vrf && vrf->info) - zlog_info ("zvrf is created."); - } - if (debug_vrf) - zlog_debug("Vrf Created: %p", vrf); - return vrf; - } - else - { - vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); - vrf->vrf_id = vrf_id; - strcpy (vrf->name, name); - RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); - RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); - if_init (&vrf->iflist); - QOBJ_REG (vrf, vrf); - if (vrf_master.vrf_new_hook) - { - (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); - - if (debug_vrf && vrf->info) - zlog_info ("zvrf is created."); - } - if (debug_vrf) - zlog_debug("Vrf Created: %p", vrf); - return vrf; - } - } + vrf->vrf_id = vrf_id; + RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); } - /* - * The final case, we've been passed a valid vrf_id - * but no name. So we create the route node - * if it hasn't already been created. - */ - else if (!name) + + /* Set name */ + if (name && vrf->name[0] != '\0' && strcmp (name, vrf->name)) { - vrf = vrf_lookup_by_id (vrf_id); - if (debug_vrf) - zlog_debug("Vrf found: %p", vrf); - - if (vrf) - return vrf; - else - { - vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); - vrf->vrf_id = vrf_id; - if_init (&vrf->iflist); - RB_INSERT (vrf_id_head, &vrfs_by_id, vrf); - QOBJ_REG (vrf, vrf); - if (debug_vrf) - zlog_debug("Vrf Created: %p", vrf); - return vrf; - } + RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf); + strlcpy (vrf->name, name, sizeof (vrf->name)); + RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); + } + else if (name && vrf->name[0] == '\0') + { + strlcpy (vrf->name, name, sizeof (vrf->name)); + RB_INSERT (vrf_name_head, &vrfs_by_name, vrf); } - /* - * We shouldn't get here and if we do - * something has gone wrong. - */ - return NULL; + if (new && vrf_master.vrf_new_hook) + (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); + + return vrf; } /* Delete a VRF. This is called in vrf_terminate(). */ @@ -264,7 +166,8 @@ vrf_delete (struct vrf *vrf) if (vrf->vrf_id != VRF_UNKNOWN) RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf); - RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf); + if (vrf->name[0] != '\0') + RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf); XFREE (MTYPE_VRF, vrf); } @@ -279,18 +182,12 @@ vrf_lookup_by_id (vrf_id_t vrf_id) } /* - * Check whether the VRF is enabled - that is, whether the VRF - * is ready to allocate resources. Currently there's only one - * type of resource: socket. + * Check whether the VRF is enabled. */ static int vrf_is_enabled (struct vrf *vrf) { return vrf && CHECK_FLAG (vrf->status, VRF_ACTIVE); - - /*Pending: figure out the real use of this routine.. it used to be.. - return vrf && vrf->vrf_id == VRF_DEFAULT; - */ } /* @@ -303,11 +200,13 @@ vrf_is_enabled (struct vrf *vrf) int vrf_enable (struct vrf *vrf) { + if (vrf_is_enabled (vrf)) + return 1; + if (debug_vrf) zlog_debug ("VRF %u is enabled.", vrf->vrf_id); - if (!CHECK_FLAG (vrf->status, VRF_ACTIVE)) - SET_FLAG (vrf->status, VRF_ACTIVE); + SET_FLAG (vrf->status, VRF_ACTIVE); if (vrf_master.vrf_enable_hook) (*vrf_master.vrf_enable_hook) (vrf->vrf_id, vrf->name, &vrf->info); @@ -323,20 +222,19 @@ vrf_enable (struct vrf *vrf) static void vrf_disable (struct vrf *vrf) { - if (vrf_is_enabled (vrf)) - { - UNSET_FLAG (vrf->status, VRF_ACTIVE); + if (! vrf_is_enabled (vrf)) + return; - if (debug_vrf) - zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id); + UNSET_FLAG (vrf->status, VRF_ACTIVE); - /* Till now, nothing to be done for the default VRF. */ - //Pending: see why this statement. + if (debug_vrf) + zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id); - if (vrf_master.vrf_disable_hook) - (*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info); - } + /* Till now, nothing to be done for the default VRF. */ + //Pending: see why this statement. + if (vrf_master.vrf_disable_hook) + (*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info); } @@ -366,19 +264,6 @@ vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **)) } } -/* Look up a VRF by name. */ -struct vrf * -vrf_lookup_by_name (const char *name) -{ - struct vrf *vrf; - - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) - if (!strcmp(vrf->name, name)) - return vrf; - - return NULL; -} - vrf_id_t vrf_name_to_id (const char *name) { @@ -571,6 +456,8 @@ vrf_terminate (void) while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL) vrf_delete (vrf); + while ((vrf = RB_ROOT (&vrfs_by_name)) != NULL) + vrf_delete (vrf); } /* Create a socket for the VRF. */ @@ -618,7 +505,7 @@ DEFUN_NOSH (no_vrf, { struct vrf *vrfp; - vrfp = vrf_list_lookup_by_name (argv[0]); + vrfp = vrf_lookup_by_name (argv[0]); if (vrfp == NULL) { diff --git a/lib/vrf.h b/lib/vrf.h index 9dfaae21fc..feaf768969 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -112,7 +112,6 @@ extern void vrf_add_hook (int, int (*)(vrf_id_t, const char *, void **)); extern struct vrf *vrf_lookup_by_id (vrf_id_t); extern struct vrf *vrf_lookup_by_name (const char *); -extern struct vrf *vrf_list_lookup_by_name (const char *); extern struct vrf *vrf_get (vrf_id_t, const char *); extern void vrf_delete (struct vrf *); extern int vrf_enable (struct vrf *); @@ -121,7 +120,7 @@ extern vrf_id_t vrf_name_to_id (const char *); #define VRF_GET_ID(V,NAME) \ do { \ struct vrf *vrf; \ - if (!(vrf = vrf_list_lookup_by_name(NAME))) \ + if (!(vrf = vrf_lookup_by_name(NAME))) \ { \ vty_out (vty, "%% VRF %s not found%s", NAME, VTY_NEWLINE);\ return CMD_WARNING; \ diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index abf1c781a3..be7a5ac78d 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -208,13 +208,6 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name) if (h->nlmsg_type == RTM_NEWLINK) { - /* If VRF already exists, we just return; status changes are handled - * against the VRF "interface". - */ - vrf = vrf_lookup_by_id ((vrf_id_t)ifi->ifi_index); - if (vrf && vrf->info) - return; - if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug ("RTM_NEWLINK for VRF %s(%u) table %u", name, ifi->ifi_index, nl_table_id); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index e28f97d763..94e5d49c2c 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -87,7 +87,7 @@ zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info) if (! zvrf) { - zvrf = zebra_vrf_list_lookup_by_name (name); + zvrf = zebra_vrf_lookup_by_name (name); if (!zvrf) { zvrf = zebra_vrf_alloc (vrf_id, name); @@ -345,14 +345,14 @@ zebra_vrf_lookup_by_id (vrf_id_t vrf_id) /* Lookup VRF by name. */ struct zebra_vrf * -zebra_vrf_list_lookup_by_name (const char *name) +zebra_vrf_lookup_by_name (const char *name) { struct vrf *vrf; if (!name) name = VRF_DEFAULT_NAME; - vrf = vrf_list_lookup_by_name (name); + vrf = vrf_lookup_by_name (name); if (vrf) return ((struct zebra_vrf *) vrf->info); diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index c7814e6c99..8247365644 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -93,7 +93,7 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, extern void zebra_vrf_static_route_interface_fixup (struct interface *ifp); extern void zebra_vrf_update_all (struct zserv *client); extern struct zebra_vrf *zebra_vrf_lookup_by_id (vrf_id_t vrf_id); -extern struct zebra_vrf *zebra_vrf_list_lookup_by_name (const char *); +extern struct zebra_vrf *zebra_vrf_lookup_by_name (const char *); extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *); extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t); extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, struct zebra_vrf *zvrf); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index d069c31893..4ae12559ad 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -107,7 +107,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd, tag = atol(tag_str); /* VRF id */ - zvrf = zebra_vrf_list_lookup_by_name (vrf_id_str); + zvrf = zebra_vrf_lookup_by_name (vrf_id_str); if (!zvrf) { @@ -2450,7 +2450,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi, json_object *json = NULL; json_object *json_prefix = NULL; - if (!(zvrf = zebra_vrf_list_lookup_by_name (vrf_name))) + if (!(zvrf = zebra_vrf_lookup_by_name (vrf_name))) { if (use_json) vty_out (vty, "{}%s", VTY_NEWLINE); @@ -3784,7 +3784,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str, ret = inet_pton (AF_INET6, gate_str, &gate_addr); /* VRF id */ - zvrf = zebra_vrf_list_lookup_by_name (vrf_id_str); + zvrf = zebra_vrf_lookup_by_name (vrf_id_str); if (!zvrf) { @@ -4925,7 +4925,7 @@ DEFUN (show_ipv6_route, if (argc > 0 && argv[0] && strcmp(argv[0], "json") != 0) { - if (!(zvrf = zebra_vrf_list_lookup_by_name (argv[0]))) + if (!(zvrf = zebra_vrf_lookup_by_name (argv[0]))) { if (uj) vty_out (vty, "{}%s", VTY_NEWLINE); From 661512bf053ecc3d441bb8938dcd4541ae7ffc33 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Sun, 30 Oct 2016 19:50:26 -0200 Subject: [PATCH 17/20] zebra/lib: remove redundant fields from zebra_vrf There's no need to duplicate the 'vrf_id' and 'name' fields from the 'vrf' structure into the 'zebra_vrf' structure. Instead of that, add a back pointer in 'zebra_vrf' that should point to the associated 'vrf' structure. Additionally, modify the vrf callbacks to pass the whole vrf structure as a parameter. This allow us to make further simplifications in the code. Signed-off-by: Renato Westphal --- bgpd/bgp_main.c | 32 +++++++----------- lib/vrf.c | 18 +++++----- lib/vrf.h | 2 +- zebra/redistribute.c | 16 ++++----- zebra/router-id.c | 16 ++++----- zebra/rt_netlink.c | 4 +-- zebra/rtadv.c | 8 ++--- zebra/zebra_fpm.c | 2 +- zebra/zebra_fpm_netlink.c | 2 +- zebra/zebra_mpls.c | 4 +-- zebra/zebra_ptm.c | 8 ++--- zebra/zebra_rib.c | 32 +++++++++--------- zebra/zebra_static.c | 2 +- zebra/zebra_vrf.c | 69 +++++++++++++-------------------------- zebra/zebra_vrf.h | 21 ++++++++---- zebra/zebra_vty.c | 58 ++++++++++++++++---------------- zebra/zserv.c | 58 ++++++++++++++++---------------- 17 files changed, 164 insertions(+), 188 deletions(-) diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 4e31eb344c..91eacc9320 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -308,38 +308,33 @@ bgp_exit (int status) } static int -bgp_vrf_new (vrf_id_t vrf_id, const char *name, void **info) +bgp_vrf_new (struct vrf *vrf) { if (BGP_DEBUG (zebra, ZEBRA)) - zlog_debug ("VRF Created: %s(%d)", name, vrf_id); + zlog_debug ("VRF Created: %s(%d)", vrf->name, vrf->vrf_id); return 0; } static int -bgp_vrf_delete (vrf_id_t vrf_id, const char *name, void **info) +bgp_vrf_delete (struct vrf *vrf) { if (BGP_DEBUG (zebra, ZEBRA)) - zlog_debug ("VRF Deletion: %s(%d)", name, vrf_id); + zlog_debug ("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id); return 0; } static int -bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) +bgp_vrf_enable (struct vrf *vrf) { - struct vrf *vrf; struct bgp *bgp; vrf_id_t old_vrf_id; - vrf = vrf_lookup_by_id (vrf_id); - if (!vrf) // unexpected - return -1; - if (BGP_DEBUG (zebra, ZEBRA)) - zlog_debug("VRF enable add %s id %d", name, vrf_id); + zlog_debug("VRF enable add %s id %d", vrf->name, vrf->vrf_id); - bgp = bgp_lookup_by_name(name); + bgp = bgp_lookup_by_name (vrf->name); if (bgp) { old_vrf_id = bgp->vrf_id; @@ -356,23 +351,18 @@ bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) } static int -bgp_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) +bgp_vrf_disable (struct vrf *vrf) { - struct vrf *vrf; struct bgp *bgp; vrf_id_t old_vrf_id; - if (vrf_id == VRF_DEFAULT) + if (vrf->vrf_id == VRF_DEFAULT) return 0; - vrf = vrf_lookup_by_id (vrf_id); - if (!vrf) // unexpected - return -1; - if (BGP_DEBUG (zebra, ZEBRA)) - zlog_debug("VRF disable %s id %d", name, vrf_id); + zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id); - bgp = bgp_lookup_by_name(name); + bgp = bgp_lookup_by_name (vrf->name); if (bgp) { old_vrf_id = bgp->vrf_id; diff --git a/lib/vrf.c b/lib/vrf.c index aa1bfeeabd..39d8a89a7c 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -53,10 +53,10 @@ int debug_vrf = 0; /* Holding VRF hooks */ struct vrf_master { - int (*vrf_new_hook) (vrf_id_t, const char *, void **); - int (*vrf_delete_hook) (vrf_id_t, const char *, void **); - int (*vrf_enable_hook) (vrf_id_t, const char *, void **); - int (*vrf_disable_hook) (vrf_id_t, const char *, void **); + int (*vrf_new_hook) (struct vrf *); + int (*vrf_delete_hook) (struct vrf *); + int (*vrf_enable_hook) (struct vrf *); + int (*vrf_disable_hook) (struct vrf *); } vrf_master = {0,}; static int vrf_is_enabled (struct vrf *vrf); @@ -143,7 +143,7 @@ vrf_get (vrf_id_t vrf_id, const char *name) } if (new && vrf_master.vrf_new_hook) - (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); + (*vrf_master.vrf_new_hook) (vrf); return vrf; } @@ -159,7 +159,7 @@ vrf_delete (struct vrf *vrf) vrf_disable (vrf); if (vrf_master.vrf_delete_hook) - (*vrf_master.vrf_delete_hook) (vrf->vrf_id, vrf->name, &vrf->info); + (*vrf_master.vrf_delete_hook) (vrf); QOBJ_UNREG (vrf); if_terminate (&vrf->iflist); @@ -209,7 +209,7 @@ vrf_enable (struct vrf *vrf) SET_FLAG (vrf->status, VRF_ACTIVE); if (vrf_master.vrf_enable_hook) - (*vrf_master.vrf_enable_hook) (vrf->vrf_id, vrf->name, &vrf->info); + (*vrf_master.vrf_enable_hook) (vrf); return 1; } @@ -234,13 +234,13 @@ vrf_disable (struct vrf *vrf) //Pending: see why this statement. if (vrf_master.vrf_disable_hook) - (*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info); + (*vrf_master.vrf_disable_hook) (vrf); } /* Add a VRF hook. Please add hooks before calling vrf_init(). */ void -vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **)) +vrf_add_hook (int type, int (*func)(struct vrf *)) { if (debug_vrf) zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__, diff --git a/lib/vrf.h b/lib/vrf.h index feaf768969..c9e81bf669 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -108,7 +108,7 @@ extern struct vrf_name_head vrfs_by_name; * - param 2: the address of the user data pointer (the user data * can be stored in or freed from there) */ -extern void vrf_add_hook (int, int (*)(vrf_id_t, const char *, void **)); +extern void vrf_add_hook (int, int (*)(struct vrf *)); extern struct vrf *vrf_lookup_by_id (vrf_id_t); extern struct vrf *vrf_lookup_by_name (const char *); diff --git a/zebra/redistribute.c b/zebra/redistribute.c index c74485bb35..9c7ef5f12c 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -262,13 +262,13 @@ zebra_redistribute_add (int command, struct zserv *client, int length, if (! redist_check_instance (&client->mi_redist[afi][type], instance)) { redist_add_instance (&client->mi_redist[afi][type], instance); - zebra_redistribute (client, type, instance, zvrf->vrf_id); + zebra_redistribute (client, type, instance, zvrf_id (zvrf)); } } else { - if (! vrf_bitmap_check (client->redist[afi][type], zvrf->vrf_id)) + if (! vrf_bitmap_check (client->redist[afi][type], zvrf_id (zvrf))) { - vrf_bitmap_set (client->redist[afi][type], zvrf->vrf_id); - zebra_redistribute (client, type, 0, zvrf->vrf_id); + vrf_bitmap_set (client->redist[afi][type], zvrf_id (zvrf)); + zebra_redistribute (client, type, 0, zvrf_id (zvrf)); } } } @@ -296,22 +296,22 @@ zebra_redistribute_delete (int command, struct zserv *client, int length, if (instance) redist_del_instance (&client->mi_redist[afi][type], instance); else - vrf_bitmap_unset (client->redist[afi][type], zvrf->vrf_id); + vrf_bitmap_unset (client->redist[afi][type], zvrf_id (zvrf)); } void zebra_redistribute_default_add (int command, struct zserv *client, int length, struct zebra_vrf *zvrf) { - vrf_bitmap_set (client->redist_default, zvrf->vrf_id); - zebra_redistribute_default (client, zvrf->vrf_id); + vrf_bitmap_set (client->redist_default, zvrf_id (zvrf)); + zebra_redistribute_default (client, zvrf_id (zvrf)); } void zebra_redistribute_default_delete (int command, struct zserv *client, int length, struct zebra_vrf *zvrf) { - vrf_bitmap_unset (client->redist_default, zvrf->vrf_id); + vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf)); } /* Interface up information. */ diff --git a/zebra/router-id.c b/zebra/router-id.c index 0799611399..0aa1bdc770 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -138,7 +138,7 @@ router_id_add_address (struct connected *ifc) if (router_id_bad_address (ifc)) return; - router_id_get (&before, zvrf->vrf_id); + router_id_get (&before, zvrf_id (zvrf)); if (!strncmp (ifc->ifp->name, "lo", 2) || !strncmp (ifc->ifp->name, "dummy", 5)) @@ -149,13 +149,13 @@ router_id_add_address (struct connected *ifc) if (!router_id_find_node (l, ifc)) listnode_add_sort (l, ifc); - router_id_get (&after, zvrf->vrf_id); + router_id_get (&after, zvrf_id (zvrf)); if (prefix_same (&before, &after)) return; for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) - zsend_router_id_update (client, &after, zvrf->vrf_id); + zsend_router_id_update (client, &after, zvrf_id (zvrf)); } void @@ -172,7 +172,7 @@ router_id_del_address (struct connected *ifc) if (router_id_bad_address (ifc)) return; - router_id_get (&before, zvrf->vrf_id); + router_id_get (&before, zvrf_id (zvrf)); if (!strncmp (ifc->ifp->name, "lo", 2) || !strncmp (ifc->ifp->name, "dummy", 5)) @@ -183,13 +183,13 @@ router_id_del_address (struct connected *ifc) if ((c = router_id_find_node (l, ifc))) listnode_delete (l, c); - router_id_get (&after, zvrf->vrf_id); + router_id_get (&after, zvrf_id (zvrf)); if (prefix_same (&before, &after)) return; for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) - zsend_router_id_update (client, &after, zvrf->vrf_id); + zsend_router_id_update (client, &after, zvrf_id (zvrf)); } void @@ -202,14 +202,14 @@ router_id_write (struct vty *vty) if ((zvrf = vrf->info) != NULL) if (zvrf->rid_user_assigned.u.prefix4.s_addr) { - if (zvrf->vrf_id == VRF_DEFAULT) + if (zvrf_id (zvrf) == VRF_DEFAULT) vty_out (vty, "router-id %s%s", inet_ntoa (zvrf->rid_user_assigned.u.prefix4), VTY_NEWLINE); else vty_out (vty, "router-id %s vrf %s%s", inet_ntoa (zvrf->rid_user_assigned.u.prefix4), - zvrf->name, + zvrf_name (zvrf), VTY_NEWLINE); } } diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index b18bf1ef7a..c04f9188fa 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -107,7 +107,7 @@ vrf_lookup_by_table (u_int32_t table_id) (zvrf->table_id != table_id)) continue; - return zvrf->vrf_id; + return zvrf_id (zvrf); } return VRF_DEFAULT; @@ -1069,7 +1069,7 @@ _netlink_route_debug( zlog_debug ("netlink_route_multipath() (%s): %s %s vrf %u type %s", routedesc, nl_msg_type_to_str (cmd), - prefix2str (p, buf, sizeof(buf)), zvrf->vrf_id, + prefix2str (p, buf, sizeof(buf)), zvrf_id (zvrf), (nexthop) ? nexthop_type_to_str (nexthop->type) : "UNK"); } } diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 1ab7ac147c..26c83bc6ac 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -826,7 +826,7 @@ zebra_interface_radv_set (struct zserv *client, int sock, u_short length, if (IS_ZEBRA_DEBUG_EVENT) zlog_debug("%u: IF %u RA %s from client %s, interval %ds", - zvrf->vrf_id, ifindex, enable ? "enable" : "disable", + zvrf_id (zvrf), ifindex, enable ? "enable" : "disable", zebra_route_string(client->proto), ra_interval); /* Locate interface and check VRF match. */ @@ -834,14 +834,14 @@ zebra_interface_radv_set (struct zserv *client, int sock, u_short length, if (!ifp) { zlog_warn("%u: IF %u RA %s client %s - interface unknown", - zvrf->vrf_id, ifindex, enable ? "enable" : "disable", + zvrf_id (zvrf), ifindex, enable ? "enable" : "disable", zebra_route_string(client->proto)); return; } - if (ifp->vrf_id != zvrf->vrf_id) + if (ifp->vrf_id != zvrf_id (zvrf)) { zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u", - zvrf->vrf_id, ifindex, enable ? "enable" : "disable", + zvrf_id (zvrf), ifindex, enable ? "enable" : "disable", zebra_route_string(client->proto), ifp->vrf_id); return; } diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 343ce1776c..5920cde29e 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -348,7 +348,7 @@ zfpm_is_table_for_fpm (struct route_table *table) * We only send the unicast tables in the main instance to the FPM * at this point. */ - if (info->zvrf->vrf_id != 0) + if (zvrf_id (info->zvrf) != 0) return 0; if (info->safi != SAFI_UNICAST) diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index 6543298605..be77e91a53 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -245,7 +245,7 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd, ri->af = rib_dest_af (dest); ri->nlmsg_type = cmd; - ri->rtm_table = rib_dest_vrf (dest)->vrf_id; + ri->rtm_table = zvrf_id (rib_dest_vrf (dest)); ri->rtm_protocol = RTPROT_UNSPEC; /* diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index b64cab625d..2ed0ce7673 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -1268,7 +1268,7 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type, struct nexthop *nexthop; /* Lookup table. */ - table = zebra_vrf_table (family2afi(prefix->family), SAFI_UNICAST, zvrf->vrf_id); + table = zebra_vrf_table (family2afi(prefix->family), SAFI_UNICAST, zvrf_id (zvrf)); if (! table) return -1; @@ -1502,7 +1502,7 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi) int update; /* Process routes of interested address-families. */ - table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf->vrf_id); + table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf_id (zvrf)); if (!table) return; diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index fe1f6e0e6f..e6d13b5070 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -768,9 +768,9 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length, ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD, tmp_buf); - if (zvrf->vrf_id != VRF_DEFAULT) + if (zvrf_id (zvrf) != VRF_DEFAULT) ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD, - zvrf->name); + zvrf_name (zvrf)); } else { @@ -915,9 +915,9 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length, ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); } #endif /* HAVE_IPV6 */ - if (zvrf->vrf_id != VRF_DEFAULT) + if (zvrf_id (zvrf) != VRF_DEFAULT) ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD, - zvrf->name); + zvrf_name (zvrf)); } else { diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 9d9b10457d..54caeba892 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1353,7 +1353,7 @@ rib_gc_dest (struct route_node *rn) zvrf = rib_dest_vrf (dest); if (IS_ZEBRA_DEBUG_RIB) - rnode_debug (rn, zvrf->vrf_id, "removing dest from table"); + rnode_debug (rn, zvrf_id (zvrf), "removing dest from table"); dest->rnode = NULL; XFREE (MTYPE_RIB_DEST, dest); @@ -1386,7 +1386,7 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, { inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type); + zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type); } if (!RIB_SYSTEM_ROUTE (new)) @@ -1395,7 +1395,7 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, { inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_warn ("%u:%s/%d: Route install failed", - zvrf->vrf_id, buf, rn->p.prefixlen); + zvrf_id (zvrf), buf, rn->p.prefixlen); } } @@ -1415,7 +1415,7 @@ rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn, { inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, old, old->type); + zvrf_id (zvrf), buf, rn->p.prefixlen, rn, old, old->type); } if (!RIB_SYSTEM_ROUTE (old)) @@ -1464,11 +1464,11 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, { if (new != old) zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) " - "old %p (type %d)", zvrf->vrf_id, buf, rn->p.prefixlen, + "old %p (type %d)", zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type, old, old->type); else zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type); + zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type); } /* Non-system route should be installed. */ if (!RIB_SYSTEM_ROUTE (new)) @@ -1478,7 +1478,7 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, installed = 0; inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_warn ("%u:%s/%d: Route install failed", - zvrf->vrf_id, buf, rn->p.prefixlen); + zvrf_id (zvrf), buf, rn->p.prefixlen); } } @@ -1512,12 +1512,12 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, { if (new != old) zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) " - "old %p (type %d) - %s", zvrf->vrf_id, buf, rn->p.prefixlen, + "old %p (type %d) - %s", zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type, old, old->type, nh_active ? "install failed" : "nexthop inactive"); else zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) - %s", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type, + zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type, nh_active ? "install failed" : "nexthop inactive"); } @@ -1627,7 +1627,7 @@ rib_process (struct route_node *rn) if (dest) { zvrf = rib_dest_vrf (dest); - vrf_id = zvrf->vrf_id; + vrf_id = zvrf_id (zvrf); } if (IS_ZEBRA_DEBUG_RIB) @@ -2027,7 +2027,7 @@ process_subq (struct list * subq, u_char qindex) { inet_ntop (rnode->p.family, &rnode->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_debug ("%u:%s/%d: rn %p dequeued from sub-queue %u", - zvrf ? zvrf->vrf_id : 0, buf, rnode->p.prefixlen, rnode, qindex); + zvrf ? zvrf_id (zvrf) : 0, buf, rnode->p.prefixlen, rnode, qindex); } if (rnode->info) @@ -2066,10 +2066,10 @@ meta_queue_process_complete (struct work_queue *dummy) continue; zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED; - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); - zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL); + zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); + zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); + zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL); } /* Schedule LSPs for processing, if needed. */ @@ -2077,7 +2077,7 @@ meta_queue_process_complete (struct work_queue *dummy) if (mpls_should_lsps_be_processed(zvrf)) { if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug ("%u: Scheduling all LSPs upon RIB completion", zvrf->vrf_id); + zlog_debug ("%u: Scheduling all LSPs upon RIB completion", zvrf_id (zvrf)); zebra_mpls_lsp_schedule (zvrf); mpls_unmark_lsps_for_processing(zvrf); } diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 32ba90ef9a..a7a68bd0de 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -422,7 +422,7 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, si->distance = distance; si->flags = flags; si->tag = tag; - si->vrf_id = zvrf->vrf_id; + si->vrf_id = zvrf_id (zvrf); si->ifindex = ifindex; if (si->ifindex) strcpy(si->ifname, ifname); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 94e5d49c2c..fbfa70d63f 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -45,7 +45,7 @@ zebra_vrf_add_update (struct zebra_vrf *zvrf) struct zserv *client; if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf->name); + zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf_name (zvrf)); for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) zsend_vrf_add (client, zvrf); @@ -58,7 +58,7 @@ zebra_vrf_delete_update (struct zebra_vrf *zvrf) struct zserv *client; if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf->name); + zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf_name (zvrf)); for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) zsend_vrf_delete (client, zvrf); @@ -78,32 +78,18 @@ zebra_vrf_update_all (struct zserv *client) /* Callback upon creating a new VRF. */ static int -zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info) +zebra_vrf_new (struct vrf *vrf) { - struct zebra_vrf *zvrf = *info; + struct zebra_vrf *zvrf; if (IS_ZEBRA_DEBUG_EVENT) - zlog_info ("ZVRF %s with id %u", name, vrf_id); + zlog_info ("ZVRF %s with id %u", vrf->name, vrf->vrf_id); - if (! zvrf) - { - zvrf = zebra_vrf_lookup_by_name (name); - if (!zvrf) - { - zvrf = zebra_vrf_alloc (vrf_id, name); - zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */ - *info = (void *)zvrf; - router_id_init (zvrf); - } - else - { - *info = (void *)zvrf; - router_id_init (zvrf); - } - } - - if (zvrf->vrf_id == VRF_UNKNOWN) - zvrf->vrf_id = vrf_id; + zvrf = zebra_vrf_alloc (); + zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */ + router_id_init (zvrf); + vrf->info = zvrf; + zvrf->vrf = vrf; return 0; } @@ -154,9 +140,9 @@ zebra_vrf_static_route_interface_fixup (struct interface *ifp) /* Callback upon enabling a VRF. */ static int -zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) +zebra_vrf_enable (struct vrf *vrf) { - struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); + struct zebra_vrf *zvrf = vrf->info; struct route_table *stable = NULL; struct route_node *rn = NULL; struct static_route *si = NULL; @@ -180,7 +166,7 @@ zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) if (rn->info) { si = rn->info; - si->vrf_id = vrf_id; + si->vrf_id = vrf->vrf_id; if (si->ifindex) { ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id); @@ -200,9 +186,9 @@ zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) /* Callback upon disabling a VRF. */ static int -zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) +zebra_vrf_disable (struct vrf *vrf) { - struct zebra_vrf *zvrf = (struct zebra_vrf *)(*info); + struct zebra_vrf *zvrf = vrf->info; struct route_table *stable = NULL; struct route_node *rn = NULL; afi_t afi; @@ -210,7 +196,7 @@ zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug ("VRF %s id %u is now disabled.", - zvrf->name, zvrf->vrf_id); + zvrf_name (zvrf), zvrf_id (zvrf)); for (afi = AFI_IP; afi < AFI_MAX; afi++) { @@ -231,9 +217,9 @@ zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) } static int -zebra_vrf_delete (vrf_id_t vrf_id, const char *name, void **info) +zebra_vrf_delete (struct vrf *vrf) { - struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); + struct zebra_vrf *zvrf = vrf->info; assert (zvrf); @@ -245,9 +231,9 @@ zebra_vrf_delete (vrf_id_t vrf_id, const char *name, void **info) list_delete_all_node (zvrf->rid_all_sorted_list); list_delete_all_node (zvrf->rid_lo_sorted_list); - zvrf->vrf_id = VRF_UNKNOWN; + vrf->vrf_id = VRF_UNKNOWN; + vrf->info = NULL; - *info = NULL; return 0; } @@ -300,7 +286,7 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi) /* Allocate new zebra VRF. */ struct zebra_vrf * -zebra_vrf_alloc (vrf_id_t vrf_id, const char *name) +zebra_vrf_alloc (void) { struct zebra_vrf *zvrf; @@ -322,15 +308,6 @@ zebra_vrf_alloc (vrf_id_t vrf_id, const char *name) zvrf->import_check_table[AFI_IP] = route_table_init(); zvrf->import_check_table[AFI_IP6] = route_table_init(); - /* Set VRF ID */ - zvrf->vrf_id = vrf_id; - - if (name) - { - strncpy (zvrf->name, name, strlen(name)); - zvrf->name[strlen(name)] = '\0'; - } - zebra_mpls_init_tables (zvrf); return zvrf; @@ -452,9 +429,9 @@ vrf_config_write (struct vty *vty) RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; - if (! zvrf || strcmp (zvrf->name, VRF_DEFAULT_NAME)) + if (! zvrf || strcmp (zvrf_name (zvrf), VRF_DEFAULT_NAME)) { - vty_out (vty, "vrf %s%s", zvrf->name, VTY_NEWLINE); + vty_out (vty, "vrf %s%s", zvrf_name (zvrf), VTY_NEWLINE); vty_out (vty, "!%s", VTY_NEWLINE); } } diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 8247365644..8c4f0b4a28 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -28,11 +28,8 @@ /* Routing table instance. */ struct zebra_vrf { - /* Identifier. */ - vrf_id_t vrf_id; - - /* Routing table name. */ - char name[VRF_NAMSIZ]; + /* Back pointer */ + struct vrf *vrf; /* Description. */ char *desc; @@ -86,6 +83,18 @@ struct zebra_vrf #define MPLS_FLAG_SCHEDULE_LSPS (1 << 0) }; +static inline vrf_id_t +zvrf_id (struct zebra_vrf *zvrf) +{ + return zvrf->vrf->vrf_id; +} + +static inline const char * +zvrf_name (struct zebra_vrf *zvrf) +{ + return zvrf->vrf->name; +} + struct route_table * zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, vrf_id_t vrf_id, u_int32_t table_id); @@ -94,7 +103,7 @@ extern void zebra_vrf_static_route_interface_fixup (struct interface *ifp); extern void zebra_vrf_update_all (struct zserv *client); extern struct zebra_vrf *zebra_vrf_lookup_by_id (vrf_id_t vrf_id); extern struct zebra_vrf *zebra_vrf_lookup_by_name (const char *); -extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, 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_static_table (afi_t, safi_t, struct zebra_vrf *zvrf); extern struct route_table *zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 4ae12559ad..84106e7ff9 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -183,7 +183,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd, ret = inet_aton (gate_str, &gate); if (!ret) { - struct interface *ifp = if_lookup_by_name_vrf (gate_str, zvrf->vrf_id); + struct interface *ifp = if_lookup_by_name_vrf (gate_str, zvrf_id (zvrf)); if (!ifp) { vty_out (vty, "%% Unknown interface: %s%s", gate_str, VTY_NEWLINE); @@ -2025,7 +2025,7 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast) if (rib->vrf_id != VRF_DEFAULT) { zvrf = vrf_info_lookup(rib->vrf_id); - vty_out (vty, ", vrf %s", zvrf->name); + vty_out (vty, ", vrf %s", zvrf_name (zvrf)); } if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) vty_out (vty, ", best"); @@ -2459,7 +2459,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi, return CMD_SUCCESS; } - if (zvrf->vrf_id == VRF_UNKNOWN) + if (zvrf_id (zvrf) == VRF_UNKNOWN) { if (use_json) vty_out (vty, "{}%s", VTY_NEWLINE); @@ -2468,7 +2468,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi, return CMD_SUCCESS; } - table = zebra_vrf_table (AFI_IP, safi, zvrf->vrf_id); + table = zebra_vrf_table (AFI_IP, safi, zvrf_id (zvrf)); if (! table) { if (use_json) @@ -2575,8 +2575,8 @@ DEFUN (show_ip_nht_vrf_all, RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); - zebra_print_rnh_table(zvrf->vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); + zebra_print_rnh_table(zvrf_id (zvrf), AF_INET, vty, RNH_NEXTHOP_TYPE); } return CMD_SUCCESS; @@ -2620,8 +2620,8 @@ DEFUN (show_ipv6_nht_vrf_all, RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) if ((zvrf = vrf->info) != NULL) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); - zebra_print_rnh_table(zvrf->vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); + zebra_print_rnh_table(zvrf_id (zvrf), AF_INET6, vty, RNH_NEXTHOP_TYPE); } return CMD_SUCCESS; @@ -3098,7 +3098,7 @@ vty_show_ip_route_summary (struct vty *vty, struct route_table *table) vty_out (vty, "%-20s %-20s %s (vrf %s)%s", "Route Source", "Routes", "FIB", - ((rib_table_info_t *)table->info)->zvrf->name, + zvrf_name (((rib_table_info_t *)table->info)->zvrf), VTY_NEWLINE); for (i = 0; i < ZEBRA_ROUTE_MAX; i++) @@ -3179,7 +3179,7 @@ vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table) vty_out (vty, "%-20s %-20s %s (vrf %s)%s", "Route Source", "Prefix Routes", "FIB", - ((rib_table_info_t *)table->info)->zvrf->name, + zvrf_name (((rib_table_info_t *)table->info)->zvrf), VTY_NEWLINE); for (i = 0; i < ZEBRA_ROUTE_MAX; i++) @@ -3310,7 +3310,7 @@ DEFUN (show_ip_route_vrf_all, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -3364,7 +3364,7 @@ DEFUN (show_ip_route_vrf_all_tag, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -3420,7 +3420,7 @@ DEFUN (show_ip_route_vrf_all_prefix_longer, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -3473,7 +3473,7 @@ DEFUN (show_ip_route_vrf_all_supernets, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -3529,7 +3529,7 @@ DEFUN (show_ip_route_vrf_all_protocol, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -3722,7 +3722,7 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd) vty_out (vty, " %d", si->distance); if (si->vrf_id != VRF_DEFAULT) - vty_out (vty, " vrf %s", zvrf ? zvrf->name : ""); + vty_out (vty, " vrf %s", zvrf ? zvrf_name (zvrf) : ""); /* Label information */ if (si->snh_label.num_labels) @@ -3855,7 +3855,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str, } type = STATIC_IPV6_GATEWAY_IFINDEX; gate = &gate_addr; - ifp = if_lookup_by_name_vrf (ifname, zvrf->vrf_id); + ifp = if_lookup_by_name_vrf (ifname, zvrf_id (zvrf)); if (!ifp) { vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE); @@ -3873,7 +3873,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str, else { type = STATIC_IFINDEX; - ifp = if_lookup_by_name_vrf (gate_str, zvrf->vrf_id); + ifp = if_lookup_by_name_vrf (gate_str, zvrf_id (zvrf)); if (!ifp) { vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE); @@ -4934,7 +4934,7 @@ DEFUN (show_ipv6_route, return CMD_SUCCESS; } - if (zvrf->vrf_id == VRF_UNKNOWN) + if (zvrf_id (zvrf) == VRF_UNKNOWN) { if (uj) vty_out (vty, "{}%s", VTY_NEWLINE); @@ -4943,7 +4943,7 @@ DEFUN (show_ipv6_route, return CMD_SUCCESS; } else - vrf_id = zvrf->vrf_id; + vrf_id = zvrf_id (zvrf); } table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); @@ -5438,7 +5438,7 @@ DEFUN (show_ipv6_route_vrf_all, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -5492,7 +5492,7 @@ DEFUN (show_ipv6_route_vrf_all_tag, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -5549,7 +5549,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -5604,7 +5604,7 @@ DEFUN (show_ipv6_route_vrf_all_protocol, if (vrf_header) { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); vrf_header = 0; } vty_show_ip_route (vty, rn, rib, NULL); @@ -5838,7 +5838,7 @@ static_config_ipv6 (struct vty *vty) if (si->vrf_id != VRF_DEFAULT) { - vty_out (vty, " vrf %s", zvrf->name); + vty_out (vty, " vrf %s", zvrf_name (zvrf)); } /* Label information */ @@ -5888,14 +5888,14 @@ DEFUN (show_vrf, RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; - if (! zvrf || ! zvrf->vrf_id) + if (! zvrf || ! zvrf_id (zvrf)) continue; - vty_out (vty, "vrf %s ", zvrf->name); - if (zvrf->vrf_id == VRF_UNKNOWN) + vty_out (vty, "vrf %s ", zvrf_name (zvrf)); + if (zvrf_id (zvrf) == VRF_UNKNOWN) vty_out (vty, "inactive"); else - vty_out (vty, "id %u table %u", zvrf->vrf_id, zvrf->table_id); + vty_out (vty, "id %u table %u", zvrf_id (zvrf), zvrf->table_id); vty_out (vty, "%s", VTY_NEWLINE); } diff --git a/zebra/zserv.c b/zebra/zserv.c index 947e7324db..83d7d0f811 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -185,7 +185,7 @@ static void zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf) { /* Interface information. */ - stream_put (s, zvrf->name, VRF_NAMSIZ); + stream_put (s, zvrf_name (zvrf), VRF_NAMSIZ); /* Write packet size. */ stream_putw_at (s, 0, stream_get_endp (s)); @@ -241,7 +241,7 @@ zsend_vrf_add (struct zserv *client, struct zebra_vrf *zvrf) s = client->obuf; stream_reset (s); - zserv_create_header (s, ZEBRA_VRF_ADD, zvrf->vrf_id); + zserv_create_header (s, ZEBRA_VRF_ADD, zvrf_id (zvrf)); zserv_encode_vrf (s, zvrf); client->vrfadd_cnt++; @@ -257,7 +257,7 @@ zsend_vrf_delete (struct zserv *client, struct zebra_vrf *zvrf) s = client->obuf; stream_reset (s); - zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf->vrf_id); + zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf_id (zvrf)); zserv_encode_vrf (s, zvrf); client->vrfdel_cnt++; @@ -850,7 +850,7 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length, p.family); return -1; } - rnh = zebra_add_rnh(&p, zvrf->vrf_id, type); + rnh = zebra_add_rnh(&p, zvrf_id (zvrf), type); if (type == RNH_NEXTHOP_TYPE) { if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) @@ -866,9 +866,9 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length, UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); } - zebra_add_rnh_client(rnh, client, type, zvrf->vrf_id); + zebra_add_rnh_client(rnh, client, type, zvrf_id (zvrf)); /* Anything not AF_INET/INET6 has been filtered out above */ - zebra_evaluate_rnh(zvrf->vrf_id, p.family, 1, type, &p); + zebra_evaluate_rnh(zvrf_id (zvrf), p.family, 1, type, &p); } return 0; } @@ -911,7 +911,7 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length, p.family); return -1; } - rnh = zebra_lookup_rnh(&p, zvrf->vrf_id, type); + rnh = zebra_lookup_rnh(&p, zvrf_id (zvrf), type); if (rnh) { client->nh_dereg_time = quagga_monotime(); @@ -939,7 +939,7 @@ zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struc stream_reset (s); /* Fill in result. */ - zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf->vrf_id); + zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id (zvrf)); stream_put_in_addr (s, &addr); if (rib) @@ -1010,7 +1010,7 @@ zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvr struct interface *ifp; /* Interface information is needed. */ - vrf_bitmap_set (client->ifinfo, zvrf->vrf_id); + vrf_bitmap_set (client->ifinfo, zvrf_id (zvrf)); RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { @@ -1034,7 +1034,7 @@ zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvr static int zread_interface_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) { - vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id); + vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf)); return 0; } @@ -1091,7 +1091,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); /* VRF ID */ - rib->vrf_id = zvrf->vrf_id; + rib->vrf_id = zvrf_id (zvrf); /* Nexthop parse. */ if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) @@ -1243,7 +1243,7 @@ zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) table_id = zvrf->table_id; - rib_delete (AFI_IP, api.safi, zvrf->vrf_id, api.type, api.instance, + rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance, api.flags, &p, nexthop_p, ifindex, table_id); client->v4_route_del_cnt++; return 0; @@ -1257,7 +1257,7 @@ zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zeb struct rib *rib; addr.s_addr = stream_get_ipv4 (client->ibuf); - rib = rib_match_ipv4_multicast (zvrf->vrf_id, addr, NULL); + rib = rib_match_ipv4_multicast (zvrf_id (zvrf), addr, NULL); return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib, zvrf); } @@ -1301,7 +1301,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); /* VRF ID */ - rib->vrf_id = zvrf->vrf_id; + rib->vrf_id = zvrf_id (zvrf); /* We need to give nh-addr, nh-ifindex with the same next-hop object * to the rib to ensure that IPv6 multipathing works; need to coalesce @@ -1498,7 +1498,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) rib->mtu = 0; /* VRF ID */ - rib->vrf_id = zvrf->vrf_id; + rib->vrf_id = zvrf_id (zvrf); rib->table = zvrf->table_id; ret = rib_add_multipath (AFI_IP6, safi, &p, rib); @@ -1582,10 +1582,10 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) api.tag = 0; if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) - rib_delete (AFI_IP6, api.safi, zvrf->vrf_id, api.type, api.instance, + rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance, api.flags, &p, NULL, ifindex, client->rtm_table); else - rib_delete (AFI_IP6, api.safi, zvrf->vrf_id, api.type, api.instance, + rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance, api.flags, &p, pnexthop, ifindex, client->rtm_table); client->v6_route_del_cnt++; @@ -1599,18 +1599,18 @@ zread_router_id_add (struct zserv *client, u_short length, struct zebra_vrf *zvr struct prefix p; /* Router-id information is needed. */ - vrf_bitmap_set (client->ridinfo, zvrf->vrf_id); + vrf_bitmap_set (client->ridinfo, zvrf_id (zvrf)); - router_id_get (&p, zvrf->vrf_id); + router_id_get (&p, zvrf_id (zvrf)); - return zsend_router_id_update (client, &p, zvrf->vrf_id); + return zsend_router_id_update (client, &p, zvrf_id (zvrf)); } /* Unregister zebra server router-id information. */ static int zread_router_id_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) { - vrf_bitmap_unset (client->ridinfo, zvrf->vrf_id); + vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf)); return 0; } @@ -1648,10 +1648,10 @@ zread_vrf_unregister (struct zserv *client, u_short length, struct zebra_vrf *zv for (afi = AFI_IP; afi < AFI_MAX; afi++) for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - vrf_bitmap_unset (client->redist[afi][i], zvrf->vrf_id); - vrf_bitmap_unset (client->redist_default, zvrf->vrf_id); - vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id); - vrf_bitmap_unset (client->ridinfo, zvrf->vrf_id); + vrf_bitmap_unset (client->redist[afi][i], zvrf_id (zvrf)); + vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf)); + vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf)); + vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf)); return 0; } @@ -1729,10 +1729,10 @@ zebra_client_close_cleanup_rnh (struct zserv *client) { if ((zvrf = vrf->info) != NULL) { - zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_NEXTHOP_TYPE); - zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_NEXTHOP_TYPE); - zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_IMPORT_CHECK_TYPE); - zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_IMPORT_CHECK_TYPE); + zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_NEXTHOP_TYPE); + zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_NEXTHOP_TYPE); + zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_IMPORT_CHECK_TYPE); + zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_IMPORT_CHECK_TYPE); if (client->proto == ZEBRA_ROUTE_LDP) { hash_iterate(zvrf->lsp_table, mpls_ldp_lsp_uninstall_all, From 2414ffe50c5c66dc08f241d918917fd765970d35 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 1 Nov 2016 07:57:39 -0200 Subject: [PATCH 18/20] zebra: loop through all static routes on vrf enable/disable Signed-off-by: Renato Westphal --- zebra/zebra_vrf.c | 78 ++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index fbfa70d63f..13010bfdcd 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -143,10 +143,10 @@ static int zebra_vrf_enable (struct vrf *vrf) { struct zebra_vrf *zvrf = vrf->info; - struct route_table *stable = NULL; - struct route_node *rn = NULL; - struct static_route *si = NULL; - struct interface *ifp = NULL; + struct route_table *stable; + struct route_node *rn; + struct static_route *si; + struct interface *ifp; afi_t afi; safi_t safi; @@ -155,32 +155,28 @@ zebra_vrf_enable (struct vrf *vrf) zebra_vrf_add_update (zvrf); for (afi = AFI_IP; afi < AFI_MAX; afi++) - { - for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) - { - stable = zvrf->stable[afi][safi]; - if (stable) + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + stable = zvrf->stable[afi][safi]; + if (! stable) + continue; + + for (rn = route_top (stable); rn; rn = route_next (rn)) + for (si = rn->info; si; si = si->next) { - for (rn = route_top (stable); rn; rn = route_next (rn)) + si->vrf_id = vrf->vrf_id; + if (si->ifindex) { - if (rn->info) - { - si = rn->info; - si->vrf_id = vrf->vrf_id; - if (si->ifindex) - { - ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id); - if (ifp) - si->ifindex = ifp->ifindex; - else - continue; - } - static_install_route (afi, safi, &rn->p, si); - } + ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id); + if (ifp) + si->ifindex = ifp->ifindex; + else + continue; } + static_install_route (afi, safi, &rn->p, si); } - } - } + } + return 0; } @@ -189,8 +185,9 @@ static int zebra_vrf_disable (struct vrf *vrf) { struct zebra_vrf *zvrf = vrf->info; - struct route_table *stable = NULL; - struct route_node *rn = NULL; + struct route_table *stable; + struct route_node *rn; + struct static_route *si; afi_t afi; safi_t safi; @@ -199,20 +196,17 @@ zebra_vrf_disable (struct vrf *vrf) zvrf_name (zvrf), zvrf_id (zvrf)); for (afi = AFI_IP; afi < AFI_MAX; afi++) - { - for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) - { - stable = zvrf->stable[afi][safi]; - if (stable) - { - for (rn = route_top (stable); rn; rn = route_next (rn)) - { - if (rn->info) - static_uninstall_route(afi, safi, &rn->p, rn->info); - } - } - } - } + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + stable = zvrf->stable[afi][safi]; + if (! stable) + continue; + + for (rn = route_top (stable); rn; rn = route_next (rn)) + for (si = rn->info; si; si = si->next) + static_uninstall_route(afi, safi, &rn->p, si); + } + return 0; } From 5a8dfcd891fd12bb9db8f504bf3a083cea4f3cbd Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Mon, 31 Oct 2016 15:15:16 -0200 Subject: [PATCH 19/20] zebra: plug more memory leaks Try to free all memory explicitly on exit. This should help to detect new memory leaks in the future with tools like valgrind. Signed-off-by: Renato Westphal --- zebra/main.c | 18 ++++- zebra/rib.h | 3 +- zebra/zebra_rib.c | 52 +++---------- zebra/zebra_rnh.c | 17 +++-- zebra/zebra_rnh.h | 1 + zebra/zebra_rnh_null.c | 4 + zebra/zebra_vrf.c | 163 ++++++++++++++++++++++++++++++++++++----- zebra/zebra_vrf.h | 1 + 8 files changed, 191 insertions(+), 68 deletions(-) diff --git a/zebra/main.c b/zebra/main.c index 1b41f8deff..4fea0104f5 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -182,17 +182,27 @@ sighup (void) static void sigint (void) { + struct vrf *vrf; + struct zebra_vrf *zvrf; struct zebra_ns *zns; zlog_notice ("Terminating on signal"); - if (!retain_mode) - rib_close (); #ifdef HAVE_IRDP irdp_finish(); #endif zebra_ptm_finish(); + list_delete_all_node (zebrad.client_list); + + if (retain_mode) + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) + { + zvrf = vrf->info; + if (zvrf) + SET_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN); + } + vrf_terminate (); zns = zebra_ns_lookup (NS_DEFAULT); zebra_ns_disable (0, (void **)&zns); @@ -204,6 +214,10 @@ sigint (void) vty_terminate (); zprivs_terminate (&zserv_privs); list_delete (zebrad.client_list); + work_queue_free (zebrad.ribq); + if (zebrad.lsp_process_q) + work_queue_free (zebrad.lsp_process_q); + meta_queue_free (zebrad.mq); thread_master_free (zebrad.master); if (zlog_default) closezlog (zlog_default); diff --git a/zebra/rib.h b/zebra/rib.h index c95a9ba0c3..30929f1beb 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -366,13 +366,14 @@ extern void rib_update (vrf_id_t, rib_update_event_t); extern void rib_weed_tables (void); extern void rib_sweep_route (void); extern void rib_close_table (struct route_table *); -extern void rib_close (void); extern void rib_init (void); extern unsigned long rib_score_proto (u_char proto, u_short instance); extern void rib_queue_add (struct route_node *rn); +extern void meta_queue_free (struct meta_queue *mq); extern struct route_table *rib_table_ipv6; +extern void rib_unlink (struct route_node *, struct rib *); extern int rib_gc_dest (struct route_node *rn); extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 54caeba892..e29307be27 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1304,8 +1304,6 @@ rib_uninstall (struct route_node *rn, struct rib *rib) } } -static void rib_unlink (struct route_node *, struct rib *); - /* * rib_can_delete_dest * @@ -2216,6 +2214,17 @@ meta_queue_new (void) return new; } +void +meta_queue_free (struct meta_queue *mq) +{ + unsigned i; + + for (i = 0; i < MQ_SIZE; i++) + list_delete (mq->subq[i]); + + XFREE (MTYPE_WORK_QUEUE, mq); +} + /* initialise zebra rib work queue */ static void rib_queue_init (struct zebra_t *zebra) @@ -2351,7 +2360,7 @@ rib_addnode (struct route_node *rn, struct rib *rib, int process) * rib_gc_dest() at some point. This allows a rib_dest_t that is no * longer required to be deleted. */ -static void +void rib_unlink (struct route_node *rn, struct rib *rib) { rib_dest_t *dest; @@ -3153,43 +3162,6 @@ rib_close_table (struct route_table *table) } } -/* Close all RIB tables. */ -void -rib_close (void) -{ - struct vrf *vrf; - struct zebra_vrf *zvrf; - struct listnode *node; - struct interface *ifp; - u_int32_t table_id; - - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) - { - if ((zvrf = vrf->info) != NULL) - { - rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]); - rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); - } - for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) - if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp); - } - - /* If we do multiple tables per vrf, need to move this to loop above */ - zvrf = vrf_info_lookup (VRF_DEFAULT); - - for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++) - { - if (zvrf->other_table[AFI_IP][table_id]) - rib_close_table (zvrf->other_table[AFI_IP][table_id]); - - if (zvrf->other_table[AFI_IP6][table_id]) - rib_close_table (zvrf->other_table[AFI_IP6][table_id]); - } - - zebra_mpls_close_tables(zvrf); - -} - /* Routing information base initialize. */ void rib_init (void) diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 7df759030d..c6fc404bed 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -163,6 +163,16 @@ zebra_lookup_rnh (struct prefix *p, vrf_id_t vrfid, rnh_type_t type) return (rn->info); } +void +zebra_free_rnh (struct rnh *rnh) +{ + rnh->flags |= ZEBRA_NHT_DELETED; + list_free (rnh->client_list); + list_free (rnh->zebra_static_route_list); + free_state (rnh->vrf_id, rnh->state, rnh->node); + XFREE (MTYPE_RNH, rnh); +} + void zebra_delete_rnh (struct rnh *rnh, rnh_type_t type) { @@ -178,14 +188,9 @@ zebra_delete_rnh (struct rnh *rnh, rnh_type_t type) rnh->vrf_id, rnh_str(rnh, buf, sizeof (buf)), type); } - rnh->flags |= ZEBRA_NHT_DELETED; - list_free(rnh->client_list); - list_free(rnh->zebra_static_route_list); - free_state(rnh->vrf_id, rnh->state, rn); - XFREE(MTYPE_RNH, rn->info); + zebra_free_rnh (rnh); rn->info = NULL; route_unlock_node (rn); - return; } void diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index 3a57ef1bc6..4394fde4f3 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -59,6 +59,7 @@ extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type); extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type); +extern void zebra_free_rnh (struct rnh *rnh); extern void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type); extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vrfid); diff --git a/zebra/zebra_rnh_null.c b/zebra/zebra_rnh_null.c index eecb8519d5..a97ae1a612 100644 --- a/zebra/zebra_rnh_null.c +++ b/zebra/zebra_rnh_null.c @@ -26,6 +26,10 @@ int zebra_rnh_ip_default_route = 0; int zebra_rnh_ipv6_default_route = 0; +void +zebra_free_rnh (struct rnh *rnh) +{} + void zebra_evaluate_rnh (vrf_id_t vrfid, int family, int force, rnh_type_t type, struct prefix *p) {} diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 13010bfdcd..b1c5e4dd35 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -30,9 +30,11 @@ #include "zebra/zserv.h" #include "zebra/rib.h" #include "zebra/zebra_vrf.h" +#include "zebra/zebra_rnh.h" #include "zebra/router-id.h" #include "zebra/zebra_memory.h" #include "zebra/zebra_static.h" +#include "zebra/interface.h" #include "zebra/zebra_mpls.h" extern struct zebra_t zebrad; @@ -214,18 +216,84 @@ 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; assert (zvrf); zebra_vrf_delete_update (zvrf); - rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]); - rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); + /* uninstall everything */ + if (! CHECK_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN)) + { + struct listnode *node; + struct interface *ifp; + 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]); + } + + zebra_mpls_close_tables (zvrf); + + for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) + if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp); + } + + /* clean-up work queues */ + for (i = 0; i < MQ_SIZE; i++) + { + struct listnode *lnode, *nnode; + struct route_node *rnode; + rib_dest_t *dest; + + 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); + list_delete_node (zebrad.mq->subq[i], lnode); + } + } + } + + /* release allocated memory */ + for (afi = AFI_IP; afi <= AFI_IP6; afi++) + { + for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) + { + table = zvrf->table[afi][safi]; + XFREE (MTYPE_RIB_TABLE_INFO, table->info); + route_table_finish (table); + + table = zvrf->stable[afi][safi]; + 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]; + XFREE (MTYPE_RIB_TABLE_INFO, table->info); + route_table_finish (table); + } + + route_table_finish (zvrf->rnh_table[afi]); + route_table_finish (zvrf->import_check_table[afi]); + } list_delete_all_node (zvrf->rid_all_sorted_list); list_delete_all_node (zvrf->rid_lo_sorted_list); - - vrf->vrf_id = VRF_UNKNOWN; + XFREE (MTYPE_ZEBRA_VRF, zvrf); vrf->info = NULL; return 0; @@ -257,6 +325,62 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, return table; } +static void +zebra_rtable_node_destroy (route_table_delegate_t *delegate, + struct route_table *table, struct route_node *node) +{ + struct rib *rib, *next; + + RNODE_FOREACH_RIB_SAFE (node, rib, next) + rib_unlink (node, rib); + + if (node->info) + XFREE (MTYPE_RIB_DEST, node->info); + + route_node_destroy (delegate, table, node); +} + +static void +zebra_stable_node_destroy (route_table_delegate_t *delegate, + struct route_table *table, struct route_node *node) +{ + struct static_route *si, *next; + + if (node->info) + for (si = node->info; si; si = next) + { + next = si->next; + XFREE (MTYPE_STATIC_ROUTE, si); + } + + route_node_destroy (delegate, table, node); +} + +static void +zebra_rnhtable_node_destroy (route_table_delegate_t *delegate, + struct route_table *table, struct route_node *node) +{ + if (node->info) + zebra_free_rnh (node->info); + + route_node_destroy (delegate, table, node); +} + +route_table_delegate_t zebra_rtable_delegate = { + .create_node = route_node_create, + .destroy_node = zebra_rtable_node_destroy +}; + +route_table_delegate_t zebra_stable_delegate = { + .create_node = route_node_create, + .destroy_node = zebra_stable_node_destroy +}; + +route_table_delegate_t zebra_rnhtable_delegate = { + .create_node = route_node_create, + .destroy_node = zebra_rnhtable_node_destroy +}; + /* * Create a routing table for the specific AFI/SAFI in the given VRF. */ @@ -268,7 +392,7 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi) assert (!zvrf->table[afi][safi]); - table = route_table_init (); + table = route_table_init_with_delegate (&zebra_rtable_delegate); zvrf->table[afi][safi] = table; info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info)); @@ -283,24 +407,25 @@ struct zebra_vrf * zebra_vrf_alloc (void) { struct zebra_vrf *zvrf; + afi_t afi; + safi_t safi; zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf)); - /* Allocate routing table and static table. */ - zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST); - zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST); - zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init (); - zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init (); - zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST); - zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST); - zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init (); - zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init (); + for (afi = AFI_IP; afi <= AFI_IP6; afi++) + { + for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) + { + zebra_vrf_table_create (zvrf, afi, safi); + zvrf->stable[afi][safi] = + route_table_init_with_delegate (&zebra_stable_delegate); + } - zvrf->rnh_table[AFI_IP] = route_table_init(); - zvrf->rnh_table[AFI_IP6] = route_table_init(); - - zvrf->import_check_table[AFI_IP] = route_table_init(); - zvrf->import_check_table[AFI_IP6] = route_table_init(); + zvrf->rnh_table[afi] = + route_table_init_with_delegate (&zebra_rnhtable_delegate); + zvrf->import_check_table[afi] = + route_table_init_with_delegate (&zebra_rnhtable_delegate); + } zebra_mpls_init_tables (zvrf); diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 8c4f0b4a28..96d631d646 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -40,6 +40,7 @@ struct zebra_vrf /* Flags. */ u_int16_t flags; #define ZEBRA_VRF_RIB_SCHEDULED (1 << 0) +#define ZEBRA_VRF_RETAIN (2 << 0) u_int32_t table_id; From f4f59de462018e48c639978cfe57cf4301a0d209 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Mon, 28 Nov 2016 15:00:05 -0200 Subject: [PATCH 20/20] bgpd: fix invalid memory access in peer_free() We shoult not call bgp_unlock() before calling bgp_delete_connected_nexthop() in the peer_free() function. Otherwise, if bgp->lock reaches zero, bgp_free() is called and peer->bgp becomes an invalid pointer in the bgp_delete_connected_nexthop() function. To fix this, move the call to bgp_unlock() to the end of peer_free(). Bug exposed by commit 37d361e ("bgpd: plug several memleaks"). Signed-off-by: Renato Westphal --- bgpd/bgpd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 22d4dd8917..d5aff84dae 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1019,8 +1019,6 @@ peer_free (struct peer *peer) { assert (peer->status == Deleted); - bgp_unlock(peer->bgp); - /* this /ought/ to have been done already through bgp_stop earlier, * but just to be sure.. */ @@ -1092,6 +1090,8 @@ peer_free (struct peer *peer) bfd_info_free(&(peer->bfd_info)); + bgp_unlock(peer->bgp); + memset (peer, 0, sizeof (struct peer)); XFREE (MTYPE_BGP_PEER, peer);