summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--bgpd/bgp_fsm.c6
-rw-r--r--bgpd/bgp_main.c32
-rw-r--r--bgpd/bgp_nexthop.c59
-rw-r--r--bgpd/bgp_nht.c54
-rw-r--r--bgpd/bgp_route.c100
-rw-r--r--bgpd/bgp_route.h2
-rw-r--r--bgpd/bgp_updgrp_adv.c2
-rw-r--r--bgpd/bgp_zebra.c1
-rw-r--r--bgpd/bgpd.c29
-rw-r--r--bgpd/bgpd.h2
-rw-r--r--ldpd/socket.c10
-rw-r--r--lib/command.c2
-rw-r--r--lib/if.c112
-rw-r--r--lib/if.h6
-rw-r--r--lib/ns.c309
-rw-r--r--lib/ns.h97
-rw-r--r--lib/qobj.c1
-rw-r--r--lib/sockopt.c15
-rw-r--r--lib/sockopt.h2
-rw-r--r--lib/table.c4
-rw-r--r--lib/table.h5
-rw-r--r--lib/vrf.c514
-rw-r--r--lib/vrf.h56
-rw-r--r--lib/zclient.c2
-rw-r--r--ospfd/ospf_network.c8
-rw-r--r--ospfd/ospf_packet.c18
-rw-r--r--ospfd/ospf_vty.c13
-rw-r--r--pimd/pim_sock.c6
-rw-r--r--pimd/pim_sock.h2
-rw-r--r--pimd/pim_ssmpingd.c18
-rw-r--r--render_md.py7
-rw-r--r--ripd/rip_interface.c64
-rw-r--r--ripd/ripd.c135
-rw-r--r--ripd/ripd.h13
-rw-r--r--ripngd/ripng_interface.c4
-rw-r--r--ripngd/ripngd.c71
-rw-r--r--tests/bgp_mpath_test.c2
-rw-r--r--zebra/if_netlink.c9
-rw-r--r--zebra/interface.c117
-rw-r--r--zebra/irdp_main.c7
-rw-r--r--zebra/irdp_packet.c10
-rw-r--r--zebra/kernel_netlink.c15
-rw-r--r--zebra/main.c30
-rw-r--r--zebra/redistribute.c16
-rw-r--r--zebra/rib.h3
-rw-r--r--zebra/router-id.c22
-rw-r--r--zebra/rt_netlink.c10
-rw-r--r--zebra/rtadv.c14
-rw-r--r--zebra/zebra_fpm.c2
-rw-r--r--zebra/zebra_fpm_netlink.c2
-rw-r--r--zebra/zebra_memory.h1
-rw-r--r--zebra/zebra_mpls.c14
-rw-r--r--zebra/zebra_ns.c15
-rw-r--r--zebra/zebra_ns.h2
-rw-r--r--zebra/zebra_ptm.c22
-rw-r--r--zebra/zebra_rib.c135
-rw-r--r--zebra/zebra_rnh.c21
-rw-r--r--zebra/zebra_rnh.h1
-rw-r--r--zebra/zebra_rnh_null.c4
-rw-r--r--zebra/zebra_routemap.c8
-rw-r--r--zebra/zebra_static.c4
-rw-r--r--zebra/zebra_vrf.c380
-rw-r--r--zebra/zebra_vrf.h26
-rw-r--r--zebra/zebra_vty.c204
-rw-r--r--zebra/zserv.c74
66 files changed, 1252 insertions, 1701 deletions
diff --git a/README b/README
index f1b25d8a9..91a1d8d0f 100644
--- a/README
+++ b/README
@@ -2,7 +2,7 @@ Quagga is free software that manages various IPv4 and IPv6 routing
protocols.
Currently Quagga supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1,
-RIPv2, and RIPng as well as very early support for IS-IS.
+RIPv2, RIPng, PIM-SSM and LDP as well as very early support for IS-IS.
See the file INSTALL.quagga.txt for building and installation instructions.
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 2f2ea3ae4..60a647533 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -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;
}
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 50ca7eda4..91eacc932 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -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;
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 493655d7f..a77e92c17 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -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;
}
@@ -523,17 +529,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);
-
- 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);
+ afi_t afi;
- 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
@@ -546,29 +549,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]);
-
- bgp_table_unlock (bgp->nexthop_cache_table[AFI_IP]);
- bgp->nexthop_cache_table[AFI_IP] = NULL;
-
- bgp_table_unlock (bgp->connected_table[AFI_IP]);
- bgp->connected_table[AFI_IP] = 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]);
+ afi_t afi;
- bgp_table_unlock (bgp->nexthop_cache_table[AFI_IP6]);
- bgp->nexthop_cache_table[AFI_IP6] = 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_IP6]);
- bgp->connected_table[AFI_IP6] = NULL;
+ bgp_table_unlock (bgp->connected_table[afi]);
+ bgp->connected_table[afi] = 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;
+ }
}
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 9aae3e7b3..1ca048367 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -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);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 6af7aced1..ade05a2c0 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -3121,7 +3121,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
struct bgp_table *table)
{
struct bgp_node *rn;
-
+ int force = bm->process_main_queue ? 0 : 1;
if (! table)
table = peer->bgp->rib[afi][safi];
@@ -3132,7 +3132,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
{
- struct bgp_info *ri;
+ struct bgp_info *ri, *next;
struct bgp_adj_in *ain;
struct bgp_adj_in *ain_next;
@@ -3184,20 +3184,28 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
ain = ain_next;
}
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer)
- {
- struct bgp_clear_node_queue *cnq;
-
- /* 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;
- }
+ for (ri = rn->info; ri; ri = next)
+ {
+ next = ri->next;
+ if (ri->peer != peer)
+ continue;
+
+ 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;
+ struct bgp_node *rn;
- bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST);
+ 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))
+ /*
+ * 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);
}
}
}
@@ -6072,7 +6076,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
}
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 6bd54aba1..63b18aa2d 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -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 *);
diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c
index c485e61e5..a95a11b62 100644
--- a/bgpd/bgp_updgrp_adv.c
+++ b/bgpd/bgp_updgrp_adv.c
@@ -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);
}
}
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 8ecd02539..3d3bd90f5 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -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]);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 50d412633..6d479e102 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1044,6 +1044,12 @@ peer_free (struct peer *peer)
peer->host = NULL;
}
+ if (peer->domainname)
+ {
+ XFREE (MTYPE_BGP_PEER_HOST, peer->domainname);
+ peer->domainname = NULL;
+ }
+
if (peer->ifname)
{
XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
@@ -1972,7 +1978,8 @@ peer_delete (struct peer *peer)
bgp_fsm_change_status (peer, Deleted);
/* Remove from NHT */
- bgp_unlink_nexthop_by_peer (peer);
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+ bgp_unlink_nexthop_by_peer (peer);
/* Password configuration */
if (peer->password)
@@ -2964,7 +2971,7 @@ bgp_lookup_by_vrf_id (vrf_id_t vrf_id)
struct vrf *vrf;
/* Lookup VRF (in tree) and follow link. */
- vrf = vrf_lookup (vrf_id);
+ vrf = vrf_lookup_by_id (vrf_id);
if (!vrf)
return NULL;
return (vrf->info) ? (struct bgp *)vrf->info : NULL;
@@ -3122,6 +3129,7 @@ bgp_delete (struct bgp *bgp)
struct peer *peer;
struct peer_group *group;
struct listnode *node, *next;
+ struct vrf *vrf;
afi_t afi;
int i;
@@ -3178,15 +3186,13 @@ bgp_delete (struct bgp *bgp)
#if ENABLE_BGP_VNC
rfapi_delete(bgp);
- bgp_cleanup_routes(); /* rfapi cleanup can create route entries! */
#endif
+ bgp_cleanup_routes(bgp);
/* Remove visibility via the master list - there may however still be
* routes to be processed still referencing the struct bgp.
*/
listnode_delete (bm->bgp, bgp);
- if (list_isempty(bm->bgp))
- bgp_close ();
/* Deregister from Zebra, if needed */
if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
@@ -3195,6 +3201,10 @@ bgp_delete (struct bgp *bgp)
/* Free interfaces in this instance. */
bgp_if_finish (bgp);
+ vrf = bgp_vrf_lookup_by_instance_type (bgp);
+ if (vrf)
+ bgp_vrf_unlink (bgp, vrf);
+
thread_master_free_unused(bm->master);
bgp_unlock(bgp); /* initial reference */
@@ -3222,7 +3232,6 @@ bgp_free (struct bgp *bgp)
{
afi_t afi;
safi_t safi;
- struct vrf *vrf;
list_delete (bgp->group);
list_delete (bgp->peer);
@@ -3244,13 +3253,9 @@ bgp_free (struct bgp *bgp)
bgp_table_finish (&bgp->rib[afi][safi]);
}
+ bgp_scan_finish (bgp);
bgp_address_destroy (bgp);
- /* If Default instance or VRF, unlink from the VRF structure. */
- vrf = bgp_vrf_lookup_by_instance_type (bgp);
- if (vrf)
- bgp_vrf_unlink (bgp, vrf);
-
if (bgp->name)
XFREE(MTYPE_BGP, bgp->name);
@@ -7596,8 +7601,6 @@ bgp_terminate (void)
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_PEER_UNCONFIG);
- bgp_cleanup_routes ();
-
if (bm->process_main_queue)
{
work_queue_free (bm->process_main_queue);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index dd6a0fdcc..510082fdc 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -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
diff --git a/ldpd/socket.c b/ldpd/socket.c
index cf352d720..1bb083740 100644
--- a/ldpd/socket.c
+++ b/ldpd/socket.c
@@ -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
diff --git a/lib/command.c b/lib/command.c
index 3c429ce1a..f691cb599 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -2496,4 +2496,6 @@ cmd_terminate ()
XFREE (MTYPE_HOST, host.motdfile);
if (host.config)
XFREE (MTYPE_HOST, host.config);
+
+ qobj_finish ();
}
diff --git a/lib/if.c b/lib/if.c
index dadf35574..3ae08abf5 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -307,13 +307,11 @@ if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id)
struct interface *
if_lookup_by_name_all_vrf (const char *name)
{
+ struct vrf *vrf;
struct interface *ifp;
- struct vrf *vrf = NULL;
- vrf_iter_t iter;
- for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
{
- vrf = vrf_iter2vrf (iter);
ifp = if_lookup_by_name_vrf (name, vrf->vrf_id);
if (ifp)
return ifp;
@@ -392,7 +390,7 @@ if_lookup_exact_address (void *src, int family)
}
/* Lookup interface by IPv4 address. */
-struct interface *
+struct connected *
if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
{
struct listnode *node;
@@ -401,7 +399,7 @@ if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
struct listnode *cnode;
struct interface *ifp;
struct connected *c;
- struct interface *match;
+ struct connected *match;
if (family == AF_INET)
{
@@ -427,14 +425,14 @@ if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
(c->address->prefixlen > bestlen))
{
bestlen = c->address->prefixlen;
- match = ifp;
+ match = c;
}
}
}
return match;
}
-struct interface *
+struct connected *
if_lookup_address (void *matchaddr, int family)
{
return if_lookup_address_vrf (matchaddr, family, VRF_DEFAULT);
@@ -489,18 +487,16 @@ struct interface *
if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id, int vty)
{
struct interface *ifp;
+ struct vrf *vrf;
struct listnode *node;
- struct vrf *vrf = NULL;
- vrf_iter_t iter;
ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id);
if (ifp)
return ifp;
/* Didn't find the interface on that vrf. Defined on a different one? */
- for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
{
- vrf = vrf_iter2vrf(iter);
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf->vrf_id), node, ifp))
{
if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
@@ -665,14 +661,13 @@ if_dump (const struct interface *ifp)
void
if_dump_all (void)
{
- struct list *intf_list;
+ struct vrf *vrf;
struct listnode *node;
void *p;
- vrf_iter_t iter;
- for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
- if ((intf_list = vrf_iter2iflist (iter)) != NULL)
- for (ALL_LIST_ELEMENTS_RO (intf_list, node, p))
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
+ if (vrf->iflist != NULL)
+ for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, p))
if_dump (p);
}
@@ -832,65 +827,6 @@ DEFUN_NOSH (no_interface,
return CMD_SUCCESS;
}
-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;
-}
-
-
/* For debug purpose. */
DEFUN (show_address,
show_address_cmd,
@@ -931,24 +867,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))
{
@@ -1359,14 +1293,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;
diff --git a/lib/if.h b/lib/if.h
index 7fdd46d3f..c53b9ff0e 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -161,6 +161,7 @@ struct if_stats
#define LP_RES_BW 0x0400
#define LP_AVA_BW 0x0800
#define LP_USE_BW 0x1000
+#define LP_TE_METRIC 0x2000
#define IS_PARAM_UNSET(lp, st) !(lp->lp_status & st)
#define IS_PARAM_SET(lp, st) (lp->lp_status & st)
@@ -174,6 +175,7 @@ struct if_stats
struct if_link_params {
u_int32_t lp_status; /* Status of Link Parameters: */
u_int32_t te_metric; /* Traffic Engineering metric */
+ float default_bw;
float max_bw; /* Maximum Bandwidth */
float max_rsv_bw; /* Maximum Reservable Bandwidth */
float unrsv_bw[MAX_CLASS_TYPE]; /* Unreserved Bandwidth per Class Type (8) */
@@ -387,7 +389,7 @@ extern int if_cmp_name_func (char *, char *);
extern struct interface *if_create (const char *name, int namelen);
extern struct interface *if_lookup_by_index (ifindex_t);
extern struct interface *if_lookup_exact_address (void *matchaddr, int family);
-extern struct interface *if_lookup_address (void *matchaddr, int family);
+extern struct connected *if_lookup_address (void *matchaddr, int family);
extern struct interface *if_lookup_prefix (struct prefix *prefix);
extern void if_update_vrf (struct interface *, const char *name, int namelen,
@@ -397,7 +399,7 @@ extern struct interface *if_create_vrf (const char *name, int namelen,
extern struct interface *if_lookup_by_index_vrf (ifindex_t, vrf_id_t vrf_id);
extern struct interface *if_lookup_exact_address_vrf (void *matchaddr, int family,
vrf_id_t vrf_id);
-extern struct interface *if_lookup_address_vrf (void *matchaddr, int family,
+extern struct connected *if_lookup_address_vrf (void *matchaddr, int family,
vrf_id_t vrf_id);
extern struct interface *if_lookup_prefix_vrf (struct prefix *prefix,
vrf_id_t vrf_id);
diff --git a/lib/ns.c b/lib/ns.c
index d8db1e45a..1673ac0a6 100644
--- a/lib/ns.c
+++ b/lib/ns.c
@@ -31,8 +31,6 @@
#include "if.h"
#include "ns.h"
-#include "prefix.h"
-#include "table.h"
#include "log.h"
#include "memory.h"
@@ -41,7 +39,13 @@
DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router")
DEFINE_MTYPE_STATIC(LIB, NS_NAME, "Logical-Router Name")
-DEFINE_MTYPE_STATIC(LIB, NS_BITMAP, "Logical-Router bit-map")
+
+static __inline int ns_compare (struct ns *, struct ns *);
+static struct ns *ns_lookup (ns_id_t);
+
+RB_GENERATE (ns_head, ns, entry, ns_compare)
+
+struct ns_head ns_tree = RB_INITIALIZER (&ns_tree);
#ifndef CLONE_NEWNET
#define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */
@@ -91,22 +95,6 @@ static int have_netns(void)
#endif
}
-struct ns
-{
- /* Identifier, same as the vector index */
- ns_id_t ns_id;
- /* Name */
- char *name;
- /* File descriptor */
- int fd;
-
- /* Master list of interfaces belonging to this NS */
- struct list *iflist;
-
- /* User data */
- void *info;
-};
-
/* Holding NS hooks */
struct ns_master
{
@@ -116,44 +104,30 @@ struct ns_master
int (*ns_disable_hook) (ns_id_t, void **);
} ns_master = {0,};
-/* NS table */
-struct route_table *ns_table = NULL;
-
static int ns_is_enabled (struct ns *ns);
static int ns_enable (struct ns *ns);
static void ns_disable (struct ns *ns);
-
-/* Build the table key */
-static void
-ns_build_key (ns_id_t ns_id, struct prefix *p)
+static __inline int
+ns_compare(struct ns *a, struct ns *b)
{
- p->family = AF_INET;
- p->prefixlen = IPV4_MAX_BITLEN;
- p->u.prefix4.s_addr = ns_id;
+ return (a->ns_id - b->ns_id);
}
/* Get a NS. If not found, create one. */
static struct ns *
ns_get (ns_id_t ns_id)
{
- struct prefix p;
- struct route_node *rn;
struct ns *ns;
- ns_build_key (ns_id, &p);
- rn = route_node_get (ns_table, &p);
- if (rn->info)
- {
- ns = (struct ns *)rn->info;
- route_unlock_node (rn); /* get */
- return ns;
- }
+ ns = ns_lookup (ns_id);
+ if (ns)
+ return (ns);
ns = XCALLOC (MTYPE_NS, sizeof (struct ns));
ns->ns_id = ns_id;
ns->fd = -1;
- rn->info = ns;
+ RB_INSERT (ns_head, &ns_tree, ns);
/*
* Initialize interfaces.
@@ -188,6 +162,7 @@ ns_delete (struct ns *ns)
*/
//if_terminate (&ns->iflist);
+ RB_REMOVE (ns_head, &ns_tree, ns);
if (ns->name)
XFREE (MTYPE_NS_NAME, ns->name);
@@ -198,18 +173,9 @@ ns_delete (struct ns *ns)
static struct ns *
ns_lookup (ns_id_t ns_id)
{
- struct prefix p;
- struct route_node *rn;
- struct ns *ns = NULL;
-
- ns_build_key (ns_id, &p);
- rn = route_node_lookup (ns_table, &p);
- if (rn)
- {
- ns = (struct ns *)rn->info;
- route_unlock_node (rn); /* lookup */
- }
- return ns;
+ struct ns ns;
+ ns.ns_id = ns_id;
+ return (RB_FIND (ns_head, &ns_tree, &ns));
}
/*
@@ -310,217 +276,6 @@ ns_add_hook (int type, int (*func)(ns_id_t, void **))
}
}
-/* Return the iterator of the first NS. */
-ns_iter_t
-ns_first (void)
-{
- struct route_node *rn;
-
- for (rn = route_top (ns_table); rn; rn = route_next (rn))
- if (rn->info)
- {
- route_unlock_node (rn); /* top/next */
- return (ns_iter_t)rn;
- }
- return NS_ITER_INVALID;
-}
-
-/* Return the next NS iterator to the given iterator. */
-ns_iter_t
-ns_next (ns_iter_t iter)
-{
- struct route_node *rn = NULL;
-
- /* Lock it first because route_next() will unlock it. */
- if (iter != NS_ITER_INVALID)
- rn = route_next (route_lock_node ((struct route_node *)iter));
-
- for (; rn; rn = route_next (rn))
- if (rn->info)
- {
- route_unlock_node (rn); /* next */
- return (ns_iter_t)rn;
- }
- return NS_ITER_INVALID;
-}
-
-/* Return the NS iterator of the given NS ID. If it does not exist,
- * the iterator of the next existing NS is returned. */
-ns_iter_t
-ns_iterator (ns_id_t ns_id)
-{
- struct prefix p;
- struct route_node *rn;
-
- ns_build_key (ns_id, &p);
- rn = route_node_get (ns_table, &p);
- if (rn->info)
- {
- /* OK, the NS exists. */
- route_unlock_node (rn); /* get */
- return (ns_iter_t)rn;
- }
-
- /* Find the next NS. */
- for (rn = route_next (rn); rn; rn = route_next (rn))
- if (rn->info)
- {
- route_unlock_node (rn); /* next */
- return (ns_iter_t)rn;
- }
-
- return NS_ITER_INVALID;
-}
-
-/* Obtain the NS ID from the given NS iterator. */
-ns_id_t
-ns_iter2id (ns_iter_t iter)
-{
- struct route_node *rn = (struct route_node *) iter;
- return (rn && rn->info) ? ((struct ns *)rn->info)->ns_id : NS_DEFAULT;
-}
-
-/* Obtain the data pointer from the given NS iterator. */
-void *
-ns_iter2info (ns_iter_t iter)
-{
- struct route_node *rn = (struct route_node *) iter;
- return (rn && rn->info) ? ((struct ns *)rn->info)->info : NULL;
-}
-
-/* Obtain the interface list from the given NS iterator. */
-struct list *
-ns_iter2iflist (ns_iter_t iter)
-{
- struct route_node *rn = (struct route_node *) iter;
- return (rn && rn->info) ? ((struct ns *)rn->info)->iflist : NULL;
-}
-
-/* Get the data pointer of the specified NS. If not found, create one. */
-void *
-ns_info_get (ns_id_t ns_id)
-{
- struct ns *ns = ns_get (ns_id);
- return ns->info;
-}
-
-/* Look up the data pointer of the specified NS. */
-void *
-ns_info_lookup (ns_id_t ns_id)
-{
- struct ns *ns = ns_lookup (ns_id);
- return ns ? ns->info : NULL;
-}
-
-/* Look up the interface list in a NS. */
-struct list *
-ns_iflist (ns_id_t ns_id)
-{
- struct ns * ns = ns_lookup (ns_id);
- return ns ? ns->iflist : NULL;
-}
-
-/* Get the interface list of the specified NS. Create one if not find. */
-struct list *
-ns_iflist_get (ns_id_t ns_id)
-{
- struct ns * ns = ns_get (ns_id);
- return ns->iflist;
-}
-
-/*
- * NS bit-map
- */
-
-#define NS_BITMAP_NUM_OF_GROUPS 8
-#define NS_BITMAP_NUM_OF_BITS_IN_GROUP \
- (UINT16_MAX / NS_BITMAP_NUM_OF_GROUPS)
-#define NS_BITMAP_NUM_OF_BYTES_IN_GROUP \
- (NS_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
-
-#define NS_BITMAP_GROUP(_id) \
- ((_id) / NS_BITMAP_NUM_OF_BITS_IN_GROUP)
-#define NS_BITMAP_BIT_OFFSET(_id) \
- ((_id) % NS_BITMAP_NUM_OF_BITS_IN_GROUP)
-
-#define NS_BITMAP_INDEX_IN_GROUP(_bit_offset) \
- ((_bit_offset) / CHAR_BIT)
-#define NS_BITMAP_FLAG(_bit_offset) \
- (((u_char)1) << ((_bit_offset) % CHAR_BIT))
-
-struct ns_bitmap
-{
- u_char *groups[NS_BITMAP_NUM_OF_GROUPS];
-};
-
-ns_bitmap_t
-ns_bitmap_init (void)
-{
- return (ns_bitmap_t) XCALLOC (MTYPE_NS_BITMAP, sizeof (struct ns_bitmap));
-}
-
-void
-ns_bitmap_free (ns_bitmap_t bmap)
-{
- struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
- int i;
-
- if (bmap == NS_BITMAP_NULL)
- return;
-
- for (i = 0; i < NS_BITMAP_NUM_OF_GROUPS; i++)
- if (bm->groups[i])
- XFREE (MTYPE_NS_BITMAP, bm->groups[i]);
-
- XFREE (MTYPE_NS_BITMAP, bm);
-}
-
-void
-ns_bitmap_set (ns_bitmap_t bmap, ns_id_t ns_id)
-{
- struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
- u_char group = NS_BITMAP_GROUP (ns_id);
- u_char offset = NS_BITMAP_BIT_OFFSET (ns_id);
-
- if (bmap == NS_BITMAP_NULL)
- return;
-
- if (bm->groups[group] == NULL)
- bm->groups[group] = XCALLOC (MTYPE_NS_BITMAP,
- NS_BITMAP_NUM_OF_BYTES_IN_GROUP);
-
- SET_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)],
- NS_BITMAP_FLAG (offset));
-}
-
-void
-ns_bitmap_unset (ns_bitmap_t bmap, ns_id_t ns_id)
-{
- struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
- u_char group = NS_BITMAP_GROUP (ns_id);
- u_char offset = NS_BITMAP_BIT_OFFSET (ns_id);
-
- if (bmap == NS_BITMAP_NULL || bm->groups[group] == NULL)
- return;
-
- UNSET_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)],
- NS_BITMAP_FLAG (offset));
-}
-
-int
-ns_bitmap_check (ns_bitmap_t bmap, ns_id_t ns_id)
-{
- struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
- u_char group = NS_BITMAP_GROUP (ns_id);
- u_char offset = NS_BITMAP_BIT_OFFSET (ns_id);
-
- if (bmap == NS_BITMAP_NULL || bm->groups[group] == NULL)
- return 0;
-
- return CHECK_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)],
- NS_BITMAP_FLAG (offset)) ? 1 : 0;
-}
-
/*
* NS realization with NETNS
*/
@@ -645,17 +400,17 @@ static struct cmd_node ns_node =
static int
ns_config_write (struct vty *vty)
{
- struct route_node *rn;
struct ns *ns;
int write = 0;
- for (rn = route_top (ns_table); rn; rn = route_next (rn))
- if ((ns = rn->info) != NULL &&
- ns->ns_id != NS_DEFAULT && ns->name)
- {
- vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name, VTY_NEWLINE);
- write++;
- }
+ RB_FOREACH (ns, ns_head, &ns_tree) {
+ if (ns->ns_id == NS_DEFAULT || ns->name == NULL)
+ continue;
+
+ vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name,
+ VTY_NEWLINE);
+ write = 1;
+ }
return write;
}
@@ -666,9 +421,6 @@ ns_init (void)
{
struct ns *default_ns;
- /* Allocate NS table. */
- ns_table = route_table_init ();
-
/* The default NS always exists. */
default_ns = ns_get (NS_DEFAULT);
if (!default_ns)
@@ -700,15 +452,10 @@ ns_init (void)
void
ns_terminate (void)
{
- struct route_node *rn;
struct ns *ns;
- for (rn = route_top (ns_table); rn; rn = route_next (rn))
- if ((ns = rn->info) != NULL)
- ns_delete (ns);
-
- route_table_finish (ns_table);
- ns_table = NULL;
+ while ((ns = RB_ROOT (&ns_tree)) != NULL)
+ ns_delete (ns);
}
/* Create a socket for the NS. */
diff --git a/lib/ns.h b/lib/ns.h
index 3fac73986..2a7be1ef8 100644
--- a/lib/ns.h
+++ b/lib/ns.h
@@ -23,6 +23,7 @@
#ifndef _ZEBRA_NS_H
#define _ZEBRA_NS_H
+#include "openbsd-tree.h"
#include "linklist.h"
typedef u_int16_t ns_id_t;
@@ -30,15 +31,32 @@ typedef u_int16_t ns_id_t;
/* The default NS ID */
#define NS_DEFAULT 0
-/*
- * The command strings
- */
+/* Default netns directory (Linux) */
#define NS_RUN_DIR "/var/run/netns"
-#define NS_CMD_STR "logical-router <0-65535>"
-#define NS_CMD_HELP_STR "Specify the Logical-Router\nThe Logical-Router ID\n"
-#define NS_ALL_CMD_STR "logical-router all"
-#define NS_ALL_CMD_HELP_STR "Specify the logical-router\nAll logical-router's\n"
+struct ns
+{
+ RB_ENTRY(ns) entry;
+
+ /* Identifier, same as the vector index */
+ ns_id_t ns_id;
+
+ /* Name */
+ char *name;
+
+ /* File descriptor */
+ int fd;
+
+ /* Master list of interfaces belonging to this NS */
+ struct list *iflist;
+
+ /* User data */
+ void *info;
+};
+RB_HEAD (ns_head, ns);
+RB_PROTOTYPE (ns_head, ns, entry, ns_compare)
+
+extern struct ns_head ns_tree;
/*
* NS hooks
@@ -60,71 +78,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
*/
/* Please add hooks before calling ns_init(). */
diff --git a/lib/qobj.c b/lib/qobj.c
index 65b537f96..f64972e32 100644
--- a/lib/qobj.c
+++ b/lib/qobj.c
@@ -78,6 +78,7 @@ void qobj_init (void)
void qobj_finish (void)
{
+ hash_clean (nodes, NULL);
hash_free (nodes);
nodes = NULL;
}
diff --git a/lib/sockopt.c b/lib/sockopt.c
index c480cee0d..be3ac0e4b 100644
--- a/lib/sockopt.c
+++ b/lib/sockopt.c
@@ -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)
{
diff --git a/lib/sockopt.h b/lib/sockopt.h
index d67b510b6..02f018934 100644
--- a/lib/sockopt.h
+++ b/lib/sockopt.h
@@ -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. */
diff --git a/lib/table.c b/lib/table.c
index d0e084ead..5133ef697 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -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)
{
diff --git a/lib/table.h b/lib/table.h
index e6cdcfef1..78bf5da74 100644
--- a/lib/table.h
+++ b/lib/table.h
@@ -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
diff --git a/lib/vrf.c b/lib/vrf.c
index 63adea4ae..548c03dac 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -35,6 +35,15 @@ DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
DEFINE_QOBJ_TYPE(vrf)
+static __inline int vrf_id_compare (struct vrf *, struct vrf *);
+static __inline int vrf_name_compare (struct vrf *, struct vrf *);
+
+RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare)
+RB_GENERATE (vrf_name_head, vrf, name_entry, vrf_name_compare)
+
+struct vrf_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id);
+struct vrf_name_head vrfs_by_name = RB_INITIALIZER (&vrfs_by_name);
+
/*
* Turn on/off debug code
* for vrf.
@@ -44,44 +53,34 @@ int debug_vrf = 0;
/* Holding VRF hooks */
struct vrf_master
{
- int (*vrf_new_hook) (vrf_id_t, const char *, void **);
- int (*vrf_delete_hook) (vrf_id_t, const char *, void **);
- int (*vrf_enable_hook) (vrf_id_t, const char *, void **);
- int (*vrf_disable_hook) (vrf_id_t, const char *, void **);
+ int (*vrf_new_hook) (struct vrf *);
+ int (*vrf_delete_hook) (struct vrf *);
+ int (*vrf_enable_hook) (struct vrf *);
+ int (*vrf_disable_hook) (struct vrf *);
} vrf_master = {0,};
-/* VRF table */
-struct route_table *vrf_table = NULL;
-
-/* VRF is part of a list too to store it before its actually active */
-struct list *vrf_list;
-
static int vrf_is_enabled (struct vrf *vrf);
static void vrf_disable (struct vrf *vrf);
/* VRF list existance check by name. */
struct vrf *
-vrf_list_lookup_by_name (const char *name)
+vrf_lookup_by_name (const char *name)
{
- struct listnode *node;
- struct vrf *vrfp;
+ struct vrf vrf;
+ strlcpy (vrf.name, name, sizeof (vrf.name));
+ return (RB_FIND (vrf_name_head, &vrfs_by_name, &vrf));
+}
- if (name)
- for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrfp))
- {
- if (strcmp(name, vrfp->name) == 0)
- return vrfp;
- }
- return NULL;
+static __inline int
+vrf_id_compare (struct vrf *a, struct vrf *b)
+{
+ return (a->vrf_id - b->vrf_id);
}
-/* Build the table key */
-static void
-vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
+static int
+vrf_name_compare (struct vrf *a, struct vrf *b)
{
- p->family = AF_INET;
- p->prefixlen = IPV4_MAX_BITLEN;
- p->u.prefix4.s_addr = vrf_id;
+ 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,66 @@ 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;
+}
+
+
/*
* Debug CLI for vrf's
*/
@@ -791,4 +582,7 @@ vrf_install_commands (void)
install_element (ENABLE_NODE, &vrf_debug_cmd);
install_element (CONFIG_NODE, &no_vrf_debug_cmd);
install_element (ENABLE_NODE, &no_vrf_debug_cmd);
+
+ install_element (CONFIG_NODE, &vrf_cmd);
+ install_element (CONFIG_NODE, &no_vrf_cmd);
}
diff --git a/lib/vrf.h b/lib/vrf.h
index f1fbad9ff..eae66599f 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -23,6 +23,7 @@
#ifndef _ZEBRA_VRF_H
#define _ZEBRA_VRF_H
+#include "openbsd-tree.h"
#include "linklist.h"
#include "qobj.h"
@@ -65,18 +66,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 +86,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 +104,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 +116,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; \
@@ -132,34 +130,6 @@ extern vrf_id_t vrf_name_to_id (const char *);
} 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
*/
diff --git a/lib/zclient.c b/lib/zclient.c
index 84f7314ba..894e0d19e 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -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
diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c
index 6caa38d68..088123ea2 100644
--- a/ospfd/ospf_network.c
+++ b/ospfd/ospf_network.c
@@ -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",
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index b7ef24409..72ce5586f 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -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))
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 8662eb425..bc013a83e 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -4393,10 +4393,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",
diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c
index a024e3ae0..231efd0f2 100644
--- a/pimd/pim_sock.c
+++ b/pimd/pim_sock.c
@@ -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));
diff --git a/pimd/pim_sock.h b/pimd/pim_sock.h
index f0a160081..cd29543fa 100644
--- a/pimd/pim_sock.h
+++ b/pimd/pim_sock.h
@@ -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,
diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c
index fe88eba27..fba563a6f 100644
--- a/pimd/pim_ssmpingd.c
+++ b/pimd/pim_ssmpingd.c
@@ -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,
diff --git a/render_md.py b/render_md.py
index d2d1fb480..16c4bbe8a 100644
--- a/render_md.py
+++ b/render_md.py
@@ -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; }
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 8c5092d78..9cf3338bb 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -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;
@@ -537,6 +538,8 @@ rip_interface_reset (struct rip_interface *ri)
ri->ri_send = RI_RIP_UNSPEC;
ri->ri_receive = RI_RIP_UNSPEC;
+ ri->v2_broadcast = 0;
+
if (ri->auth_str)
{
free (ri->auth_str);
@@ -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);
@@ -2029,6 +2076,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);
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 24ba74c73..9de3ca7c3 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -812,7 +812,15 @@ rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
struct interface *ifp)
{
struct rip_interface *ri;
- char *auth_str;
+ char *auth_str = (char *) &rte->prefix;
+ int i;
+
+ /* reject passwords with zeros in the middle of the string */
+ for (i = strlen (auth_str); i < 16; i++)
+ {
+ if (auth_str[i] != '\0')
+ return 0;
+ }
if (IS_RIP_DEBUG_EVENT)
zlog_debug ("RIPv2 simple password authentication from %s",
@@ -827,8 +835,6 @@ rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
/* Simple password authentication. */
if (ri->auth_str)
{
- auth_str = (char *) &rte->prefix;
-
if (strncmp (auth_str, ri->auth_str, 16) == 0)
return 1;
}
@@ -841,7 +847,7 @@ rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
if (keychain == NULL)
return 0;
- key = key_match_for_accept (keychain, (char *) &rte->prefix);
+ key = key_match_for_accept (keychain, auth_str);
if (key)
return 1;
}
@@ -1333,30 +1339,23 @@ rip_response_process (struct rip_packet *packet, int size,
/* Make socket for RIP protocol. */
static int
-rip_create_socket (struct sockaddr_in *from)
+rip_create_socket (void)
{
int ret;
int sock;
struct sockaddr_in addr;
memset (&addr, 0, sizeof (struct sockaddr_in));
-
- if (!from)
- {
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- addr.sin_len = sizeof (struct sockaddr_in);
+ addr.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
- } else {
- memcpy(&addr, from, sizeof(addr));
- }
-
/* sending port must always be the RIP port */
addr.sin_port = htons (RIP_PORT_DEFAULT);
/* Make datagram socket. */
- sock = socket (AF_INET, SOCK_DGRAM, 0);
+ sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock < 0)
{
zlog_err("Cannot create UDP socket: %s", safe_strerror(errno));
@@ -1366,6 +1365,7 @@ rip_create_socket (struct sockaddr_in *from)
sockopt_broadcast (sock);
sockopt_reuseaddr (sock);
sockopt_reuseport (sock);
+ setsockopt_ipv4_multicast_loop (sock, 0);
#ifdef RIP_RECVMSG
setsockopt_pktinfo (sock);
#endif /* RIP_RECVMSG */
@@ -1406,7 +1406,7 @@ static int
rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,
struct connected *ifc)
{
- int ret, send_sock;
+ int ret;
struct sockaddr_in sin;
assert (ifc != NULL);
@@ -1462,38 +1462,16 @@ rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,
{
sin.sin_port = to->sin_port;
sin.sin_addr = to->sin_addr;
- send_sock = rip->sock;
}
else
{
- struct sockaddr_in from;
-
sin.sin_port = htons (RIP_PORT_DEFAULT);
sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
-
- /* multicast send should bind to local interface address */
- memset (&from, 0, sizeof (from));
- from.sin_family = AF_INET;
- from.sin_port = htons (RIP_PORT_DEFAULT);
- from.sin_addr = ifc->address->u.prefix4;
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- from.sin_len = sizeof (struct sockaddr_in);
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
-
- /*
- * we have to open a new socket for each packet because this
- * is the most portable way to bind to a different source
- * ipv4 address for each packet.
- */
- if ( (send_sock = rip_create_socket (&from)) < 0)
- {
- zlog_warn("rip_send_packet could not create socket.");
- return -1;
- }
- rip_interface_multicast_set (send_sock, ifc);
+
+ rip_interface_multicast_set (rip->sock, ifc);
}
- ret = sendto (send_sock, buf, size, 0, (struct sockaddr *)&sin,
+ ret = sendto (rip->sock, buf, size, 0, (struct sockaddr *)&sin,
sizeof (struct sockaddr_in));
if (IS_RIP_DEBUG_EVENT)
@@ -1503,9 +1481,6 @@ rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,
if (ret < 0)
zlog_warn ("can't send packet : %s", safe_strerror (errno));
- if (!to)
- close(send_sock);
-
return ret;
}
@@ -1681,6 +1656,9 @@ rip_request_process (struct rip_packet *packet, int size,
}
else
{
+ if (ntohs (rte->family) != AF_INET)
+ return;
+
/* Examine the list of RTEs in the Request one by one. For each
entry, look up the destination in the router's routing
database and, if there is a route, put that route's metric in
@@ -1803,7 +1781,7 @@ rip_read (struct thread *t)
int len;
int vrecv;
socklen_t fromlen;
- struct interface *ifp;
+ struct interface *ifp = NULL;
struct connected *ifc;
struct rip_interface *ri;
struct prefix p;
@@ -1836,8 +1814,10 @@ rip_read (struct thread *t)
}
/* Which interface is this packet comes from. */
- ifp = if_lookup_address ((void *)&from.sin_addr, AF_INET);
-
+ ifc = if_lookup_address ((void *)&from.sin_addr, AF_INET);
+ if (ifc)
+ ifp = ifc->ifp;
+
/* RIP packet received */
if (IS_RIP_DEBUG_EVENT)
zlog_debug ("RECV packet from %s port %d on %s",
@@ -1928,15 +1908,9 @@ rip_read (struct thread *t)
/* RIP Version check. RFC2453, 4.6 and 5.1 */
vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ?
rip->version_recv : ri->ri_receive);
- if ((packet->version == RIPv1) && !(vrecv & RIPv1))
- {
- if (IS_RIP_DEBUG_PACKET)
- zlog_debug (" packet's v%d doesn't fit to if version spec",
- packet->version);
- rip_peer_bad_packet (&from);
- return -1;
- }
- if ((packet->version == RIPv2) && !(vrecv & RIPv2))
+ if (vrecv == RI_RIP_VERSION_NONE ||
+ ((packet->version == RIPv1) && !(vrecv & RIPv1)) ||
+ ((packet->version == RIPv2) && !(vrecv & RIPv2)))
{
if (IS_RIP_DEBUG_PACKET)
zlog_debug (" packet's v%d doesn't fit to if version spec",
@@ -2434,20 +2408,22 @@ rip_output_process (struct connected *ifc, struct sockaddr_in *to,
static void
rip_update_interface (struct connected *ifc, u_char version, int route_type)
{
+ struct interface *ifp = ifc->ifp;
+ struct rip_interface *ri = ifp->info;
struct sockaddr_in to;
/* When RIP version is 2 and multicast enable interface. */
- if (version == RIPv2 && if_is_multicast (ifc->ifp))
+ if (version == RIPv2 && !ri->v2_broadcast && if_is_multicast (ifp))
{
if (IS_RIP_DEBUG_EVENT)
- zlog_debug ("multicast announce on %s ", ifc->ifp->name);
+ zlog_debug ("multicast announce on %s ", ifp->name);
rip_output_process (ifc, NULL, route_type, version);
return;
}
/* If we can't send multicast packet, send it with unicast. */
- if (if_is_broadcast (ifc->ifp) || if_is_pointopoint (ifc->ifp))
+ if (if_is_broadcast (ifp) || if_is_pointopoint (ifp))
{
if (ifc->address->family == AF_INET)
{
@@ -2469,7 +2445,7 @@ rip_update_interface (struct connected *ifc, u_char version, int route_type)
if (IS_RIP_DEBUG_EVENT)
zlog_debug("%s announce to %s on %s",
CONNECTED_PEER(ifc) ? "unicast" : "broadcast",
- inet_ntoa (to.sin_addr), ifc->ifp->name);
+ inet_ntoa (to.sin_addr), ifp->name);
rip_output_process (ifc, &to, route_type, version);
}
@@ -2539,21 +2515,14 @@ rip_update_process (int route_type)
{
p = &rp->p;
- ifp = if_lookup_prefix (p);
- if (! ifp)
+ connected = if_lookup_address (&p->u.prefix4, AF_INET);
+ if (! connected)
{
zlog_warn ("Neighbor %s doesnt have connected interface!",
inet_ntoa (p->u.prefix4));
continue;
}
- if ( (connected = connected_lookup_prefix (ifp, p)) == NULL)
- {
- zlog_warn ("Neighbor %s doesnt have connected network",
- inet_ntoa (p->u.prefix4));
- continue;
- }
-
/* Set destination address and port */
memset (&to, 0, sizeof (struct sockaddr_in));
to.sin_addr = p->u.prefix4;
@@ -2579,11 +2548,7 @@ rip_update (struct thread *t)
/* Triggered updates may be suppressed if a regular update is due by
the time the triggered update would be sent. */
- if (rip->t_triggered_interval)
- {
- thread_cancel (rip->t_triggered_interval);
- rip->t_triggered_interval = NULL;
- }
+ RIP_TIMER_OFF (rip->t_triggered_interval);
rip->trigger = 0;
/* Register myself. */
@@ -2637,11 +2602,7 @@ rip_triggered_update (struct thread *t)
rip->t_triggered_update = NULL;
/* Cancel interval timer. */
- if (rip->t_triggered_interval)
- {
- thread_cancel (rip->t_triggered_interval);
- rip->t_triggered_interval = NULL;
- }
+ RIP_TIMER_OFF (rip->t_triggered_interval);
rip->trigger = 0;
/* Logging triggered update. */
@@ -2729,7 +2690,7 @@ rip_create (void)
rip->obuf = stream_new (1500);
/* Make socket. */
- rip->sock = rip_create_socket (NULL);
+ rip->sock = rip_create_socket ();
if (rip->sock < 0)
return rip->sock;
@@ -2819,11 +2780,7 @@ rip_event (enum rip_event event, int sock)
rip->t_read = thread_add_read (master, rip_read, NULL, sock);
break;
case RIP_UPDATE_EVENT:
- if (rip->t_update)
- {
- thread_cancel (rip->t_update);
- rip->t_update = NULL;
- }
+ RIP_TIMER_OFF (rip->t_update);
jitter = rip_update_jitter (rip->update_time);
rip->t_update =
thread_add_timer (master, rip_update, NULL,
@@ -3919,11 +3876,7 @@ rip_clean (void)
RIP_TIMER_OFF (rip->t_triggered_interval);
/* Cancel read thread. */
- if (rip->t_read)
- {
- thread_cancel (rip->t_read);
- rip->t_read = NULL;
- }
+ THREAD_READ_OFF (rip->t_read);
/* Close RIP socket. */
if (rip->sock >= 0)
diff --git a/ripd/ripd.h b/ripd/ripd.h
index 1cc46ff31..cd4d560af 100644
--- a/ripd/ripd.h
+++ b/ripd/ripd.h
@@ -258,6 +258,9 @@ struct rip_interface
int ri_send;
int ri_receive;
+ /* RIPv2 broadcast mode */
+ int v2_broadcast;
+
/* RIPv2 authentication type. */
int auth_type;
@@ -347,6 +350,7 @@ struct rip_md5_data
#define RI_RIP_VERSION_1 1
#define RI_RIP_VERSION_2 2
#define RI_RIP_VERSION_1_AND_2 3
+#define RI_RIP_VERSION_NONE 4
/* N.B. stuff will break if
(RIPv1 != RI_RIP_VERSION_1) || (RIPv2 != RI_RIP_VERSION_2) */
@@ -369,14 +373,7 @@ enum rip_event
} while (0)
/* Macro for timer turn off. */
-#define RIP_TIMER_OFF(X) \
- do { \
- if (X) \
- { \
- thread_cancel (X); \
- (X) = NULL; \
- } \
- } while (0)
+#define RIP_TIMER_OFF(X) THREAD_TIMER_OFF(X)
/* Prototypes. */
extern void rip_init (void);
diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c
index 7bee7625d..664187030 100644
--- a/ripngd/ripng_interface.c
+++ b/ripngd/ripng_interface.c
@@ -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;
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index e7db97120..ca8850e5f 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -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",
@@ -3028,6 +3091,8 @@ ripng_init ()
install_element (VIEW_NODE, &show_ipv6_ripng_cmd);
install_element (VIEW_NODE, &show_ipv6_ripng_status_cmd);
+ install_element (ENABLE_NODE, &clear_ipv6_rip_cmd);
+
install_element (CONFIG_NODE, &router_ripng_cmd);
install_element (CONFIG_NODE, &no_router_ripng_cmd);
diff --git a/tests/bgp_mpath_test.c b/tests/bgp_mpath_test.c
index dbcb00a2e..723f2977d 100644
--- a/tests/bgp_mpath_test.c
+++ b/tests/bgp_mpath_test.c
@@ -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;
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index f7f6334a7..c5fd16b9c 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -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)
{
diff --git a/zebra/interface.c b/zebra/interface.c
index 91dbe5276..f48450d5e 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -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)
@@ -1269,33 +1283,6 @@ struct cmd_node interface_node =
1
};
-/* Wrapper hook point for zebra daemon so that ifindex can be set
- * DEFUN macro not used as extract.pl HAS to ignore this
- * See also interface_cmd in lib/if.c
- */
-DEFUN_NOSH (zebra_vrf,
- zebra_vrf_cmd,
- "vrf NAME",
- "Select a VRF to configure\n"
- "VRF's name\n")
-{
- // VTY_DECLVAR_CONTEXT (vrf, vrfp);
- int ret;
-
- /* Call lib vrf() */
- if ((ret = vrf_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
- return ret;
-
- return ret;
-}
-
-struct cmd_node vrf_node =
-{
- VRF_NODE,
- "%s(config-vrf)# ",
- 1
-};
-
/* Show all interfaces to vty. */
DEFUN (show_interface,
show_interface_cmd,
@@ -1329,15 +1316,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;
@@ -1385,17 +1372,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);
@@ -1480,15 +1467,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;
@@ -1825,7 +1811,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;
}
@@ -1839,7 +1825,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;
}
@@ -2777,20 +2763,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);
@@ -2821,14 +2808,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;
@@ -2837,7 +2824,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);
@@ -2905,23 +2892,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)
@@ -2933,7 +2903,6 @@ zebra_if_init (void)
/* Install configuration write function. */
install_node (&interface_node, if_config_write);
install_node (&link_params_node, NULL);
- install_node (&vrf_node, vrf_config_write);
install_element (VIEW_NODE, &show_interface_cmd);
install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
@@ -2990,8 +2959,4 @@ zebra_if_init (void)
install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
-
- install_element (CONFIG_NODE, &zebra_vrf_cmd);
- install_element (CONFIG_NODE, &no_vrf_cmd);
- install_default (VRF_NODE);
}
diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c
index cc3a4abaf..7fa4ad4cb 100644
--- a/zebra/irdp_main.c
+++ b/zebra/irdp_main.c
@@ -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;
diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c
index 25c7aff26..c9c32ce31 100644
--- a/zebra/irdp_packet.c
+++ b/zebra/irdp_packet.c
@@ -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;
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 378327ab4..9f9a62f38 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -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. */
diff --git a/zebra/main.c b/zebra/main.c
index 9247d4350..4fea0104f 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -182,20 +182,46 @@ sighup (void)
static void
sigint (void)
{
+ struct vrf *vrf;
+ struct zebra_vrf *zvrf;
struct zebra_ns *zns;
zlog_notice ("Terminating on signal");
- if (!retain_mode)
- rib_close ();
#ifdef HAVE_IRDP
irdp_finish();
#endif
zebra_ptm_finish();
+ list_delete_all_node (zebrad.client_list);
+
+ if (retain_mode)
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
+ {
+ zvrf = vrf->info;
+ if (zvrf)
+ SET_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN);
+ }
+ vrf_terminate ();
zns = zebra_ns_lookup (NS_DEFAULT);
zebra_ns_disable (0, (void **)&zns);
+
+ access_list_reset ();
+ prefix_list_reset ();
+ route_map_finish ();
+ cmd_terminate ();
+ vty_terminate ();
+ zprivs_terminate (&zserv_privs);
+ list_delete (zebrad.client_list);
+ work_queue_free (zebrad.ribq);
+ if (zebrad.lsp_process_q)
+ work_queue_free (zebrad.lsp_process_q);
+ meta_queue_free (zebrad.mq);
+ thread_master_free (zebrad.master);
+ if (zlog_default)
+ closezlog (zlog_default);
+
exit (0);
}
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index c74485bb3..9c7ef5f12 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -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. */
diff --git a/zebra/rib.h b/zebra/rib.h
index c95a9ba0c..30929f1be 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -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);
diff --git a/zebra/router-id.c b/zebra/router-id.c
index 23b8cc743..b1e786d0c 100644
--- a/zebra/router-id.c
+++ b/zebra/router-id.c
@@ -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);
}
}
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 90d71e635..f168ef395 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -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");
}
}
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index dcf31ff45..0d4ce9313 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -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;
}
diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c
index 7e8b8682d..80512c71f 100644
--- a/zebra/zebra_fpm.c
+++ b/zebra/zebra_fpm.c
@@ -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)
diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c
index f2cba1094..a09008b39 100644
--- a/zebra/zebra_fpm_netlink.c
+++ b/zebra/zebra_fpm_netlink.c
@@ -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;
/*
diff --git a/zebra/zebra_memory.h b/zebra/zebra_memory.h
index fbd8f3261..c1ac4fe95 100644
--- a/zebra/zebra_memory.h
+++ b/zebra/zebra_memory.h
@@ -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 */
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 3b19a5da0..3333b7226 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -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);
}
/*
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index 41034e198..642d2700a 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -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
diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h
index 8a821c465..c50f9249d 100644
--- a/zebra/zebra_ns.h
+++ b/zebra/zebra_ns.h
@@ -32,7 +32,7 @@ struct nlsock
int sock;
int seq;
struct sockaddr_nl snl;
- const char *name;
+ char name[64];
};
#endif
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index ebae1bd4b..e6d13b507 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -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)
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 8b36eb806..c573f6bd5 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -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);
-
- /* The same one ? Then find out the next. */
- if (zvrf && (zvrf->vrf_id == vrf_id))
- zvrf = vrf_iter2info (vrf_next (iter));
+ struct vrf *vrf;
- 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;
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 062f9d383..c4c11f98d 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -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)
{
@@ -163,6 +163,16 @@ zebra_lookup_rnh (struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
}
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)
{
struct route_node *rn;
@@ -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
diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h
index 3a57ef1bc..4394fde4f 100644
--- a/zebra/zebra_rnh.h
+++ b/zebra/zebra_rnh.h
@@ -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);
diff --git a/zebra/zebra_rnh_null.c b/zebra/zebra_rnh_null.c
index a5e6b3562..286290a52 100644
--- a/zebra/zebra_rnh_null.c
+++ b/zebra/zebra_rnh_null.c
@@ -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)
{}
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index 28f09fea0..54aaef674 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -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;
diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c
index 7dc6cbaaa..e6ae9c71d 100644
--- a/zebra/zebra_static.c
+++ b/zebra/zebra_static.c
@@ -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);
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 8db89b1e4..d06b0c03d 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -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,51 @@ zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
return zvrf->table[afi][SAFI_UNICAST];
}
+/* Wrapper hook point for zebra daemon so that ifindex can be set
+ * DEFUN macro not used as extract.pl HAS to ignore this
+ * See also interface_cmd in lib/if.c
+ */
+DEFUN_NOSH (zebra_vrf,
+ zebra_vrf_cmd,
+ "vrf NAME",
+ "Select a VRF to configure\n"
+ "VRF's name\n")
+{
+ // VTY_DECLVAR_CONTEXT (vrf, vrfp);
+ int ret;
+
+ /* Call lib vrf() */
+ if ((ret = vrf_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
+ return ret;
+
+ return ret;
+}
+
+static int
+vrf_config_write (struct vty *vty)
+{
+ struct vrf *vrf;
+ struct zebra_vrf *zvrf;
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
+ {
+ zvrf = vrf->info;
+ if (! zvrf || strcmp (zvrf_name (zvrf), VRF_DEFAULT_NAME))
+ {
+ vty_out (vty, "vrf %s%s", zvrf_name (zvrf), VTY_NEWLINE);
+ vty_out (vty, "!%s", VTY_NEWLINE);
+ }
+ }
+ return 0;
+}
+
+struct cmd_node vrf_node =
+{
+ VRF_NODE,
+ "%s(config-vrf)# ",
+ 1
+};
+
/* Zebra VRF initialization. */
void
zebra_vrf_init (void)
@@ -437,7 +574,10 @@ zebra_vrf_init (void)
vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete);
- zvrf_list = list_new ();
-
vrf_init ();
+
+ install_node (&vrf_node, vrf_config_write);
+ install_default (VRF_NODE);
+ install_element (CONFIG_NODE, &zebra_vrf_cmd);
+ install_element (CONFIG_NODE, &no_vrf_cmd);
}
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index 0baddc1b6..96d631d64 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -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,
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 05356b3d0..16a667469 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -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);
}
diff --git a/zebra/zserv.c b/zebra/zserv.c
index cb396942a..61ea55f47 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -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)