Merge remote-tracking branch 'osr/master' into vtysh-grammar

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>

Conflicts:
	lib/command_match.c
This commit is contained in:
Quentin Young 2016-12-06 19:51:33 +00:00
commit 6fd800be4a
72 changed files with 1374 additions and 1789 deletions

2
README
View File

@ -2,7 +2,7 @@ Quagga is free software that manages various IPv4 and IPv6 routing
protocols. protocols.
Currently Quagga supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1, Currently Quagga supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1,
RIPv2, and RIPng as well as very early support for IS-IS. RIPv2, RIPng, PIM-SSM and LDP as well as very early support for IS-IS.
See the file INSTALL.quagga.txt for building and installation instructions. See the file INSTALL.quagga.txt for building and installation instructions.

View File

@ -172,8 +172,7 @@ peer_xfer_conn(struct peer *from_peer)
peer->hostname = NULL; peer->hostname = NULL;
} }
peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, from_peer->hostname); peer->hostname = from_peer->hostname;
XFREE(MTYPE_BGP_PEER_HOST, from_peer->hostname);
from_peer->hostname = NULL; from_peer->hostname = NULL;
} }
@ -185,8 +184,7 @@ peer_xfer_conn(struct peer *from_peer)
peer->domainname= NULL; peer->domainname= NULL;
} }
peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, from_peer->domainname); peer->domainname = from_peer->domainname;
XFREE(MTYPE_BGP_PEER_HOST, from_peer->domainname);
from_peer->domainname = NULL; from_peer->domainname = NULL;
} }

View File

@ -308,38 +308,33 @@ bgp_exit (int status)
} }
static int 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)) 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; return 0;
} }
static int 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)) 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; return 0;
} }
static int 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; struct bgp *bgp;
vrf_id_t old_vrf_id; vrf_id_t old_vrf_id;
vrf = vrf_lookup (vrf_id);
if (!vrf) // unexpected
return -1;
if (BGP_DEBUG (zebra, ZEBRA)) 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) if (bgp)
{ {
old_vrf_id = bgp->vrf_id; 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 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; struct bgp *bgp;
vrf_id_t old_vrf_id; vrf_id_t old_vrf_id;
if (vrf_id == VRF_DEFAULT) if (vrf->vrf_id == VRF_DEFAULT)
return 0; return 0;
vrf = vrf_lookup (vrf_id);
if (!vrf) // unexpected
return -1;
if (BGP_DEBUG (zebra, ZEBRA)) 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) if (bgp)
{ {
old_vrf_id = bgp->vrf_id; old_vrf_id = bgp->vrf_id;

View File

@ -113,6 +113,12 @@ bgp_address_hash_alloc (void *p)
return addr; return addr;
} }
static void
bgp_address_hash_free (void *addr)
{
XFREE (MTYPE_BGP_ADDR, addr);
}
static unsigned int static unsigned int
bgp_address_hash_key_make (void *p) bgp_address_hash_key_make (void *p)
{ {
@ -142,7 +148,7 @@ bgp_address_destroy (struct bgp *bgp)
{ {
if (bgp->address_hash == NULL) if (bgp->address_hash == NULL)
return; return;
hash_clean(bgp->address_hash, NULL); hash_clean(bgp->address_hash, bgp_address_hash_free);
hash_free(bgp->address_hash); hash_free(bgp->address_hash);
bgp->address_hash = NULL; bgp->address_hash = NULL;
} }
@ -524,17 +530,14 @@ DEFUN (show_ip_bgp_instance_all_nexthop,
void void
bgp_scan_init (struct bgp *bgp) bgp_scan_init (struct bgp *bgp)
{ {
bgp->nexthop_cache_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST); afi_t afi;
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);
bgp->nexthop_cache_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST); for (afi = AFI_IP; afi < AFI_MAX; afi++)
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] = bgp_table_init (afi, SAFI_UNICAST);
bgp->connected_table[afi] = bgp_table_init (afi, SAFI_UNICAST);
bgp->nexthop_cache_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST); bgp->import_check_table[afi] = bgp_table_init (afi, 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);
} }
void void
@ -547,29 +550,19 @@ bgp_scan_vty_init (void)
void void
bgp_scan_finish (struct bgp *bgp) bgp_scan_finish (struct bgp *bgp)
{ {
/* Only the current one needs to be reset. */ afi_t afi;
bgp_nexthop_cache_reset (bgp->nexthop_cache_table[AFI_IP]);
bgp_table_unlock (bgp->nexthop_cache_table[AFI_IP]); for (afi = AFI_IP; afi < AFI_MAX; afi++)
bgp->nexthop_cache_table[AFI_IP] = NULL; {
/* 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_table_unlock (bgp->connected_table[afi]);
bgp->connected_table[AFI_IP] = NULL; bgp->connected_table[afi] = NULL;
bgp_table_unlock (bgp->import_check_table[AFI_IP]); bgp_table_unlock (bgp->import_check_table[afi]);
bgp->import_check_table[AFI_IP] = NULL; bgp->import_check_table[afi] = 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 */
} }

View File

@ -115,19 +115,7 @@ bgp_unlink_nexthop_by_peer (struct peer *peer)
struct bgp_nexthop_cache *bnc; struct bgp_nexthop_cache *bnc;
afi_t afi = family2afi(peer->su.sa.sa_family); afi_t afi = family2afi(peer->su.sa.sa_family);
if (afi == AFI_IP) if (! sockunion2hostprefix (&peer->su, &p))
{
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
return; return;
rn = bgp_node_get (peer->bgp->nexthop_cache_table[afi], &p); 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) else if (peer)
{ {
if (afi == AFI_IP) /* Don't register link local NH */
{ if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&peer->su.sin6.sin6_addr))
p.family = AF_INET; return 1;
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 (! sockunion2hostprefix (&peer->su, &p))
if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
return 1;
}
else
{ {
if (BGP_DEBUG(nht, NHT)) if (BGP_DEBUG(nht, NHT))
{ {
@ -297,23 +273,11 @@ bgp_delete_connected_nexthop (afi_t afi, struct peer *peer)
if (!peer) if (!peer)
return; return;
if (afi == AFI_IP) /* We don't register link local address for NHT */
{ if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&peer->su.sin6.sin6_addr))
p.family = AF_INET; return;
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 (! sockunion2hostprefix (&peer->su, &p))
if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
return;
}
else
return; return;
rn = bgp_node_lookup(peer->bgp->nexthop_cache_table[family2afi(p.family)], &p); rn = bgp_node_lookup(peer->bgp->nexthop_cache_table[family2afi(p.family)], &p);

View File

@ -3121,7 +3121,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
struct bgp_table *table) struct bgp_table *table)
{ {
struct bgp_node *rn; struct bgp_node *rn;
int force = bm->process_main_queue ? 0 : 1;
if (! table) if (! table)
table = peer->bgp->rib[afi][safi]; table = peer->bgp->rib[afi][safi];
@ -3132,7 +3132,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)) 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;
struct bgp_adj_in *ain_next; struct bgp_adj_in *ain_next;
@ -3184,20 +3184,28 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
ain = ain_next; ain = ain_next;
} }
for (ri = rn->info; ri; ri = ri->next) for (ri = rn->info; ri; ri = next)
if (ri->peer == peer) {
{ next = ri->next;
struct bgp_clear_node_queue *cnq; if (ri->peer != peer)
continue;
/* both unlocked in bgp_clear_node_queue_del */ if (force)
bgp_table_lock (bgp_node_table (rn)); bgp_info_reap (rn, ri);
bgp_lock_node (rn); else
cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE, {
sizeof (struct bgp_clear_node_queue)); struct bgp_clear_node_queue *cnq;
cnq->rn = rn;
work_queue_add (peer->clear_node_queue, cnq); /* both unlocked in bgp_clear_node_queue_del */
break; 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; return;
} }
@ -3333,52 +3341,48 @@ bgp_cleanup_table(struct bgp_table *table, safi_t safi)
if (table->owner && table->owner->bgp) if (table->owner && table->owner->bgp)
vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri); vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri);
#endif #endif
bgp_zebra_withdraw (&rn->p, ri, safi); bgp_zebra_withdraw (&rn->p, ri, safi);
bgp_info_reap (rn, ri);
}
} }
} }
}
/* Delete all kernel routes. */ /* Delete all kernel routes. */
void void
bgp_cleanup_routes (void) bgp_cleanup_routes (struct bgp *bgp)
{ {
struct bgp *bgp;
struct listnode *node, *nnode;
afi_t afi; 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; if (rn->info)
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) bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_MPLS_VPN);
{ bgp_table_finish ((struct bgp_table **)&(rn->info));
bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_MPLS_VPN); rn->info = NULL;
bgp_table_finish ((struct bgp_table **)&(rn->info)); bgp_unlock_node(rn);
rn->info = NULL;
bgp_unlock_node(rn);
}
} }
}
for (rn = bgp_table_top(bgp->rib[afi][SAFI_ENCAP]); rn; for (rn = bgp_table_top(bgp->rib[afi][SAFI_ENCAP]); rn;
rn = bgp_route_next (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));
bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_ENCAP); rn->info = NULL;
bgp_table_finish ((struct bgp_table **)&(rn->info)); bgp_unlock_node(rn);
rn->info = NULL;
bgp_unlock_node(rn);
}
} }
} }
} }
@ -6073,7 +6077,7 @@ route_vty_out (struct vty *vty, struct prefix *p,
vty_out (vty, "%s", VTY_NEWLINE); vty_out (vty, "%s", VTY_NEWLINE);
#if ENABLE_BGP_VNC #if ENABLE_BGP_VNC
/* prints an additional line, indented, with VNC info, if present */ /* prints an additional line, indented, with VNC info, if present */
if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_UNICAST)) if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
rfapi_vty_out_vncinfo(vty, p, binfo, safi); rfapi_vty_out_vncinfo(vty, p, binfo, safi);
#endif #endif
} }

View File

@ -241,7 +241,7 @@ bgp_bump_version (struct bgp_node *node)
extern void bgp_process_queue_init (void); extern void bgp_process_queue_init (void);
extern void bgp_route_init (void); extern void bgp_route_init (void);
extern void bgp_route_finish (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_announce_route (struct peer *, afi_t, safi_t);
extern void bgp_stop_announce_route_timer(struct peer_af *paf); extern void bgp_stop_announce_route_timer(struct peer_af *paf);
extern void bgp_announce_route_all (struct peer *); extern void bgp_announce_route_all (struct peer *);

View File

@ -573,8 +573,8 @@ subgroup_clear_table (struct update_subgroup *subgrp)
SUBGRP_FOREACH_ADJ_SAFE (subgrp, aout, taout) SUBGRP_FOREACH_ADJ_SAFE (subgrp, aout, taout)
{ {
bgp_unlock_node (aout->rn);
bgp_adj_out_remove_subgroup (aout->rn, aout, subgrp); bgp_adj_out_remove_subgroup (aout->rn, aout, subgrp);
bgp_unlock_node (aout->rn);
} }
} }

View File

@ -11421,6 +11421,7 @@ community_list_vty (void)
/* Community-list. */ /* Community-list. */
install_element (CONFIG_NODE, &ip_community_list_standard_cmd); install_element (CONFIG_NODE, &ip_community_list_standard_cmd);
install_element (CONFIG_NODE, &ip_community_list_expanded_all_cmd);
install_element (CONFIG_NODE, &no_ip_community_list_standard_all_cmd); install_element (CONFIG_NODE, &no_ip_community_list_standard_all_cmd);
install_element (CONFIG_NODE, &no_ip_community_list_expanded_all_cmd); install_element (CONFIG_NODE, &no_ip_community_list_expanded_all_cmd);
install_element (VIEW_NODE, &show_ip_community_list_cmd); install_element (VIEW_NODE, &show_ip_community_list_cmd);

View File

@ -1792,6 +1792,7 @@ bgp_redist_del (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
if (red) if (red)
{ {
listnode_delete(bgp->redist[afi][type], red); listnode_delete(bgp->redist[afi][type], red);
XFREE (MTYPE_BGP_REDIST, red);
if (!bgp->redist[afi][type]->count) if (!bgp->redist[afi][type]->count)
{ {
list_free(bgp->redist[afi][type]); list_free(bgp->redist[afi][type]);

View File

@ -1044,6 +1044,12 @@ peer_free (struct peer *peer)
peer->host = NULL; peer->host = NULL;
} }
if (peer->domainname)
{
XFREE (MTYPE_BGP_PEER_HOST, peer->domainname);
peer->domainname = NULL;
}
if (peer->ifname) if (peer->ifname)
{ {
XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname); XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
@ -1972,7 +1978,8 @@ peer_delete (struct peer *peer)
bgp_fsm_change_status (peer, Deleted); bgp_fsm_change_status (peer, Deleted);
/* Remove from NHT */ /* Remove from NHT */
bgp_unlink_nexthop_by_peer (peer); if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
bgp_unlink_nexthop_by_peer (peer);
/* Password configuration */ /* Password configuration */
if (peer->password) if (peer->password)
@ -2964,7 +2971,7 @@ bgp_lookup_by_vrf_id (vrf_id_t vrf_id)
struct vrf *vrf; struct vrf *vrf;
/* Lookup VRF (in tree) and follow link. */ /* Lookup VRF (in tree) and follow link. */
vrf = vrf_lookup (vrf_id); vrf = vrf_lookup_by_id (vrf_id);
if (!vrf) if (!vrf)
return NULL; return NULL;
return (vrf->info) ? (struct bgp *)vrf->info : NULL; return (vrf->info) ? (struct bgp *)vrf->info : NULL;
@ -3122,6 +3129,7 @@ bgp_delete (struct bgp *bgp)
struct peer *peer; struct peer *peer;
struct peer_group *group; struct peer_group *group;
struct listnode *node, *next; struct listnode *node, *next;
struct vrf *vrf;
afi_t afi; afi_t afi;
int i; int i;
@ -3178,15 +3186,13 @@ bgp_delete (struct bgp *bgp)
#if ENABLE_BGP_VNC #if ENABLE_BGP_VNC
rfapi_delete(bgp); rfapi_delete(bgp);
bgp_cleanup_routes(); /* rfapi cleanup can create route entries! */
#endif #endif
bgp_cleanup_routes(bgp);
/* Remove visibility via the master list - there may however still be /* Remove visibility via the master list - there may however still be
* routes to be processed still referencing the struct bgp. * routes to be processed still referencing the struct bgp.
*/ */
listnode_delete (bm->bgp, bgp); listnode_delete (bm->bgp, bgp);
if (list_isempty(bm->bgp))
bgp_close ();
/* Deregister from Zebra, if needed */ /* Deregister from Zebra, if needed */
if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
@ -3195,6 +3201,10 @@ bgp_delete (struct bgp *bgp)
/* Free interfaces in this instance. */ /* Free interfaces in this instance. */
bgp_if_finish (bgp); 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); thread_master_free_unused(bm->master);
bgp_unlock(bgp); /* initial reference */ bgp_unlock(bgp); /* initial reference */
@ -3222,7 +3232,6 @@ bgp_free (struct bgp *bgp)
{ {
afi_t afi; afi_t afi;
safi_t safi; safi_t safi;
struct vrf *vrf;
list_delete (bgp->group); list_delete (bgp->group);
list_delete (bgp->peer); list_delete (bgp->peer);
@ -3244,13 +3253,9 @@ bgp_free (struct bgp *bgp)
bgp_table_finish (&bgp->rib[afi][safi]); bgp_table_finish (&bgp->rib[afi][safi]);
} }
bgp_scan_finish (bgp);
bgp_address_destroy (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) if (bgp->name)
XFREE(MTYPE_BGP, bgp->name); XFREE(MTYPE_BGP, bgp->name);
@ -7596,8 +7601,6 @@ bgp_terminate (void)
bgp_notify_send (peer, BGP_NOTIFY_CEASE, bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_PEER_UNCONFIG); BGP_NOTIFY_CEASE_PEER_UNCONFIG);
bgp_cleanup_routes ();
if (bm->process_main_queue) if (bm->process_main_queue)
{ {
work_queue_free (bm->process_main_queue); work_queue_free (bm->process_main_queue);

View File

@ -1490,7 +1490,7 @@ bgp_vrf_lookup_by_instance_type (struct bgp *bgp)
struct vrf *vrf; struct vrf *vrf;
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) 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) else if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
vrf = vrf_lookup_by_name (bgp->name); vrf = vrf_lookup_by_name (bgp->name);
else else

View File

@ -421,15 +421,7 @@ sock_set_ipv4_mcast(struct iface *iface)
int int
sock_set_ipv4_mcast_loop(int fd) sock_set_ipv4_mcast_loop(int fd)
{ {
uint8_t loop = 0; return (setsockopt_ipv4_multicast_loop(fd, 0));
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
(char *)&loop, sizeof(loop)) < 0) {
log_warn("%s: error setting IP_MULTICAST_LOOP", __func__);
return (-1);
}
return (0);
} }
int int

View File

@ -2069,21 +2069,6 @@ DEFUN (config_log_syslog,
} }
} }
DEFUN_DEPRECATED (config_log_syslog_facility,
config_log_syslog_facility_cmd,
"log syslog facility (kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7)",
"Logging control\n"
"Logging goes to syslog\n"
"(Deprecated) Facility parameter for syslog messages\n"
LOG_FACILITY_DESC)
{
int facility = facility_match(argv[3]->arg);
zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
zlog_default->facility = facility;
return CMD_SUCCESS;
}
DEFUN (no_config_log_syslog, DEFUN (no_config_log_syslog,
no_config_log_syslog_cmd, no_config_log_syslog_cmd,
"no log syslog [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>] [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", "no log syslog [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>] [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
@ -2483,4 +2468,6 @@ cmd_terminate ()
XFREE (MTYPE_HOST, host.motdfile); XFREE (MTYPE_HOST, host.motdfile);
if (host.config) if (host.config)
XFREE (MTYPE_HOST, host.config); XFREE (MTYPE_HOST, host.config);
qobj_finish ();
} }

View File

@ -27,7 +27,6 @@
#include "command_match.h" #include "command_match.h"
#include "memory.h" #include "memory.h"
#ifdef TRACE_MATCHER #ifdef TRACE_MATCHER
#define TM 1 #define TM 1
#else #else
@ -37,8 +36,6 @@
#define trace_matcher(...) \ #define trace_matcher(...) \
do { if (TM) fprintf (stderr, __VA_ARGS__); } while (0); do { if (TM) fprintf (stderr, __VA_ARGS__); } while (0);
DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens")
/* matcher helper prototypes */ /* matcher helper prototypes */
static int static int
add_nexthops (struct list *, struct graph_node *); add_nexthops (struct list *, struct graph_node *);
@ -125,12 +122,28 @@ command_match (struct graph *cmdgraph,
assert (*el); assert (*el);
} }
<<<<<<< HEAD
if (!*el) { if (!*el) {
trace_matcher ("No match\n"); trace_matcher ("No match\n");
} }
else { else {
trace_matcher ("Matched command\n->string %s\n->desc %s\n", (*el)->string, (*el)->doc); trace_matcher ("Matched command\n->string %s\n->desc %s\n", (*el)->string, (*el)->doc);
} }
||||||| merged common ancestors
if (!*el) {
trace_matcher ("No match");
}
else {
trace_matcher ("Matched command\n->string %s\n->desc %s\n", (*el)->string, (*el)->doc);
}
=======
#ifdef TRACE_MATCHER
if (!*el)
fprintf (stdout, "No match\n");
else
fprintf (stdout, "Matched command\n->string %s\n->desc %s\n", (*el)->string, (*el)->doc);
#endif
>>>>>>> osr/master
// free the leader token we alloc'd // free the leader token we alloc'd
XFREE (MTYPE_TMP, vector_slot (vvline, 0)); XFREE (MTYPE_TMP, vector_slot (vvline, 0));
@ -203,26 +216,28 @@ command_match_r (struct graph_node *start, vector vline, unsigned int n)
// get the current operating input token // get the current operating input token
char *input_token = vector_slot (vline, n); char *input_token = vector_slot (vline, n);
trace_matcher ("\"%-20s\" matches \"%-30s\" ? ", input_token, token->text); #ifdef TRACE_MATCHER
fprintf (stdout, "\"%-20s\" matches \"%-30s\" ? ", input_token, token->text);
enum match_type mt = match_token (token, input_token); enum match_type mt = match_token (token, input_token);
trace_matcher ("min: %d - ", minmatch); fprintf (stdout, "min: %d - ", minmatch);
switch (mt) switch (mt)
{ {
case trivial_match: case trivial_match:
trace_matcher ("trivial_match "); fprintf (stdout, "trivial_match ");
break; break;
case no_match: case no_match:
trace_matcher ("no_match "); fprintf (stdout, "no_match ");
break; break;
case partly_match: case partly_match:
trace_matcher ("partly_match "); fprintf (stdout, "partly_match ");
break; break;
case exact_match: case exact_match:
trace_matcher ("exact_match "); fprintf (stdout, "exact_match ");
break; break;
} }
if (mt >= minmatch) { trace_matcher (" MATCH") }; if (mt >= minmatch) fprintf (stdout, " MATCH");
trace_matcher ("\n"); fprintf (stdout, "\n");
#endif
// if we don't match this node, die // if we don't match this node, die
if (match_token (token, input_token) < minmatch) if (match_token (token, input_token) < minmatch)
@ -359,8 +374,16 @@ command_complete (struct graph *graph,
continue; continue;
enum match_type minmatch = min_match_level (token->type); enum match_type minmatch = min_match_level (token->type);
<<<<<<< HEAD
trace_matcher ("\"%s\" matches \"%s\" (%d) ? ", trace_matcher ("\"%s\" matches \"%s\" (%d) ? ",
input_token, token->text, token->type); input_token, token->text, token->type);
||||||| merged common ancestors
trace_matcher ("\"%s\" matches \"%s\" (%d) ? ", input_token, token->text, token->type);
=======
#ifdef TRACE_MATCHER
fprintf (stdout, "\"%s\" matches \"%s\" (%d) ? ", input_token, token->text, token->type);
#endif
>>>>>>> osr/master
unsigned int last_token = (vector_active (vline) - 1 == idx); unsigned int last_token = (vector_active (vline) - 1 == idx);
enum match_type matchtype = match_token (token, input_token); enum match_type matchtype = match_token (token, input_token);
@ -368,23 +391,73 @@ command_complete (struct graph *graph,
{ {
// occurs when last token is whitespace // occurs when last token is whitespace
case trivial_match: case trivial_match:
<<<<<<< HEAD
trace_matcher ("trivial_match\n"); trace_matcher ("trivial_match\n");
assert(last_token); assert(last_token);
listnode_add (next, gn); listnode_add (next, gn);
break; break;
||||||| merged common ancestors
trace_matcher ("trivial_match\n");
assert(idx == vector_active (vline) - 1);
listnode_add (next, gn);
break;
=======
#ifdef TRACE_MATCHER
fprintf (stdout, "trivial_match\n");
#endif
>>>>>>> osr/master
case partly_match: case partly_match:
<<<<<<< HEAD
trace_matcher ("trivial_match\n"); trace_matcher ("trivial_match\n");
if (exact_match_exists && !last_token) if (exact_match_exists && !last_token)
break; break;
||||||| merged common ancestors
trace_matcher ("partly_match\n");
// last token on line is partial and
// not a space
if (idx == vector_active (vline) - 1)
{
listnode_add (next, gn);
break;
}
if (minmatch <= partly_match)
add_nexthops (next, gn);
break;
=======
#ifdef TRACE_MATCHER
fprintf (stdout, "partly_match\n");
#endif
if (idx == vector_active (vline) - 1)
{
listnode_add (next, gn);
break;
}
if (minmatch > partly_match)
break;
>>>>>>> osr/master
case exact_match: case exact_match:
<<<<<<< HEAD
trace_matcher ("exact_match\n"); trace_matcher ("exact_match\n");
if (last_token) if (last_token)
listnode_add (next, gn); listnode_add (next, gn);
else if (matchtype >= minmatch) else if (matchtype >= minmatch)
add_nexthops (next, gn); add_nexthops (next, gn);
||||||| merged common ancestors
trace_matcher ("exact_match\n");
add_nexthops (next, gn);
listnode_add (next, gn);
=======
#ifdef TRACE_MATCHER
fprintf (stdout, "exact_match\n");
#endif
add_nexthops (next, gn);
>>>>>>> osr/master
break; break;
default: default:
trace_matcher ("no_match\n"); #ifdef TRACE_MATCHER
fprintf (stdout, "no_match\n");
#endif
break; break;
} }
} }

121
lib/if.c
View File

@ -307,13 +307,11 @@ if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id)
struct interface * struct interface *
if_lookup_by_name_all_vrf (const char *name) if_lookup_by_name_all_vrf (const char *name)
{ {
struct vrf *vrf;
struct interface *ifp; 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); ifp = if_lookup_by_name_vrf (name, vrf->vrf_id);
if (ifp) if (ifp)
return ifp; return ifp;
@ -392,7 +390,7 @@ if_lookup_exact_address (void *src, int family)
} }
/* Lookup interface by IPv4 address. */ /* Lookup interface by IPv4 address. */
struct interface * struct connected *
if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id) if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
{ {
struct listnode *node; struct listnode *node;
@ -401,7 +399,7 @@ if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
struct listnode *cnode; struct listnode *cnode;
struct interface *ifp; struct interface *ifp;
struct connected *c; struct connected *c;
struct interface *match; struct connected *match;
if (family == AF_INET) if (family == AF_INET)
{ {
@ -427,14 +425,14 @@ if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
(c->address->prefixlen > bestlen)) (c->address->prefixlen > bestlen))
{ {
bestlen = c->address->prefixlen; bestlen = c->address->prefixlen;
match = ifp; match = c;
} }
} }
} }
return match; return match;
} }
struct interface * struct connected *
if_lookup_address (void *matchaddr, int family) if_lookup_address (void *matchaddr, int family)
{ {
return if_lookup_address_vrf (matchaddr, family, VRF_DEFAULT); return if_lookup_address_vrf (matchaddr, family, VRF_DEFAULT);
@ -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) if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id, int vty)
{ {
struct interface *ifp; struct interface *ifp;
struct vrf *vrf;
struct listnode *node; struct listnode *node;
struct vrf *vrf = NULL;
vrf_iter_t iter;
ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id); ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id);
if (ifp) if (ifp)
return ifp; return ifp;
/* Didn't find the interface on that vrf. Defined on a different one? */ /* 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)) for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf->vrf_id), node, ifp))
{ {
if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0')) if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
@ -665,14 +661,13 @@ if_dump (const struct interface *ifp)
void void
if_dump_all (void) if_dump_all (void)
{ {
struct list *intf_list; struct vrf *vrf;
struct listnode *node; struct listnode *node;
void *p; void *p;
vrf_iter_t iter;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
if ((intf_list = vrf_iter2iflist (iter)) != NULL) if (vrf->iflist != NULL)
for (ALL_LIST_ELEMENTS_RO (intf_list, node, p)) for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, p))
if_dump (p); if_dump (p);
} }
@ -843,72 +838,7 @@ if_cmd_init (void)
install_element (INTERFACE_NODE, &no_interface_desc_cmd); install_element (INTERFACE_NODE, &no_interface_desc_cmd);
} }
DEFUN (vrf, #if 0
vrf_cmd,
"vrf NAME",
"Select a VRF to configure\n"
"VRF's name\n")
{
int idx_name = 1;
const char *vrfname = argv[idx_name]->arg;
struct vrf *vrfp;
size_t sl;
if ((sl = strlen(vrfname)) > VRF_NAMSIZ)
{
vty_out (vty, "%% VRF name %s is invalid: length exceeds "
"%d characters%s",
vrfname, VRF_NAMSIZ, VTY_NEWLINE);
return CMD_WARNING;
}
vrfp = vrf_get (VRF_UNKNOWN, vrfname);
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")
{
const char *vrfname = argv[2]->arg;
struct vrf *vrfp;
vrfp = vrf_list_lookup_by_name (vrfname);;
if (vrfp == NULL)
{
vty_out (vty, "%% VRF %s does not exist%s", vrfname, 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;
}
void
vrf_cmd_init (void)
{
install_element (CONFIG_NODE, &vrf_cmd);
install_element (CONFIG_NODE, &no_vrf_cmd);
install_default (VRF_NODE);
}
/* For debug purpose. */ /* For debug purpose. */
DEFUN (show_address, DEFUN (show_address,
show_address_cmd, show_address_cmd,
@ -949,24 +879,22 @@ DEFUN (show_address_vrf_all,
"address\n" "address\n"
VRF_ALL_CMD_HELP_STR) VRF_ALL_CMD_HELP_STR)
{ {
struct list *intf_list; struct vrf *vrf;
struct listnode *node; struct listnode *node;
struct listnode *node2; struct listnode *node2;
struct interface *ifp; struct interface *ifp;
struct connected *ifc; struct connected *ifc;
struct prefix *p; 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 (!vrf->iflist || !listcount (vrf->iflist))
if (!intf_list || !listcount (intf_list))
continue; continue;
vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf_iter2id (iter), vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id, VTY_NEWLINE,
VTY_NEWLINE, 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)) for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
{ {
@ -980,6 +908,7 @@ DEFUN (show_address_vrf_all,
} }
return CMD_SUCCESS; return CMD_SUCCESS;
} }
#endif
/* Allocate connected structure. */ /* Allocate connected structure. */
struct connected * struct connected *
@ -1377,14 +1306,14 @@ if_link_params_get (struct interface *ifp)
iflp->te_metric = ifp->metric; iflp->te_metric = ifp->metric;
/* Compute default bandwidth based on interface */ /* Compute default bandwidth based on interface */
int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH) iflp->default_bw = ((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
* TE_KILO_BIT / TE_BYTE); * TE_KILO_BIT / TE_BYTE);
/* Set Max, Reservable and Unreserved Bandwidth */ /* Set Max, Reservable and Unreserved Bandwidth */
iflp->max_bw = bw; iflp->max_bw = iflp->default_bw;
iflp->max_rsv_bw = bw; iflp->max_rsv_bw = iflp->default_bw;
for (i = 0; i < MAX_CLASS_TYPE; i++) for (i = 0; i < MAX_CLASS_TYPE; i++)
iflp->unrsv_bw[i] = bw; iflp->unrsv_bw[i] = iflp->default_bw;
/* Update Link parameters status */ /* Update Link parameters status */
iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW; iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;

View File

@ -161,6 +161,7 @@ struct if_stats
#define LP_RES_BW 0x0400 #define LP_RES_BW 0x0400
#define LP_AVA_BW 0x0800 #define LP_AVA_BW 0x0800
#define LP_USE_BW 0x1000 #define LP_USE_BW 0x1000
#define LP_TE_METRIC 0x2000
#define IS_PARAM_UNSET(lp, st) !(lp->lp_status & st) #define IS_PARAM_UNSET(lp, st) !(lp->lp_status & st)
#define IS_PARAM_SET(lp, st) (lp->lp_status & st) #define IS_PARAM_SET(lp, st) (lp->lp_status & st)
@ -174,6 +175,7 @@ struct if_stats
struct if_link_params { struct if_link_params {
u_int32_t lp_status; /* Status of Link Parameters: */ u_int32_t lp_status; /* Status of Link Parameters: */
u_int32_t te_metric; /* Traffic Engineering metric */ u_int32_t te_metric; /* Traffic Engineering metric */
float default_bw;
float max_bw; /* Maximum Bandwidth */ float max_bw; /* Maximum Bandwidth */
float max_rsv_bw; /* Maximum Reservable Bandwidth */ float max_rsv_bw; /* Maximum Reservable Bandwidth */
float unrsv_bw[MAX_CLASS_TYPE]; /* Unreserved Bandwidth per Class Type (8) */ float unrsv_bw[MAX_CLASS_TYPE]; /* Unreserved Bandwidth per Class Type (8) */
@ -387,7 +389,7 @@ extern int if_cmp_name_func (char *, char *);
extern struct interface *if_create (const char *name, int namelen); extern struct interface *if_create (const char *name, int namelen);
extern struct interface *if_lookup_by_index (ifindex_t); extern struct interface *if_lookup_by_index (ifindex_t);
extern struct interface *if_lookup_exact_address (void *matchaddr, int family); extern struct interface *if_lookup_exact_address (void *matchaddr, int family);
extern struct interface *if_lookup_address (void *matchaddr, int family); extern struct connected *if_lookup_address (void *matchaddr, int family);
extern struct interface *if_lookup_prefix (struct prefix *prefix); extern struct interface *if_lookup_prefix (struct prefix *prefix);
extern void if_update_vrf (struct interface *, const char *name, int namelen, extern void if_update_vrf (struct interface *, const char *name, int namelen,
@ -397,7 +399,7 @@ extern struct interface *if_create_vrf (const char *name, int namelen,
extern struct interface *if_lookup_by_index_vrf (ifindex_t, vrf_id_t vrf_id); extern struct interface *if_lookup_by_index_vrf (ifindex_t, vrf_id_t vrf_id);
extern struct interface *if_lookup_exact_address_vrf (void *matchaddr, int family, extern struct interface *if_lookup_exact_address_vrf (void *matchaddr, int family,
vrf_id_t vrf_id); vrf_id_t vrf_id);
extern struct interface *if_lookup_address_vrf (void *matchaddr, int family, extern struct connected *if_lookup_address_vrf (void *matchaddr, int family,
vrf_id_t vrf_id); vrf_id_t vrf_id);
extern struct interface *if_lookup_prefix_vrf (struct prefix *prefix, extern struct interface *if_lookup_prefix_vrf (struct prefix *prefix,
vrf_id_t vrf_id); vrf_id_t vrf_id);
@ -451,8 +453,6 @@ extern void if_dump_all (void);
extern const char *if_flag_dump(unsigned long); extern const char *if_flag_dump(unsigned long);
extern const char *if_link_type_str (enum zebra_link_type); extern const char *if_link_type_str (enum zebra_link_type);
extern void vrf_cmd_init (void);
/* Please use ifindex2ifname instead of if_indextoname where possible; /* Please use ifindex2ifname instead of if_indextoname where possible;
ifindex2ifname uses internal interface info, whereas if_indextoname must ifindex2ifname uses internal interface info, whereas if_indextoname must
make a system call. */ make a system call. */

309
lib/ns.c
View File

@ -31,8 +31,6 @@
#include "if.h" #include "if.h"
#include "ns.h" #include "ns.h"
#include "prefix.h"
#include "table.h"
#include "log.h" #include "log.h"
#include "memory.h" #include "memory.h"
@ -41,7 +39,13 @@
DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router") DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router")
DEFINE_MTYPE_STATIC(LIB, NS_NAME, "Logical-Router Name") 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 #ifndef CLONE_NEWNET
#define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */ #define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */
@ -91,22 +95,6 @@ static int have_netns(void)
#endif #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 */ /* Holding NS hooks */
struct ns_master struct ns_master
{ {
@ -116,44 +104,30 @@ struct ns_master
int (*ns_disable_hook) (ns_id_t, void **); int (*ns_disable_hook) (ns_id_t, void **);
} ns_master = {0,}; } ns_master = {0,};
/* NS table */
struct route_table *ns_table = NULL;
static int ns_is_enabled (struct ns *ns); static int ns_is_enabled (struct ns *ns);
static int ns_enable (struct ns *ns); static int ns_enable (struct ns *ns);
static void ns_disable (struct ns *ns); static void ns_disable (struct ns *ns);
static __inline int
/* Build the table key */ ns_compare(struct ns *a, struct ns *b)
static void
ns_build_key (ns_id_t ns_id, struct prefix *p)
{ {
p->family = AF_INET; return (a->ns_id - b->ns_id);
p->prefixlen = IPV4_MAX_BITLEN;
p->u.prefix4.s_addr = ns_id;
} }
/* Get a NS. If not found, create one. */ /* Get a NS. If not found, create one. */
static struct ns * static struct ns *
ns_get (ns_id_t ns_id) ns_get (ns_id_t ns_id)
{ {
struct prefix p;
struct route_node *rn;
struct ns *ns; struct ns *ns;
ns_build_key (ns_id, &p); ns = ns_lookup (ns_id);
rn = route_node_get (ns_table, &p); if (ns)
if (rn->info) return (ns);
{
ns = (struct ns *)rn->info;
route_unlock_node (rn); /* get */
return ns;
}
ns = XCALLOC (MTYPE_NS, sizeof (struct ns)); ns = XCALLOC (MTYPE_NS, sizeof (struct ns));
ns->ns_id = ns_id; ns->ns_id = ns_id;
ns->fd = -1; ns->fd = -1;
rn->info = ns; RB_INSERT (ns_head, &ns_tree, ns);
/* /*
* Initialize interfaces. * Initialize interfaces.
@ -188,6 +162,7 @@ ns_delete (struct ns *ns)
*/ */
//if_terminate (&ns->iflist); //if_terminate (&ns->iflist);
RB_REMOVE (ns_head, &ns_tree, ns);
if (ns->name) if (ns->name)
XFREE (MTYPE_NS_NAME, ns->name); XFREE (MTYPE_NS_NAME, ns->name);
@ -198,18 +173,9 @@ ns_delete (struct ns *ns)
static struct ns * static struct ns *
ns_lookup (ns_id_t ns_id) ns_lookup (ns_id_t ns_id)
{ {
struct prefix p; struct ns ns;
struct route_node *rn; ns.ns_id = ns_id;
struct ns *ns = NULL; return (RB_FIND (ns_head, &ns_tree, &ns));
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;
} }
/* /*
@ -310,217 +276,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 * NS realization with NETNS
*/ */
@ -645,17 +400,17 @@ static struct cmd_node ns_node =
static int static int
ns_config_write (struct vty *vty) ns_config_write (struct vty *vty)
{ {
struct route_node *rn;
struct ns *ns; struct ns *ns;
int write = 0; int write = 0;
for (rn = route_top (ns_table); rn; rn = route_next (rn)) RB_FOREACH (ns, ns_head, &ns_tree) {
if ((ns = rn->info) != NULL && if (ns->ns_id == NS_DEFAULT || ns->name == NULL)
ns->ns_id != NS_DEFAULT && ns->name) continue;
{
vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name, VTY_NEWLINE); vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name,
write++; VTY_NEWLINE);
} write = 1;
}
return write; return write;
} }
@ -666,9 +421,6 @@ ns_init (void)
{ {
struct ns *default_ns; struct ns *default_ns;
/* Allocate NS table. */
ns_table = route_table_init ();
/* The default NS always exists. */ /* The default NS always exists. */
default_ns = ns_get (NS_DEFAULT); default_ns = ns_get (NS_DEFAULT);
if (!default_ns) if (!default_ns)
@ -700,15 +452,10 @@ ns_init (void)
void void
ns_terminate (void) ns_terminate (void)
{ {
struct route_node *rn;
struct ns *ns; struct ns *ns;
for (rn = route_top (ns_table); rn; rn = route_next (rn)) while ((ns = RB_ROOT (&ns_tree)) != NULL)
if ((ns = rn->info) != NULL) ns_delete (ns);
ns_delete (ns);
route_table_finish (ns_table);
ns_table = NULL;
} }
/* Create a socket for the NS. */ /* Create a socket for the NS. */

View File

@ -23,6 +23,7 @@
#ifndef _ZEBRA_NS_H #ifndef _ZEBRA_NS_H
#define _ZEBRA_NS_H #define _ZEBRA_NS_H
#include "openbsd-tree.h"
#include "linklist.h" #include "linklist.h"
typedef u_int16_t ns_id_t; typedef u_int16_t ns_id_t;
@ -30,15 +31,32 @@ typedef u_int16_t ns_id_t;
/* The default NS ID */ /* The default NS ID */
#define NS_DEFAULT 0 #define NS_DEFAULT 0
/* /* Default netns directory (Linux) */
* The command strings
*/
#define NS_RUN_DIR "/var/run/netns" #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" struct ns
#define NS_ALL_CMD_HELP_STR "Specify the logical-router\nAll logical-router's\n" {
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 * NS hooks
@ -59,71 +77,6 @@ typedef u_int16_t ns_id_t;
*/ */
extern void ns_add_hook (int, int (*)(ns_id_t, void **)); 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 * NS initializer/destructor
*/ */

View File

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

View File

@ -384,7 +384,20 @@ setsockopt_ipv4_multicast_if(int sock, struct in_addr if_addr,
#error "Unsupported multicast API" #error "Unsupported multicast API"
#endif #endif
} }
int
setsockopt_ipv4_multicast_loop (int sock, u_char val)
{
int ret;
ret = setsockopt (sock, IPPROTO_IP, IP_MULTICAST_LOOP, (void *) &val,
sizeof (val));
if (ret < 0)
zlog_warn ("can't setsockopt IP_MULTICAST_LOOP");
return ret;
}
static int static int
setsockopt_ipv4_ifindex (int sock, ifindex_t val) setsockopt_ipv4_ifindex (int sock, ifindex_t val)
{ {

View File

@ -89,6 +89,8 @@ extern int setsockopt_ipv4_multicast(int sock, int optname,
struct in_addr if_addr, struct in_addr if_addr,
unsigned int mcast_addr, unsigned int mcast_addr,
ifindex_t ifindex); ifindex_t ifindex);
extern int setsockopt_ipv4_multicast_loop (int sock, u_char val);
extern int setsockopt_ipv4_tos(int sock, int tos); extern int setsockopt_ipv4_tos(int sock, int tos);
/* Ask for, and get, ifindex, by whatever method is supported. */ /* Ask for, and get, ifindex, by whatever method is supported. */

View File

@ -494,7 +494,7 @@ route_table_count (const struct route_table *table)
* *
* Default function for creating a route node. * Default function for creating a route node.
*/ */
static struct route_node * struct route_node *
route_node_create (route_table_delegate_t *delegate, route_node_create (route_table_delegate_t *delegate,
struct route_table *table) struct route_table *table)
{ {
@ -508,7 +508,7 @@ route_node_create (route_table_delegate_t *delegate,
* *
* Default function for destroying a route node. * Default function for destroying a route node.
*/ */
static void void
route_node_destroy (route_table_delegate_t *delegate, route_node_destroy (route_table_delegate_t *delegate,
struct route_table *table, struct route_node *node) struct route_table *table, struct route_node *node)
{ {

View File

@ -169,6 +169,11 @@ extern struct route_node *route_node_match_ipv6 (const struct route_table *,
extern unsigned long route_table_count (const struct route_table *); extern 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 * extern struct route_node *
route_table_get_next (const struct route_table *table, struct prefix *p); route_table_get_next (const struct route_table *table, struct prefix *p);
extern int extern int

529
lib/vrf.c
View File

@ -35,6 +35,15 @@ DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
DEFINE_QOBJ_TYPE(vrf) 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 * Turn on/off debug code
* for vrf. * for vrf.
@ -44,44 +53,34 @@ int debug_vrf = 0;
/* Holding VRF hooks */ /* Holding VRF hooks */
struct vrf_master struct vrf_master
{ {
int (*vrf_new_hook) (vrf_id_t, const char *, void **); int (*vrf_new_hook) (struct vrf *);
int (*vrf_delete_hook) (vrf_id_t, const char *, void **); int (*vrf_delete_hook) (struct vrf *);
int (*vrf_enable_hook) (vrf_id_t, const char *, void **); int (*vrf_enable_hook) (struct vrf *);
int (*vrf_disable_hook) (vrf_id_t, const char *, void **); int (*vrf_disable_hook) (struct vrf *);
} vrf_master = {0,}; } 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 int vrf_is_enabled (struct vrf *vrf);
static void vrf_disable (struct vrf *vrf); static void vrf_disable (struct vrf *vrf);
/* VRF list existance check by name. */ /* VRF list existance check by name. */
struct vrf * struct vrf *
vrf_list_lookup_by_name (const char *name) vrf_lookup_by_name (const char *name)
{ {
struct listnode *node; struct vrf vrf;
struct vrf *vrfp; strlcpy (vrf.name, name, sizeof (vrf.name));
return (RB_FIND (vrf_name_head, &vrfs_by_name, &vrf));
if (name)
for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrfp))
{
if (strcmp(name, vrfp->name) == 0)
return vrfp;
}
return NULL;
} }
/* Build the table key */ static __inline int
static void vrf_id_compare (struct vrf *a, struct vrf *b)
vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
{ {
p->family = AF_INET; return (a->vrf_id - b->vrf_id);
p->prefixlen = IPV4_MAX_BITLEN; }
p->u.prefix4.s_addr = 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. /* 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 * struct vrf *
vrf_get (vrf_id_t vrf_id, const char *name) vrf_get (vrf_id_t vrf_id, const char *name)
{ {
struct prefix p;
struct route_node *rn = NULL;
struct vrf *vrf = NULL; struct vrf *vrf = NULL;
int new = 0;
if (debug_vrf) if (debug_vrf)
zlog_debug ("VRF_GET: %s(%d)", name, vrf_id); 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) if (!name && vrf_id == VRF_UNKNOWN)
return NULL; return NULL;
/* /* Try to find VRF both by ID and name */
* Valid vrf name and unknown vrf_id case if (vrf_id != VRF_UNKNOWN)
* vrf = vrf_lookup_by_id (vrf_id);
* This is called when we are configured from if (! vrf && name)
* the cli but we have no kernel information yet. vrf = vrf_lookup_by_name (name);
*/
if (name && vrf_id == VRF_UNKNOWN)
{
vrf = vrf_list_lookup_by_name (name);
if (vrf)
return vrf;
if (vrf == NULL)
{
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
if (debug_vrf) vrf->vrf_id = VRF_UNKNOWN;
zlog_debug ("VRF(%u) %s is created.",
vrf_id, (name) ? name : "(NULL)");
strcpy (vrf->name, name);
listnode_add_sort (vrf_list, vrf);
if_init (&vrf->iflist); if_init (&vrf->iflist);
QOBJ_REG (vrf, vrf); QOBJ_REG (vrf, vrf);
if (vrf_master.vrf_new_hook) new = 1;
{
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
if (debug_vrf && vrf->info)
zlog_info ("zvrf is created.");
}
if (debug_vrf) if (debug_vrf)
zlog_debug("Vrf Created: %p", vrf); zlog_debug ("VRF(%u) %s is created.",
return vrf; vrf_id, (name) ? name : "(NULL)");
} }
/*
* Valid vrf name and valid vrf_id case /* Set identifier */
* if (vrf_id != VRF_UNKNOWN && vrf->vrf_id == VRF_UNKNOWN)
* This can be passed from the kernel
*/
else if (name && vrf_id != VRF_UNKNOWN)
{ {
vrf = vrf_list_lookup_by_name (name); vrf->vrf_id = vrf_id;
if (vrf) RB_INSERT (vrf_id_head, &vrfs_by_id, 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;
}
}
} }
/*
* The final case, we've been passed a valid vrf_id /* Set name */
* but no name. So we create the route node if (name && vrf->name[0] != '\0' && strcmp (name, vrf->name))
* if it hasn't already been created.
*/
else if (!name)
{ {
vrf_build_key (vrf_id, &p); RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf);
rn = route_node_get (vrf_table, &p); strlcpy (vrf->name, name, sizeof (vrf->name));
if (debug_vrf) RB_INSERT (vrf_name_head, &vrfs_by_name, vrf);
zlog_debug("Vrf found: %p", rn->info); }
else if (name && vrf->name[0] == '\0')
if (rn->info) {
{ strlcpy (vrf->name, name, sizeof (vrf->name));
route_unlock_node (rn); RB_INSERT (vrf_name_head, &vrfs_by_name, vrf);
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;
}
} }
/* if (new && vrf_master.vrf_new_hook)
* We shouldn't get here and if we do (*vrf_master.vrf_new_hook) (vrf);
* something has gone wrong.
*/ return vrf;
return NULL;
} }
/* Delete a VRF. This is called in vrf_terminate(). */ /* Delete a VRF. This is called in vrf_terminate(). */
@ -278,53 +159,35 @@ vrf_delete (struct vrf *vrf)
vrf_disable (vrf); vrf_disable (vrf);
if (vrf_master.vrf_delete_hook) 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); QOBJ_UNREG (vrf);
if_terminate (&vrf->iflist); if_terminate (&vrf->iflist);
if (vrf->node) if (vrf->vrf_id != VRF_UNKNOWN)
{ RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf);
vrf->node->info = NULL; if (vrf->name[0] != '\0')
route_unlock_node(vrf->node); RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf);
}
listnode_delete (vrf_list, vrf);
XFREE (MTYPE_VRF, vrf); XFREE (MTYPE_VRF, vrf);
} }
/* Look up a VRF by identifier. */ /* Look up a VRF by identifier. */
struct vrf * struct vrf *
vrf_lookup (vrf_id_t vrf_id) vrf_lookup_by_id (vrf_id_t vrf_id)
{ {
struct prefix p; struct vrf vrf;
struct route_node *rn; vrf.vrf_id = vrf_id;
struct vrf *vrf = NULL; return (RB_FIND (vrf_id_head, &vrfs_by_id, &vrf));
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;
} }
/* /*
* Check whether the VRF is enabled - that is, whether the VRF * Check whether the VRF is enabled.
* is ready to allocate resources. Currently there's only one
* type of resource: socket.
*/ */
static int static int
vrf_is_enabled (struct vrf *vrf) vrf_is_enabled (struct vrf *vrf)
{ {
return vrf && CHECK_FLAG (vrf->status, VRF_ACTIVE); 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 int
vrf_enable (struct vrf *vrf) vrf_enable (struct vrf *vrf)
{ {
if (vrf_is_enabled (vrf))
return 1;
if (debug_vrf) if (debug_vrf)
zlog_debug ("VRF %u is enabled.", vrf->vrf_id); 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) 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; return 1;
} }
@ -357,26 +222,25 @@ vrf_enable (struct vrf *vrf)
static void static void
vrf_disable (struct vrf *vrf) vrf_disable (struct vrf *vrf)
{ {
if (vrf_is_enabled (vrf)) if (! vrf_is_enabled (vrf))
{ return;
UNSET_FLAG (vrf->status, VRF_ACTIVE);
if (debug_vrf) UNSET_FLAG (vrf->status, VRF_ACTIVE);
zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id);
/* Till now, nothing to be done for the default VRF. */ if (debug_vrf)
//Pending: see why this statement. zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id);
if (vrf_master.vrf_disable_hook) /* Till now, nothing to be done for the default VRF. */
(*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info); //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(). */ /* Add a VRF hook. Please add hooks before calling vrf_init(). */
void 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) if (debug_vrf)
zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__, 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_id_t
vrf_name_to_id (const char *name) vrf_name_to_id (const char *name)
{ {
@ -535,7 +289,7 @@ vrf_info_get (vrf_id_t vrf_id)
void * void *
vrf_info_lookup (vrf_id_t vrf_id) 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; return vrf ? vrf->info : NULL;
} }
@ -543,7 +297,7 @@ vrf_info_lookup (vrf_id_t vrf_id)
struct list * struct list *
vrf_iflist (vrf_id_t vrf_id) 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; return vrf ? vrf->iflist : NULL;
} }
@ -559,7 +313,7 @@ vrf_iflist_get (vrf_id_t vrf_id)
void void
vrf_iflist_create (vrf_id_t vrf_id) 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 (vrf && !vrf->iflist)
if_init (&vrf->iflist); if_init (&vrf->iflist);
} }
@ -568,7 +322,7 @@ vrf_iflist_create (vrf_id_t vrf_id)
void void
vrf_iflist_terminate (vrf_id_t vrf_id) 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 (vrf && vrf->iflist)
if_terminate (&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; 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. */ /* Initialize VRF module. */
void void
vrf_init (void) vrf_init (void)
@ -689,12 +429,6 @@ vrf_init (void)
if (debug_vrf) if (debug_vrf)
zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__); 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. */ /* The default VRF always exists. */
default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME); default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
if (!default_vrf) if (!default_vrf)
@ -715,18 +449,15 @@ vrf_init (void)
void void
vrf_terminate (void) vrf_terminate (void)
{ {
struct route_node *rn;
struct vrf *vrf; struct vrf *vrf;
if (debug_vrf) if (debug_vrf)
zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__); zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__);
for (rn = route_top (vrf_table); rn; rn = route_next (rn)) while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL)
if ((vrf = rn->info) != NULL) vrf_delete (vrf);
vrf_delete (vrf); while ((vrf = RB_ROOT (&vrfs_by_name)) != NULL)
vrf_delete (vrf);
route_table_finish (vrf_table);
vrf_table = NULL;
} }
/* Create a socket for the VRF. */ /* Create a socket for the VRF. */
@ -740,6 +471,73 @@ vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
return ret; return ret;
} }
/* vrf CLI commands */
DEFUN (vrf,
vrf_cmd,
"vrf NAME",
"Select a VRF to configure\n"
"VRF's name\n")
{
int idx_name = 1;
const char *vrfname = argv[idx_name]->arg;
struct vrf *vrfp;
size_t sl;
if ((sl = strlen(vrfname)) > VRF_NAMSIZ)
{
vty_out (vty, "%% VRF name %s is invalid: length exceeds "
"%d characters%s",
vrfname, VRF_NAMSIZ, VTY_NEWLINE);
return CMD_WARNING;
}
vrfp = vrf_get (VRF_UNKNOWN, vrfname);
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")
{
const char *vrfname = argv[2]->arg;
struct vrf *vrfp;
vrfp = vrf_lookup_by_name (vrfname);
if (vrfp == NULL)
{
vty_out (vty, "%% VRF %s does not exist%s", vrfname, 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;
}
struct cmd_node vrf_node =
{
VRF_NODE,
"%s(config-vrf)# ",
1
};
/* /*
* Debug CLI for vrf's * Debug CLI for vrf's
*/ */
@ -792,3 +590,12 @@ vrf_install_commands (void)
install_element (CONFIG_NODE, &no_vrf_debug_cmd); install_element (CONFIG_NODE, &no_vrf_debug_cmd);
install_element (ENABLE_NODE, &no_vrf_debug_cmd); install_element (ENABLE_NODE, &no_vrf_debug_cmd);
} }
void
vrf_cmd_init (int (*writefunc)(struct vty *vty))
{
install_element (CONFIG_NODE, &vrf_cmd);
install_element (CONFIG_NODE, &no_vrf_cmd);
install_node (&vrf_node, writefunc);
install_default (VRF_NODE);
}

View File

@ -23,8 +23,10 @@
#ifndef _ZEBRA_VRF_H #ifndef _ZEBRA_VRF_H
#define _ZEBRA_VRF_H #define _ZEBRA_VRF_H
#include "openbsd-tree.h"
#include "linklist.h" #include "linklist.h"
#include "qobj.h" #include "qobj.h"
#include "vty.h"
/* The default NS ID */ /* The default NS ID */
#define NS_DEFAULT 0 #define NS_DEFAULT 0
@ -65,18 +67,18 @@ enum {
struct vrf struct vrf
{ {
RB_ENTRY(vrf) id_entry, name_entry;
/* Identifier, same as the vector index */ /* Identifier, same as the vector index */
vrf_id_t vrf_id; vrf_id_t vrf_id;
/* Name */
/* Name */
char name[VRF_NAMSIZ + 1]; char name[VRF_NAMSIZ + 1];
/* Zebra internal VRF status */ /* Zebra internal VRF status */
u_char status; u_char status;
#define VRF_ACTIVE (1 << 0) #define VRF_ACTIVE (1 << 0)
struct route_node *node;
/* Master list of interfaces belonging to this VRF */ /* Master list of interfaces belonging to this VRF */
struct list *iflist; struct list *iflist;
@ -85,10 +87,15 @@ struct vrf
QOBJ_FIELDS 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) 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. * Add a specific hook to VRF module.
@ -98,18 +105,10 @@ extern struct list *vrf_list;
* - param 2: the address of the user data pointer (the user data * - param 2: the address of the user data pointer (the user data
* can be stored in or freed from there) * can be stored in or freed from there)
*/ */
extern void vrf_add_hook (int, int (*)(vrf_id_t, const char *, void **)); extern void vrf_add_hook (int, int (*)(struct vrf *));
/* extern struct vrf *vrf_lookup_by_id (vrf_id_t);
* VRF iteration
*/
typedef void * vrf_iter_t;
#define VRF_ITER_INVALID NULL /* invalid value of the iterator */
extern struct vrf *vrf_lookup (vrf_id_t);
extern struct vrf *vrf_lookup_by_name (const char *); extern struct vrf *vrf_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 struct vrf *vrf_get (vrf_id_t, const char *);
extern void vrf_delete (struct vrf *); extern void vrf_delete (struct vrf *);
extern int vrf_enable (struct vrf *); extern int vrf_enable (struct vrf *);
@ -118,7 +117,7 @@ extern vrf_id_t vrf_name_to_id (const char *);
#define VRF_GET_ID(V,NAME) \ #define VRF_GET_ID(V,NAME) \
do { \ do { \
struct vrf *vrf; \ 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);\ vty_out (vty, "%% VRF %s not found%s", NAME, VTY_NEWLINE);\
return CMD_WARNING; \ return CMD_WARNING; \
@ -131,34 +130,6 @@ extern vrf_id_t vrf_name_to_id (const char *);
(V) = vrf->vrf_id; \ (V) = vrf->vrf_id; \
} while (0) } 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 * Utilities to obtain the user data
*/ */
@ -201,6 +172,8 @@ extern int vrf_bitmap_check (vrf_bitmap_t, vrf_id_t);
extern void vrf_init (void); extern void vrf_init (void);
extern void vrf_terminate (void); extern void vrf_terminate (void);
extern void vrf_cmd_init (int (*writefunc)(struct vty *vty));
/* /*
* VRF utilities * VRF utilities
*/ */

View File

@ -1042,7 +1042,7 @@ zclient_vrf_delete (struct zclient *zclient, vrf_id_t vrf_id)
struct vrf *vrf; struct vrf *vrf;
/* Lookup vrf by vrf_id. */ /* 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 * If a routing protocol doesn't know about a

View File

@ -913,6 +913,7 @@ void
ospf6_neighbor_init (void) ospf6_neighbor_init (void)
{ {
install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_one_cmd);
} }
DEFUN (debug_ospf6_neighbor, DEFUN (debug_ospf6_neighbor,

View File

@ -623,6 +623,7 @@ DEFUN (no_ospf6_distance_ospf6,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
#if 0
DEFUN (ospf6_distance_source, DEFUN (ospf6_distance_source,
ospf6_distance_source_cmd, ospf6_distance_source_cmd,
"distance (1-255) X:X::X:X/M [WORD]", "distance (1-255) X:X::X:X/M [WORD]",
@ -653,6 +654,7 @@ DEFUN (no_ospf6_distance_source,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
#endif
DEFUN (ospf6_interface_area, DEFUN (ospf6_interface_area,
ospf6_interface_area_cmd, ospf6_interface_area_cmd,
@ -834,6 +836,7 @@ DEFUN (no_ospf6_stub_router_admin,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
#if 0
DEFUN (ospf6_stub_router_startup, DEFUN (ospf6_stub_router_startup,
ospf6_stub_router_startup_cmd, ospf6_stub_router_startup_cmd,
"stub-router on-startup (5-86400)", "stub-router on-startup (5-86400)",
@ -879,6 +882,7 @@ DEFUN (no_ospf6_stub_router_shutdown,
{ {
return CMD_SUCCESS; return CMD_SUCCESS;
} }
#endif
static void static void
ospf6_show (struct vty *vty, struct ospf6 *o) ospf6_show (struct vty *vty, struct ospf6 *o)

View File

@ -132,18 +132,16 @@ ospf_if_ipmulticast (struct ospf *top, struct prefix *p, ifindex_t ifindex)
{ {
u_char val; u_char val;
int ret, len; int ret, len;
val = 0;
len = sizeof (val);
/* Prevent receiving self-origined multicast packets. */ /* Prevent receiving self-origined multicast packets. */
ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&val, len); ret = setsockopt_ipv4_multicast_loop (top->fd, 0);
if (ret < 0) if (ret < 0)
zlog_warn ("can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s", zlog_warn ("can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s",
top->fd, safe_strerror(errno)); top->fd, safe_strerror(errno));
/* Explicitly set multicast ttl to 1 -- endo. */ /* Explicitly set multicast ttl to 1 -- endo. */
val = 1; val = 1;
len = sizeof (val);
ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, len); ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, len);
if (ret < 0) if (ret < 0)
zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s", zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",

View File

@ -2772,6 +2772,7 @@ ospf_read (struct thread *thread)
struct ospf_header *ospfh; struct ospf_header *ospfh;
u_int16_t length; u_int16_t length;
struct interface *ifp; struct interface *ifp;
struct connected *c;
/* first of all get interface pointer. */ /* first of all get interface pointer. */
ospf = THREAD_ARG (thread); ospf = THREAD_ARG (thread);
@ -2790,13 +2791,16 @@ ospf_read (struct thread *thread)
/* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */ /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
if (ifp == NULL) if (ifp == NULL)
/* Handle cases where the platform does not support retrieving the ifindex, {
and also platforms (such as Solaris 8) that claim to support ifindex /* Handle cases where the platform does not support retrieving the ifindex,
retrieval but do not. */ and also platforms (such as Solaris 8) that claim to support ifindex
ifp = if_lookup_address ((void *)&iph->ip_src, AF_INET); retrieval but do not. */
c = if_lookup_address ((void *)&iph->ip_src, AF_INET);
if (ifp == NULL) if (c)
return 0; ifp = c->ifp;
if (ifp == NULL)
return 0;
}
/* IP Header dump. */ /* IP Header dump. */
if (IS_DEBUG_OSPF_PACKET(0, RECV)) if (IS_DEBUG_OSPF_PACKET(0, RECV))

View File

@ -1662,6 +1662,7 @@ ospf_router_info_register_vty (void)
install_element (OSPF_NODE, &pce_neighbor_cmd); install_element (OSPF_NODE, &pce_neighbor_cmd);
install_element (OSPF_NODE, &no_pce_neighbor_cmd); install_element (OSPF_NODE, &no_pce_neighbor_cmd);
install_element (OSPF_NODE, &pce_cap_flag_cmd); install_element (OSPF_NODE, &pce_cap_flag_cmd);
install_element (OSPF_NODE, &no_pce_cap_flag_cmd);
return; return;
} }

View File

@ -4402,10 +4402,15 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi,
/* Show Router Dead interval timer. */ /* Show Router Dead interval timer. */
if (use_json) if (use_json)
{ {
struct timeval res = tv_sub (nbr->t_inactivity->u.sands, recent_relative_time ()); if (nbr->t_inactivity)
unsigned long time_store = 0; {
time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000); struct timeval res = tv_sub (nbr->t_inactivity->u.sands, recent_relative_time ());
json_object_int_add(json_sub, "routerDeadIntervalTimerDueMsec", time_store); unsigned long time_store = 0;
time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000);
json_object_int_add(json_sub, "routerDeadIntervalTimerDueMsec", time_store);
}
else
json_object_int_add(json_sub, "routerDeadIntervalTimerDueMsec", -1);
} }
else else
vty_out (vty, " Dead timer due in %s%s", vty_out (vty, " Dead timer due in %s%s",
@ -7798,6 +7803,7 @@ DEFUN (ospf_distance_ospf,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
#if 0
DEFUN (ospf_distance_source, DEFUN (ospf_distance_source,
ospf_distance_source_cmd, ospf_distance_source_cmd,
"distance (1-255) A.B.C.D/M", "distance (1-255) A.B.C.D/M",
@ -7879,6 +7885,7 @@ DEFUN (no_ospf_distance_source_access_list,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
#endif
DEFUN (ip_ospf_mtu_ignore, DEFUN (ip_ospf_mtu_ignore,
ip_ospf_mtu_ignore_addr_cmd, ip_ospf_mtu_ignore_addr_cmd,

View File

@ -35,6 +35,7 @@
#include "privs.h" #include "privs.h"
#include "if.h" #include "if.h"
#include "vrf.h" #include "vrf.h"
#include "sockopt.h"
#include "pimd.h" #include "pimd.h"
#include "pim_mroute.h" #include "pim_mroute.h"
@ -68,7 +69,7 @@ int pim_socket_raw(int protocol)
return fd; return fd;
} }
int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, int loop) int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char loop)
{ {
int fd; int fd;
@ -173,8 +174,7 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, int loop)
} }
} }
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, if (setsockopt_ipv4_multicast_loop (fd, loop)) {
(void *) &loop, sizeof(loop))) {
zlog_warn("Could not %s Multicast Loopback Option on socket fd=%d: errno=%d: %s", zlog_warn("Could not %s Multicast Loopback Option on socket fd=%d: errno=%d: %s",
loop ? "enable" : "disable", loop ? "enable" : "disable",
fd, errno, safe_strerror(errno)); fd, errno, safe_strerror(errno));

View File

@ -39,7 +39,7 @@
#define PIM_SOCK_ERR_BIND (-11) /* Can't bind to interface */ #define PIM_SOCK_ERR_BIND (-11) /* Can't bind to interface */
int pim_socket_raw(int protocol); int pim_socket_raw(int protocol);
int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, int loop); int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char loop);
int pim_socket_join(int fd, struct in_addr group, int pim_socket_join(int fd, struct in_addr group,
struct in_addr ifaddr, ifindex_t ifindex); struct in_addr ifaddr, ifindex_t ifindex);
int pim_socket_join_source(int fd, ifindex_t ifindex, int pim_socket_join_source(int fd, ifindex_t ifindex,

View File

@ -25,6 +25,7 @@
#include "if.h" #include "if.h"
#include "log.h" #include "log.h"
#include "memory.h" #include "memory.h"
#include "sockopt.h"
#include "pim_ssmpingd.h" #include "pim_ssmpingd.h"
#include "pim_time.h" #include "pim_time.h"
@ -150,17 +151,12 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl)
return -1; return -1;
} }
{ if (setsockopt_ipv4_multicast_loop (fd, 0)) {
int loop = 0; zlog_warn("%s: could not disable Multicast Loopback Option on socket fd=%d: errno=%d: %s",
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, __PRETTY_FUNCTION__,
(void *) &loop, sizeof(loop))) { fd, errno, safe_strerror(errno));
zlog_warn("%s: could not %s Multicast Loopback Option on socket fd=%d: errno=%d: %s", close(fd);
__PRETTY_FUNCTION__, return PIM_SOCK_ERR_LOOP;
loop ? "enable" : "disable",
fd, errno, safe_strerror(errno));
close(fd);
return PIM_SOCK_ERR_LOOP;
}
} }
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,

View File

@ -4,11 +4,14 @@ import sys, markdown
template = '''<html><head><meta charset="UTF-8"><style type="text/css"> template = '''<html><head><meta charset="UTF-8"><style type="text/css">
body { max-width: 45em; margin: auto; margin-top: 2em; margin-bottom: 2em; body { max-width: 45em; margin: auto; margin-top: 2em; margin-bottom: 2em;
font-family:Fira Sans,sans-serif; text-align: justify; } font-family:Fira Sans,sans-serif; text-align: justify;
counter-reset: ch2; }
pre, code { font-family:Fira Mono,monospace; } pre, code { font-family:Fira Mono,monospace; }
pre > code { display: block; padding:0.5em; border:1px solid black; pre > code { display: block; padding:0.5em; border:1px solid black;
background-color:#eee; color:#000; } background-color:#eee; color:#000; }
h2 { clear: both; margin-top: 3em; text-decoration: underline; } h2:before { content: counter(ch2) ". "; counter-increment: ch2; }
h2 { clear: both; margin-top: 3em; text-decoration: underline; counter-reset: ch3; }
h3:before { content: counter(ch2) "." counter(ch3) ". "; counter-increment: ch3; }
h3 { clear: both; margin-top: 2em; font-weight: normal; font-style: italic; } h3 { clear: both; margin-top: 2em; font-weight: normal; font-style: italic; }
h4 { font-weight: normal; font-style: italic; } h4 { font-weight: normal; font-style: italic; }
img[alt~="float-right"] { float:right; margin-left:2em; margin-bottom:2em; } img[alt~="float-right"] { float:right; margin-left:2em; margin-bottom:2em; }

View File

@ -55,6 +55,7 @@ const struct message ri_version_msg[] =
{RI_RIP_VERSION_1, "1"}, {RI_RIP_VERSION_1, "1"},
{RI_RIP_VERSION_2, "2"}, {RI_RIP_VERSION_2, "2"},
{RI_RIP_VERSION_1_AND_2, "1 2"}, {RI_RIP_VERSION_1_AND_2, "1 2"},
{RI_RIP_VERSION_NONE, "none"},
}; };
extern struct zebra_privs_t ripd_privs; extern struct zebra_privs_t ripd_privs;
@ -497,17 +498,17 @@ rip_interface_delete (int command, struct zclient *zclient,
static void static void
rip_interface_clean (struct rip_interface *ri) rip_interface_clean (struct rip_interface *ri)
{ {
ri->enable_network = 0; ri->enable_network = 0;
ri->enable_interface = 0; ri->enable_interface = 0;
ri->running = 0; ri->running = 0;
if (ri->t_wakeup) if (ri->t_wakeup)
{ {
thread_cancel (ri->t_wakeup); thread_cancel (ri->t_wakeup);
ri->t_wakeup = NULL; ri->t_wakeup = NULL;
}
} }
}
void void
rip_interfaces_clean (void) rip_interfaces_clean (void)
@ -521,7 +522,7 @@ rip_interfaces_clean (void)
static void static void
rip_interface_reset (struct rip_interface *ri) rip_interface_reset (struct rip_interface *ri)
{ {
/* Default authentication type is simple password for Cisco /* Default authentication type is simple password for Cisco
compatibility. */ compatibility. */
ri->auth_type = RIP_NO_AUTH; ri->auth_type = RIP_NO_AUTH;
@ -534,34 +535,36 @@ rip_interface_reset (struct rip_interface *ri)
ri->split_horizon_default = RIP_SPLIT_HORIZON; ri->split_horizon_default = RIP_SPLIT_HORIZON;
ri->split_horizon = ri->split_horizon_default; ri->split_horizon = ri->split_horizon_default;
ri->ri_send = RI_RIP_UNSPEC; ri->ri_send = RI_RIP_UNSPEC;
ri->ri_receive = RI_RIP_UNSPEC; ri->ri_receive = RI_RIP_UNSPEC;
if (ri->auth_str) ri->v2_broadcast = 0;
{
free (ri->auth_str);
ri->auth_str = NULL;
}
if (ri->key_chain)
{
free (ri->key_chain);
ri->key_chain = NULL;
}
ri->list[RIP_FILTER_IN] = NULL; if (ri->auth_str)
ri->list[RIP_FILTER_OUT] = NULL; {
free (ri->auth_str);
ri->auth_str = NULL;
}
if (ri->key_chain)
{
free (ri->key_chain);
ri->key_chain = NULL;
}
ri->prefix[RIP_FILTER_IN] = NULL; ri->list[RIP_FILTER_IN] = NULL;
ri->prefix[RIP_FILTER_OUT] = NULL; ri->list[RIP_FILTER_OUT] = NULL;
ri->recv_badpackets = 0;
ri->recv_badroutes = 0;
ri->sent_updates = 0;
ri->passive = 0; ri->prefix[RIP_FILTER_IN] = NULL;
ri->prefix[RIP_FILTER_OUT] = NULL;
ri->recv_badpackets = 0;
ri->recv_badroutes = 0;
ri->sent_updates = 0;
ri->passive = 0;
rip_interface_clean (ri); rip_interface_clean (ri);
} }
void void
rip_interfaces_reset (void) rip_interfaces_reset (void)
@ -1320,13 +1323,14 @@ DEFUN (no_rip_neighbor,
DEFUN (ip_rip_receive_version, DEFUN (ip_rip_receive_version,
ip_rip_receive_version_cmd, ip_rip_receive_version_cmd,
"ip rip receive version (1-2)", "ip rip receive version <1|2|none>",
IP_STR IP_STR
"Routing Information Protocol\n" "Routing Information Protocol\n"
"Advertisement reception\n" "Advertisement reception\n"
"Version control\n" "Version control\n"
"RIP version 1\n" "RIP version 1\n"
"RIP version 2\n") "RIP version 2\n"
"None\n")
{ {
int idx_type = 4; int idx_type = 4;
struct interface *ifp; struct interface *ifp;
@ -1335,17 +1339,21 @@ DEFUN (ip_rip_receive_version,
ifp = (struct interface *)vty->index; ifp = (struct interface *)vty->index;
ri = ifp->info; ri = ifp->info;
/* Version 1. */ switch (argv[idx_type]->arg[0])
if (atoi (argv[idx_type]->arg) == 1)
{ {
case '1':
ri->ri_receive = RI_RIP_VERSION_1; ri->ri_receive = RI_RIP_VERSION_1;
return CMD_SUCCESS; return CMD_SUCCESS;
} case '2':
if (atoi (argv[idx_type]->arg) == 2)
{
ri->ri_receive = RI_RIP_VERSION_2; ri->ri_receive = RI_RIP_VERSION_2;
return CMD_SUCCESS; return CMD_SUCCESS;
case 'n':
ri->ri_receive = RI_RIP_VERSION_NONE;
return CMD_SUCCESS;
default:
break;
} }
return CMD_WARNING; return CMD_WARNING;
} }
@ -1508,6 +1516,41 @@ DEFUN (no_ip_rip_send_version,
} }
DEFUN (ip_rip_v2_broadcast,
ip_rip_v2_broadcast_cmd,
"ip rip v2-broadcast",
IP_STR
"Routing Information Protocol\n"
"Send ip broadcast v2 update\n")
{
struct interface *ifp;
struct rip_interface *ri;
ifp = (struct interface *)vty->index;
ri = ifp->info;
ri->v2_broadcast = 1;
return CMD_SUCCESS;
}
DEFUN (no_ip_rip_v2_broadcast,
no_ip_rip_v2_broadcast_cmd,
"no ip rip v2-broadcast",
NO_STR
IP_STR
"Routing Information Protocol\n"
"Send ip broadcast v2 update\n")
{
struct interface *ifp;
struct rip_interface *ri;
ifp = (struct interface *)vty->index;
ri = ifp->info;
ri->v2_broadcast = 0;
return CMD_SUCCESS;
}
DEFUN (ip_rip_authentication_mode, DEFUN (ip_rip_authentication_mode,
ip_rip_authentication_mode_cmd, ip_rip_authentication_mode_cmd,
"ip rip authentication mode <md5|text> [auth-length <rfc|old-ripd>]", "ip rip authentication mode <md5|text> [auth-length <rfc|old-ripd>]",
@ -1850,6 +1893,7 @@ rip_interface_config_write (struct vty *vty)
(ri->ri_send == RI_RIP_UNSPEC) && (ri->ri_send == RI_RIP_UNSPEC) &&
(ri->ri_receive == RI_RIP_UNSPEC) && (ri->ri_receive == RI_RIP_UNSPEC) &&
(ri->auth_type != RIP_AUTH_MD5) && (ri->auth_type != RIP_AUTH_MD5) &&
(!ri->v2_broadcast) &&
(ri->md5_auth_len != RIP_AUTH_MD5_SIZE) && (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
(!ri->auth_str) && (!ri->auth_str) &&
(!ri->key_chain) ) (!ri->key_chain) )
@ -1891,6 +1935,9 @@ rip_interface_config_write (struct vty *vty)
lookup (ri_version_msg, ri->ri_receive), lookup (ri_version_msg, ri->ri_receive),
VTY_NEWLINE); VTY_NEWLINE);
if (ri->v2_broadcast)
vty_out (vty, " ip rip v2-broadcast%s", VTY_NEWLINE);
/* RIP authentication. */ /* RIP authentication. */
if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD) if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE); vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
@ -2025,6 +2072,9 @@ rip_if_init (void)
install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd); install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd); install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
install_element (INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
install_element (INTERFACE_NODE, &no_ip_rip_v2_broadcast_cmd);
install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd); install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd); install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);

View File

@ -812,7 +812,15 @@ rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
struct interface *ifp) struct interface *ifp)
{ {
struct rip_interface *ri; struct rip_interface *ri;
char *auth_str; char *auth_str = (char *) &rte->prefix;
int i;
/* reject passwords with zeros in the middle of the string */
for (i = strlen (auth_str); i < 16; i++)
{
if (auth_str[i] != '\0')
return 0;
}
if (IS_RIP_DEBUG_EVENT) if (IS_RIP_DEBUG_EVENT)
zlog_debug ("RIPv2 simple password authentication from %s", zlog_debug ("RIPv2 simple password authentication from %s",
@ -827,8 +835,6 @@ rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
/* Simple password authentication. */ /* Simple password authentication. */
if (ri->auth_str) if (ri->auth_str)
{ {
auth_str = (char *) &rte->prefix;
if (strncmp (auth_str, ri->auth_str, 16) == 0) if (strncmp (auth_str, ri->auth_str, 16) == 0)
return 1; return 1;
} }
@ -841,7 +847,7 @@ rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
if (keychain == NULL) if (keychain == NULL)
return 0; return 0;
key = key_match_for_accept (keychain, (char *) &rte->prefix); key = key_match_for_accept (keychain, auth_str);
if (key) if (key)
return 1; return 1;
} }
@ -1333,30 +1339,23 @@ rip_response_process (struct rip_packet *packet, int size,
/* Make socket for RIP protocol. */ /* Make socket for RIP protocol. */
static int static int
rip_create_socket (struct sockaddr_in *from) rip_create_socket (void)
{ {
int ret; int ret;
int sock; int sock;
struct sockaddr_in addr; struct sockaddr_in addr;
memset (&addr, 0, sizeof (struct sockaddr_in)); memset (&addr, 0, sizeof (struct sockaddr_in));
addr.sin_family = AF_INET;
if (!from) addr.sin_addr.s_addr = INADDR_ANY;
{
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
addr.sin_len = sizeof (struct sockaddr_in); addr.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
} else {
memcpy(&addr, from, sizeof(addr));
}
/* sending port must always be the RIP port */ /* sending port must always be the RIP port */
addr.sin_port = htons (RIP_PORT_DEFAULT); addr.sin_port = htons (RIP_PORT_DEFAULT);
/* Make datagram socket. */ /* Make datagram socket. */
sock = socket (AF_INET, SOCK_DGRAM, 0); sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock < 0) if (sock < 0)
{ {
zlog_err("Cannot create UDP socket: %s", safe_strerror(errno)); zlog_err("Cannot create UDP socket: %s", safe_strerror(errno));
@ -1366,6 +1365,7 @@ rip_create_socket (struct sockaddr_in *from)
sockopt_broadcast (sock); sockopt_broadcast (sock);
sockopt_reuseaddr (sock); sockopt_reuseaddr (sock);
sockopt_reuseport (sock); sockopt_reuseport (sock);
setsockopt_ipv4_multicast_loop (sock, 0);
#ifdef RIP_RECVMSG #ifdef RIP_RECVMSG
setsockopt_pktinfo (sock); setsockopt_pktinfo (sock);
#endif /* RIP_RECVMSG */ #endif /* RIP_RECVMSG */
@ -1406,7 +1406,7 @@ static int
rip_send_packet (u_char * buf, int size, struct sockaddr_in *to, rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,
struct connected *ifc) struct connected *ifc)
{ {
int ret, send_sock; int ret;
struct sockaddr_in sin; struct sockaddr_in sin;
assert (ifc != NULL); assert (ifc != NULL);
@ -1462,38 +1462,16 @@ rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,
{ {
sin.sin_port = to->sin_port; sin.sin_port = to->sin_port;
sin.sin_addr = to->sin_addr; sin.sin_addr = to->sin_addr;
send_sock = rip->sock;
} }
else else
{ {
struct sockaddr_in from;
sin.sin_port = htons (RIP_PORT_DEFAULT); sin.sin_port = htons (RIP_PORT_DEFAULT);
sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP); sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
/* multicast send should bind to local interface address */ rip_interface_multicast_set (rip->sock, ifc);
memset (&from, 0, sizeof (from));
from.sin_family = AF_INET;
from.sin_port = htons (RIP_PORT_DEFAULT);
from.sin_addr = ifc->address->u.prefix4;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
from.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
/*
* we have to open a new socket for each packet because this
* is the most portable way to bind to a different source
* ipv4 address for each packet.
*/
if ( (send_sock = rip_create_socket (&from)) < 0)
{
zlog_warn("rip_send_packet could not create socket.");
return -1;
}
rip_interface_multicast_set (send_sock, ifc);
} }
ret = sendto (send_sock, buf, size, 0, (struct sockaddr *)&sin, ret = sendto (rip->sock, buf, size, 0, (struct sockaddr *)&sin,
sizeof (struct sockaddr_in)); sizeof (struct sockaddr_in));
if (IS_RIP_DEBUG_EVENT) if (IS_RIP_DEBUG_EVENT)
@ -1503,9 +1481,6 @@ rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,
if (ret < 0) if (ret < 0)
zlog_warn ("can't send packet : %s", safe_strerror (errno)); zlog_warn ("can't send packet : %s", safe_strerror (errno));
if (!to)
close(send_sock);
return ret; return ret;
} }
@ -1681,6 +1656,9 @@ rip_request_process (struct rip_packet *packet, int size,
} }
else else
{ {
if (ntohs (rte->family) != AF_INET)
return;
/* Examine the list of RTEs in the Request one by one. For each /* Examine the list of RTEs in the Request one by one. For each
entry, look up the destination in the router's routing entry, look up the destination in the router's routing
database and, if there is a route, put that route's metric in database and, if there is a route, put that route's metric in
@ -1803,7 +1781,7 @@ rip_read (struct thread *t)
int len; int len;
int vrecv; int vrecv;
socklen_t fromlen; socklen_t fromlen;
struct interface *ifp; struct interface *ifp = NULL;
struct connected *ifc; struct connected *ifc;
struct rip_interface *ri; struct rip_interface *ri;
struct prefix p; struct prefix p;
@ -1836,8 +1814,10 @@ rip_read (struct thread *t)
} }
/* Which interface is this packet comes from. */ /* Which interface is this packet comes from. */
ifp = if_lookup_address ((void *)&from.sin_addr, AF_INET); ifc = if_lookup_address ((void *)&from.sin_addr, AF_INET);
if (ifc)
ifp = ifc->ifp;
/* RIP packet received */ /* RIP packet received */
if (IS_RIP_DEBUG_EVENT) if (IS_RIP_DEBUG_EVENT)
zlog_debug ("RECV packet from %s port %d on %s", zlog_debug ("RECV packet from %s port %d on %s",
@ -1928,15 +1908,9 @@ rip_read (struct thread *t)
/* RIP Version check. RFC2453, 4.6 and 5.1 */ /* RIP Version check. RFC2453, 4.6 and 5.1 */
vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ? vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ?
rip->version_recv : ri->ri_receive); rip->version_recv : ri->ri_receive);
if ((packet->version == RIPv1) && !(vrecv & RIPv1)) if (vrecv == RI_RIP_VERSION_NONE ||
{ ((packet->version == RIPv1) && !(vrecv & RIPv1)) ||
if (IS_RIP_DEBUG_PACKET) ((packet->version == RIPv2) && !(vrecv & RIPv2)))
zlog_debug (" packet's v%d doesn't fit to if version spec",
packet->version);
rip_peer_bad_packet (&from);
return -1;
}
if ((packet->version == RIPv2) && !(vrecv & RIPv2))
{ {
if (IS_RIP_DEBUG_PACKET) if (IS_RIP_DEBUG_PACKET)
zlog_debug (" packet's v%d doesn't fit to if version spec", zlog_debug (" packet's v%d doesn't fit to if version spec",
@ -2434,20 +2408,22 @@ rip_output_process (struct connected *ifc, struct sockaddr_in *to,
static void static void
rip_update_interface (struct connected *ifc, u_char version, int route_type) rip_update_interface (struct connected *ifc, u_char version, int route_type)
{ {
struct interface *ifp = ifc->ifp;
struct rip_interface *ri = ifp->info;
struct sockaddr_in to; struct sockaddr_in to;
/* When RIP version is 2 and multicast enable interface. */ /* When RIP version is 2 and multicast enable interface. */
if (version == RIPv2 && if_is_multicast (ifc->ifp)) if (version == RIPv2 && !ri->v2_broadcast && if_is_multicast (ifp))
{ {
if (IS_RIP_DEBUG_EVENT) if (IS_RIP_DEBUG_EVENT)
zlog_debug ("multicast announce on %s ", ifc->ifp->name); zlog_debug ("multicast announce on %s ", ifp->name);
rip_output_process (ifc, NULL, route_type, version); rip_output_process (ifc, NULL, route_type, version);
return; return;
} }
/* If we can't send multicast packet, send it with unicast. */ /* If we can't send multicast packet, send it with unicast. */
if (if_is_broadcast (ifc->ifp) || if_is_pointopoint (ifc->ifp)) if (if_is_broadcast (ifp) || if_is_pointopoint (ifp))
{ {
if (ifc->address->family == AF_INET) if (ifc->address->family == AF_INET)
{ {
@ -2469,7 +2445,7 @@ rip_update_interface (struct connected *ifc, u_char version, int route_type)
if (IS_RIP_DEBUG_EVENT) if (IS_RIP_DEBUG_EVENT)
zlog_debug("%s announce to %s on %s", zlog_debug("%s announce to %s on %s",
CONNECTED_PEER(ifc) ? "unicast" : "broadcast", CONNECTED_PEER(ifc) ? "unicast" : "broadcast",
inet_ntoa (to.sin_addr), ifc->ifp->name); inet_ntoa (to.sin_addr), ifp->name);
rip_output_process (ifc, &to, route_type, version); rip_output_process (ifc, &to, route_type, version);
} }
@ -2539,21 +2515,14 @@ rip_update_process (int route_type)
{ {
p = &rp->p; p = &rp->p;
ifp = if_lookup_prefix (p); connected = if_lookup_address (&p->u.prefix4, AF_INET);
if (! ifp) if (! connected)
{ {
zlog_warn ("Neighbor %s doesnt have connected interface!", zlog_warn ("Neighbor %s doesnt have connected interface!",
inet_ntoa (p->u.prefix4)); inet_ntoa (p->u.prefix4));
continue; continue;
} }
if ( (connected = connected_lookup_prefix (ifp, p)) == NULL)
{
zlog_warn ("Neighbor %s doesnt have connected network",
inet_ntoa (p->u.prefix4));
continue;
}
/* Set destination address and port */ /* Set destination address and port */
memset (&to, 0, sizeof (struct sockaddr_in)); memset (&to, 0, sizeof (struct sockaddr_in));
to.sin_addr = p->u.prefix4; to.sin_addr = p->u.prefix4;
@ -2579,11 +2548,7 @@ rip_update (struct thread *t)
/* Triggered updates may be suppressed if a regular update is due by /* Triggered updates may be suppressed if a regular update is due by
the time the triggered update would be sent. */ the time the triggered update would be sent. */
if (rip->t_triggered_interval) RIP_TIMER_OFF (rip->t_triggered_interval);
{
thread_cancel (rip->t_triggered_interval);
rip->t_triggered_interval = NULL;
}
rip->trigger = 0; rip->trigger = 0;
/* Register myself. */ /* Register myself. */
@ -2637,11 +2602,7 @@ rip_triggered_update (struct thread *t)
rip->t_triggered_update = NULL; rip->t_triggered_update = NULL;
/* Cancel interval timer. */ /* Cancel interval timer. */
if (rip->t_triggered_interval) RIP_TIMER_OFF (rip->t_triggered_interval);
{
thread_cancel (rip->t_triggered_interval);
rip->t_triggered_interval = NULL;
}
rip->trigger = 0; rip->trigger = 0;
/* Logging triggered update. */ /* Logging triggered update. */
@ -2729,7 +2690,7 @@ rip_create (void)
rip->obuf = stream_new (1500); rip->obuf = stream_new (1500);
/* Make socket. */ /* Make socket. */
rip->sock = rip_create_socket (NULL); rip->sock = rip_create_socket ();
if (rip->sock < 0) if (rip->sock < 0)
return rip->sock; return rip->sock;
@ -2819,11 +2780,7 @@ rip_event (enum rip_event event, int sock)
rip->t_read = thread_add_read (master, rip_read, NULL, sock); rip->t_read = thread_add_read (master, rip_read, NULL, sock);
break; break;
case RIP_UPDATE_EVENT: case RIP_UPDATE_EVENT:
if (rip->t_update) RIP_TIMER_OFF (rip->t_update);
{
thread_cancel (rip->t_update);
rip->t_update = NULL;
}
jitter = rip_update_jitter (rip->update_time); jitter = rip_update_jitter (rip->update_time);
rip->t_update = rip->t_update =
thread_add_timer (master, rip_update, NULL, thread_add_timer (master, rip_update, NULL,
@ -3919,11 +3876,7 @@ rip_clean (void)
RIP_TIMER_OFF (rip->t_triggered_interval); RIP_TIMER_OFF (rip->t_triggered_interval);
/* Cancel read thread. */ /* Cancel read thread. */
if (rip->t_read) THREAD_READ_OFF (rip->t_read);
{
thread_cancel (rip->t_read);
rip->t_read = NULL;
}
/* Close RIP socket. */ /* Close RIP socket. */
if (rip->sock >= 0) if (rip->sock >= 0)

View File

@ -258,6 +258,9 @@ struct rip_interface
int ri_send; int ri_send;
int ri_receive; int ri_receive;
/* RIPv2 broadcast mode */
int v2_broadcast;
/* RIPv2 authentication type. */ /* RIPv2 authentication type. */
int auth_type; int auth_type;
@ -347,6 +350,7 @@ struct rip_md5_data
#define RI_RIP_VERSION_1 1 #define RI_RIP_VERSION_1 1
#define RI_RIP_VERSION_2 2 #define RI_RIP_VERSION_2 2
#define RI_RIP_VERSION_1_AND_2 3 #define RI_RIP_VERSION_1_AND_2 3
#define RI_RIP_VERSION_NONE 4
/* N.B. stuff will break if /* N.B. stuff will break if
(RIPv1 != RI_RIP_VERSION_1) || (RIPv2 != RI_RIP_VERSION_2) */ (RIPv1 != RI_RIP_VERSION_1) || (RIPv2 != RI_RIP_VERSION_2) */
@ -369,14 +373,7 @@ enum rip_event
} while (0) } while (0)
/* Macro for timer turn off. */ /* Macro for timer turn off. */
#define RIP_TIMER_OFF(X) \ #define RIP_TIMER_OFF(X) THREAD_TIMER_OFF(X)
do { \
if (X) \
{ \
thread_cancel (X); \
(X) = NULL; \
} \
} while (0)
/* Prototypes. */ /* Prototypes. */
extern void rip_init (void); extern void rip_init (void);

View File

@ -65,7 +65,7 @@ ripng_multicast_join (struct interface *ifp)
struct ipv6_mreq mreq; struct ipv6_mreq mreq;
int save_errno; int save_errno;
if (if_is_up (ifp) && if_is_multicast (ifp)) { if (if_is_multicast (ifp)) {
memset (&mreq, 0, sizeof (mreq)); memset (&mreq, 0, sizeof (mreq));
inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr); inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr);
mreq.ipv6mr_interface = ifp->ifindex; mreq.ipv6mr_interface = ifp->ifindex;
@ -116,7 +116,7 @@ ripng_multicast_leave (struct interface *ifp)
int ret; int ret;
struct ipv6_mreq mreq; struct ipv6_mreq mreq;
if (if_is_up (ifp) && if_is_multicast (ifp)) { if (if_is_multicast (ifp)) {
memset (&mreq, 0, sizeof (mreq)); memset (&mreq, 0, sizeof (mreq));
inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr); inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr);
mreq.ipv6mr_interface = ifp->ifindex; mreq.ipv6mr_interface = ifp->ifindex;

View File

@ -829,8 +829,10 @@ ripng_route_process (struct rte *rte, struct sockaddr_in6 *from,
* with the new one in below. */ * with the new one in below. */
break; break;
/* Metrics are same. Keep "rinfo" null and the new route /* Metrics are same. Unless ECMP is disabled, keep "rinfo" null and
* is added in the ECMP list in below. */ * the new route is added in the ECMP list in below. */
if (! ripng->ecmp)
break;
} }
} }
@ -874,11 +876,24 @@ ripng_route_process (struct rte *rte, struct sockaddr_in6 *from,
same = (IN6_ARE_ADDR_EQUAL (&rinfo->from, &from->sin6_addr) same = (IN6_ARE_ADDR_EQUAL (&rinfo->from, &from->sin6_addr)
&& (rinfo->ifindex == ifp->ifindex)); && (rinfo->ifindex == ifp->ifindex));
/*
* RFC 2080 - Section 2.4.2:
* "If the new metric is the same as the old one, examine the timeout
* for the existing route. If it is at least halfway to the expiration
* point, switch to the new route. This heuristic is optional, but
* highly recommended".
*/
if (!ripng->ecmp && !same &&
rinfo->metric == rte->metric && rinfo->t_timeout &&
(thread_timer_remain_second (rinfo->t_timeout) < (ripng->timeout_time / 2)))
{
ripng_ecmp_replace (&newinfo);
}
/* Next, compare the metrics. If the datagram is from the same /* Next, compare the metrics. If the datagram is from the same
router as the existing route, and the new metric is different router as the existing route, and the new metric is different
than the old one; or, if the new metric is lower than the old than the old one; or, if the new metric is lower than the old
one; do the following actions: */ one; do the following actions: */
if ((same && rinfo->metric != rte->metric) || else if ((same && rinfo->metric != rte->metric) ||
rte->metric < rinfo->metric) rte->metric < rinfo->metric)
{ {
if (listcount (list) == 1) if (listcount (list) == 1)
@ -2155,6 +2170,54 @@ DEFUN (show_ipv6_ripng_status,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN (clear_ipv6_rip,
clear_ipv6_rip_cmd,
"clear ipv6 ripng",
CLEAR_STR
IPV6_STR
"Clear IPv6 RIP database")
{
struct route_node *rp;
struct ripng_info *rinfo;
struct list *list;
struct listnode *listnode;
/* Clear received RIPng routes */
for (rp = route_top (ripng->table); rp; rp = route_next (rp))
{
list = rp->info;
if (list == NULL)
continue;
for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo))
{
if (! ripng_route_rte (rinfo))
continue;
if (CHECK_FLAG (rinfo->flags, RIPNG_RTF_FIB))
ripng_zebra_ipv6_delete (rp);
break;
}
if (rinfo)
{
RIPNG_TIMER_OFF (rinfo->t_timeout);
RIPNG_TIMER_OFF (rinfo->t_garbage_collect);
listnode_delete (list, rinfo);
ripng_info_free (rinfo);
}
if (list_isempty (list))
{
list_free (list);
rp->info = NULL;
route_unlock_node (rp);
}
}
return CMD_SUCCESS;
}
DEFUN (router_ripng, DEFUN (router_ripng,
router_ripng_cmd, router_ripng_cmd,
"router ripng", "router ripng",
@ -2512,6 +2575,7 @@ DEFUN (no_ripng_timers,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
#if 0
DEFUN (show_ipv6_protocols, DEFUN (show_ipv6_protocols,
show_ipv6_protocols_cmd, show_ipv6_protocols_cmd,
"show ipv6 protocols", "show ipv6 protocols",
@ -2538,6 +2602,7 @@ DEFUN (show_ipv6_protocols,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
#endif
/* Please be carefull to use this command. */ /* Please be carefull to use this command. */
DEFUN (ripng_default_information_originate, DEFUN (ripng_default_information_originate,
@ -3029,6 +3094,8 @@ ripng_init ()
install_element (VIEW_NODE, &show_ipv6_ripng_status_cmd); install_element (VIEW_NODE, &show_ipv6_ripng_status_cmd);
install_element (VIEW_NODE, &show_ipv6_protocols_cmd); install_element (VIEW_NODE, &show_ipv6_protocols_cmd);
install_element (ENABLE_NODE, &clear_ipv6_rip_cmd);
install_element (CONFIG_NODE, &router_ripng_cmd); install_element (CONFIG_NODE, &router_ripng_cmd);
install_element (CONFIG_NODE, &no_router_ripng_cmd); install_element (CONFIG_NODE, &no_router_ripng_cmd);

View File

@ -37,6 +37,7 @@
#include "bgpd/bgp_table.h" #include "bgpd/bgp_table.h"
#include "bgpd/bgp_route.h" #include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h" #include "bgpd/bgp_attr.h"
#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_mpath.h" #include "bgpd/bgp_mpath.h"
#define VT100_RESET "\x1b[0m" #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->maxpaths[afi][safi].maxpaths_ibgp = MULTIPATH_NUM;
} }
bgp_scan_init (bgp);
bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF; bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
bgp->default_holdtime = BGP_DEFAULT_HOLDTIME; bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE; bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;

View File

@ -1560,24 +1560,6 @@ DEFUNSH (VTYSH_BGPD,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUNSH (VTYSH_ZEBRA,
vtysh_exit_zebra,
vtysh_exit_zebra_cmd,
"exit",
"Exit current mode and down to previous mode\n")
{
return vtysh_exit (vty);
}
DEFUNSH (VTYSH_ZEBRA,
vtysh_quit_zebra,
vtysh_quit_zebra_cmd,
"quit",
"Exit current mode and down to previous mode\n")
{
return vtysh_exit_zebra (self, vty, argc, argv);
}
DEFUNSH (VTYSH_RIPD, DEFUNSH (VTYSH_RIPD,
vtysh_exit_ripd, vtysh_exit_ripd,
vtysh_exit_ripd_cmd, vtysh_exit_ripd_cmd,
@ -3122,7 +3104,8 @@ vtysh_init_vty (void)
/* "exit" command. */ /* "exit" command. */
install_element (VIEW_NODE, &vtysh_exit_all_cmd); install_element (VIEW_NODE, &vtysh_exit_all_cmd);
install_element (CONFIG_NODE, &vtysh_exit_all_cmd); install_element (CONFIG_NODE, &vtysh_exit_all_cmd);
/* install_element (CONFIG_NODE, &vtysh_quit_all_cmd); */ install_element (VIEW_NODE, &vtysh_quit_all_cmd);
install_element (CONFIG_NODE, &vtysh_quit_all_cmd);
install_element (RIP_NODE, &vtysh_exit_ripd_cmd); install_element (RIP_NODE, &vtysh_exit_ripd_cmd);
install_element (RIP_NODE, &vtysh_quit_ripd_cmd); install_element (RIP_NODE, &vtysh_quit_ripd_cmd);
install_element (RIPNG_NODE, &vtysh_exit_ripngd_cmd); install_element (RIPNG_NODE, &vtysh_exit_ripngd_cmd);
@ -3226,6 +3209,8 @@ vtysh_init_vty (void)
install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd); install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd);
install_element (NS_NODE, &vtysh_end_all_cmd); install_element (NS_NODE, &vtysh_end_all_cmd);
install_element (CONFIG_NODE, &vtysh_ns_cmd);
install_element (NS_NODE, &vtysh_exit_ns_cmd); install_element (NS_NODE, &vtysh_exit_ns_cmd);
install_element (NS_NODE, &vtysh_quit_ns_cmd); install_element (NS_NODE, &vtysh_quit_ns_cmd);
@ -3255,6 +3240,7 @@ vtysh_init_vty (void)
#if defined(ENABLE_BGP_VNC) #if defined(ENABLE_BGP_VNC)
install_element (BGP_NODE, &vnc_defaults_cmd); install_element (BGP_NODE, &vnc_defaults_cmd);
install_element (BGP_NODE, &vnc_nve_group_cmd); install_element (BGP_NODE, &vnc_nve_group_cmd);
install_element (BGP_NODE, &vnc_l2_group_cmd);
#endif #endif
install_element (BGP_NODE, &address_family_ipv4_unicast_cmd); install_element (BGP_NODE, &address_family_ipv4_unicast_cmd);
install_element (BGP_NODE, &address_family_ipv4_multicast_cmd); install_element (BGP_NODE, &address_family_ipv4_multicast_cmd);

View File

@ -209,13 +209,6 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name)
if (h->nlmsg_type == RTM_NEWLINK) 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) if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("RTM_NEWLINK for VRF %s(%u) table %u", zlog_debug ("RTM_NEWLINK for VRF %s(%u) table %u",
name, ifi->ifi_index, nl_table_id); name, ifi->ifi_index, nl_table_id);
@ -251,7 +244,7 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name)
if (IS_ZEBRA_DEBUG_KERNEL) if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("RTM_DELLINK for VRF %s(%u)", name, ifi->ifi_index); 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) if (!vrf)
{ {

View File

@ -59,6 +59,20 @@ const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
static void if_down_del_nbr_connected (struct interface *ifp); static void 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. */ /* Called when new interface is added. */
static int static int
if_zebra_new_hook (struct interface *ifp) if_zebra_new_hook (struct interface *ifp)
@ -101,7 +115,7 @@ if_zebra_new_hook (struct interface *ifp)
#endif /* HAVE_RTADV */ #endif /* HAVE_RTADV */
/* Initialize installed address chains tree. */ /* 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; ifp->info = zebra_if;
@ -1025,7 +1039,7 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
zebra_ptm_show_status(vty, 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); vty_out (vty, " vrf: %s%s", vrf->name, VTY_NEWLINE);
if (ifp->desc) if (ifp->desc)
@ -1243,35 +1257,6 @@ struct cmd_node interface_node =
1 1
}; };
#if 0
/* 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;
}
#endif
struct cmd_node vrf_node =
{
VRF_NODE,
"%s(config-vrf)# ",
1
};
/* Show all interfaces to vty. */ /* Show all interfaces to vty. */
DEFUN (show_interface, DEFUN (show_interface,
show_interface_cmd, show_interface_cmd,
@ -1305,15 +1290,15 @@ DEFUN (show_interface_vrf_all,
"Interface status and configuration\n" "Interface status and configuration\n"
VRF_ALL_CMD_HELP_STR) VRF_ALL_CMD_HELP_STR)
{ {
struct vrf *vrf;
struct listnode *node; struct listnode *node;
struct interface *ifp; struct interface *ifp;
vrf_iter_t iter;
interface_update_stats (); interface_update_stats ();
/* All interface print. */ /* All interface print. */
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp)) for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
if_dump_vty (vty, ifp); if_dump_vty (vty, ifp);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -1361,17 +1346,17 @@ DEFUN (show_interface_name_vrf_all,
VRF_ALL_CMD_HELP_STR) VRF_ALL_CMD_HELP_STR)
{ {
int idx_ifname = 2; int idx_ifname = 2;
struct vrf *vrf;
struct interface *ifp; struct interface *ifp;
vrf_iter_t iter;
int found = 0; int found = 0;
interface_update_stats (); interface_update_stats ();
/* All interface print. */ /* 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. */ /* Specified interface print. */
ifp = if_lookup_by_name_vrf (argv[idx_ifname]->arg, vrf_iter2id (iter)); ifp = if_lookup_by_name_vrf (argv[idx_ifname]->arg, vrf->vrf_id);
if (ifp) if (ifp)
{ {
if_dump_vty (vty, ifp); if_dump_vty (vty, ifp);
@ -1456,15 +1441,14 @@ DEFUN (show_interface_desc_vrf_all,
"Interface description\n" "Interface description\n"
VRF_ALL_CMD_HELP_STR) VRF_ALL_CMD_HELP_STR)
{ {
vrf_iter_t iter; struct vrf *vrf;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
if (!list_isempty (vrf_iter2iflist (iter))) if (!list_isempty (vrf->iflist))
{ {
vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id,
vrf_iter2id (iter), VTY_NEWLINE, VTY_NEWLINE);
VTY_NEWLINE, VTY_NEWLINE); if_show_description (vty, vrf->vrf_id);
if_show_description (vty, vrf_iter2id (iter));
} }
return CMD_SUCCESS; return CMD_SUCCESS;
@ -1801,7 +1785,7 @@ DEFUN (link_params_metric,
VTY_GET_ULONG("metric", metric, argv[idx_number]->arg); VTY_GET_ULONG("metric", metric, argv[idx_number]->arg);
/* Update TE metric if needed */ /* Update TE metric if needed */
link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE, metric); link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE | LP_TE_METRIC, metric);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -1815,7 +1799,7 @@ DEFUN (no_link_params_metric,
VTY_DECLVAR_CONTEXT (interface, ifp); VTY_DECLVAR_CONTEXT (interface, ifp);
/* Unset TE Metric */ /* Unset TE Metric */
link_param_cmd_unset(ifp, LP_TE); link_param_cmd_unset(ifp, LP_TE | LP_TE_METRIC);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -2753,20 +2737,21 @@ link_params_config_write (struct vty *vty, struct interface *ifp)
vty_out (vty, " link-params%s", VTY_NEWLINE); vty_out (vty, " link-params%s", VTY_NEWLINE);
vty_out(vty, " enable%s", VTY_NEWLINE); vty_out(vty, " enable%s", VTY_NEWLINE);
if (IS_PARAM_SET(iflp, LP_TE)) if (IS_PARAM_SET(iflp, LP_TE) && IS_PARAM_SET(iflp, LP_TE_METRIC))
vty_out(vty, " metric %u%s",iflp->te_metric, VTY_NEWLINE); vty_out(vty, " metric %u%s",iflp->te_metric, VTY_NEWLINE);
if (IS_PARAM_SET(iflp, LP_MAX_BW)) if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
vty_out(vty, " max-bw %g%s", iflp->max_bw, VTY_NEWLINE); vty_out(vty, " max-bw %g%s", iflp->max_bw, VTY_NEWLINE);
if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)) if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW) && iflp->max_rsv_bw != iflp->default_bw)
vty_out(vty, " max-rsv-bw %g%s", iflp->max_rsv_bw, VTY_NEWLINE); vty_out(vty, " max-rsv-bw %g%s", iflp->max_rsv_bw, VTY_NEWLINE);
if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) if (IS_PARAM_SET(iflp, LP_UNRSV_BW))
{ {
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
vty_out(vty, " unrsv-bw %d %g%s", if (iflp->unrsv_bw[i] != iflp->default_bw)
i, iflp->unrsv_bw[i], VTY_NEWLINE); vty_out(vty, " unrsv-bw %d %g%s",
i, iflp->unrsv_bw[i], VTY_NEWLINE);
} }
if (IS_PARAM_SET(iflp, LP_ADM_GRP)) if (IS_PARAM_SET(iflp, LP_ADM_GRP))
vty_out(vty, " admin-grp %u%s", iflp->admin_grp, VTY_NEWLINE); vty_out(vty, " admin-grp 0x%x%s", iflp->admin_grp, VTY_NEWLINE);
if (IS_PARAM_SET(iflp, LP_DELAY)) if (IS_PARAM_SET(iflp, LP_DELAY))
{ {
vty_out(vty, " delay %u", iflp->av_delay); vty_out(vty, " delay %u", iflp->av_delay);
@ -2797,14 +2782,14 @@ link_params_config_write (struct vty *vty, struct interface *ifp)
static int static int
if_config_write (struct vty *vty) if_config_write (struct vty *vty)
{ {
struct vrf *vrf;
struct listnode *node; struct listnode *node;
struct interface *ifp; struct interface *ifp;
vrf_iter_t iter;
zebra_ptm_write (vty); zebra_ptm_write (vty);
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp)) for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
{ {
struct zebra_if *if_data; struct zebra_if *if_data;
struct listnode *addrnode; struct listnode *addrnode;
@ -2813,7 +2798,7 @@ if_config_write (struct vty *vty)
struct vrf *vrf; struct vrf *vrf;
if_data = ifp->info; if_data = ifp->info;
vrf = vrf_lookup(ifp->vrf_id); vrf = vrf_lookup_by_id (ifp->vrf_id);
if (ifp->vrf_id == VRF_DEFAULT) if (ifp->vrf_id == VRF_DEFAULT)
vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE); vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
@ -2881,23 +2866,6 @@ if_config_write (struct vty *vty)
return 0; 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. */ /* Allocate and initialize interface vector. */
void void
zebra_if_init (void) zebra_if_init (void)
@ -2909,7 +2877,6 @@ zebra_if_init (void)
/* Install configuration write function. */ /* Install configuration write function. */
install_node (&interface_node, if_config_write); install_node (&interface_node, if_config_write);
install_node (&link_params_node, NULL); install_node (&link_params_node, NULL);
install_node (&vrf_node, vrf_config_write);
if_cmd_init (); if_cmd_init ();
install_element (VIEW_NODE, &show_interface_cmd); install_element (VIEW_NODE, &show_interface_cmd);
@ -2942,6 +2909,7 @@ zebra_if_init (void)
install_element(LINK_PARAMS_NODE, &link_params_enable_cmd); install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd); install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
install_element(LINK_PARAMS_NODE, &link_params_metric_cmd); install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd); install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd); install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd); install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
@ -2962,6 +2930,4 @@ zebra_if_init (void)
install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd); 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, &no_link_params_use_bw_cmd);
install_element(LINK_PARAMS_NODE, &exit_link_params_cmd); install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
vrf_cmd_init();
} }

View File

@ -304,17 +304,16 @@ void process_solicit (struct interface *ifp)
void irdp_finish() void irdp_finish()
{ {
struct vrf *vrf;
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct interface *ifp; struct interface *ifp;
struct zebra_if *zi; struct zebra_if *zi;
struct irdp_interface *irdp; struct irdp_interface *irdp;
vrf_iter_t iter;
zlog_info("IRDP: Received shutdown notification."); zlog_info("IRDP: Received shutdown notification.");
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp)) for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp))
{ {
zi = ifp->info; zi = ifp->info;

View File

@ -282,7 +282,7 @@ send_packet(struct interface *ifp,
char buf[256]; char buf[256];
struct in_pktinfo *pktinfo; struct in_pktinfo *pktinfo;
u_long src; u_long src;
int on; u_char on;
if (!(ifp->flags & IFF_UP)) if (!(ifp->flags & IFF_UP))
return; return;
@ -323,12 +323,8 @@ send_packet(struct interface *ifp,
zlog_warn("sendto %s", safe_strerror (errno)); zlog_warn("sendto %s", safe_strerror (errno));
} }
if(dst != INADDR_BROADCAST) { if(dst != INADDR_BROADCAST)
on = 0; setsockopt_ipv4_multicast_loop (irdp_sock, 0);
if( setsockopt(irdp_sock,IPPROTO_IP, IP_MULTICAST_LOOP,
(char *)&on,sizeof(on)) < 0)
zlog_warn("sendto %s", safe_strerror (errno));
}
memset(&sockdst,0,sizeof(sockdst)); memset(&sockdst,0,sizeof(sockdst));
sockdst.sin_family=AF_INET; sockdst.sin_family=AF_INET;

View File

@ -716,11 +716,18 @@ kernel_init (struct zebra_ns *zns)
{ {
unsigned long groups; unsigned long groups;
groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR; /* Initialize netlink sockets */
#ifdef HAVE_IPV6 groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR |
groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR; RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
#endif /* HAVE_IPV6 */
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); 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); netlink_socket (&zns->netlink_cmd, 0, zns->ns_id);
/* Register kernel socket. */ /* Register kernel socket. */

View File

@ -182,20 +182,46 @@ sighup (void)
static void static void
sigint (void) sigint (void)
{ {
struct vrf *vrf;
struct zebra_vrf *zvrf;
struct zebra_ns *zns; struct zebra_ns *zns;
zlog_notice ("Terminating on signal"); zlog_notice ("Terminating on signal");
if (!retain_mode)
rib_close ();
#ifdef HAVE_IRDP #ifdef HAVE_IRDP
irdp_finish(); irdp_finish();
#endif #endif
zebra_ptm_finish(); 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); zns = zebra_ns_lookup (NS_DEFAULT);
zebra_ns_disable (0, (void **)&zns); 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); exit (0);
} }

View File

@ -262,13 +262,13 @@ zebra_redistribute_add (int command, struct zserv *client, int length,
if (! redist_check_instance (&client->mi_redist[afi][type], instance)) if (! redist_check_instance (&client->mi_redist[afi][type], instance))
{ {
redist_add_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 { } 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); vrf_bitmap_set (client->redist[afi][type], zvrf_id (zvrf));
zebra_redistribute (client, type, 0, zvrf->vrf_id); zebra_redistribute (client, type, 0, zvrf_id (zvrf));
} }
} }
} }
@ -296,22 +296,22 @@ zebra_redistribute_delete (int command, struct zserv *client, int length,
if (instance) if (instance)
redist_del_instance (&client->mi_redist[afi][type], instance); redist_del_instance (&client->mi_redist[afi][type], instance);
else else
vrf_bitmap_unset (client->redist[afi][type], zvrf->vrf_id); vrf_bitmap_unset (client->redist[afi][type], zvrf_id (zvrf));
} }
void void
zebra_redistribute_default_add (int command, struct zserv *client, int length, zebra_redistribute_default_add (int command, struct zserv *client, int length,
struct zebra_vrf *zvrf) struct zebra_vrf *zvrf)
{ {
vrf_bitmap_set (client->redist_default, zvrf->vrf_id); vrf_bitmap_set (client->redist_default, zvrf_id (zvrf));
zebra_redistribute_default (client, zvrf->vrf_id); zebra_redistribute_default (client, zvrf_id (zvrf));
} }
void void
zebra_redistribute_default_delete (int command, struct zserv *client, zebra_redistribute_default_delete (int command, struct zserv *client,
int length, struct zebra_vrf *zvrf) 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. */ /* Interface up information. */

View File

@ -366,13 +366,14 @@ extern void rib_update (vrf_id_t, rib_update_event_t);
extern void rib_weed_tables (void); extern void rib_weed_tables (void);
extern void rib_sweep_route (void); extern void rib_sweep_route (void);
extern void rib_close_table (struct route_table *); extern void rib_close_table (struct route_table *);
extern void rib_close (void);
extern void rib_init (void); extern void rib_init (void);
extern unsigned long rib_score_proto (u_char proto, u_short instance); extern unsigned long rib_score_proto (u_char proto, u_short instance);
extern void rib_queue_add (struct route_node *rn); 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 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 int rib_gc_dest (struct route_node *rn);
extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter); extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);

View File

@ -138,7 +138,7 @@ router_id_add_address (struct connected *ifc)
if (router_id_bad_address (ifc)) if (router_id_bad_address (ifc))
return; return;
router_id_get (&before, zvrf->vrf_id); router_id_get (&before, zvrf_id (zvrf));
if (!strncmp (ifc->ifp->name, "lo", 2) if (!strncmp (ifc->ifp->name, "lo", 2)
|| !strncmp (ifc->ifp->name, "dummy", 5)) || !strncmp (ifc->ifp->name, "dummy", 5))
@ -149,13 +149,13 @@ router_id_add_address (struct connected *ifc)
if (!router_id_find_node (l, ifc)) if (!router_id_find_node (l, ifc))
listnode_add_sort (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)) if (prefix_same (&before, &after))
return; return;
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) 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 void
@ -172,7 +172,7 @@ router_id_del_address (struct connected *ifc)
if (router_id_bad_address (ifc)) if (router_id_bad_address (ifc))
return; return;
router_id_get (&before, zvrf->vrf_id); router_id_get (&before, zvrf_id (zvrf));
if (!strncmp (ifc->ifp->name, "lo", 2) if (!strncmp (ifc->ifp->name, "lo", 2)
|| !strncmp (ifc->ifp->name, "dummy", 5)) || !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))) if ((c = router_id_find_node (l, ifc)))
listnode_delete (l, c); listnode_delete (l, c);
router_id_get (&after, zvrf->vrf_id); router_id_get (&after, zvrf_id (zvrf));
if (prefix_same (&before, &after)) if (prefix_same (&before, &after))
return; return;
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) 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 void
router_id_write (struct vty *vty) router_id_write (struct vty *vty)
{ {
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
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)
if ((zvrf = vrf_iter2info (iter)) != NULL) if ((zvrf = vrf->info) != NULL)
if (zvrf->rid_user_assigned.u.prefix4.s_addr) 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", vty_out (vty, "router-id %s%s",
inet_ntoa (zvrf->rid_user_assigned.u.prefix4), inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
VTY_NEWLINE); VTY_NEWLINE);
else else
vty_out (vty, "router-id %s vrf %s%s", vty_out (vty, "router-id %s vrf %s%s",
inet_ntoa (zvrf->rid_user_assigned.u.prefix4), inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
zvrf->name, zvrf_name (zvrf),
VTY_NEWLINE); VTY_NEWLINE);
} }
} }

View File

@ -99,16 +99,16 @@ Pending: create an efficient table_id (in a tree/hash) based lookup)
static vrf_id_t static vrf_id_t
vrf_lookup_by_table (u_int32_t table_id) vrf_lookup_by_table (u_int32_t table_id)
{ {
struct vrf *vrf;
struct zebra_vrf *zvrf; 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)) (zvrf->table_id != table_id))
continue; continue;
return zvrf->vrf_id; return zvrf_id (zvrf);
} }
return VRF_DEFAULT; return VRF_DEFAULT;
@ -1069,7 +1069,7 @@ _netlink_route_debug(
zlog_debug ("netlink_route_multipath() (%s): %s %s vrf %u type %s", zlog_debug ("netlink_route_multipath() (%s): %s %s vrf %u type %s",
routedesc, routedesc,
nl_msg_type_to_str (cmd), 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"); (nexthop) ? nexthop_type_to_str (nexthop->type) : "UNK");
} }
} }

View File

@ -374,7 +374,7 @@ static int
rtadv_timer (struct thread *thread) rtadv_timer (struct thread *thread)
{ {
struct zebra_ns *zns = THREAD_ARG (thread); struct zebra_ns *zns = THREAD_ARG (thread);
vrf_iter_t iter; struct vrf *vrf;
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct interface *ifp; struct interface *ifp;
struct zebra_if *zif; struct zebra_if *zif;
@ -392,8 +392,8 @@ rtadv_timer (struct thread *thread)
rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */); rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */);
} }
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp)) for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp))
{ {
if (if_is_loopback (ifp) || if (if_is_loopback (ifp) ||
CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) ||
@ -827,7 +827,7 @@ zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
if (IS_ZEBRA_DEBUG_EVENT) if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("%u: IF %u RA %s from client %s, interval %ds", 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); zebra_route_string(client->proto), ra_interval);
/* Locate interface and check VRF match. */ /* Locate interface and check VRF match. */
@ -835,14 +835,14 @@ zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
if (!ifp) if (!ifp)
{ {
zlog_warn("%u: IF %u RA %s client %s - interface unknown", 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)); zebra_route_string(client->proto));
return; 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", 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); zebra_route_string(client->proto), ifp->vrf_id);
return; return;
} }

View File

@ -348,7 +348,7 @@ zfpm_is_table_for_fpm (struct route_table *table)
* We only send the unicast tables in the main instance to the FPM * We only send the unicast tables in the main instance to the FPM
* at this point. * at this point.
*/ */
if (info->zvrf->vrf_id != 0) if (zvrf_id (info->zvrf) != 0)
return 0; return 0;
if (info->safi != SAFI_UNICAST) if (info->safi != SAFI_UNICAST)

View File

@ -246,7 +246,7 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
ri->af = rib_dest_af (dest); ri->af = rib_dest_af (dest);
ri->nlmsg_type = cmd; 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; ri->rtm_protocol = RTPROT_UNSPEC;
/* /*

View File

@ -35,6 +35,5 @@ DECLARE_MTYPE(STATIC_ROUTE)
DECLARE_MTYPE(RIB_DEST) DECLARE_MTYPE(RIB_DEST)
DECLARE_MTYPE(RIB_TABLE_INFO) DECLARE_MTYPE(RIB_TABLE_INFO)
DECLARE_MTYPE(RNH) DECLARE_MTYPE(RNH)
DECLARE_MTYPE(NETLINK_NAME)
#endif /* _QUAGGA_ZEBRA_MEMORY_H */ #endif /* _QUAGGA_ZEBRA_MEMORY_H */

View File

@ -1267,7 +1267,7 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
struct nexthop *nexthop; struct nexthop *nexthop;
/* Lookup table. */ /* 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) if (! table)
return -1; return -1;
@ -1501,7 +1501,7 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)
int update; int update;
/* Process routes of interested address-families. */ /* 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) if (!table)
return; return;
@ -1828,7 +1828,7 @@ zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf,
vty_out (vty, "%s", VTY_NEWLINE); 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); return (zvrf->slsp_table->count ? 1 : 0);
} }
@ -1880,9 +1880,11 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf)
void void
zebra_mpls_close_tables (struct zebra_vrf *zvrf) zebra_mpls_close_tables (struct zebra_vrf *zvrf)
{ {
if (!zvrf)
return;
hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL); hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL);
hash_clean(zvrf->lsp_table, NULL);
hash_free(zvrf->lsp_table);
hash_clean(zvrf->slsp_table, NULL);
hash_free(zvrf->slsp_table);
} }
/* /*

View File

@ -32,7 +32,6 @@
#include "zebra_memory.h" #include "zebra_memory.h"
DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space") DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space")
DEFINE_MTYPE(ZEBRA, NETLINK_NAME, "Netlink name")
struct zebra_ns *dzns; struct zebra_ns *dzns;
@ -46,24 +45,11 @@ int
zebra_ns_enable (ns_id_t ns_id, void **info) zebra_ns_enable (ns_id_t ns_id, void **info)
{ {
struct zebra_ns *zns = (struct zebra_ns *) (*info); struct zebra_ns *zns = (struct zebra_ns *) (*info);
#ifdef HAVE_NETLINK
char nl_name[64];
#endif
#if defined (HAVE_RTADV) #if defined (HAVE_RTADV)
rtadv_init (zns); rtadv_init (zns);
#endif #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 (); zns->if_table = route_table_init ();
kernel_init (zns); kernel_init (zns);
interface_list (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); struct zebra_ns *zns = (struct zebra_ns *) (*info);
route_table_finish (zns->if_table);
#if defined (HAVE_RTADV) #if defined (HAVE_RTADV)
rtadv_terminate (zns); rtadv_terminate (zns);
#endif #endif

View File

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

View File

@ -140,6 +140,8 @@ zebra_ptm_finish(void)
buffer_flush_all(ptm_cb.wb, ptm_cb.ptm_sock); buffer_flush_all(ptm_cb.wb, ptm_cb.ptm_sock);
free (ptm_hdl);
if (ptm_cb.out_data) if (ptm_cb.out_data)
free(ptm_cb.out_data); free(ptm_cb.out_data);
@ -256,15 +258,15 @@ DEFUN (zebra_ptm_enable,
"ptm-enable", "ptm-enable",
"Enable neighbor check with specified topology\n") "Enable neighbor check with specified topology\n")
{ {
struct vrf *vrf;
struct listnode *i; struct listnode *i;
struct interface *ifp; struct interface *ifp;
struct zebra_if *if_data; struct zebra_if *if_data;
vrf_iter_t iter;
ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON; ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), i, ifp)) for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp))
if (!ifp->ptm_enable) if (!ifp->ptm_enable)
{ {
if_data = (struct zebra_if *)ifp->info; 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, ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD,
tmp_buf); 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, ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD,
zvrf->name); zvrf_name (zvrf));
} }
else 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); ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
} }
#endif /* HAVE_IPV6 */ #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, ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD,
zvrf->name); zvrf_name (zvrf));
} }
else else
{ {
@ -1110,13 +1112,13 @@ zebra_ptm_send_status_req(void)
void void
zebra_ptm_reset_status(int ptm_disable) zebra_ptm_reset_status(int ptm_disable)
{ {
struct vrf *vrf;
struct listnode *i; struct listnode *i;
struct interface *ifp; struct interface *ifp;
int send_linkup; int send_linkup;
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)
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), i, ifp)) for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp))
{ {
send_linkup = 0; send_linkup = 0;
if (ifp->ptm_enable) if (ifp->ptm_enable)

View File

@ -1303,8 +1303,6 @@ rib_uninstall (struct route_node *rn, struct rib *rib)
} }
} }
static void rib_unlink (struct route_node *, struct rib *);
/* /*
* rib_can_delete_dest * rib_can_delete_dest
* *
@ -1352,7 +1350,7 @@ rib_gc_dest (struct route_node *rn)
zvrf = rib_dest_vrf (dest); zvrf = rib_dest_vrf (dest);
if (IS_ZEBRA_DEBUG_RIB) 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; dest->rnode = NULL;
XFREE (MTYPE_RIB_DEST, dest); 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); 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)", 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)) 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); inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
zlog_warn ("%u:%s/%d: Route install failed", 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); 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)", 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)) if (!RIB_SYSTEM_ROUTE (old))
@ -1463,11 +1461,11 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
{ {
if (new != old) if (new != old)
zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) " 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); rn, new, new->type, old, old->type);
else else
zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)", 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. */ /* Non-system route should be installed. */
if (!RIB_SYSTEM_ROUTE (new)) if (!RIB_SYSTEM_ROUTE (new))
@ -1477,7 +1475,7 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
installed = 0; installed = 0;
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
zlog_warn ("%u:%s/%d: Route install failed", 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) if (new != old)
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) " 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, rn, new, new->type, old, old->type,
nh_active ? "install failed" : "nexthop inactive"); nh_active ? "install failed" : "nexthop inactive");
else else
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) - %s", 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"); nh_active ? "install failed" : "nexthop inactive");
} }
@ -1626,7 +1624,7 @@ rib_process (struct route_node *rn)
if (dest) if (dest)
{ {
zvrf = rib_dest_vrf (dest); zvrf = rib_dest_vrf (dest);
vrf_id = zvrf->vrf_id; vrf_id = zvrf_id (zvrf);
} }
if (IS_ZEBRA_DEBUG_RIB) 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); inet_ntop (rnode->p.family, &rnode->p.u.prefix, buf, INET6_ADDRSTRLEN);
zlog_debug ("%u:%s/%d: rn %p dequeued from sub-queue %u", 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) if (rnode->info)
@ -2051,24 +2049,24 @@ process_subq (struct list * subq, u_char qindex)
static void static void
meta_queue_process_complete (struct work_queue *dummy) meta_queue_process_complete (struct work_queue *dummy)
{ {
vrf_iter_t iter; struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
/* Evaluate nexthops for those VRFs which underwent route processing. This /* Evaluate nexthops for those VRFs which underwent route processing. This
* should limit the evaluation to the necessary VRFs in most common * should limit the evaluation to the necessary VRFs in most common
* situations. * 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 = vrf->info;
(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED)) if (zvrf == NULL || !(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED))
{ continue;
zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED;
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED;
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_NEXTHOP_TYPE, NULL);
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL);
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 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. */ /* 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 (mpls_should_lsps_be_processed(zvrf))
{ {
if (IS_ZEBRA_DEBUG_MPLS) 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); zebra_mpls_lsp_schedule (zvrf);
mpls_unmark_lsps_for_processing(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", rnode_debug (rn, rib->vrf_id, "queued rn %p into sub-queue %u",
(void *)rn, qindex); (void *)rn, qindex);
zvrf = zebra_vrf_lookup (rib->vrf_id); zvrf = zebra_vrf_lookup_by_id (rib->vrf_id);
if (zvrf) if (zvrf)
zvrf->flags |= ZEBRA_VRF_RIB_SCHEDULED; zvrf->flags |= ZEBRA_VRF_RIB_SCHEDULED;
} }
@ -2215,6 +2213,17 @@ meta_queue_new (void)
return new; 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 */ /* initialise zebra rib work queue */
static void static void
rib_queue_init (struct zebra_t *zebra) 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 * rib_gc_dest() at some point. This allows a rib_dest_t that is no
* longer required to be deleted. * longer required to be deleted.
*/ */
static void void
rib_unlink (struct route_node *rn, struct rib *rib) rib_unlink (struct route_node *rn, struct rib *rib)
{ {
rib_dest_t *dest; rib_dest_t *dest;
@ -3036,11 +3045,11 @@ rib_weed_table (struct route_table *table)
void void
rib_weed_tables (void) rib_weed_tables (void)
{ {
vrf_iter_t iter; struct vrf *vrf;
struct zebra_vrf *zvrf; 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)
{ {
rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]); rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
@ -3077,11 +3086,11 @@ rib_sweep_table (struct route_table *table)
void void
rib_sweep_route (void) rib_sweep_route (void)
{ {
vrf_iter_t iter; struct vrf *vrf;
struct zebra_vrf *zvrf; 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)
{ {
rib_sweep_table (zvrf->table[AFI_IP][SAFI_UNICAST]); rib_sweep_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
rib_sweep_table (zvrf->table[AFI_IP6][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 unsigned long
rib_score_proto (u_char proto, u_short instance) rib_score_proto (u_char proto, u_short instance)
{ {
vrf_iter_t iter; struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
unsigned long cnt = 0; unsigned long cnt = 0;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
if ((zvrf = vrf_iter2info (iter)) != NULL) if ((zvrf = vrf->info) != NULL)
cnt += rib_score_proto_table (proto, instance, zvrf->table[AFI_IP][SAFI_UNICAST]) 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]); +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. */ /* Routing information base initialize. */
void void
rib_init (void) rib_init (void)
@ -3206,17 +3178,16 @@ rib_init (void)
static inline int static inline int
vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p) vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
{ {
vrf_iter_t iter = vrf_iterator (vrf_id); struct vrf *vrf;
struct zebra_vrf *zvrf = vrf_iter2info (iter);
/* The same one ? Then find out the next. */ vrf = vrf_lookup_by_id (vrf_id);
if (zvrf && (zvrf->vrf_id == vrf_id)) if (vrf)
zvrf = vrf_iter2info (vrf_next (iter));
if (zvrf)
{ {
*next_id_p = zvrf->vrf_id; vrf = RB_NEXT (vrf_id_head, &vrfs_by_id, vrf);
return 1; if (vrf) {
*next_id_p = vrf->vrf_id;
return 1;
}
} }
return 0; return 0;

View File

@ -56,7 +56,7 @@ static void copy_state(struct rnh *rnh, struct rib *rib,
({ \ ({ \
struct zebra_vrf *zvrf; \ struct zebra_vrf *zvrf; \
struct route_table *t = NULL; \ struct route_table *t = NULL; \
zvrf = zebra_vrf_lookup(v); \ zvrf = zebra_vrf_lookup_by_id(v); \
if (zvrf) \ if (zvrf) \
t = zvrf->rnh_table[family2afi(f)]; \ t = zvrf->rnh_table[family2afi(f)]; \
t; \ t; \
@ -76,7 +76,7 @@ static inline struct route_table *get_rnh_table(vrf_id_t vrfid, int family,
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
struct route_table *t = NULL; struct route_table *t = NULL;
zvrf = zebra_vrf_lookup(vrfid); zvrf = zebra_vrf_lookup_by_id(vrfid);
if (zvrf) if (zvrf)
switch (type) switch (type)
{ {
@ -162,6 +162,16 @@ zebra_lookup_rnh (struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
return (rn->info); 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 void
zebra_delete_rnh (struct rnh *rnh, rnh_type_t type) 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->vrf_id, rnh_str(rnh, buf, sizeof (buf)), type);
} }
rnh->flags |= ZEBRA_NHT_DELETED; zebra_free_rnh (rnh);
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);
rn->info = NULL; rn->info = NULL;
route_unlock_node (rn); route_unlock_node (rn);
return;
} }
void void

View File

@ -59,6 +59,7 @@ extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid,
rnh_type_t type); rnh_type_t type);
extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid,
rnh_type_t type); 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_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, extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
vrf_id_t vrfid); vrf_id_t vrfid);

View File

@ -27,6 +27,10 @@
int zebra_rnh_ip_default_route = 0; int zebra_rnh_ip_default_route = 0;
int zebra_rnh_ipv6_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, void zebra_evaluate_rnh (vrf_id_t vrfid, int family, int force, rnh_type_t type,
struct prefix *p) struct prefix *p)
{} {}

View File

@ -345,7 +345,7 @@ DEFUN (set_src,
struct interface *pif = NULL; struct interface *pif = NULL;
int family; int family;
struct prefix p; struct prefix p;
vrf_iter_t iter; struct vrf *vrf;
if (inet_pton(AF_INET, argv[idx_ip]->arg, &src.ipv4) != 1) if (inet_pton(AF_INET, argv[idx_ip]->arg, &src.ipv4) != 1)
{ {
@ -372,14 +372,14 @@ DEFUN (set_src,
return CMD_WARNING; 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) if (family == AF_INET)
pif = if_lookup_exact_address_vrf ((void *)&src.ipv4, AF_INET, pif = if_lookup_exact_address_vrf ((void *)&src.ipv4, AF_INET,
vrf_iter2id (iter)); vrf->vrf_id);
else if (family == AF_INET6) else if (family == AF_INET6)
pif = if_lookup_exact_address_vrf ((void *)&src.ipv6, AF_INET6, pif = if_lookup_exact_address_vrf ((void *)&src.ipv6, AF_INET6,
vrf_iter2id (iter)); vrf->vrf_id);
if (pif != NULL) if (pif != NULL)
break; break;

View File

@ -130,7 +130,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
rib->metric = 0; rib->metric = 0;
rib->mtu = 0; rib->mtu = 0;
rib->vrf_id = si->vrf_id; 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->nexthop_num = 0;
rib->tag = si->tag; rib->tag = si->tag;
@ -423,7 +423,7 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
si->distance = distance; si->distance = distance;
si->flags = flags; si->flags = flags;
si->tag = tag; si->tag = tag;
si->vrf_id = zvrf->vrf_id; si->vrf_id = zvrf_id (zvrf);
si->ifindex = ifindex; si->ifindex = ifindex;
if (si->ifindex) if (si->ifindex)
strcpy(si->ifname, ifname); strcpy(si->ifname, ifname);

View File

@ -23,6 +23,7 @@
#include "log.h" #include "log.h"
#include "linklist.h" #include "linklist.h"
#include "command.h"
#include "memory.h" #include "memory.h"
#include "vty.h" #include "vty.h"
@ -30,13 +31,14 @@
#include "zebra/zserv.h" #include "zebra/zserv.h"
#include "zebra/rib.h" #include "zebra/rib.h"
#include "zebra/zebra_vrf.h" #include "zebra/zebra_vrf.h"
#include "zebra/zebra_rnh.h"
#include "zebra/router-id.h" #include "zebra/router-id.h"
#include "zebra/zebra_memory.h" #include "zebra/zebra_memory.h"
#include "zebra/zebra_static.h" #include "zebra/zebra_static.h"
#include "zebra/interface.h"
#include "zebra/zebra_mpls.h" #include "zebra/zebra_mpls.h"
extern struct zebra_t zebrad; extern struct zebra_t zebrad;
struct list *zvrf_list;
/* VRF information update. */ /* VRF information update. */
static void static void
@ -46,7 +48,7 @@ zebra_vrf_add_update (struct zebra_vrf *zvrf)
struct zserv *client; struct zserv *client;
if (IS_ZEBRA_DEBUG_EVENT) 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)) for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
zsend_vrf_add (client, zvrf); zsend_vrf_add (client, zvrf);
@ -59,7 +61,7 @@ zebra_vrf_delete_update (struct zebra_vrf *zvrf)
struct zserv *client; struct zserv *client;
if (IS_ZEBRA_DEBUG_EVENT) 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)) for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
zsend_vrf_delete (client, zvrf); zsend_vrf_delete (client, zvrf);
@ -69,44 +71,28 @@ void
zebra_vrf_update_all (struct zserv *client) zebra_vrf_update_all (struct zserv *client)
{ {
struct vrf *vrf; 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)); zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id));
} }
} }
/* Callback upon creating a new VRF. */ /* Callback upon creating a new VRF. */
static int 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) 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_alloc ();
{ zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */
zvrf = zebra_vrf_list_lookup_by_name (name); router_id_init (zvrf);
if (!zvrf) vrf->info = zvrf;
{ zvrf->vrf = vrf;
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;
return 0; return 0;
} }
@ -123,7 +109,7 @@ zebra_vrf_static_route_interface_fixup (struct interface *ifp)
{ {
afi_t afi; afi_t afi;
safi_t safi; 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_table *stable = NULL;
struct route_node *rn = NULL; struct route_node *rn = NULL;
struct static_route *si = NULL; struct static_route *si = NULL;
@ -157,13 +143,13 @@ zebra_vrf_static_route_interface_fixup (struct interface *ifp)
/* Callback upon enabling a VRF. */ /* Callback upon enabling a VRF. */
static int static int
zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) zebra_vrf_enable (struct vrf *vrf)
{ {
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); struct zebra_vrf *zvrf = vrf->info;
struct route_table *stable = NULL; struct route_table *stable;
struct route_node *rn = NULL; struct route_node *rn;
struct static_route *si = NULL; struct static_route *si;
struct interface *ifp = NULL; struct interface *ifp;
afi_t afi; afi_t afi;
safi_t safi; safi_t safi;
@ -172,85 +158,145 @@ zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
zebra_vrf_add_update (zvrf); zebra_vrf_add_update (zvrf);
for (afi = AFI_IP; afi < AFI_MAX; afi++) for (afi = AFI_IP; afi < AFI_MAX; afi++)
{ for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) {
{ stable = zvrf->stable[afi][safi];
stable = zvrf->stable[afi][safi]; if (! stable)
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) ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id);
{ if (ifp)
si = rn->info; si->ifindex = ifp->ifindex;
si->vrf_id = vrf_id; else
if (si->ifindex) continue;
{
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);
}
} }
static_install_route (afi, safi, &rn->p, si);
} }
} }
}
return 0; return 0;
} }
/* Callback upon disabling a VRF. */ /* Callback upon disabling a VRF. */
static int static int
zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) zebra_vrf_disable (struct vrf *vrf)
{ {
struct zebra_vrf *zvrf = (struct zebra_vrf *)(*info); struct zebra_vrf *zvrf = vrf->info;
struct route_table *stable = NULL; struct route_table *stable;
struct route_node *rn = NULL; struct route_node *rn;
struct static_route *si;
afi_t afi; afi_t afi;
safi_t safi; safi_t safi;
if (IS_ZEBRA_DEBUG_KERNEL) if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("VRF %s id %u is now disabled.", 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 (afi = AFI_IP; afi < AFI_MAX; afi++)
{ for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) {
{ stable = zvrf->stable[afi][safi];
stable = zvrf->stable[afi][safi]; if (! stable)
if (stable) continue;
{
for (rn = route_top (stable); rn; rn = route_next (rn)) for (rn = route_top (stable); rn; rn = route_next (rn))
{ for (si = rn->info; si; si = si->next)
if (rn->info) static_uninstall_route(afi, safi, &rn->p, si);
static_uninstall_route(afi, safi, &rn->p, rn->info); }
}
}
}
}
return 0; return 0;
} }
static int 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); assert (zvrf);
zebra_vrf_delete_update (zvrf); zebra_vrf_delete_update (zvrf);
rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]); /* uninstall everything */
rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); 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_all_sorted_list);
list_delete_all_node (zvrf->rid_lo_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; return 0;
} }
@ -280,6 +326,62 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
return table; 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. * Create a routing table for the specific AFI/SAFI in the given VRF.
*/ */
@ -291,7 +393,7 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
assert (!zvrf->table[afi][safi]); assert (!zvrf->table[afi][safi]);
table = route_table_init (); table = route_table_init_with_delegate (&zebra_rtable_delegate);
zvrf->table[afi][safi] = table; zvrf->table[afi][safi] = table;
info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info)); info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
@ -303,35 +405,27 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
/* Allocate new zebra VRF. */ /* Allocate new zebra VRF. */
struct zebra_vrf * struct zebra_vrf *
zebra_vrf_alloc (vrf_id_t vrf_id, const char *name) zebra_vrf_alloc (void)
{ {
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
afi_t afi;
safi_t safi;
zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf)); zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
/* Allocate routing table and static table. */ for (afi = AFI_IP; afi <= AFI_IP6; afi++)
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)
{ {
strncpy (zvrf->name, name, strlen(name)); for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
zvrf->name[strlen(name)] = '\0'; {
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); zebra_mpls_init_tables (zvrf);
@ -341,26 +435,24 @@ zebra_vrf_alloc (vrf_id_t vrf_id, const char *name)
/* Lookup VRF by identifier. */ /* Lookup VRF by identifier. */
struct zebra_vrf * 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); return vrf_info_lookup (vrf_id);
} }
/* Lookup the zvrf in the zvrf_list. */ /* Lookup VRF by name. */
struct zebra_vrf * struct zebra_vrf *
zebra_vrf_list_lookup_by_name (const char *name) zebra_vrf_lookup_by_name (const char *name)
{ {
struct listnode *node; struct vrf *vrf;
struct zebra_vrf *zvrf;
if (!name) if (!name)
name = VRF_DEFAULT_NAME; name = VRF_DEFAULT_NAME;
for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) vrf = vrf_lookup_by_name (name);
{ if (vrf)
if (strcmp(name, zvrf->name) == 0) return ((struct zebra_vrf *) vrf->info);
return zvrf;
}
return NULL; return NULL;
} }
@ -428,6 +520,24 @@ zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
return zvrf->table[afi][SAFI_UNICAST]; return zvrf->table[afi][SAFI_UNICAST];
} }
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;
}
/* Zebra VRF initialization. */ /* Zebra VRF initialization. */
void void
zebra_vrf_init (void) zebra_vrf_init (void)
@ -437,7 +547,6 @@ zebra_vrf_init (void)
vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable); vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete); vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete);
zvrf_list = list_new ();
vrf_init (); vrf_init ();
vrf_cmd_init (vrf_config_write);
} }

View File

@ -28,11 +28,8 @@
/* Routing table instance. */ /* Routing table instance. */
struct zebra_vrf struct zebra_vrf
{ {
/* Identifier. */ /* Back pointer */
vrf_id_t vrf_id; struct vrf *vrf;
/* Routing table name. */
char name[VRF_NAMSIZ];
/* Description. */ /* Description. */
char *desc; char *desc;
@ -43,6 +40,7 @@ struct zebra_vrf
/* Flags. */ /* Flags. */
u_int16_t flags; u_int16_t flags;
#define ZEBRA_VRF_RIB_SCHEDULED (1 << 0) #define ZEBRA_VRF_RIB_SCHEDULED (1 << 0)
#define ZEBRA_VRF_RETAIN (2 << 0)
u_int32_t table_id; u_int32_t table_id;
@ -86,7 +84,17 @@ struct zebra_vrf
#define MPLS_FLAG_SCHEDULE_LSPS (1 << 0) #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 * struct route_table *
zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, 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_static_route_interface_fixup (struct interface *ifp);
extern void zebra_vrf_update_all (struct zserv *client); extern void zebra_vrf_update_all (struct zserv *client);
extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id); extern struct zebra_vrf *zebra_vrf_lookup_by_id (vrf_id_t vrf_id);
extern struct zebra_vrf *zebra_vrf_list_lookup_by_name (const char *); extern struct zebra_vrf *zebra_vrf_lookup_by_name (const char *);
extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *); extern struct zebra_vrf *zebra_vrf_alloc (void);
extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t); extern struct route_table *zebra_vrf_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_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, extern struct route_table *zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id,

View File

@ -107,7 +107,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
tag = atol(tag_str); tag = atol(tag_str);
/* VRF id */ /* VRF id */
zvrf = zebra_vrf_list_lookup_by_name (vrf_id_str); zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
if (!zvrf) if (!zvrf)
{ {
@ -183,7 +183,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
ret = inet_aton (gate_str, &gate); ret = inet_aton (gate_str, &gate);
if (!ret) 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) if (!ifp)
{ {
vty_out (vty, "%% Unknown interface: %s%s", gate_str, VTY_NEWLINE); vty_out (vty, "%% Unknown interface: %s%s", gate_str, VTY_NEWLINE);
@ -811,7 +811,7 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
if (rib->vrf_id != VRF_DEFAULT) if (rib->vrf_id != VRF_DEFAULT)
{ {
zvrf = vrf_info_lookup(rib->vrf_id); 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)) if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
vty_out (vty, ", best"); vty_out (vty, ", best");
@ -1215,7 +1215,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
json_object *json = NULL; json_object *json = NULL;
json_object *json_prefix = 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) if (use_json)
vty_out (vty, "{}%s", VTY_NEWLINE); vty_out (vty, "{}%s", VTY_NEWLINE);
@ -1224,7 +1224,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
if (zvrf->vrf_id == VRF_UNKNOWN) if (zvrf_id (zvrf) == VRF_UNKNOWN)
{ {
if (use_json) if (use_json)
vty_out (vty, "{}%s", VTY_NEWLINE); vty_out (vty, "{}%s", VTY_NEWLINE);
@ -1233,7 +1233,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
return CMD_SUCCESS; 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 (! table)
{ {
if (use_json) if (use_json)
@ -1328,14 +1328,14 @@ DEFUN (show_ip_nht_vrf_all,
"IP nexthop tracking table\n" "IP nexthop tracking table\n"
VRF_ALL_CMD_HELP_STR) VRF_ALL_CMD_HELP_STR)
{ {
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
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)
if ((zvrf = vrf_iter2info (iter)) != NULL) if ((zvrf = vrf->info) != NULL)
{ {
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);
zebra_print_rnh_table(zvrf->vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE); zebra_print_rnh_table(zvrf_id (zvrf), AF_INET, vty, RNH_NEXTHOP_TYPE);
} }
return CMD_SUCCESS; return CMD_SUCCESS;
@ -1368,14 +1368,14 @@ DEFUN (show_ipv6_nht_vrf_all,
"IPv6 nexthop tracking table\n" "IPv6 nexthop tracking table\n"
VRF_ALL_CMD_HELP_STR) VRF_ALL_CMD_HELP_STR)
{ {
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
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)
if ((zvrf = vrf_iter2info (iter)) != NULL) if ((zvrf = vrf->info) != NULL)
{ {
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);
zebra_print_rnh_table(zvrf->vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE); zebra_print_rnh_table(zvrf_id (zvrf), AF_INET6, vty, RNH_NEXTHOP_TYPE);
} }
return CMD_SUCCESS; return CMD_SUCCESS;
@ -1819,7 +1819,7 @@ vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
vty_out (vty, "%-20s %-20s %s (vrf %s)%s", vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
"Route Source", "Routes", "FIB", "Route Source", "Routes", "FIB",
((rib_table_info_t *)table->info)->zvrf->name, zvrf_name (((rib_table_info_t *)table->info)->zvrf),
VTY_NEWLINE); VTY_NEWLINE);
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
@ -1900,7 +1900,7 @@ vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
vty_out (vty, "%-20s %-20s %s (vrf %s)%s", vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
"Route Source", "Prefix Routes", "FIB", "Route Source", "Prefix Routes", "FIB",
((rib_table_info_t *)table->info)->zvrf->name, zvrf_name (((rib_table_info_t *)table->info)->zvrf),
VTY_NEWLINE); VTY_NEWLINE);
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
@ -1992,14 +1992,14 @@ DEFUN (show_ip_route_vrf_all,
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct rib *rib;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
int first = 1; int first = 1;
int vrf_header = 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) (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue; continue;
@ -2015,7 +2015,7 @@ DEFUN (show_ip_route_vrf_all,
if (vrf_header) 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; vrf_header = 0;
} }
vty_show_ip_route (vty, rn, rib, NULL); vty_show_ip_route (vty, rn, rib, NULL);
@ -2040,8 +2040,8 @@ DEFUN (show_ip_route_vrf_all_tag,
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct rib *rib;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
int first = 1; int first = 1;
int vrf_header = 1; int vrf_header = 1;
route_tag_t tag = 0; route_tag_t tag = 0;
@ -2049,9 +2049,9 @@ DEFUN (show_ip_route_vrf_all_tag,
if (argv[idx_number]->arg) if (argv[idx_number]->arg)
tag = atol(argv[idx_number]->arg); tag = atol(argv[idx_number]->arg);
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) (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue; continue;
@ -2070,7 +2070,7 @@ DEFUN (show_ip_route_vrf_all_tag,
if (vrf_header) 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; vrf_header = 0;
} }
vty_show_ip_route (vty, rn, rib, NULL); vty_show_ip_route (vty, rn, rib, NULL);
@ -2095,8 +2095,8 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct rib *rib;
struct prefix p; struct prefix p;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
int ret; int ret;
int first = 1; int first = 1;
int vrf_header = 1; int vrf_header = 1;
@ -2108,9 +2108,9 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,
return CMD_WARNING; 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) (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue; continue;
@ -2127,7 +2127,7 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,
if (vrf_header) 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; vrf_header = 0;
} }
vty_show_ip_route (vty, rn, rib, NULL); vty_show_ip_route (vty, rn, rib, NULL);
@ -2150,15 +2150,15 @@ DEFUN (show_ip_route_vrf_all_supernets,
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct rib *rib;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
u_int32_t addr; u_int32_t addr;
int first = 1; int first = 1;
int vrf_header = 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) (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue; continue;
@ -2179,7 +2179,7 @@ DEFUN (show_ip_route_vrf_all_supernets,
} }
if (vrf_header) 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; vrf_header = 0;
} }
vty_show_ip_route (vty, rn, rib, NULL); vty_show_ip_route (vty, rn, rib, NULL);
@ -2204,8 +2204,8 @@ DEFUN (show_ip_route_vrf_all_protocol,
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct rib *rib;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
int first = 1; int first = 1;
int vrf_header = 1; int vrf_header = 1;
@ -2216,9 +2216,9 @@ DEFUN (show_ip_route_vrf_all_protocol,
return CMD_WARNING; 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) (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue; continue;
@ -2235,7 +2235,7 @@ DEFUN (show_ip_route_vrf_all_protocol,
if (vrf_header) 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; vrf_header = 0;
} }
vty_show_ip_route (vty, rn, rib, NULL); vty_show_ip_route (vty, rn, rib, NULL);
@ -2260,8 +2260,8 @@ DEFUN (show_ip_route_vrf_all_addr,
struct prefix_ipv4 p; struct prefix_ipv4 p;
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p); ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p);
if (ret <= 0) if (ret <= 0)
@ -2270,9 +2270,9 @@ DEFUN (show_ip_route_vrf_all_addr,
return CMD_WARNING; 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) (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue; continue;
@ -2302,8 +2302,8 @@ DEFUN (show_ip_route_vrf_all_prefix,
struct prefix_ipv4 p; struct prefix_ipv4 p;
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p); ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p);
if (ret <= 0) if (ret <= 0)
@ -2312,9 +2312,9 @@ DEFUN (show_ip_route_vrf_all_prefix,
return CMD_WARNING; 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) (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue; continue;
@ -2344,11 +2344,11 @@ DEFUN (show_ip_route_vrf_all_summary,
VRF_ALL_CMD_HELP_STR VRF_ALL_CMD_HELP_STR
"Summary of all routes\n") "Summary of all routes\n")
{ {
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
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)
if ((zvrf = vrf_iter2info (iter)) != NULL) if ((zvrf = vrf->info) != NULL)
vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -2364,11 +2364,11 @@ DEFUN (show_ip_route_vrf_all_summary_prefix,
"Summary of all routes\n" "Summary of all routes\n"
"Prefix routes\n") "Prefix routes\n")
{ {
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
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)
if ((zvrf = vrf_iter2info (iter)) != NULL) if ((zvrf = vrf->info) != NULL)
vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -2381,13 +2381,15 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
struct route_node *rn; struct route_node *rn;
struct static_route *si; struct static_route *si;
struct route_table *stable; struct route_table *stable;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
char buf[BUFSIZ]; char buf[BUFSIZ];
int write =0; int write =0;
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{ {
if (!(zvrf = vrf->info))
continue;
if ((stable = zvrf->stable[AFI_IP][safi]) == NULL) if ((stable = zvrf->stable[AFI_IP][safi]) == NULL)
continue; continue;
@ -2426,7 +2428,7 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
vty_out (vty, " %d", si->distance); vty_out (vty, " %d", si->distance);
if (si->vrf_id != VRF_DEFAULT) 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 */ /* Label information */
if (si->snh_label.num_labels) if (si->snh_label.num_labels)
@ -2488,7 +2490,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
ret = inet_pton (AF_INET6, gate_str, &gate_addr); ret = inet_pton (AF_INET6, gate_str, &gate_addr);
/* VRF id */ /* VRF id */
zvrf = zebra_vrf_list_lookup_by_name (vrf_id_str); zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
if (!zvrf) if (!zvrf)
{ {
@ -2559,7 +2561,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
} }
type = STATIC_IPV6_GATEWAY_IFINDEX; type = STATIC_IPV6_GATEWAY_IFINDEX;
gate = &gate_addr; 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) if (!ifp)
{ {
vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE); vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE);
@ -2577,7 +2579,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
else else
{ {
type = STATIC_IFINDEX; 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) if (!ifp)
{ {
vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE); vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE);
@ -2894,7 +2896,7 @@ DEFUN (show_ipv6_route,
if (vrf) if (vrf)
{ {
if (!(zvrf = zebra_vrf_list_lookup_by_name (vrfname))) if (!(zvrf = zebra_vrf_lookup_by_name (vrfname)))
{ {
if (uj) if (uj)
vty_out (vty, "{}%s", VTY_NEWLINE); vty_out (vty, "{}%s", VTY_NEWLINE);
@ -2903,7 +2905,7 @@ DEFUN (show_ipv6_route,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
if (zvrf->vrf_id == VRF_UNKNOWN) if (zvrf_id (zvrf) == VRF_UNKNOWN)
{ {
if (uj) if (uj)
vty_out (vty, "{}%s", VTY_NEWLINE); vty_out (vty, "{}%s", VTY_NEWLINE);
@ -2912,7 +2914,7 @@ DEFUN (show_ipv6_route,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
else else
vrf_id = zvrf->vrf_id; vrf_id = zvrf_id (zvrf);
} }
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
@ -3326,14 +3328,14 @@ DEFUN (show_ipv6_route_vrf_all,
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct rib *rib;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
int first = 1; int first = 1;
int vrf_header = 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) (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue; continue;
@ -3349,7 +3351,7 @@ DEFUN (show_ipv6_route_vrf_all,
if (vrf_header) 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; vrf_header = 0;
} }
vty_show_ip_route (vty, rn, rib, NULL); vty_show_ip_route (vty, rn, rib, NULL);
@ -3374,8 +3376,8 @@ DEFUN (show_ipv6_route_vrf_all_tag,
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct rib *rib;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
int first = 1; int first = 1;
int vrf_header = 1; int vrf_header = 1;
route_tag_t tag = 0; route_tag_t tag = 0;
@ -3383,9 +3385,9 @@ DEFUN (show_ipv6_route_vrf_all_tag,
if (argv[idx_number]->arg) if (argv[idx_number]->arg)
tag = atol(argv[idx_number]->arg); tag = atol(argv[idx_number]->arg);
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) (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue; continue;
@ -3404,7 +3406,7 @@ DEFUN (show_ipv6_route_vrf_all_tag,
if (vrf_header) 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; vrf_header = 0;
} }
vty_show_ip_route (vty, rn, rib, NULL); vty_show_ip_route (vty, rn, rib, NULL);
@ -3430,8 +3432,8 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct rib *rib;
struct prefix p; struct prefix p;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
int ret; int ret;
int first = 1; int first = 1;
int vrf_header = 1; int vrf_header = 1;
@ -3443,9 +3445,9 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
return CMD_WARNING; 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) (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue; continue;
@ -3462,7 +3464,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
if (vrf_header) 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; vrf_header = 0;
} }
vty_show_ip_route (vty, rn, rib, NULL); vty_show_ip_route (vty, rn, rib, NULL);
@ -3487,8 +3489,8 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct rib *rib;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
int first = 1; int first = 1;
int vrf_header = 1; int vrf_header = 1;
@ -3499,9 +3501,9 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
return CMD_WARNING; 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) (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue; continue;
@ -3518,7 +3520,7 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
if (vrf_header) 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; vrf_header = 0;
} }
vty_show_ip_route (vty, rn, rib, NULL); vty_show_ip_route (vty, rn, rib, NULL);
@ -3543,8 +3545,8 @@ DEFUN (show_ipv6_route_vrf_all_addr,
struct prefix_ipv6 p; struct prefix_ipv6 p;
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
ret = str2prefix_ipv6 (argv[idx_ipv6]->arg, &p); ret = str2prefix_ipv6 (argv[idx_ipv6]->arg, &p);
if (ret <= 0) if (ret <= 0)
@ -3553,9 +3555,9 @@ DEFUN (show_ipv6_route_vrf_all_addr,
return CMD_WARNING; 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) (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue; continue;
@ -3585,8 +3587,8 @@ DEFUN (show_ipv6_route_vrf_all_prefix,
struct prefix_ipv6 p; struct prefix_ipv6 p;
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, &p); ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, &p);
if (ret <= 0) if (ret <= 0)
@ -3595,9 +3597,9 @@ DEFUN (show_ipv6_route_vrf_all_prefix,
return CMD_WARNING; 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) (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue; continue;
@ -3627,11 +3629,11 @@ DEFUN (show_ipv6_route_vrf_all_summary,
VRF_ALL_CMD_HELP_STR VRF_ALL_CMD_HELP_STR
"Summary of all IPv6 routes\n") "Summary of all IPv6 routes\n")
{ {
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
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)
if ((zvrf = vrf_iter2info (iter)) != NULL) if ((zvrf = vrf->info) != NULL)
vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -3648,13 +3650,13 @@ DEFUN (show_ipv6_mroute_vrf_all,
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rib *rib; struct rib *rib;
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vrf_iter_t iter;
int first = 1; 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) (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue; continue;
@ -3683,11 +3685,11 @@ DEFUN (show_ipv6_route_vrf_all_summary_prefix,
"Summary of all IPv6 routes\n" "Summary of all IPv6 routes\n"
"Prefix routes\n") "Prefix routes\n")
{ {
struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
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)
if ((zvrf = vrf_iter2info (iter)) != NULL) if ((zvrf = vrf->info) != NULL)
vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -3702,11 +3704,13 @@ static_config_ipv6 (struct vty *vty)
int write = 0; int write = 0;
char buf[PREFIX_STRLEN]; char buf[PREFIX_STRLEN];
struct route_table *stable; struct route_table *stable;
struct vrf *vrf;
struct zebra_vrf *zvrf; 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->info))
continue;
if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL) if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL)
continue; continue;
@ -3750,7 +3754,7 @@ static_config_ipv6 (struct vty *vty)
if (si->vrf_id != VRF_DEFAULT) if (si->vrf_id != VRF_DEFAULT)
{ {
vty_out (vty, " vrf %s", zvrf->name); vty_out (vty, " vrf %s", zvrf_name (zvrf));
} }
/* Label information */ /* Label information */
@ -3794,19 +3798,21 @@ DEFUN (show_vrf,
SHOW_STR SHOW_STR
"VRF\n") "VRF\n")
{ {
struct vrf *vrf;
struct zebra_vrf *zvrf; 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) if (!(zvrf = vrf->info))
continue;
if (!zvrf_id (zvrf))
continue; continue;
vty_out (vty, "vrf %s ", zvrf->name); vty_out (vty, "vrf %s ", zvrf_name (zvrf));
if (zvrf->vrf_id == VRF_UNKNOWN) if (zvrf_id (zvrf) == VRF_UNKNOWN)
vty_out (vty, "inactive"); vty_out (vty, "inactive");
else 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); vty_out (vty, "%s", VTY_NEWLINE);
} }

View File

@ -185,7 +185,7 @@ static void
zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf) zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf)
{ {
/* Interface information. */ /* Interface information. */
stream_put (s, zvrf->name, VRF_NAMSIZ); stream_put (s, zvrf_name (zvrf), VRF_NAMSIZ);
/* Write packet size. */ /* Write packet size. */
stream_putw_at (s, 0, stream_get_endp (s)); 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; s = client->obuf;
stream_reset (s); 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); zserv_encode_vrf (s, zvrf);
client->vrfadd_cnt++; client->vrfadd_cnt++;
@ -257,7 +257,7 @@ zsend_vrf_delete (struct zserv *client, struct zebra_vrf *zvrf)
s = client->obuf; s = client->obuf;
stream_reset (s); 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); zserv_encode_vrf (s, zvrf);
client->vrfdel_cnt++; client->vrfdel_cnt++;
@ -850,7 +850,7 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length,
p.family); p.family);
return -1; 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 (type == RNH_NEXTHOP_TYPE)
{ {
if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) 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); 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 */ /* 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; return 0;
} }
@ -911,7 +911,7 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
p.family); p.family);
return -1; return -1;
} }
rnh = zebra_lookup_rnh(&p, zvrf->vrf_id, type); rnh = zebra_lookup_rnh(&p, zvrf_id (zvrf), type);
if (rnh) if (rnh)
{ {
client->nh_dereg_time = quagga_monotime(); 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); stream_reset (s);
/* Fill in result. */ /* 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); stream_put_in_addr (s, &addr);
if (rib) if (rib)
@ -1005,18 +1005,16 @@ zsend_router_id_update (struct zserv *client, struct prefix *p,
static int static int
zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{ {
struct vrf *vrf;
struct listnode *ifnode, *ifnnode; struct listnode *ifnode, *ifnnode;
vrf_iter_t iter;
struct interface *ifp; struct interface *ifp;
struct zebra_vrf *zvrf_iter;
/* Interface information is needed. */ /* 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, ifnode, ifnnode, ifp))
for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf_iter->vrf_id), ifnode, ifnnode, ifp))
{ {
/* Skip pseudo interface. */ /* Skip pseudo interface. */
if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) 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 static int
zread_interface_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) 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; 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)); stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
/* VRF ID */ /* VRF ID */
rib->vrf_id = zvrf->vrf_id; rib->vrf_id = zvrf_id (zvrf);
/* Nexthop parse. */ /* Nexthop parse. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) 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; 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); api.flags, &p, nexthop_p, ifindex, table_id);
client->v4_route_del_cnt++; client->v4_route_del_cnt++;
return 0; return 0;
@ -1259,7 +1257,7 @@ zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zeb
struct rib *rib; struct rib *rib;
addr.s_addr = stream_get_ipv4 (client->ibuf); 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); 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)); stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
/* VRF ID */ /* 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 /* 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 * 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; rib->mtu = 0;
/* VRF ID */ /* VRF ID */
rib->vrf_id = zvrf->vrf_id; rib->vrf_id = zvrf_id (zvrf);
rib->table = zvrf->table_id; rib->table = zvrf->table_id;
ret = rib_add_multipath (AFI_IP6, safi, &p, rib); 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; api.tag = 0;
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) 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); api.flags, &p, NULL, ifindex, client->rtm_table);
else 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); api.flags, &p, pnexthop, ifindex, client->rtm_table);
client->v6_route_del_cnt++; 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; struct prefix p;
/* Router-id information is needed. */ /* 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. */ /* Unregister zebra server router-id information. */
static int static int
zread_router_id_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) 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; 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 (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
vrf_bitmap_unset (client->redist[afi][i], zvrf->vrf_id); vrf_bitmap_unset (client->redist[afi][i], zvrf_id (zvrf));
vrf_bitmap_unset (client->redist_default, zvrf->vrf_id); vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf));
vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id); vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf));
vrf_bitmap_unset (client->ridinfo, zvrf->vrf_id); vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf));
return 0; return 0;
} }
@ -1724,17 +1722,17 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
static void static void
zebra_client_close_cleanup_rnh (struct zserv *client) zebra_client_close_cleanup_rnh (struct zserv *client)
{ {
vrf_iter_t iter; struct vrf *vrf;
struct zebra_vrf *zvrf; 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_id (zvrf), AF_INET, client, RNH_NEXTHOP_TYPE);
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_NEXTHOP_TYPE); zebra_cleanup_rnh_client(zvrf_id (zvrf), 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_id (zvrf), 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_INET6, client, RNH_IMPORT_CHECK_TYPE);
if (client->proto == ZEBRA_ROUTE_LDP) if (client->proto == ZEBRA_ROUTE_LDP)
{ {
hash_iterate(zvrf->lsp_table, mpls_ldp_lsp_uninstall_all, 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_time = quagga_monotime();
client->last_read_cmd = command; client->last_read_cmd = command;
zvrf = zebra_vrf_lookup (vrf_id); zvrf = zebra_vrf_lookup_by_id (vrf_id);
if (!zvrf) if (!zvrf)
{ {
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)