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

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

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

2
README
View file

@ -2,7 +2,7 @@ Quagga is free software that manages various IPv4 and IPv6 routing
protocols.
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.

View file

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

View file

@ -308,38 +308,33 @@ bgp_exit (int status)
}
static int
bgp_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
bgp_vrf_new (struct vrf *vrf)
{
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug ("VRF Created: %s(%d)", name, vrf_id);
zlog_debug ("VRF Created: %s(%d)", vrf->name, vrf->vrf_id);
return 0;
}
static int
bgp_vrf_delete (vrf_id_t vrf_id, const char *name, void **info)
bgp_vrf_delete (struct vrf *vrf)
{
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug ("VRF Deletion: %s(%d)", name, vrf_id);
zlog_debug ("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id);
return 0;
}
static int
bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
bgp_vrf_enable (struct vrf *vrf)
{
struct vrf *vrf;
struct bgp *bgp;
vrf_id_t old_vrf_id;
vrf = vrf_lookup (vrf_id);
if (!vrf) // unexpected
return -1;
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("VRF enable add %s id %d", name, vrf_id);
zlog_debug("VRF enable add %s id %d", vrf->name, vrf->vrf_id);
bgp = bgp_lookup_by_name(name);
bgp = bgp_lookup_by_name (vrf->name);
if (bgp)
{
old_vrf_id = bgp->vrf_id;
@ -356,23 +351,18 @@ bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
}
static int
bgp_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
bgp_vrf_disable (struct vrf *vrf)
{
struct vrf *vrf;
struct bgp *bgp;
vrf_id_t old_vrf_id;
if (vrf_id == VRF_DEFAULT)
if (vrf->vrf_id == VRF_DEFAULT)
return 0;
vrf = vrf_lookup (vrf_id);
if (!vrf) // unexpected
return -1;
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("VRF disable %s id %d", name, vrf_id);
zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
bgp = bgp_lookup_by_name(name);
bgp = bgp_lookup_by_name (vrf->name);
if (bgp)
{
old_vrf_id = bgp->vrf_id;

View file

@ -113,6 +113,12 @@ bgp_address_hash_alloc (void *p)
return addr;
}
static void
bgp_address_hash_free (void *addr)
{
XFREE (MTYPE_BGP_ADDR, addr);
}
static unsigned int
bgp_address_hash_key_make (void *p)
{
@ -142,7 +148,7 @@ bgp_address_destroy (struct bgp *bgp)
{
if (bgp->address_hash == NULL)
return;
hash_clean(bgp->address_hash, NULL);
hash_clean(bgp->address_hash, bgp_address_hash_free);
hash_free(bgp->address_hash);
bgp->address_hash = NULL;
}
@ -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;
}
}

View file

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

View file

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

View file

@ -241,7 +241,7 @@ bgp_bump_version (struct bgp_node *node)
extern void bgp_process_queue_init (void);
extern void bgp_route_init (void);
extern void bgp_route_finish (void);
extern void bgp_cleanup_routes (void);
extern void bgp_cleanup_routes (struct bgp *);
extern void bgp_announce_route (struct peer *, afi_t, safi_t);
extern void bgp_stop_announce_route_timer(struct peer_af *paf);
extern void bgp_announce_route_all (struct peer *);

View file

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

View file

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

View file

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

View file

@ -1044,6 +1044,12 @@ peer_free (struct peer *peer)
peer->host = NULL;
}
if (peer->domainname)
{
XFREE (MTYPE_BGP_PEER_HOST, peer->domainname);
peer->domainname = NULL;
}
if (peer->ifname)
{
XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
@ -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);

View file

@ -1490,7 +1490,7 @@ bgp_vrf_lookup_by_instance_type (struct bgp *bgp)
struct vrf *vrf;
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
vrf = vrf_lookup (VRF_DEFAULT);
vrf = vrf_lookup_by_id (VRF_DEFAULT);
else if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
vrf = vrf_lookup_by_name (bgp->name);
else

View file

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

View file

@ -2069,21 +2069,6 @@ DEFUN (config_log_syslog,
}
}
DEFUN_DEPRECATED (config_log_syslog_facility,
config_log_syslog_facility_cmd,
"log syslog facility (kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7)",
"Logging control\n"
"Logging goes to syslog\n"
"(Deprecated) Facility parameter for syslog messages\n"
LOG_FACILITY_DESC)
{
int facility = facility_match(argv[3]->arg);
zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
zlog_default->facility = facility;
return CMD_SUCCESS;
}
DEFUN (no_config_log_syslog,
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 ();
}

View file

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

@ -307,13 +307,11 @@ if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id)
struct interface *
if_lookup_by_name_all_vrf (const char *name)
{
struct vrf *vrf;
struct interface *ifp;
struct vrf *vrf = NULL;
vrf_iter_t iter;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
{
vrf = vrf_iter2vrf (iter);
ifp = if_lookup_by_name_vrf (name, vrf->vrf_id);
if (ifp)
return ifp;
@ -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;

View file

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

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

View file

@ -23,6 +23,7 @@
#ifndef _ZEBRA_NS_H
#define _ZEBRA_NS_H
#include "openbsd-tree.h"
#include "linklist.h"
typedef u_int16_t ns_id_t;
@ -30,15 +31,32 @@ typedef u_int16_t ns_id_t;
/* The default NS ID */
#define NS_DEFAULT 0
/*
* The command strings
*/
/* Default netns directory (Linux) */
#define NS_RUN_DIR "/var/run/netns"
#define NS_CMD_STR "logical-router <0-65535>"
#define NS_CMD_HELP_STR "Specify the Logical-Router\nThe Logical-Router ID\n"
#define NS_ALL_CMD_STR "logical-router all"
#define NS_ALL_CMD_HELP_STR "Specify the logical-router\nAll logical-router's\n"
struct ns
{
RB_ENTRY(ns) entry;
/* Identifier, same as the vector index */
ns_id_t ns_id;
/* Name */
char *name;
/* File descriptor */
int fd;
/* Master list of interfaces belonging to this NS */
struct list *iflist;
/* User data */
void *info;
};
RB_HEAD (ns_head, ns);
RB_PROTOTYPE (ns_head, ns, entry, ns_compare)
extern struct ns_head ns_tree;
/*
* NS hooks
@ -59,71 +77,6 @@ typedef u_int16_t ns_id_t;
*/
extern void ns_add_hook (int, int (*)(ns_id_t, void **));
/*
* NS iteration
*/
typedef void * ns_iter_t;
#define NS_ITER_INVALID NULL /* invalid value of the iterator */
/*
* NS iteration utilities. Example for the usage:
*
* ns_iter_t iter = ns_first();
* for (; iter != NS_ITER_INVALID; iter = ns_next (iter))
*
* or
*
* ns_iter_t iter = ns_iterator (<a given NS ID>);
* for (; iter != NS_ITER_INVALID; iter = ns_next (iter))
*/
/* Return the iterator of the first NS. */
extern ns_iter_t ns_first (void);
/* Return the next NS iterator to the given iterator. */
extern ns_iter_t ns_next (ns_iter_t);
/* Return the NS iterator of the given NS ID. If it does not exist,
* the iterator of the next existing NS is returned. */
extern ns_iter_t ns_iterator (ns_id_t);
/*
* NS iterator to properties
*/
extern ns_id_t ns_iter2id (ns_iter_t);
extern void *ns_iter2info (ns_iter_t);
extern struct list *ns_iter2iflist (ns_iter_t);
/*
* Utilities to obtain the user data
*/
/* Get the data pointer of the specified NS. If not found, create one. */
extern void *ns_info_get (ns_id_t);
/* Look up the data pointer of the specified NS. */
extern void *ns_info_lookup (ns_id_t);
/*
* Utilities to obtain the interface list
*/
/* Look up the interface list of the specified NS. */
extern struct list *ns_iflist (ns_id_t);
/* Get the interface list of the specified NS. Create one if not find. */
extern struct list *ns_iflist_get (ns_id_t);
/*
* NS bit-map: maintaining flags, one bit per NS ID
*/
typedef void * ns_bitmap_t;
#define NS_BITMAP_NULL NULL
extern ns_bitmap_t ns_bitmap_init (void);
extern void ns_bitmap_free (ns_bitmap_t);
extern void ns_bitmap_set (ns_bitmap_t, ns_id_t);
extern void ns_bitmap_unset (ns_bitmap_t, ns_id_t);
extern int ns_bitmap_check (ns_bitmap_t, ns_id_t);
/*
* NS initializer/destructor
*/

View file

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

View file

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

View file

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

View file

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

View file

@ -169,6 +169,11 @@ extern struct route_node *route_node_match_ipv6 (const struct route_table *,
extern unsigned long route_table_count (const struct route_table *);
extern struct route_node *route_node_create (route_table_delegate_t *,
struct route_table *);
extern void route_node_destroy (route_table_delegate_t *,
struct route_table *, struct route_node *);
extern struct route_node *
route_table_get_next (const struct route_table *table, struct prefix *p);
extern int

529
lib/vrf.c
View file

@ -35,6 +35,15 @@ DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
DEFINE_QOBJ_TYPE(vrf)
static __inline int vrf_id_compare (struct vrf *, struct vrf *);
static __inline int vrf_name_compare (struct vrf *, struct vrf *);
RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare)
RB_GENERATE (vrf_name_head, vrf, name_entry, vrf_name_compare)
struct vrf_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id);
struct vrf_name_head vrfs_by_name = RB_INITIALIZER (&vrfs_by_name);
/*
* Turn on/off debug code
* for vrf.
@ -44,44 +53,34 @@ int debug_vrf = 0;
/* Holding VRF hooks */
struct vrf_master
{
int (*vrf_new_hook) (vrf_id_t, const char *, void **);
int (*vrf_delete_hook) (vrf_id_t, const char *, void **);
int (*vrf_enable_hook) (vrf_id_t, const char *, void **);
int (*vrf_disable_hook) (vrf_id_t, const char *, void **);
int (*vrf_new_hook) (struct vrf *);
int (*vrf_delete_hook) (struct vrf *);
int (*vrf_enable_hook) (struct vrf *);
int (*vrf_disable_hook) (struct vrf *);
} vrf_master = {0,};
/* VRF table */
struct route_table *vrf_table = NULL;
/* VRF is part of a list too to store it before its actually active */
struct list *vrf_list;
static int vrf_is_enabled (struct vrf *vrf);
static void vrf_disable (struct vrf *vrf);
/* VRF list existance check by name. */
struct vrf *
vrf_list_lookup_by_name (const char *name)
vrf_lookup_by_name (const char *name)
{
struct listnode *node;
struct vrf *vrfp;
if (name)
for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrfp))
{
if (strcmp(name, vrfp->name) == 0)
return vrfp;
}
return NULL;
struct vrf vrf;
strlcpy (vrf.name, name, sizeof (vrf.name));
return (RB_FIND (vrf_name_head, &vrfs_by_name, &vrf));
}
/* Build the table key */
static void
vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
static __inline int
vrf_id_compare (struct vrf *a, struct vrf *b)
{
p->family = AF_INET;
p->prefixlen = IPV4_MAX_BITLEN;
p->u.prefix4.s_addr = vrf_id;
return (a->vrf_id - b->vrf_id);
}
static int
vrf_name_compare (struct vrf *a, struct vrf *b)
{
return strcmp (a->name, b->name);
}
/* Get a VRF. If not found, create one.
@ -94,177 +93,59 @@ vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
struct vrf *
vrf_get (vrf_id_t vrf_id, const char *name)
{
struct prefix p;
struct route_node *rn = NULL;
struct vrf *vrf = NULL;
int new = 0;
if (debug_vrf)
zlog_debug ("VRF_GET: %s(%d)", name, vrf_id);
/*
* Nothing to see, move along here
*/
/* Nothing to see, move along here */
if (!name && vrf_id == VRF_UNKNOWN)
return NULL;
/*
* Valid vrf name and unknown vrf_id case
*
* This is called when we are configured from
* the cli but we have no kernel information yet.
*/
if (name && vrf_id == VRF_UNKNOWN)
{
vrf = vrf_list_lookup_by_name (name);
if (vrf)
return vrf;
/* Try to find VRF both by ID and name */
if (vrf_id != VRF_UNKNOWN)
vrf = vrf_lookup_by_id (vrf_id);
if (! vrf && name)
vrf = vrf_lookup_by_name (name);
if (vrf == NULL)
{
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
if (debug_vrf)
zlog_debug ("VRF(%u) %s is created.",
vrf_id, (name) ? name : "(NULL)");
strcpy (vrf->name, name);
listnode_add_sort (vrf_list, vrf);
vrf->vrf_id = VRF_UNKNOWN;
if_init (&vrf->iflist);
QOBJ_REG (vrf, vrf);
if (vrf_master.vrf_new_hook)
{
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
new = 1;
if (debug_vrf && vrf->info)
zlog_info ("zvrf is created.");
}
if (debug_vrf)
zlog_debug("Vrf Created: %p", vrf);
return vrf;
zlog_debug ("VRF(%u) %s is created.",
vrf_id, (name) ? name : "(NULL)");
}
/*
* Valid vrf name and valid vrf_id case
*
* This can be passed from the kernel
*/
else if (name && vrf_id != VRF_UNKNOWN)
/* Set identifier */
if (vrf_id != VRF_UNKNOWN && vrf->vrf_id == VRF_UNKNOWN)
{
vrf = vrf_list_lookup_by_name (name);
if (vrf)
{
/*
* If the passed in vrf_id and name match
* return, nothing to do here.
*/
if (vrf->vrf_id == vrf_id)
return vrf;
/*
* Now we have a situation where we've had a
* vrf created, but not yet created the vrf_id route
* node, let's do so and match the code up.
*/
vrf_build_key (vrf_id, &p);
rn = route_node_get (vrf_table, &p);
rn->info = vrf;
vrf->node = rn;
vrf->vrf_id = vrf_id;
if (vrf_master.vrf_new_hook)
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
if (debug_vrf)
zlog_debug("Vrf found matched stuff up: %p", vrf);
return vrf;
}
else
{
/*
* We can have 1 of two situations here
* We've already been told about the vrf_id
* or we haven't.
*/
vrf_build_key (vrf_id, &p);
rn = route_node_get (vrf_table, &p);
if (rn->info)
{
vrf = rn->info;
route_unlock_node (rn);
/*
* We know at this point that the vrf->name is not
* right because we would have caught it above.
* so let's set it.
*/
strcpy (vrf->name, name);
listnode_add_sort (vrf_list, vrf);
if (vrf_master.vrf_new_hook)
{
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
if (debug_vrf && vrf->info)
zlog_info ("zvrf is created.");
}
if (debug_vrf)
zlog_debug("Vrf Created: %p", vrf);
return vrf;
}
else
{
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
rn->info = vrf;
vrf->node = rn;
vrf->vrf_id = vrf_id;
strcpy (vrf->name, name);
listnode_add_sort (vrf_list, vrf);
if_init (&vrf->iflist);
QOBJ_REG (vrf, vrf);
if (vrf_master.vrf_new_hook)
{
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
if (debug_vrf && vrf->info)
zlog_info ("zvrf is created.");
}
if (debug_vrf)
zlog_debug("Vrf Created: %p", vrf);
return vrf;
}
}
vrf->vrf_id = vrf_id;
RB_INSERT (vrf_id_head, &vrfs_by_id, vrf);
}
/*
* The final case, we've been passed a valid vrf_id
* but no name. So we create the route node
* if it hasn't already been created.
*/
else if (!name)
/* Set name */
if (name && vrf->name[0] != '\0' && strcmp (name, vrf->name))
{
vrf_build_key (vrf_id, &p);
rn = route_node_get (vrf_table, &p);
if (debug_vrf)
zlog_debug("Vrf found: %p", rn->info);
if (rn->info)
{
route_unlock_node (rn);
return (rn->info);
}
else
{
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
rn->info = vrf;
vrf->node = rn;
vrf->vrf_id = vrf_id;
if_init (&vrf->iflist);
QOBJ_REG (vrf, vrf);
if (debug_vrf)
zlog_debug("Vrf Created: %p", vrf);
return vrf;
}
RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf);
strlcpy (vrf->name, name, sizeof (vrf->name));
RB_INSERT (vrf_name_head, &vrfs_by_name, vrf);
}
else if (name && vrf->name[0] == '\0')
{
strlcpy (vrf->name, name, sizeof (vrf->name));
RB_INSERT (vrf_name_head, &vrfs_by_name, vrf);
}
/*
* We shouldn't get here and if we do
* something has gone wrong.
*/
return NULL;
if (new && vrf_master.vrf_new_hook)
(*vrf_master.vrf_new_hook) (vrf);
return vrf;
}
/* Delete a VRF. This is called in vrf_terminate(). */
@ -278,53 +159,35 @@ vrf_delete (struct vrf *vrf)
vrf_disable (vrf);
if (vrf_master.vrf_delete_hook)
(*vrf_master.vrf_delete_hook) (vrf->vrf_id, vrf->name, &vrf->info);
(*vrf_master.vrf_delete_hook) (vrf);
QOBJ_UNREG (vrf);
if_terminate (&vrf->iflist);
if (vrf->node)
{
vrf->node->info = NULL;
route_unlock_node(vrf->node);
}
listnode_delete (vrf_list, vrf);
if (vrf->vrf_id != VRF_UNKNOWN)
RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf);
if (vrf->name[0] != '\0')
RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf);
XFREE (MTYPE_VRF, vrf);
}
/* Look up a VRF by identifier. */
struct vrf *
vrf_lookup (vrf_id_t vrf_id)
vrf_lookup_by_id (vrf_id_t vrf_id)
{
struct prefix p;
struct route_node *rn;
struct vrf *vrf = NULL;
vrf_build_key (vrf_id, &p);
rn = route_node_lookup (vrf_table, &p);
if (rn)
{
vrf = (struct vrf *)rn->info;
route_unlock_node (rn); /* lookup */
}
return vrf;
struct vrf vrf;
vrf.vrf_id = vrf_id;
return (RB_FIND (vrf_id_head, &vrfs_by_id, &vrf));
}
/*
* Check whether the VRF is enabled - that is, whether the VRF
* is ready to allocate resources. Currently there's only one
* type of resource: socket.
* Check whether the VRF is enabled.
*/
static int
vrf_is_enabled (struct vrf *vrf)
{
return vrf && CHECK_FLAG (vrf->status, VRF_ACTIVE);
/*Pending: figure out the real use of this routine.. it used to be..
return vrf && vrf->vrf_id == VRF_DEFAULT;
*/
}
/*
@ -337,14 +200,16 @@ vrf_is_enabled (struct vrf *vrf)
int
vrf_enable (struct vrf *vrf)
{
if (vrf_is_enabled (vrf))
return 1;
if (debug_vrf)
zlog_debug ("VRF %u is enabled.", vrf->vrf_id);
if (!CHECK_FLAG (vrf->status, VRF_ACTIVE))
SET_FLAG (vrf->status, VRF_ACTIVE);
SET_FLAG (vrf->status, VRF_ACTIVE);
if (vrf_master.vrf_enable_hook)
(*vrf_master.vrf_enable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
(*vrf_master.vrf_enable_hook) (vrf);
return 1;
}
@ -357,26 +222,25 @@ vrf_enable (struct vrf *vrf)
static void
vrf_disable (struct vrf *vrf)
{
if (vrf_is_enabled (vrf))
{
UNSET_FLAG (vrf->status, VRF_ACTIVE);
if (! vrf_is_enabled (vrf))
return;
if (debug_vrf)
zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id);
UNSET_FLAG (vrf->status, VRF_ACTIVE);
/* Till now, nothing to be done for the default VRF. */
//Pending: see why this statement.
if (debug_vrf)
zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id);
if (vrf_master.vrf_disable_hook)
(*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
}
/* Till now, nothing to be done for the default VRF. */
//Pending: see why this statement.
if (vrf_master.vrf_disable_hook)
(*vrf_master.vrf_disable_hook) (vrf);
}
/* Add a VRF hook. Please add hooks before calling vrf_init(). */
void
vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **))
vrf_add_hook (int type, int (*func)(struct vrf *))
{
if (debug_vrf)
zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__,
@ -400,116 +264,6 @@ vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **))
}
}
/* Return the iterator of the first VRF. */
vrf_iter_t
vrf_first (void)
{
struct route_node *rn;
for (rn = route_top (vrf_table); rn; rn = route_next (rn))
if (rn->info)
{
route_unlock_node (rn); /* top/next */
return (vrf_iter_t)rn;
}
return VRF_ITER_INVALID;
}
/* Return the next VRF iterator to the given iterator. */
vrf_iter_t
vrf_next (vrf_iter_t iter)
{
struct route_node *rn = NULL;
/* Lock it first because route_next() will unlock it. */
if (iter != VRF_ITER_INVALID)
rn = route_next (route_lock_node ((struct route_node *)iter));
for (; rn; rn = route_next (rn))
if (rn->info)
{
route_unlock_node (rn); /* next */
return (vrf_iter_t)rn;
}
return VRF_ITER_INVALID;
}
/* Return the VRF iterator of the given VRF ID. If it does not exist,
* the iterator of the next existing VRF is returned. */
vrf_iter_t
vrf_iterator (vrf_id_t vrf_id)
{
struct prefix p;
struct route_node *rn;
vrf_build_key (vrf_id, &p);
rn = route_node_get (vrf_table, &p);
if (rn->info)
{
/* OK, the VRF exists. */
route_unlock_node (rn); /* get */
return (vrf_iter_t)rn;
}
/* Find the next VRF. */
for (rn = route_next (rn); rn; rn = route_next (rn))
if (rn->info)
{
route_unlock_node (rn); /* next */
return (vrf_iter_t)rn;
}
return VRF_ITER_INVALID;
}
/* Obtain the VRF ID from the given VRF iterator. */
vrf_id_t
vrf_iter2id (vrf_iter_t iter)
{
struct route_node *rn = (struct route_node *) iter;
return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT;
}
struct vrf *
vrf_iter2vrf (vrf_iter_t iter)
{
struct route_node *rn = (struct route_node *) iter;
return (rn && rn->info) ? (struct vrf *)rn->info : NULL;
}
/* Obtain the data pointer from the given VRF iterator. */
void *
vrf_iter2info (vrf_iter_t iter)
{
struct route_node *rn = (struct route_node *) iter;
return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL;
}
/* Obtain the interface list from the given VRF iterator. */
struct list *
vrf_iter2iflist (vrf_iter_t iter)
{
struct route_node *rn = (struct route_node *) iter;
return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL;
}
/* Look up a VRF by name. */
struct vrf *
vrf_lookup_by_name (const char *name)
{
struct vrf *vrf = NULL;
vrf_iter_t iter;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
{
vrf = vrf_iter2vrf (iter);
if (vrf && !strcmp(vrf->name, name))
return vrf;
}
return NULL;
}
vrf_id_t
vrf_name_to_id (const char *name)
{
@ -535,7 +289,7 @@ vrf_info_get (vrf_id_t vrf_id)
void *
vrf_info_lookup (vrf_id_t vrf_id)
{
struct vrf *vrf = vrf_lookup (vrf_id);
struct vrf *vrf = vrf_lookup_by_id (vrf_id);
return vrf ? vrf->info : NULL;
}
@ -543,7 +297,7 @@ vrf_info_lookup (vrf_id_t vrf_id)
struct list *
vrf_iflist (vrf_id_t vrf_id)
{
struct vrf * vrf = vrf_lookup (vrf_id);
struct vrf * vrf = vrf_lookup_by_id (vrf_id);
return vrf ? vrf->iflist : NULL;
}
@ -559,7 +313,7 @@ vrf_iflist_get (vrf_id_t vrf_id)
void
vrf_iflist_create (vrf_id_t vrf_id)
{
struct vrf * vrf = vrf_lookup (vrf_id);
struct vrf * vrf = vrf_lookup_by_id (vrf_id);
if (vrf && !vrf->iflist)
if_init (&vrf->iflist);
}
@ -568,7 +322,7 @@ vrf_iflist_create (vrf_id_t vrf_id)
void
vrf_iflist_terminate (vrf_id_t vrf_id)
{
struct vrf * vrf = vrf_lookup (vrf_id);
struct vrf * vrf = vrf_lookup_by_id (vrf_id);
if (vrf && vrf->iflist)
if_terminate (&vrf->iflist);
}
@ -666,20 +420,6 @@ vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id)
VRF_BITMAP_FLAG (offset)) ? 1 : 0;
}
/* Compare interface names, returning an integer greater than, equal to, or
* less than 0, (following the strcmp convention), according to the
* relationship between vrfp1 and vrfp2. Interface names consist of an
* alphabetic prefix and a numeric suffix. The primary sort key is
* lexicographic by name, and then numeric by number. No number sorts
* before all numbers. Examples: de0 < de1, de100 < fxp0 < xl0, devpty <
* devpty0, de0 < del0
*/
static int
vrf_cmp_func (struct vrf *vrfp1, struct vrf *vrfp2)
{
return if_cmp_name_func (vrfp1->name, vrfp2->name);
}
/* Initialize VRF module. */
void
vrf_init (void)
@ -689,12 +429,6 @@ vrf_init (void)
if (debug_vrf)
zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__);
vrf_list = list_new ();
vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func;
/* Allocate VRF table. */
vrf_table = route_table_init ();
/* The default VRF always exists. */
default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
if (!default_vrf)
@ -715,18 +449,15 @@ vrf_init (void)
void
vrf_terminate (void)
{
struct route_node *rn;
struct vrf *vrf;
if (debug_vrf)
zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__);
for (rn = route_top (vrf_table); rn; rn = route_next (rn))
if ((vrf = rn->info) != NULL)
vrf_delete (vrf);
route_table_finish (vrf_table);
vrf_table = NULL;
while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL)
vrf_delete (vrf);
while ((vrf = RB_ROOT (&vrfs_by_name)) != NULL)
vrf_delete (vrf);
}
/* Create a socket for the VRF. */
@ -740,6 +471,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);
}

View file

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

View file

@ -1042,7 +1042,7 @@ zclient_vrf_delete (struct zclient *zclient, vrf_id_t vrf_id)
struct vrf *vrf;
/* Lookup vrf by vrf_id. */
vrf = vrf_lookup (vrf_id);
vrf = vrf_lookup_by_id (vrf_id);
/*
* If a routing protocol doesn't know about a

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -37,6 +37,7 @@
#include "bgpd/bgp_table.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_mpath.h"
#define VT100_RESET "\x1b[0m"
@ -116,6 +117,7 @@ bgp_create_fake (as_t *as, const char *name)
bgp->maxpaths[afi][safi].maxpaths_ibgp = MULTIPATH_NUM;
}
bgp_scan_init (bgp);
bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;

View file

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

View file

@ -209,13 +209,6 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name)
if (h->nlmsg_type == RTM_NEWLINK)
{
/* If 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)
{

View file

@ -59,6 +59,20 @@ const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
static void if_down_del_nbr_connected (struct interface *ifp);
static void
zebra_if_node_destroy (route_table_delegate_t *delegate,
struct route_table *table, struct route_node *node)
{
if (node->info)
list_delete (node->info);
route_node_destroy (delegate, table, node);
}
route_table_delegate_t zebra_if_table_delegate = {
.create_node = route_node_create,
.destroy_node = zebra_if_node_destroy
};
/* Called when new interface is added. */
static int
if_zebra_new_hook (struct interface *ifp)
@ -101,7 +115,7 @@ if_zebra_new_hook (struct interface *ifp)
#endif /* HAVE_RTADV */
/* Initialize installed address chains tree. */
zebra_if->ipv4_subnets = route_table_init ();
zebra_if->ipv4_subnets = route_table_init_with_delegate (&zebra_if_table_delegate);
ifp->info = zebra_if;
@ -1025,7 +1039,7 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
zebra_ptm_show_status(vty, ifp);
vrf = vrf_lookup(ifp->vrf_id);
vrf = vrf_lookup_by_id (ifp->vrf_id);
vty_out (vty, " vrf: %s%s", vrf->name, VTY_NEWLINE);
if (ifp->desc)
@ -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();
}

View file

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

View file

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

View file

@ -716,11 +716,18 @@ kernel_init (struct zebra_ns *zns)
{
unsigned long groups;
groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR;
#ifdef HAVE_IPV6
groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
#endif /* HAVE_IPV6 */
/* Initialize netlink sockets */
groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR |
RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
snprintf (zns->netlink.name, sizeof (zns->netlink.name),
"netlink-listen (NS %u)", zns->ns_id);
zns->netlink.sock = -1;
netlink_socket (&zns->netlink, groups, zns->ns_id);
snprintf (zns->netlink_cmd.name, sizeof (zns->netlink_cmd.name),
"netlink-cmd (NS %u)", zns->ns_id);
zns->netlink_cmd.sock = -1;
netlink_socket (&zns->netlink_cmd, 0, zns->ns_id);
/* Register kernel socket. */

View file

@ -182,20 +182,46 @@ sighup (void)
static void
sigint (void)
{
struct vrf *vrf;
struct zebra_vrf *zvrf;
struct zebra_ns *zns;
zlog_notice ("Terminating on signal");
if (!retain_mode)
rib_close ();
#ifdef HAVE_IRDP
irdp_finish();
#endif
zebra_ptm_finish();
list_delete_all_node (zebrad.client_list);
if (retain_mode)
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
zvrf = vrf->info;
if (zvrf)
SET_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN);
}
vrf_terminate ();
zns = zebra_ns_lookup (NS_DEFAULT);
zebra_ns_disable (0, (void **)&zns);
access_list_reset ();
prefix_list_reset ();
route_map_finish ();
cmd_terminate ();
vty_terminate ();
zprivs_terminate (&zserv_privs);
list_delete (zebrad.client_list);
work_queue_free (zebrad.ribq);
if (zebrad.lsp_process_q)
work_queue_free (zebrad.lsp_process_q);
meta_queue_free (zebrad.mq);
thread_master_free (zebrad.master);
if (zlog_default)
closezlog (zlog_default);
exit (0);
}

View file

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

View file

@ -366,13 +366,14 @@ extern void rib_update (vrf_id_t, rib_update_event_t);
extern void rib_weed_tables (void);
extern void rib_sweep_route (void);
extern void rib_close_table (struct route_table *);
extern void rib_close (void);
extern void rib_init (void);
extern unsigned long rib_score_proto (u_char proto, u_short instance);
extern void rib_queue_add (struct route_node *rn);
extern void meta_queue_free (struct meta_queue *mq);
extern struct route_table *rib_table_ipv6;
extern void rib_unlink (struct route_node *, struct rib *);
extern int rib_gc_dest (struct route_node *rn);
extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1267,7 +1267,7 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
struct nexthop *nexthop;
/* Lookup table. */
table = zebra_vrf_table (family2afi(prefix->family), SAFI_UNICAST, zvrf->vrf_id);
table = zebra_vrf_table (family2afi(prefix->family), SAFI_UNICAST, zvrf_id (zvrf));
if (! table)
return -1;
@ -1501,7 +1501,7 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)
int update;
/* Process routes of interested address-families. */
table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf->vrf_id);
table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf_id (zvrf));
if (!table)
return;
@ -1828,7 +1828,7 @@ zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf,
vty_out (vty, "%s", VTY_NEWLINE);
}
list_delete_all_node(lsp_list);
list_delete (lsp_list);
}
/*
@ -1868,7 +1868,7 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf)
}
}
list_delete_all_node(slsp_list);
list_delete (slsp_list);
return (zvrf->slsp_table->count ? 1 : 0);
}
@ -1880,9 +1880,11 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf)
void
zebra_mpls_close_tables (struct zebra_vrf *zvrf)
{
if (!zvrf)
return;
hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL);
hash_clean(zvrf->lsp_table, NULL);
hash_free(zvrf->lsp_table);
hash_clean(zvrf->slsp_table, NULL);
hash_free(zvrf->slsp_table);
}
/*

View file

@ -32,7 +32,6 @@
#include "zebra_memory.h"
DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space")
DEFINE_MTYPE(ZEBRA, NETLINK_NAME, "Netlink name")
struct zebra_ns *dzns;
@ -46,24 +45,11 @@ int
zebra_ns_enable (ns_id_t ns_id, void **info)
{
struct zebra_ns *zns = (struct zebra_ns *) (*info);
#ifdef HAVE_NETLINK
char nl_name[64];
#endif
#if defined (HAVE_RTADV)
rtadv_init (zns);
#endif
#ifdef HAVE_NETLINK
/* Initialize netlink sockets */
snprintf (nl_name, 64, "netlink-listen (NS %u)", ns_id);
zns->netlink.sock = -1;
zns->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
snprintf (nl_name, 64, "netlink-cmd (NS %u)", ns_id);
zns->netlink_cmd.sock = -1;
zns->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
#endif
zns->if_table = route_table_init ();
kernel_init (zns);
interface_list (zns);
@ -77,6 +63,7 @@ zebra_ns_disable (ns_id_t ns_id, void **info)
{
struct zebra_ns *zns = (struct zebra_ns *) (*info);
route_table_finish (zns->if_table);
#if defined (HAVE_RTADV)
rtadv_terminate (zns);
#endif

View file

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

View file

@ -140,6 +140,8 @@ zebra_ptm_finish(void)
buffer_flush_all(ptm_cb.wb, ptm_cb.ptm_sock);
free (ptm_hdl);
if (ptm_cb.out_data)
free(ptm_cb.out_data);
@ -256,15 +258,15 @@ DEFUN (zebra_ptm_enable,
"ptm-enable",
"Enable neighbor check with specified topology\n")
{
struct vrf *vrf;
struct listnode *i;
struct interface *ifp;
struct zebra_if *if_data;
vrf_iter_t iter;
ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), i, ifp))
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp))
if (!ifp->ptm_enable)
{
if_data = (struct zebra_if *)ifp->info;
@ -766,9 +768,9 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD,
tmp_buf);
if (zvrf->vrf_id != VRF_DEFAULT)
if (zvrf_id (zvrf) != VRF_DEFAULT)
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD,
zvrf->name);
zvrf_name (zvrf));
}
else
{
@ -913,9 +915,9 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length,
ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
}
#endif /* HAVE_IPV6 */
if (zvrf->vrf_id != VRF_DEFAULT)
if (zvrf_id (zvrf) != VRF_DEFAULT)
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD,
zvrf->name);
zvrf_name (zvrf));
}
else
{
@ -1110,13 +1112,13 @@ zebra_ptm_send_status_req(void)
void
zebra_ptm_reset_status(int ptm_disable)
{
struct vrf *vrf;
struct listnode *i;
struct interface *ifp;
int send_linkup;
vrf_iter_t iter;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), i, ifp))
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp))
{
send_linkup = 0;
if (ifp->ptm_enable)

View file

@ -1303,8 +1303,6 @@ rib_uninstall (struct route_node *rn, struct rib *rib)
}
}
static void rib_unlink (struct route_node *, struct rib *);
/*
* rib_can_delete_dest
*
@ -1352,7 +1350,7 @@ rib_gc_dest (struct route_node *rn)
zvrf = rib_dest_vrf (dest);
if (IS_ZEBRA_DEBUG_RIB)
rnode_debug (rn, zvrf->vrf_id, "removing dest from table");
rnode_debug (rn, zvrf_id (zvrf), "removing dest from table");
dest->rnode = NULL;
XFREE (MTYPE_RIB_DEST, dest);
@ -1385,7 +1383,7 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
{
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)",
zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type);
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type);
}
if (!RIB_SYSTEM_ROUTE (new))
@ -1394,7 +1392,7 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
{
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
zlog_warn ("%u:%s/%d: Route install failed",
zvrf->vrf_id, buf, rn->p.prefixlen);
zvrf_id (zvrf), buf, rn->p.prefixlen);
}
}
@ -1414,7 +1412,7 @@ rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
{
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)",
zvrf->vrf_id, buf, rn->p.prefixlen, rn, old, old->type);
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, old, old->type);
}
if (!RIB_SYSTEM_ROUTE (old))
@ -1463,11 +1461,11 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
{
if (new != old)
zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) "
"old %p (type %d)", zvrf->vrf_id, buf, rn->p.prefixlen,
"old %p (type %d)", zvrf_id (zvrf), buf, rn->p.prefixlen,
rn, new, new->type, old, old->type);
else
zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)",
zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type);
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type);
}
/* Non-system route should be installed. */
if (!RIB_SYSTEM_ROUTE (new))
@ -1477,7 +1475,7 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
installed = 0;
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
zlog_warn ("%u:%s/%d: Route install failed",
zvrf->vrf_id, buf, rn->p.prefixlen);
zvrf_id (zvrf), buf, rn->p.prefixlen);
}
}
@ -1511,12 +1509,12 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
{
if (new != old)
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) "
"old %p (type %d) - %s", zvrf->vrf_id, buf, rn->p.prefixlen,
"old %p (type %d) - %s", zvrf_id (zvrf), buf, rn->p.prefixlen,
rn, new, new->type, old, old->type,
nh_active ? "install failed" : "nexthop inactive");
else
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) - %s",
zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type,
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type,
nh_active ? "install failed" : "nexthop inactive");
}
@ -1626,7 +1624,7 @@ rib_process (struct route_node *rn)
if (dest)
{
zvrf = rib_dest_vrf (dest);
vrf_id = zvrf->vrf_id;
vrf_id = zvrf_id (zvrf);
}
if (IS_ZEBRA_DEBUG_RIB)
@ -2026,7 +2024,7 @@ process_subq (struct list * subq, u_char qindex)
{
inet_ntop (rnode->p.family, &rnode->p.u.prefix, buf, INET6_ADDRSTRLEN);
zlog_debug ("%u:%s/%d: rn %p dequeued from sub-queue %u",
zvrf ? zvrf->vrf_id : 0, buf, rnode->p.prefixlen, rnode, qindex);
zvrf ? zvrf_id (zvrf) : 0, buf, rnode->p.prefixlen, rnode, qindex);
}
if (rnode->info)
@ -2051,24 +2049,24 @@ process_subq (struct list * subq, u_char qindex)
static void
meta_queue_process_complete (struct work_queue *dummy)
{
vrf_iter_t iter;
struct vrf *vrf;
struct zebra_vrf *zvrf;
/* Evaluate nexthops for those VRFs which underwent route processing. This
* should limit the evaluation to the necessary VRFs in most common
* situations.
*/
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
{
if (((zvrf = vrf_iter2info (iter)) != NULL) &&
(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED))
{
zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED;
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL);
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL);
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL);
zebra_evaluate_rnh(zvrf->vrf_id, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL);
}
zvrf = vrf->info;
if (zvrf == NULL || !(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED))
continue;
zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED;
zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_NEXTHOP_TYPE, NULL);
zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL);
zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL);
zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL);
}
/* Schedule LSPs for processing, if needed. */
@ -2076,7 +2074,7 @@ meta_queue_process_complete (struct work_queue *dummy)
if (mpls_should_lsps_be_processed(zvrf))
{
if (IS_ZEBRA_DEBUG_MPLS)
zlog_debug ("%u: Scheduling all LSPs upon RIB completion", zvrf->vrf_id);
zlog_debug ("%u: Scheduling all LSPs upon RIB completion", zvrf_id (zvrf));
zebra_mpls_lsp_schedule (zvrf);
mpls_unmark_lsps_for_processing(zvrf);
}
@ -2151,7 +2149,7 @@ rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
rnode_debug (rn, rib->vrf_id, "queued rn %p into sub-queue %u",
(void *)rn, qindex);
zvrf = zebra_vrf_lookup (rib->vrf_id);
zvrf = zebra_vrf_lookup_by_id (rib->vrf_id);
if (zvrf)
zvrf->flags |= ZEBRA_VRF_RIB_SCHEDULED;
}
@ -2215,6 +2213,17 @@ meta_queue_new (void)
return new;
}
void
meta_queue_free (struct meta_queue *mq)
{
unsigned i;
for (i = 0; i < MQ_SIZE; i++)
list_delete (mq->subq[i]);
XFREE (MTYPE_WORK_QUEUE, mq);
}
/* initialise zebra rib work queue */
static void
rib_queue_init (struct zebra_t *zebra)
@ -2350,7 +2359,7 @@ rib_addnode (struct route_node *rn, struct rib *rib, int process)
* rib_gc_dest() at some point. This allows a rib_dest_t that is no
* longer required to be deleted.
*/
static void
void
rib_unlink (struct route_node *rn, struct rib *rib)
{
rib_dest_t *dest;
@ -3036,11 +3045,11 @@ rib_weed_table (struct route_table *table)
void
rib_weed_tables (void)
{
vrf_iter_t iter;
struct vrf *vrf;
struct zebra_vrf *zvrf;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
if ((zvrf = vrf_iter2info (iter)) != NULL)
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
if ((zvrf = vrf->info) != NULL)
{
rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
@ -3077,11 +3086,11 @@ rib_sweep_table (struct route_table *table)
void
rib_sweep_route (void)
{
vrf_iter_t iter;
struct vrf *vrf;
struct zebra_vrf *zvrf;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
if ((zvrf = vrf_iter2info (iter)) != NULL)
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
if ((zvrf = vrf->info) != NULL)
{
rib_sweep_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
rib_sweep_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
@ -3117,12 +3126,12 @@ rib_score_proto_table (u_char proto, u_short instance, struct route_table *table
unsigned long
rib_score_proto (u_char proto, u_short instance)
{
vrf_iter_t iter;
struct vrf *vrf;
struct zebra_vrf *zvrf;
unsigned long cnt = 0;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
if ((zvrf = vrf_iter2info (iter)) != NULL)
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
if ((zvrf = vrf->info) != NULL)
cnt += rib_score_proto_table (proto, instance, zvrf->table[AFI_IP][SAFI_UNICAST])
+rib_score_proto_table (proto, instance, zvrf->table[AFI_IP6][SAFI_UNICAST]);
@ -3152,43 +3161,6 @@ rib_close_table (struct route_table *table)
}
}
/* Close all RIB tables. */
void
rib_close (void)
{
vrf_iter_t iter;
struct zebra_vrf *zvrf;
struct listnode *node;
struct interface *ifp;
u_int32_t table_id;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
{
if ((zvrf = vrf_iter2info (iter)) != NULL)
{
rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
}
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
}
/* If we do multiple tables per vrf, need to move this to loop above */
zvrf = vrf_info_lookup (VRF_DEFAULT);
for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
{
if (zvrf->other_table[AFI_IP][table_id])
rib_close_table (zvrf->other_table[AFI_IP][table_id]);
if (zvrf->other_table[AFI_IP6][table_id])
rib_close_table (zvrf->other_table[AFI_IP6][table_id]);
}
zebra_mpls_close_tables(zvrf);
}
/* Routing information base initialize. */
void
rib_init (void)
@ -3206,17 +3178,16 @@ rib_init (void)
static inline int
vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
{
vrf_iter_t iter = vrf_iterator (vrf_id);
struct zebra_vrf *zvrf = vrf_iter2info (iter);
struct vrf *vrf;
/* The same one ? Then find out the next. */
if (zvrf && (zvrf->vrf_id == vrf_id))
zvrf = vrf_iter2info (vrf_next (iter));
if (zvrf)
vrf = vrf_lookup_by_id (vrf_id);
if (vrf)
{
*next_id_p = zvrf->vrf_id;
return 1;
vrf = RB_NEXT (vrf_id_head, &vrfs_by_id, vrf);
if (vrf) {
*next_id_p = vrf->vrf_id;
return 1;
}
}
return 0;

View file

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

View file

@ -59,6 +59,7 @@ extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid,
rnh_type_t type);
extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid,
rnh_type_t type);
extern void zebra_free_rnh (struct rnh *rnh);
extern void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type);
extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
vrf_id_t vrfid);

View file

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

View file

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

View file

@ -130,7 +130,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
rib->metric = 0;
rib->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);

View file

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

View file

@ -28,11 +28,8 @@
/* Routing table instance. */
struct zebra_vrf
{
/* Identifier. */
vrf_id_t vrf_id;
/* Routing table name. */
char name[VRF_NAMSIZ];
/* Back pointer */
struct vrf *vrf;
/* Description. */
char *desc;
@ -43,6 +40,7 @@ struct zebra_vrf
/* Flags. */
u_int16_t flags;
#define ZEBRA_VRF_RIB_SCHEDULED (1 << 0)
#define ZEBRA_VRF_RETAIN (2 << 0)
u_int32_t table_id;
@ -86,7 +84,17 @@ struct zebra_vrf
#define MPLS_FLAG_SCHEDULE_LSPS (1 << 0)
};
extern struct list *zvrf_list;
static inline vrf_id_t
zvrf_id (struct zebra_vrf *zvrf)
{
return zvrf->vrf->vrf_id;
}
static inline const char *
zvrf_name (struct zebra_vrf *zvrf)
{
return zvrf->vrf->name;
}
struct route_table *
zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
@ -94,9 +102,9 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
extern void zebra_vrf_static_route_interface_fixup (struct interface *ifp);
extern void zebra_vrf_update_all (struct zserv *client);
extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id);
extern struct zebra_vrf *zebra_vrf_list_lookup_by_name (const char *);
extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *);
extern struct zebra_vrf *zebra_vrf_lookup_by_id (vrf_id_t vrf_id);
extern struct zebra_vrf *zebra_vrf_lookup_by_name (const char *);
extern struct zebra_vrf *zebra_vrf_alloc (void);
extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t);
extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, struct zebra_vrf *zvrf);
extern struct route_table *zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id,

View file

@ -107,7 +107,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
tag = atol(tag_str);
/* VRF id */
zvrf = zebra_vrf_list_lookup_by_name (vrf_id_str);
zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
if (!zvrf)
{
@ -183,7 +183,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
ret = inet_aton (gate_str, &gate);
if (!ret)
{
struct interface *ifp = if_lookup_by_name_vrf (gate_str, zvrf->vrf_id);
struct interface *ifp = if_lookup_by_name_vrf (gate_str, zvrf_id (zvrf));
if (!ifp)
{
vty_out (vty, "%% Unknown interface: %s%s", gate_str, VTY_NEWLINE);
@ -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);
}

View file

@ -185,7 +185,7 @@ static void
zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf)
{
/* Interface information. */
stream_put (s, zvrf->name, VRF_NAMSIZ);
stream_put (s, zvrf_name (zvrf), VRF_NAMSIZ);
/* Write packet size. */
stream_putw_at (s, 0, stream_get_endp (s));
@ -241,7 +241,7 @@ zsend_vrf_add (struct zserv *client, struct zebra_vrf *zvrf)
s = client->obuf;
stream_reset (s);
zserv_create_header (s, ZEBRA_VRF_ADD, zvrf->vrf_id);
zserv_create_header (s, ZEBRA_VRF_ADD, zvrf_id (zvrf));
zserv_encode_vrf (s, zvrf);
client->vrfadd_cnt++;
@ -257,7 +257,7 @@ zsend_vrf_delete (struct zserv *client, struct zebra_vrf *zvrf)
s = client->obuf;
stream_reset (s);
zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf->vrf_id);
zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf_id (zvrf));
zserv_encode_vrf (s, zvrf);
client->vrfdel_cnt++;
@ -850,7 +850,7 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length,
p.family);
return -1;
}
rnh = zebra_add_rnh(&p, zvrf->vrf_id, type);
rnh = zebra_add_rnh(&p, zvrf_id (zvrf), type);
if (type == RNH_NEXTHOP_TYPE)
{
if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
@ -866,9 +866,9 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length,
UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
}
zebra_add_rnh_client(rnh, client, type, zvrf->vrf_id);
zebra_add_rnh_client(rnh, client, type, zvrf_id (zvrf));
/* Anything not AF_INET/INET6 has been filtered out above */
zebra_evaluate_rnh(zvrf->vrf_id, p.family, 1, type, &p);
zebra_evaluate_rnh(zvrf_id (zvrf), p.family, 1, type, &p);
}
return 0;
}
@ -911,7 +911,7 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
p.family);
return -1;
}
rnh = zebra_lookup_rnh(&p, zvrf->vrf_id, type);
rnh = zebra_lookup_rnh(&p, zvrf_id (zvrf), type);
if (rnh)
{
client->nh_dereg_time = quagga_monotime();
@ -939,7 +939,7 @@ zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struc
stream_reset (s);
/* Fill in result. */
zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf->vrf_id);
zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id (zvrf));
stream_put_in_addr (s, &addr);
if (rib)
@ -1005,18 +1005,16 @@ zsend_router_id_update (struct zserv *client, struct prefix *p,
static int
zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{
struct vrf *vrf;
struct listnode *ifnode, *ifnnode;
vrf_iter_t iter;
struct interface *ifp;
struct zebra_vrf *zvrf_iter;
/* Interface information is needed. */
vrf_bitmap_set (client->ifinfo, zvrf->vrf_id);
vrf_bitmap_set (client->ifinfo, zvrf_id (zvrf));
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
{
zvrf_iter = vrf_iter2info (iter);
for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf_iter->vrf_id), ifnode, ifnnode, ifp))
for (ALL_LIST_ELEMENTS (vrf->iflist, ifnode, ifnnode, ifp))
{
/* Skip pseudo interface. */
if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
@ -1036,7 +1034,7 @@ zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvr
static int
zread_interface_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{
vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id);
vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf));
return 0;
}
@ -1093,7 +1091,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
/* VRF ID */
rib->vrf_id = zvrf->vrf_id;
rib->vrf_id = zvrf_id (zvrf);
/* Nexthop parse. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
@ -1245,7 +1243,7 @@ zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
table_id = zvrf->table_id;
rib_delete (AFI_IP, api.safi, zvrf->vrf_id, api.type, api.instance,
rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance,
api.flags, &p, nexthop_p, ifindex, table_id);
client->v4_route_del_cnt++;
return 0;
@ -1259,7 +1257,7 @@ zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zeb
struct rib *rib;
addr.s_addr = stream_get_ipv4 (client->ibuf);
rib = rib_match_ipv4_multicast (zvrf->vrf_id, addr, NULL);
rib = rib_match_ipv4_multicast (zvrf_id (zvrf), addr, NULL);
return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib, zvrf);
}
@ -1303,7 +1301,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
/* VRF ID */
rib->vrf_id = zvrf->vrf_id;
rib->vrf_id = zvrf_id (zvrf);
/* We need to give nh-addr, nh-ifindex with the same next-hop object
* to the rib to ensure that IPv6 multipathing works; need to coalesce
@ -1500,7 +1498,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
rib->mtu = 0;
/* VRF ID */
rib->vrf_id = zvrf->vrf_id;
rib->vrf_id = zvrf_id (zvrf);
rib->table = zvrf->table_id;
ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
@ -1584,10 +1582,10 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
api.tag = 0;
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
rib_delete (AFI_IP6, api.safi, zvrf->vrf_id, api.type, api.instance,
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
api.flags, &p, NULL, ifindex, client->rtm_table);
else
rib_delete (AFI_IP6, api.safi, zvrf->vrf_id, api.type, api.instance,
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
api.flags, &p, pnexthop, ifindex, client->rtm_table);
client->v6_route_del_cnt++;
@ -1601,18 +1599,18 @@ zread_router_id_add (struct zserv *client, u_short length, struct zebra_vrf *zvr
struct prefix p;
/* Router-id information is needed. */
vrf_bitmap_set (client->ridinfo, zvrf->vrf_id);
vrf_bitmap_set (client->ridinfo, zvrf_id (zvrf));
router_id_get (&p, zvrf->vrf_id);
router_id_get (&p, zvrf_id (zvrf));
return zsend_router_id_update (client, &p, zvrf->vrf_id);
return zsend_router_id_update (client, &p, zvrf_id (zvrf));
}
/* Unregister zebra server router-id information. */
static int
zread_router_id_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{
vrf_bitmap_unset (client->ridinfo, zvrf->vrf_id);
vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf));
return 0;
}
@ -1650,10 +1648,10 @@ zread_vrf_unregister (struct zserv *client, u_short length, struct zebra_vrf *zv
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
vrf_bitmap_unset (client->redist[afi][i], zvrf->vrf_id);
vrf_bitmap_unset (client->redist_default, zvrf->vrf_id);
vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id);
vrf_bitmap_unset (client->ridinfo, zvrf->vrf_id);
vrf_bitmap_unset (client->redist[afi][i], zvrf_id (zvrf));
vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf));
vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf));
vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf));
return 0;
}
@ -1724,17 +1722,17 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
static void
zebra_client_close_cleanup_rnh (struct zserv *client)
{
vrf_iter_t iter;
struct vrf *vrf;
struct zebra_vrf *zvrf;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
{
if ((zvrf = vrf_iter2info (iter)) != NULL)
if ((zvrf = vrf->info) != NULL)
{
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_NEXTHOP_TYPE);
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_NEXTHOP_TYPE);
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_IMPORT_CHECK_TYPE);
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_IMPORT_CHECK_TYPE);
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_NEXTHOP_TYPE);
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_NEXTHOP_TYPE);
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_IMPORT_CHECK_TYPE);
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_IMPORT_CHECK_TYPE);
if (client->proto == ZEBRA_ROUTE_LDP)
{
hash_iterate(zvrf->lsp_table, mpls_ldp_lsp_uninstall_all,
@ -1937,7 +1935,7 @@ zebra_client_read (struct thread *thread)
client->last_read_time = quagga_monotime();
client->last_read_cmd = command;
zvrf = zebra_vrf_lookup (vrf_id);
zvrf = zebra_vrf_lookup_by_id (vrf_id);
if (!zvrf)
{
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)