From be2a7ed6af56af46da7593ef65f431be070c5759 Mon Sep 17 00:00:00 2001 From: Nathan Bahr Date: Mon, 28 Oct 2024 18:55:49 +0000 Subject: [PATCH 1/3] zebra: Add ability to import alternate tables into the MRIB Expanded the cli command to include an mrib flag for importing to the main table MRIB instead of the main table URIB. Piped through specifying the safi through the import table functions rather than hardcoding to SAFI_UNICAST. Import still only import routes from the URIB subtable, only added the ability to import into the main table MRIB. Signed-off-by: Nathan Bahr --- zebra/redistribute.c | 114 ++++++++++++++++++++--------------------- zebra/redistribute.h | 17 +++--- zebra/zebra_rib.c | 30 ++++++----- zebra/zebra_routemap.c | 16 +++--- zebra/zebra_routemap.h | 6 +-- zebra/zebra_vty.c | 54 ++++++------------- 6 files changed, 107 insertions(+), 130 deletions(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 2de0917a7e..66dc5b4b5f 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -35,10 +35,10 @@ /* array holding redistribute info about table redistribution */ /* bit AFI is set if that AFI is redistributing routes from this table */ -static int zebra_import_table_used[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; -static uint32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; +static int zebra_import_table_used[AFI_MAX][SAFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; +static uint32_t zebra_import_table_distance[AFI_MAX][SAFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; -int is_zebra_import_table_enabled(afi_t afi, vrf_id_t vrf_id, uint32_t table_id) +int is_zebra_import_table_enabled(afi_t afi, safi_t safi, vrf_id_t vrf_id, uint32_t table_id) { /* * Make sure that what we are called with actualy makes sense @@ -46,9 +46,12 @@ int is_zebra_import_table_enabled(afi_t afi, vrf_id_t vrf_id, uint32_t table_id) if (afi == AFI_MAX) return 0; + if (safi == SAFI_MAX) + return 0; + if (is_zebra_valid_kernel_table(table_id) && table_id < ZEBRA_KERNEL_TABLE_MAX) - return zebra_import_table_used[afi][table_id]; + return zebra_import_table_used[afi][safi][table_id]; return 0; } @@ -687,7 +690,7 @@ void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id) } } -int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, +int zebra_add_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, struct route_entry *re, const char *rmap_name) { struct route_entry *newre; @@ -705,7 +708,7 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, if (ret != RMAP_PERMITMATCH) { UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED); - zebra_del_import_table_entry(zvrf, rn, re); + zebra_del_import_table_entry(zvrf, safi, rn, re); return 0; } @@ -724,26 +727,26 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, if (same) { UNSET_FLAG(same->flags, ZEBRA_FLAG_SELECTED); - zebra_del_import_table_entry(zvrf, rn, same); + zebra_del_import_table_entry(zvrf, safi, rn, same); } UNSET_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE); - newre = zebra_rib_route_entry_new( - 0, ZEBRA_ROUTE_TABLE, re->table, re->flags, re->nhe_id, - zvrf->table_id, re->metric, re->mtu, - zebra_import_table_distance[afi][re->table], re->tag); + newre = zebra_rib_route_entry_new(0, ZEBRA_ROUTE_TABLE, re->table, re->flags, re->nhe_id, + zvrf->table_id, re->metric, re->mtu, + zebra_import_table_distance[afi][safi][re->table], + re->tag); ng = nexthop_group_new(); copy_nexthops(&ng->nexthop, re->nhe->nhg.nexthop, NULL); - rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre, ng, false); + rib_add_multipath(afi, safi, &p, NULL, newre, ng, false); nexthop_group_delete(&ng); return 0; } -int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, +int zebra_del_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, struct route_entry *re) { struct prefix p; @@ -752,17 +755,16 @@ int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, afi = family2afi(rn->p.family); prefix_copy(&p, &rn->p); - rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE, - re->table, re->flags, &p, NULL, re->nhe->nhg.nexthop, - re->nhe_id, zvrf->table_id, re->metric, re->distance, + rib_delete(afi, safi, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE, re->table, re->flags, &p, NULL, + re->nhe->nhg.nexthop, re->nhe_id, zvrf->table_id, re->metric, re->distance, false); return 0; } /* Assuming no one calls this with the main routing table */ -int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, - uint32_t distance, const char *rmap_name, int add) +int zebra_import_table(afi_t afi, safi_t safi, vrf_id_t vrf_id, uint32_t table_id, + uint32_t distance, const char *rmap_name, bool add) { struct route_table *table; struct route_entry *re; @@ -776,38 +778,39 @@ int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, if (afi >= AFI_MAX) return -1; + if (safi >= SAFI_MAX) + return -1; + + /* Always import from the URIB sub-table */ table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST, vrf_id, table_id); if (table == NULL) { return 0; } else if (IS_ZEBRA_DEBUG_RIB) { - zlog_debug("%s routes from table %d", - add ? "Importing" : "Unimporting", table_id); + zlog_debug("%s routes from table %d into %s", add ? "Importing" : "Unimporting", + table_id, safi2str(safi)); } if (add) { if (rmap_name) - zebra_add_import_table_route_map(afi, rmap_name, - table_id); + zebra_add_import_table_route_map(afi, safi, rmap_name, table_id); else { - rmap_name = - zebra_get_import_table_route_map(afi, table_id); + rmap_name = zebra_get_import_table_route_map(afi, safi, table_id); if (rmap_name) { - zebra_del_import_table_route_map(afi, table_id); + zebra_del_import_table_route_map(afi, safi, table_id); rmap_name = NULL; } } - zebra_import_table_used[afi][table_id] = 1; - zebra_import_table_distance[afi][table_id] = distance; + zebra_import_table_used[afi][safi][table_id] = 1; + zebra_import_table_distance[afi][safi][table_id] = distance; } else { - zebra_import_table_used[afi][table_id] = 0; - zebra_import_table_distance[afi][table_id] = - ZEBRA_TABLE_DISTANCE_DEFAULT; + zebra_import_table_used[afi][safi][table_id] = 0; + zebra_import_table_distance[afi][safi][table_id] = ZEBRA_TABLE_DISTANCE_DEFAULT; - rmap_name = zebra_get_import_table_route_map(afi, table_id); + rmap_name = zebra_get_import_table_route_map(afi, safi, table_id); if (rmap_name) { - zebra_del_import_table_route_map(afi, table_id); + zebra_del_import_table_route_map(afi, safi, table_id); rmap_name = NULL; } } @@ -831,10 +834,9 @@ int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, if (((afi == AFI_IP) && (rn->p.family == AF_INET)) || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) { if (add) - zebra_add_import_table_entry(zvrf, rn, re, - rmap_name); + zebra_add_import_table_entry(zvrf, safi, rn, re, rmap_name); else - zebra_del_import_table_entry(zvrf, rn, re); + zebra_del_import_table_entry(zvrf, safi, rn, re); } } return 0; @@ -844,26 +846,27 @@ int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id) { int i; afi_t afi; + safi_t safi; int write = 0; char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"}; const char *rmap_name; - for (afi = AFI_IP; afi < AFI_MAX; afi++) { + FOREACH_AFI_SAFI (afi, safi) { for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { - if (!is_zebra_import_table_enabled(afi, vrf_id, i)) + if (!is_zebra_import_table_enabled(afi, safi, vrf_id, i)) continue; - if (zebra_import_table_distance[afi][i] - != ZEBRA_TABLE_DISTANCE_DEFAULT) { - vty_out(vty, "%s import-table %d distance %d", - afi_str[afi], i, - zebra_import_table_distance[afi][i]); + if (zebra_import_table_distance[afi][safi][i] != + ZEBRA_TABLE_DISTANCE_DEFAULT) { + vty_out(vty, "%s import-table %d %sdistance %d", afi_str[afi], i, + (safi == SAFI_MULTICAST ? "mrib " : ""), + zebra_import_table_distance[afi][safi][i]); } else { - vty_out(vty, "%s import-table %d", afi_str[afi], - i); + vty_out(vty, "%s import-table %d%s", afi_str[afi], i, + (safi == SAFI_MULTICAST ? " mrib" : "")); } - rmap_name = zebra_get_import_table_route_map(afi, i); + rmap_name = zebra_get_import_table_route_map(afi, safi, i); if (rmap_name) vty_out(vty, " route-map %s", rmap_name); @@ -875,21 +878,19 @@ int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id) return write; } -static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf, - afi_t afi, int table_id, - const char *rmap) +static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf, afi_t afi, safi_t safi, + int table_id, const char *rmap) { struct route_table *table; struct route_entry *re; struct route_node *rn; const char *rmap_name; - rmap_name = zebra_get_import_table_route_map(afi, table_id); + rmap_name = zebra_get_import_table_route_map(afi, safi, table_id); if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0)) return; - table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST, - zvrf->vrf->vrf_id, table_id); + table = zebra_vrf_get_table_with_table_id(afi, safi, zvrf->vrf->vrf_id, table_id); if (!table) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug("%s: Table id=%d not found", __func__, @@ -916,7 +917,7 @@ static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf, if (((afi == AFI_IP) && (rn->p.family == AF_INET)) || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) - zebra_add_import_table_entry(zvrf, rn, re, rmap_name); + zebra_add_import_table_entry(zvrf, safi, rn, re, rmap_name); } return; @@ -926,16 +927,15 @@ static void zebra_import_table_rm_update_vrf(struct zebra_vrf *zvrf, const char *rmap) { afi_t afi; + safi_t safi; int i; - for (afi = AFI_IP; afi < AFI_MAX; afi++) { + FOREACH_AFI_SAFI (afi, safi) { for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { - if (!is_zebra_import_table_enabled( - afi, zvrf->vrf->vrf_id, i)) + if (!is_zebra_import_table_enabled(afi, safi, zvrf->vrf->vrf_id, i)) continue; - zebra_import_table_rm_update_vrf_afi(zvrf, afi, i, - rmap); + zebra_import_table_rm_update_vrf_afi(zvrf, afi, safi, i, rmap); } } } diff --git a/zebra/redistribute.h b/zebra/redistribute.h index 4347454eb7..7fb31f01cf 100644 --- a/zebra/redistribute.h +++ b/zebra/redistribute.h @@ -56,19 +56,14 @@ extern void zebra_interface_vrf_update_del(struct interface *ifp, extern void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id); -extern int zebra_import_table(afi_t afi, vrf_id_t vrf_id, - uint32_t table_id, uint32_t distance, - const char *rmap_name, int add); +extern int zebra_import_table(afi_t afi, safi_t safi, vrf_id_t vrf_id, uint32_t table_id, + uint32_t distance, const char *rmap_name, bool add); -extern int zebra_add_import_table_entry(struct zebra_vrf *zvrf, - struct route_node *rn, - struct route_entry *re, - const char *rmap_name); -extern int zebra_del_import_table_entry(struct zebra_vrf *zvrf, - struct route_node *rn, +extern int zebra_add_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, + struct route_entry *re, const char *rmap_name); +extern int zebra_del_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, struct route_entry *re); -extern int is_zebra_import_table_enabled(afi_t, vrf_id_t vrf_id, - uint32_t table_id); +extern int is_zebra_import_table_enabled(afi_t, safi_t safi, vrf_id_t vrf_id, uint32_t table_id); extern int zebra_import_table_config(struct vty *, vrf_id_t vrf_id); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index aea39b8ecf..59e7696ed2 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -4014,6 +4014,7 @@ static void rib_link(struct route_node *rn, struct route_entry *re, int process) { rib_dest_t *dest; afi_t afi; + safi_t safi; const char *rmap_name; assert(re && rn); @@ -4031,11 +4032,13 @@ static void rib_link(struct route_node *rn, struct route_entry *re, int process) afi = (rn->p.family == AF_INET) ? AFI_IP : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; - if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) { - struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { + if (is_zebra_import_table_enabled(afi, safi, re->vrf_id, re->table)) { + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); - rmap_name = zebra_get_import_table_route_map(afi, re->table); - zebra_add_import_table_entry(zvrf, rn, re, rmap_name); + rmap_name = zebra_get_import_table_route_map(afi, safi, re->table); + zebra_add_import_table_entry(zvrf, safi, rn, re, rmap_name); + } } if (process) @@ -4093,6 +4096,7 @@ void rib_unlink(struct route_node *rn, struct route_entry *re) void rib_delnode(struct route_node *rn, struct route_entry *re) { afi_t afi; + safi_t safi; if (IS_ZEBRA_DEBUG_RIB) rnode_debug(rn, re->vrf_id, "rn %p, re %p, removing", @@ -4106,15 +4110,17 @@ void rib_delnode(struct route_node *rn, struct route_entry *re) afi = (rn->p.family == AF_INET) ? AFI_IP : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; - if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) { - struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { + if (is_zebra_import_table_enabled(afi, safi, re->vrf_id, re->table)) { + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); - zebra_del_import_table_entry(zvrf, rn, re); - /* Just clean up if non main table */ - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug("%s(%u):%pRN: Freeing route rn %p, re %p (%s)", - vrf_id_to_name(re->vrf_id), re->vrf_id, rn, - rn, re, zebra_route_string(re->type)); + zebra_del_import_table_entry(zvrf, safi, rn, re); + /* Just clean up if non main table */ + if (IS_ZEBRA_DEBUG_RIB) + zlog_debug("%s %s(%u):%pRN: Freeing route rn %p, re %p (%s)", + safi2str(safi), vrf_id_to_name(re->vrf_id), re->vrf_id, + rn, rn, re, zebra_route_string(re->type)); + } } rib_queue_add(rn); diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 46afbcecfa..29bbf6023d 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -29,7 +29,7 @@ static uint32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER; static struct event *zebra_t_rmap_update = NULL; -char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; +char *zebra_import_table_routemap[AFI_MAX][SAFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; struct zebra_rmap_obj { struct nexthop *nexthop; @@ -1235,21 +1235,19 @@ route_map_result_t zebra_route_map_check(afi_t family, struct route_entry *re, return (ret); } -char *zebra_get_import_table_route_map(afi_t afi, uint32_t table) +char *zebra_get_import_table_route_map(afi_t afi, safi_t safi, uint32_t table) { - return zebra_import_table_routemap[afi][table]; + return zebra_import_table_routemap[afi][safi][table]; } -void zebra_add_import_table_route_map(afi_t afi, const char *rmap_name, - uint32_t table) +void zebra_add_import_table_route_map(afi_t afi, safi_t safi, const char *rmap_name, uint32_t table) { - zebra_import_table_routemap[afi][table] = - XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name); + zebra_import_table_routemap[afi][safi][table] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name); } -void zebra_del_import_table_route_map(afi_t afi, uint32_t table) +void zebra_del_import_table_route_map(afi_t afi, safi_t safi, uint32_t table) { - XFREE(MTYPE_ROUTE_MAP_NAME, zebra_import_table_routemap[afi][table]); + XFREE(MTYPE_ROUTE_MAP_NAME, zebra_import_table_routemap[afi][safi][table]); } route_map_result_t zebra_import_table_route_map_check(int family, diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h index 2039e80e3a..fca9752285 100644 --- a/zebra/zebra_routemap.h +++ b/zebra/zebra_routemap.h @@ -14,10 +14,10 @@ extern "C" { #endif extern void zebra_route_map_init(void); -extern char *zebra_get_import_table_route_map(afi_t afi, uint32_t table); -extern void zebra_add_import_table_route_map(afi_t afi, const char *rmap_name, +extern char *zebra_get_import_table_route_map(afi_t afi, safi_t safi, uint32_t table); +extern void zebra_add_import_table_route_map(afi_t afi, safi_t safi, const char *rmap_name, uint32_t table); -extern void zebra_del_import_table_route_map(afi_t afi, uint32_t table); +extern void zebra_del_import_table_route_map(afi_t afi, safi_t safi, uint32_t table); extern route_map_result_t zebra_import_table_route_map_check( int family, struct route_entry *re, const struct prefix *p, diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 309cde9a35..8c0d6df68a 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -3594,54 +3594,34 @@ static int zebra_ip_config(struct vty *vty) return write; } -DEFUN (ip_zebra_import_table_distance, +DEFPY (ip_zebra_import_table_distance, ip_zebra_import_table_distance_cmd, - "ip import-table (1-252) [distance (1-255)] [route-map RMAP_NAME]", + "ip import-table (1-252)$table_id [mrib]$mrib [distance (1-255)$distance] [route-map RMAP_NAME$rmap]", IP_STR "import routes from non-main kernel table\n" "kernel routing table id\n" + "Import into the MRIB instead of the URIB\n" "Distance for imported routes\n" "Default distance value\n" "route-map for filtering\n" "route-map name\n") { - uint32_t table_id = 0; + safi_t safi = mrib ? SAFI_MULTICAST : SAFI_UNICAST; - table_id = strtoul(argv[2]->arg, NULL, 10); - int distance = ZEBRA_TABLE_DISTANCE_DEFAULT; - char *rmap = - strmatch(argv[argc - 2]->text, "route-map") - ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg) - : NULL; - int ret; - - if (argc == 7 || (argc == 5 && !rmap)) - distance = strtoul(argv[4]->arg, NULL, 10); + if (distance_str == NULL) + distance = ZEBRA_TABLE_DISTANCE_DEFAULT; if (!is_zebra_valid_kernel_table(table_id)) { - vty_out(vty, - "Invalid routing table ID, %d. Must be in range 1-252\n", - table_id); - if (rmap) - XFREE(MTYPE_ROUTE_MAP_NAME, rmap); + vty_out(vty, "Invalid routing table ID, %ld. Must be in range 1-252\n", table_id); return CMD_WARNING; } if (is_zebra_main_routing_table(table_id)) { - vty_out(vty, - "Invalid routing table ID, %d. Must be non-default table\n", - table_id); - if (rmap) - XFREE(MTYPE_ROUTE_MAP_NAME, rmap); + vty_out(vty, "Invalid routing table ID, %ld. Must be non-default table\n", table_id); return CMD_WARNING; } - ret = zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, - distance, rmap, 1); - if (rmap) - XFREE(MTYPE_ROUTE_MAP_NAME, rmap); - - return ret; + return zebra_import_table(AFI_IP, safi, VRF_DEFAULT, table_id, distance, rmap, true); } DEFUN_HIDDEN (zebra_packet_process, @@ -3700,20 +3680,20 @@ DEFUN_HIDDEN (no_zebra_workqueue_timer, return CMD_SUCCESS; } -DEFUN (no_ip_zebra_import_table, +DEFPY (no_ip_zebra_import_table, no_ip_zebra_import_table_cmd, - "no ip import-table (1-252) [distance (1-255)] [route-map NAME]", + "no ip import-table (1-252)$table_id [mrib]$mrib [distance (1-255)] [route-map NAME]", NO_STR IP_STR "import routes from non-main kernel table\n" "kernel routing table id\n" + "Import into the MRIB instead of the URIB\n" "Distance for imported routes\n" "Default distance value\n" "route-map for filtering\n" "route-map name\n") { - uint32_t table_id = 0; - table_id = strtoul(argv[3]->arg, NULL, 10); + safi_t safi = mrib ? SAFI_MULTICAST : SAFI_UNICAST; if (!is_zebra_valid_kernel_table(table_id)) { vty_out(vty, @@ -3722,16 +3702,14 @@ DEFUN (no_ip_zebra_import_table, } if (is_zebra_main_routing_table(table_id)) { - vty_out(vty, - "Invalid routing table ID, %d. Must be non-default table\n", - table_id); + vty_out(vty, "Invalid routing table ID, %ld. Must be non-default table\n", table_id); return CMD_WARNING; } - if (!is_zebra_import_table_enabled(AFI_IP, VRF_DEFAULT, table_id)) + if (!is_zebra_import_table_enabled(AFI_IP, safi, VRF_DEFAULT, table_id)) return CMD_SUCCESS; - return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0)); + return (zebra_import_table(AFI_IP, safi, VRF_DEFAULT, table_id, 0, NULL, false)); } DEFPY (zebra_nexthop_group_keep, From 1c50a553fc910f583c8a5c2df252f10b34d47361 Mon Sep 17 00:00:00 2001 From: Nathan Bahr Date: Tue, 29 Oct 2024 03:40:55 +0000 Subject: [PATCH 2/3] doc: Document zebra table import command with additional mrib flag Signed-off-by: Nathan Bahr --- doc/user/zebra.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 74564c94b9..242d616a5f 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -1287,6 +1287,25 @@ IPv6 example for OSPFv3. Set the delay before any route-maps are processed in zebra. The default time for this is 5 seconds. + +.. _zebra-table-import: + +zebra Table Import +================== + +Zebra supports importing an alternate routing table into the main unicast RIB (URIB). +An imported table will continously sync all changes to the main URIB as routes are +added or deleted from the alternate table. +Zebra also supports importing into the main multicast RIB (MRIB) which can be used +to affect how multicast RPF lookups are performed as described in :ref: `_pim-multicast-rib`. + +.. clicmd:: ip import-table (1-252) [mrib] [distance (1-255)] [route-map RMAP_NAME] + + Import table, by given table id, into the main URIB (or MRIB). Optional distance can override + the default distance when importing routes from the alternate table. An optional route map + can be provided to filter routes that are imported into the main table. + + .. _zebra-fib-push-interface: zebra FIB push interface From 180e1a0d77a2041e9d0ad70cc3a182ff6ed0c1fd Mon Sep 17 00:00:00 2001 From: Nathan Bahr Date: Tue, 29 Oct 2024 15:06:36 +0000 Subject: [PATCH 3/3] tests: Add zebra rib import-table tests Signed-off-by: Nathan Bahr --- tests/topotests/zebra_rib/r1/frr-import.conf | 18 ++ .../zebra_rib/r1/import_init_mrib_table.json | 126 ++++++++ .../zebra_rib/r1/import_init_table.json | 126 ++++++++ .../zebra_rib/r1/import_mrib_table_2.json | 258 ++++++++++++++++ .../zebra_rib/r1/import_mrib_table_3.json | 291 ++++++++++++++++++ .../zebra_rib/r1/import_mrib_table_4.json | 258 ++++++++++++++++ .../zebra_rib/r1/import_table_2.json | 258 ++++++++++++++++ .../zebra_rib/r1/import_table_3.json | 291 ++++++++++++++++++ .../zebra_rib/r1/import_table_4.json | 258 ++++++++++++++++ .../topotests/zebra_rib/test_zebra_import.py | 280 +++++++++++++++++ 10 files changed, 2164 insertions(+) create mode 100644 tests/topotests/zebra_rib/r1/frr-import.conf create mode 100644 tests/topotests/zebra_rib/r1/import_init_mrib_table.json create mode 100644 tests/topotests/zebra_rib/r1/import_init_table.json create mode 100644 tests/topotests/zebra_rib/r1/import_mrib_table_2.json create mode 100644 tests/topotests/zebra_rib/r1/import_mrib_table_3.json create mode 100644 tests/topotests/zebra_rib/r1/import_mrib_table_4.json create mode 100644 tests/topotests/zebra_rib/r1/import_table_2.json create mode 100644 tests/topotests/zebra_rib/r1/import_table_3.json create mode 100644 tests/topotests/zebra_rib/r1/import_table_4.json create mode 100644 tests/topotests/zebra_rib/test_zebra_import.py diff --git a/tests/topotests/zebra_rib/r1/frr-import.conf b/tests/topotests/zebra_rib/r1/frr-import.conf new file mode 100644 index 0000000000..d07433144f --- /dev/null +++ b/tests/topotests/zebra_rib/r1/frr-import.conf @@ -0,0 +1,18 @@ +! +hostname r1 +password zebra +log file /tmp/r1-frr.log +! +interface r1-eth0 + ip address 10.0.0.1/24 +! +interface r1-eth1 + ip address 10.10.0.1/24 +! +ip route 10.1.0.0/24 10.0.0.2 table 10 +ip route 10.2.0.0/24 10.0.0.2 table 10 +ip route 10.3.0.0/24 10.10.0.2 table 10 +ip route 10.4.0.0/24 10.10.0.2 table 10 +! +ip forwarding +! \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_init_mrib_table.json b/tests/topotests/zebra_rib/r1/import_init_mrib_table.json new file mode 100644 index 0000000000..a6807d2cdd --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_init_mrib_table.json @@ -0,0 +1,126 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_init_table.json b/tests/topotests/zebra_rib/r1/import_init_table.json new file mode 100644 index 0000000000..a6807d2cdd --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_init_table.json @@ -0,0 +1,126 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_mrib_table_2.json b/tests/topotests/zebra_rib/r1/import_mrib_table_2.json new file mode 100644 index 0000000000..0a7915df0f --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_mrib_table_2.json @@ -0,0 +1,258 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_mrib_table_3.json b/tests/topotests/zebra_rib/r1/import_mrib_table_3.json new file mode 100644 index 0000000000..11bbcf8ec8 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_mrib_table_3.json @@ -0,0 +1,291 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.20.0.0/24": [ + { + "prefix": "10.20.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_mrib_table_4.json b/tests/topotests/zebra_rib/r1/import_mrib_table_4.json new file mode 100644 index 0000000000..4375b9cde6 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_mrib_table_4.json @@ -0,0 +1,258 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_table_2.json b/tests/topotests/zebra_rib/r1/import_table_2.json new file mode 100644 index 0000000000..0a7915df0f --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_table_2.json @@ -0,0 +1,258 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_table_3.json b/tests/topotests/zebra_rib/r1/import_table_3.json new file mode 100644 index 0000000000..11bbcf8ec8 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_table_3.json @@ -0,0 +1,291 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.20.0.0/24": [ + { + "prefix": "10.20.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_table_4.json b/tests/topotests/zebra_rib/r1/import_table_4.json new file mode 100644 index 0000000000..4375b9cde6 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_table_4.json @@ -0,0 +1,258 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/test_zebra_import.py b/tests/topotests/zebra_rib/test_zebra_import.py new file mode 100644 index 0000000000..7819548ad2 --- /dev/null +++ b/tests/topotests/zebra_rib/test_zebra_import.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC +# +# test_zebra_import.py +# +# Copyright (c) 2024 ATCorp +# Nathan Bahr +# + +import os +import sys +from functools import partial +import pytest +import json +import platform + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, get_topogen +from lib.topolog import logger +from lib.common_config import step, write_test_header + +""" +test_zebra_import.py: Test zebra table import functionality +""" + +TOPOLOGY = """ + Single router zebra functionality + + +---+---+ + 10.0.0.1/24 | | 10.10.0.1/24 + <--->+ R1 +<---> + | | + +---+---+ +""" + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +pytestmark = [pytest.mark.sharpd] +krel = platform.release() + +def build_topo(tgen): + "Build function" + + tgen.add_router("r1") + sw1 = tgen.add_switch("sw1") + sw2 = tgen.add_switch("sw2") + sw1.add_link(tgen.gears["r1"], "r1-eth0") + sw2.add_link(tgen.gears["r1"], "r1-eth1") + +def setup_module(mod): + "Sets up the pytest environment" + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for rname, router in router_list.items(): + logger.info("Loading router %s" % rname) + router.load_frr_config(os.path.join(CWD, "{}/frr-import.conf".format(rname))) + + # Initialize all routers. + tgen.start_router() + for router in router_list.values(): + if router.has_version("<", "4.0"): + tgen.set_error("unsupported version") + + +def teardown_module(): + "Teardown the pytest environment" + tgen = get_topogen() + tgen.stop_topology() + + +def test_zebra_urib_import(request): + "Verify router starts with the initial URIB" + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + step("Verify initial main routing table") + initial_json_file = "{}/r1/import_init_table.json".format(CWD) + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + r1.vtysh_cmd( + """ + conf term + ip import-table 10 + """) + + import_json_file = "{}/r1/import_table_2.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Add a new static route and verify it gets added") + r1.vtysh_cmd( + """ + conf term + ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + sync_json_file = "{}/r1/import_table_3.json".format(CWD) + expected = json.loads(open(sync_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Remove the static route and verify it gets removed") + r1.vtysh_cmd( + """ + conf term + no ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Disable table import and verify it goes back to the initial table") + r1.vtysh_cmd( + """ + conf term + no ip import-table 10 + """ + ) + + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Re-import with distance and verify correct distance") + r1.vtysh_cmd( + """ + conf term + ip import-table 10 distance 123 + """) + + import_json_file = "{}/r1/import_table_4.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + +def test_zebra_mrib_import(request): + "Verify router starts with the initial MRIB" + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + step("Verify initial main MRIB routing table") + initial_json_file = "{}/r1/import_init_mrib_table.json".format(CWD) + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + r1.vtysh_cmd( + """ + conf term + ip import-table 10 mrib + """) + + import_json_file = "{}/r1/import_mrib_table_2.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Add a new static route and verify it gets added") + r1.vtysh_cmd( + """ + conf term + ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + sync_json_file = "{}/r1/import_mrib_table_3.json".format(CWD) + expected = json.loads(open(sync_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Remove the static route and verify it gets removed") + r1.vtysh_cmd( + """ + conf term + no ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Disable table import and verify it goes back to the initial table") + r1.vtysh_cmd( + """ + conf term + no ip import-table 10 mrib + """ + ) + + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Re-import with distance and verify correct distance") + r1.vtysh_cmd( + """ + conf term + ip import-table 10 mrib distance 123 + """) + + import_json_file = "{}/r1/import_mrib_table_4.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args))