mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 14:29:47 +00:00
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:
commit
8ab22cd4be
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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]);
|
||||
|
26
bgpd/bgpd.c
26
bgpd/bgpd.c
@ -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);
|
||||
|
@ -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
|
||||
|
@ -4436,4 +4436,6 @@ cmd_terminate ()
|
||||
XFREE (MTYPE_HOST, host.motdfile);
|
||||
if (host.config)
|
||||
XFREE (MTYPE_HOST, host.config);
|
||||
|
||||
qobj_finish ();
|
||||
}
|
||||
|
89
lib/if.c
89
lib/if.c
@ -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
308
lib/ns.c
@ -31,8 +31,6 @@
|
||||
|
||||
#include "if.h"
|
||||
#include "ns.h"
|
||||
#include "prefix.h"
|
||||
#include "table.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
|
||||
@ -43,6 +41,13 @@ DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router")
|
||||
DEFINE_MTYPE_STATIC(LIB, NS_NAME, "Logical-Router Name")
|
||||
DEFINE_MTYPE_STATIC(LIB, NS_BITMAP, "Logical-Router bit-map")
|
||||
|
||||
static __inline int ns_compare (struct ns *, struct ns *);
|
||||
static struct ns *ns_lookup (ns_id_t);
|
||||
|
||||
RB_GENERATE (ns_head, ns, entry, ns_compare)
|
||||
|
||||
struct ns_head ns_tree = RB_INITIALIZER (&ns_tree);
|
||||
|
||||
#ifndef CLONE_NEWNET
|
||||
#define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */
|
||||
#endif
|
||||
@ -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. */
|
||||
|
97
lib/ns.h
97
lib/ns.h
@ -23,6 +23,7 @@
|
||||
#ifndef _ZEBRA_NS_H
|
||||
#define _ZEBRA_NS_H
|
||||
|
||||
#include "openbsd-tree.h"
|
||||
#include "linklist.h"
|
||||
|
||||
typedef u_int16_t ns_id_t;
|
||||
@ -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
|
||||
*/
|
||||
|
@ -78,6 +78,7 @@ void qobj_init (void)
|
||||
|
||||
void qobj_finish (void)
|
||||
{
|
||||
hash_clean (nodes, NULL);
|
||||
hash_free (nodes);
|
||||
nodes = NULL;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
507
lib/vrf.c
@ -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
|
||||
*/
|
||||
|
56
lib/vrf.h
56
lib/vrf.h
@ -23,6 +23,7 @@
|
||||
#ifndef _ZEBRA_VRF_H
|
||||
#define _ZEBRA_VRF_H
|
||||
|
||||
#include "openbsd-tree.h"
|
||||
#include "linklist.h"
|
||||
#include "qobj.h"
|
||||
|
||||
@ -69,18 +70,18 @@ enum {
|
||||
|
||||
struct vrf
|
||||
{
|
||||
RB_ENTRY(vrf) id_entry, 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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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. */
|
||||
|
30
zebra/main.c
30
zebra/main.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -32,7 +32,7 @@ struct nlsock
|
||||
int sock;
|
||||
int seq;
|
||||
struct sockaddr_nl snl;
|
||||
const char *name;
|
||||
char name[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user