forked from Mirror/frr
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:
commit
6fd800be4a
2
README
2
README
|
@ -2,7 +2,7 @@ Quagga is free software that manages various IPv4 and IPv6 routing
|
|||
protocols.
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
@ -172,8 +172,7 @@ peer_xfer_conn(struct peer *from_peer)
|
|||
peer->hostname = NULL;
|
||||
}
|
||||
|
||||
peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, from_peer->hostname);
|
||||
XFREE(MTYPE_BGP_PEER_HOST, from_peer->hostname);
|
||||
peer->hostname = from_peer->hostname;
|
||||
from_peer->hostname = NULL;
|
||||
}
|
||||
|
||||
|
@ -185,8 +184,7 @@ peer_xfer_conn(struct peer *from_peer)
|
|||
peer->domainname= NULL;
|
||||
}
|
||||
|
||||
peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, from_peer->domainname);
|
||||
XFREE(MTYPE_BGP_PEER_HOST, from_peer->domainname);
|
||||
peer->domainname = from_peer->domainname;
|
||||
from_peer->domainname = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -308,38 +308,33 @@ bgp_exit (int status)
|
|||
}
|
||||
|
||||
static int
|
||||
bgp_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
|
||||
bgp_vrf_new (struct vrf *vrf)
|
||||
{
|
||||
if (BGP_DEBUG (zebra, ZEBRA))
|
||||
zlog_debug ("VRF Created: %s(%d)", name, vrf_id);
|
||||
zlog_debug ("VRF Created: %s(%d)", vrf->name, vrf->vrf_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bgp_vrf_delete (vrf_id_t vrf_id, const char *name, void **info)
|
||||
bgp_vrf_delete (struct vrf *vrf)
|
||||
{
|
||||
if (BGP_DEBUG (zebra, ZEBRA))
|
||||
zlog_debug ("VRF Deletion: %s(%d)", name, vrf_id);
|
||||
zlog_debug ("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
bgp_vrf_enable (struct vrf *vrf)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct bgp *bgp;
|
||||
vrf_id_t old_vrf_id;
|
||||
|
||||
vrf = vrf_lookup (vrf_id);
|
||||
if (!vrf) // unexpected
|
||||
return -1;
|
||||
|
||||
if (BGP_DEBUG (zebra, ZEBRA))
|
||||
zlog_debug("VRF enable add %s id %d", name, vrf_id);
|
||||
zlog_debug("VRF enable add %s id %d", vrf->name, vrf->vrf_id);
|
||||
|
||||
bgp = bgp_lookup_by_name(name);
|
||||
bgp = bgp_lookup_by_name (vrf->name);
|
||||
if (bgp)
|
||||
{
|
||||
old_vrf_id = bgp->vrf_id;
|
||||
|
@ -356,23 +351,18 @@ bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
|
|||
}
|
||||
|
||||
static int
|
||||
bgp_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
bgp_vrf_disable (struct vrf *vrf)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct bgp *bgp;
|
||||
vrf_id_t old_vrf_id;
|
||||
|
||||
if (vrf_id == VRF_DEFAULT)
|
||||
if (vrf->vrf_id == VRF_DEFAULT)
|
||||
return 0;
|
||||
|
||||
vrf = vrf_lookup (vrf_id);
|
||||
if (!vrf) // unexpected
|
||||
return -1;
|
||||
|
||||
if (BGP_DEBUG (zebra, ZEBRA))
|
||||
zlog_debug("VRF disable %s id %d", name, vrf_id);
|
||||
zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
|
||||
|
||||
bgp = bgp_lookup_by_name(name);
|
||||
bgp = bgp_lookup_by_name (vrf->name);
|
||||
if (bgp)
|
||||
{
|
||||
old_vrf_id = bgp->vrf_id;
|
||||
|
|
|
@ -113,6 +113,12 @@ bgp_address_hash_alloc (void *p)
|
|||
return addr;
|
||||
}
|
||||
|
||||
static void
|
||||
bgp_address_hash_free (void *addr)
|
||||
{
|
||||
XFREE (MTYPE_BGP_ADDR, addr);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
bgp_address_hash_key_make (void *p)
|
||||
{
|
||||
|
@ -142,7 +148,7 @@ bgp_address_destroy (struct bgp *bgp)
|
|||
{
|
||||
if (bgp->address_hash == NULL)
|
||||
return;
|
||||
hash_clean(bgp->address_hash, NULL);
|
||||
hash_clean(bgp->address_hash, bgp_address_hash_free);
|
||||
hash_free(bgp->address_hash);
|
||||
bgp->address_hash = NULL;
|
||||
}
|
||||
|
@ -524,17 +530,14 @@ DEFUN (show_ip_bgp_instance_all_nexthop,
|
|||
void
|
||||
bgp_scan_init (struct bgp *bgp)
|
||||
{
|
||||
bgp->nexthop_cache_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
|
||||
bgp->connected_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
|
||||
bgp->import_check_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
|
||||
afi_t afi;
|
||||
|
||||
bgp->nexthop_cache_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
|
||||
bgp->connected_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
|
||||
bgp->import_check_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
|
||||
|
||||
bgp->nexthop_cache_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST);
|
||||
bgp->connected_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST);
|
||||
bgp->import_check_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST);
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
||||
{
|
||||
bgp->nexthop_cache_table[afi] = bgp_table_init (afi, SAFI_UNICAST);
|
||||
bgp->connected_table[afi] = bgp_table_init (afi, SAFI_UNICAST);
|
||||
bgp->import_check_table[afi] = bgp_table_init (afi, SAFI_UNICAST);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -547,29 +550,19 @@ bgp_scan_vty_init (void)
|
|||
void
|
||||
bgp_scan_finish (struct bgp *bgp)
|
||||
{
|
||||
/* Only the current one needs to be reset. */
|
||||
bgp_nexthop_cache_reset (bgp->nexthop_cache_table[AFI_IP]);
|
||||
afi_t afi;
|
||||
|
||||
bgp_table_unlock (bgp->nexthop_cache_table[AFI_IP]);
|
||||
bgp->nexthop_cache_table[AFI_IP] = NULL;
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
||||
{
|
||||
/* Only the current one needs to be reset. */
|
||||
bgp_nexthop_cache_reset (bgp->nexthop_cache_table[afi]);
|
||||
bgp_table_unlock (bgp->nexthop_cache_table[afi]);
|
||||
bgp->nexthop_cache_table[afi] = NULL;
|
||||
|
||||
bgp_table_unlock (bgp->connected_table[AFI_IP]);
|
||||
bgp->connected_table[AFI_IP] = NULL;
|
||||
bgp_table_unlock (bgp->connected_table[afi]);
|
||||
bgp->connected_table[afi] = NULL;
|
||||
|
||||
bgp_table_unlock (bgp->import_check_table[AFI_IP]);
|
||||
bgp->import_check_table[AFI_IP] = NULL;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
/* Only the current one needs to be reset. */
|
||||
bgp_nexthop_cache_reset (bgp->nexthop_cache_table[AFI_IP6]);
|
||||
|
||||
bgp_table_unlock (bgp->nexthop_cache_table[AFI_IP6]);
|
||||
bgp->nexthop_cache_table[AFI_IP6] = NULL;
|
||||
|
||||
bgp_table_unlock (bgp->connected_table[AFI_IP6]);
|
||||
bgp->connected_table[AFI_IP6] = NULL;
|
||||
|
||||
bgp_table_unlock (bgp->import_check_table[AFI_IP6]);
|
||||
bgp->import_check_table[AFI_IP6] = NULL;
|
||||
#endif /* HAVE_IPV6 */
|
||||
bgp_table_unlock (bgp->import_check_table[afi]);
|
||||
bgp->import_check_table[afi] = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,19 +115,7 @@ bgp_unlink_nexthop_by_peer (struct peer *peer)
|
|||
struct bgp_nexthop_cache *bnc;
|
||||
afi_t afi = family2afi(peer->su.sa.sa_family);
|
||||
|
||||
if (afi == AFI_IP)
|
||||
{
|
||||
p.family = AF_INET;
|
||||
p.prefixlen = IPV4_MAX_BITLEN;
|
||||
p.u.prefix4 = peer->su.sin.sin_addr;
|
||||
}
|
||||
else if (afi == AFI_IP6)
|
||||
{
|
||||
p.family = AF_INET6;
|
||||
p.prefixlen = IPV6_MAX_BITLEN;
|
||||
p.u.prefix6 = peer->su.sin6.sin6_addr;
|
||||
}
|
||||
else
|
||||
if (! sockunion2hostprefix (&peer->su, &p))
|
||||
return;
|
||||
|
||||
rn = bgp_node_get (peer->bgp->nexthop_cache_table[afi], &p);
|
||||
|
@ -168,23 +156,11 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
|
|||
}
|
||||
else if (peer)
|
||||
{
|
||||
if (afi == AFI_IP)
|
||||
{
|
||||
p.family = AF_INET;
|
||||
p.prefixlen = IPV4_MAX_BITLEN;
|
||||
p.u.prefix4 = peer->su.sin.sin_addr;
|
||||
}
|
||||
else if (afi == AFI_IP6)
|
||||
{
|
||||
p.family = AF_INET6;
|
||||
p.prefixlen = IPV6_MAX_BITLEN;
|
||||
p.u.prefix6 = peer->su.sin6.sin6_addr;
|
||||
/* Don't register link local NH */
|
||||
if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&peer->su.sin6.sin6_addr))
|
||||
return 1;
|
||||
|
||||
/* Don't register link local NH */
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
if (! sockunion2hostprefix (&peer->su, &p))
|
||||
{
|
||||
if (BGP_DEBUG(nht, NHT))
|
||||
{
|
||||
|
@ -297,23 +273,11 @@ bgp_delete_connected_nexthop (afi_t afi, struct peer *peer)
|
|||
if (!peer)
|
||||
return;
|
||||
|
||||
if (afi == AFI_IP)
|
||||
{
|
||||
p.family = AF_INET;
|
||||
p.prefixlen = IPV4_MAX_BITLEN;
|
||||
p.u.prefix4 = peer->su.sin.sin_addr;
|
||||
}
|
||||
else if (afi == AFI_IP6)
|
||||
{
|
||||
p.family = AF_INET6;
|
||||
p.prefixlen = IPV6_MAX_BITLEN;
|
||||
p.u.prefix6 = peer->su.sin6.sin6_addr;
|
||||
/* We don't register link local address for NHT */
|
||||
if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&peer->su.sin6.sin6_addr))
|
||||
return;
|
||||
|
||||
/* We don't register link local address for NHT */
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
|
||||
return;
|
||||
}
|
||||
else
|
||||
if (! sockunion2hostprefix (&peer->su, &p))
|
||||
return;
|
||||
|
||||
rn = bgp_node_lookup(peer->bgp->nexthop_cache_table[family2afi(p.family)], &p);
|
||||
|
|
100
bgpd/bgp_route.c
100
bgpd/bgp_route.c
|
@ -3121,7 +3121,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
|
|||
struct bgp_table *table)
|
||||
{
|
||||
struct bgp_node *rn;
|
||||
|
||||
int force = bm->process_main_queue ? 0 : 1;
|
||||
|
||||
if (! table)
|
||||
table = peer->bgp->rib[afi][safi];
|
||||
|
@ -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))
|
||||
{
|
||||
struct bgp_info *ri;
|
||||
struct bgp_info *ri, *next;
|
||||
struct bgp_adj_in *ain;
|
||||
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;
|
||||
}
|
||||
|
||||
for (ri = rn->info; ri; ri = ri->next)
|
||||
if (ri->peer == peer)
|
||||
{
|
||||
struct bgp_clear_node_queue *cnq;
|
||||
for (ri = rn->info; ri; ri = next)
|
||||
{
|
||||
next = ri->next;
|
||||
if (ri->peer != peer)
|
||||
continue;
|
||||
|
||||
/* both unlocked in bgp_clear_node_queue_del */
|
||||
bgp_table_lock (bgp_node_table (rn));
|
||||
bgp_lock_node (rn);
|
||||
cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE,
|
||||
sizeof (struct bgp_clear_node_queue));
|
||||
cnq->rn = rn;
|
||||
work_queue_add (peer->clear_node_queue, cnq);
|
||||
break;
|
||||
}
|
||||
if (force)
|
||||
bgp_info_reap (rn, ri);
|
||||
else
|
||||
{
|
||||
struct bgp_clear_node_queue *cnq;
|
||||
|
||||
/* both unlocked in bgp_clear_node_queue_del */
|
||||
bgp_table_lock (bgp_node_table (rn));
|
||||
bgp_lock_node (rn);
|
||||
cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE,
|
||||
sizeof (struct bgp_clear_node_queue));
|
||||
cnq->rn = rn;
|
||||
work_queue_add (peer->clear_node_queue, cnq);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -3333,52 +3341,48 @@ bgp_cleanup_table(struct bgp_table *table, safi_t safi)
|
|||
if (table->owner && table->owner->bgp)
|
||||
vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri);
|
||||
#endif
|
||||
bgp_zebra_withdraw (&rn->p, ri, safi);
|
||||
bgp_zebra_withdraw (&rn->p, ri, safi);
|
||||
bgp_info_reap (rn, ri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete all kernel routes. */
|
||||
void
|
||||
bgp_cleanup_routes (void)
|
||||
bgp_cleanup_routes (struct bgp *bgp)
|
||||
{
|
||||
struct bgp *bgp;
|
||||
struct listnode *node, *nnode;
|
||||
afi_t afi;
|
||||
|
||||
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
|
||||
for (afi = AFI_IP; afi < AFI_MAX; ++afi)
|
||||
{
|
||||
for (afi = AFI_IP; afi < AFI_MAX; ++afi)
|
||||
struct bgp_node *rn;
|
||||
|
||||
bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST);
|
||||
|
||||
/*
|
||||
* VPN and ENCAP tables are two-level (RD is top level)
|
||||
*/
|
||||
for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn;
|
||||
rn = bgp_route_next (rn))
|
||||
{
|
||||
struct bgp_node *rn;
|
||||
|
||||
bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST);
|
||||
|
||||
/*
|
||||
* VPN and ENCAP tables are two-level (RD is top level)
|
||||
*/
|
||||
for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn;
|
||||
rn = bgp_route_next (rn))
|
||||
if (rn->info)
|
||||
{
|
||||
if (rn->info)
|
||||
{
|
||||
bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_MPLS_VPN);
|
||||
bgp_table_finish ((struct bgp_table **)&(rn->info));
|
||||
rn->info = NULL;
|
||||
bgp_unlock_node(rn);
|
||||
}
|
||||
bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_MPLS_VPN);
|
||||
bgp_table_finish ((struct bgp_table **)&(rn->info));
|
||||
rn->info = NULL;
|
||||
bgp_unlock_node(rn);
|
||||
}
|
||||
}
|
||||
|
||||
for (rn = bgp_table_top(bgp->rib[afi][SAFI_ENCAP]); rn;
|
||||
rn = bgp_route_next (rn))
|
||||
for (rn = bgp_table_top(bgp->rib[afi][SAFI_ENCAP]); rn;
|
||||
rn = bgp_route_next (rn))
|
||||
{
|
||||
if (rn->info)
|
||||
{
|
||||
if (rn->info)
|
||||
{
|
||||
bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_ENCAP);
|
||||
bgp_table_finish ((struct bgp_table **)&(rn->info));
|
||||
rn->info = NULL;
|
||||
bgp_unlock_node(rn);
|
||||
}
|
||||
bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_ENCAP);
|
||||
bgp_table_finish ((struct bgp_table **)&(rn->info));
|
||||
rn->info = NULL;
|
||||
bgp_unlock_node(rn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6073,7 +6077,7 @@ route_vty_out (struct vty *vty, struct prefix *p,
|
|||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
#if ENABLE_BGP_VNC
|
||||
/* 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);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -241,7 +241,7 @@ bgp_bump_version (struct bgp_node *node)
|
|||
extern void bgp_process_queue_init (void);
|
||||
extern void bgp_route_init (void);
|
||||
extern void bgp_route_finish (void);
|
||||
extern void bgp_cleanup_routes (void);
|
||||
extern void bgp_cleanup_routes (struct bgp *);
|
||||
extern void bgp_announce_route (struct peer *, afi_t, safi_t);
|
||||
extern void bgp_stop_announce_route_timer(struct peer_af *paf);
|
||||
extern void bgp_announce_route_all (struct peer *);
|
||||
|
|
|
@ -573,8 +573,8 @@ subgroup_clear_table (struct update_subgroup *subgrp)
|
|||
|
||||
SUBGRP_FOREACH_ADJ_SAFE (subgrp, aout, taout)
|
||||
{
|
||||
bgp_unlock_node (aout->rn);
|
||||
bgp_adj_out_remove_subgroup (aout->rn, aout, subgrp);
|
||||
bgp_unlock_node (aout->rn);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11421,6 +11421,7 @@ community_list_vty (void)
|
|||
|
||||
/* Community-list. */
|
||||
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_expanded_all_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_community_list_cmd);
|
||||
|
|
|
@ -1792,6 +1792,7 @@ bgp_redist_del (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
|
|||
if (red)
|
||||
{
|
||||
listnode_delete(bgp->redist[afi][type], red);
|
||||
XFREE (MTYPE_BGP_REDIST, red);
|
||||
if (!bgp->redist[afi][type]->count)
|
||||
{
|
||||
list_free(bgp->redist[afi][type]);
|
||||
|
|
29
bgpd/bgpd.c
29
bgpd/bgpd.c
|
@ -1044,6 +1044,12 @@ peer_free (struct peer *peer)
|
|||
peer->host = NULL;
|
||||
}
|
||||
|
||||
if (peer->domainname)
|
||||
{
|
||||
XFREE (MTYPE_BGP_PEER_HOST, peer->domainname);
|
||||
peer->domainname = NULL;
|
||||
}
|
||||
|
||||
if (peer->ifname)
|
||||
{
|
||||
XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
|
||||
|
@ -1972,7 +1978,8 @@ peer_delete (struct peer *peer)
|
|||
bgp_fsm_change_status (peer, Deleted);
|
||||
|
||||
/* 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 */
|
||||
if (peer->password)
|
||||
|
@ -2964,7 +2971,7 @@ bgp_lookup_by_vrf_id (vrf_id_t vrf_id)
|
|||
struct vrf *vrf;
|
||||
|
||||
/* Lookup VRF (in tree) and follow link. */
|
||||
vrf = vrf_lookup (vrf_id);
|
||||
vrf = vrf_lookup_by_id (vrf_id);
|
||||
if (!vrf)
|
||||
return NULL;
|
||||
return (vrf->info) ? (struct bgp *)vrf->info : NULL;
|
||||
|
@ -3122,6 +3129,7 @@ bgp_delete (struct bgp *bgp)
|
|||
struct peer *peer;
|
||||
struct peer_group *group;
|
||||
struct listnode *node, *next;
|
||||
struct vrf *vrf;
|
||||
afi_t afi;
|
||||
int i;
|
||||
|
||||
|
@ -3178,15 +3186,13 @@ bgp_delete (struct bgp *bgp)
|
|||
|
||||
#if ENABLE_BGP_VNC
|
||||
rfapi_delete(bgp);
|
||||
bgp_cleanup_routes(); /* rfapi cleanup can create route entries! */
|
||||
#endif
|
||||
bgp_cleanup_routes(bgp);
|
||||
|
||||
/* Remove visibility via the master list - there may however still be
|
||||
* routes to be processed still referencing the struct bgp.
|
||||
*/
|
||||
listnode_delete (bm->bgp, bgp);
|
||||
if (list_isempty(bm->bgp))
|
||||
bgp_close ();
|
||||
|
||||
/* Deregister from Zebra, if needed */
|
||||
if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
|
||||
|
@ -3195,6 +3201,10 @@ bgp_delete (struct bgp *bgp)
|
|||
/* Free interfaces in this instance. */
|
||||
bgp_if_finish (bgp);
|
||||
|
||||
vrf = bgp_vrf_lookup_by_instance_type (bgp);
|
||||
if (vrf)
|
||||
bgp_vrf_unlink (bgp, vrf);
|
||||
|
||||
thread_master_free_unused(bm->master);
|
||||
bgp_unlock(bgp); /* initial reference */
|
||||
|
||||
|
@ -3222,7 +3232,6 @@ bgp_free (struct bgp *bgp)
|
|||
{
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
struct vrf *vrf;
|
||||
|
||||
list_delete (bgp->group);
|
||||
list_delete (bgp->peer);
|
||||
|
@ -3244,13 +3253,9 @@ bgp_free (struct bgp *bgp)
|
|||
bgp_table_finish (&bgp->rib[afi][safi]);
|
||||
}
|
||||
|
||||
bgp_scan_finish (bgp);
|
||||
bgp_address_destroy (bgp);
|
||||
|
||||
/* If Default instance or VRF, unlink from the VRF structure. */
|
||||
vrf = bgp_vrf_lookup_by_instance_type (bgp);
|
||||
if (vrf)
|
||||
bgp_vrf_unlink (bgp, vrf);
|
||||
|
||||
if (bgp->name)
|
||||
XFREE(MTYPE_BGP, bgp->name);
|
||||
|
||||
|
@ -7596,8 +7601,6 @@ bgp_terminate (void)
|
|||
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
|
||||
BGP_NOTIFY_CEASE_PEER_UNCONFIG);
|
||||
|
||||
bgp_cleanup_routes ();
|
||||
|
||||
if (bm->process_main_queue)
|
||||
{
|
||||
work_queue_free (bm->process_main_queue);
|
||||
|
|
|
@ -1490,7 +1490,7 @@ bgp_vrf_lookup_by_instance_type (struct bgp *bgp)
|
|||
struct vrf *vrf;
|
||||
|
||||
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
|
||||
vrf = vrf_lookup (VRF_DEFAULT);
|
||||
vrf = vrf_lookup_by_id (VRF_DEFAULT);
|
||||
else if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
|
||||
vrf = vrf_lookup_by_name (bgp->name);
|
||||
else
|
||||
|
|
|
@ -421,15 +421,7 @@ sock_set_ipv4_mcast(struct iface *iface)
|
|||
int
|
||||
sock_set_ipv4_mcast_loop(int fd)
|
||||
{
|
||||
uint8_t loop = 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);
|
||||
return (setsockopt_ipv4_multicast_loop(fd, 0));
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -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,
|
||||
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>]",
|
||||
|
@ -2483,4 +2468,6 @@ cmd_terminate ()
|
|||
XFREE (MTYPE_HOST, host.motdfile);
|
||||
if (host.config)
|
||||
XFREE (MTYPE_HOST, host.config);
|
||||
|
||||
qobj_finish ();
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "command_match.h"
|
||||
#include "memory.h"
|
||||
|
||||
|
||||
#ifdef TRACE_MATCHER
|
||||
#define TM 1
|
||||
#else
|
||||
|
@ -37,8 +36,6 @@
|
|||
#define trace_matcher(...) \
|
||||
do { if (TM) fprintf (stderr, __VA_ARGS__); } while (0);
|
||||
|
||||
DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens")
|
||||
|
||||
/* matcher helper prototypes */
|
||||
static int
|
||||
add_nexthops (struct list *, struct graph_node *);
|
||||
|
@ -125,12 +122,28 @@ command_match (struct graph *cmdgraph,
|
|||
assert (*el);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (!*el) {
|
||||
trace_matcher ("No match\n");
|
||||
}
|
||||
else {
|
||||
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
|
||||
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
|
||||
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);
|
||||
trace_matcher ("min: %d - ", minmatch);
|
||||
fprintf (stdout, "min: %d - ", minmatch);
|
||||
switch (mt)
|
||||
{
|
||||
case trivial_match:
|
||||
trace_matcher ("trivial_match ");
|
||||
fprintf (stdout, "trivial_match ");
|
||||
break;
|
||||
case no_match:
|
||||
trace_matcher ("no_match ");
|
||||
fprintf (stdout, "no_match ");
|
||||
break;
|
||||
case partly_match:
|
||||
trace_matcher ("partly_match ");
|
||||
fprintf (stdout, "partly_match ");
|
||||
break;
|
||||
case exact_match:
|
||||
trace_matcher ("exact_match ");
|
||||
fprintf (stdout, "exact_match ");
|
||||
break;
|
||||
}
|
||||
if (mt >= minmatch) { trace_matcher (" MATCH") };
|
||||
trace_matcher ("\n");
|
||||
if (mt >= minmatch) fprintf (stdout, " MATCH");
|
||||
fprintf (stdout, "\n");
|
||||
#endif
|
||||
|
||||
// if we don't match this node, die
|
||||
if (match_token (token, input_token) < minmatch)
|
||||
|
@ -359,8 +374,16 @@ command_complete (struct graph *graph,
|
|||
continue;
|
||||
|
||||
enum match_type minmatch = min_match_level (token->type);
|
||||
<<<<<<< HEAD
|
||||
trace_matcher ("\"%s\" matches \"%s\" (%d) ? ",
|
||||
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);
|
||||
enum match_type matchtype = match_token (token, input_token);
|
||||
|
@ -368,23 +391,73 @@ command_complete (struct graph *graph,
|
|||
{
|
||||
// occurs when last token is whitespace
|
||||
case trivial_match:
|
||||
<<<<<<< HEAD
|
||||
trace_matcher ("trivial_match\n");
|
||||
assert(last_token);
|
||||
listnode_add (next, gn);
|
||||
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:
|
||||
<<<<<<< HEAD
|
||||
trace_matcher ("trivial_match\n");
|
||||
if (exact_match_exists && !last_token)
|
||||
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:
|
||||
<<<<<<< HEAD
|
||||
trace_matcher ("exact_match\n");
|
||||
if (last_token)
|
||||
listnode_add (next, gn);
|
||||
else if (matchtype >= minmatch)
|
||||
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;
|
||||
default:
|
||||
trace_matcher ("no_match\n");
|
||||
#ifdef TRACE_MATCHER
|
||||
fprintf (stdout, "no_match\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
121
lib/if.c
121
lib/if.c
|
@ -307,13 +307,11 @@ if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id)
|
|||
struct interface *
|
||||
if_lookup_by_name_all_vrf (const char *name)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct interface *ifp;
|
||||
struct vrf *vrf = NULL;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
{
|
||||
vrf = vrf_iter2vrf (iter);
|
||||
ifp = if_lookup_by_name_vrf (name, vrf->vrf_id);
|
||||
if (ifp)
|
||||
return ifp;
|
||||
|
@ -392,7 +390,7 @@ if_lookup_exact_address (void *src, int family)
|
|||
}
|
||||
|
||||
/* Lookup interface by IPv4 address. */
|
||||
struct interface *
|
||||
struct connected *
|
||||
if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
|
||||
{
|
||||
struct listnode *node;
|
||||
|
@ -401,7 +399,7 @@ if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
|
|||
struct listnode *cnode;
|
||||
struct interface *ifp;
|
||||
struct connected *c;
|
||||
struct interface *match;
|
||||
struct connected *match;
|
||||
|
||||
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))
|
||||
{
|
||||
bestlen = c->address->prefixlen;
|
||||
match = ifp;
|
||||
match = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
struct interface *
|
||||
struct connected *
|
||||
if_lookup_address (void *matchaddr, int family)
|
||||
{
|
||||
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)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct vrf *vrf;
|
||||
struct listnode *node;
|
||||
struct vrf *vrf = NULL;
|
||||
vrf_iter_t iter;
|
||||
|
||||
ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id);
|
||||
if (ifp)
|
||||
return ifp;
|
||||
|
||||
/* Didn't find the interface on that vrf. Defined on a different one? */
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
{
|
||||
vrf = vrf_iter2vrf(iter);
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf->vrf_id), node, ifp))
|
||||
{
|
||||
if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
|
||||
|
@ -665,14 +661,13 @@ if_dump (const struct interface *ifp)
|
|||
void
|
||||
if_dump_all (void)
|
||||
{
|
||||
struct list *intf_list;
|
||||
struct vrf *vrf;
|
||||
struct listnode *node;
|
||||
void *p;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if ((intf_list = vrf_iter2iflist (iter)) != NULL)
|
||||
for (ALL_LIST_ELEMENTS_RO (intf_list, node, p))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
if (vrf->iflist != NULL)
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, p))
|
||||
if_dump (p);
|
||||
}
|
||||
|
||||
|
@ -843,72 +838,7 @@ if_cmd_init (void)
|
|||
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
|
||||
}
|
||||
|
||||
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_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);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* For debug purpose. */
|
||||
DEFUN (show_address,
|
||||
show_address_cmd,
|
||||
|
@ -949,24 +879,22 @@ DEFUN (show_address_vrf_all,
|
|||
"address\n"
|
||||
VRF_ALL_CMD_HELP_STR)
|
||||
{
|
||||
struct list *intf_list;
|
||||
struct vrf *vrf;
|
||||
struct listnode *node;
|
||||
struct listnode *node2;
|
||||
struct interface *ifp;
|
||||
struct connected *ifc;
|
||||
struct prefix *p;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
intf_list = vrf_iter2iflist (iter);
|
||||
if (!intf_list || !listcount (intf_list))
|
||||
if (!vrf->iflist || !listcount (vrf->iflist))
|
||||
continue;
|
||||
|
||||
vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf_iter2id (iter),
|
||||
VTY_NEWLINE, VTY_NEWLINE);
|
||||
vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id, VTY_NEWLINE,
|
||||
VTY_NEWLINE);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (intf_list, node, ifp))
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
|
||||
{
|
||||
for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
|
||||
{
|
||||
|
@ -980,6 +908,7 @@ DEFUN (show_address_vrf_all,
|
|||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate connected structure. */
|
||||
struct connected *
|
||||
|
@ -1377,14 +1306,14 @@ if_link_params_get (struct interface *ifp)
|
|||
iflp->te_metric = ifp->metric;
|
||||
|
||||
/* Compute default bandwidth based on interface */
|
||||
int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
|
||||
* TE_KILO_BIT / TE_BYTE);
|
||||
iflp->default_bw = ((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
|
||||
* TE_KILO_BIT / TE_BYTE);
|
||||
|
||||
/* Set Max, Reservable and Unreserved Bandwidth */
|
||||
iflp->max_bw = bw;
|
||||
iflp->max_rsv_bw = bw;
|
||||
iflp->max_bw = iflp->default_bw;
|
||||
iflp->max_rsv_bw = iflp->default_bw;
|
||||
for (i = 0; i < MAX_CLASS_TYPE; i++)
|
||||
iflp->unrsv_bw[i] = bw;
|
||||
iflp->unrsv_bw[i] = iflp->default_bw;
|
||||
|
||||
/* Update Link parameters status */
|
||||
iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
|
||||
|
|
8
lib/if.h
8
lib/if.h
|
@ -161,6 +161,7 @@ struct if_stats
|
|||
#define LP_RES_BW 0x0400
|
||||
#define LP_AVA_BW 0x0800
|
||||
#define LP_USE_BW 0x1000
|
||||
#define LP_TE_METRIC 0x2000
|
||||
|
||||
#define IS_PARAM_UNSET(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 {
|
||||
u_int32_t lp_status; /* Status of Link Parameters: */
|
||||
u_int32_t te_metric; /* Traffic Engineering metric */
|
||||
float default_bw;
|
||||
float max_bw; /* Maximum Bandwidth */
|
||||
float max_rsv_bw; /* Maximum Reservable Bandwidth */
|
||||
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_lookup_by_index (ifindex_t);
|
||||
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 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_exact_address_vrf (void *matchaddr, int family,
|
||||
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);
|
||||
extern struct interface *if_lookup_prefix_vrf (struct prefix *prefix,
|
||||
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_link_type_str (enum zebra_link_type);
|
||||
|
||||
extern void vrf_cmd_init (void);
|
||||
|
||||
/* Please use ifindex2ifname instead of if_indextoname where possible;
|
||||
ifindex2ifname uses internal interface info, whereas if_indextoname must
|
||||
make a system call. */
|
||||
|
|
309
lib/ns.c
309
lib/ns.c
|
@ -31,8 +31,6 @@
|
|||
|
||||
#include "if.h"
|
||||
#include "ns.h"
|
||||
#include "prefix.h"
|
||||
#include "table.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
|
||||
|
@ -41,7 +39,13 @@
|
|||
|
||||
DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router")
|
||||
DEFINE_MTYPE_STATIC(LIB, NS_NAME, "Logical-Router Name")
|
||||
DEFINE_MTYPE_STATIC(LIB, NS_BITMAP, "Logical-Router bit-map")
|
||||
|
||||
static __inline int ns_compare (struct ns *, struct ns *);
|
||||
static struct ns *ns_lookup (ns_id_t);
|
||||
|
||||
RB_GENERATE (ns_head, ns, entry, ns_compare)
|
||||
|
||||
struct ns_head ns_tree = RB_INITIALIZER (&ns_tree);
|
||||
|
||||
#ifndef CLONE_NEWNET
|
||||
#define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */
|
||||
|
@ -91,22 +95,6 @@ static int have_netns(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
struct ns
|
||||
{
|
||||
/* Identifier, same as the vector index */
|
||||
ns_id_t ns_id;
|
||||
/* Name */
|
||||
char *name;
|
||||
/* File descriptor */
|
||||
int fd;
|
||||
|
||||
/* Master list of interfaces belonging to this NS */
|
||||
struct list *iflist;
|
||||
|
||||
/* User data */
|
||||
void *info;
|
||||
};
|
||||
|
||||
/* Holding NS hooks */
|
||||
struct ns_master
|
||||
{
|
||||
|
@ -116,44 +104,30 @@ struct ns_master
|
|||
int (*ns_disable_hook) (ns_id_t, void **);
|
||||
} ns_master = {0,};
|
||||
|
||||
/* NS table */
|
||||
struct route_table *ns_table = NULL;
|
||||
|
||||
static int ns_is_enabled (struct ns *ns);
|
||||
static int ns_enable (struct ns *ns);
|
||||
static void ns_disable (struct ns *ns);
|
||||
|
||||
|
||||
/* Build the table key */
|
||||
static void
|
||||
ns_build_key (ns_id_t ns_id, struct prefix *p)
|
||||
static __inline int
|
||||
ns_compare(struct ns *a, struct ns *b)
|
||||
{
|
||||
p->family = AF_INET;
|
||||
p->prefixlen = IPV4_MAX_BITLEN;
|
||||
p->u.prefix4.s_addr = ns_id;
|
||||
return (a->ns_id - b->ns_id);
|
||||
}
|
||||
|
||||
/* Get a NS. If not found, create one. */
|
||||
static struct ns *
|
||||
ns_get (ns_id_t ns_id)
|
||||
{
|
||||
struct prefix p;
|
||||
struct route_node *rn;
|
||||
struct ns *ns;
|
||||
|
||||
ns_build_key (ns_id, &p);
|
||||
rn = route_node_get (ns_table, &p);
|
||||
if (rn->info)
|
||||
{
|
||||
ns = (struct ns *)rn->info;
|
||||
route_unlock_node (rn); /* get */
|
||||
return ns;
|
||||
}
|
||||
ns = ns_lookup (ns_id);
|
||||
if (ns)
|
||||
return (ns);
|
||||
|
||||
ns = XCALLOC (MTYPE_NS, sizeof (struct ns));
|
||||
ns->ns_id = ns_id;
|
||||
ns->fd = -1;
|
||||
rn->info = ns;
|
||||
RB_INSERT (ns_head, &ns_tree, ns);
|
||||
|
||||
/*
|
||||
* Initialize interfaces.
|
||||
|
@ -188,6 +162,7 @@ ns_delete (struct ns *ns)
|
|||
*/
|
||||
//if_terminate (&ns->iflist);
|
||||
|
||||
RB_REMOVE (ns_head, &ns_tree, ns);
|
||||
if (ns->name)
|
||||
XFREE (MTYPE_NS_NAME, ns->name);
|
||||
|
||||
|
@ -198,18 +173,9 @@ ns_delete (struct ns *ns)
|
|||
static struct ns *
|
||||
ns_lookup (ns_id_t ns_id)
|
||||
{
|
||||
struct prefix p;
|
||||
struct route_node *rn;
|
||||
struct ns *ns = NULL;
|
||||
|
||||
ns_build_key (ns_id, &p);
|
||||
rn = route_node_lookup (ns_table, &p);
|
||||
if (rn)
|
||||
{
|
||||
ns = (struct ns *)rn->info;
|
||||
route_unlock_node (rn); /* lookup */
|
||||
}
|
||||
return ns;
|
||||
struct ns ns;
|
||||
ns.ns_id = ns_id;
|
||||
return (RB_FIND (ns_head, &ns_tree, &ns));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -310,217 +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
|
||||
*/
|
||||
|
@ -645,17 +400,17 @@ static struct cmd_node ns_node =
|
|||
static int
|
||||
ns_config_write (struct vty *vty)
|
||||
{
|
||||
struct route_node *rn;
|
||||
struct ns *ns;
|
||||
int write = 0;
|
||||
|
||||
for (rn = route_top (ns_table); rn; rn = route_next (rn))
|
||||
if ((ns = rn->info) != NULL &&
|
||||
ns->ns_id != NS_DEFAULT && ns->name)
|
||||
{
|
||||
vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name, VTY_NEWLINE);
|
||||
write++;
|
||||
}
|
||||
RB_FOREACH (ns, ns_head, &ns_tree) {
|
||||
if (ns->ns_id == NS_DEFAULT || ns->name == NULL)
|
||||
continue;
|
||||
|
||||
vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name,
|
||||
VTY_NEWLINE);
|
||||
write = 1;
|
||||
}
|
||||
|
||||
return write;
|
||||
}
|
||||
|
@ -666,9 +421,6 @@ ns_init (void)
|
|||
{
|
||||
struct ns *default_ns;
|
||||
|
||||
/* Allocate NS table. */
|
||||
ns_table = route_table_init ();
|
||||
|
||||
/* The default NS always exists. */
|
||||
default_ns = ns_get (NS_DEFAULT);
|
||||
if (!default_ns)
|
||||
|
@ -700,15 +452,10 @@ ns_init (void)
|
|||
void
|
||||
ns_terminate (void)
|
||||
{
|
||||
struct route_node *rn;
|
||||
struct ns *ns;
|
||||
|
||||
for (rn = route_top (ns_table); rn; rn = route_next (rn))
|
||||
if ((ns = rn->info) != NULL)
|
||||
ns_delete (ns);
|
||||
|
||||
route_table_finish (ns_table);
|
||||
ns_table = NULL;
|
||||
while ((ns = RB_ROOT (&ns_tree)) != NULL)
|
||||
ns_delete (ns);
|
||||
}
|
||||
|
||||
/* Create a socket for the NS. */
|
||||
|
|
97
lib/ns.h
97
lib/ns.h
|
@ -23,6 +23,7 @@
|
|||
#ifndef _ZEBRA_NS_H
|
||||
#define _ZEBRA_NS_H
|
||||
|
||||
#include "openbsd-tree.h"
|
||||
#include "linklist.h"
|
||||
|
||||
typedef u_int16_t ns_id_t;
|
||||
|
@ -30,15 +31,32 @@ typedef u_int16_t ns_id_t;
|
|||
/* The default NS ID */
|
||||
#define NS_DEFAULT 0
|
||||
|
||||
/*
|
||||
* The command strings
|
||||
*/
|
||||
/* Default netns directory (Linux) */
|
||||
#define NS_RUN_DIR "/var/run/netns"
|
||||
#define NS_CMD_STR "logical-router <0-65535>"
|
||||
#define NS_CMD_HELP_STR "Specify the Logical-Router\nThe Logical-Router ID\n"
|
||||
|
||||
#define NS_ALL_CMD_STR "logical-router all"
|
||||
#define NS_ALL_CMD_HELP_STR "Specify the logical-router\nAll logical-router's\n"
|
||||
struct ns
|
||||
{
|
||||
RB_ENTRY(ns) entry;
|
||||
|
||||
/* Identifier, same as the vector index */
|
||||
ns_id_t ns_id;
|
||||
|
||||
/* Name */
|
||||
char *name;
|
||||
|
||||
/* File descriptor */
|
||||
int fd;
|
||||
|
||||
/* Master list of interfaces belonging to this NS */
|
||||
struct list *iflist;
|
||||
|
||||
/* User data */
|
||||
void *info;
|
||||
};
|
||||
RB_HEAD (ns_head, ns);
|
||||
RB_PROTOTYPE (ns_head, ns, entry, ns_compare)
|
||||
|
||||
extern struct ns_head ns_tree;
|
||||
|
||||
/*
|
||||
* NS hooks
|
||||
|
@ -59,71 +77,6 @@ typedef u_int16_t ns_id_t;
|
|||
*/
|
||||
extern void ns_add_hook (int, int (*)(ns_id_t, void **));
|
||||
|
||||
/*
|
||||
* NS iteration
|
||||
*/
|
||||
|
||||
typedef void * ns_iter_t;
|
||||
#define NS_ITER_INVALID NULL /* invalid value of the iterator */
|
||||
|
||||
/*
|
||||
* NS iteration utilities. Example for the usage:
|
||||
*
|
||||
* ns_iter_t iter = ns_first();
|
||||
* for (; iter != NS_ITER_INVALID; iter = ns_next (iter))
|
||||
*
|
||||
* or
|
||||
*
|
||||
* ns_iter_t iter = ns_iterator (<a given NS ID>);
|
||||
* for (; iter != NS_ITER_INVALID; iter = ns_next (iter))
|
||||
*/
|
||||
|
||||
/* Return the iterator of the first NS. */
|
||||
extern ns_iter_t ns_first (void);
|
||||
/* Return the next NS iterator to the given iterator. */
|
||||
extern ns_iter_t ns_next (ns_iter_t);
|
||||
/* Return the NS iterator of the given NS ID. If it does not exist,
|
||||
* the iterator of the next existing NS is returned. */
|
||||
extern ns_iter_t ns_iterator (ns_id_t);
|
||||
|
||||
/*
|
||||
* NS iterator to properties
|
||||
*/
|
||||
extern ns_id_t ns_iter2id (ns_iter_t);
|
||||
extern void *ns_iter2info (ns_iter_t);
|
||||
extern struct list *ns_iter2iflist (ns_iter_t);
|
||||
|
||||
/*
|
||||
* Utilities to obtain the user data
|
||||
*/
|
||||
|
||||
/* Get the data pointer of the specified NS. If not found, create one. */
|
||||
extern void *ns_info_get (ns_id_t);
|
||||
/* Look up the data pointer of the specified NS. */
|
||||
extern void *ns_info_lookup (ns_id_t);
|
||||
|
||||
/*
|
||||
* Utilities to obtain the interface list
|
||||
*/
|
||||
|
||||
/* Look up the interface list of the specified NS. */
|
||||
extern struct list *ns_iflist (ns_id_t);
|
||||
/* Get the interface list of the specified NS. Create one if not find. */
|
||||
extern struct list *ns_iflist_get (ns_id_t);
|
||||
|
||||
/*
|
||||
* NS bit-map: maintaining flags, one bit per NS ID
|
||||
*/
|
||||
|
||||
typedef void * ns_bitmap_t;
|
||||
#define NS_BITMAP_NULL NULL
|
||||
|
||||
extern ns_bitmap_t ns_bitmap_init (void);
|
||||
extern void ns_bitmap_free (ns_bitmap_t);
|
||||
extern void ns_bitmap_set (ns_bitmap_t, ns_id_t);
|
||||
extern void ns_bitmap_unset (ns_bitmap_t, ns_id_t);
|
||||
extern int ns_bitmap_check (ns_bitmap_t, ns_id_t);
|
||||
|
||||
/*
|
||||
* NS initializer/destructor
|
||||
*/
|
||||
|
|
|
@ -78,6 +78,7 @@ void qobj_init (void)
|
|||
|
||||
void qobj_finish (void)
|
||||
{
|
||||
hash_clean (nodes, NULL);
|
||||
hash_free (nodes);
|
||||
nodes = NULL;
|
||||
}
|
||||
|
|
|
@ -384,7 +384,20 @@ setsockopt_ipv4_multicast_if(int sock, struct in_addr if_addr,
|
|||
#error "Unsupported multicast API"
|
||||
#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
|
||||
setsockopt_ipv4_ifindex (int sock, ifindex_t val)
|
||||
{
|
||||
|
|
|
@ -89,6 +89,8 @@ extern int setsockopt_ipv4_multicast(int sock, int optname,
|
|||
struct in_addr if_addr,
|
||||
unsigned int mcast_addr,
|
||||
ifindex_t ifindex);
|
||||
extern int setsockopt_ipv4_multicast_loop (int sock, u_char val);
|
||||
|
||||
extern int setsockopt_ipv4_tos(int sock, int tos);
|
||||
|
||||
/* Ask for, and get, ifindex, by whatever method is supported. */
|
||||
|
|
|
@ -494,7 +494,7 @@ route_table_count (const struct route_table *table)
|
|||
*
|
||||
* Default function for creating a route node.
|
||||
*/
|
||||
static struct route_node *
|
||||
struct route_node *
|
||||
route_node_create (route_table_delegate_t *delegate,
|
||||
struct route_table *table)
|
||||
{
|
||||
|
@ -508,7 +508,7 @@ route_node_create (route_table_delegate_t *delegate,
|
|||
*
|
||||
* Default function for destroying a route node.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
route_node_destroy (route_table_delegate_t *delegate,
|
||||
struct route_table *table, struct route_node *node)
|
||||
{
|
||||
|
|
|
@ -169,6 +169,11 @@ extern struct route_node *route_node_match_ipv6 (const struct route_table *,
|
|||
|
||||
extern unsigned long route_table_count (const struct route_table *);
|
||||
|
||||
extern struct route_node *route_node_create (route_table_delegate_t *,
|
||||
struct route_table *);
|
||||
extern void route_node_destroy (route_table_delegate_t *,
|
||||
struct route_table *, struct route_node *);
|
||||
|
||||
extern struct route_node *
|
||||
route_table_get_next (const struct route_table *table, struct prefix *p);
|
||||
extern int
|
||||
|
|
529
lib/vrf.c
529
lib/vrf.c
|
@ -35,6 +35,15 @@ DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
|
|||
|
||||
DEFINE_QOBJ_TYPE(vrf)
|
||||
|
||||
static __inline int vrf_id_compare (struct vrf *, struct vrf *);
|
||||
static __inline int vrf_name_compare (struct vrf *, struct vrf *);
|
||||
|
||||
RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare)
|
||||
RB_GENERATE (vrf_name_head, vrf, name_entry, vrf_name_compare)
|
||||
|
||||
struct vrf_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id);
|
||||
struct vrf_name_head vrfs_by_name = RB_INITIALIZER (&vrfs_by_name);
|
||||
|
||||
/*
|
||||
* Turn on/off debug code
|
||||
* for vrf.
|
||||
|
@ -44,44 +53,34 @@ int debug_vrf = 0;
|
|||
/* Holding VRF hooks */
|
||||
struct vrf_master
|
||||
{
|
||||
int (*vrf_new_hook) (vrf_id_t, const char *, void **);
|
||||
int (*vrf_delete_hook) (vrf_id_t, const char *, void **);
|
||||
int (*vrf_enable_hook) (vrf_id_t, const char *, void **);
|
||||
int (*vrf_disable_hook) (vrf_id_t, const char *, void **);
|
||||
int (*vrf_new_hook) (struct vrf *);
|
||||
int (*vrf_delete_hook) (struct vrf *);
|
||||
int (*vrf_enable_hook) (struct vrf *);
|
||||
int (*vrf_disable_hook) (struct vrf *);
|
||||
} vrf_master = {0,};
|
||||
|
||||
/* VRF table */
|
||||
struct route_table *vrf_table = NULL;
|
||||
|
||||
/* VRF is part of a list too to store it before its actually active */
|
||||
struct list *vrf_list;
|
||||
|
||||
static int vrf_is_enabled (struct vrf *vrf);
|
||||
static void vrf_disable (struct vrf *vrf);
|
||||
|
||||
/* VRF list existance check by name. */
|
||||
struct vrf *
|
||||
vrf_list_lookup_by_name (const char *name)
|
||||
vrf_lookup_by_name (const char *name)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct vrf *vrfp;
|
||||
|
||||
if (name)
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrfp))
|
||||
{
|
||||
if (strcmp(name, vrfp->name) == 0)
|
||||
return vrfp;
|
||||
}
|
||||
return NULL;
|
||||
struct vrf vrf;
|
||||
strlcpy (vrf.name, name, sizeof (vrf.name));
|
||||
return (RB_FIND (vrf_name_head, &vrfs_by_name, &vrf));
|
||||
}
|
||||
|
||||
/* Build the table key */
|
||||
static void
|
||||
vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
|
||||
static __inline int
|
||||
vrf_id_compare (struct vrf *a, struct vrf *b)
|
||||
{
|
||||
p->family = AF_INET;
|
||||
p->prefixlen = IPV4_MAX_BITLEN;
|
||||
p->u.prefix4.s_addr = vrf_id;
|
||||
return (a->vrf_id - b->vrf_id);
|
||||
}
|
||||
|
||||
static int
|
||||
vrf_name_compare (struct vrf *a, struct vrf *b)
|
||||
{
|
||||
return strcmp (a->name, b->name);
|
||||
}
|
||||
|
||||
/* Get a VRF. If not found, create one.
|
||||
|
@ -94,177 +93,59 @@ vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
|
|||
struct vrf *
|
||||
vrf_get (vrf_id_t vrf_id, const char *name)
|
||||
{
|
||||
struct prefix p;
|
||||
struct route_node *rn = NULL;
|
||||
struct vrf *vrf = NULL;
|
||||
int new = 0;
|
||||
|
||||
if (debug_vrf)
|
||||
zlog_debug ("VRF_GET: %s(%d)", name, vrf_id);
|
||||
|
||||
/*
|
||||
* Nothing to see, move along here
|
||||
*/
|
||||
/* Nothing to see, move along here */
|
||||
if (!name && vrf_id == VRF_UNKNOWN)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Valid vrf name and unknown vrf_id case
|
||||
*
|
||||
* This is called when we are configured from
|
||||
* the cli but we have no kernel information yet.
|
||||
*/
|
||||
if (name && vrf_id == VRF_UNKNOWN)
|
||||
{
|
||||
vrf = vrf_list_lookup_by_name (name);
|
||||
if (vrf)
|
||||
return vrf;
|
||||
/* Try to find VRF both by ID and name */
|
||||
if (vrf_id != VRF_UNKNOWN)
|
||||
vrf = vrf_lookup_by_id (vrf_id);
|
||||
if (! vrf && name)
|
||||
vrf = vrf_lookup_by_name (name);
|
||||
|
||||
if (vrf == NULL)
|
||||
{
|
||||
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
|
||||
if (debug_vrf)
|
||||
zlog_debug ("VRF(%u) %s is created.",
|
||||
vrf_id, (name) ? name : "(NULL)");
|
||||
strcpy (vrf->name, name);
|
||||
listnode_add_sort (vrf_list, vrf);
|
||||
vrf->vrf_id = VRF_UNKNOWN;
|
||||
if_init (&vrf->iflist);
|
||||
QOBJ_REG (vrf, vrf);
|
||||
if (vrf_master.vrf_new_hook)
|
||||
{
|
||||
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
|
||||
new = 1;
|
||||
|
||||
if (debug_vrf && vrf->info)
|
||||
zlog_info ("zvrf is created.");
|
||||
}
|
||||
if (debug_vrf)
|
||||
zlog_debug("Vrf Created: %p", vrf);
|
||||
return vrf;
|
||||
zlog_debug ("VRF(%u) %s is created.",
|
||||
vrf_id, (name) ? name : "(NULL)");
|
||||
}
|
||||
/*
|
||||
* Valid vrf name and valid vrf_id case
|
||||
*
|
||||
* This can be passed from the kernel
|
||||
*/
|
||||
else if (name && vrf_id != VRF_UNKNOWN)
|
||||
|
||||
/* Set identifier */
|
||||
if (vrf_id != VRF_UNKNOWN && vrf->vrf_id == VRF_UNKNOWN)
|
||||
{
|
||||
vrf = vrf_list_lookup_by_name (name);
|
||||
if (vrf)
|
||||
{
|
||||
/*
|
||||
* If the passed in vrf_id and name match
|
||||
* return, nothing to do here.
|
||||
*/
|
||||
if (vrf->vrf_id == vrf_id)
|
||||
return vrf;
|
||||
|
||||
/*
|
||||
* Now we have a situation where we've had a
|
||||
* vrf created, but not yet created the vrf_id route
|
||||
* node, let's do so and match the code up.
|
||||
*/
|
||||
vrf_build_key (vrf_id, &p);
|
||||
rn = route_node_get (vrf_table, &p);
|
||||
|
||||
rn->info = vrf;
|
||||
vrf->node = rn;
|
||||
vrf->vrf_id = vrf_id;
|
||||
if (vrf_master.vrf_new_hook)
|
||||
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
|
||||
|
||||
if (debug_vrf)
|
||||
zlog_debug("Vrf found matched stuff up: %p", vrf);
|
||||
|
||||
return vrf;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* We can have 1 of two situations here
|
||||
* We've already been told about the vrf_id
|
||||
* or we haven't.
|
||||
*/
|
||||
vrf_build_key (vrf_id, &p);
|
||||
rn = route_node_get (vrf_table, &p);
|
||||
if (rn->info)
|
||||
{
|
||||
vrf = rn->info;
|
||||
route_unlock_node (rn);
|
||||
/*
|
||||
* We know at this point that the vrf->name is not
|
||||
* right because we would have caught it above.
|
||||
* so let's set it.
|
||||
*/
|
||||
strcpy (vrf->name, name);
|
||||
listnode_add_sort (vrf_list, vrf);
|
||||
if (vrf_master.vrf_new_hook)
|
||||
{
|
||||
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
|
||||
|
||||
if (debug_vrf && vrf->info)
|
||||
zlog_info ("zvrf is created.");
|
||||
}
|
||||
if (debug_vrf)
|
||||
zlog_debug("Vrf Created: %p", vrf);
|
||||
return vrf;
|
||||
}
|
||||
else
|
||||
{
|
||||
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
|
||||
|
||||
rn->info = vrf;
|
||||
vrf->node = rn;
|
||||
vrf->vrf_id = vrf_id;
|
||||
strcpy (vrf->name, name);
|
||||
listnode_add_sort (vrf_list, vrf);
|
||||
if_init (&vrf->iflist);
|
||||
QOBJ_REG (vrf, vrf);
|
||||
if (vrf_master.vrf_new_hook)
|
||||
{
|
||||
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
|
||||
|
||||
if (debug_vrf && vrf->info)
|
||||
zlog_info ("zvrf is created.");
|
||||
}
|
||||
if (debug_vrf)
|
||||
zlog_debug("Vrf Created: %p", vrf);
|
||||
return vrf;
|
||||
}
|
||||
}
|
||||
vrf->vrf_id = vrf_id;
|
||||
RB_INSERT (vrf_id_head, &vrfs_by_id, vrf);
|
||||
}
|
||||
/*
|
||||
* The final case, we've been passed a valid vrf_id
|
||||
* but no name. So we create the route node
|
||||
* if it hasn't already been created.
|
||||
*/
|
||||
else if (!name)
|
||||
|
||||
/* Set name */
|
||||
if (name && vrf->name[0] != '\0' && strcmp (name, vrf->name))
|
||||
{
|
||||
vrf_build_key (vrf_id, &p);
|
||||
rn = route_node_get (vrf_table, &p);
|
||||
if (debug_vrf)
|
||||
zlog_debug("Vrf found: %p", rn->info);
|
||||
|
||||
if (rn->info)
|
||||
{
|
||||
route_unlock_node (rn);
|
||||
return (rn->info);
|
||||
}
|
||||
else
|
||||
{
|
||||
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
|
||||
rn->info = vrf;
|
||||
vrf->node = rn;
|
||||
vrf->vrf_id = vrf_id;
|
||||
if_init (&vrf->iflist);
|
||||
QOBJ_REG (vrf, vrf);
|
||||
if (debug_vrf)
|
||||
zlog_debug("Vrf Created: %p", vrf);
|
||||
return vrf;
|
||||
}
|
||||
RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf);
|
||||
strlcpy (vrf->name, name, sizeof (vrf->name));
|
||||
RB_INSERT (vrf_name_head, &vrfs_by_name, vrf);
|
||||
}
|
||||
else if (name && vrf->name[0] == '\0')
|
||||
{
|
||||
strlcpy (vrf->name, name, sizeof (vrf->name));
|
||||
RB_INSERT (vrf_name_head, &vrfs_by_name, vrf);
|
||||
}
|
||||
|
||||
/*
|
||||
* We shouldn't get here and if we do
|
||||
* something has gone wrong.
|
||||
*/
|
||||
return NULL;
|
||||
if (new && vrf_master.vrf_new_hook)
|
||||
(*vrf_master.vrf_new_hook) (vrf);
|
||||
|
||||
return vrf;
|
||||
}
|
||||
|
||||
/* Delete a VRF. This is called in vrf_terminate(). */
|
||||
|
@ -278,53 +159,35 @@ vrf_delete (struct vrf *vrf)
|
|||
vrf_disable (vrf);
|
||||
|
||||
if (vrf_master.vrf_delete_hook)
|
||||
(*vrf_master.vrf_delete_hook) (vrf->vrf_id, vrf->name, &vrf->info);
|
||||
(*vrf_master.vrf_delete_hook) (vrf);
|
||||
|
||||
QOBJ_UNREG (vrf);
|
||||
if_terminate (&vrf->iflist);
|
||||
|
||||
if (vrf->node)
|
||||
{
|
||||
vrf->node->info = NULL;
|
||||
route_unlock_node(vrf->node);
|
||||
}
|
||||
|
||||
listnode_delete (vrf_list, vrf);
|
||||
if (vrf->vrf_id != VRF_UNKNOWN)
|
||||
RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf);
|
||||
if (vrf->name[0] != '\0')
|
||||
RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf);
|
||||
|
||||
XFREE (MTYPE_VRF, vrf);
|
||||
}
|
||||
|
||||
/* Look up a VRF by identifier. */
|
||||
struct vrf *
|
||||
vrf_lookup (vrf_id_t vrf_id)
|
||||
vrf_lookup_by_id (vrf_id_t vrf_id)
|
||||
{
|
||||
struct prefix p;
|
||||
struct route_node *rn;
|
||||
struct vrf *vrf = NULL;
|
||||
|
||||
vrf_build_key (vrf_id, &p);
|
||||
rn = route_node_lookup (vrf_table, &p);
|
||||
if (rn)
|
||||
{
|
||||
vrf = (struct vrf *)rn->info;
|
||||
route_unlock_node (rn); /* lookup */
|
||||
}
|
||||
return vrf;
|
||||
struct vrf vrf;
|
||||
vrf.vrf_id = vrf_id;
|
||||
return (RB_FIND (vrf_id_head, &vrfs_by_id, &vrf));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether the VRF is enabled - that is, whether the VRF
|
||||
* is ready to allocate resources. Currently there's only one
|
||||
* type of resource: socket.
|
||||
* Check whether the VRF is enabled.
|
||||
*/
|
||||
static int
|
||||
vrf_is_enabled (struct vrf *vrf)
|
||||
{
|
||||
return vrf && CHECK_FLAG (vrf->status, VRF_ACTIVE);
|
||||
|
||||
/*Pending: figure out the real use of this routine.. it used to be..
|
||||
return vrf && vrf->vrf_id == VRF_DEFAULT;
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -337,14 +200,16 @@ vrf_is_enabled (struct vrf *vrf)
|
|||
int
|
||||
vrf_enable (struct vrf *vrf)
|
||||
{
|
||||
if (vrf_is_enabled (vrf))
|
||||
return 1;
|
||||
|
||||
if (debug_vrf)
|
||||
zlog_debug ("VRF %u is enabled.", vrf->vrf_id);
|
||||
|
||||
if (!CHECK_FLAG (vrf->status, VRF_ACTIVE))
|
||||
SET_FLAG (vrf->status, VRF_ACTIVE);
|
||||
SET_FLAG (vrf->status, VRF_ACTIVE);
|
||||
|
||||
if (vrf_master.vrf_enable_hook)
|
||||
(*vrf_master.vrf_enable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
|
||||
(*vrf_master.vrf_enable_hook) (vrf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -357,26 +222,25 @@ vrf_enable (struct vrf *vrf)
|
|||
static void
|
||||
vrf_disable (struct vrf *vrf)
|
||||
{
|
||||
if (vrf_is_enabled (vrf))
|
||||
{
|
||||
UNSET_FLAG (vrf->status, VRF_ACTIVE);
|
||||
if (! vrf_is_enabled (vrf))
|
||||
return;
|
||||
|
||||
if (debug_vrf)
|
||||
zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id);
|
||||
UNSET_FLAG (vrf->status, VRF_ACTIVE);
|
||||
|
||||
/* Till now, nothing to be done for the default VRF. */
|
||||
//Pending: see why this statement.
|
||||
if (debug_vrf)
|
||||
zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id);
|
||||
|
||||
if (vrf_master.vrf_disable_hook)
|
||||
(*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
|
||||
}
|
||||
/* Till now, nothing to be done for the default VRF. */
|
||||
//Pending: see why this statement.
|
||||
|
||||
if (vrf_master.vrf_disable_hook)
|
||||
(*vrf_master.vrf_disable_hook) (vrf);
|
||||
}
|
||||
|
||||
|
||||
/* Add a VRF hook. Please add hooks before calling vrf_init(). */
|
||||
void
|
||||
vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **))
|
||||
vrf_add_hook (int type, int (*func)(struct vrf *))
|
||||
{
|
||||
if (debug_vrf)
|
||||
zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__,
|
||||
|
@ -400,116 +264,6 @@ vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **))
|
|||
}
|
||||
}
|
||||
|
||||
/* Return the iterator of the first VRF. */
|
||||
vrf_iter_t
|
||||
vrf_first (void)
|
||||
{
|
||||
struct route_node *rn;
|
||||
|
||||
for (rn = route_top (vrf_table); rn; rn = route_next (rn))
|
||||
if (rn->info)
|
||||
{
|
||||
route_unlock_node (rn); /* top/next */
|
||||
return (vrf_iter_t)rn;
|
||||
}
|
||||
return VRF_ITER_INVALID;
|
||||
}
|
||||
|
||||
/* Return the next VRF iterator to the given iterator. */
|
||||
vrf_iter_t
|
||||
vrf_next (vrf_iter_t iter)
|
||||
{
|
||||
struct route_node *rn = NULL;
|
||||
|
||||
/* Lock it first because route_next() will unlock it. */
|
||||
if (iter != VRF_ITER_INVALID)
|
||||
rn = route_next (route_lock_node ((struct route_node *)iter));
|
||||
|
||||
for (; rn; rn = route_next (rn))
|
||||
if (rn->info)
|
||||
{
|
||||
route_unlock_node (rn); /* next */
|
||||
return (vrf_iter_t)rn;
|
||||
}
|
||||
return VRF_ITER_INVALID;
|
||||
}
|
||||
|
||||
/* Return the VRF iterator of the given VRF ID. If it does not exist,
|
||||
* the iterator of the next existing VRF is returned. */
|
||||
vrf_iter_t
|
||||
vrf_iterator (vrf_id_t vrf_id)
|
||||
{
|
||||
struct prefix p;
|
||||
struct route_node *rn;
|
||||
|
||||
vrf_build_key (vrf_id, &p);
|
||||
rn = route_node_get (vrf_table, &p);
|
||||
if (rn->info)
|
||||
{
|
||||
/* OK, the VRF exists. */
|
||||
route_unlock_node (rn); /* get */
|
||||
return (vrf_iter_t)rn;
|
||||
}
|
||||
|
||||
/* Find the next VRF. */
|
||||
for (rn = route_next (rn); rn; rn = route_next (rn))
|
||||
if (rn->info)
|
||||
{
|
||||
route_unlock_node (rn); /* next */
|
||||
return (vrf_iter_t)rn;
|
||||
}
|
||||
|
||||
return VRF_ITER_INVALID;
|
||||
}
|
||||
|
||||
/* Obtain the VRF ID from the given VRF iterator. */
|
||||
vrf_id_t
|
||||
vrf_iter2id (vrf_iter_t iter)
|
||||
{
|
||||
struct route_node *rn = (struct route_node *) iter;
|
||||
return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT;
|
||||
}
|
||||
|
||||
struct vrf *
|
||||
vrf_iter2vrf (vrf_iter_t iter)
|
||||
{
|
||||
struct route_node *rn = (struct route_node *) iter;
|
||||
return (rn && rn->info) ? (struct vrf *)rn->info : NULL;
|
||||
}
|
||||
|
||||
/* Obtain the data pointer from the given VRF iterator. */
|
||||
void *
|
||||
vrf_iter2info (vrf_iter_t iter)
|
||||
{
|
||||
struct route_node *rn = (struct route_node *) iter;
|
||||
return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL;
|
||||
}
|
||||
|
||||
/* Obtain the interface list from the given VRF iterator. */
|
||||
struct list *
|
||||
vrf_iter2iflist (vrf_iter_t iter)
|
||||
{
|
||||
struct route_node *rn = (struct route_node *) iter;
|
||||
return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL;
|
||||
}
|
||||
|
||||
/* Look up a VRF by name. */
|
||||
struct vrf *
|
||||
vrf_lookup_by_name (const char *name)
|
||||
{
|
||||
struct vrf *vrf = NULL;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
{
|
||||
vrf = vrf_iter2vrf (iter);
|
||||
if (vrf && !strcmp(vrf->name, name))
|
||||
return vrf;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vrf_id_t
|
||||
vrf_name_to_id (const char *name)
|
||||
{
|
||||
|
@ -535,7 +289,7 @@ vrf_info_get (vrf_id_t vrf_id)
|
|||
void *
|
||||
vrf_info_lookup (vrf_id_t vrf_id)
|
||||
{
|
||||
struct vrf *vrf = vrf_lookup (vrf_id);
|
||||
struct vrf *vrf = vrf_lookup_by_id (vrf_id);
|
||||
return vrf ? vrf->info : NULL;
|
||||
}
|
||||
|
||||
|
@ -543,7 +297,7 @@ vrf_info_lookup (vrf_id_t vrf_id)
|
|||
struct list *
|
||||
vrf_iflist (vrf_id_t vrf_id)
|
||||
{
|
||||
struct vrf * vrf = vrf_lookup (vrf_id);
|
||||
struct vrf * vrf = vrf_lookup_by_id (vrf_id);
|
||||
return vrf ? vrf->iflist : NULL;
|
||||
}
|
||||
|
||||
|
@ -559,7 +313,7 @@ vrf_iflist_get (vrf_id_t vrf_id)
|
|||
void
|
||||
vrf_iflist_create (vrf_id_t vrf_id)
|
||||
{
|
||||
struct vrf * vrf = vrf_lookup (vrf_id);
|
||||
struct vrf * vrf = vrf_lookup_by_id (vrf_id);
|
||||
if (vrf && !vrf->iflist)
|
||||
if_init (&vrf->iflist);
|
||||
}
|
||||
|
@ -568,7 +322,7 @@ vrf_iflist_create (vrf_id_t vrf_id)
|
|||
void
|
||||
vrf_iflist_terminate (vrf_id_t vrf_id)
|
||||
{
|
||||
struct vrf * vrf = vrf_lookup (vrf_id);
|
||||
struct vrf * vrf = vrf_lookup_by_id (vrf_id);
|
||||
if (vrf && vrf->iflist)
|
||||
if_terminate (&vrf->iflist);
|
||||
}
|
||||
|
@ -666,20 +420,6 @@ vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id)
|
|||
VRF_BITMAP_FLAG (offset)) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Compare interface names, returning an integer greater than, equal to, or
|
||||
* less than 0, (following the strcmp convention), according to the
|
||||
* relationship between vrfp1 and vrfp2. Interface names consist of an
|
||||
* alphabetic prefix and a numeric suffix. The primary sort key is
|
||||
* lexicographic by name, and then numeric by number. No number sorts
|
||||
* before all numbers. Examples: de0 < de1, de100 < fxp0 < xl0, devpty <
|
||||
* devpty0, de0 < del0
|
||||
*/
|
||||
static int
|
||||
vrf_cmp_func (struct vrf *vrfp1, struct vrf *vrfp2)
|
||||
{
|
||||
return if_cmp_name_func (vrfp1->name, vrfp2->name);
|
||||
}
|
||||
|
||||
/* Initialize VRF module. */
|
||||
void
|
||||
vrf_init (void)
|
||||
|
@ -689,12 +429,6 @@ vrf_init (void)
|
|||
if (debug_vrf)
|
||||
zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__);
|
||||
|
||||
vrf_list = list_new ();
|
||||
vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func;
|
||||
|
||||
/* Allocate VRF table. */
|
||||
vrf_table = route_table_init ();
|
||||
|
||||
/* The default VRF always exists. */
|
||||
default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
|
||||
if (!default_vrf)
|
||||
|
@ -715,18 +449,15 @@ vrf_init (void)
|
|||
void
|
||||
vrf_terminate (void)
|
||||
{
|
||||
struct route_node *rn;
|
||||
struct vrf *vrf;
|
||||
|
||||
if (debug_vrf)
|
||||
zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__);
|
||||
|
||||
for (rn = route_top (vrf_table); rn; rn = route_next (rn))
|
||||
if ((vrf = rn->info) != NULL)
|
||||
vrf_delete (vrf);
|
||||
|
||||
route_table_finish (vrf_table);
|
||||
vrf_table = NULL;
|
||||
while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL)
|
||||
vrf_delete (vrf);
|
||||
while ((vrf = RB_ROOT (&vrfs_by_name)) != NULL)
|
||||
vrf_delete (vrf);
|
||||
}
|
||||
|
||||
/* Create a socket for the VRF. */
|
||||
|
@ -740,6 +471,73 @@ vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* vrf CLI commands */
|
||||
DEFUN (vrf,
|
||||
vrf_cmd,
|
||||
"vrf NAME",
|
||||
"Select a VRF to configure\n"
|
||||
"VRF's name\n")
|
||||
{
|
||||
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
|
||||
*/
|
||||
|
@ -792,3 +590,12 @@ vrf_install_commands (void)
|
|||
install_element (CONFIG_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);
|
||||
}
|
||||
|
|
59
lib/vrf.h
59
lib/vrf.h
|
@ -23,8 +23,10 @@
|
|||
#ifndef _ZEBRA_VRF_H
|
||||
#define _ZEBRA_VRF_H
|
||||
|
||||
#include "openbsd-tree.h"
|
||||
#include "linklist.h"
|
||||
#include "qobj.h"
|
||||
#include "vty.h"
|
||||
|
||||
/* The default NS ID */
|
||||
#define NS_DEFAULT 0
|
||||
|
@ -65,18 +67,18 @@ enum {
|
|||
|
||||
struct vrf
|
||||
{
|
||||
RB_ENTRY(vrf) id_entry, name_entry;
|
||||
|
||||
/* Identifier, same as the vector index */
|
||||
vrf_id_t vrf_id;
|
||||
/* Name */
|
||||
|
||||
/* Name */
|
||||
char name[VRF_NAMSIZ + 1];
|
||||
|
||||
/* Zebra internal VRF status */
|
||||
u_char status;
|
||||
#define VRF_ACTIVE (1 << 0)
|
||||
|
||||
struct route_node *node;
|
||||
|
||||
/* Master list of interfaces belonging to this VRF */
|
||||
struct list *iflist;
|
||||
|
||||
|
@ -85,10 +87,15 @@ struct vrf
|
|||
|
||||
QOBJ_FIELDS
|
||||
};
|
||||
RB_HEAD (vrf_id_head, vrf);
|
||||
RB_PROTOTYPE (vrf_id_head, vrf, id_entry, vrf_id_compare)
|
||||
RB_HEAD (vrf_name_head, vrf);
|
||||
RB_PROTOTYPE (vrf_name_head, vrf, name_entry, vrf_name_compare)
|
||||
DECLARE_QOBJ_TYPE(vrf)
|
||||
|
||||
|
||||
extern struct list *vrf_list;
|
||||
extern struct vrf_id_head vrfs_by_id;
|
||||
extern struct vrf_name_head vrfs_by_name;
|
||||
|
||||
/*
|
||||
* Add a specific hook to VRF module.
|
||||
|
@ -98,18 +105,10 @@ extern struct list *vrf_list;
|
|||
* - param 2: the address of the user data pointer (the user data
|
||||
* can be stored in or freed from there)
|
||||
*/
|
||||
extern void vrf_add_hook (int, int (*)(vrf_id_t, const char *, void **));
|
||||
extern void vrf_add_hook (int, int (*)(struct vrf *));
|
||||
|
||||
/*
|
||||
* VRF iteration
|
||||
*/
|
||||
|
||||
typedef void * vrf_iter_t;
|
||||
#define VRF_ITER_INVALID NULL /* invalid value of the iterator */
|
||||
|
||||
extern struct vrf *vrf_lookup (vrf_id_t);
|
||||
extern struct vrf *vrf_lookup_by_id (vrf_id_t);
|
||||
extern struct vrf *vrf_lookup_by_name (const char *);
|
||||
extern struct vrf *vrf_list_lookup_by_name (const char *);
|
||||
extern struct vrf *vrf_get (vrf_id_t, const char *);
|
||||
extern void vrf_delete (struct vrf *);
|
||||
extern int vrf_enable (struct vrf *);
|
||||
|
@ -118,7 +117,7 @@ extern vrf_id_t vrf_name_to_id (const char *);
|
|||
#define VRF_GET_ID(V,NAME) \
|
||||
do { \
|
||||
struct vrf *vrf; \
|
||||
if (!(vrf = vrf_list_lookup_by_name(NAME))) \
|
||||
if (!(vrf = vrf_lookup_by_name(NAME))) \
|
||||
{ \
|
||||
vty_out (vty, "%% VRF %s not found%s", NAME, VTY_NEWLINE);\
|
||||
return CMD_WARNING; \
|
||||
|
@ -131,34 +130,6 @@ extern vrf_id_t vrf_name_to_id (const char *);
|
|||
(V) = vrf->vrf_id; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* VRF iteration utilities. Example for the usage:
|
||||
*
|
||||
* vrf_iter_t iter = vrf_first();
|
||||
* for (; iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
*
|
||||
* or
|
||||
*
|
||||
* vrf_iter_t iter = vrf_iterator (<a given VRF ID>);
|
||||
* for (; iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
*/
|
||||
|
||||
/* Return the iterator of the first VRF. */
|
||||
extern vrf_iter_t vrf_first (void);
|
||||
/* Return the next VRF iterator to the given iterator. */
|
||||
extern vrf_iter_t vrf_next (vrf_iter_t);
|
||||
/* Return the VRF iterator of the given VRF ID. If it does not exist,
|
||||
* the iterator of the next existing VRF is returned. */
|
||||
extern vrf_iter_t vrf_iterator (vrf_id_t);
|
||||
|
||||
/*
|
||||
* VRF iterator to properties
|
||||
*/
|
||||
extern vrf_id_t vrf_iter2id (vrf_iter_t);
|
||||
extern struct vrf *vrf_iter2vrf (vrf_iter_t);
|
||||
extern void *vrf_iter2info (vrf_iter_t);
|
||||
extern struct list *vrf_iter2iflist (vrf_iter_t);
|
||||
|
||||
/*
|
||||
* Utilities to obtain the user data
|
||||
*/
|
||||
|
@ -201,6 +172,8 @@ extern int vrf_bitmap_check (vrf_bitmap_t, vrf_id_t);
|
|||
extern void vrf_init (void);
|
||||
extern void vrf_terminate (void);
|
||||
|
||||
extern void vrf_cmd_init (int (*writefunc)(struct vty *vty));
|
||||
|
||||
/*
|
||||
* VRF utilities
|
||||
*/
|
||||
|
|
|
@ -1042,7 +1042,7 @@ zclient_vrf_delete (struct zclient *zclient, vrf_id_t vrf_id)
|
|||
struct vrf *vrf;
|
||||
|
||||
/* Lookup vrf by vrf_id. */
|
||||
vrf = vrf_lookup (vrf_id);
|
||||
vrf = vrf_lookup_by_id (vrf_id);
|
||||
|
||||
/*
|
||||
* If a routing protocol doesn't know about a
|
||||
|
|
|
@ -913,6 +913,7 @@ void
|
|||
ospf6_neighbor_init (void)
|
||||
{
|
||||
install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
|
||||
install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_one_cmd);
|
||||
}
|
||||
|
||||
DEFUN (debug_ospf6_neighbor,
|
||||
|
|
|
@ -623,6 +623,7 @@ DEFUN (no_ospf6_distance_ospf6,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
DEFUN (ospf6_distance_source,
|
||||
ospf6_distance_source_cmd,
|
||||
"distance (1-255) X:X::X:X/M [WORD]",
|
||||
|
@ -653,6 +654,7 @@ DEFUN (no_ospf6_distance_source,
|
|||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
DEFUN (ospf6_interface_area,
|
||||
ospf6_interface_area_cmd,
|
||||
|
@ -834,6 +836,7 @@ DEFUN (no_ospf6_stub_router_admin,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
DEFUN (ospf6_stub_router_startup,
|
||||
ospf6_stub_router_startup_cmd,
|
||||
"stub-router on-startup (5-86400)",
|
||||
|
@ -879,6 +882,7 @@ DEFUN (no_ospf6_stub_router_shutdown,
|
|||
{
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ospf6_show (struct vty *vty, struct ospf6 *o)
|
||||
|
|
|
@ -132,18 +132,16 @@ ospf_if_ipmulticast (struct ospf *top, struct prefix *p, ifindex_t ifindex)
|
|||
{
|
||||
u_char val;
|
||||
int ret, len;
|
||||
|
||||
val = 0;
|
||||
len = sizeof (val);
|
||||
|
||||
|
||||
/* 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)
|
||||
zlog_warn ("can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s",
|
||||
top->fd, safe_strerror(errno));
|
||||
|
||||
/* Explicitly set multicast ttl to 1 -- endo. */
|
||||
val = 1;
|
||||
len = sizeof (val);
|
||||
ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, len);
|
||||
if (ret < 0)
|
||||
zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
|
||||
|
|
|
@ -2772,6 +2772,7 @@ ospf_read (struct thread *thread)
|
|||
struct ospf_header *ospfh;
|
||||
u_int16_t length;
|
||||
struct interface *ifp;
|
||||
struct connected *c;
|
||||
|
||||
/* first of all get interface pointer. */
|
||||
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. */
|
||||
|
||||
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
|
||||
retrieval but do not. */
|
||||
ifp = if_lookup_address ((void *)&iph->ip_src, AF_INET);
|
||||
|
||||
if (ifp == NULL)
|
||||
return 0;
|
||||
{
|
||||
/* Handle cases where the platform does not support retrieving the ifindex,
|
||||
and also platforms (such as Solaris 8) that claim to support ifindex
|
||||
retrieval but do not. */
|
||||
c = if_lookup_address ((void *)&iph->ip_src, AF_INET);
|
||||
if (c)
|
||||
ifp = c->ifp;
|
||||
if (ifp == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* IP Header dump. */
|
||||
if (IS_DEBUG_OSPF_PACKET(0, RECV))
|
||||
|
|
|
@ -1662,6 +1662,7 @@ ospf_router_info_register_vty (void)
|
|||
install_element (OSPF_NODE, &pce_neighbor_cmd);
|
||||
install_element (OSPF_NODE, &no_pce_neighbor_cmd);
|
||||
install_element (OSPF_NODE, &pce_cap_flag_cmd);
|
||||
install_element (OSPF_NODE, &no_pce_cap_flag_cmd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4402,10 +4402,15 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi,
|
|||
/* Show Router Dead interval timer. */
|
||||
if (use_json)
|
||||
{
|
||||
struct timeval res = tv_sub (nbr->t_inactivity->u.sands, recent_relative_time ());
|
||||
unsigned long time_store = 0;
|
||||
time_store = (1000 * res.tv_sec) + (res.tv_usec / 1000);
|
||||
json_object_int_add(json_sub, "routerDeadIntervalTimerDueMsec", time_store);
|
||||
if (nbr->t_inactivity)
|
||||
{
|
||||
struct timeval res = tv_sub (nbr->t_inactivity->u.sands, recent_relative_time ());
|
||||
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
|
||||
vty_out (vty, " Dead timer due in %s%s",
|
||||
|
@ -7798,6 +7803,7 @@ DEFUN (ospf_distance_ospf,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
DEFUN (ospf_distance_source,
|
||||
ospf_distance_source_cmd,
|
||||
"distance (1-255) A.B.C.D/M",
|
||||
|
@ -7879,6 +7885,7 @@ DEFUN (no_ospf_distance_source_access_list,
|
|||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
DEFUN (ip_ospf_mtu_ignore,
|
||||
ip_ospf_mtu_ignore_addr_cmd,
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "privs.h"
|
||||
#include "if.h"
|
||||
#include "vrf.h"
|
||||
#include "sockopt.h"
|
||||
|
||||
#include "pimd.h"
|
||||
#include "pim_mroute.h"
|
||||
|
@ -68,7 +69,7 @@ int pim_socket_raw(int protocol)
|
|||
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;
|
||||
|
||||
|
@ -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,
|
||||
(void *) &loop, sizeof(loop))) {
|
||||
if (setsockopt_ipv4_multicast_loop (fd, loop)) {
|
||||
zlog_warn("Could not %s Multicast Loopback Option on socket fd=%d: errno=%d: %s",
|
||||
loop ? "enable" : "disable",
|
||||
fd, errno, safe_strerror(errno));
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#define PIM_SOCK_ERR_BIND (-11) /* Can't bind to interface */
|
||||
|
||||
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,
|
||||
struct in_addr ifaddr, ifindex_t ifindex);
|
||||
int pim_socket_join_source(int fd, ifindex_t ifindex,
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "if.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
#include "sockopt.h"
|
||||
|
||||
#include "pim_ssmpingd.h"
|
||||
#include "pim_time.h"
|
||||
|
@ -150,17 +151,12 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl)
|
|||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
int loop = 0;
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
|
||||
(void *) &loop, sizeof(loop))) {
|
||||
zlog_warn("%s: could not %s Multicast Loopback Option on socket fd=%d: errno=%d: %s",
|
||||
__PRETTY_FUNCTION__,
|
||||
loop ? "enable" : "disable",
|
||||
fd, errno, safe_strerror(errno));
|
||||
close(fd);
|
||||
return PIM_SOCK_ERR_LOOP;
|
||||
}
|
||||
if (setsockopt_ipv4_multicast_loop (fd, 0)) {
|
||||
zlog_warn("%s: could not disable Multicast Loopback Option on socket fd=%d: errno=%d: %s",
|
||||
__PRETTY_FUNCTION__,
|
||||
fd, errno, safe_strerror(errno));
|
||||
close(fd);
|
||||
return PIM_SOCK_ERR_LOOP;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
|
|
|
@ -4,11 +4,14 @@ import sys, markdown
|
|||
|
||||
template = '''<html><head><meta charset="UTF-8"><style type="text/css">
|
||||
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 { display: block; padding:0.5em; border:1px solid black;
|
||||
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; }
|
||||
h4 { font-weight: normal; font-style: italic; }
|
||||
img[alt~="float-right"] { float:right; margin-left:2em; margin-bottom:2em; }
|
||||
|
|
|
@ -55,6 +55,7 @@ const struct message ri_version_msg[] =
|
|||
{RI_RIP_VERSION_1, "1"},
|
||||
{RI_RIP_VERSION_2, "2"},
|
||||
{RI_RIP_VERSION_1_AND_2, "1 2"},
|
||||
{RI_RIP_VERSION_NONE, "none"},
|
||||
};
|
||||
|
||||
extern struct zebra_privs_t ripd_privs;
|
||||
|
@ -497,17 +498,17 @@ rip_interface_delete (int command, struct zclient *zclient,
|
|||
|
||||
static void
|
||||
rip_interface_clean (struct rip_interface *ri)
|
||||
{
|
||||
ri->enable_network = 0;
|
||||
ri->enable_interface = 0;
|
||||
ri->running = 0;
|
||||
{
|
||||
ri->enable_network = 0;
|
||||
ri->enable_interface = 0;
|
||||
ri->running = 0;
|
||||
|
||||
if (ri->t_wakeup)
|
||||
{
|
||||
thread_cancel (ri->t_wakeup);
|
||||
ri->t_wakeup = NULL;
|
||||
}
|
||||
if (ri->t_wakeup)
|
||||
{
|
||||
thread_cancel (ri->t_wakeup);
|
||||
ri->t_wakeup = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rip_interfaces_clean (void)
|
||||
|
@ -521,7 +522,7 @@ rip_interfaces_clean (void)
|
|||
|
||||
static void
|
||||
rip_interface_reset (struct rip_interface *ri)
|
||||
{
|
||||
{
|
||||
/* Default authentication type is simple password for Cisco
|
||||
compatibility. */
|
||||
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 = ri->split_horizon_default;
|
||||
|
||||
ri->ri_send = RI_RIP_UNSPEC;
|
||||
ri->ri_receive = RI_RIP_UNSPEC;
|
||||
ri->ri_send = RI_RIP_UNSPEC;
|
||||
ri->ri_receive = RI_RIP_UNSPEC;
|
||||
|
||||
if (ri->auth_str)
|
||||
{
|
||||
free (ri->auth_str);
|
||||
ri->auth_str = NULL;
|
||||
}
|
||||
if (ri->key_chain)
|
||||
{
|
||||
free (ri->key_chain);
|
||||
ri->key_chain = NULL;
|
||||
}
|
||||
ri->v2_broadcast = 0;
|
||||
|
||||
ri->list[RIP_FILTER_IN] = NULL;
|
||||
ri->list[RIP_FILTER_OUT] = NULL;
|
||||
if (ri->auth_str)
|
||||
{
|
||||
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->prefix[RIP_FILTER_OUT] = NULL;
|
||||
|
||||
ri->recv_badpackets = 0;
|
||||
ri->recv_badroutes = 0;
|
||||
ri->sent_updates = 0;
|
||||
ri->list[RIP_FILTER_IN] = NULL;
|
||||
ri->list[RIP_FILTER_OUT] = NULL;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rip_interfaces_reset (void)
|
||||
|
@ -1320,13 +1323,14 @@ DEFUN (no_rip_neighbor,
|
|||
|
||||
DEFUN (ip_rip_receive_version,
|
||||
ip_rip_receive_version_cmd,
|
||||
"ip rip receive version (1-2)",
|
||||
"ip rip receive version <1|2|none>",
|
||||
IP_STR
|
||||
"Routing Information Protocol\n"
|
||||
"Advertisement reception\n"
|
||||
"Version control\n"
|
||||
"RIP version 1\n"
|
||||
"RIP version 2\n")
|
||||
"RIP version 2\n"
|
||||
"None\n")
|
||||
{
|
||||
int idx_type = 4;
|
||||
struct interface *ifp;
|
||||
|
@ -1335,17 +1339,21 @@ DEFUN (ip_rip_receive_version,
|
|||
ifp = (struct interface *)vty->index;
|
||||
ri = ifp->info;
|
||||
|
||||
/* Version 1. */
|
||||
if (atoi (argv[idx_type]->arg) == 1)
|
||||
switch (argv[idx_type]->arg[0])
|
||||
{
|
||||
case '1':
|
||||
ri->ri_receive = RI_RIP_VERSION_1;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
if (atoi (argv[idx_type]->arg) == 2)
|
||||
{
|
||||
case '2':
|
||||
ri->ri_receive = RI_RIP_VERSION_2;
|
||||
return CMD_SUCCESS;
|
||||
case 'n':
|
||||
ri->ri_receive = RI_RIP_VERSION_NONE;
|
||||
return CMD_SUCCESS;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
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,
|
||||
ip_rip_authentication_mode_cmd,
|
||||
"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_receive == RI_RIP_UNSPEC) &&
|
||||
(ri->auth_type != RIP_AUTH_MD5) &&
|
||||
(!ri->v2_broadcast) &&
|
||||
(ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
|
||||
(!ri->auth_str) &&
|
||||
(!ri->key_chain) )
|
||||
|
@ -1891,6 +1935,9 @@ rip_interface_config_write (struct vty *vty)
|
|||
lookup (ri_version_msg, ri->ri_receive),
|
||||
VTY_NEWLINE);
|
||||
|
||||
if (ri->v2_broadcast)
|
||||
vty_out (vty, " ip rip v2-broadcast%s", VTY_NEWLINE);
|
||||
|
||||
/* RIP authentication. */
|
||||
if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
|
||||
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, &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, &no_ip_rip_authentication_mode_cmd);
|
||||
|
||||
|
|
135
ripd/ripd.c
135
ripd/ripd.c
|
@ -812,7 +812,15 @@ rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
|
|||
struct interface *ifp)
|
||||
{
|
||||
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)
|
||||
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. */
|
||||
if (ri->auth_str)
|
||||
{
|
||||
auth_str = (char *) &rte->prefix;
|
||||
|
||||
if (strncmp (auth_str, ri->auth_str, 16) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
@ -841,7 +847,7 @@ rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
|
|||
if (keychain == NULL)
|
||||
return 0;
|
||||
|
||||
key = key_match_for_accept (keychain, (char *) &rte->prefix);
|
||||
key = key_match_for_accept (keychain, auth_str);
|
||||
if (key)
|
||||
return 1;
|
||||
}
|
||||
|
@ -1333,30 +1339,23 @@ rip_response_process (struct rip_packet *packet, int size,
|
|||
|
||||
/* Make socket for RIP protocol. */
|
||||
static int
|
||||
rip_create_socket (struct sockaddr_in *from)
|
||||
rip_create_socket (void)
|
||||
{
|
||||
int ret;
|
||||
int sock;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
memset (&addr, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
if (!from)
|
||||
{
|
||||
addr.sin_family = AF_INET;
|
||||
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
|
||||
addr.sin_len = sizeof (struct sockaddr_in);
|
||||
addr.sin_len = sizeof (struct sockaddr_in);
|
||||
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
||||
} else {
|
||||
memcpy(&addr, from, sizeof(addr));
|
||||
}
|
||||
|
||||
/* sending port must always be the RIP port */
|
||||
addr.sin_port = htons (RIP_PORT_DEFAULT);
|
||||
|
||||
/* Make datagram socket. */
|
||||
sock = socket (AF_INET, SOCK_DGRAM, 0);
|
||||
sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sock < 0)
|
||||
{
|
||||
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_reuseaddr (sock);
|
||||
sockopt_reuseport (sock);
|
||||
setsockopt_ipv4_multicast_loop (sock, 0);
|
||||
#ifdef RIP_RECVMSG
|
||||
setsockopt_pktinfo (sock);
|
||||
#endif /* RIP_RECVMSG */
|
||||
|
@ -1406,7 +1406,7 @@ static int
|
|||
rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,
|
||||
struct connected *ifc)
|
||||
{
|
||||
int ret, send_sock;
|
||||
int ret;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
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_addr = to->sin_addr;
|
||||
send_sock = rip->sock;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct sockaddr_in from;
|
||||
|
||||
sin.sin_port = htons (RIP_PORT_DEFAULT);
|
||||
sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
|
||||
|
||||
/* multicast send should bind to local interface address */
|
||||
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);
|
||||
|
||||
rip_interface_multicast_set (rip->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));
|
||||
|
||||
if (IS_RIP_DEBUG_EVENT)
|
||||
|
@ -1503,9 +1481,6 @@ rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,
|
|||
if (ret < 0)
|
||||
zlog_warn ("can't send packet : %s", safe_strerror (errno));
|
||||
|
||||
if (!to)
|
||||
close(send_sock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1681,6 +1656,9 @@ rip_request_process (struct rip_packet *packet, int size,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (ntohs (rte->family) != AF_INET)
|
||||
return;
|
||||
|
||||
/* Examine the list of RTEs in the Request one by one. For each
|
||||
entry, look up the destination in the router's routing
|
||||
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 vrecv;
|
||||
socklen_t fromlen;
|
||||
struct interface *ifp;
|
||||
struct interface *ifp = NULL;
|
||||
struct connected *ifc;
|
||||
struct rip_interface *ri;
|
||||
struct prefix p;
|
||||
|
@ -1836,8 +1814,10 @@ rip_read (struct thread *t)
|
|||
}
|
||||
|
||||
/* 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 */
|
||||
if (IS_RIP_DEBUG_EVENT)
|
||||
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 */
|
||||
vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ?
|
||||
rip->version_recv : ri->ri_receive);
|
||||
if ((packet->version == RIPv1) && !(vrecv & RIPv1))
|
||||
{
|
||||
if (IS_RIP_DEBUG_PACKET)
|
||||
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 (vrecv == RI_RIP_VERSION_NONE ||
|
||||
((packet->version == RIPv1) && !(vrecv & RIPv1)) ||
|
||||
((packet->version == RIPv2) && !(vrecv & RIPv2)))
|
||||
{
|
||||
if (IS_RIP_DEBUG_PACKET)
|
||||
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
|
||||
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;
|
||||
|
||||
/* 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)
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
@ -2469,7 +2445,7 @@ rip_update_interface (struct connected *ifc, u_char version, int route_type)
|
|||
if (IS_RIP_DEBUG_EVENT)
|
||||
zlog_debug("%s announce to %s on %s",
|
||||
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);
|
||||
}
|
||||
|
@ -2539,21 +2515,14 @@ rip_update_process (int route_type)
|
|||
{
|
||||
p = &rp->p;
|
||||
|
||||
ifp = if_lookup_prefix (p);
|
||||
if (! ifp)
|
||||
connected = if_lookup_address (&p->u.prefix4, AF_INET);
|
||||
if (! connected)
|
||||
{
|
||||
zlog_warn ("Neighbor %s doesnt have connected interface!",
|
||||
inet_ntoa (p->u.prefix4));
|
||||
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 */
|
||||
memset (&to, 0, sizeof (struct sockaddr_in));
|
||||
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
|
||||
the time the triggered update would be sent. */
|
||||
if (rip->t_triggered_interval)
|
||||
{
|
||||
thread_cancel (rip->t_triggered_interval);
|
||||
rip->t_triggered_interval = NULL;
|
||||
}
|
||||
RIP_TIMER_OFF (rip->t_triggered_interval);
|
||||
rip->trigger = 0;
|
||||
|
||||
/* Register myself. */
|
||||
|
@ -2637,11 +2602,7 @@ rip_triggered_update (struct thread *t)
|
|||
rip->t_triggered_update = NULL;
|
||||
|
||||
/* Cancel interval timer. */
|
||||
if (rip->t_triggered_interval)
|
||||
{
|
||||
thread_cancel (rip->t_triggered_interval);
|
||||
rip->t_triggered_interval = NULL;
|
||||
}
|
||||
RIP_TIMER_OFF (rip->t_triggered_interval);
|
||||
rip->trigger = 0;
|
||||
|
||||
/* Logging triggered update. */
|
||||
|
@ -2729,7 +2690,7 @@ rip_create (void)
|
|||
rip->obuf = stream_new (1500);
|
||||
|
||||
/* Make socket. */
|
||||
rip->sock = rip_create_socket (NULL);
|
||||
rip->sock = rip_create_socket ();
|
||||
if (rip->sock < 0)
|
||||
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);
|
||||
break;
|
||||
case RIP_UPDATE_EVENT:
|
||||
if (rip->t_update)
|
||||
{
|
||||
thread_cancel (rip->t_update);
|
||||
rip->t_update = NULL;
|
||||
}
|
||||
RIP_TIMER_OFF (rip->t_update);
|
||||
jitter = rip_update_jitter (rip->update_time);
|
||||
rip->t_update =
|
||||
thread_add_timer (master, rip_update, NULL,
|
||||
|
@ -3919,11 +3876,7 @@ rip_clean (void)
|
|||
RIP_TIMER_OFF (rip->t_triggered_interval);
|
||||
|
||||
/* Cancel read thread. */
|
||||
if (rip->t_read)
|
||||
{
|
||||
thread_cancel (rip->t_read);
|
||||
rip->t_read = NULL;
|
||||
}
|
||||
THREAD_READ_OFF (rip->t_read);
|
||||
|
||||
/* Close RIP socket. */
|
||||
if (rip->sock >= 0)
|
||||
|
|
13
ripd/ripd.h
13
ripd/ripd.h
|
@ -258,6 +258,9 @@ struct rip_interface
|
|||
int ri_send;
|
||||
int ri_receive;
|
||||
|
||||
/* RIPv2 broadcast mode */
|
||||
int v2_broadcast;
|
||||
|
||||
/* RIPv2 authentication type. */
|
||||
int auth_type;
|
||||
|
||||
|
@ -347,6 +350,7 @@ struct rip_md5_data
|
|||
#define RI_RIP_VERSION_1 1
|
||||
#define RI_RIP_VERSION_2 2
|
||||
#define RI_RIP_VERSION_1_AND_2 3
|
||||
#define RI_RIP_VERSION_NONE 4
|
||||
/* N.B. stuff will break if
|
||||
(RIPv1 != RI_RIP_VERSION_1) || (RIPv2 != RI_RIP_VERSION_2) */
|
||||
|
||||
|
@ -369,14 +373,7 @@ enum rip_event
|
|||
} while (0)
|
||||
|
||||
/* Macro for timer turn off. */
|
||||
#define RIP_TIMER_OFF(X) \
|
||||
do { \
|
||||
if (X) \
|
||||
{ \
|
||||
thread_cancel (X); \
|
||||
(X) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
#define RIP_TIMER_OFF(X) THREAD_TIMER_OFF(X)
|
||||
|
||||
/* Prototypes. */
|
||||
extern void rip_init (void);
|
||||
|
|
|
@ -65,7 +65,7 @@ ripng_multicast_join (struct interface *ifp)
|
|||
struct ipv6_mreq mreq;
|
||||
int save_errno;
|
||||
|
||||
if (if_is_up (ifp) && if_is_multicast (ifp)) {
|
||||
if (if_is_multicast (ifp)) {
|
||||
memset (&mreq, 0, sizeof (mreq));
|
||||
inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr);
|
||||
mreq.ipv6mr_interface = ifp->ifindex;
|
||||
|
@ -116,7 +116,7 @@ ripng_multicast_leave (struct interface *ifp)
|
|||
int ret;
|
||||
struct ipv6_mreq mreq;
|
||||
|
||||
if (if_is_up (ifp) && if_is_multicast (ifp)) {
|
||||
if (if_is_multicast (ifp)) {
|
||||
memset (&mreq, 0, sizeof (mreq));
|
||||
inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr);
|
||||
mreq.ipv6mr_interface = ifp->ifindex;
|
||||
|
|
|
@ -829,8 +829,10 @@ ripng_route_process (struct rte *rte, struct sockaddr_in6 *from,
|
|||
* with the new one in below. */
|
||||
break;
|
||||
|
||||
/* Metrics are same. Keep "rinfo" null and the new route
|
||||
* is added in the ECMP list in below. */
|
||||
/* Metrics are same. Unless ECMP is disabled, keep "rinfo" null and
|
||||
* 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)
|
||||
&& (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
|
||||
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
|
||||
one; do the following actions: */
|
||||
if ((same && rinfo->metric != rte->metric) ||
|
||||
else if ((same && rinfo->metric != rte->metric) ||
|
||||
rte->metric < rinfo->metric)
|
||||
{
|
||||
if (listcount (list) == 1)
|
||||
|
@ -2155,6 +2170,54 @@ DEFUN (show_ipv6_ripng_status,
|
|||
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,
|
||||
router_ripng_cmd,
|
||||
"router ripng",
|
||||
|
@ -2512,6 +2575,7 @@ DEFUN (no_ripng_timers,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
DEFUN (show_ipv6_protocols,
|
||||
show_ipv6_protocols_cmd,
|
||||
"show ipv6 protocols",
|
||||
|
@ -2538,6 +2602,7 @@ DEFUN (show_ipv6_protocols,
|
|||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Please be carefull to use this command. */
|
||||
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_protocols_cmd);
|
||||
|
||||
install_element (ENABLE_NODE, &clear_ipv6_rip_cmd);
|
||||
|
||||
install_element (CONFIG_NODE, &router_ripng_cmd);
|
||||
install_element (CONFIG_NODE, &no_router_ripng_cmd);
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "bgpd/bgp_table.h"
|
||||
#include "bgpd/bgp_route.h"
|
||||
#include "bgpd/bgp_attr.h"
|
||||
#include "bgpd/bgp_nexthop.h"
|
||||
#include "bgpd/bgp_mpath.h"
|
||||
|
||||
#define VT100_RESET "\x1b[0m"
|
||||
|
@ -116,6 +117,7 @@ bgp_create_fake (as_t *as, const char *name)
|
|||
bgp->maxpaths[afi][safi].maxpaths_ibgp = MULTIPATH_NUM;
|
||||
}
|
||||
|
||||
bgp_scan_init (bgp);
|
||||
bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
|
||||
bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
|
||||
bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
|
||||
|
|
|
@ -1560,24 +1560,6 @@ DEFUNSH (VTYSH_BGPD,
|
|||
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,
|
||||
vtysh_exit_ripd,
|
||||
vtysh_exit_ripd_cmd,
|
||||
|
@ -3122,7 +3104,8 @@ vtysh_init_vty (void)
|
|||
/* "exit" command. */
|
||||
install_element (VIEW_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_quit_ripd_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 (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_quit_ns_cmd);
|
||||
|
||||
|
@ -3255,6 +3240,7 @@ vtysh_init_vty (void)
|
|||
#if defined(ENABLE_BGP_VNC)
|
||||
install_element (BGP_NODE, &vnc_defaults_cmd);
|
||||
install_element (BGP_NODE, &vnc_nve_group_cmd);
|
||||
install_element (BGP_NODE, &vnc_l2_group_cmd);
|
||||
#endif
|
||||
install_element (BGP_NODE, &address_family_ipv4_unicast_cmd);
|
||||
install_element (BGP_NODE, &address_family_ipv4_multicast_cmd);
|
||||
|
|
|
@ -209,13 +209,6 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name)
|
|||
|
||||
if (h->nlmsg_type == RTM_NEWLINK)
|
||||
{
|
||||
/* If VRF already exists, we just return; status changes are handled
|
||||
* against the VRF "interface".
|
||||
*/
|
||||
vrf = vrf_lookup ((vrf_id_t)ifi->ifi_index);
|
||||
if (vrf && vrf->info)
|
||||
return;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("RTM_NEWLINK for VRF %s(%u) table %u",
|
||||
name, ifi->ifi_index, nl_table_id);
|
||||
|
@ -251,7 +244,7 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name)
|
|||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("RTM_DELLINK for VRF %s(%u)", name, ifi->ifi_index);
|
||||
|
||||
vrf = vrf_lookup ((vrf_id_t)ifi->ifi_index);
|
||||
vrf = vrf_lookup_by_id ((vrf_id_t)ifi->ifi_index);
|
||||
|
||||
if (!vrf)
|
||||
{
|
||||
|
|
|
@ -59,6 +59,20 @@ const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
|
|||
|
||||
static void if_down_del_nbr_connected (struct interface *ifp);
|
||||
|
||||
static void
|
||||
zebra_if_node_destroy (route_table_delegate_t *delegate,
|
||||
struct route_table *table, struct route_node *node)
|
||||
{
|
||||
if (node->info)
|
||||
list_delete (node->info);
|
||||
route_node_destroy (delegate, table, node);
|
||||
}
|
||||
|
||||
route_table_delegate_t zebra_if_table_delegate = {
|
||||
.create_node = route_node_create,
|
||||
.destroy_node = zebra_if_node_destroy
|
||||
};
|
||||
|
||||
/* Called when new interface is added. */
|
||||
static int
|
||||
if_zebra_new_hook (struct interface *ifp)
|
||||
|
@ -101,7 +115,7 @@ if_zebra_new_hook (struct interface *ifp)
|
|||
#endif /* HAVE_RTADV */
|
||||
|
||||
/* Initialize installed address chains tree. */
|
||||
zebra_if->ipv4_subnets = route_table_init ();
|
||||
zebra_if->ipv4_subnets = route_table_init_with_delegate (&zebra_if_table_delegate);
|
||||
|
||||
ifp->info = zebra_if;
|
||||
|
||||
|
@ -1025,7 +1039,7 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
|
|||
|
||||
zebra_ptm_show_status(vty, ifp);
|
||||
|
||||
vrf = vrf_lookup(ifp->vrf_id);
|
||||
vrf = vrf_lookup_by_id (ifp->vrf_id);
|
||||
vty_out (vty, " vrf: %s%s", vrf->name, VTY_NEWLINE);
|
||||
|
||||
if (ifp->desc)
|
||||
|
@ -1243,35 +1257,6 @@ struct cmd_node interface_node =
|
|||
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. */
|
||||
DEFUN (show_interface,
|
||||
show_interface_cmd,
|
||||
|
@ -1305,15 +1290,15 @@ DEFUN (show_interface_vrf_all,
|
|||
"Interface status and configuration\n"
|
||||
VRF_ALL_CMD_HELP_STR)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct listnode *node;
|
||||
struct interface *ifp;
|
||||
vrf_iter_t iter;
|
||||
|
||||
interface_update_stats ();
|
||||
|
||||
/* All interface print. */
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
|
||||
if_dump_vty (vty, ifp);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -1361,17 +1346,17 @@ DEFUN (show_interface_name_vrf_all,
|
|||
VRF_ALL_CMD_HELP_STR)
|
||||
{
|
||||
int idx_ifname = 2;
|
||||
struct vrf *vrf;
|
||||
struct interface *ifp;
|
||||
vrf_iter_t iter;
|
||||
int found = 0;
|
||||
|
||||
interface_update_stats ();
|
||||
|
||||
/* All interface print. */
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
/* Specified interface print. */
|
||||
ifp = if_lookup_by_name_vrf (argv[idx_ifname]->arg, vrf_iter2id (iter));
|
||||
ifp = if_lookup_by_name_vrf (argv[idx_ifname]->arg, vrf->vrf_id);
|
||||
if (ifp)
|
||||
{
|
||||
if_dump_vty (vty, ifp);
|
||||
|
@ -1456,15 +1441,14 @@ DEFUN (show_interface_desc_vrf_all,
|
|||
"Interface description\n"
|
||||
VRF_ALL_CMD_HELP_STR)
|
||||
{
|
||||
vrf_iter_t iter;
|
||||
struct vrf *vrf;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if (!list_isempty (vrf_iter2iflist (iter)))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
if (!list_isempty (vrf->iflist))
|
||||
{
|
||||
vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
|
||||
vrf_iter2id (iter),
|
||||
VTY_NEWLINE, VTY_NEWLINE);
|
||||
if_show_description (vty, vrf_iter2id (iter));
|
||||
vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id,
|
||||
VTY_NEWLINE, VTY_NEWLINE);
|
||||
if_show_description (vty, vrf->vrf_id);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -1801,7 +1785,7 @@ DEFUN (link_params_metric,
|
|||
VTY_GET_ULONG("metric", metric, argv[idx_number]->arg);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -1815,7 +1799,7 @@ DEFUN (no_link_params_metric,
|
|||
VTY_DECLVAR_CONTEXT (interface, ifp);
|
||||
|
||||
/* Unset TE Metric */
|
||||
link_param_cmd_unset(ifp, LP_TE);
|
||||
link_param_cmd_unset(ifp, LP_TE | LP_TE_METRIC);
|
||||
|
||||
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, " 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);
|
||||
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);
|
||||
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);
|
||||
if (IS_PARAM_SET(iflp, LP_UNRSV_BW))
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
vty_out(vty, " unrsv-bw %d %g%s",
|
||||
i, iflp->unrsv_bw[i], VTY_NEWLINE);
|
||||
if (iflp->unrsv_bw[i] != iflp->default_bw)
|
||||
vty_out(vty, " unrsv-bw %d %g%s",
|
||||
i, iflp->unrsv_bw[i], VTY_NEWLINE);
|
||||
}
|
||||
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))
|
||||
{
|
||||
vty_out(vty, " delay %u", iflp->av_delay);
|
||||
|
@ -2797,14 +2782,14 @@ link_params_config_write (struct vty *vty, struct interface *ifp)
|
|||
static int
|
||||
if_config_write (struct vty *vty)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct listnode *node;
|
||||
struct interface *ifp;
|
||||
vrf_iter_t iter;
|
||||
|
||||
zebra_ptm_write (vty);
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
|
||||
{
|
||||
struct zebra_if *if_data;
|
||||
struct listnode *addrnode;
|
||||
|
@ -2813,7 +2798,7 @@ if_config_write (struct vty *vty)
|
|||
struct vrf *vrf;
|
||||
|
||||
if_data = ifp->info;
|
||||
vrf = vrf_lookup(ifp->vrf_id);
|
||||
vrf = vrf_lookup_by_id (ifp->vrf_id);
|
||||
|
||||
if (ifp->vrf_id == VRF_DEFAULT)
|
||||
vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
|
||||
|
@ -2881,23 +2866,6 @@ if_config_write (struct vty *vty)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vrf_config_write (struct vty *vty)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf))
|
||||
{
|
||||
if (strcmp(zvrf->name, VRF_DEFAULT_NAME))
|
||||
{
|
||||
vty_out (vty, "vrf %s%s", zvrf->name, VTY_NEWLINE);
|
||||
vty_out (vty, "!%s", VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate and initialize interface vector. */
|
||||
void
|
||||
zebra_if_init (void)
|
||||
|
@ -2909,7 +2877,6 @@ zebra_if_init (void)
|
|||
/* Install configuration write function. */
|
||||
install_node (&interface_node, if_config_write);
|
||||
install_node (&link_params_node, NULL);
|
||||
install_node (&vrf_node, vrf_config_write);
|
||||
if_cmd_init ();
|
||||
|
||||
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, &no_link_params_enable_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_max_rsv_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, &no_link_params_use_bw_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
|
||||
|
||||
vrf_cmd_init();
|
||||
}
|
||||
|
|
|
@ -304,17 +304,16 @@ void process_solicit (struct interface *ifp)
|
|||
|
||||
void irdp_finish()
|
||||
{
|
||||
|
||||
struct vrf *vrf;
|
||||
struct listnode *node, *nnode;
|
||||
struct interface *ifp;
|
||||
struct zebra_if *zi;
|
||||
struct irdp_interface *irdp;
|
||||
vrf_iter_t iter;
|
||||
|
||||
zlog_info("IRDP: Received shutdown notification.");
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp))
|
||||
{
|
||||
zi = ifp->info;
|
||||
|
||||
|
|
|
@ -282,7 +282,7 @@ send_packet(struct interface *ifp,
|
|||
char buf[256];
|
||||
struct in_pktinfo *pktinfo;
|
||||
u_long src;
|
||||
int on;
|
||||
u_char on;
|
||||
|
||||
if (!(ifp->flags & IFF_UP))
|
||||
return;
|
||||
|
@ -323,12 +323,8 @@ send_packet(struct interface *ifp,
|
|||
zlog_warn("sendto %s", safe_strerror (errno));
|
||||
}
|
||||
|
||||
if(dst != INADDR_BROADCAST) {
|
||||
on = 0;
|
||||
if( setsockopt(irdp_sock,IPPROTO_IP, IP_MULTICAST_LOOP,
|
||||
(char *)&on,sizeof(on)) < 0)
|
||||
zlog_warn("sendto %s", safe_strerror (errno));
|
||||
}
|
||||
if(dst != INADDR_BROADCAST)
|
||||
setsockopt_ipv4_multicast_loop (irdp_sock, 0);
|
||||
|
||||
memset(&sockdst,0,sizeof(sockdst));
|
||||
sockdst.sin_family=AF_INET;
|
||||
|
|
|
@ -716,11 +716,18 @@ kernel_init (struct zebra_ns *zns)
|
|||
{
|
||||
unsigned long groups;
|
||||
|
||||
groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR;
|
||||
#ifdef HAVE_IPV6
|
||||
groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
|
||||
#endif /* HAVE_IPV6 */
|
||||
/* Initialize netlink sockets */
|
||||
groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR |
|
||||
RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
|
||||
|
||||
snprintf (zns->netlink.name, sizeof (zns->netlink.name),
|
||||
"netlink-listen (NS %u)", zns->ns_id);
|
||||
zns->netlink.sock = -1;
|
||||
netlink_socket (&zns->netlink, groups, zns->ns_id);
|
||||
|
||||
snprintf (zns->netlink_cmd.name, sizeof (zns->netlink_cmd.name),
|
||||
"netlink-cmd (NS %u)", zns->ns_id);
|
||||
zns->netlink_cmd.sock = -1;
|
||||
netlink_socket (&zns->netlink_cmd, 0, zns->ns_id);
|
||||
|
||||
/* Register kernel socket. */
|
||||
|
|
30
zebra/main.c
30
zebra/main.c
|
@ -182,20 +182,46 @@ sighup (void)
|
|||
static void
|
||||
sigint (void)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
struct zebra_ns *zns;
|
||||
|
||||
zlog_notice ("Terminating on signal");
|
||||
|
||||
if (!retain_mode)
|
||||
rib_close ();
|
||||
#ifdef HAVE_IRDP
|
||||
irdp_finish();
|
||||
#endif
|
||||
|
||||
zebra_ptm_finish();
|
||||
list_delete_all_node (zebrad.client_list);
|
||||
|
||||
if (retain_mode)
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
zvrf = vrf->info;
|
||||
if (zvrf)
|
||||
SET_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN);
|
||||
}
|
||||
vrf_terminate ();
|
||||
|
||||
zns = zebra_ns_lookup (NS_DEFAULT);
|
||||
zebra_ns_disable (0, (void **)&zns);
|
||||
|
||||
access_list_reset ();
|
||||
prefix_list_reset ();
|
||||
route_map_finish ();
|
||||
cmd_terminate ();
|
||||
vty_terminate ();
|
||||
zprivs_terminate (&zserv_privs);
|
||||
list_delete (zebrad.client_list);
|
||||
work_queue_free (zebrad.ribq);
|
||||
if (zebrad.lsp_process_q)
|
||||
work_queue_free (zebrad.lsp_process_q);
|
||||
meta_queue_free (zebrad.mq);
|
||||
thread_master_free (zebrad.master);
|
||||
if (zlog_default)
|
||||
closezlog (zlog_default);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -262,13 +262,13 @@ zebra_redistribute_add (int command, struct zserv *client, int length,
|
|||
if (! redist_check_instance (&client->mi_redist[afi][type], instance))
|
||||
{
|
||||
redist_add_instance (&client->mi_redist[afi][type], instance);
|
||||
zebra_redistribute (client, type, instance, zvrf->vrf_id);
|
||||
zebra_redistribute (client, type, instance, zvrf_id (zvrf));
|
||||
}
|
||||
} else {
|
||||
if (! vrf_bitmap_check (client->redist[afi][type], zvrf->vrf_id))
|
||||
if (! vrf_bitmap_check (client->redist[afi][type], zvrf_id (zvrf)))
|
||||
{
|
||||
vrf_bitmap_set (client->redist[afi][type], zvrf->vrf_id);
|
||||
zebra_redistribute (client, type, 0, zvrf->vrf_id);
|
||||
vrf_bitmap_set (client->redist[afi][type], zvrf_id (zvrf));
|
||||
zebra_redistribute (client, type, 0, zvrf_id (zvrf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -296,22 +296,22 @@ zebra_redistribute_delete (int command, struct zserv *client, int length,
|
|||
if (instance)
|
||||
redist_del_instance (&client->mi_redist[afi][type], instance);
|
||||
else
|
||||
vrf_bitmap_unset (client->redist[afi][type], zvrf->vrf_id);
|
||||
vrf_bitmap_unset (client->redist[afi][type], zvrf_id (zvrf));
|
||||
}
|
||||
|
||||
void
|
||||
zebra_redistribute_default_add (int command, struct zserv *client, int length,
|
||||
struct zebra_vrf *zvrf)
|
||||
{
|
||||
vrf_bitmap_set (client->redist_default, zvrf->vrf_id);
|
||||
zebra_redistribute_default (client, zvrf->vrf_id);
|
||||
vrf_bitmap_set (client->redist_default, zvrf_id (zvrf));
|
||||
zebra_redistribute_default (client, zvrf_id (zvrf));
|
||||
}
|
||||
|
||||
void
|
||||
zebra_redistribute_default_delete (int command, struct zserv *client,
|
||||
int length, struct zebra_vrf *zvrf)
|
||||
{
|
||||
vrf_bitmap_unset (client->redist_default, zvrf->vrf_id);
|
||||
vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf));
|
||||
}
|
||||
|
||||
/* Interface up information. */
|
||||
|
|
|
@ -366,13 +366,14 @@ extern void rib_update (vrf_id_t, rib_update_event_t);
|
|||
extern void rib_weed_tables (void);
|
||||
extern void rib_sweep_route (void);
|
||||
extern void rib_close_table (struct route_table *);
|
||||
extern void rib_close (void);
|
||||
extern void rib_init (void);
|
||||
extern unsigned long rib_score_proto (u_char proto, u_short instance);
|
||||
extern void rib_queue_add (struct route_node *rn);
|
||||
extern void meta_queue_free (struct meta_queue *mq);
|
||||
|
||||
extern struct route_table *rib_table_ipv6;
|
||||
|
||||
extern void rib_unlink (struct route_node *, struct rib *);
|
||||
extern int rib_gc_dest (struct route_node *rn);
|
||||
extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ router_id_add_address (struct connected *ifc)
|
|||
if (router_id_bad_address (ifc))
|
||||
return;
|
||||
|
||||
router_id_get (&before, zvrf->vrf_id);
|
||||
router_id_get (&before, zvrf_id (zvrf));
|
||||
|
||||
if (!strncmp (ifc->ifp->name, "lo", 2)
|
||||
|| !strncmp (ifc->ifp->name, "dummy", 5))
|
||||
|
@ -149,13 +149,13 @@ router_id_add_address (struct connected *ifc)
|
|||
if (!router_id_find_node (l, ifc))
|
||||
listnode_add_sort (l, ifc);
|
||||
|
||||
router_id_get (&after, zvrf->vrf_id);
|
||||
router_id_get (&after, zvrf_id (zvrf));
|
||||
|
||||
if (prefix_same (&before, &after))
|
||||
return;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
|
||||
zsend_router_id_update (client, &after, zvrf->vrf_id);
|
||||
zsend_router_id_update (client, &after, zvrf_id (zvrf));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -172,7 +172,7 @@ router_id_del_address (struct connected *ifc)
|
|||
if (router_id_bad_address (ifc))
|
||||
return;
|
||||
|
||||
router_id_get (&before, zvrf->vrf_id);
|
||||
router_id_get (&before, zvrf_id (zvrf));
|
||||
|
||||
if (!strncmp (ifc->ifp->name, "lo", 2)
|
||||
|| !strncmp (ifc->ifp->name, "dummy", 5))
|
||||
|
@ -183,33 +183,33 @@ router_id_del_address (struct connected *ifc)
|
|||
if ((c = router_id_find_node (l, ifc)))
|
||||
listnode_delete (l, c);
|
||||
|
||||
router_id_get (&after, zvrf->vrf_id);
|
||||
router_id_get (&after, zvrf_id (zvrf));
|
||||
|
||||
if (prefix_same (&before, &after))
|
||||
return;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
|
||||
zsend_router_id_update (client, &after, zvrf->vrf_id);
|
||||
zsend_router_id_update (client, &after, zvrf_id (zvrf));
|
||||
}
|
||||
|
||||
void
|
||||
router_id_write (struct vty *vty)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
if (zvrf->rid_user_assigned.u.prefix4.s_addr)
|
||||
{
|
||||
if (zvrf->vrf_id == VRF_DEFAULT)
|
||||
if (zvrf_id (zvrf) == VRF_DEFAULT)
|
||||
vty_out (vty, "router-id %s%s",
|
||||
inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
|
||||
VTY_NEWLINE);
|
||||
else
|
||||
vty_out (vty, "router-id %s vrf %s%s",
|
||||
inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
|
||||
zvrf->name,
|
||||
zvrf_name (zvrf),
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,16 +99,16 @@ Pending: create an efficient table_id (in a tree/hash) based lookup)
|
|||
static vrf_id_t
|
||||
vrf_lookup_by_table (u_int32_t table_id)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(zvrf->table_id != table_id))
|
||||
continue;
|
||||
|
||||
return zvrf->vrf_id;
|
||||
return zvrf_id (zvrf);
|
||||
}
|
||||
|
||||
return VRF_DEFAULT;
|
||||
|
@ -1069,7 +1069,7 @@ _netlink_route_debug(
|
|||
zlog_debug ("netlink_route_multipath() (%s): %s %s vrf %u type %s",
|
||||
routedesc,
|
||||
nl_msg_type_to_str (cmd),
|
||||
prefix2str (p, buf, sizeof(buf)), zvrf->vrf_id,
|
||||
prefix2str (p, buf, sizeof(buf)), zvrf_id (zvrf),
|
||||
(nexthop) ? nexthop_type_to_str (nexthop->type) : "UNK");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -374,7 +374,7 @@ static int
|
|||
rtadv_timer (struct thread *thread)
|
||||
{
|
||||
struct zebra_ns *zns = THREAD_ARG (thread);
|
||||
vrf_iter_t iter;
|
||||
struct vrf *vrf;
|
||||
struct listnode *node, *nnode;
|
||||
struct interface *ifp;
|
||||
struct zebra_if *zif;
|
||||
|
@ -392,8 +392,8 @@ rtadv_timer (struct thread *thread)
|
|||
rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */);
|
||||
}
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp))
|
||||
{
|
||||
if (if_is_loopback (ifp) ||
|
||||
CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) ||
|
||||
|
@ -827,7 +827,7 @@ zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
|
|||
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
|
||||
zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
|
||||
zvrf_id (zvrf), ifindex, enable ? "enable" : "disable",
|
||||
zebra_route_string(client->proto), ra_interval);
|
||||
|
||||
/* Locate interface and check VRF match. */
|
||||
|
@ -835,14 +835,14 @@ zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
|
|||
if (!ifp)
|
||||
{
|
||||
zlog_warn("%u: IF %u RA %s client %s - interface unknown",
|
||||
zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
|
||||
zvrf_id (zvrf), ifindex, enable ? "enable" : "disable",
|
||||
zebra_route_string(client->proto));
|
||||
return;
|
||||
}
|
||||
if (ifp->vrf_id != zvrf->vrf_id)
|
||||
if (ifp->vrf_id != zvrf_id (zvrf))
|
||||
{
|
||||
zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
|
||||
zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
|
||||
zvrf_id (zvrf), ifindex, enable ? "enable" : "disable",
|
||||
zebra_route_string(client->proto), ifp->vrf_id);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -348,7 +348,7 @@ zfpm_is_table_for_fpm (struct route_table *table)
|
|||
* We only send the unicast tables in the main instance to the FPM
|
||||
* at this point.
|
||||
*/
|
||||
if (info->zvrf->vrf_id != 0)
|
||||
if (zvrf_id (info->zvrf) != 0)
|
||||
return 0;
|
||||
|
||||
if (info->safi != SAFI_UNICAST)
|
||||
|
|
|
@ -246,7 +246,7 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
|
|||
ri->af = rib_dest_af (dest);
|
||||
|
||||
ri->nlmsg_type = cmd;
|
||||
ri->rtm_table = rib_dest_vrf (dest)->vrf_id;
|
||||
ri->rtm_table = zvrf_id (rib_dest_vrf (dest));
|
||||
ri->rtm_protocol = RTPROT_UNSPEC;
|
||||
|
||||
/*
|
||||
|
|
|
@ -35,6 +35,5 @@ DECLARE_MTYPE(STATIC_ROUTE)
|
|||
DECLARE_MTYPE(RIB_DEST)
|
||||
DECLARE_MTYPE(RIB_TABLE_INFO)
|
||||
DECLARE_MTYPE(RNH)
|
||||
DECLARE_MTYPE(NETLINK_NAME)
|
||||
|
||||
#endif /* _QUAGGA_ZEBRA_MEMORY_H */
|
||||
|
|
|
@ -1267,7 +1267,7 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
|
|||
struct nexthop *nexthop;
|
||||
|
||||
/* Lookup table. */
|
||||
table = zebra_vrf_table (family2afi(prefix->family), SAFI_UNICAST, zvrf->vrf_id);
|
||||
table = zebra_vrf_table (family2afi(prefix->family), SAFI_UNICAST, zvrf_id (zvrf));
|
||||
if (! table)
|
||||
return -1;
|
||||
|
||||
|
@ -1501,7 +1501,7 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)
|
|||
int update;
|
||||
|
||||
/* Process routes of interested address-families. */
|
||||
table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf->vrf_id);
|
||||
table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf_id (zvrf));
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
|
@ -1828,7 +1828,7 @@ zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf,
|
|||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
list_delete_all_node(lsp_list);
|
||||
list_delete (lsp_list);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1868,7 +1868,7 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf)
|
|||
}
|
||||
}
|
||||
|
||||
list_delete_all_node(slsp_list);
|
||||
list_delete (slsp_list);
|
||||
return (zvrf->slsp_table->count ? 1 : 0);
|
||||
}
|
||||
|
||||
|
@ -1880,9 +1880,11 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf)
|
|||
void
|
||||
zebra_mpls_close_tables (struct zebra_vrf *zvrf)
|
||||
{
|
||||
if (!zvrf)
|
||||
return;
|
||||
hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL);
|
||||
hash_clean(zvrf->lsp_table, NULL);
|
||||
hash_free(zvrf->lsp_table);
|
||||
hash_clean(zvrf->slsp_table, NULL);
|
||||
hash_free(zvrf->slsp_table);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "zebra_memory.h"
|
||||
|
||||
DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space")
|
||||
DEFINE_MTYPE(ZEBRA, NETLINK_NAME, "Netlink name")
|
||||
|
||||
struct zebra_ns *dzns;
|
||||
|
||||
|
@ -46,24 +45,11 @@ int
|
|||
zebra_ns_enable (ns_id_t ns_id, void **info)
|
||||
{
|
||||
struct zebra_ns *zns = (struct zebra_ns *) (*info);
|
||||
#ifdef HAVE_NETLINK
|
||||
char nl_name[64];
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_RTADV)
|
||||
rtadv_init (zns);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETLINK
|
||||
/* Initialize netlink sockets */
|
||||
snprintf (nl_name, 64, "netlink-listen (NS %u)", ns_id);
|
||||
zns->netlink.sock = -1;
|
||||
zns->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
|
||||
|
||||
snprintf (nl_name, 64, "netlink-cmd (NS %u)", ns_id);
|
||||
zns->netlink_cmd.sock = -1;
|
||||
zns->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
|
||||
#endif
|
||||
zns->if_table = route_table_init ();
|
||||
kernel_init (zns);
|
||||
interface_list (zns);
|
||||
|
@ -77,6 +63,7 @@ zebra_ns_disable (ns_id_t ns_id, void **info)
|
|||
{
|
||||
struct zebra_ns *zns = (struct zebra_ns *) (*info);
|
||||
|
||||
route_table_finish (zns->if_table);
|
||||
#if defined (HAVE_RTADV)
|
||||
rtadv_terminate (zns);
|
||||
#endif
|
||||
|
|
|
@ -32,7 +32,7 @@ struct nlsock
|
|||
int sock;
|
||||
int seq;
|
||||
struct sockaddr_nl snl;
|
||||
const char *name;
|
||||
char name[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -140,6 +140,8 @@ zebra_ptm_finish(void)
|
|||
|
||||
buffer_flush_all(ptm_cb.wb, ptm_cb.ptm_sock);
|
||||
|
||||
free (ptm_hdl);
|
||||
|
||||
if (ptm_cb.out_data)
|
||||
free(ptm_cb.out_data);
|
||||
|
||||
|
@ -256,15 +258,15 @@ DEFUN (zebra_ptm_enable,
|
|||
"ptm-enable",
|
||||
"Enable neighbor check with specified topology\n")
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct listnode *i;
|
||||
struct interface *ifp;
|
||||
struct zebra_if *if_data;
|
||||
vrf_iter_t iter;
|
||||
|
||||
ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), i, ifp))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp))
|
||||
if (!ifp->ptm_enable)
|
||||
{
|
||||
if_data = (struct zebra_if *)ifp->info;
|
||||
|
@ -766,9 +768,9 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
|
|||
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD,
|
||||
tmp_buf);
|
||||
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
if (zvrf_id (zvrf) != VRF_DEFAULT)
|
||||
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD,
|
||||
zvrf->name);
|
||||
zvrf_name (zvrf));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -913,9 +915,9 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length,
|
|||
ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
if (zvrf_id (zvrf) != VRF_DEFAULT)
|
||||
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD,
|
||||
zvrf->name);
|
||||
zvrf_name (zvrf));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1110,13 +1112,13 @@ zebra_ptm_send_status_req(void)
|
|||
void
|
||||
zebra_ptm_reset_status(int ptm_disable)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct listnode *i;
|
||||
struct interface *ifp;
|
||||
int send_linkup;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), i, ifp))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp))
|
||||
{
|
||||
send_linkup = 0;
|
||||
if (ifp->ptm_enable)
|
||||
|
|
|
@ -1303,8 +1303,6 @@ rib_uninstall (struct route_node *rn, struct rib *rib)
|
|||
}
|
||||
}
|
||||
|
||||
static void rib_unlink (struct route_node *, struct rib *);
|
||||
|
||||
/*
|
||||
* rib_can_delete_dest
|
||||
*
|
||||
|
@ -1352,7 +1350,7 @@ rib_gc_dest (struct route_node *rn)
|
|||
|
||||
zvrf = rib_dest_vrf (dest);
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
rnode_debug (rn, zvrf->vrf_id, "removing dest from table");
|
||||
rnode_debug (rn, zvrf_id (zvrf), "removing dest from table");
|
||||
|
||||
dest->rnode = NULL;
|
||||
XFREE (MTYPE_RIB_DEST, dest);
|
||||
|
@ -1385,7 +1383,7 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
|||
{
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)",
|
||||
zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type);
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type);
|
||||
}
|
||||
|
||||
if (!RIB_SYSTEM_ROUTE (new))
|
||||
|
@ -1394,7 +1392,7 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
|||
{
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_warn ("%u:%s/%d: Route install failed",
|
||||
zvrf->vrf_id, buf, rn->p.prefixlen);
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1414,7 +1412,7 @@ rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
|||
{
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)",
|
||||
zvrf->vrf_id, buf, rn->p.prefixlen, rn, old, old->type);
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, old, old->type);
|
||||
}
|
||||
|
||||
if (!RIB_SYSTEM_ROUTE (old))
|
||||
|
@ -1463,11 +1461,11 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
|
|||
{
|
||||
if (new != old)
|
||||
zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) "
|
||||
"old %p (type %d)", zvrf->vrf_id, buf, rn->p.prefixlen,
|
||||
"old %p (type %d)", zvrf_id (zvrf), buf, rn->p.prefixlen,
|
||||
rn, new, new->type, old, old->type);
|
||||
else
|
||||
zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)",
|
||||
zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type);
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type);
|
||||
}
|
||||
/* Non-system route should be installed. */
|
||||
if (!RIB_SYSTEM_ROUTE (new))
|
||||
|
@ -1477,7 +1475,7 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
|
|||
installed = 0;
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_warn ("%u:%s/%d: Route install failed",
|
||||
zvrf->vrf_id, buf, rn->p.prefixlen);
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1511,12 +1509,12 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
|
|||
{
|
||||
if (new != old)
|
||||
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) "
|
||||
"old %p (type %d) - %s", zvrf->vrf_id, buf, rn->p.prefixlen,
|
||||
"old %p (type %d) - %s", zvrf_id (zvrf), buf, rn->p.prefixlen,
|
||||
rn, new, new->type, old, old->type,
|
||||
nh_active ? "install failed" : "nexthop inactive");
|
||||
else
|
||||
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) - %s",
|
||||
zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type,
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type,
|
||||
nh_active ? "install failed" : "nexthop inactive");
|
||||
}
|
||||
|
||||
|
@ -1626,7 +1624,7 @@ rib_process (struct route_node *rn)
|
|||
if (dest)
|
||||
{
|
||||
zvrf = rib_dest_vrf (dest);
|
||||
vrf_id = zvrf->vrf_id;
|
||||
vrf_id = zvrf_id (zvrf);
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
|
@ -2026,7 +2024,7 @@ process_subq (struct list * subq, u_char qindex)
|
|||
{
|
||||
inet_ntop (rnode->p.family, &rnode->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: rn %p dequeued from sub-queue %u",
|
||||
zvrf ? zvrf->vrf_id : 0, buf, rnode->p.prefixlen, rnode, qindex);
|
||||
zvrf ? zvrf_id (zvrf) : 0, buf, rnode->p.prefixlen, rnode, qindex);
|
||||
}
|
||||
|
||||
if (rnode->info)
|
||||
|
@ -2051,24 +2049,24 @@ process_subq (struct list * subq, u_char qindex)
|
|||
static void
|
||||
meta_queue_process_complete (struct work_queue *dummy)
|
||||
{
|
||||
vrf_iter_t iter;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
/* Evaluate nexthops for those VRFs which underwent route processing. This
|
||||
* should limit the evaluation to the necessary VRFs in most common
|
||||
* situations.
|
||||
*/
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
{
|
||||
if (((zvrf = vrf_iter2info (iter)) != NULL) &&
|
||||
(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED))
|
||||
{
|
||||
zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED;
|
||||
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL);
|
||||
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL);
|
||||
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL);
|
||||
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL);
|
||||
}
|
||||
zvrf = vrf->info;
|
||||
if (zvrf == NULL || !(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED))
|
||||
continue;
|
||||
|
||||
zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED;
|
||||
zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_NEXTHOP_TYPE, NULL);
|
||||
zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL);
|
||||
zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL);
|
||||
zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL);
|
||||
}
|
||||
|
||||
/* Schedule LSPs for processing, if needed. */
|
||||
|
@ -2076,7 +2074,7 @@ meta_queue_process_complete (struct work_queue *dummy)
|
|||
if (mpls_should_lsps_be_processed(zvrf))
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_MPLS)
|
||||
zlog_debug ("%u: Scheduling all LSPs upon RIB completion", zvrf->vrf_id);
|
||||
zlog_debug ("%u: Scheduling all LSPs upon RIB completion", zvrf_id (zvrf));
|
||||
zebra_mpls_lsp_schedule (zvrf);
|
||||
mpls_unmark_lsps_for_processing(zvrf);
|
||||
}
|
||||
|
@ -2151,7 +2149,7 @@ rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
|
|||
rnode_debug (rn, rib->vrf_id, "queued rn %p into sub-queue %u",
|
||||
(void *)rn, qindex);
|
||||
|
||||
zvrf = zebra_vrf_lookup (rib->vrf_id);
|
||||
zvrf = zebra_vrf_lookup_by_id (rib->vrf_id);
|
||||
if (zvrf)
|
||||
zvrf->flags |= ZEBRA_VRF_RIB_SCHEDULED;
|
||||
}
|
||||
|
@ -2215,6 +2213,17 @@ meta_queue_new (void)
|
|||
return new;
|
||||
}
|
||||
|
||||
void
|
||||
meta_queue_free (struct meta_queue *mq)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < MQ_SIZE; i++)
|
||||
list_delete (mq->subq[i]);
|
||||
|
||||
XFREE (MTYPE_WORK_QUEUE, mq);
|
||||
}
|
||||
|
||||
/* initialise zebra rib work queue */
|
||||
static void
|
||||
rib_queue_init (struct zebra_t *zebra)
|
||||
|
@ -2350,7 +2359,7 @@ rib_addnode (struct route_node *rn, struct rib *rib, int process)
|
|||
* rib_gc_dest() at some point. This allows a rib_dest_t that is no
|
||||
* longer required to be deleted.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
rib_unlink (struct route_node *rn, struct rib *rib)
|
||||
{
|
||||
rib_dest_t *dest;
|
||||
|
@ -3036,11 +3045,11 @@ rib_weed_table (struct route_table *table)
|
|||
void
|
||||
rib_weed_tables (void)
|
||||
{
|
||||
vrf_iter_t iter;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
{
|
||||
rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||
rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||
|
@ -3077,11 +3086,11 @@ rib_sweep_table (struct route_table *table)
|
|||
void
|
||||
rib_sweep_route (void)
|
||||
{
|
||||
vrf_iter_t iter;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
{
|
||||
rib_sweep_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||
rib_sweep_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||
|
@ -3117,12 +3126,12 @@ rib_score_proto_table (u_char proto, u_short instance, struct route_table *table
|
|||
unsigned long
|
||||
rib_score_proto (u_char proto, u_short instance)
|
||||
{
|
||||
vrf_iter_t iter;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
unsigned long cnt = 0;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
cnt += rib_score_proto_table (proto, instance, zvrf->table[AFI_IP][SAFI_UNICAST])
|
||||
+rib_score_proto_table (proto, instance, zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||
|
||||
|
@ -3152,43 +3161,6 @@ rib_close_table (struct route_table *table)
|
|||
}
|
||||
}
|
||||
|
||||
/* Close all RIB tables. */
|
||||
void
|
||||
rib_close (void)
|
||||
{
|
||||
vrf_iter_t iter;
|
||||
struct zebra_vrf *zvrf;
|
||||
struct listnode *node;
|
||||
struct interface *ifp;
|
||||
u_int32_t table_id;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
{
|
||||
rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||
rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||
}
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
|
||||
}
|
||||
|
||||
/* If we do multiple tables per vrf, need to move this to loop above */
|
||||
zvrf = vrf_info_lookup (VRF_DEFAULT);
|
||||
|
||||
for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
|
||||
{
|
||||
if (zvrf->other_table[AFI_IP][table_id])
|
||||
rib_close_table (zvrf->other_table[AFI_IP][table_id]);
|
||||
|
||||
if (zvrf->other_table[AFI_IP6][table_id])
|
||||
rib_close_table (zvrf->other_table[AFI_IP6][table_id]);
|
||||
}
|
||||
|
||||
zebra_mpls_close_tables(zvrf);
|
||||
|
||||
}
|
||||
|
||||
/* Routing information base initialize. */
|
||||
void
|
||||
rib_init (void)
|
||||
|
@ -3206,17 +3178,16 @@ rib_init (void)
|
|||
static inline int
|
||||
vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
|
||||
{
|
||||
vrf_iter_t iter = vrf_iterator (vrf_id);
|
||||
struct zebra_vrf *zvrf = vrf_iter2info (iter);
|
||||
struct vrf *vrf;
|
||||
|
||||
/* The same one ? Then find out the next. */
|
||||
if (zvrf && (zvrf->vrf_id == vrf_id))
|
||||
zvrf = vrf_iter2info (vrf_next (iter));
|
||||
|
||||
if (zvrf)
|
||||
vrf = vrf_lookup_by_id (vrf_id);
|
||||
if (vrf)
|
||||
{
|
||||
*next_id_p = zvrf->vrf_id;
|
||||
return 1;
|
||||
vrf = RB_NEXT (vrf_id_head, &vrfs_by_id, vrf);
|
||||
if (vrf) {
|
||||
*next_id_p = vrf->vrf_id;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -56,7 +56,7 @@ static void copy_state(struct rnh *rnh, struct rib *rib,
|
|||
({ \
|
||||
struct zebra_vrf *zvrf; \
|
||||
struct route_table *t = NULL; \
|
||||
zvrf = zebra_vrf_lookup(v); \
|
||||
zvrf = zebra_vrf_lookup_by_id(v); \
|
||||
if (zvrf) \
|
||||
t = zvrf->rnh_table[family2afi(f)]; \
|
||||
t; \
|
||||
|
@ -76,7 +76,7 @@ static inline struct route_table *get_rnh_table(vrf_id_t vrfid, int family,
|
|||
struct zebra_vrf *zvrf;
|
||||
struct route_table *t = NULL;
|
||||
|
||||
zvrf = zebra_vrf_lookup(vrfid);
|
||||
zvrf = zebra_vrf_lookup_by_id(vrfid);
|
||||
if (zvrf)
|
||||
switch (type)
|
||||
{
|
||||
|
@ -162,6 +162,16 @@ zebra_lookup_rnh (struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
|
|||
return (rn->info);
|
||||
}
|
||||
|
||||
void
|
||||
zebra_free_rnh (struct rnh *rnh)
|
||||
{
|
||||
rnh->flags |= ZEBRA_NHT_DELETED;
|
||||
list_free (rnh->client_list);
|
||||
list_free (rnh->zebra_static_route_list);
|
||||
free_state (rnh->vrf_id, rnh->state, rnh->node);
|
||||
XFREE (MTYPE_RNH, rnh);
|
||||
}
|
||||
|
||||
void
|
||||
zebra_delete_rnh (struct rnh *rnh, rnh_type_t type)
|
||||
{
|
||||
|
@ -177,14 +187,9 @@ zebra_delete_rnh (struct rnh *rnh, rnh_type_t type)
|
|||
rnh->vrf_id, rnh_str(rnh, buf, sizeof (buf)), type);
|
||||
}
|
||||
|
||||
rnh->flags |= ZEBRA_NHT_DELETED;
|
||||
list_free(rnh->client_list);
|
||||
list_free(rnh->zebra_static_route_list);
|
||||
free_state(rnh->vrf_id, rnh->state, rn);
|
||||
XFREE(MTYPE_RNH, rn->info);
|
||||
zebra_free_rnh (rnh);
|
||||
rn->info = NULL;
|
||||
route_unlock_node (rn);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -59,6 +59,7 @@ extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid,
|
|||
rnh_type_t type);
|
||||
extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid,
|
||||
rnh_type_t type);
|
||||
extern void zebra_free_rnh (struct rnh *rnh);
|
||||
extern void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type);
|
||||
extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
|
||||
vrf_id_t vrfid);
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
int zebra_rnh_ip_default_route = 0;
|
||||
int zebra_rnh_ipv6_default_route = 0;
|
||||
|
||||
void
|
||||
zebra_free_rnh (struct rnh *rnh)
|
||||
{}
|
||||
|
||||
void zebra_evaluate_rnh (vrf_id_t vrfid, int family, int force, rnh_type_t type,
|
||||
struct prefix *p)
|
||||
{}
|
||||
|
|
|
@ -345,7 +345,7 @@ DEFUN (set_src,
|
|||
struct interface *pif = NULL;
|
||||
int family;
|
||||
struct prefix p;
|
||||
vrf_iter_t iter;
|
||||
struct vrf *vrf;
|
||||
|
||||
if (inet_pton(AF_INET, argv[idx_ip]->arg, &src.ipv4) != 1)
|
||||
{
|
||||
|
@ -372,14 +372,14 @@ DEFUN (set_src,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
{
|
||||
if (family == AF_INET)
|
||||
pif = if_lookup_exact_address_vrf ((void *)&src.ipv4, AF_INET,
|
||||
vrf_iter2id (iter));
|
||||
vrf->vrf_id);
|
||||
else if (family == AF_INET6)
|
||||
pif = if_lookup_exact_address_vrf ((void *)&src.ipv6, AF_INET6,
|
||||
vrf_iter2id (iter));
|
||||
vrf->vrf_id);
|
||||
|
||||
if (pif != NULL)
|
||||
break;
|
||||
|
|
|
@ -130,7 +130,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
|
|||
rib->metric = 0;
|
||||
rib->mtu = 0;
|
||||
rib->vrf_id = si->vrf_id;
|
||||
rib->table = si->vrf_id ? (zebra_vrf_lookup(si->vrf_id))->table_id : zebrad.rtm_table_default;
|
||||
rib->table = si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default;
|
||||
rib->nexthop_num = 0;
|
||||
rib->tag = si->tag;
|
||||
|
||||
|
@ -423,7 +423,7 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
|
|||
si->distance = distance;
|
||||
si->flags = flags;
|
||||
si->tag = tag;
|
||||
si->vrf_id = zvrf->vrf_id;
|
||||
si->vrf_id = zvrf_id (zvrf);
|
||||
si->ifindex = ifindex;
|
||||
if (si->ifindex)
|
||||
strcpy(si->ifname, ifname);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "log.h"
|
||||
#include "linklist.h"
|
||||
#include "command.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "vty.h"
|
||||
|
@ -30,13 +31,14 @@
|
|||
#include "zebra/zserv.h"
|
||||
#include "zebra/rib.h"
|
||||
#include "zebra/zebra_vrf.h"
|
||||
#include "zebra/zebra_rnh.h"
|
||||
#include "zebra/router-id.h"
|
||||
#include "zebra/zebra_memory.h"
|
||||
#include "zebra/zebra_static.h"
|
||||
#include "zebra/interface.h"
|
||||
#include "zebra/zebra_mpls.h"
|
||||
|
||||
extern struct zebra_t zebrad;
|
||||
struct list *zvrf_list;
|
||||
|
||||
/* VRF information update. */
|
||||
static void
|
||||
|
@ -46,7 +48,7 @@ zebra_vrf_add_update (struct zebra_vrf *zvrf)
|
|||
struct zserv *client;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf->name);
|
||||
zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf_name (zvrf));
|
||||
|
||||
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
|
||||
zsend_vrf_add (client, zvrf);
|
||||
|
@ -59,7 +61,7 @@ zebra_vrf_delete_update (struct zebra_vrf *zvrf)
|
|||
struct zserv *client;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf->name);
|
||||
zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf_name (zvrf));
|
||||
|
||||
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
|
||||
zsend_vrf_delete (client, zvrf);
|
||||
|
@ -69,44 +71,28 @@ void
|
|||
zebra_vrf_update_all (struct zserv *client)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
{
|
||||
if ((vrf = vrf_iter2vrf (iter)) && vrf->vrf_id)
|
||||
if (vrf->vrf_id)
|
||||
zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id));
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback upon creating a new VRF. */
|
||||
static int
|
||||
zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
|
||||
zebra_vrf_new (struct vrf *vrf)
|
||||
{
|
||||
struct zebra_vrf *zvrf = *info;
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_info ("ZVRF %s with id %u", name, vrf_id);
|
||||
zlog_info ("ZVRF %s with id %u", vrf->name, vrf->vrf_id);
|
||||
|
||||
if (! zvrf)
|
||||
{
|
||||
zvrf = zebra_vrf_list_lookup_by_name (name);
|
||||
if (!zvrf)
|
||||
{
|
||||
zvrf = zebra_vrf_alloc (vrf_id, name);
|
||||
zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */
|
||||
*info = (void *)zvrf;
|
||||
router_id_init (zvrf);
|
||||
listnode_add_sort (zvrf_list, zvrf);
|
||||
}
|
||||
else
|
||||
{
|
||||
*info = (void *)zvrf;
|
||||
router_id_init (zvrf);
|
||||
}
|
||||
}
|
||||
|
||||
if (zvrf->vrf_id == VRF_UNKNOWN)
|
||||
zvrf->vrf_id = vrf_id;
|
||||
zvrf = zebra_vrf_alloc ();
|
||||
zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */
|
||||
router_id_init (zvrf);
|
||||
vrf->info = zvrf;
|
||||
zvrf->vrf = vrf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -123,7 +109,7 @@ zebra_vrf_static_route_interface_fixup (struct interface *ifp)
|
|||
{
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
struct zebra_vrf *zvrf = zebra_vrf_lookup (ifp->vrf_id);
|
||||
struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id (ifp->vrf_id);
|
||||
struct route_table *stable = NULL;
|
||||
struct route_node *rn = NULL;
|
||||
struct static_route *si = NULL;
|
||||
|
@ -157,13 +143,13 @@ zebra_vrf_static_route_interface_fixup (struct interface *ifp)
|
|||
|
||||
/* Callback upon enabling a VRF. */
|
||||
static int
|
||||
zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
zebra_vrf_enable (struct vrf *vrf)
|
||||
{
|
||||
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
|
||||
struct route_table *stable = NULL;
|
||||
struct route_node *rn = NULL;
|
||||
struct static_route *si = NULL;
|
||||
struct interface *ifp = NULL;
|
||||
struct zebra_vrf *zvrf = vrf->info;
|
||||
struct route_table *stable;
|
||||
struct route_node *rn;
|
||||
struct static_route *si;
|
||||
struct interface *ifp;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
|
||||
|
@ -172,85 +158,145 @@ zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
|
|||
zebra_vrf_add_update (zvrf);
|
||||
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
||||
{
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
|
||||
{
|
||||
stable = zvrf->stable[afi][safi];
|
||||
if (stable)
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
|
||||
{
|
||||
stable = zvrf->stable[afi][safi];
|
||||
if (! stable)
|
||||
continue;
|
||||
|
||||
for (rn = route_top (stable); rn; rn = route_next (rn))
|
||||
for (si = rn->info; si; si = si->next)
|
||||
{
|
||||
for (rn = route_top (stable); rn; rn = route_next (rn))
|
||||
si->vrf_id = vrf->vrf_id;
|
||||
if (si->ifindex)
|
||||
{
|
||||
if (rn->info)
|
||||
{
|
||||
si = rn->info;
|
||||
si->vrf_id = vrf_id;
|
||||
if (si->ifindex)
|
||||
{
|
||||
ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id);
|
||||
if (ifp)
|
||||
si->ifindex = ifp->ifindex;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
static_install_route (afi, safi, &rn->p, si);
|
||||
}
|
||||
ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id);
|
||||
if (ifp)
|
||||
si->ifindex = ifp->ifindex;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
static_install_route (afi, safi, &rn->p, si);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Callback upon disabling a VRF. */
|
||||
static int
|
||||
zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
zebra_vrf_disable (struct vrf *vrf)
|
||||
{
|
||||
struct zebra_vrf *zvrf = (struct zebra_vrf *)(*info);
|
||||
struct route_table *stable = NULL;
|
||||
struct route_node *rn = NULL;
|
||||
struct zebra_vrf *zvrf = vrf->info;
|
||||
struct route_table *stable;
|
||||
struct route_node *rn;
|
||||
struct static_route *si;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("VRF %s id %u is now disabled.",
|
||||
zvrf->name, zvrf->vrf_id);
|
||||
zvrf_name (zvrf), zvrf_id (zvrf));
|
||||
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
||||
{
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
|
||||
{
|
||||
stable = zvrf->stable[afi][safi];
|
||||
if (stable)
|
||||
{
|
||||
for (rn = route_top (stable); rn; rn = route_next (rn))
|
||||
{
|
||||
if (rn->info)
|
||||
static_uninstall_route(afi, safi, &rn->p, rn->info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
|
||||
{
|
||||
stable = zvrf->stable[afi][safi];
|
||||
if (! stable)
|
||||
continue;
|
||||
|
||||
for (rn = route_top (stable); rn; rn = route_next (rn))
|
||||
for (si = rn->info; si; si = si->next)
|
||||
static_uninstall_route(afi, safi, &rn->p, si);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
zebra_vrf_delete (vrf_id_t vrf_id, const char *name, void **info)
|
||||
zebra_vrf_delete (struct vrf *vrf)
|
||||
{
|
||||
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
|
||||
struct zebra_vrf *zvrf = vrf->info;
|
||||
struct route_table *table;
|
||||
u_int32_t table_id;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
unsigned i;
|
||||
|
||||
assert (zvrf);
|
||||
|
||||
zebra_vrf_delete_update (zvrf);
|
||||
|
||||
rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||
rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||
/* uninstall everything */
|
||||
if (! CHECK_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN))
|
||||
{
|
||||
struct listnode *node;
|
||||
struct interface *ifp;
|
||||
|
||||
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
|
||||
{
|
||||
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
|
||||
rib_close_table (zvrf->table[afi][safi]);
|
||||
|
||||
if (vrf->vrf_id == VRF_DEFAULT)
|
||||
for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
|
||||
if (zvrf->other_table[afi][table_id])
|
||||
rib_close_table (zvrf->other_table[afi][table_id]);
|
||||
}
|
||||
|
||||
zebra_mpls_close_tables (zvrf);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
|
||||
}
|
||||
|
||||
/* clean-up work queues */
|
||||
for (i = 0; i < MQ_SIZE; i++)
|
||||
{
|
||||
struct listnode *lnode, *nnode;
|
||||
struct route_node *rnode;
|
||||
rib_dest_t *dest;
|
||||
|
||||
for (ALL_LIST_ELEMENTS (zebrad.mq->subq[i], lnode, nnode, rnode))
|
||||
{
|
||||
dest = rib_dest_from_rnode (rnode);
|
||||
if (dest && rib_dest_vrf (dest) == zvrf)
|
||||
{
|
||||
route_unlock_node (rnode);
|
||||
list_delete_node (zebrad.mq->subq[i], lnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* release allocated memory */
|
||||
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
|
||||
{
|
||||
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
|
||||
{
|
||||
table = zvrf->table[afi][safi];
|
||||
XFREE (MTYPE_RIB_TABLE_INFO, table->info);
|
||||
route_table_finish (table);
|
||||
|
||||
table = zvrf->stable[afi][safi];
|
||||
route_table_finish (table);
|
||||
}
|
||||
|
||||
for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
|
||||
if (zvrf->other_table[afi][table_id])
|
||||
{
|
||||
table = zvrf->other_table[afi][table_id];
|
||||
XFREE (MTYPE_RIB_TABLE_INFO, table->info);
|
||||
route_table_finish (table);
|
||||
}
|
||||
|
||||
route_table_finish (zvrf->rnh_table[afi]);
|
||||
route_table_finish (zvrf->import_check_table[afi]);
|
||||
}
|
||||
list_delete_all_node (zvrf->rid_all_sorted_list);
|
||||
list_delete_all_node (zvrf->rid_lo_sorted_list);
|
||||
XFREE (MTYPE_ZEBRA_VRF, zvrf);
|
||||
vrf->info = NULL;
|
||||
|
||||
zvrf->vrf_id = VRF_UNKNOWN;
|
||||
|
||||
*info = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -280,6 +326,62 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
|
|||
return table;
|
||||
}
|
||||
|
||||
static void
|
||||
zebra_rtable_node_destroy (route_table_delegate_t *delegate,
|
||||
struct route_table *table, struct route_node *node)
|
||||
{
|
||||
struct rib *rib, *next;
|
||||
|
||||
RNODE_FOREACH_RIB_SAFE (node, rib, next)
|
||||
rib_unlink (node, rib);
|
||||
|
||||
if (node->info)
|
||||
XFREE (MTYPE_RIB_DEST, node->info);
|
||||
|
||||
route_node_destroy (delegate, table, node);
|
||||
}
|
||||
|
||||
static void
|
||||
zebra_stable_node_destroy (route_table_delegate_t *delegate,
|
||||
struct route_table *table, struct route_node *node)
|
||||
{
|
||||
struct static_route *si, *next;
|
||||
|
||||
if (node->info)
|
||||
for (si = node->info; si; si = next)
|
||||
{
|
||||
next = si->next;
|
||||
XFREE (MTYPE_STATIC_ROUTE, si);
|
||||
}
|
||||
|
||||
route_node_destroy (delegate, table, node);
|
||||
}
|
||||
|
||||
static void
|
||||
zebra_rnhtable_node_destroy (route_table_delegate_t *delegate,
|
||||
struct route_table *table, struct route_node *node)
|
||||
{
|
||||
if (node->info)
|
||||
zebra_free_rnh (node->info);
|
||||
|
||||
route_node_destroy (delegate, table, node);
|
||||
}
|
||||
|
||||
route_table_delegate_t zebra_rtable_delegate = {
|
||||
.create_node = route_node_create,
|
||||
.destroy_node = zebra_rtable_node_destroy
|
||||
};
|
||||
|
||||
route_table_delegate_t zebra_stable_delegate = {
|
||||
.create_node = route_node_create,
|
||||
.destroy_node = zebra_stable_node_destroy
|
||||
};
|
||||
|
||||
route_table_delegate_t zebra_rnhtable_delegate = {
|
||||
.create_node = route_node_create,
|
||||
.destroy_node = zebra_rnhtable_node_destroy
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a routing table for the specific AFI/SAFI in the given VRF.
|
||||
*/
|
||||
|
@ -291,7 +393,7 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
|
|||
|
||||
assert (!zvrf->table[afi][safi]);
|
||||
|
||||
table = route_table_init ();
|
||||
table = route_table_init_with_delegate (&zebra_rtable_delegate);
|
||||
zvrf->table[afi][safi] = table;
|
||||
|
||||
info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
|
||||
|
@ -303,35 +405,27 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
|
|||
|
||||
/* Allocate new zebra VRF. */
|
||||
struct zebra_vrf *
|
||||
zebra_vrf_alloc (vrf_id_t vrf_id, const char *name)
|
||||
zebra_vrf_alloc (void)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
|
||||
zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
|
||||
|
||||
/* Allocate routing table and static table. */
|
||||
zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
|
||||
zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
|
||||
zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
|
||||
zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
|
||||
zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
|
||||
zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
|
||||
zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
|
||||
zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
|
||||
|
||||
zvrf->rnh_table[AFI_IP] = route_table_init();
|
||||
zvrf->rnh_table[AFI_IP6] = route_table_init();
|
||||
|
||||
zvrf->import_check_table[AFI_IP] = route_table_init();
|
||||
zvrf->import_check_table[AFI_IP6] = route_table_init();
|
||||
|
||||
/* Set VRF ID */
|
||||
zvrf->vrf_id = vrf_id;
|
||||
|
||||
if (name)
|
||||
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
|
||||
{
|
||||
strncpy (zvrf->name, name, strlen(name));
|
||||
zvrf->name[strlen(name)] = '\0';
|
||||
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
|
||||
{
|
||||
zebra_vrf_table_create (zvrf, afi, safi);
|
||||
zvrf->stable[afi][safi] =
|
||||
route_table_init_with_delegate (&zebra_stable_delegate);
|
||||
}
|
||||
|
||||
zvrf->rnh_table[afi] =
|
||||
route_table_init_with_delegate (&zebra_rnhtable_delegate);
|
||||
zvrf->import_check_table[afi] =
|
||||
route_table_init_with_delegate (&zebra_rnhtable_delegate);
|
||||
}
|
||||
|
||||
zebra_mpls_init_tables (zvrf);
|
||||
|
@ -341,26 +435,24 @@ zebra_vrf_alloc (vrf_id_t vrf_id, const char *name)
|
|||
|
||||
/* Lookup VRF by identifier. */
|
||||
struct zebra_vrf *
|
||||
zebra_vrf_lookup (vrf_id_t vrf_id)
|
||||
zebra_vrf_lookup_by_id (vrf_id_t vrf_id)
|
||||
{
|
||||
return vrf_info_lookup (vrf_id);
|
||||
}
|
||||
|
||||
/* Lookup the zvrf in the zvrf_list. */
|
||||
/* Lookup VRF by name. */
|
||||
struct zebra_vrf *
|
||||
zebra_vrf_list_lookup_by_name (const char *name)
|
||||
zebra_vrf_lookup_by_name (const char *name)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct zebra_vrf *zvrf;
|
||||
struct vrf *vrf;
|
||||
|
||||
if (!name)
|
||||
name = VRF_DEFAULT_NAME;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf))
|
||||
{
|
||||
if (strcmp(name, zvrf->name) == 0)
|
||||
return zvrf;
|
||||
}
|
||||
vrf = vrf_lookup_by_name (name);
|
||||
if (vrf)
|
||||
return ((struct zebra_vrf *) vrf->info);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
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. */
|
||||
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_DELETE_HOOK, zebra_vrf_delete);
|
||||
|
||||
zvrf_list = list_new ();
|
||||
|
||||
vrf_init ();
|
||||
vrf_cmd_init (vrf_config_write);
|
||||
}
|
||||
|
|
|
@ -28,11 +28,8 @@
|
|||
/* Routing table instance. */
|
||||
struct zebra_vrf
|
||||
{
|
||||
/* Identifier. */
|
||||
vrf_id_t vrf_id;
|
||||
|
||||
/* Routing table name. */
|
||||
char name[VRF_NAMSIZ];
|
||||
/* Back pointer */
|
||||
struct vrf *vrf;
|
||||
|
||||
/* Description. */
|
||||
char *desc;
|
||||
|
@ -43,6 +40,7 @@ struct zebra_vrf
|
|||
/* Flags. */
|
||||
u_int16_t flags;
|
||||
#define ZEBRA_VRF_RIB_SCHEDULED (1 << 0)
|
||||
#define ZEBRA_VRF_RETAIN (2 << 0)
|
||||
|
||||
u_int32_t table_id;
|
||||
|
||||
|
@ -86,7 +84,17 @@ struct zebra_vrf
|
|||
#define MPLS_FLAG_SCHEDULE_LSPS (1 << 0)
|
||||
};
|
||||
|
||||
extern struct list *zvrf_list;
|
||||
static inline vrf_id_t
|
||||
zvrf_id (struct zebra_vrf *zvrf)
|
||||
{
|
||||
return zvrf->vrf->vrf_id;
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
zvrf_name (struct zebra_vrf *zvrf)
|
||||
{
|
||||
return zvrf->vrf->name;
|
||||
}
|
||||
|
||||
struct route_table *
|
||||
zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
|
||||
|
@ -94,9 +102,9 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
|
|||
|
||||
extern void zebra_vrf_static_route_interface_fixup (struct interface *ifp);
|
||||
extern void zebra_vrf_update_all (struct zserv *client);
|
||||
extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id);
|
||||
extern struct zebra_vrf *zebra_vrf_list_lookup_by_name (const char *);
|
||||
extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *);
|
||||
extern struct zebra_vrf *zebra_vrf_lookup_by_id (vrf_id_t vrf_id);
|
||||
extern struct zebra_vrf *zebra_vrf_lookup_by_name (const char *);
|
||||
extern struct zebra_vrf *zebra_vrf_alloc (void);
|
||||
extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t);
|
||||
extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, struct zebra_vrf *zvrf);
|
||||
extern struct route_table *zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id,
|
||||
|
|
|
@ -107,7 +107,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
|
|||
tag = atol(tag_str);
|
||||
|
||||
/* VRF id */
|
||||
zvrf = zebra_vrf_list_lookup_by_name (vrf_id_str);
|
||||
zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
|
||||
|
||||
if (!zvrf)
|
||||
{
|
||||
|
@ -183,7 +183,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
|
|||
ret = inet_aton (gate_str, &gate);
|
||||
if (!ret)
|
||||
{
|
||||
struct interface *ifp = if_lookup_by_name_vrf (gate_str, zvrf->vrf_id);
|
||||
struct interface *ifp = if_lookup_by_name_vrf (gate_str, zvrf_id (zvrf));
|
||||
if (!ifp)
|
||||
{
|
||||
vty_out (vty, "%% Unknown interface: %s%s", gate_str, VTY_NEWLINE);
|
||||
|
@ -811,7 +811,7 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
|
|||
if (rib->vrf_id != VRF_DEFAULT)
|
||||
{
|
||||
zvrf = vrf_info_lookup(rib->vrf_id);
|
||||
vty_out (vty, ", vrf %s", zvrf->name);
|
||||
vty_out (vty, ", vrf %s", zvrf_name (zvrf));
|
||||
}
|
||||
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
|
||||
vty_out (vty, ", best");
|
||||
|
@ -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_prefix = NULL;
|
||||
|
||||
if (!(zvrf = zebra_vrf_list_lookup_by_name (vrf_name)))
|
||||
if (!(zvrf = zebra_vrf_lookup_by_name (vrf_name)))
|
||||
{
|
||||
if (use_json)
|
||||
vty_out (vty, "{}%s", VTY_NEWLINE);
|
||||
|
@ -1224,7 +1224,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
if (zvrf->vrf_id == VRF_UNKNOWN)
|
||||
if (zvrf_id (zvrf) == VRF_UNKNOWN)
|
||||
{
|
||||
if (use_json)
|
||||
vty_out (vty, "{}%s", VTY_NEWLINE);
|
||||
|
@ -1233,7 +1233,7 @@ do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, safi, zvrf->vrf_id);
|
||||
table = zebra_vrf_table (AFI_IP, safi, zvrf_id (zvrf));
|
||||
if (! table)
|
||||
{
|
||||
if (use_json)
|
||||
|
@ -1328,14 +1328,14 @@ DEFUN (show_ip_nht_vrf_all,
|
|||
"IP nexthop tracking table\n"
|
||||
VRF_ALL_CMD_HELP_STR)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
|
||||
zebra_print_rnh_table(zvrf->vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
zebra_print_rnh_table(zvrf_id (zvrf), AF_INET, vty, RNH_NEXTHOP_TYPE);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -1368,14 +1368,14 @@ DEFUN (show_ipv6_nht_vrf_all,
|
|||
"IPv6 nexthop tracking table\n"
|
||||
VRF_ALL_CMD_HELP_STR)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
|
||||
zebra_print_rnh_table(zvrf->vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
zebra_print_rnh_table(zvrf_id (zvrf), AF_INET6, vty, RNH_NEXTHOP_TYPE);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -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",
|
||||
"Route Source", "Routes", "FIB",
|
||||
((rib_table_info_t *)table->info)->zvrf->name,
|
||||
zvrf_name (((rib_table_info_t *)table->info)->zvrf),
|
||||
VTY_NEWLINE);
|
||||
|
||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||
|
@ -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",
|
||||
"Route Source", "Prefix Routes", "FIB",
|
||||
((rib_table_info_t *)table->info)->zvrf->name,
|
||||
zvrf_name (((rib_table_info_t *)table->info)->zvrf),
|
||||
VTY_NEWLINE);
|
||||
|
||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||
|
@ -1992,14 +1992,14 @@ DEFUN (show_ip_route_vrf_all,
|
|||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
int first = 1;
|
||||
int vrf_header = 1;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -2015,7 +2015,7 @@ DEFUN (show_ip_route_vrf_all,
|
|||
|
||||
if (vrf_header)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
vrf_header = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
|
@ -2040,8 +2040,8 @@ DEFUN (show_ip_route_vrf_all_tag,
|
|||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
int first = 1;
|
||||
int vrf_header = 1;
|
||||
route_tag_t tag = 0;
|
||||
|
@ -2049,9 +2049,9 @@ DEFUN (show_ip_route_vrf_all_tag,
|
|||
if (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)
|
||||
continue;
|
||||
|
||||
|
@ -2070,7 +2070,7 @@ DEFUN (show_ip_route_vrf_all_tag,
|
|||
|
||||
if (vrf_header)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
vrf_header = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
|
@ -2095,8 +2095,8 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,
|
|||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct prefix p;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
int ret;
|
||||
int first = 1;
|
||||
int vrf_header = 1;
|
||||
|
@ -2108,9 +2108,9 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -2127,7 +2127,7 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,
|
|||
|
||||
if (vrf_header)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
vrf_header = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
|
@ -2150,15 +2150,15 @@ DEFUN (show_ip_route_vrf_all_supernets,
|
|||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
u_int32_t addr;
|
||||
int first = 1;
|
||||
int vrf_header = 1;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -2179,7 +2179,7 @@ DEFUN (show_ip_route_vrf_all_supernets,
|
|||
}
|
||||
if (vrf_header)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
vrf_header = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
|
@ -2204,8 +2204,8 @@ DEFUN (show_ip_route_vrf_all_protocol,
|
|||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
int first = 1;
|
||||
int vrf_header = 1;
|
||||
|
||||
|
@ -2216,9 +2216,9 @@ DEFUN (show_ip_route_vrf_all_protocol,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -2235,7 +2235,7 @@ DEFUN (show_ip_route_vrf_all_protocol,
|
|||
|
||||
if (vrf_header)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
vrf_header = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
|
@ -2260,8 +2260,8 @@ DEFUN (show_ip_route_vrf_all_addr,
|
|||
struct prefix_ipv4 p;
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p);
|
||||
if (ret <= 0)
|
||||
|
@ -2270,9 +2270,9 @@ DEFUN (show_ip_route_vrf_all_addr,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -2302,8 +2302,8 @@ DEFUN (show_ip_route_vrf_all_prefix,
|
|||
struct prefix_ipv4 p;
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p);
|
||||
if (ret <= 0)
|
||||
|
@ -2312,9 +2312,9 @@ DEFUN (show_ip_route_vrf_all_prefix,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -2344,11 +2344,11 @@ DEFUN (show_ip_route_vrf_all_summary,
|
|||
VRF_ALL_CMD_HELP_STR
|
||||
"Summary of all routes\n")
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -2364,11 +2364,11 @@ DEFUN (show_ip_route_vrf_all_summary_prefix,
|
|||
"Summary of all routes\n"
|
||||
"Prefix routes\n")
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -2381,13 +2381,15 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
|
|||
struct route_node *rn;
|
||||
struct static_route *si;
|
||||
struct route_table *stable;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
char buf[BUFSIZ];
|
||||
int write =0;
|
||||
struct listnode *node;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if (!(zvrf = vrf->info))
|
||||
continue;
|
||||
if ((stable = zvrf->stable[AFI_IP][safi]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -2426,7 +2428,7 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
|
|||
vty_out (vty, " %d", si->distance);
|
||||
|
||||
if (si->vrf_id != VRF_DEFAULT)
|
||||
vty_out (vty, " vrf %s", zvrf ? zvrf->name : "");
|
||||
vty_out (vty, " vrf %s", zvrf ? zvrf_name (zvrf) : "");
|
||||
|
||||
/* Label information */
|
||||
if (si->snh_label.num_labels)
|
||||
|
@ -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);
|
||||
|
||||
/* VRF id */
|
||||
zvrf = zebra_vrf_list_lookup_by_name (vrf_id_str);
|
||||
zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
|
||||
|
||||
if (!zvrf)
|
||||
{
|
||||
|
@ -2559,7 +2561,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
|
|||
}
|
||||
type = STATIC_IPV6_GATEWAY_IFINDEX;
|
||||
gate = &gate_addr;
|
||||
ifp = if_lookup_by_name_vrf (ifname, zvrf->vrf_id);
|
||||
ifp = if_lookup_by_name_vrf (ifname, zvrf_id (zvrf));
|
||||
if (!ifp)
|
||||
{
|
||||
vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE);
|
||||
|
@ -2577,7 +2579,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
|
|||
else
|
||||
{
|
||||
type = STATIC_IFINDEX;
|
||||
ifp = if_lookup_by_name_vrf (gate_str, zvrf->vrf_id);
|
||||
ifp = if_lookup_by_name_vrf (gate_str, zvrf_id (zvrf));
|
||||
if (!ifp)
|
||||
{
|
||||
vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE);
|
||||
|
@ -2894,7 +2896,7 @@ DEFUN (show_ipv6_route,
|
|||
|
||||
if (vrf)
|
||||
{
|
||||
if (!(zvrf = zebra_vrf_list_lookup_by_name (vrfname)))
|
||||
if (!(zvrf = zebra_vrf_lookup_by_name (vrfname)))
|
||||
{
|
||||
if (uj)
|
||||
vty_out (vty, "{}%s", VTY_NEWLINE);
|
||||
|
@ -2903,7 +2905,7 @@ DEFUN (show_ipv6_route,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
if (zvrf->vrf_id == VRF_UNKNOWN)
|
||||
if (zvrf_id (zvrf) == VRF_UNKNOWN)
|
||||
{
|
||||
if (uj)
|
||||
vty_out (vty, "{}%s", VTY_NEWLINE);
|
||||
|
@ -2912,7 +2914,7 @@ DEFUN (show_ipv6_route,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
else
|
||||
vrf_id = zvrf->vrf_id;
|
||||
vrf_id = zvrf_id (zvrf);
|
||||
}
|
||||
|
||||
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||
|
@ -3326,14 +3328,14 @@ DEFUN (show_ipv6_route_vrf_all,
|
|||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
int first = 1;
|
||||
int vrf_header = 1;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -3349,7 +3351,7 @@ DEFUN (show_ipv6_route_vrf_all,
|
|||
|
||||
if (vrf_header)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
vrf_header = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
|
@ -3374,8 +3376,8 @@ DEFUN (show_ipv6_route_vrf_all_tag,
|
|||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
int first = 1;
|
||||
int vrf_header = 1;
|
||||
route_tag_t tag = 0;
|
||||
|
@ -3383,9 +3385,9 @@ DEFUN (show_ipv6_route_vrf_all_tag,
|
|||
if (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)
|
||||
continue;
|
||||
|
||||
|
@ -3404,7 +3406,7 @@ DEFUN (show_ipv6_route_vrf_all_tag,
|
|||
|
||||
if (vrf_header)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
vrf_header = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
|
@ -3430,8 +3432,8 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
|
|||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct prefix p;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
int ret;
|
||||
int first = 1;
|
||||
int vrf_header = 1;
|
||||
|
@ -3443,9 +3445,9 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -3462,7 +3464,7 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
|
|||
|
||||
if (vrf_header)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
vrf_header = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
|
@ -3487,8 +3489,8 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
|
|||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
int first = 1;
|
||||
int vrf_header = 1;
|
||||
|
||||
|
@ -3499,9 +3501,9 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -3518,7 +3520,7 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
|
|||
|
||||
if (vrf_header)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
vrf_header = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
|
@ -3543,8 +3545,8 @@ DEFUN (show_ipv6_route_vrf_all_addr,
|
|||
struct prefix_ipv6 p;
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
ret = str2prefix_ipv6 (argv[idx_ipv6]->arg, &p);
|
||||
if (ret <= 0)
|
||||
|
@ -3553,9 +3555,9 @@ DEFUN (show_ipv6_route_vrf_all_addr,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -3585,8 +3587,8 @@ DEFUN (show_ipv6_route_vrf_all_prefix,
|
|||
struct prefix_ipv6 p;
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, &p);
|
||||
if (ret <= 0)
|
||||
|
@ -3595,9 +3597,9 @@ DEFUN (show_ipv6_route_vrf_all_prefix,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -3627,11 +3629,11 @@ DEFUN (show_ipv6_route_vrf_all_summary,
|
|||
VRF_ALL_CMD_HELP_STR
|
||||
"Summary of all IPv6 routes\n")
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -3648,13 +3650,13 @@ DEFUN (show_ipv6_mroute_vrf_all,
|
|||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
int first = 1;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
if ((zvrf = vrf->info) == NULL ||
|
||||
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -3683,11 +3685,11 @@ DEFUN (show_ipv6_route_vrf_all_summary_prefix,
|
|||
"Summary of all IPv6 routes\n"
|
||||
"Prefix routes\n")
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -3702,11 +3704,13 @@ static_config_ipv6 (struct vty *vty)
|
|||
int write = 0;
|
||||
char buf[PREFIX_STRLEN];
|
||||
struct route_table *stable;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
struct listnode *node;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if (!(zvrf = vrf->info))
|
||||
continue;
|
||||
if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -3750,7 +3754,7 @@ static_config_ipv6 (struct vty *vty)
|
|||
|
||||
if (si->vrf_id != VRF_DEFAULT)
|
||||
{
|
||||
vty_out (vty, " vrf %s", zvrf->name);
|
||||
vty_out (vty, " vrf %s", zvrf_name (zvrf));
|
||||
}
|
||||
|
||||
/* Label information */
|
||||
|
@ -3794,19 +3798,21 @@ DEFUN (show_vrf,
|
|||
SHOW_STR
|
||||
"VRF\n")
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
struct listnode *node;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf))
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
{
|
||||
if (!zvrf->vrf_id)
|
||||
if (!(zvrf = vrf->info))
|
||||
continue;
|
||||
if (!zvrf_id (zvrf))
|
||||
continue;
|
||||
|
||||
vty_out (vty, "vrf %s ", zvrf->name);
|
||||
if (zvrf->vrf_id == VRF_UNKNOWN)
|
||||
vty_out (vty, "vrf %s ", zvrf_name (zvrf));
|
||||
if (zvrf_id (zvrf) == VRF_UNKNOWN)
|
||||
vty_out (vty, "inactive");
|
||||
else
|
||||
vty_out (vty, "id %u table %u", zvrf->vrf_id, zvrf->table_id);
|
||||
vty_out (vty, "id %u table %u", zvrf_id (zvrf), zvrf->table_id);
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
|
||||
}
|
||||
|
|
|
@ -185,7 +185,7 @@ static void
|
|||
zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf)
|
||||
{
|
||||
/* Interface information. */
|
||||
stream_put (s, zvrf->name, VRF_NAMSIZ);
|
||||
stream_put (s, zvrf_name (zvrf), VRF_NAMSIZ);
|
||||
|
||||
/* Write packet size. */
|
||||
stream_putw_at (s, 0, stream_get_endp (s));
|
||||
|
@ -241,7 +241,7 @@ zsend_vrf_add (struct zserv *client, struct zebra_vrf *zvrf)
|
|||
s = client->obuf;
|
||||
stream_reset (s);
|
||||
|
||||
zserv_create_header (s, ZEBRA_VRF_ADD, zvrf->vrf_id);
|
||||
zserv_create_header (s, ZEBRA_VRF_ADD, zvrf_id (zvrf));
|
||||
zserv_encode_vrf (s, zvrf);
|
||||
|
||||
client->vrfadd_cnt++;
|
||||
|
@ -257,7 +257,7 @@ zsend_vrf_delete (struct zserv *client, struct zebra_vrf *zvrf)
|
|||
s = client->obuf;
|
||||
stream_reset (s);
|
||||
|
||||
zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf->vrf_id);
|
||||
zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf_id (zvrf));
|
||||
zserv_encode_vrf (s, zvrf);
|
||||
|
||||
client->vrfdel_cnt++;
|
||||
|
@ -850,7 +850,7 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length,
|
|||
p.family);
|
||||
return -1;
|
||||
}
|
||||
rnh = zebra_add_rnh(&p, zvrf->vrf_id, type);
|
||||
rnh = zebra_add_rnh(&p, zvrf_id (zvrf), type);
|
||||
if (type == RNH_NEXTHOP_TYPE)
|
||||
{
|
||||
if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
|
||||
|
@ -866,9 +866,9 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length,
|
|||
UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
|
||||
}
|
||||
|
||||
zebra_add_rnh_client(rnh, client, type, zvrf->vrf_id);
|
||||
zebra_add_rnh_client(rnh, client, type, zvrf_id (zvrf));
|
||||
/* Anything not AF_INET/INET6 has been filtered out above */
|
||||
zebra_evaluate_rnh(zvrf->vrf_id, p.family, 1, type, &p);
|
||||
zebra_evaluate_rnh(zvrf_id (zvrf), p.family, 1, type, &p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -911,7 +911,7 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
|
|||
p.family);
|
||||
return -1;
|
||||
}
|
||||
rnh = zebra_lookup_rnh(&p, zvrf->vrf_id, type);
|
||||
rnh = zebra_lookup_rnh(&p, zvrf_id (zvrf), type);
|
||||
if (rnh)
|
||||
{
|
||||
client->nh_dereg_time = quagga_monotime();
|
||||
|
@ -939,7 +939,7 @@ zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struc
|
|||
stream_reset (s);
|
||||
|
||||
/* Fill in result. */
|
||||
zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf->vrf_id);
|
||||
zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id (zvrf));
|
||||
stream_put_in_addr (s, &addr);
|
||||
|
||||
if (rib)
|
||||
|
@ -1005,18 +1005,16 @@ zsend_router_id_update (struct zserv *client, struct prefix *p,
|
|||
static int
|
||||
zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct listnode *ifnode, *ifnnode;
|
||||
vrf_iter_t iter;
|
||||
struct interface *ifp;
|
||||
struct zebra_vrf *zvrf_iter;
|
||||
|
||||
/* Interface information is needed. */
|
||||
vrf_bitmap_set (client->ifinfo, zvrf->vrf_id);
|
||||
vrf_bitmap_set (client->ifinfo, zvrf_id (zvrf));
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
{
|
||||
zvrf_iter = vrf_iter2info (iter);
|
||||
for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf_iter->vrf_id), ifnode, ifnnode, ifp))
|
||||
for (ALL_LIST_ELEMENTS (vrf->iflist, ifnode, ifnnode, ifp))
|
||||
{
|
||||
/* Skip pseudo interface. */
|
||||
if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
|
||||
|
@ -1036,7 +1034,7 @@ zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvr
|
|||
static int
|
||||
zread_interface_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||
{
|
||||
vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id);
|
||||
vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1093,7 +1091,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
|||
stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
|
||||
|
||||
/* VRF ID */
|
||||
rib->vrf_id = zvrf->vrf_id;
|
||||
rib->vrf_id = zvrf_id (zvrf);
|
||||
|
||||
/* Nexthop parse. */
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
|
||||
|
@ -1245,7 +1243,7 @@ zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
|||
|
||||
table_id = zvrf->table_id;
|
||||
|
||||
rib_delete (AFI_IP, api.safi, zvrf->vrf_id, api.type, api.instance,
|
||||
rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance,
|
||||
api.flags, &p, nexthop_p, ifindex, table_id);
|
||||
client->v4_route_del_cnt++;
|
||||
return 0;
|
||||
|
@ -1259,7 +1257,7 @@ zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zeb
|
|||
struct rib *rib;
|
||||
|
||||
addr.s_addr = stream_get_ipv4 (client->ibuf);
|
||||
rib = rib_match_ipv4_multicast (zvrf->vrf_id, addr, NULL);
|
||||
rib = rib_match_ipv4_multicast (zvrf_id (zvrf), addr, NULL);
|
||||
return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib, zvrf);
|
||||
}
|
||||
|
||||
|
@ -1303,7 +1301,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
|
|||
stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
|
||||
|
||||
/* VRF ID */
|
||||
rib->vrf_id = zvrf->vrf_id;
|
||||
rib->vrf_id = zvrf_id (zvrf);
|
||||
|
||||
/* We need to give nh-addr, nh-ifindex with the same next-hop object
|
||||
* to the rib to ensure that IPv6 multipathing works; need to coalesce
|
||||
|
@ -1500,7 +1498,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
|||
rib->mtu = 0;
|
||||
|
||||
/* VRF ID */
|
||||
rib->vrf_id = zvrf->vrf_id;
|
||||
rib->vrf_id = zvrf_id (zvrf);
|
||||
rib->table = zvrf->table_id;
|
||||
|
||||
ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
|
||||
|
@ -1584,10 +1582,10 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
|||
api.tag = 0;
|
||||
|
||||
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
|
||||
rib_delete (AFI_IP6, api.safi, zvrf->vrf_id, api.type, api.instance,
|
||||
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
|
||||
api.flags, &p, NULL, ifindex, client->rtm_table);
|
||||
else
|
||||
rib_delete (AFI_IP6, api.safi, zvrf->vrf_id, api.type, api.instance,
|
||||
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
|
||||
api.flags, &p, pnexthop, ifindex, client->rtm_table);
|
||||
|
||||
client->v6_route_del_cnt++;
|
||||
|
@ -1601,18 +1599,18 @@ zread_router_id_add (struct zserv *client, u_short length, struct zebra_vrf *zvr
|
|||
struct prefix p;
|
||||
|
||||
/* Router-id information is needed. */
|
||||
vrf_bitmap_set (client->ridinfo, zvrf->vrf_id);
|
||||
vrf_bitmap_set (client->ridinfo, zvrf_id (zvrf));
|
||||
|
||||
router_id_get (&p, zvrf->vrf_id);
|
||||
router_id_get (&p, zvrf_id (zvrf));
|
||||
|
||||
return zsend_router_id_update (client, &p, zvrf->vrf_id);
|
||||
return zsend_router_id_update (client, &p, zvrf_id (zvrf));
|
||||
}
|
||||
|
||||
/* Unregister zebra server router-id information. */
|
||||
static int
|
||||
zread_router_id_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||
{
|
||||
vrf_bitmap_unset (client->ridinfo, zvrf->vrf_id);
|
||||
vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1650,10 +1648,10 @@ zread_vrf_unregister (struct zserv *client, u_short length, struct zebra_vrf *zv
|
|||
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||
vrf_bitmap_unset (client->redist[afi][i], zvrf->vrf_id);
|
||||
vrf_bitmap_unset (client->redist_default, zvrf->vrf_id);
|
||||
vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id);
|
||||
vrf_bitmap_unset (client->ridinfo, zvrf->vrf_id);
|
||||
vrf_bitmap_unset (client->redist[afi][i], zvrf_id (zvrf));
|
||||
vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf));
|
||||
vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf));
|
||||
vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1724,17 +1722,17 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
|
|||
static void
|
||||
zebra_client_close_cleanup_rnh (struct zserv *client)
|
||||
{
|
||||
vrf_iter_t iter;
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||
if ((zvrf = vrf->info) != NULL)
|
||||
{
|
||||
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_NEXTHOP_TYPE);
|
||||
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_NEXTHOP_TYPE);
|
||||
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_IMPORT_CHECK_TYPE);
|
||||
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_IMPORT_CHECK_TYPE);
|
||||
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_NEXTHOP_TYPE);
|
||||
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_NEXTHOP_TYPE);
|
||||
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_IMPORT_CHECK_TYPE);
|
||||
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_IMPORT_CHECK_TYPE);
|
||||
if (client->proto == ZEBRA_ROUTE_LDP)
|
||||
{
|
||||
hash_iterate(zvrf->lsp_table, mpls_ldp_lsp_uninstall_all,
|
||||
|
@ -1937,7 +1935,7 @@ zebra_client_read (struct thread *thread)
|
|||
client->last_read_time = quagga_monotime();
|
||||
client->last_read_cmd = command;
|
||||
|
||||
zvrf = zebra_vrf_lookup (vrf_id);
|
||||
zvrf = zebra_vrf_lookup_by_id (vrf_id);
|
||||
if (!zvrf)
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
|
||||
|
|
Loading…
Reference in a new issue