Thanks for your commets. These are really helpful.
I update my patch for adapt to the latest quagga code.
This code add a new struct route_table_info between zebra_vrf and
route_table, which help us for select route_table by table id
lib/table.h | 1 +
zebra/main.c | 7 ++++--
zebra/rib.h | 49 ++++++++++++++++++++++++++++++-------
zebra/test_main.c | 5 ++--
zebra/zebra_rib.c | 167
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
zebra/zebra_vty.c | 232
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------
6 files changed, 359 insertions(+), 102 deletions(-)
diff --git a/lib/table.h b/lib/table.h
index 2ffd79b..9906729 100644
--- a/lib/table.h
+++ b/lib/table.h
@@ -54,6 +54,7 @@ struct route_table
{
struct route_node *top;
+ int table_id;
/*
* Delegate that performs certain functions for this table.
*/
diff --git a/zebra/main.c b/zebra/main.c
index f3c08f1..4d25475 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -249,8 +249,11 @@ zebra_vrf_disable (vrf_id_t vrf_id, void
**info)
assert (zvrf);
- rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
- rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
+ rib_close_table (rt_info->table[AFI_IP][SAFI_UNICAST]);
+ rib_close_table (rt_info->table[AFI_IP6][SAFI_UNICAST]);
+ }
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), list_node, ifp))
{
diff --git a/zebra/rib.h b/zebra/rib.h
index ffe7e2f..ccce064 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -27,6 +27,7 @@
#include "prefix.h"
#include "table.h"
#include "queue.h"
+#include "vector.h"
#define DISTANCE_INFINITY 255
@@ -330,14 +331,29 @@ struct nlsock
};
#endif
+struct route_table_info
+{
+ /* Routing table id */
+ int table_id;
+
+ /* Routing table name. */
+ char *name;
+
+ /* Routing table. */
+ struct route_table *table[AFI_MAX][SAFI_MAX];
+
+ /* Static route configuration. */
+ struct route_table *stable[AFI_MAX][SAFI_MAX];
+
+};
/* Routing table instance. */
struct zebra_vrf
{
/* Identifier. */
vrf_id_t vrf_id;
- /* Routing table name. */
- char *name;
+ /* Contain all the route tables */
+ vector route_tables_info;
/* Description. */
char *desc;
@@ -345,12 +361,6 @@ struct zebra_vrf
/* FIB identifier. */
u_char fib_id;
- /* Routing table. */
- struct route_table *table[AFI_MAX][SAFI_MAX];
-
- /* Static route configuration. */
- struct route_table *stable[AFI_MAX][SAFI_MAX];
-
#ifdef HAVE_NETLINK
struct nlsock netlink; /* kernel messages */
struct nlsock netlink_cmd; /* command channel */
@@ -520,6 +530,11 @@ static_delete_ipv6 (struct prefix *p, u_char
type, struct in6_addr *gate,
extern int rib_gc_dest (struct route_node *rn);
extern struct route_table *rib_tables_iter_next (rib_tables_iter_t
*iter);
+extern struct route_table_info *get_route_table_info(
+ struct zebra_vrf *zvrf, int table_id);
+
+extern struct route_table *zebra_vrf_table_id (
+ afi_t afi, safi_t safi, vrf_id_t vrf_id, int table_id);
/*
* Inline functions.
*/
@@ -630,4 +645,22 @@ rib_tables_iter_cleanup (rib_tables_iter_t
*iter)
iter->state = RIB_TABLES_ITER_S_DONE;
}
+#define VRF_FOREACH_TABLE(vrf_id, table, afi, safi)\
+ struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);\
+ (table) = ((struct
route_table_info*)vector_lookup((zvrf)->route_tables_info,
0))->table[afi][safi];\
+ for(int i = 0; i < vector_count((zvrf)->route_tables_info);\
+ (table) = ((struct
route_table_info*)vector_lookup((zvrf)->route_tables_info,
i))->table[afi][safi], \
+ i++)
+
+#define ZVRF_FOREACH_TABLE(zvrf, table, afi, safi)\
+ (table) = ((struct
route_table_info*)vector_lookup((zvrf)->route_tables_info,
0))->table[afi][safi];\
+ for(int i = 0; i < vector_count((zvrf)->route_tables_info);\
+ (table) = ((struct
route_table_info*)vector_lookup((zvrf)->route_tables_info,
i))->table[afi][safi], \
+ i++)
+
+#define ZVRF_FOREACH_RTINFO(zvrf)\
+ struct route_table_info *rt_info =
vector_lookup((zvrf)->route_tables_info, 0);\
+ for(int i = 0; i < vector_count((zvrf)->route_tables_info);\
+ (rt_info) = vector_lookup((zvrf)->route_tables_info, i), \
+ i++)
#endif /*_ZEBRA_RIB_H */
diff --git a/zebra/test_main.c b/zebra/test_main.c
index 448d1ef..a705a20 100644
--- a/zebra/test_main.c
+++ b/zebra/test_main.c
@@ -233,11 +233,12 @@ zebra_vrf_disable (vrf_id_t vrf_id, void
**info)
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
struct listnode *list_node;
struct interface *ifp;
+ struct route_table_info *rt_info = get_route_table_info(zvrf,
RT_TABLE_MAIN);
assert (zvrf);
- rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
- rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
+ rib_close_table (rt_info->table[AFI_IP][SAFI_UNICAST]);
+ rib_close_table (rt_info->table[AFI_IP6][SAFI_UNICAST]);
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), list_node, ifp))
{
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 38357ff..9bcb7ec 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1810,9 +1810,16 @@ rib_add_ipv4 (int type, int flags, struct
prefix_ipv4 *p,
struct nexthop *nexthop;
/* Lookup table. */
- table = zebra_vrf_table (AFI_IP, safi, vrf_id);
+ table = zebra_vrf_table_id(AFI_IP, safi, vrf_id, table_id);
if (! table)
- return 0;
+ {
+ struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
+ if (!zvrf)
+ return NULL;
+
+ zebra_route_tables_create(zvrf, table_id);
+ table = zebra_vrf_table_id(AFI_IP, safi, vrf_id, table_id);
+ }
/* Make it sure prefixlen is applied to the prefix. */
apply_mask_ipv4 (p);
@@ -2286,9 +2293,16 @@ static_install_route (afi_t afi, safi_t
safi, struct prefix *p, struct static_ro
struct route_table *table;
/* Lookup table. */
- table = zebra_vrf_table (afi, safi, si->vrf_id);
+ table = zebra_vrf_table_id(afi, safi, si->vrf_id,
zebrad.rtm_table_default);
if (! table)
- return;
+ {
+ struct zebra_vrf *zvrf = vrf_info_lookup (si->vrf_id);
+ if (!zvrf)
+ return NULL;
+
+ zebra_route_tables_create(zvrf, zebrad.rtm_table_default);
+ table = zebra_vrf_table_id(afi, safi, si->vrf_id,
zebrad.rtm_table_default);
+ }
/* Lookup existing route */
rn = route_node_get (table, p);
@@ -2474,7 +2488,15 @@ static_add_ipv4_safi (safi_t safi, struct
prefix *p, struct in_addr *gate,
struct static_route *cp;
struct static_route *update = NULL;
struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
- struct route_table *stable = zvrf->stable[AFI_IP][safi];
+ struct route_table_info *rt_info = get_route_table_info(
+ zvrf, zebrad.rtm_table_default);
+ if (! rt_info)
+ {
+ zebra_route_tables_create(zvrf, zebrad.rtm_table_default);
+ rt_info = get_route_table_info(
+ zvrf, zebrad.rtm_table_default);
+ }
+ struct route_table *stable = rt_info->stable[AFI_IP][safi];
if (! stable)
return -1;
@@ -2868,7 +2890,15 @@ static_add_ipv6 (struct prefix *p, u_char
type, struct in6_addr *gate,
struct static_route *cp;
struct static_route *update = NULL;
struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
- struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
+ struct route_table_info *rt_info = get_route_table_info(
+ zvrf, zebrad.rtm_table_default);
+ if (! rt_info)
+ {
+ zebra_route_tables_create(zvrf, zebrad.rtm_table_default);
+ rt_info = get_route_table_info(
+ zvrf, zebrad.rtm_table_default);
+ }
+ struct route_table *stable =
rt_info->stable[AFI_IP6][SAFI_UNICAST];
if (! stable)
return -1;
@@ -3028,7 +3058,7 @@ rib_update (vrf_id_t vrf_id)
/* Remove all routes which comes from non main table. */
static void
-rib_weed_table (struct route_table *table)
+rib_weed_table (struct route_table *table, int table_id)
{
struct route_node *rn;
struct rib *rib;
@@ -3042,7 +3072,8 @@ rib_weed_table (struct route_table *table)
continue;
if (rib->table != zebrad.rtm_table_default &&
- rib->table != RT_TABLE_MAIN)
+ rib->table != RT_TABLE_MAIN &&
+ rib->table != table_id)
rib_delnode (rn, rib);
}
}
@@ -3053,12 +3084,19 @@ rib_weed_tables (void)
{
vrf_iter_t iter;
struct zebra_vrf *zvrf;
+ struct route_table_info *rt_info;
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]);
+ for (int i=0; i < vector_count(zvrf->route_tables_info);
i++)
+ {
+ rt_info = vector_lookup(zvrf->route_tables_info, i);
+ rib_weed_table (rt_info->table[AFI_IP][SAFI_UNICAST],
+ rt_info->table_id);
+ rib_weed_table (rt_info->table[AFI_IP6][SAFI_UNICAST],
+ rt_info->table_id);
+ }
}
}
@@ -3100,8 +3138,11 @@ rib_sweep_route (void)
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]);
+ struct route_table_info *rt_info =
get_route_table_info(zvrf, RT_TABLE_MAIN);
+ rib_weed_table (rt_info->table[AFI_IP][SAFI_UNICAST],
+ rt_info->table_id);
+ rib_weed_table (rt_info->table[AFI_IP6][SAFI_UNICAST],
+ rt_info->table_id);
}
}
@@ -3140,8 +3181,11 @@ rib_score_proto (u_char proto)
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
if ((zvrf = vrf_iter2info (iter)) != NULL)
- cnt += rib_score_proto_table (proto,
zvrf->table[AFI_IP][SAFI_UNICAST])
- +rib_score_proto_table (proto,
zvrf->table[AFI_IP6][SAFI_UNICAST]);
+ {
+ struct route_table_info *rt_info =
get_route_table_info(zvrf, RT_TABLE_MAIN);
+ cnt += rib_score_proto_table (proto,
rt_info->table[AFI_IP][SAFI_UNICAST])
+ +rib_score_proto_table (proto,
rt_info->table[AFI_IP6][SAFI_UNICAST]);
+ }
return cnt;
}
@@ -3175,12 +3219,17 @@ rib_close (void)
{
vrf_iter_t iter;
struct zebra_vrf *zvrf;
+ struct route_table_info *rt_info;
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 (int i=0; i < vector_count(zvrf->route_tables_info);
i++)
+ {
+ rt_info = vector_lookup(zvrf->route_tables_info, i);
+ rib_close_table (rt_info->table[AFI_IP][SAFI_UNICAST]);
+ rib_close_table (rt_info->table[AFI_IP6][SAFI_UNICAST]);
+ }
}
}
@@ -3302,15 +3351,15 @@ rib_tables_iter_next (rib_tables_iter_t
*iter)
* 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)
+zebra_vrf_table_create (struct zebra_vrf *zvrf, struct
route_table_info *rt_info, afi_t afi, safi_t safi)
{
rib_table_info_t *info;
struct route_table *table;
- assert (!zvrf->table[afi][safi]);
+ assert (!rt_info->table[afi][safi]);
table = route_table_init ();
- zvrf->table[afi][safi] = table;
+ rt_info->table[afi][safi] = table;
info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
info->zvrf = zvrf;
@@ -3324,21 +3373,14 @@ struct zebra_vrf *
zebra_vrf_alloc (vrf_id_t vrf_id)
{
struct zebra_vrf *zvrf;
+ struct route_table_info *rt_info;
#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 ();
+ init_zebra_route_tables_info(zvrf);
/* Set VRF ID */
zvrf->vrf_id = vrf_id;
@@ -3369,9 +3411,40 @@ zebra_vrf_table (afi_t afi, safi_t safi,
vrf_id_t vrf_id)
if (afi >= AFI_MAX || safi >= SAFI_MAX)
return NULL;
- return zvrf->table[afi][safi];
+ struct route_table_info * rt_info = get_route_table_info(zvrf,
RT_TABLE_MAIN);
+
+ return rt_info->table[afi][safi];
}
+/* Lookup the routing table in an enabled VRF. */
+struct route_table *
+zebra_vrf_table_id (afi_t afi, safi_t safi, vrf_id_t vrf_id, int
table_id)
+{
+ struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
+
+ if (!zvrf)
+ return NULL;
+
+ if (afi >= AFI_MAX || safi >= SAFI_MAX)
+ return NULL;
+
+ struct route_table_info * rt_info = get_route_table_info(zvrf,
table_id);
+ if (rt_info)
+ return rt_info->table[afi][safi];
+}
+
+struct route_table_info *
+get_route_table_info(struct zebra_vrf *zvrf, int table_id)
+{
+ struct route_table_info* rt_info;
+ for (int i=0; i < vector_count(zvrf->route_tables_info); i++)
+ {
+ rt_info = vector_lookup(zvrf->route_tables_info, i);
+ if (rt_info->table_id == table_id)
+ return rt_info;
+ }
+ return NULL;
+}
/* 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)
@@ -3384,6 +3457,40 @@ zebra_vrf_static_table (afi_t afi, safi_t
safi, vrf_id_t vrf_id)
if (afi >= AFI_MAX || safi >= SAFI_MAX)
return NULL;
- return zvrf->stable[afi][safi];
+ struct route_table_info *rt_info = get_route_table_info(zvrf,
RT_TABLE_MAIN);
+ return rt_info->stable[afi][safi];
}
+void
+init_zebra_route_tables_info(struct zebra_vrf *zvrf)
+{
+ zvrf->route_tables_info = vector_init(1);
+ struct route_table_info *rt_info = malloc (sizeof(struct
route_table_info));
+ rt_info->table_id = RT_TABLE_MAIN;
+
+ init_zebra_route_table(zvrf, rt_info);
+ vector_set_index (zvrf->route_tables_info, 0, rt_info);
+}
+
+void
+zebra_route_tables_create(struct zebra_vrf *zvrf, int table_id)
+{
+ struct route_table_info *rt_info = malloc (sizeof(struct
route_table_info));
+ rt_info->table_id = table_id;
+ init_zebra_route_table(zvrf, rt_info);
+ vector_set_index (zvrf->route_tables_info,
vector_count(zvrf->route_tables_info), rt_info);
+}
+
+void
+init_zebra_route_table(struct zebra_vrf *zvrf, struct
route_table_info *rt_info)
+{
+ /* Allocate routing table and static table. */
+ zebra_vrf_table_create (zvrf, rt_info, AFI_IP, SAFI_UNICAST);
+ zebra_vrf_table_create (zvrf, rt_info, AFI_IP6, SAFI_UNICAST);
+ rt_info->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
+ rt_info->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
+ zebra_vrf_table_create (zvrf, rt_info, AFI_IP, SAFI_MULTICAST);
+ zebra_vrf_table_create (zvrf, rt_info, AFI_IP6, SAFI_MULTICAST);
+ rt_info->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
+ rt_info->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
+}
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 656f55d..5369212 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -404,8 +404,11 @@ DEFUN (show_ip_rpf_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP][SAFI_MULTICAST]) == NULL)
+ (table = rt_info->table[AFI_IP][SAFI_MULTICAST]) == NULL)
continue;
/* Show all IPv4 routes. */
@@ -419,6 +422,7 @@ DEFUN (show_ip_rpf_vrf_all,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
}
return CMD_SUCCESS;
@@ -1579,21 +1583,24 @@ static int do_show_ip_route(struct vty
*vty, safi_t safi, vrf_id_t vrf_id)
struct rib *rib;
int first = 1;
- table = zebra_vrf_table (AFI_IP, safi, vrf_id);
+
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP, safi)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show all IPv4 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, rib)
{
- if (first)
- {
- vty_out (vty, SHOW_ROUTE_V4_HEADER);
- first = 0;
- }
- vty_show_ip_route (vty, rn, rib);
+ if (first)
+ {
+ vty_out (vty, SHOW_ROUTE_V4_HEADER);
+ first = 0;
}
+ vty_show_ip_route (vty, rn, rib);
+ }
+ }
return CMD_SUCCESS;
}
@@ -1632,9 +1639,10 @@ DEFUN (show_ip_route_prefix_longer,
if (argc > 1)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show matched type IPv4 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -1648,6 +1656,7 @@ DEFUN (show_ip_route_prefix_longer,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -1679,9 +1688,10 @@ DEFUN (show_ip_route_supernets,
if (argc > 0)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show matched type IPv4 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -1701,6 +1711,7 @@ DEFUN (show_ip_route_supernets,
vty_show_ip_route (vty, rn, rib);
}
}
+ }
return CMD_SUCCESS;
}
@@ -1738,9 +1749,10 @@ DEFUN (show_ip_route_protocol,
if (argc > 1)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show matched type IPv4 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -1754,6 +1766,7 @@ DEFUN (show_ip_route_protocol,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -1790,9 +1803,10 @@ DEFUN (show_ip_route_addr,
if (argc > 1)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
rn = route_node_match (table, (struct prefix *) &p);
if (! rn)
@@ -1804,6 +1818,7 @@ DEFUN (show_ip_route_addr,
vty_show_ip_route_detail (vty, rn, 0);
route_unlock_node (rn);
+ }
return CMD_SUCCESS;
}
@@ -1841,9 +1856,10 @@ DEFUN (show_ip_route_prefix,
if (argc > 1)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
rn = route_node_match (table, (struct prefix *) &p);
if (! rn || rn->p.prefixlen != p.prefixlen)
@@ -1857,6 +1873,7 @@ DEFUN (show_ip_route_prefix,
vty_show_ip_route_detail (vty, rn, 0);
route_unlock_node (rn);
+ }
return CMD_SUCCESS;
}
@@ -2033,12 +2050,14 @@ DEFUN (show_ip_route_summary,
if (argc > 0)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
vty_show_ip_route_summary (vty, table);
+ }
return CMD_SUCCESS;
}
@@ -2067,11 +2086,13 @@ DEFUN (show_ip_route_summary_prefix,
if (argc > 0)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
vty_show_ip_route_summary_prefix (vty, table);
+ }
return CMD_SUCCESS;
}
@@ -2103,8 +2124,11 @@ DEFUN (show_ip_route_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
/* Show all IPv4 routes. */
@@ -2118,6 +2142,7 @@ DEFUN (show_ip_route_vrf_all,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
}
return CMD_SUCCESS;
@@ -2151,8 +2176,11 @@ DEFUN (show_ip_route_prefix_longer_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
/* Show matched type IPv4 routes. */
@@ -2167,6 +2195,7 @@ DEFUN (show_ip_route_prefix_longer_vrf_all,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
}
return CMD_SUCCESS;
@@ -2191,8 +2220,11 @@ DEFUN (show_ip_route_supernets_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
/* Show matched type IPv4 routes. */
@@ -2213,6 +2245,7 @@ DEFUN (show_ip_route_supernets_vrf_all,
vty_show_ip_route (vty, rn, rib);
}
}
+ }
}
return CMD_SUCCESS;
@@ -2244,8 +2277,11 @@ DEFUN (show_ip_route_protocol_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
/* Show matched type IPv4 routes. */
@@ -2260,6 +2296,7 @@ DEFUN (show_ip_route_protocol_vrf_all,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
}
return CMD_SUCCESS;
@@ -2290,8 +2327,11 @@ DEFUN (show_ip_route_addr_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
rn = route_node_match (table, (struct prefix *) &p);
@@ -2302,6 +2342,7 @@ DEFUN (show_ip_route_addr_vrf_all,
route_unlock_node (rn);
}
+ }
return CMD_SUCCESS;
}
@@ -2331,8 +2372,11 @@ DEFUN (show_ip_route_prefix_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP][SAFI_UNICAST]) == NULL)
continue;
rn = route_node_match (table, (struct prefix *) &p);
@@ -2348,6 +2392,7 @@ DEFUN (show_ip_route_prefix_vrf_all,
route_unlock_node (rn);
}
+ }
return CMD_SUCCESS;
}
@@ -2366,7 +2411,12 @@ DEFUN (show_ip_route_summary_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
if ((zvrf = vrf_iter2info (iter)) != NULL)
- vty_show_ip_route_summary (vty,
zvrf->table[AFI_IP][SAFI_UNICAST]);
+ {
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
+ vty_show_ip_route_summary (vty,
rt_info->table[AFI_IP][SAFI_UNICAST]);
+ }
+ }
return CMD_SUCCESS;
}
@@ -2386,7 +2436,12 @@ DEFUN (show_ip_route_summary_prefix_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
if ((zvrf = vrf_iter2info (iter)) != NULL)
- vty_show_ip_route_summary_prefix (vty,
zvrf->table[AFI_IP][SAFI_UNICAST]);
+ {
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
+ vty_show_ip_route_summary_prefix (vty,
rt_info->table[AFI_IP][SAFI_UNICAST]);
+ }
+ }
return CMD_SUCCESS;
}
@@ -2406,8 +2461,11 @@ static_config_ipv4 (struct vty *vty, safi_t
safi, const char *cmd)
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (stable = zvrf->stable[AFI_IP][safi]) == NULL)
+ (stable = rt_info->stable[AFI_IP][safi]) == NULL)
continue;
for (rn = route_top (stable); rn; rn = route_next (rn))
@@ -2449,6 +2507,7 @@ static_config_ipv4 (struct vty *vty, safi_t
safi, const char *cmd)
write = 1;
}
+ }
}
return write;
}
@@ -3072,9 +3131,10 @@ DEFUN (show_ipv6_route,
if (argc > 0)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP6, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show all IPv6 route. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -3087,6 +3147,7 @@ DEFUN (show_ipv6_route,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -3125,9 +3186,10 @@ DEFUN (show_ipv6_route_prefix_longer,
if (argc > 1)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP6, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show matched type IPv6 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -3141,6 +3203,7 @@ DEFUN (show_ipv6_route_prefix_longer,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -3179,9 +3242,10 @@ DEFUN (show_ipv6_route_protocol,
if (argc > 1)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP6, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show matched type IPv6 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -3195,6 +3259,7 @@ DEFUN (show_ipv6_route_protocol,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -3231,9 +3296,10 @@ DEFUN (show_ipv6_route_addr,
if (argc > 1)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP6, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
rn = route_node_match (table, (struct prefix *) &p);
if (! rn)
@@ -3246,6 +3312,7 @@ DEFUN (show_ipv6_route_addr,
route_unlock_node (rn);
+ }
return CMD_SUCCESS;
}
@@ -3282,9 +3349,10 @@ DEFUN (show_ipv6_route_prefix,
if (argc > 1)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP6, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
rn = route_node_match (table, (struct prefix *) &p);
if (! rn || rn->p.prefixlen != p.prefixlen)
@@ -3298,6 +3366,7 @@ DEFUN (show_ipv6_route_prefix,
vty_show_ip_route_detail (vty, rn, 0);
route_unlock_node (rn);
+ }
return CMD_SUCCESS;
}
@@ -3326,12 +3395,13 @@ DEFUN (show_ipv6_route_summary,
if (argc > 0)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP6, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
vty_show_ip_route_summary (vty, table);
-
+ }
return CMD_SUCCESS;
}
@@ -3360,11 +3430,13 @@ DEFUN (show_ipv6_route_summary_prefix,
if (argc > 0)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP6, SAFI_UNICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
vty_show_ip_route_summary_prefix (vty, table);
+ }
return CMD_SUCCESS;
}
@@ -3400,14 +3472,14 @@ DEFUN (show_ipv6_mroute,
if (argc > 0)
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
- table = zebra_vrf_table (AFI_IP6, SAFI_MULTICAST, vrf_id);
+ VRF_FOREACH_TABLE(vrf_id, table, AFI_IP6, SAFI_MULTICAST)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show all IPv6 route. */
for (rn = route_top (table); rn; rn = route_next (rn))
- RNODE_FOREACH_RIB (rn, rib)
- {
+ RNODE_FOREACH_RIB (rn, rib) {
if (first)
{
vty_out (vty, SHOW_ROUTE_V6_HEADER);
@@ -3415,6 +3487,7 @@ DEFUN (show_ipv6_mroute,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -3443,8 +3516,11 @@ DEFUN (show_ipv6_route_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
/* Show all IPv6 route. */
@@ -3458,6 +3534,7 @@ DEFUN (show_ipv6_route_vrf_all,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
}
return CMD_SUCCESS;
@@ -3491,8 +3568,11 @@ DEFUN (show_ipv6_route_prefix_longer_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
/* Show matched type IPv6 routes. */
@@ -3507,6 +3587,7 @@ DEFUN (show_ipv6_route_prefix_longer_vrf_all,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
}
return CMD_SUCCESS;
@@ -3538,8 +3619,11 @@ DEFUN (show_ipv6_route_protocol_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
/* Show matched type IPv6 routes. */
@@ -3554,6 +3638,7 @@ DEFUN (show_ipv6_route_protocol_vrf_all,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
}
return CMD_SUCCESS;
@@ -3584,8 +3669,11 @@ DEFUN (show_ipv6_route_addr_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
rn = route_node_match (table, (struct prefix *) &p);
@@ -3596,6 +3684,7 @@ DEFUN (show_ipv6_route_addr_vrf_all,
route_unlock_node (rn);
}
+ }
return CMD_SUCCESS;
}
@@ -3625,8 +3714,11 @@ DEFUN (show_ipv6_route_prefix_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
rn = route_node_match (table, (struct prefix *) &p);
@@ -3642,6 +3734,7 @@ DEFUN (show_ipv6_route_prefix_vrf_all,
route_unlock_node (rn);
}
+ }
return CMD_SUCCESS;
}
@@ -3660,8 +3753,14 @@ DEFUN (show_ipv6_route_summary_vrf_all,
vrf_iter_t iter;
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
+ {
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) != NULL)
- vty_show_ip_route_summary (vty,
zvrf->table[AFI_IP6][SAFI_UNICAST]);
+ vty_show_ip_route_summary (vty,
rt_info->table[AFI_IP6][SAFI_UNICAST]);
+ }
+ }
return CMD_SUCCESS;
}
@@ -3683,8 +3782,11 @@ DEFUN (show_ipv6_mroute_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
+ (table = rt_info->table[AFI_IP6][SAFI_UNICAST]) == NULL)
continue;
/* Show all IPv6 route. */
@@ -3698,6 +3800,7 @@ DEFUN (show_ipv6_mroute_vrf_all,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
}
return CMD_SUCCESS;
}
@@ -3717,7 +3820,12 @@ DEFUN
(show_ipv6_route_summary_prefix_vrf_all,
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
if ((zvrf = vrf_iter2info (iter)) != NULL)
- vty_show_ip_route_summary_prefix (vty,
zvrf->table[AFI_IP6][SAFI_UNICAST]);
+ {
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
+ vty_show_ip_route_summary_prefix (vty,
rt_info->table[AFI_IP6][SAFI_UNICAST]);
+ }
+ }
return CMD_SUCCESS;
}
@@ -3738,8 +3846,11 @@ static_config_ipv6 (struct vty *vty)
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter =
vrf_next (iter))
{
+ zvrf = vrf_iter2info (iter);
+ ZVRF_FOREACH_RTINFO(zvrf)
+ {
if ((zvrf = vrf_iter2info (iter)) == NULL ||
- (stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL)
+ (stable = rt_info->stable[AFI_IP6][SAFI_UNICAST]) ==
NULL)
continue;
for (rn = route_top (stable); rn; rn = route_next (rn))
@@ -3779,6 +3890,7 @@ static_config_ipv6 (struct vty *vty)
write = 1;
}
+ }
}
return write;
}
2016-01-07 21:56 GMT+08:00 Donald Sharp <sha...@cumulusnetworks.com
:
Comments inline...
On Thu, Jan 7, 2016 at 8:09 AM, 林守磊 <linxiu...@gmail.com> wrote:
diff --git a/lib/table.h b/lib/table.h
index ab357a0..946fcb2 100644
--- a/lib/table.h
+++ b/lib/table.h
@@ -53,6 +53,7 @@ struct route_table_delegate_t_
struct route_table
{
struct route_node *top;
+ int tableno;
/*
* Delegate that performs certain functions for this table.
diff --git a/zebra/rib.h b/zebra/rib.h
index d3a83c6..78df691 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -577,4 +577,24 @@ rib_tables_iter_cleanup (rib_tables_iter_t
*iter)
iter->state = RIB_TABLES_ITER_S_DONE;
}
+typedef enum { false, true } bool;
irrespective of whether or not we want to introduce true/false to
the code it does not belong in zebra/rib.h.
I would prefer just returning 0/1 and using that instead of
true/false enum's. Unless someone would be willing to retrofit the
entirety of the code base.
+struct route_table_iter;
+
+struct route_table_iter
+{
+ struct route_table_iter *pre;
+ struct route_table_iter *next;
+ struct route_table *route_table;
+};
+
+int vrf_create(int tableno);
+bool vrf_tableno_exists(int tableno);
+int get_table_count();
+
vrf_create is a poorly named function imo, it should fit in with
the current code in quagga.. There is already a zebra_vrf_alloc() and
zebra_vrf_table_create(). The code you are working on needs to work in the
confines of those functions. Possibly you are working on an old code base?
+#define VRF_FOREACH_TABLE(afi, safi, table) \
+ (table) = vrf_table((afi), (safi), 0);\
+ for (int i = 0, j = get_table_count();\
+ i < j;\
+ i++, (table) = vrf_table((afi), (safi), i))
+
#endif /*_ZEBRA_RIB_H */
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 95a82fd..e94c47e 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -685,6 +685,7 @@ netlink_routing_table (struct sockaddr_nl
*snl, struct nlmsghdr *h)
return 0;
table = rtm->rtm_table;
+ vrf_create(table);
I don't think that this is the concern of netlink_routing_table.
It should be passing the route to zebra_rib.c and zebra_rib.c should do the
right thing with it.
#if 0 /* we weed them out later in
rib_weed_tables () */
if (table != RT_TABLE_MAIN && table !=
zebrad.rtm_table_default)
return 0;
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index dc7e1ca..e00cf83 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -122,6 +122,39 @@ vrf_alloc (const char *name)
return vrf;
}
+static struct vrf*
+vrf_alloc_tableno(const char *name, int tableno)
+{
+ struct vrf *vrf;
+ vrf = vrf_alloc(name);
+
+ vrf->stable[AFI_IP][SAFI_UNICAST]->tableno = tableno;
+ vrf->stable[AFI_IP6][SAFI_UNICAST]->tableno = tableno;
+ vrf->stable[AFI_IP][SAFI_MULTICAST]->tableno = tableno;
+ vrf->stable[AFI_IP6][SAFI_MULTICAST]->tableno = tableno;
+
+ vrf->table[AFI_IP][SAFI_UNICAST]->tableno = tableno;
+ vrf->table[AFI_IP6][SAFI_UNICAST]->tableno = tableno;
+ vrf->table[AFI_IP][SAFI_MULTICAST]->tableno = tableno;
+ vrf->table[AFI_IP6][SAFI_MULTICAST]->tableno = tableno;
+ return vrf;
+}
Again this sure looks like code that is already in the latest
master. Are you working off of it?
+
+int
+get_vrfid_by_tableno(afi_t afi, safi_t safi, int tableno)
+{
+ if (tableno == 0 || tableno == RT_TABLE_MAIN)
+ return 0;
+
+ struct route_table *table;
+ for (int i = 0; i < vector_count(vrf_vector); i++)
+ {
+ table = vrf_table(afi, safi, i);
+ if (table->tableno == tableno)
+ return i;
+ }
+ return -1;
+}
/* Lookup VRF by identifier. */
struct vrf *
vrf_lookup (u_int32_t id)
@@ -136,7 +169,7 @@ vrf_init (void)
struct vrf *default_table;
/* Allocate VRF vector. */
- vrf_vector = vector_init (1);
+ vrf_vector = vector_init (2);
/* Allocate default main table. */
default_table = vrf_alloc ("Default-IP-Routing-Table");
@@ -145,6 +178,43 @@ vrf_init (void)
vector_set_index (vrf_vector, 0, default_table);
}
+int
+get_table_count()
+{
+ return vector_count(vrf_vector);
+}
+
+int
+vrf_create(int tableno)
+{
+ if (vrf_tableno_exists(tableno))
+ {
+ return -1;
+ }
+
+ unsigned int table_nums = vector_count(vrf_vector);
+ struct vrf *table;
+ char tablename[40];
+ sprintf(tablename, "%d-IP-Routing-Table", tableno);
+ table = vrf_alloc_tableno (tablename, tableno);
+ vector_set_index (vrf_vector, table_nums, table);
+}
+
+bool
+vrf_tableno_exists(int tableno)
+{
+ if (tableno == 0 || tableno == RT_TABLE_MAIN)
+ return true;
+
+ struct route_table *table;
+ VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table)
+ {
+ if (table->tableno == tableno)
+ return true;
+ }
+ return false;
+}
+
/* Lookup route table. */
struct route_table *
vrf_table (afi_t afi, safi_t safi, u_int32_t id)
@@ -484,7 +554,6 @@ nexthop_active_ipv4 (struct rib *rib, struct
nexthop *nexthop, int set,
newhop = match->nexthop;
if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
nexthop->ifindex = newhop->ifindex;
-
Whitespace change?
return 1;
}
else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
@@ -1033,7 +1102,7 @@ nexthop_active_check (struct route_node
*rn, struct rib *rib,
if (RIB_SYSTEM_ROUTE(rib) ||
(family == AFI_IP && rn->p.family != AF_INET) ||
(family == AFI_IP6 && rn->p.family != AF_INET6))
- return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
Whitespace change?
/* The original code didn't determine the family correctly
* e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi
@@ -1059,6 +1128,12 @@ nexthop_active_check (struct route_node
*rn, struct rib *rib,
return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
}
+void
+print_rib(struct route_node *rn)
+{
+ char buf[INET6_ADDRSTRLEN];
+ inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
+}
This function doesn't do anything with the output of inet_ntop,
just remove?
/* Iterate over all nexthops of the given RIB entry and refresh
their
* ACTIVE flag. rib->nexthop_active_num is updated accordingly.
If any
* nexthop is found to toggle the ACTIVE flag, the whole rib
structure
@@ -1082,7 +1157,7 @@ nexthop_active_update (struct route_node
*rn, struct rib *rib, int set)
prev_active = CHECK_FLAG (nexthop->flags,
NEXTHOP_FLAG_ACTIVE);
prev_index = nexthop->ifindex;
if ((new_active = nexthop_active_check (rn, rib, nexthop,
set)))
- rib->nexthop_active_num++;
+ rib->nexthop_active_num++;
whitespace change?
if (prev_active != new_active ||
prev_index != nexthop->ifindex)
SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
@@ -1255,6 +1330,7 @@ rib_process (struct route_node *rn)
if (IS_ZEBRA_DEBUG_RIB || IS_ZEBRA_DEBUG_RIB_Q)
inet_ntop (rn->p.family, &rn->p.u.prefix, buf,
INET6_ADDRSTRLEN);
+ inet_ntop (rn->p.family, &rn->p.u.prefix, buf,
INET6_ADDRSTRLEN);
Why the addition of this line? The exact same thing is done above
but protected by the DEBUG guards.
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
{
/* Currently installed rib. */
@@ -1815,8 +1891,15 @@ rib_add_ipv4 (int type, int flags, struct
prefix_ipv4 *p,
struct route_node *rn;
struct nexthop *nexthop;
+ int id;
+ // in this case vrf_id is the real tableno
+ // and id is the vector index
+ id = get_vrfid_by_tableno(AFI_IP, safi, vrf_id);
+ assert(id >= 0);
+
Let's name our variables appropriately here and consistent with
the rest of the code base.
+
/* Lookup table. */
- table = vrf_table (AFI_IP, safi, 0);
+ table = vrf_table (AFI_IP, safi, id);
if (! table)
return 0;
@@ -2154,8 +2237,10 @@ rib_delete_ipv4 (int type, int flags,
struct prefix_ipv4 *p,
char buf1[INET_ADDRSTRLEN];
char buf2[INET_ADDRSTRLEN];
+ int id;
+ id = get_vrfid_by_tableno(AFI_IP, safi, vrf_id);
/* Lookup table. */
- table = vrf_table (AFI_IP, safi, 0);
+ table = vrf_table (AFI_IP, safi, id);
if (! table)
return 0;
@@ -2292,10 +2377,25 @@ static_install_ipv4 (struct prefix *p,
struct static_ipv4 *si)
struct route_node *rn;
struct route_table *table;
- /* Lookup table. */
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table)
+ {
if (! table)
- return;
+ {
+ continue;
+ }
+
+ if ((zebrad.rtm_table_default == 0 || zebrad.rtm_table_default
== RT_TABLE_MAIN) && \
+ (table->tableno == 0 || table->tableno ==
RT_TABLE_MAIN) ) {
+ ;
+ }
+ else if (table->tableno == zebrad.rtm_table_default)
+ {
+ ;
+ }
+ else
+ {
+ continue;
+ }
/* Lookup existing route */
rn = route_node_get (table, p);
@@ -2357,6 +2457,7 @@ static_install_ipv4 (struct prefix *p,
struct static_ipv4 *si)
/* Link this rib to the tree. */
rib_addnode (rn, rib);
}
+ }
}
static int
@@ -2450,11 +2551,14 @@ static_add_ipv4 (struct prefix *p, struct
in_addr *gate, const char *ifname,
struct static_ipv4 *update = NULL;
struct route_table *stable;
+ // ignore vrf_id, because it is always zero. And it sucks
+ vrf_id = get_vrfid_by_tableno(AFI_IP, SAFI_UNICAST,
zebrad.rtm_table_default);
+ assert(vrf_id >= 0);
+
/* Lookup table. */
stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (! stable)
return -1;
-
/* Lookup static route prefix. */
rn = route_node_get (stable, p);
@@ -2630,8 +2734,10 @@ rib_add_ipv6 (int type, int flags, struct
prefix_ipv6 *p,
struct route_node *rn;
struct nexthop *nexthop;
+ int id;
+ id = get_vrfid_by_tableno(AFI_IP6, safi, vrf_id);
again, can we name the variables a bit better?
In any event, I would highly suggest respinning your code with the
latest Quagga, this version is old and won't work properly with the current
code base.
donald
/* Lookup table. */
- table = vrf_table (AFI_IP6, safi, 0);
+ table = vrf_table (AFI_IP6, safi, id);
if (! table)
return 0;
@@ -2745,8 +2851,10 @@ rib_delete_ipv6 (int type, int flags,
struct prefix_ipv6 *p,
/* Apply mask. */
apply_mask_ipv6 (p);
+ int id;
+ id = get_vrfid_by_tableno(AFI_IP6, safi, vrf_id);
/* Lookup table. */
- table = vrf_table (AFI_IP6, safi, 0);
+ table = vrf_table (AFI_IP6, safi, id);
if (! table)
return 0;
@@ -3163,17 +3271,21 @@ rib_update (void)
struct route_node *rn;
struct route_table *table;
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table)
+ {
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);
+ VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table)
+ {
if (table)
for (rn = route_top (table); rn; rn = route_next (rn))
if (rnode_to_ribs (rn))
rib_queue_add (&zebrad, rn);
+ }
}
@@ -3193,8 +3305,9 @@ rib_weed_table (struct route_table *table)
continue;
if (rib->table != zebrad.rtm_table_default &&
- rib->table != RT_TABLE_MAIN)
- rib_delnode (rn, rib);
+ rib->table != RT_TABLE_MAIN &&
+ rib->table != 0)
+ rib_delnode (rn, rib);
}
}
@@ -3298,8 +3411,11 @@ rib_close_table (struct route_table *table)
void
rib_close (void)
{
- rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
- rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
+ for (int i = 0; i < vector_count(vrf_vector); i++)
+ {
+ rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, i));
+ rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, i));
+ }
}
/* Routing information base initialize. */
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index baa60db..df3b353 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -777,6 +777,7 @@ vty_show_ip_route (struct vty *vty, struct
route_node *rn, struct rib *rib)
tm->tm_yday/7,
tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
}
+ //vty_out (vty, ", tableno %d", rib->table);
Dead code, please remove..
vty_out (vty, "%s", VTY_NEWLINE);
}
}
@@ -793,9 +794,10 @@ DEFUN (show_ip_route,
struct rib *rib;
int first = 1;
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show all IPv4 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -808,6 +810,7 @@ DEFUN (show_ip_route,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -834,9 +837,10 @@ DEFUN (show_ip_route_prefix_longer,
return CMD_WARNING;
}
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show matched type IPv4 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -850,6 +854,7 @@ DEFUN (show_ip_route_prefix_longer,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -867,9 +872,10 @@ DEFUN (show_ip_route_supernets,
u_int32_t addr;
int first = 1;
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show matched type IPv4 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -889,6 +895,7 @@ DEFUN (show_ip_route_supernets,
vty_show_ip_route (vty, rn, rib);
}
}
+ }
return CMD_SUCCESS;
}
@@ -913,9 +920,10 @@ DEFUN (show_ip_route_protocol,
return CMD_WARNING;
}
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show matched type IPv4 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -929,6 +937,7 @@ DEFUN (show_ip_route_protocol,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -952,9 +961,10 @@ DEFUN (show_ip_route_addr,
return CMD_WARNING;
}
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
rn = route_node_match (table, (struct prefix *) &p);
if (! rn)
@@ -967,6 +977,7 @@ DEFUN (show_ip_route_addr,
route_unlock_node (rn);
+ }
return CMD_SUCCESS;
}
@@ -990,9 +1001,10 @@ DEFUN (show_ip_route_prefix,
return CMD_WARNING;
}
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
rn = route_node_match (table, (struct prefix *) &p);
if (! rn || rn->p.prefixlen != p.prefixlen)
@@ -1005,6 +1017,7 @@ DEFUN (show_ip_route_prefix,
route_unlock_node (rn);
+ }
return CMD_SUCCESS;
}
@@ -1083,12 +1096,14 @@ DEFUN (show_ip_route_summary,
{
struct route_table *table;
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
vty_show_ip_route_summary (vty, table);
+ }
return CMD_SUCCESS;
}
@@ -1192,9 +1207,10 @@ DEFUN (show_ip_mroute,
struct rib *rib;
int first = 1;
- table = vrf_table (AFI_IP, SAFI_MULTICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP, SAFI_MULTICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show all IPv4 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -1207,6 +1223,7 @@ DEFUN (show_ip_mroute,
}
vty_show_ip_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -1731,9 +1748,10 @@ DEFUN (show_ipv6_route,
struct rib *rib;
int first = 1;
- table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show all IPv6 route. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -1746,6 +1764,7 @@ DEFUN (show_ipv6_route,
}
vty_show_ipv6_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -1765,9 +1784,10 @@ DEFUN (show_ipv6_route_prefix_longer,
int ret;
int first = 1;
- table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
ret = str2prefix (argv[0], &p);
if (! ret)
@@ -1788,6 +1808,7 @@ DEFUN (show_ipv6_route_prefix_longer,
}
vty_show_ipv6_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -1812,9 +1833,10 @@ DEFUN (show_ipv6_route_protocol,
return CMD_WARNING;
}
- table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show matched type IPv6 routes. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -1828,6 +1850,7 @@ DEFUN (show_ipv6_route_protocol,
}
vty_show_ipv6_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
@@ -1851,20 +1874,22 @@ DEFUN (show_ipv6_route_addr,
return CMD_WARNING;
}
- table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
rn = route_node_match (table, (struct prefix *) &p);
if (! rn)
{
vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
- return CMD_WARNING;
+ continue;
}
vty_show_ipv6_route_detail (vty, rn);
route_unlock_node (rn);
+ }
return CMD_SUCCESS;
}
@@ -1889,21 +1914,22 @@ DEFUN (show_ipv6_route_prefix,
return CMD_WARNING;
}
- table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
rn = route_node_match (table, (struct prefix *) &p);
if (! rn || rn->p.prefixlen != p.prefixlen)
{
vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
- return CMD_WARNING;
+ continue;
}
vty_show_ipv6_route_detail (vty, rn);
route_unlock_node (rn);
-
+ }
return CMD_SUCCESS;
}
@@ -1918,12 +1944,14 @@ DEFUN (show_ipv6_route_summary,
{
struct route_table *table;
- table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP6, SAFI_UNICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
vty_show_ip_route_summary (vty, table);
+ }
return CMD_SUCCESS;
}
@@ -1944,9 +1972,10 @@ DEFUN (show_ipv6_mroute,
struct rib *rib;
int first = 1;
- table = vrf_table (AFI_IP6, SAFI_MULTICAST, 0);
+ VRF_FOREACH_TABLE(AFI_IP6, SAFI_MULTICAST, table)
+ {
if (! table)
- return CMD_SUCCESS;
+ continue;
/* Show all IPv6 route. */
for (rn = route_top (table); rn; rn = route_next (rn))
@@ -1959,6 +1988,7 @@ DEFUN (show_ipv6_mroute,
}
vty_show_ipv6_route (vty, rn, rib);
}
+ }
return CMD_SUCCESS;
}
diff --git a/zebra/zserv.c b/zebra/zserv.c
index ca17c2c..97048b1 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -1577,7 +1577,12 @@ DEFUN (config_table,
"Configure target kernel routing table\n"
"TABLE integer\n")
{
- zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
+ int tableno;
+ tableno = strtol (argv[0], (char**)0, 10);
+ zebrad.rtm_table_default = tableno;
+ if (!vrf_tableno_exists(tableno)){
+ vrf_create(tableno);
+ }
return CMD_SUCCESS;
}
2015-12-31 17:56 GMT+08:00 林守磊 <linxiu...@gmail.com>:
Hi All
I use zebra in my production environment, but found that
command table was not good as I thounght..And I found someone got the same
problem just like me.
http://www.gossamer-threads.com/lists/quagga/users/23301
At last, I had to fix problems in below by myself
1. At first, it can not inject a route to non-default route
table which is already in default route
2. It can not define multiple route tables
The patch(perfect_cmd_table.patch) is tested.
Example zebra.conf like
table 100
ip route 11.0.0.0/8 10.97.215.247
ip route 172.16.0.0/12 10.97.215.247
!
table 101
ip route 11.0.0.0/8 10.97.215.247
ip route 172.16.0.0/12 10.97.215.247
ip route 10.0.0.0/8 10.97.215.247
ip route 100.64.0.0/10 10.97.215.247
!
Forwarding Your Reply.
Regards
_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev