summaryrefslogtreecommitdiff
path: root/zebra/zebra_rib.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2015-10-30 05:52:29 -0700
committerDonald Sharp <sharpd@cumulusnetworks.com>2015-10-30 05:52:29 -0700
commitbe5e48abecd137b47e4493a8fd616186c61f48f7 (patch)
tree4184faeca4bb606af98deb606d9b53db3ac314b4 /zebra/zebra_rib.c
parent526e17284570266dcdd606ff163a614e6b3655a5 (diff)
parent2bed4e86e378334341e01f3afe33784ef2713e83 (diff)
Merge branch 'cmaster' of ssh://stash.cumulusnetworks.com:7999/quag/quagga into cmaster
Conflicts: zebra/rib.h zebra/zebra_rib.c zebra/zebra_vty.c
Diffstat (limited to 'zebra/zebra_rib.c')
-rw-r--r--zebra/zebra_rib.c525
1 files changed, 287 insertions, 238 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 94a6315292..0bb9b58118 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -35,6 +35,7 @@
#include "prefix.h"
#include "routemap.h"
#include "nexthop.h"
+#include "vrf.h"
#include "zebra/rib.h"
#include "zebra/rt.h"
@@ -78,137 +79,29 @@ static const struct
/* no entry/default: 150 */
};
-/* Vector for routing table. */
-static vector vrf_vector;
-
/*
- * vrf_table_create
+ * nexthop_type_to_str
*/
-static void
-vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
-{
- rib_table_info_t *info;
- struct route_table *table;
-
- assert (!vrf->table[afi][safi]);
-
- table = route_table_init ();
- vrf->table[afi][safi] = table;
-
- info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
- info->vrf = vrf;
- info->afi = afi;
- info->safi = safi;
- table->info = info;
-}
-
-/* Allocate new VRF. */
-static struct vrf *
-vrf_alloc (const char *name)
-{
- struct vrf *vrf;
-
- vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
-
- /* Put name. */
- if (name)
- vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
-
- /* Allocate routing table and static table. */
- vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
- vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
- vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
- vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
- vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
- vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
- vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
- vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
-
- vrf->rnh_table[AFI_IP] = route_table_init();
- vrf->rnh_table[AFI_IP6] = route_table_init();
-
- vrf->import_check_table[AFI_IP] = route_table_init();
- vrf->import_check_table[AFI_IP6] = route_table_init();
-
- return vrf;
-}
-
-/* Lookup VRF by identifier. */
-struct vrf *
-vrf_lookup (u_int32_t id)
-{
- return vector_lookup (vrf_vector, id);
-}
-
-/* Initialize VRF. */
-static void
-vrf_init (void)
-{
- struct vrf *default_table;
-
- /* Allocate VRF vector. */
- vrf_vector = vector_init (1);
-
- /* Allocate default main table. */
- default_table = vrf_alloc ("Default-IP-Routing-Table");
-
- /* Default table index must be 0. */
- vector_set_index (vrf_vector, 0, default_table);
-}
-
-/* Lookup route table. */
-struct route_table *
-vrf_table (afi_t afi, safi_t safi, u_int32_t id)
-{
- struct vrf *vrf;
-
- vrf = vrf_lookup (id);
- if (! vrf)
- return NULL;
-
- if( afi >= AFI_MAX || safi >= SAFI_MAX )
- return NULL;
-
- return vrf->table[afi][safi];
-}
-
-/* Lookup static route table. */
-struct route_table *
-vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
-{
- struct vrf *vrf;
-
- vrf = vrf_lookup (id);
- if (! vrf)
- return NULL;
-
- if( afi >= AFI_MAX || safi >= SAFI_MAX )
- return NULL;
-
- return vrf->stable[afi][safi];
-}
-
-struct route_table *
-vrf_other_route_table (afi_t afi, u_int32_t table_id, u_int32_t vrf_id)
-{
- struct vrf *vrf;
-
- vrf = vrf_lookup (vrf_id);
- if (! vrf)
- return NULL;
-
- if(afi >= AFI_MAX)
- return NULL;
-
- if (table_id >= ZEBRA_KERNEL_TABLE_MAX)
- return NULL;
+const char *
+nexthop_type_to_str (enum nexthop_types_t nh_type)
+{
+ static const char *desc[] = {
+ "none",
+ "Directly connected",
+ "Interface route",
+ "IPv4 nexthop",
+ "IPv4 nexthop with ifindex",
+ "IPv4 nexthop with ifname",
+ "IPv6 nexthop",
+ "IPv6 nexthop with ifindex",
+ "IPv6 nexthop with ifname",
+ "Null0 nexthop",
+ };
- if (vrf->other_table[afi][table_id] == NULL)
- {
- vrf->other_table[afi][table_id] = route_table_init();
- }
+ if (nh_type >= ZEBRA_NUM_OF (desc))
+ return "<Invalid nh type>";
- return (vrf->other_table[afi][table_id]);
+ return desc[nh_type];
}
int
@@ -583,7 +476,7 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
p.prefix = nexthop->gate.ipv4;
/* Lookup table. */
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id);
if (! table)
return 0;
@@ -791,7 +684,7 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
p.prefix = nexthop->gate.ipv6;
/* Lookup table. */
- table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
+ table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, rib->vrf_id);
if (! table)
return 0;
@@ -944,7 +837,7 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
}
struct rib *
-rib_match_ipv4 (struct in_addr addr)
+rib_match_ipv4 (struct in_addr addr, vrf_id_t vrf_id)
{
struct prefix_ipv4 p;
struct route_table *table;
@@ -954,7 +847,7 @@ rib_match_ipv4 (struct in_addr addr)
int recursing;
/* Lookup table. */
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (! table)
return 0;
@@ -1006,7 +899,7 @@ rib_match_ipv4 (struct in_addr addr)
}
struct rib *
-rib_lookup_ipv4 (struct prefix_ipv4 *p)
+rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
{
struct route_table *table;
struct route_node *rn;
@@ -1015,7 +908,7 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p)
int recursing;
/* Lookup table. */
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (! table)
return 0;
@@ -1062,7 +955,8 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p)
* 3: no matches found
*/
int
-rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
+rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
+ vrf_id_t vrf_id)
{
struct route_table *table;
struct route_node *rn;
@@ -1072,7 +966,7 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
int nexthops_active;
/* Lookup table. */
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (! table)
return ZEBRA_RIB_LOOKUP_ERROR;
@@ -1127,7 +1021,7 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
}
struct rib *
-rib_match_ipv6 (struct in6_addr *addr)
+rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id)
{
struct prefix_ipv6 p;
struct route_table *table;
@@ -1137,7 +1031,7 @@ rib_match_ipv6 (struct in6_addr *addr)
int recursing;
/* Lookup table. */
- table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
+ table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
if (! table)
return 0;
@@ -1220,7 +1114,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
switch (nexthop->type)
{
case NEXTHOP_TYPE_IFINDEX:
- ifp = if_lookup_by_index (nexthop->ifindex);
+ ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
if (ifp && if_is_operative(ifp))
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
@@ -1229,7 +1123,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
case NEXTHOP_TYPE_IPV6_IFNAME:
family = AFI_IP6;
case NEXTHOP_TYPE_IFNAME:
- ifp = if_lookup_by_name (nexthop->ifname);
+ ifp = if_lookup_by_name_vrf (nexthop->ifname, rib->vrf_id);
if (ifp && if_is_operative(ifp))
{
if (set)
@@ -1264,7 +1158,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
family = AFI_IP6;
if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
{
- ifp = if_lookup_by_index (nexthop->ifindex);
+ ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
if (ifp && if_is_operative(ifp))
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
@@ -1306,7 +1200,8 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
/* It'll get set if required inside */
- ret = zebra_route_map_check(family, rib->type, &rn->p, nexthop, rib->tag);
+ ret = zebra_route_map_check(family, rib->type, &rn->p, nexthop, rib->vrf_id,
+ rib->tag);
if (ret == RMAP_DENYMATCH)
{
if (IS_ZEBRA_DEBUG_RIB)
@@ -2238,7 +2133,7 @@ rib_delnode (struct route_node *rn, struct rib *rib)
int
rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
struct in_addr *gate, struct in_addr *src,
- unsigned int ifindex, u_int32_t table_id,
+ unsigned int ifindex, vrf_id_t vrf_id, u_int32_t table_id,
u_int32_t metric, u_char distance, safi_t safi)
{
struct rib *rib;
@@ -2250,11 +2145,11 @@ rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
/* Lookup table. */
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
{
- table = vrf_table (AFI_IP, safi, 0);
+ table = zebra_vrf_table (AFI_IP, safi, vrf_id);
}
else
{
- table = vrf_other_route_table (AFI_IP, table_id, 0);
+ table = zebra_vrf_other_route_table (AFI_IP, table_id, vrf_id);
}
if (! table)
return 0;
@@ -2314,6 +2209,7 @@ rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
rib->flags = flags;
rib->metric = metric;
rib->table = table_id;
+ rib->vrf_id = vrf_id;
rib->nexthop_num = 0;
rib->uptime = time (NULL);
@@ -2367,8 +2263,8 @@ void _rib_dump (const char * func,
struct nexthop *nexthop, *tnexthop;
int recursing;
- inet_ntop (p->family, &p->u.prefix, straddr, INET6_ADDRSTRLEN);
- zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
+ zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, rib,
+ prefix2str(pp, straddr, sizeof(straddr)), rib->vrf_id);
zlog_debug
(
"%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d",
@@ -2426,10 +2322,10 @@ void rib_lookup_and_dump (struct prefix_ipv4 * p)
char prefix_buf[INET_ADDRSTRLEN];
/* Lookup table. */
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
if (! table)
{
- zlog_err ("%s: vrf_table() returned NULL", __func__);
+ zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
return;
}
@@ -2475,9 +2371,9 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p)
struct rib *rib;
unsigned changed = 0;
- if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
+ if (NULL == (table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT)))
{
- zlog_err ("%s: vrf_table() returned NULL", __func__);
+ zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
return;
}
@@ -2527,11 +2423,11 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
/* Lookup table. */
if ((rib->table == zebrad.rtm_table_default) || (rib->table == RT_TABLE_MAIN))
{
- table = vrf_table (AFI_IP, safi, 0);
+ table = zebra_vrf_table (AFI_IP, safi, rib->vrf_id);
}
else
{
- table = vrf_other_route_table (AFI_IP, rib->table, 0);
+ table = zebra_vrf_other_route_table (AFI_IP, rib->table, rib->vrf_id);
}
if (! table)
return 0;
@@ -2601,7 +2497,7 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
/* XXX factor with rib_delete_ipv6 */
int
rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
- struct in_addr *gate, unsigned int ifindex,
+ struct in_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
u_int32_t table_id, safi_t safi)
{
struct route_table *table;
@@ -2617,11 +2513,11 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
/* Lookup table. */
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
{
- table = vrf_table (AFI_IP, safi, 0);
+ table = zebra_vrf_table (AFI_IP, safi, vrf_id);
}
else
{
- table = vrf_other_route_table(AFI_IP, table_id, 0);
+ table = zebra_vrf_other_route_table(AFI_IP, table_id, vrf_id);
}
if (! table)
return 0;
@@ -2632,15 +2528,13 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
if (IS_ZEBRA_DEBUG_KERNEL)
{
if (gate)
- zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
- inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
- p->prefixlen,
+ zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u via %s ifindex %d",
+ prefix2str (p, buf1, sizeof(buf1)), vrf_id,
inet_ntoa (*gate),
ifindex);
else
- zlog_debug ("rib_delete_ipv4(): route delete %s/%d ifindex %d",
- inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
- p->prefixlen,
+ zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u ifindex %d",
+ prefix2str (p, buf1, sizeof(buf1)), vrf_id,
ifindex);
}
@@ -2651,15 +2545,13 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
if (IS_ZEBRA_DEBUG_KERNEL)
{
if (gate)
- zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
- inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
- p->prefixlen,
+ zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
+ prefix2str (p, buf1, sizeof(buf1)), vrf_id,
inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
ifindex);
else
- zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
- inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
- p->prefixlen,
+ zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
+ prefix2str (p, buf1, sizeof(buf1)), vrf_id,
ifindex);
}
return ZEBRA_ERR_RTNOEXIST;
@@ -2744,16 +2636,15 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
if (IS_ZEBRA_DEBUG_KERNEL)
{
if (gate)
- zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
- inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
- p->prefixlen,
+ zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
+ "doesn't exist in rib",
+ prefix2str (p, buf1, sizeof(buf1)), vrf_id,
inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
ifindex,
type);
else
- zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
- inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
- p->prefixlen,
+ zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
+ prefix2str (p, buf1, sizeof(buf1)), vrf_id,
ifindex,
type);
}
@@ -2779,7 +2670,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
struct prefix nh_p;
/* Lookup table. */
- table = vrf_table (afi, safi, 0);
+ table = zebra_vrf_table (afi, safi, si->vrf_id);
if (! table)
return;
@@ -2843,6 +2734,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
rib->instance = 0;
rib->distance = si->distance;
rib->metric = 0;
+ rib->vrf_id = si->vrf_id;
rib->table = zebrad.rtm_table_default;
rib->nexthop_num = 0;
rib->tag = si->tag;
@@ -2926,7 +2818,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
struct prefix nh_p;
/* Lookup table. */
- table = vrf_table (afi, safi, 0);
+ table = zebra_vrf_table (afi, safi, si->vrf_id);
if (! table)
return;
@@ -3026,7 +2918,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
/* Add static route into static route configuration. */
int
static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
- u_char flags, u_short tag, u_char distance, u_int32_t vrf_id)
+ u_char flags, u_short tag, u_char distance, vrf_id_t vrf_id)
{
u_char type = 0;
struct route_node *rn;
@@ -3034,10 +2926,9 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
struct static_route *pp;
struct static_route *cp;
struct static_route *update = NULL;
- struct route_table *stable;
+ struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
+ struct route_table *stable = zvrf->stable[AFI_IP][SAFI_UNICAST];
- /* Lookup table. */
- stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (! stable)
return -1;
@@ -3080,6 +2971,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
si->distance = distance;
si->flags = flags;
si->tag = tag;
+ si->vrf_id = vrf_id;
if (gate)
si->addr.ipv4 = *gate;
@@ -3122,7 +3014,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
/* Delete static route from static route configuration. */
int
static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
- u_short tag, u_char distance, u_int32_t vrf_id)
+ u_short tag, u_char distance, vrf_id_t vrf_id)
{
u_char type = 0;
struct route_node *rn;
@@ -3130,7 +3022,7 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
struct route_table *stable;
/* Lookup table. */
- stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
+ stable = zebra_vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (! stable)
return -1;
@@ -3208,8 +3100,8 @@ rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
int
rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
- struct in6_addr *gate, unsigned int ifindex, u_int32_t table_id,
- u_int32_t metric, u_char distance, safi_t safi)
+ struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
+ u_int32_t table_id, u_int32_t metric, u_char distance, safi_t safi)
{
struct rib *rib;
struct rib *same = NULL;
@@ -3220,11 +3112,11 @@ rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
/* Lookup table. */
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
{
- table = vrf_table (AFI_IP6, safi, 0);
+ table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
}
else
{
- table = vrf_other_route_table(AFI_IP6, table_id, 0);
+ table = zebra_vrf_other_route_table(AFI_IP6, table_id, vrf_id);
}
if (! table)
return 0;
@@ -3280,6 +3172,7 @@ rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
rib->flags = flags;
rib->metric = metric;
rib->table = table_id;
+ rib->vrf_id = vrf_id;
rib->nexthop_num = 0;
rib->uptime = time (NULL);
@@ -3340,7 +3233,7 @@ rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi,
if (!rib)
return 0;
- table = vrf_table (AFI_IP, safi, 0);
+ table = zebra_vrf_table (AFI_IP, safi, VRF_DEFAULT);
if (!table)
return 0;
/* Make it sure prefixlen is applied to the prefix. */
@@ -3356,11 +3249,11 @@ rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi,
/* Lookup table. */
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
{
- table = vrf_table (AFI_IP6, safi, 0);
+ table = zebra_vrf_table (AFI_IP6, safi, VRF_DEFAULT);
}
else
{
- table = vrf_other_route_table(AFI_IP6, table_id, 0);
+ table = zebra_vrf_other_route_table(AFI_IP6, table_id, VRF_DEFAULT);
}
if (! table)
@@ -3443,7 +3336,8 @@ rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi,
/* XXX factor with rib_delete_ipv6 */
int
rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
- struct in6_addr *gate, unsigned int ifindex, u_int32_t table_id, safi_t safi)
+ struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
+ u_int32_t table_id, safi_t safi)
{
struct route_table *table;
struct route_node *rn;
@@ -3461,11 +3355,11 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
/* Lookup table. */
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
{
- table = vrf_table (AFI_IP6, safi, 0);
+ table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
}
else
{
- table = vrf_other_route_table(AFI_IP6, table_id, 0);
+ table = zebra_vrf_other_route_table(AFI_IP6, table_id, VRF_DEFAULT);
}
if (! table)
return 0;
@@ -3477,15 +3371,13 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
if (IS_ZEBRA_DEBUG_KERNEL)
{
if (gate)
- zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
- inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
- p->prefixlen,
+ zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
+ prefix2str (p, buf1, sizeof(buf1)), vrf_id,
inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
ifindex);
else
- zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
- inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
- p->prefixlen,
+ zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
+ prefix2str (p, buf1, sizeof(buf1)), vrf_id,
ifindex);
}
return ZEBRA_ERR_RTNOEXIST;
@@ -3571,16 +3463,15 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
if (IS_ZEBRA_DEBUG_KERNEL)
{
if (gate)
- zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
- inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
- p->prefixlen,
+ zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
+ "doesn't exist in rib",
+ prefix2str (p, buf1, sizeof(buf1)), vrf_id,
inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
ifindex,
type);
else
- zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
- inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
- p->prefixlen,
+ zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
+ prefix2str (p, buf1, sizeof(buf1)), vrf_id,
ifindex,
type);
}
@@ -3600,17 +3491,16 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
int
static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
const char *ifname, u_char flags, u_short tag,
- u_char distance, u_int32_t vrf_id)
+ u_char distance, vrf_id_t vrf_id)
{
struct route_node *rn;
struct static_route *si;
struct static_route *pp;
struct static_route *cp;
struct static_route *update = NULL;
- struct route_table *stable;
+ struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
+ struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
- /* Lookup table. */
- stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
if (! stable)
return -1;
@@ -3653,6 +3543,7 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
si->distance = distance;
si->flags = flags;
si->tag = tag;
+ si->vrf_id = vrf_id;
switch (type)
{
@@ -3698,14 +3589,14 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
int
static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
const char *ifname, u_short tag, u_char distance,
- u_int32_t vrf_id)
+ vrf_id_t vrf_id)
{
struct route_node *rn;
struct static_route *si;
struct route_table *stable;
/* Lookup table. */
- stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
+ stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
if (! stable)
return -1;
@@ -3751,13 +3642,13 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
/* RIB update function. */
void
-rib_update_static (void)
+rib_update_static (vrf_id_t vrf_id)
{
struct route_node *rn;
struct route_table *table;
struct rib *rib, *next;
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (table)
for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
@@ -3767,7 +3658,7 @@ rib_update_static (void)
break;
}
- table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
+ table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
if (table)
for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
@@ -3780,18 +3671,18 @@ rib_update_static (void)
/* RIB update function. */
void
-rib_update (void)
+rib_update (vrf_id_t vrf_id)
{
struct route_node *rn;
struct route_table *table;
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (table)
for (rn = route_top (table); rn; rn = route_next (rn))
if (rnode_to_ribs (rn))
rib_queue_add (&zebrad, rn);
- table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
+ table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
if (table)
for (rn = route_top (table); rn; rn = route_next (rn))
if (rnode_to_ribs (rn))
@@ -3824,8 +3715,15 @@ rib_weed_table (struct route_table *table)
void
rib_weed_tables (void)
{
- rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
- rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
+ vrf_iter_t iter;
+ struct zebra_vrf *zvrf;
+
+ for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+ if ((zvrf = vrf_iter2info (iter)) != NULL)
+ {
+ rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
+ rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
+ }
}
/* Delete self installed routes after zebra is relaunched. */
@@ -3858,8 +3756,15 @@ rib_sweep_table (struct route_table *table)
void
rib_sweep_route (void)
{
- rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
- rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
+ vrf_iter_t iter;
+ struct zebra_vrf *zvrf;
+
+ for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+ if ((zvrf = vrf_iter2info (iter)) != NULL)
+ {
+ rib_sweep_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
+ rib_sweep_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
+ }
}
/* Remove specific by protocol routes from 'table'. */
@@ -3891,12 +3796,20 @@ 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)
{
- return rib_score_proto_table (proto, instance, vrf_table (AFI_IP, SAFI_UNICAST, 0))
- +rib_score_proto_table (proto, instance, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
+ vrf_iter_t iter;
+ 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)
+ 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]);
+
+ return cnt;
}
/* Close RIB and clean up kernel routes. */
-static void
+void
rib_close_table (struct route_table *table)
{
struct route_node *rn;
@@ -3920,14 +3833,21 @@ rib_close_table (struct route_table *table)
void
rib_close (void)
{
- struct listnode *node, *nnode;
+ vrf_iter_t iter;
+ struct zebra_vrf *zvrf;
+ struct listnode *node;
struct interface *ifp;
- rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
- rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
-
- for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
- if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
+ 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);
+ }
}
/* Routing information base initialize. */
@@ -3935,8 +3855,6 @@ void
rib_init (void)
{
rib_queue_init (&zebrad);
- /* VRF initialization. */
- vrf_init ();
}
/*
@@ -3947,15 +3865,19 @@ rib_init (void)
* Returns TRUE if a vrf id was found, FALSE otherwise.
*/
static inline int
-vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
+vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
{
- while (++id < vector_active (vrf_vector))
+ 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));
+
+ if (zvrf)
{
- if (vrf_lookup (id))
- {
- *next_id_p = id;
- return 1;
- }
+ *next_id_p = zvrf->vrf_id;
+ return 1;
}
return 0;
@@ -4003,7 +3925,7 @@ rib_tables_iter_next (rib_tables_iter_t *iter)
while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
{
- table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
+ table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
afi_safis[iter->afi_safi_ix].safi,
iter->vrf_id);
if (table)
@@ -4041,3 +3963,130 @@ rib_tables_iter_next (rib_tables_iter_t *iter)
return table;
}
+
+/*
+ * Create a routing table for the specific AFI/SAFI in the given VRF.
+ */
+static void
+zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
+{
+ rib_table_info_t *info;
+ struct route_table *table;
+
+ assert (!zvrf->table[afi][safi]);
+
+ table = route_table_init ();
+ zvrf->table[afi][safi] = table;
+
+ info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
+ info->zvrf = zvrf;
+ info->afi = afi;
+ info->safi = safi;
+ table->info = info;
+}
+
+/* Allocate new zebra VRF. */
+struct zebra_vrf *
+zebra_vrf_alloc (vrf_id_t vrf_id)
+{
+ struct zebra_vrf *zvrf;
+#ifdef HAVE_NETLINK
+ char nl_name[64];
+#endif
+
+ 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;
+
+#ifdef HAVE_NETLINK
+ /* Initialize netlink sockets */
+ snprintf (nl_name, 64, "netlink-listen (vrf %u)", vrf_id);
+ zvrf->netlink.sock = -1;
+ zvrf->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
+
+ snprintf (nl_name, 64, "netlink-cmd (vrf %u)", vrf_id);
+ zvrf->netlink_cmd.sock = -1;
+ zvrf->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
+#endif
+
+ return zvrf;
+}
+
+/* Lookup VRF by identifier. */
+struct zebra_vrf *
+zebra_vrf_lookup (vrf_id_t vrf_id)
+{
+ return vrf_info_lookup (vrf_id);
+}
+
+/* Lookup the routing table in an enabled VRF. */
+struct route_table *
+zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
+{
+ struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
+
+ if (!zvrf)
+ return NULL;
+
+ if (afi >= AFI_MAX || safi >= SAFI_MAX)
+ return NULL;
+
+ return zvrf->table[afi][safi];
+}
+
+/* Lookup the static routing table in a VRF. */
+struct route_table *
+zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
+{
+ struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
+
+ if (!zvrf)
+ return NULL;
+
+ if (afi >= AFI_MAX || safi >= SAFI_MAX)
+ return NULL;
+
+ return zvrf->stable[afi][safi];
+}
+
+struct route_table *
+zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
+{
+ struct zebra_vrf *zvrf;
+
+ zvrf = vrf_info_lookup (vrf_id);
+ if (! zvrf)
+ return NULL;
+
+ if(afi >= AFI_MAX)
+ return NULL;
+
+ if (table_id >= ZEBRA_KERNEL_TABLE_MAX)
+ return NULL;
+
+ if (zvrf->other_table[afi][table_id] == NULL)
+ {
+ zvrf->other_table[afi][table_id] = route_table_init();
+ }
+
+ return (zvrf->other_table[afi][table_id]);
+}
+
+