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,