]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_rib.c
zebra: clean up zapi organization
[mirror_frr.git] / zebra / zebra_rib.c
index 7f6c8aefa8086626d4e40b31fe3b0b49b6801348..67832f2d3fe54ba157f6c205ccb6d8dcf00f29cc 100644 (file)
@@ -42,7 +42,6 @@
 #include "zebra/rib.h"
 #include "zebra/rt.h"
 #include "zebra/zebra_ns.h"
-#include "zebra/zserv.h"
 #include "zebra/zebra_vrf.h"
 #include "zebra/redistribute.h"
 #include "zebra/zebra_routemap.h"
@@ -51,6 +50,7 @@
 #include "zebra/interface.h"
 #include "zebra/connected.h"
 #include "zebra/zebra_vxlan.h"
+#include "zebra/zapi_msg.h"
 
 DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason),
            (rn, reason))
@@ -137,11 +137,8 @@ uint8_t route_distance(int type)
        return distance;
 }
 
-int is_zebra_valid_kernel_table(u_int32_t table_id)
+int is_zebra_valid_kernel_table(uint32_t table_id)
 {
-       if ((table_id > ZEBRA_KERNEL_TABLE_MAX))
-               return 0;
-
 #ifdef linux
        if ((table_id == RT_TABLE_UNSPEC) || (table_id == RT_TABLE_LOCAL)
            || (table_id == RT_TABLE_COMPAT))
@@ -151,7 +148,7 @@ int is_zebra_valid_kernel_table(u_int32_t table_id)
        return 1;
 }
 
-int is_zebra_main_routing_table(u_int32_t table_id)
+int is_zebra_main_routing_table(uint32_t table_id)
 {
        if ((table_id == RT_TABLE_MAIN)
            || (table_id == zebrad.rtm_table_default))
@@ -162,7 +159,7 @@ int is_zebra_main_routing_table(u_int32_t table_id)
 int zebra_check_addr(struct prefix *p)
 {
        if (p->family == AF_INET) {
-               u_int32_t addr;
+               uint32_t addr;
 
                addr = p->u.prefix4.s_addr;
                addr = ntohl(addr);
@@ -183,7 +180,7 @@ int zebra_check_addr(struct prefix *p)
 /* Add nexthop to the end of a rib node's nexthop list */
 void route_entry_nexthop_add(struct route_entry *re, struct nexthop *nexthop)
 {
-       nexthop_add(&re->nexthop, nexthop);
+       nexthop_add(&re->ng.nexthop, nexthop);
        re->nexthop_num++;
 }
 
@@ -193,8 +190,8 @@ void route_entry_nexthop_add(struct route_entry *re, struct nexthop *nexthop)
  */
 void route_entry_copy_nexthops(struct route_entry *re, struct nexthop *nh)
 {
-       assert(!re->nexthop);
-       copy_nexthops(&re->nexthop, nh, NULL);
+       assert(!re->ng.nexthop);
+       copy_nexthops(&re->ng.nexthop, nh, NULL);
        for (struct nexthop *nexthop = nh; nexthop; nexthop = nexthop->next)
                re->nexthop_num++;
 }
@@ -207,7 +204,7 @@ void route_entry_nexthop_delete(struct route_entry *re, struct nexthop *nexthop)
        if (nexthop->prev)
                nexthop->prev->next = nexthop->next;
        else
-               re->nexthop = nexthop->next;
+               re->ng.nexthop = nexthop->next;
        re->nexthop_num--;
 }
 
@@ -267,8 +264,8 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re,
        /*Pending: need to think if null ifp here is ok during bootup?
          There was a crash because ifp here was coming to be NULL */
        if (ifp)
-               if (connected_is_unnumbered(ifp) ||
-                   CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)) {
+               if (connected_is_unnumbered(ifp)
+                   || CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)) {
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
                }
 
@@ -305,6 +302,8 @@ struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
        nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
        nexthop->gate.ipv6 = *ipv6;
        nexthop->ifindex = ifindex;
+       if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE))
+               SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
 
        route_entry_nexthop_add(re, nexthop);
 
@@ -421,6 +420,10 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
                re->nexthop_mtu = 0;
        }
 
+       /* Next hops (remote VTEPs) for EVPN routes are fully resolved. */
+       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN_RVTEP))
+               return 1;
+
        /* Skip nexthops that have been filtered out due to route-map */
        /* The nexthops are specific to this route and so the same */
        /* nexthop for a different route may not have this flag set */
@@ -475,8 +478,8 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
                 * host route.
                 */
                if (top && rn == top)
-                       if (((afi == AFI_IP) && (rn->p.prefixlen != 32)) ||
-                           ((afi == AFI_IP6) && (rn->p.prefixlen != 128)))
+                       if (((afi == AFI_IP) && (rn->p.prefixlen != 32))
+                           || ((afi == AFI_IP6) && (rn->p.prefixlen != 128)))
                                return 0;
 
                /* Pick up selected route. */
@@ -487,10 +490,10 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
                        return 0;
 
                dest = rib_dest_from_rnode(rn);
-               if (dest && dest->selected_fib &&
-                   !CHECK_FLAG(dest->selected_fib->status,
-                               ROUTE_ENTRY_REMOVED) &&
-                   dest->selected_fib->type != ZEBRA_ROUTE_TABLE)
+               if (dest && dest->selected_fib
+                   && !CHECK_FLAG(dest->selected_fib->status,
+                                  ROUTE_ENTRY_REMOVED)
+                   && dest->selected_fib->type != ZEBRA_ROUTE_TABLE)
                        match = dest->selected_fib;
 
                /* If there is no selected route or matched route is EGP, go up
@@ -507,7 +510,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
 
                if (match->type == ZEBRA_ROUTE_CONNECT) {
                        /* Directly point connected route. */
-                       newhop = match->nexthop;
+                       newhop = match->ng.nexthop;
                        if (newhop) {
                                if (nexthop->type == NEXTHOP_TYPE_IPV4
                                    || nexthop->type == NEXTHOP_TYPE_IPV6)
@@ -516,7 +519,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
                        return 1;
                } else if (CHECK_FLAG(re->flags, ZEBRA_FLAG_ALLOW_RECURSION)) {
                        resolved = 0;
-                       for (ALL_NEXTHOPS(match->nexthop, newhop)) {
+                       for (ALL_NEXTHOPS(match->ng, newhop)) {
                                if (!CHECK_FLAG(newhop->flags,
                                                NEXTHOP_FLAG_FIB))
                                        continue;
@@ -539,7 +542,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
                        return resolved;
                } else if (re->type == ZEBRA_ROUTE_STATIC) {
                        resolved = 0;
-                       for (ALL_NEXTHOPS(match->nexthop, newhop)) {
+                       for (ALL_NEXTHOPS(match->ng, newhop)) {
                                if (!CHECK_FLAG(newhop->flags,
                                                NEXTHOP_FLAG_FIB))
                                        continue;
@@ -594,8 +597,9 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
                route_unlock_node(rn);
 
                dest = rib_dest_from_rnode(rn);
-               if (dest && dest->selected_fib &&
-                   !CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
+               if (dest && dest->selected_fib
+                   && !CHECK_FLAG(dest->selected_fib->status,
+                                  ROUTE_ENTRY_REMOVED))
                        match = dest->selected_fib;
 
                /* If there is no selected route or matched route is EGP, go up
@@ -609,7 +613,7 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
                } else {
                        if (match->type != ZEBRA_ROUTE_CONNECT) {
                                int found = 0;
-                               for (ALL_NEXTHOPS(match->nexthop, newhop))
+                               for (ALL_NEXTHOPS(match->ng, newhop))
                                        if (CHECK_FLAG(newhop->flags,
                                                       NEXTHOP_FLAG_FIB)) {
                                                found = 1;
@@ -678,7 +682,8 @@ struct route_entry *rib_match_ipv4_multicast(vrf_id_t vrf_id,
                char buf[BUFSIZ];
                inet_ntop(AF_INET, &addr, buf, BUFSIZ);
 
-               zlog_debug("%s: %s: found %s, using %s", __func__, buf,
+               zlog_debug("%s: %s: vrf: %u found %s, using %s",
+                          __func__, buf, vrf_id,
                           mre ? (ure ? "MRIB+URIB" : "MRIB")
                               : ure ? "URIB" : "nothing",
                           re == ure ? "URIB" : re == mre ? "MRIB" : "none");
@@ -722,8 +727,8 @@ struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)
        route_unlock_node(rn);
        dest = rib_dest_from_rnode(rn);
 
-       if (dest && dest->selected_fib &&
-           !CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
+       if (dest && dest->selected_fib
+           && !CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
                match = dest->selected_fib;
 
        if (!match)
@@ -732,7 +737,7 @@ struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)
        if (match->type == ZEBRA_ROUTE_CONNECT)
                return match;
 
-       for (ALL_NEXTHOPS(match->nexthop, nexthop))
+       for (ALL_NEXTHOPS(match->ng, nexthop))
                if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
                        return match;
 
@@ -779,8 +784,8 @@ int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
 
        /* Find out if a "selected" RR for the discovered RIB entry exists ever.
         */
-       if (dest && dest->selected_fib &&
-           !CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
+       if (dest && dest->selected_fib
+           && !CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
                match = dest->selected_fib;
 
        /* None such found :( */
@@ -792,7 +797,7 @@ int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
 
        /* Ok, we have a cood candidate, let's check it's nexthop list... */
        nexthops_active = 0;
-       for (ALL_NEXTHOPS(match->nexthop, nexthop))
+       for (ALL_NEXTHOPS(match->ng, nexthop))
                if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
                        nexthops_active = 1;
                        if (nexthop->gate.ipv4.s_addr == sockunion2ip(qgate))
@@ -858,9 +863,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
        case NEXTHOP_TYPE_IPV4:
        case NEXTHOP_TYPE_IPV4_IFINDEX:
                family = AFI_IP;
-               if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN_RVTEP))
-                       SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
-               else if (nexthop_active(AFI_IP, re, nexthop, set, rn))
+               if (nexthop_active(AFI_IP, re, nexthop, set, rn))
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                else
                        UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
@@ -958,7 +961,7 @@ static int nexthop_active_update(struct route_node *rn, struct route_entry *re,
        re->nexthop_active_num = 0;
        UNSET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
 
-       for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) {
+       for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) {
                /* No protocol daemon provides src and so we're skipping
                 * tracking it */
                prev_src = nexthop->rmap_src;
@@ -1002,7 +1005,7 @@ int zebra_rib_labeled_unicast(struct route_entry *re)
        if (re->type != ZEBRA_ROUTE_BGP)
                return 0;
 
-       for (ALL_NEXTHOPS(re->nexthop, nexthop))
+       for (ALL_NEXTHOPS(re->ng, nexthop))
                if (!nexthop->nh_label || !nexthop->nh_label->num_labels)
                        return 0;
 
@@ -1022,7 +1025,7 @@ void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p,
        switch (res) {
        case SOUTHBOUND_INSTALL_SUCCESS:
                dest->selected_fib = re;
-               for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+               for (ALL_NEXTHOPS(re->ng, nexthop)) {
                        if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
                                continue;
 
@@ -1055,8 +1058,10 @@ void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p,
                 */
                if (dest->selected_fib == re)
                        dest->selected_fib = NULL;
-               for (ALL_NEXTHOPS(re->nexthop, nexthop))
+               for (ALL_NEXTHOPS(re->ng, nexthop))
                        UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
+
+               zsend_route_notify_owner(re, p, ZAPI_ROUTE_REMOVED);
                break;
        case SOUTHBOUND_DELETE_FAILURE:
                /*
@@ -1066,6 +1071,8 @@ void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p,
                dest->selected_fib = NULL;
                zlog_warn("%u:%s: Route Deletion failure", re->vrf_id,
                          prefix2str(p, buf, sizeof(buf)));
+
+               zsend_route_notify_owner(re, p, ZAPI_ROUTE_REMOVE_FAIL);
                break;
        }
 }
@@ -1084,20 +1091,20 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
        srcdest_rnode_prefixes(rn, &p, &src_p);
 
        if (info->safi != SAFI_UNICAST) {
-               for (ALL_NEXTHOPS(re->nexthop, nexthop))
+               for (ALL_NEXTHOPS(re->ng, nexthop))
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                return;
        } else {
                struct nexthop *prev;
 
-               for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+               for (ALL_NEXTHOPS(re->ng, nexthop)) {
                        UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_DUPLICATE);
-                       for (ALL_NEXTHOPS(re->nexthop, prev)) {
+                       for (ALL_NEXTHOPS(re->ng, prev)) {
                                if (prev == nexthop)
                                        break;
-                               if (nexthop_same_firsthop (nexthop, prev))
-                               {
-                                       SET_FLAG (nexthop->flags, NEXTHOP_FLAG_DUPLICATE);
+                               if (nexthop_same_firsthop(nexthop, prev)) {
+                                       SET_FLAG(nexthop->flags,
+                                                NEXTHOP_FLAG_DUPLICATE);
                                        break;
                                }
                        }
@@ -1133,7 +1140,7 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re)
        srcdest_rnode_prefixes(rn, &p, &src_p);
 
        if (info->safi != SAFI_UNICAST) {
-               for (ALL_NEXTHOPS(re->nexthop, nexthop))
+               for (ALL_NEXTHOPS(re->ng, nexthop))
                        UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                return;
        }
@@ -1383,7 +1390,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
                                        if (!RIB_SYSTEM_ROUTE(old))
                                                rib_uninstall_kernel(rn, old);
                                } else {
-                                       for (nexthop = old->nexthop; nexthop;
+                                       for (nexthop = old->ng.nexthop; nexthop;
                                             nexthop = nexthop->next)
                                                UNSET_FLAG(nexthop->flags,
                                                           NEXTHOP_FLAG_FIB);
@@ -1439,7 +1446,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
                if (!RIB_SYSTEM_ROUTE(new)) {
                        bool in_fib = false;
 
-                       for (ALL_NEXTHOPS(new->nexthop, nexthop))
+                       for (ALL_NEXTHOPS(new->ng, nexthop))
                                if (CHECK_FLAG(nexthop->flags,
                                               NEXTHOP_FLAG_FIB)) {
                                        in_fib = true;
@@ -1599,9 +1606,9 @@ static void rib_process(struct route_node *rn)
                                if (re != old_selected) {
                                        if (IS_ZEBRA_DEBUG_RIB)
                                                zlog_debug(
-                                                       "%s: %s: imported via import-table but denied "
+                                                       "%s: %u:%s: imported via import-table but denied "
                                                        "by the ip protocol table route-map",
-                                                       __func__, buf);
+                                                       __func__, vrf_id, buf);
                                        rib_unlink(rn, re);
                                } else
                                        SET_FLAG(re->status,
@@ -1671,13 +1678,16 @@ static void rib_process(struct route_node *rn)
 
        /* Redistribute SELECTED entry */
        if (old_selected != new_selected || selected_changed) {
-               struct nexthop *nexthop;
+               struct nexthop *nexthop = NULL;
 
                /* Check if we have a FIB route for the destination, otherwise,
                 * don't redistribute it */
-               for (ALL_NEXTHOPS(new_fib ? new_fib->nexthop : NULL, nexthop)) {
-                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
-                               break;
+               if (new_fib) {
+                       for (ALL_NEXTHOPS(new_fib->ng, nexthop)) {
+                               if (CHECK_FLAG(nexthop->flags,
+                                              NEXTHOP_FLAG_FIB)) {
+                                       break;
+                               }
                        }
                }
                if (!nexthop)
@@ -1726,7 +1736,7 @@ static void rib_process(struct route_node *rn)
  * picked from it and processed by rib_process(). Don't process more,
  * than one RN record; operate only in the specified sub-queue.
  */
-static unsigned int process_subq(struct list *subq, u_char qindex)
+static unsigned int process_subq(struct list *subq, uint8_t qindex)
 {
        struct listnode *lnode = listhead(subq);
        struct route_node *rnode;
@@ -1829,31 +1839,31 @@ static wq_item_status meta_queue_process(struct work_queue *dummy, void *data)
 /*
  * Map from rib types to queue type (priority) in meta queue
  */
-static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
-               [ZEBRA_ROUTE_SYSTEM] = 4,
-               [ZEBRA_ROUTE_KERNEL] = 0,
-               [ZEBRA_ROUTE_CONNECT] = 0,
-               [ZEBRA_ROUTE_STATIC] = 1,
-               [ZEBRA_ROUTE_RIP] = 2,
-               [ZEBRA_ROUTE_RIPNG] = 2,
-               [ZEBRA_ROUTE_OSPF] = 2,
-               [ZEBRA_ROUTE_OSPF6] = 2,
-               [ZEBRA_ROUTE_ISIS] = 2,
-               [ZEBRA_ROUTE_BGP] = 3,
-               [ZEBRA_ROUTE_PIM] = 4, // Shouldn't happen but for safety
-               [ZEBRA_ROUTE_EIGRP] = 2,
-               [ZEBRA_ROUTE_NHRP] = 2,
-               [ZEBRA_ROUTE_HSLS] = 4,
-               [ZEBRA_ROUTE_OLSR] = 4,
-               [ZEBRA_ROUTE_TABLE] = 1,
-               [ZEBRA_ROUTE_LDP] = 4,
-               [ZEBRA_ROUTE_VNC] = 3,
-               [ZEBRA_ROUTE_VNC_DIRECT] = 3,
-               [ZEBRA_ROUTE_VNC_DIRECT_RH] = 3,
-               [ZEBRA_ROUTE_BGP_DIRECT] = 3,
-               [ZEBRA_ROUTE_BGP_DIRECT_EXT] = 3,
-               [ZEBRA_ROUTE_BABEL] = 2,
-               [ZEBRA_ROUTE_ALL] = 4, // Shouldn't happen but for safety
+static const uint8_t meta_queue_map[ZEBRA_ROUTE_MAX] = {
+       [ZEBRA_ROUTE_SYSTEM] = 4,
+       [ZEBRA_ROUTE_KERNEL] = 0,
+       [ZEBRA_ROUTE_CONNECT] = 0,
+       [ZEBRA_ROUTE_STATIC] = 1,
+       [ZEBRA_ROUTE_RIP] = 2,
+       [ZEBRA_ROUTE_RIPNG] = 2,
+       [ZEBRA_ROUTE_OSPF] = 2,
+       [ZEBRA_ROUTE_OSPF6] = 2,
+       [ZEBRA_ROUTE_ISIS] = 2,
+       [ZEBRA_ROUTE_BGP] = 3,
+       [ZEBRA_ROUTE_PIM] = 4, // Shouldn't happen but for safety
+       [ZEBRA_ROUTE_EIGRP] = 2,
+       [ZEBRA_ROUTE_NHRP] = 2,
+       [ZEBRA_ROUTE_HSLS] = 4,
+       [ZEBRA_ROUTE_OLSR] = 4,
+       [ZEBRA_ROUTE_TABLE] = 1,
+       [ZEBRA_ROUTE_LDP] = 4,
+       [ZEBRA_ROUTE_VNC] = 3,
+       [ZEBRA_ROUTE_VNC_DIRECT] = 3,
+       [ZEBRA_ROUTE_VNC_DIRECT_RH] = 3,
+       [ZEBRA_ROUTE_BGP_DIRECT] = 3,
+       [ZEBRA_ROUTE_BGP_DIRECT_EXT] = 3,
+       [ZEBRA_ROUTE_BABEL] = 2,
+       [ZEBRA_ROUTE_ALL] = 4, // Shouldn't happen but for safety
 };
 
 /* Look into the RN and queue it into one or more priority queues,
@@ -1864,7 +1874,7 @@ static void rib_meta_queue_add(struct meta_queue *mq, struct route_node *rn)
        struct route_entry *re;
 
        RNODE_FOREACH_RE (rn, re) {
-               u_char qindex = meta_queue_map[re->type];
+               uint8_t qindex = meta_queue_map[re->type];
                struct zebra_vrf *zvrf;
 
                /* Invariant: at this point we always have rn->info set. */
@@ -2111,9 +2121,9 @@ void rib_unlink(struct route_node *rn, struct route_entry *re)
 
        /* free RE and nexthops */
        if (re->type == ZEBRA_ROUTE_STATIC)
-               zebra_deregister_rnh_static_nexthops(re->vrf_id,
-                                                    re->nexthop, rn);
-       nexthops_free(re->nexthop);
+               zebra_deregister_rnh_static_nexthops(re->ng.nexthop->vrf_id,
+                                                    re->ng.nexthop, rn);
+       nexthops_free(re->ng.nexthop);
        XFREE(MTYPE_RE, re);
 }
 
@@ -2177,11 +2187,11 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
        zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", func,
                   re->nexthop_num, re->nexthop_active_num);
 
-       for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+       for (ALL_NEXTHOPS(re->ng, nexthop)) {
                inet_ntop(p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
-               zlog_debug("%s: %s %s[%u] with flags %s%s%s", func,
+               zlog_debug("%s: %s %s[%u] vrf %u with flags %s%s%s", func,
                           (nexthop->rparent ? "  NH" : "NH"), straddr,
-                          nexthop->ifindex,
+                          nexthop->ifindex, nexthop->vrf_id,
                           (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)
                                    ? "ACTIVE "
                                    : ""),
@@ -2209,7 +2219,8 @@ void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id)
        /* Lookup table.  */
        table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
        if (!table) {
-               zlog_err("%s: zebra_vrf_table() returned NULL", __func__);
+               zlog_err("%s:%u zebra_vrf_table() returned NULL",
+                        __func__, vrf_id);
                return;
        }
 
@@ -2218,7 +2229,7 @@ void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id)
 
        /* No route for this prefix. */
        if (!rn) {
-               zlog_debug("%s: lookup failed for %s", __func__,
+               zlog_debug("%s:%u lookup failed for %s", __func__, vrf_id,
                           prefix2str((struct prefix *)p, prefix_buf,
                                      sizeof(prefix_buf)));
                return;
@@ -2229,8 +2240,9 @@ void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id)
 
        /* let's go */
        RNODE_FOREACH_RE (rn, re) {
-               zlog_debug("%s: rn %p, re %p: %s, %s", __func__, (void *)rn,
-                          (void *)re,
+               zlog_debug("%s:%u rn %p, re %p: %s, %s",
+                          __func__, vrf_id,
+                          (void *)rn, (void *)re,
                           (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)
                                    ? "removed"
                                    : "NOT removed"),
@@ -2254,7 +2266,8 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id)
        rib_dest_t *dest;
 
        if (NULL == (table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id))) {
-               zlog_err("%s: zebra_vrf_table() returned NULL", __func__);
+               zlog_err("%s:%u zebra_vrf_table() returned NULL",
+                        __func__, vrf_id);
                return;
        }
 
@@ -2339,8 +2352,8 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
                        continue;
                if (same->instance != re->instance)
                        continue;
-               if (same->type == ZEBRA_ROUTE_KERNEL &&
-                   same->metric != re->metric)
+               if (same->type == ZEBRA_ROUTE_KERNEL
+                   && same->metric != re->metric)
                        continue;
                /*
                 * We should allow duplicate connected routes because of
@@ -2352,7 +2365,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
 
        /* If this route is kernel route, set FIB flag to the route. */
        if (RIB_SYSTEM_ROUTE(re))
-               for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
+               for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
 
        /* Link new re to node.*/
@@ -2379,9 +2392,9 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
 }
 
 void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
-               u_short instance, int flags, struct prefix *p,
+               unsigned short instance, int flags, struct prefix *p,
                struct prefix_ipv6 *src_p, const struct nexthop *nh,
-               u_int32_t table_id, u_int32_t metric, bool fromkernel,
+               uint32_t table_id, uint32_t metric, bool fromkernel,
                struct ethaddr *rmac)
 {
        struct route_table *table;
@@ -2436,10 +2449,9 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                        continue;
                if (re->instance != instance)
                        continue;
-               if (re->type == ZEBRA_ROUTE_KERNEL &&
-                   re->metric != metric)
+               if (re->type == ZEBRA_ROUTE_KERNEL && re->metric != metric)
                        continue;
-               if (re->type == ZEBRA_ROUTE_CONNECT && (rtnh = re->nexthop)
+               if (re->type == ZEBRA_ROUTE_CONNECT && (rtnh = re->ng.nexthop)
                    && rtnh->type == NEXTHOP_TYPE_IFINDEX && nh) {
                        if (rtnh->ifindex != nh->ifindex)
                                continue;
@@ -2452,7 +2464,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                                same = re;
                                break;
                        }
-                       for (ALL_NEXTHOPS(re->nexthop, rtnh))
+                       for (ALL_NEXTHOPS(re->ng, rtnh))
                                if (nexthop_same_no_recurse(rtnh, nh)) {
                                        same = re;
                                        break;
@@ -2479,8 +2491,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                 * If we can show that this code path is
                 * dead then we can remove it.
                 */
-               if (fib && type == ZEBRA_ROUTE_KERNEL
-                   && CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)) {
+               if (fib && CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)) {
                        if (IS_ZEBRA_DEBUG_RIB) {
                                rnode_debug(
                                        rn, vrf_id,
@@ -2489,7 +2500,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                        }
                        if (allow_delete) {
                                /* Unset flags. */
-                               for (rtnh = fib->nexthop; rtnh;
+                               for (rtnh = fib->ng.nexthop; rtnh;
                                     rtnh = rtnh->next)
                                        UNSET_FLAG(rtnh->flags,
                                                   NEXTHOP_FLAG_FIB);
@@ -2532,9 +2543,8 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
        }
 
        if (same) {
-               if (fromkernel &&
-                   CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE) &&
-                   !allow_delete) {
+               if (fromkernel && CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)
+                   && !allow_delete) {
                        rib_install_kernel(rn, same, NULL);
                        route_unlock_node(rn);
 
@@ -2544,14 +2554,21 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                if (CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE)) {
                        struct nexthop *tmp_nh;
 
-                       for (ALL_NEXTHOPS(re->nexthop, tmp_nh)) {
+                       for (ALL_NEXTHOPS(re->ng, tmp_nh)) {
                                struct ipaddr vtep_ip;
 
                                memset(&vtep_ip, 0, sizeof(struct ipaddr));
-                               vtep_ip.ipa_type = IPADDR_V4;
-                               memcpy(&(vtep_ip.ipaddr_v4),
-                                      &(tmp_nh->gate.ipv4),
-                                      sizeof(struct in_addr));
+                               if (afi == AFI_IP) {
+                                       vtep_ip.ipa_type = IPADDR_V4;
+                                       memcpy(&(vtep_ip.ipaddr_v4),
+                                              &(tmp_nh->gate.ipv4),
+                                              sizeof(struct in_addr));
+                               } else {
+                                       vtep_ip.ipa_type = IPADDR_V6;
+                                       memcpy(&(vtep_ip.ipaddr_v6),
+                                              &(tmp_nh->gate.ipv6),
+                                              sizeof(struct in6_addr));
+                               }
                                zebra_vxlan_evpn_vrf_route_del(re->vrf_id, rmac,
                                                               &vtep_ip, p);
                        }
@@ -2564,10 +2581,11 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
 }
 
 
-int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
-           int flags, struct prefix *p, struct prefix_ipv6 *src_p,
-           const struct nexthop *nh, u_int32_t table_id, u_int32_t metric,
-           u_int32_t mtu, uint8_t distance, route_tag_t tag)
+int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
+           unsigned short instance, int flags, struct prefix *p,
+           struct prefix_ipv6 *src_p, const struct nexthop *nh,
+           uint32_t table_id, uint32_t metric, uint32_t mtu, uint8_t distance,
+           route_tag_t tag)
 {
        struct route_entry *re;
        struct nexthop *nexthop;
@@ -2610,9 +2628,8 @@ static void rib_update_table(struct route_table *table,
                 * has already been queued  we don't
                 * need to queue it up again
                 */
-               if (rn->info
-                   && CHECK_FLAG(rib_dest_from_rnode(rn)->flags,
-                                 RIB_ROUTE_ANY_QUEUED))
+               if (rn->info && CHECK_FLAG(rib_dest_from_rnode(rn)->flags,
+                                          RIB_ROUTE_ANY_QUEUED))
                        continue;
                switch (event) {
                case RIB_UPDATE_IF_CHANGE:
@@ -2629,10 +2646,10 @@ static void rib_update_table(struct route_table *table,
                        RNODE_FOREACH_RE_SAFE (rn, re, next) {
                                struct nexthop *nh;
 
-                               if (re->type != ZEBRA_ROUTE_SYSTEM &&
-                                   re->type != ZEBRA_ROUTE_KERNEL &&
-                                   re->type != ZEBRA_ROUTE_CONNECT &&
-                                   re->type != ZEBRA_ROUTE_STATIC)
+                               if (re->type != ZEBRA_ROUTE_SYSTEM
+                                   && re->type != ZEBRA_ROUTE_KERNEL
+                                   && re->type != ZEBRA_ROUTE_CONNECT
+                                   && re->type != ZEBRA_ROUTE_STATIC)
                                        continue;
 
                                if (re->type != ZEBRA_ROUTE_STATIC) {
@@ -2640,7 +2657,7 @@ static void rib_update_table(struct route_table *table,
                                        continue;
                                }
 
-                               for (nh = re->nexthop; nh; nh = nh->next)
+                               for (nh = re->ng.nexthop; nh; nh = nh->next)
                                        if (!(nh->type == NEXTHOP_TYPE_IPV4
                                              || nh->type == NEXTHOP_TYPE_IPV6))
                                                break;
@@ -2685,40 +2702,8 @@ void rib_update(vrf_id_t vrf_id, rib_update_event_t event)
                rib_update_table(table, event);
 }
 
-/* Remove all routes which comes from non main table.  */
-static void rib_weed_table(struct route_table *table)
-{
-       struct route_node *rn;
-       struct route_entry *re;
-       struct route_entry *next;
-
-       if (table)
-               for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
-                       RNODE_FOREACH_RE_SAFE (rn, re, next) {
-                               if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
-                                       continue;
-
-                               if (re->table != zebrad.rtm_table_default
-                                   && re->table != RT_TABLE_MAIN)
-                                       rib_delnode(rn, re);
-                       }
-}
-
-/* Delete all routes from non main table. */
-void rib_weed_tables(void)
-{
-       struct vrf *vrf;
-       struct zebra_vrf *zvrf;
-
-       RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
-               if ((zvrf = vrf->info) != NULL) {
-                       rib_weed_table(zvrf->table[AFI_IP][SAFI_UNICAST]);
-                       rib_weed_table(zvrf->table[AFI_IP6][SAFI_UNICAST]);
-               }
-}
-
 /* Delete self installed routes after zebra is relaunched.  */
-static void rib_sweep_table(struct route_table *table)
+void rib_sweep_table(struct route_table *table)
 {
        struct route_node *rn;
        struct route_entry *re;
@@ -2757,7 +2742,7 @@ static void rib_sweep_table(struct route_table *table)
                         * to a different spot (ie startup )
                         * this decision needs to be revisited
                         */
-                       for (ALL_NEXTHOPS(re->nexthop, nexthop))
+                       for (ALL_NEXTHOPS(re->ng, nexthop))
                                SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
 
                        rib_uninstall_kernel(rn, re);
@@ -2779,11 +2764,13 @@ void rib_sweep_route(void)
                rib_sweep_table(zvrf->table[AFI_IP][SAFI_UNICAST]);
                rib_sweep_table(zvrf->table[AFI_IP6][SAFI_UNICAST]);
        }
+
+       zebra_ns_sweep_route();
 }
 
 /* Remove specific by protocol routes from 'table'. */
-static unsigned long rib_score_proto_table(u_char proto, u_short instance,
-                                          struct route_table *table)
+unsigned long rib_score_proto_table(uint8_t proto, unsigned short instance,
+                                   struct route_table *table)
 {
        struct route_node *rn;
        struct route_entry *re;
@@ -2805,7 +2792,7 @@ static unsigned long rib_score_proto_table(u_char proto, u_short instance,
 }
 
 /* Remove specific by protocol routes. */
-unsigned long rib_score_proto(u_char proto, u_short instance)
+unsigned long rib_score_proto(uint8_t proto, unsigned short instance)
 {
        struct vrf *vrf;
        struct zebra_vrf *zvrf;
@@ -2820,6 +2807,8 @@ unsigned long rib_score_proto(u_char proto, u_short instance)
                                         proto, instance,
                                         zvrf->table[AFI_IP6][SAFI_UNICAST]);
 
+       cnt += zebra_ns_score_proto(proto, instance);
+
        return cnt;
 }