Merge branch '-renato' into stable/2.0

This contains bgp memory leak fixes as well as cleanups to VRF/namespace
handling and has been run through extended testing in Cumulus' testbed:

Tested-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
David Lamparter 2016-12-05 16:22:16 +01:00
commit 8ab22cd4be
47 changed files with 984 additions and 1511 deletions

View File

@ -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;
}

View File

@ -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 (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 (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;

View File

@ -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;
}
@ -554,17 +560,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 +583,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;
}
}

View File

@ -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);

View File

@ -3122,7 +3122,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];
@ -3133,7 +3133,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;
@ -3185,20 +3185,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;
}
@ -3335,51 +3343,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);
}
}
}

View File

@ -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 *);

View File

@ -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]);

View File

@ -1044,6 +1044,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);
@ -2965,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;
@ -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;
@ -3179,15 +3186,13 @@ 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.
*/
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);
@ -7597,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);

View File

@ -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

View File

@ -4436,4 +4436,6 @@ cmd_terminate ()
XFREE (MTYPE_HOST, host.motdfile);
if (host.config)
XFREE (MTYPE_HOST, host.config);
qobj_finish ();
}

View File

@ -307,13 +307,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;
@ -489,18 +487,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'))
@ -665,14 +661,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);
}
@ -839,60 +834,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,
@ -938,24 +879,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_name_head, &vrfs_by_name)
{
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))
{

308
lib/ns.c
View File

@ -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
@ -91,22 +96,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
{
@ -116,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.
@ -188,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);
@ -198,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));
}
/*
@ -310,217 +277,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
*/
@ -641,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;
}
@ -662,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)
@ -696,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. */

View File

@ -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;
@ -30,15 +31,32 @@ 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"
struct ns
{
RB_ENTRY(ns) entry;
/* 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;
};
RB_HEAD (ns_head, ns);
RB_PROTOTYPE (ns_head, ns, entry, ns_compare)
extern struct ns_head ns_tree;
/*
* NS hooks
@ -59,71 +77,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 (<a given NS ID>);
* 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
*/

View File

@ -78,6 +78,7 @@ void qobj_init (void)
void qobj_finish (void)
{
hash_clean (nodes, NULL);
hash_free (nodes);
nodes = NULL;
}

View File

@ -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)
{

View File

@ -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

507
lib/vrf.c
View File

@ -35,6 +35,15 @@ 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
* for vrf.
@ -44,44 +53,34 @@ 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,};
/* 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;
static int vrf_is_enabled (struct vrf *vrf);
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 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));
}
/* 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);
}
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.
@ -94,177 +93,59 @@ 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;
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);
listnode_add_sort (vrf_list, vrf);
vrf->vrf_id = VRF_UNKNOWN;
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;
/*
* 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;
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_build_key (vrf_id, &p);
rn = route_node_get (vrf_table, &p);
if (rn->info)
{
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.
* so let's set it.
*/
strcpy (vrf->name, name);
listnode_add_sort (vrf_list, 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));
rn->info = vrf;
vrf->node = rn;
vrf->vrf_id = vrf_id;
strcpy (vrf->name, name);
listnode_add_sort (vrf_list, 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_build_key (vrf_id, &p);
rn = route_node_get (vrf_table, &p);
if (debug_vrf)
zlog_debug("Vrf found: %p", rn->info);
if (rn->info)
{
route_unlock_node (rn);
return (rn->info);
}
else
{
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
rn->info = vrf;
vrf->node = rn;
vrf->vrf_id = vrf_id;
if_init (&vrf->iflist);
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);
return vrf;
}
/* Delete a VRF. This is called in vrf_terminate(). */
@ -278,53 +159,35 @@ 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);
if (vrf->node)
{
vrf->node->info = NULL;
route_unlock_node(vrf->node);
}
listnode_delete (vrf_list, vrf);
if (vrf->vrf_id != VRF_UNKNOWN)
RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf);
if (vrf->name[0] != '\0')
RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf);
XFREE (MTYPE_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 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));
}
/*
* 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;
*/
}
/*
@ -337,14 +200,16 @@ 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);
(*vrf_master.vrf_enable_hook) (vrf);
return 1;
}
@ -357,26 +222,25 @@ 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);
}
/* 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__,
@ -400,116 +264,6 @@ 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;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
{
vrf = vrf_iter2vrf (iter);
if (vrf && !strcmp(vrf->name, name))
return vrf;
}
return NULL;
}
vrf_id_t
vrf_name_to_id (const char *name)
{
@ -535,7 +289,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;
}
@ -543,7 +297,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;
}
@ -559,7 +313,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);
}
@ -568,7 +322,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);
}
@ -666,20 +420,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)
@ -689,12 +429,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;
/* 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)
@ -715,18 +449,15 @@ 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);
while ((vrf = RB_ROOT (&vrfs_by_name)) != NULL)
vrf_delete (vrf);
}
/* Create a socket for the VRF. */
@ -740,6 +471,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_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
*/

View File

@ -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, name_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,10 +90,15 @@ struct vrf
QOBJ_FIELDS
};
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 list *vrf_list;
extern struct vrf_id_head vrfs_by_id;
extern struct vrf_name_head vrfs_by_name;
/*
* Add a specific hook to VRF module.
@ -102,18 +108,10 @@ extern struct list *vrf_list;
* - 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 *));
/*
* 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_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 *);
@ -122,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; \
@ -135,34 +133,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 (<a given VRF ID>);
* 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
*/

View File

@ -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

View File

@ -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;

View File

@ -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 ((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);
@ -250,7 +243,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)
{

View File

@ -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;
@ -1025,7 +1039,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)
@ -1276,33 +1290,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",
@ -1339,15 +1326,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_name_head, &vrfs_by_name)
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
if_dump_vty (vty, ifp);
return CMD_SUCCESS;
@ -1392,17 +1379,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_name_head, &vrfs_by_name)
{
/* 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);
@ -1498,15 +1485,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_name_head, &vrfs_by_name)
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;
@ -2833,14 +2819,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_name_head, &vrfs_by_name)
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
{
struct zebra_if *if_data;
struct listnode *addrnode;
@ -2849,7 +2835,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);
@ -2917,23 +2903,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)
@ -2945,7 +2914,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);
@ -3008,8 +2976,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);
}

View File

@ -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;

View File

@ -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. */

View File

@ -182,20 +182,46 @@ 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);
access_list_reset ();
prefix_list_reset ();
route_map_finish ();
cmd_terminate ();
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);
exit (0);
}

View File

@ -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. */

View File

@ -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);

View File

@ -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,33 +183,33 @@ 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
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_name_head, &vrfs_by_name)
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);
}
}

View File

@ -98,16 +98,16 @@ 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;
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");
}
}

View File

@ -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) ||
@ -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;
}

View File

@ -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)

View File

@ -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;
/*

View File

@ -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 */

View File

@ -1267,7 +1267,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;
@ -1501,7 +1501,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;
@ -1828,7 +1828,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);
}
/*
@ -1868,7 +1868,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);
}
@ -1880,9 +1880,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);
}
/*

View File

@ -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,24 +45,11 @@ 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);
#endif
#ifdef HAVE_NETLINK
/* Initialize netlink sockets */
snprintf (nl_name, 64, "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);
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);
interface_list (zns);
@ -77,6 +63,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

View File

@ -32,7 +32,7 @@ struct nlsock
int sock;
int seq;
struct sockaddr_nl snl;
const char *name;
char name[64];
};
#endif

View File

@ -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);
@ -256,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_name_head, &vrfs_by_name)
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp))
if (!ifp->ptm_enable)
{
if_data = (struct zebra_if *)ifp->info;
@ -766,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
{
@ -913,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
{
@ -1110,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)

View File

@ -1303,8 +1303,6 @@ rib_uninstall (struct route_node *rn, struct rib *rib)
}
}
static void rib_unlink (struct route_node *, struct rib *);
/*
* rib_can_delete_dest
*
@ -1352,7 +1350,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);
@ -1385,7 +1383,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))
@ -1394,7 +1392,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);
}
}
@ -1414,7 +1412,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))
@ -1463,11 +1461,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))
@ -1477,7 +1475,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);
}
}
@ -1511,12 +1509,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");
}
@ -1626,7 +1624,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)
@ -2026,7 +2024,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)
@ -2051,24 +2049,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_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. */
@ -2076,7 +2074,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);
}
@ -2151,7 +2149,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;
}
@ -2215,6 +2213,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)
@ -2350,7 +2359,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;
@ -3036,11 +3045,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]);
@ -3077,11 +3086,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]);
@ -3117,12 +3126,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]);
@ -3152,43 +3161,6 @@ rib_close_table (struct route_table *table)
}
}
/* Close all RIB tables. */
void
rib_close (void)
{
vrf_iter_t iter;
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))
{
if ((zvrf = vrf_iter2info (iter)) != 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))
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)
@ -3206,17 +3178,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_by_id (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;

View File

@ -56,7 +56,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; \
@ -76,7 +76,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)
{
@ -162,6 +162,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)
{
@ -177,14 +187,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

View File

@ -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);

View File

@ -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)
{}

View File

@ -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;

View File

@ -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;
@ -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);

View File

@ -23,19 +23,21 @@
#include "log.h"
#include "linklist.h"
#include "command.h"
#include "memory.h"
#include "zebra/debug.h"
#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;
struct list *zvrf_list;
/* VRF information update. */
static void
@ -45,7 +47,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 +60,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);
@ -68,44 +70,28 @@ 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));
}
}
/* 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_list_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);
listnode_add_sort (zvrf_list, 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;
}
@ -122,7 +108,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;
@ -156,13 +142,13 @@ 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 route_table *stable = NULL;
struct route_node *rn = NULL;
struct static_route *si = NULL;
struct interface *ifp = NULL;
struct zebra_vrf *zvrf = vrf->info;
struct route_table *stable;
struct route_node *rn;
struct static_route *si;
struct interface *ifp;
afi_t afi;
safi_t safi;
@ -171,85 +157,145 @@ zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
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_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;
}
/* 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 route_table *stable = NULL;
struct route_node *rn = NULL;
struct zebra_vrf *zvrf = vrf->info;
struct route_table *stable;
struct route_node *rn;
struct static_route *si;
afi_t afi;
safi_t safi;
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++)
{
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;
}
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;
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);
XFREE (MTYPE_ZEBRA_VRF, zvrf);
vrf->info = NULL;
zvrf->vrf_id = VRF_UNKNOWN;
*info = NULL;
return 0;
}
@ -279,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.
*/
@ -290,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));
@ -302,35 +404,27 @@ 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;
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 ();
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();
/* Set VRF ID */
zvrf->vrf_id = vrf_id;
if (name)
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
{
strncpy (zvrf->name, name, strlen(name));
zvrf->name[strlen(name)] = '\0';
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] =
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);
@ -340,26 +434,24 @@ 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);
}
/* Lookup the zvrf in the zvrf_list. */
/* 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 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_lookup_by_name (name);
if (vrf)
return ((struct zebra_vrf *) vrf->info);
return NULL;
}
@ -427,6 +519,51 @@ 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 vrf *vrf;
struct zebra_vrf *zvrf;
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
zvrf = vrf->info;
if (! zvrf || strcmp (zvrf_name (zvrf), VRF_DEFAULT_NAME))
{
vty_out (vty, "vrf %s%s", zvrf_name (zvrf), 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)
@ -436,7 +573,10 @@ 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);
install_default (VRF_NODE);
install_element (CONFIG_NODE, &zebra_vrf_cmd);
install_element (CONFIG_NODE, &no_vrf_cmd);
}

View File

@ -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;
@ -43,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;
@ -86,7 +84,17 @@ struct zebra_vrf
#define MPLS_FLAG_SCHEDULE_LSPS (1 << 0)
};
extern struct list *zvrf_list;
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,
@ -94,9 +102,9 @@ 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_list_lookup_by_name (const char *);
extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *);
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 (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,

View File

@ -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)
{
@ -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");
@ -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);
@ -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)
@ -2569,14 +2569,14 @@ 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_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;
@ -2614,14 +2614,14 @@ 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_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++)
@ -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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
@ -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);
@ -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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
@ -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);
@ -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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
@ -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);
@ -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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
@ -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);
@ -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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
@ -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);
@ -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_name_head, &vrfs_by_name)
{
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_name_head, &vrfs_by_name)
{
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_name_head, &vrfs_by_name)
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_name_head, &vrfs_by_name)
if ((zvrf = vrf->info) != NULL)
vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
return CMD_SUCCESS;
@ -3673,13 +3673,17 @@ 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))
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
zvrf = vrf->info;
if (! zvrf)
continue;
if ((stable = zvrf->stable[AFI_IP][safi]) == NULL)
continue;
@ -3718,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)
@ -3780,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)
{
@ -3851,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);
@ -3869,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);
@ -4921,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);
@ -4930,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);
@ -4939,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);
@ -5411,14 +5415,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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
@ -5434,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);
@ -5458,8 +5462,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;
@ -5467,9 +5471,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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
@ -5488,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);
@ -5513,8 +5517,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;
@ -5526,9 +5530,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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
@ -5545,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);
@ -5569,8 +5573,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;
@ -5581,9 +5585,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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
@ -5600,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);
@ -5624,8 +5628,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)
@ -5634,9 +5638,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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
@ -5665,8 +5669,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)
@ -5675,9 +5679,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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
@ -5707,11 +5711,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_name_head, &vrfs_by_name)
if ((zvrf = vrf->info) != NULL)
vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
return CMD_SUCCESS;
@ -5728,13 +5732,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_name_head, &vrfs_by_name)
{
if ((zvrf = vrf_iter2info (iter)) == NULL ||
if ((zvrf = vrf->info) == NULL ||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
@ -5763,11 +5767,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_name_head, &vrfs_by_name)
if ((zvrf = vrf->info) != NULL)
vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
return CMD_SUCCESS;
@ -5782,11 +5786,15 @@ 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))
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
zvrf = vrf->info;
if (! zvrf)
continue;
if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
@ -5830,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 */
@ -5874,19 +5882,20 @@ 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))
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
if (!zvrf->vrf_id)
continue;
zvrf = vrf->info;
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);
}

View File

@ -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)
@ -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);
vrf_bitmap_set (client->ifinfo, zvrf_id (zvrf));
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))
@ -1036,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;
}
@ -1093,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))
@ -1245,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;
@ -1259,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);
}
@ -1303,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
@ -1500,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);
@ -1584,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++;
@ -1601,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;
}
@ -1650,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;
}
@ -1724,17 +1722,17 @@ 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);
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,
@ -1937,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)