]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Add ability to import alternate tables into the MRIB
authorNathan Bahr <nbahr@atcorp.com>
Mon, 28 Oct 2024 18:55:49 +0000 (18:55 +0000)
committerNathan Bahr <nbahr@atcorp.com>
Tue, 29 Oct 2024 20:17:59 +0000 (20:17 +0000)
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 <nbahr@atcorp.com>
zebra/redistribute.c
zebra/redistribute.h
zebra/zebra_rib.c
zebra/zebra_routemap.c
zebra/zebra_routemap.h
zebra/zebra_vty.c

index 2de0917a7e4322a2b0a701a044942feb00e89ff1..66dc5b4b5f821aa6e8c372188890438b771f81c8 100644 (file)
 
 /* 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);
                }
        }
 }
index 4347454eb7c676e3e6681a74452ac8a43c2058cb..7fb31f01cface40882e5b6d07451f293f79f5e95 100644 (file)
@@ -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);
 
index aea39b8ecf18c0f4c69cb944e6314f69af9bd22c..59e7696ed29cefe9e6a438887cce54e53d63e7a1 100644 (file)
@@ -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);
index 46afbcecfa98d1293ed032f3e29d862353a5acc1..29bbf6023dd6ae84d83e5bde6b345740d48e3340 100644 (file)
@@ -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,
index 2039e80e3a74d83577ca9895a7c2149f219a0334..fca9752285c2893caf5c0cf0e11c63094a9d8aa1 100644 (file)
@@ -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,
index 309cde9a35b2c2b55dd5f7054cc3ac1917c041d6..8c0d6df68a76403e736a4e9e6aabdf5aa48abf78 100644 (file)
@@ -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;
-
-       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;
+       safi_t safi = mrib ? SAFI_MULTICAST : SAFI_UNICAST;
 
-       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,