FIB table add/delete API
[vpp.git] / src / vnet / fib / fib_test.c
index d3bdfa3..572d7f0 100644 (file)
@@ -25,7 +25,7 @@
 #include <vnet/dpo/receive_dpo.h>
 #include <vnet/dpo/ip_null_dpo.h>
 #include <vnet/bfd/bfd_main.h>
-#include <vnet/dpo/interface_dpo.h>
+#include <vnet/dpo/interface_rx_dpo.h>
 #include <vnet/dpo/replicate_dpo.h>
 
 #include <vnet/mpls/mpls.h>
@@ -407,7 +407,7 @@ fib_test_validate_rep_v (const replicate_t *rep,
            }
            break;
        case FT_REP_INTF:
-            FIB_TEST_LB((DPO_INTERFACE == dpo->dpoi_type),
+            FIB_TEST_LB((DPO_INTERFACE_RX == dpo->dpoi_type),
                         "bucket %d stacks on %U",
                         bucket,
                         format_dpo_type, dpo->dpoi_type);
@@ -589,7 +589,7 @@ fib_test_validate_lb_v (const load_balance_t *lb,
                        exp->adj.adj);
            break;
        case FT_LB_INTF:
-           FIB_TEST_I((DPO_INTERFACE == dpo->dpoi_type),
+           FIB_TEST_I((DPO_INTERFACE_RX == dpo->dpoi_type),
                       "bucket %d stacks on %U",
                       bucket,
                       format_dpo_type, dpo->dpoi_type);
@@ -604,9 +604,10 @@ fib_test_validate_lb_v (const load_balance_t *lb,
                        bucket,
                        format_dpo_type, dpo->dpoi_type);
            FIB_TEST_LB((exp->lb.lb == dpo->dpoi_index),
-                       "bucket %d stacks on lb %d",
+                       "bucket %d stacks on lb %d not %d",
                        bucket,
-                       exp->lb.lb);
+                       dpo->dpoi_index,
+                        exp->lb.lb);
            break;
        case FT_LB_SPECIAL:
            FIB_TEST_I((DPO_DROP == dpo->dpoi_type),
@@ -738,7 +739,8 @@ fib_test_v4 (void)
     lb_count = pool_elts(load_balance_pool);
 
     /* Find or create FIB table 11 */
-    fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11);
+    fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11,
+                                                  FIB_SOURCE_API);
 
     for (ii = 0; ii < 4; ii++)
     {
@@ -832,7 +834,7 @@ fib_test_v4 (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_ATTACHED),
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -846,7 +848,8 @@ fib_test_v4 (void)
             "Flags set on attached interface");
 
     ai = fib_entry_get_adj(fei);
-    FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "attached interface route adj present");
+    FIB_TEST((FIB_NODE_INDEX_INVALID != ai),
+             "attached interface route adj present %d", ai);
     adj = adj_get(ai);
     FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
             "attached interface adj is glean");
@@ -859,7 +862,7 @@ fib_test_v4 (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_LOCAL),
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -909,7 +912,7 @@ fib_test_v4 (void)
     fib_table_entry_path_add(fib_index, &pfx,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_1,
                             tm->hw[0]->sw_if_index,
                             ~0, // invalid fib index
@@ -961,7 +964,7 @@ fib_test_v4 (void)
     pfx.fp_len = 0;
     fib_table_entry_path_remove(fib_index, &pfx,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_1,
                                tm->hw[0]->sw_if_index,
                                ~0, // non-recursive path, so no FIB index
@@ -1027,7 +1030,7 @@ fib_test_v4 (void)
                                           &pfx_11_11_11_11_s_32,
                                           FIB_SOURCE_API,
                                           FIB_ENTRY_FLAG_ATTACHED,
-                                         FIB_PROTOCOL_IP4,
+                                         DPO_PROTO_IP4,
                                           &pfx_10_10_10_1_s_32.fp_addr,
                                           tm->hw[0]->sw_if_index,
                                           ~0, // invalid fib index
@@ -1089,26 +1092,26 @@ fib_test_v4 (void)
     /*
      * add the adj fib
      */
-    fei = fib_table_entry_update_one_path(fib_index,
-                                          &pfx_10_10_10_1_s_32,
-                                          FIB_SOURCE_ADJ,
-                                          FIB_ENTRY_FLAG_ATTACHED,
-                                         FIB_PROTOCOL_IP4,
-                                          &pfx_10_10_10_1_s_32.fp_addr,
-                                          tm->hw[0]->sw_if_index,
-                                          ~0, // invalid fib index
-                                          1,
-                                          NULL,
-                                          FIB_ROUTE_PATH_FLAG_NONE);
+    fei = fib_table_entry_path_add(fib_index,
+                                   &pfx_10_10_10_1_s_32,
+                                   FIB_SOURCE_ADJ,
+                                   FIB_ENTRY_FLAG_ATTACHED,
+                                   DPO_PROTO_IP4,
+                                   &pfx_10_10_10_1_s_32.fp_addr,
+                                   tm->hw[0]->sw_if_index,
+                                   ~0, // invalid fib index
+                                   1,
+                                   NULL,
+                                   FIB_ROUTE_PATH_FLAG_NONE);
     FIB_TEST((FIB_ENTRY_FLAG_ATTACHED  == fib_entry_get_flags(fei)),
             "Flags set on adj-fib");
     ai = fib_entry_get_adj(fei);
-    FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
+    FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj, %d", ai);
 
     fib_table_entry_path_remove(fib_index,
                                 &pfx_11_11_11_11_s_32,
                                 FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                 &pfx_10_10_10_1_s_32.fp_addr,
                                 tm->hw[0]->sw_if_index,
                                 ~0, // invalid fib index
@@ -1138,17 +1141,17 @@ fib_test_v4 (void)
              "adj nbr next-hop ok");
     FIB_TEST((ai_01 != ai_02), "ADJs are different");
 
-    fib_table_entry_update_one_path(fib_index,
-                                   &pfx_10_10_10_2_s_32,
-                                   FIB_SOURCE_ADJ,
-                                   FIB_ENTRY_FLAG_ATTACHED,
-                                   FIB_PROTOCOL_IP4,
-                                   &pfx_10_10_10_2_s_32.fp_addr,
-                                   tm->hw[0]->sw_if_index,
-                                   ~0, // invalid fib index
-                                   1,
-                                   NULL,
-                                   FIB_ROUTE_PATH_FLAG_NONE);
+    fib_table_entry_path_add(fib_index,
+                             &pfx_10_10_10_2_s_32,
+                             FIB_SOURCE_ADJ,
+                             FIB_ENTRY_FLAG_ATTACHED,
+                             DPO_PROTO_IP4,
+                             &pfx_10_10_10_2_s_32.fp_addr,
+                             tm->hw[0]->sw_if_index,
+                             ~0, // invalid fib index
+                             1,
+                             NULL,
+                             FIB_ROUTE_PATH_FLAG_NONE);
 
     fei = fib_table_lookup(fib_index, &pfx_10_10_10_2_s_32);
     ai = fib_entry_get_adj(fei);
@@ -1179,7 +1182,7 @@ fib_test_v4 (void)
                             &pfx_1_1_1_1_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_1,
                             tm->hw[0]->sw_if_index,
                             ~0, // invalid fib index
@@ -1212,7 +1215,7 @@ fib_test_v4 (void)
                             &pfx_1_1_2_0_s_24,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_1,
                             tm->hw[0]->sw_if_index,
                             ~0, // invalid fib index
@@ -1239,7 +1242,7 @@ fib_test_v4 (void)
                             &pfx_1_1_2_0_s_24,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_2,
                             tm->hw[0]->sw_if_index,
                             ~0, // invalid fib index
@@ -1278,7 +1281,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_1_1_2_0_s_24,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_2,
                                tm->hw[0]->sw_if_index,
                                ~0,
@@ -1325,7 +1328,7 @@ fib_test_v4 (void)
                                   &bgp_100_pfx,
                                   FIB_SOURCE_API,
                                   FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                   &nh_1_1_1_1,
                                   ~0, // no index provided.
                                   fib_index, // nexthop in same fib as route
@@ -1361,7 +1364,7 @@ fib_test_v4 (void)
                             &bgp_101_pfx,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_1_1_1_1,
                             ~0, // no index provided.
                             fib_index, // nexthop in same fib as route
@@ -1481,19 +1484,20 @@ fib_test_v4 (void)
        },
     };
 
-    fib_table_entry_path_add(fib_index,
-                            &bgp_200_pfx,
-                            FIB_SOURCE_API,
-                            FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
-                            &pfx_1_1_1_2_s_32.fp_addr,
-                            ~0, // no index provided.
-                            fib_index, // nexthop in same fib as route
-                            1,
-                            NULL,
-                            FIB_ROUTE_PATH_FLAG_NONE);
+    fei = fib_table_entry_path_add(fib_index,
+                                   &bgp_200_pfx,
+                                   FIB_SOURCE_API,
+                                   FIB_ENTRY_FLAG_NONE,
+                                   DPO_PROTO_IP4,
+                                   &pfx_1_1_1_2_s_32.fp_addr,
+                                   ~0, // no index provided.
+                                   fib_index, // nexthop in same fib as route
+                                   1,
+                                   NULL,
+                                   FIB_ROUTE_PATH_FLAG_NONE);
 
-    FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
+    FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
+             "Recursive via unresolved is drop");
 
     /*
      * the adj should be recursive via drop, since the route resolves via
@@ -1531,7 +1535,7 @@ fib_test_v4 (void)
                             &pfx_1_2_3_4_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                              &nh_10_10_10_1,
                              tm->hw[0]->sw_if_index,
                              ~0,
@@ -1542,7 +1546,7 @@ fib_test_v4 (void)
                                    &pfx_1_2_3_4_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                    &nh_12_12_12_12,
                                    tm->hw[1]->sw_if_index,
                                    ~0,
@@ -1583,7 +1587,7 @@ fib_test_v4 (void)
                             &pfx_1_2_3_5_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                              &nh_12_12_12_12,
                              tm->hw[1]->sw_if_index,
                              ~0,
@@ -1594,7 +1598,7 @@ fib_test_v4 (void)
                                    &pfx_1_2_3_5_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                    &nh_10_10_10_1,
                                    tm->hw[0]->sw_if_index,
                                    ~0,
@@ -1644,13 +1648,13 @@ fib_test_v4 (void)
            .ip4.as_u32 = clib_host_to_net_u32(0x06060606),
        },
     };
-    fib_test_lb_bucket_t ip_6_6_6_6_o_10_10_10_1 = {
+    fib_test_lb_bucket_t ip_o_10_10_10_1 = {
        .type = FT_LB_ADJ,
        .adj = {
            .adj = ai_01,
        },
     };
-    fib_test_lb_bucket_t ip_6_6_6_6_o_10_10_10_2 = {
+    fib_test_lb_bucket_t ip_o_10_10_10_2 = {
         .type = FT_LB_ADJ,
         .adj = {
             .adj = ai_02,
@@ -1666,7 +1670,7 @@ fib_test_v4 (void)
                                    &pfx_6_6_6_6_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &nh_10_10_10_1,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -1678,14 +1682,14 @@ fib_test_v4 (void)
     FIB_TEST(fib_test_validate_entry(fei,
                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
                                     1,
-                                    &ip_6_6_6_6_o_10_10_10_1),
+                                    &ip_o_10_10_10_1),
             "6.6.6.6/32 via 10.10.10.1");
 
     fib_table_entry_path_add(fib_index,
                              &pfx_6_6_6_6_s_32,
                              FIB_SOURCE_API,
                              FIB_ENTRY_FLAG_NONE,
-                             FIB_PROTOCOL_IP4,
+                             DPO_PROTO_IP4,
                              &nh_10_10_10_2,
                              tm->hw[0]->sw_if_index,
                              ~0, // invalid fib index
@@ -1697,77 +1701,77 @@ fib_test_v4 (void)
     FIB_TEST(fib_test_validate_entry(fei,
                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
                                     64,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_1),
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_1),
             "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
 
     fib_table_entry_path_add(fib_index,
                              &pfx_6_6_6_6_s_32,
                              FIB_SOURCE_API,
                              FIB_ENTRY_FLAG_NONE,
-                             FIB_PROTOCOL_IP4,
+                             DPO_PROTO_IP4,
                              &nh_12_12_12_12,
                              tm->hw[1]->sw_if_index,
                              ~0, // invalid fib index
@@ -1779,71 +1783,71 @@ fib_test_v4 (void)
     FIB_TEST(fib_test_validate_entry(fei,
                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
                                     128,
-                                    &ip_6_6_6_6_o_10_10_10_1,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
+                                    &ip_o_10_10_10_1,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
                                     &ip_6_6_6_6_o_12_12_12_12,
                                     &ip_6_6_6_6_o_12_12_12_12,
                                     &ip_6_6_6_6_o_12_12_12_12,
@@ -1912,7 +1916,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                 &pfx_6_6_6_6_s_32,
                                 FIB_SOURCE_API,
-                                FIB_PROTOCOL_IP4,
+                                DPO_PROTO_IP4,
                                 &nh_12_12_12_12,
                                 tm->hw[1]->sw_if_index,
                                 ~0, // invalid fib index
@@ -1923,76 +1927,76 @@ fib_test_v4 (void)
     FIB_TEST(fib_test_validate_entry(fei,
                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
                                     64,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_2,
-                                    &ip_6_6_6_6_o_10_10_10_1),
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_2,
+                                    &ip_o_10_10_10_1),
             "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
 
     fib_table_entry_path_remove(fib_index,
                                 &pfx_6_6_6_6_s_32,
                                 FIB_SOURCE_API,
-                                FIB_PROTOCOL_IP4,
+                                DPO_PROTO_IP4,
                                 &nh_10_10_10_2,
                                 tm->hw[0]->sw_if_index,
                                 ~0, // invalid fib index
@@ -2003,7 +2007,7 @@ fib_test_v4 (void)
     FIB_TEST(fib_test_validate_entry(fei,
                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
                                     1,
-                                    &ip_6_6_6_6_o_10_10_10_1),
+                                    &ip_o_10_10_10_1),
             "6.6.6.6/32 via 10.10.10.1");
 
     fib_table_entry_delete(fib_index, &pfx_6_6_6_6_s_32, FIB_SOURCE_API);
@@ -2023,7 +2027,7 @@ fib_test_v4 (void)
                                    &bgp_44_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                   &pfx_1_2_3_4_s_32.fp_addr,
                                    ~0,
                                    fib_index,
@@ -2034,7 +2038,7 @@ fib_test_v4 (void)
                                    &bgp_44_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                   &pfx_1_2_3_5_s_32.fp_addr,
                                    ~0,
                                    fib_index,
@@ -2100,19 +2104,20 @@ fib_test_v4 (void)
        },
     };
 
-    fib_table_entry_path_add(fib_index,
-                            &bgp_201_pfx,
-                            FIB_SOURCE_API,
-                            FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
-                            &pfx_1_1_1_200_s_32.fp_addr,
-                            ~0, // no index provided.
-                            fib_index, // nexthop in same fib as route
-                            1,
-                            NULL,
-                            FIB_ROUTE_PATH_FLAG_NONE);
+    fei = fib_table_entry_path_add(fib_index,
+                                   &bgp_201_pfx,
+                                   FIB_SOURCE_API,
+                                   FIB_ENTRY_FLAG_NONE,
+                                   DPO_PROTO_IP4,
+                                   &pfx_1_1_1_200_s_32.fp_addr,
+                                   ~0, // no index provided.
+                                   fib_index, // nexthop in same fib as route
+                                   1,
+                                   NULL,
+                                   FIB_ROUTE_PATH_FLAG_NONE);
 
-    FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
+    FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
+             "Recursive via unresolved is drop");
 
     fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
     FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
@@ -2147,7 +2152,7 @@ fib_test_v4 (void)
                             &pfx_1_1_1_0_s_24,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_1,
                             tm->hw[0]->sw_if_index,
                             ~0, // invalid fib index
@@ -2205,7 +2210,7 @@ fib_test_v4 (void)
                             &pfx_1_1_1_0_s_28,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_2,
                             tm->hw[0]->sw_if_index,
                             ~0, // invalid fib index
@@ -2240,7 +2245,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_1_1_1_0_s_28,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_2,
                                tm->hw[0]->sw_if_index,
                                ~0,
@@ -2271,7 +2276,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_1_1_1_0_s_24,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_1,
                                tm->hw[0]->sw_if_index,
                                ~0,
@@ -2284,12 +2289,16 @@ fib_test_v4 (void)
     fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
     FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
             "1.1.1.2/32 route is DROP");
-    fei = fib_table_lookup(fib_index, &pfx_1_1_1_200_s_32);
+    fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
     FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
             "1.1.1.200/32 route is DROP");
 
-    FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
-    FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
+    fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
+    FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
+             "201 is drop");
+    fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
+    FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
+             "200 is drop");
 
     /*
      * -1 entry
@@ -2308,7 +2317,7 @@ fib_test_v4 (void)
                                   &pfx_1_1_1_2_s_32,
                                   FIB_SOURCE_API,
                                   FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                   &nh_10_10_10_1,
                                   tm->hw[0]->sw_if_index,
                                   ~0, // invalid fib index
@@ -2319,7 +2328,9 @@ fib_test_v4 (void)
     ai = fib_entry_get_adj(fei);
     FIB_TEST((ai = ai_01), "1.1.1.2/32 resolves via 10.10.10.1");
 
-    FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
+    fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
+    FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
+             "201 is drop");
     FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
 
     /*
@@ -2332,13 +2343,40 @@ fib_test_v4 (void)
     FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
             fib_entry_pool_size());
 
+    /*
+     * give 201 a resolved path.
+     *  it now has the unresolved 1.1.1.200 and the resolved 1.1.1.2,
+     *  only the latter contributes forwarding.
+     */
+    fei = fib_table_entry_path_add(fib_index,
+                                   &bgp_201_pfx,
+                                   FIB_SOURCE_API,
+                                   FIB_ENTRY_FLAG_NONE,
+                                   DPO_PROTO_IP4,
+                                   &pfx_1_1_1_2_s_32.fp_addr,
+                                   ~0,
+                                   fib_index,
+                                   1,
+                                   NULL,
+                                   FIB_ROUTE_PATH_FLAG_NONE);
+    FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_2_s_32, 0);
+    fib_table_entry_path_remove(fib_index,
+                                &bgp_201_pfx,
+                                FIB_SOURCE_API,
+                                DPO_PROTO_IP4,
+                                &pfx_1_1_1_2_s_32.fp_addr,
+                                ~0,
+                                fib_index,
+                                1,
+                                FIB_ROUTE_PATH_FLAG_NONE);
+
     /*
      * remove 200.200.200.201/32 which does not have a valid via FIB
      */
     fib_table_entry_path_remove(fib_index,
                                &bgp_201_pfx,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &pfx_1_1_1_200_s_32.fp_addr,
                                ~0, // no index provided.
                                fib_index,
@@ -2368,7 +2406,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &bgp_200_pfx,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &pfx_1_1_1_2_s_32.fp_addr,
                                ~0, // no index provided.
                                fib_index,
@@ -2409,7 +2447,7 @@ fib_test_v4 (void)
                             &bgp_102,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &pfx_1_1_1_1_s_32.fp_addr,
                             ~0, // no index provided.
                             fib_index, // same as route
@@ -2420,7 +2458,7 @@ fib_test_v4 (void)
                             &bgp_102,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &pfx_1_1_1_2_s_32.fp_addr,
                             ~0, // no index provided.
                             fib_index, // same as route's FIB
@@ -2446,7 +2484,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &bgp_102,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &pfx_1_1_1_1_s_32.fp_addr,
                                ~0, // no index provided.
                                fib_index, // same as route's FIB
@@ -2455,7 +2493,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &bgp_102,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &pfx_1_1_1_2_s_32.fp_addr,
                                ~0, // no index provided.
                                fib_index, // same as route's FIB
@@ -2470,7 +2508,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &bgp_100_pfx,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &pfx_1_1_1_1_s_32.fp_addr,
                                ~0, // no index provided.
                                fib_index, // same as route's FIB
@@ -2479,7 +2517,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &bgp_101_pfx,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &pfx_1_1_1_1_s_32.fp_addr,
                                ~0, // no index provided.
                                fib_index, // same as route's FIB
@@ -2509,7 +2547,7 @@ fib_test_v4 (void)
                             &bgp_200_pfx,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_1,
                             ~0, // no index provided.
                             fib_index, // Same as route's FIB
@@ -2556,7 +2594,7 @@ fib_test_v4 (void)
                             &bgp_201_pfx,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_3,
                             ~0, // no index provided.
                             fib_index,
@@ -2602,7 +2640,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &bgp_200_pfx,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_1,
                                ~0, // no index provided.
                                fib_index, // same as route's FIB
@@ -2611,7 +2649,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &bgp_201_pfx,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_3,
                                ~0, // no index provided.
                                fib_index, // same as route's FIB
@@ -2670,7 +2708,7 @@ fib_test_v4 (void)
                             &pfx_5_5_5_5_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &pfx_5_5_5_6_s_32.fp_addr,
                             ~0, // no index provided.
                             fib_index,
@@ -2681,7 +2719,7 @@ fib_test_v4 (void)
                             &pfx_5_5_5_6_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &pfx_5_5_5_7_s_32.fp_addr,
                             ~0, // no index provided.
                             fib_index,
@@ -2692,7 +2730,7 @@ fib_test_v4 (void)
                             &pfx_5_5_5_7_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &pfx_5_5_5_5_s_32.fp_addr,
                             ~0, // no index provided.
                             fib_index,
@@ -2731,7 +2769,7 @@ fib_test_v4 (void)
                             &pfx_5_5_5_6_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_1,
                             tm->hw[0]->sw_if_index,
                             ~0,
@@ -2764,7 +2802,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_5_5_5_6_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_1,
                                tm->hw[0]->sw_if_index,
                                ~0,
@@ -2789,7 +2827,7 @@ fib_test_v4 (void)
                                    &pfx_5_5_5_5_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &nh_10_10_10_1,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -2831,7 +2869,7 @@ fib_test_v4 (void)
                                    &pfx_5_5_5_5_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &pfx_5_5_5_6_s_32.fp_addr,
                                    ~0, // no index provided.
                                    fib_index,
@@ -2855,7 +2893,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_5_5_5_5_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &pfx_5_5_5_6_s_32.fp_addr,
                                ~0, // no index provided.
                                fib_index, // same as route's FIB
@@ -2864,7 +2902,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_5_5_5_6_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &pfx_5_5_5_7_s_32.fp_addr,
                                ~0, // no index provided.
                                fib_index, // same as route's FIB
@@ -2873,7 +2911,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_5_5_5_7_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &pfx_5_5_5_5_s_32.fp_addr,
                                ~0, // no index provided.
                                fib_index, // same as route's FIB
@@ -2882,7 +2920,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_5_5_5_6_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_2,
                                ~0, // no index provided.
                                fib_index, // same as route's FIB
@@ -2906,7 +2944,7 @@ fib_test_v4 (void)
                             &pfx_5_5_5_6_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &pfx_5_5_5_6_s_32.fp_addr,
                             ~0, // no index provided.
                             fib_index,
@@ -2920,7 +2958,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_5_5_5_6_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &pfx_5_5_5_6_s_32.fp_addr,
                                ~0, // no index provided.
                                fib_index, // same as route's FIB
@@ -2954,7 +2992,7 @@ fib_test_v4 (void)
                                   &pfx_23_23_23_0_s_24,
                                   FIB_SOURCE_API,
                                   FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                   &pfx_23_23_23_23_s_32.fp_addr,
                                   ~0, // recursive
                                   fib_index,
@@ -2976,6 +3014,36 @@ fib_test_v4 (void)
     FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
             fib_entry_pool_size());
 
+    /*
+     * Make the default route recursive via a unknown next-hop. Thus the
+     * next hop's cover would be the default route
+     */
+    fei = fib_table_entry_path_add(fib_index,
+                                  &pfx_0_0_0_0_s_0,
+                                  FIB_SOURCE_API,
+                                  FIB_ENTRY_FLAG_NONE,
+                                  DPO_PROTO_IP4,
+                                  &pfx_23_23_23_23_s_32.fp_addr,
+                                  ~0, // recursive
+                                  fib_index,
+                                  1,
+                                  NULL,
+                                  FIB_ROUTE_PATH_FLAG_NONE);
+    dpo = fib_entry_contribute_ip_forwarding(fei);
+    FIB_TEST(load_balance_is_drop(dpo),
+            "0.0.0.0.0/0 via is DROP");
+    FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
+             "no resolving interface for looped 0.0.0.0/0");
+
+    fei = fib_table_lookup_exact_match(fib_index, &pfx_23_23_23_23_s_32);
+    dpo = fib_entry_contribute_ip_forwarding(fei);
+    FIB_TEST(load_balance_is_drop(dpo),
+            "23.23.23.23/32 via is DROP");
+    FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
+             "no resolving interface for looped 23.23.23.23/32");
+
+    fib_table_entry_delete(fib_index, &pfx_0_0_0_0_s_0, FIB_SOURCE_API);
+
     /*
      * A recursive route with recursion constraints.
      *  200.200.200.200/32 via 1.1.1.1 is recurse via host constrained
@@ -2984,7 +3052,7 @@ fib_test_v4 (void)
                             &bgp_200_pfx,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_1_1_1_1,
                             ~0,
                             fib_index,
@@ -3014,7 +3082,7 @@ fib_test_v4 (void)
                             &pfx_1_1_1_0_s_28,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_1,
                             tm->hw[0]->sw_if_index,
                             ~0, // invalid fib index
@@ -3032,7 +3100,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_1_1_1_1_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_1,
                                tm->hw[0]->sw_if_index,
                                ~0, // invalid fib index
@@ -3049,7 +3117,7 @@ fib_test_v4 (void)
                             &pfx_1_1_1_1_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_1,
                             tm->hw[0]->sw_if_index,
                             ~0, // invalid fib index
@@ -3073,7 +3141,7 @@ fib_test_v4 (void)
                             &pfx_1_1_1_3_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_2,
                             tm->hw[0]->sw_if_index,
                             ~0, // invalid fib index
@@ -3085,7 +3153,7 @@ fib_test_v4 (void)
                             &bgp_200_pfx,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &pfx_1_1_1_3_s_32.fp_addr,
                             ~0,
                             fib_index,
@@ -3110,7 +3178,7 @@ fib_test_v4 (void)
                                  &bgp_78s[ii],
                                  FIB_SOURCE_API,
                                  FIB_ENTRY_FLAG_NONE,
-                                 FIB_PROTOCOL_IP4,
+                                 DPO_PROTO_IP4,
                                  &pfx_1_1_1_3_s_32.fp_addr,
                                  ~0,
                                  fib_index,
@@ -3121,7 +3189,7 @@ fib_test_v4 (void)
                                  &bgp_78s[ii],
                                  FIB_SOURCE_API,
                                  FIB_ENTRY_FLAG_NONE,
-                                 FIB_PROTOCOL_IP4,
+                                 DPO_PROTO_IP4,
                                  &nh_1_1_1_1,
                                  ~0,
                                  fib_index,
@@ -3171,7 +3239,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_1_1_1_1_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_1,
                                tm->hw[0]->sw_if_index,
                                ~0, // invalid fib index
@@ -3210,7 +3278,7 @@ fib_test_v4 (void)
                             &pfx_1_1_1_1_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_1,
                             tm->hw[0]->sw_if_index,
                             ~0, // invalid fib index
@@ -3240,7 +3308,7 @@ fib_test_v4 (void)
                             &bgp_200_pfx,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &pfx_1_1_1_2_s_32.fp_addr,
                             ~0,
                             fib_index,
@@ -3253,7 +3321,7 @@ fib_test_v4 (void)
                                  &bgp_78s[ii],
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &pfx_1_1_1_2_s_32.fp_addr,
                             ~0,
                             fib_index,
@@ -3287,7 +3355,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_1_1_1_1_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_1,
                                tm->hw[0]->sw_if_index,
                                ~0,
@@ -3324,7 +3392,7 @@ fib_test_v4 (void)
                              &pfx_1_1_1_1_s_32,
                              FIB_SOURCE_API,
                              FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                              &nh_10_10_10_1,
                              tm->hw[0]->sw_if_index,
                              ~0,
@@ -3345,7 +3413,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                 &bgp_200_pfx,
                                 FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                 &pfx_1_1_1_2_s_32.fp_addr,
                                 ~0,
                                 fib_index,
@@ -3354,7 +3422,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &bgp_200_pfx,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_1_1_1_1,
                                ~0,
                                fib_index,
@@ -3363,7 +3431,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &bgp_200_pfx,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &pfx_1_1_1_3_s_32.fp_addr,
                                ~0,
                                fib_index,
@@ -3414,7 +3482,7 @@ fib_test_v4 (void)
                             &pfx_4_4_4_4_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_1,
                             tm->hw[0]->sw_if_index,
                             ~0,
@@ -3425,7 +3493,7 @@ fib_test_v4 (void)
                             &pfx_4_4_4_4_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_2,
                             tm->hw[0]->sw_if_index,
                             ~0,
@@ -3436,7 +3504,7 @@ fib_test_v4 (void)
                             &pfx_4_4_4_4_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_3,
                             tm->hw[0]->sw_if_index,
                             ~0,
@@ -3472,7 +3540,7 @@ fib_test_v4 (void)
     for (ii = 0; ii < 4; ii++)
     {
        fib_route_path_t r_path = {
-           .frp_proto = FIB_PROTOCOL_IP4,
+           .frp_proto = DPO_PROTO_IP4,
            .frp_addr = {
                .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
            },
@@ -3521,7 +3589,7 @@ fib_test_v4 (void)
                             &pfx_4_4_4_4_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &zero_addr,
                             ~0,
                             fib_index,
@@ -3577,11 +3645,22 @@ fib_test_v4 (void)
            .ip4.as_u32 = clib_host_to_net_u32(0x22220101),
        },
     };
+    fei = fib_table_entry_path_add(fib_index,
+                                   &pfx_34_34_1_1_s_32,
+                                   FIB_SOURCE_API,
+                                   FIB_ENTRY_FLAG_NONE,
+                                   DPO_PROTO_IP4,
+                                   &nh_10_10_10_1,
+                                   tm->hw[0]->sw_if_index,
+                                   0,
+                                   1,
+                                   NULL,
+                                   FIB_ROUTE_PATH_FLAG_NONE);
     fei = fib_table_entry_path_add(fib_index,
                                    &pfx_34_1_1_1_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &pfx_34_34_1_1_s_32.fp_addr,
                                    ~0,
                                    fib_index,
@@ -3592,7 +3671,7 @@ fib_test_v4 (void)
                                    &pfx_34_1_1_1_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &pfx_34_34_1_1_s_32.fp_addr,
                                    ~0,
                                    fib_index,
@@ -3601,6 +3680,9 @@ fib_test_v4 (void)
                                    FIB_ROUTE_PATH_FLAG_NONE);
     FIB_TEST_REC_FORW(&pfx_34_1_1_1_s_32, &pfx_34_34_1_1_s_32, 0);
     fib_table_entry_delete_index(fei, FIB_SOURCE_API);
+    fib_table_entry_delete(fib_index,
+                           &pfx_34_34_1_1_s_32,
+                           FIB_SOURCE_API);
 
     /*
      * CLEANUP
@@ -3610,7 +3692,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_1_1_1_2_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_1,
                                tm->hw[0]->sw_if_index,
                                ~0,
@@ -3619,7 +3701,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_1_1_1_1_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_1,
                                tm->hw[0]->sw_if_index,
                                ~0,
@@ -3628,7 +3710,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_1_1_2_0_s_24,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_1,
                                tm->hw[0]->sw_if_index,
                                ~0,
@@ -3670,7 +3752,7 @@ fib_test_v4 (void)
                             &pfx_4_1_1_1_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &zero_addr,
                             tm->hw[0]->sw_if_index,
                             fib_index,
@@ -3724,7 +3806,7 @@ fib_test_v4 (void)
                                   &pfx_2001_s_64,
                                   FIB_SOURCE_API,
                                   FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                   &nh_10_10_10_1,
                                   tm->hw[0]->sw_if_index,
                                   fib_index,
@@ -3778,17 +3860,17 @@ fib_test_v4 (void)
        },
     };
 
-    fib_table_entry_update_one_path(fib_index,
-                                   &pfx_12_10_10_2_s_32,
-                                   FIB_SOURCE_ADJ,
-                                   FIB_ENTRY_FLAG_ATTACHED,
-                                   FIB_PROTOCOL_IP4,
-                                   &pfx_12_10_10_2_s_32.fp_addr,
-                                   tm->hw[0]->sw_if_index,
-                                   ~0, // invalid fib index
-                                   1,
-                                   NULL,
-                                   FIB_ROUTE_PATH_FLAG_NONE);
+    fib_table_entry_path_add(fib_index,
+                             &pfx_12_10_10_2_s_32,
+                             FIB_SOURCE_ADJ,
+                             FIB_ENTRY_FLAG_ATTACHED,
+                             DPO_PROTO_IP4,
+                             &pfx_12_10_10_2_s_32.fp_addr,
+                             tm->hw[0]->sw_if_index,
+                             ~0, // invalid fib index
+                             1,
+                             NULL,
+                             FIB_ROUTE_PATH_FLAG_NONE);
 
     fei = fib_table_lookup_exact_match(fib_index, &pfx_12_10_10_2_s_32);
     dpo = fib_entry_contribute_ip_forwarding(fei);
@@ -3812,17 +3894,17 @@ fib_test_v4 (void)
        },
     };
 
-    fib_table_entry_update_one_path(fib_index,
-                                   &pfx_10_10_10_127_s_32,
-                                   FIB_SOURCE_ADJ,
-                                   FIB_ENTRY_FLAG_ATTACHED,
-                                   FIB_PROTOCOL_IP4,
-                                   &pfx_10_10_10_127_s_32.fp_addr,
-                                   tm->hw[1]->sw_if_index,
-                                   ~0, // invalid fib index
-                                   1,
-                                   NULL,
-                                   FIB_ROUTE_PATH_FLAG_NONE);
+    fib_table_entry_path_add(fib_index,
+                             &pfx_10_10_10_127_s_32,
+                             FIB_SOURCE_ADJ,
+                             FIB_ENTRY_FLAG_ATTACHED,
+                             DPO_PROTO_IP4,
+                             &pfx_10_10_10_127_s_32.fp_addr,
+                             tm->hw[1]->sw_if_index,
+                             ~0, // invalid fib index
+                             1,
+                             NULL,
+                             FIB_ROUTE_PATH_FLAG_NONE);
 
     fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_127_s_32);
     dpo = fib_entry_contribute_ip_forwarding(fei);
@@ -3833,6 +3915,157 @@ fib_test_v4 (void)
                           &pfx_10_10_10_127_s_32,
                           FIB_SOURCE_ADJ);
 
+    /*
+     * add a second path to an adj-fib
+     * this is a sumiluation of another ARP entry created
+     * on an interface on which the connected prefi does not exist.
+     * The second path fails refinement. Expect to forward through the
+     * first.
+     */
+    fib_prefix_t pfx_10_10_10_3_s_32 = {
+        .fp_len = 32,
+        .fp_proto = FIB_PROTOCOL_IP4,
+        .fp_addr = {
+            /* 10.10.10.3 */
+            .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
+        },
+    };
+
+    ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
+                                VNET_LINK_IP4,
+                                &nh_10_10_10_3,
+                                tm->hw[0]->sw_if_index);
+
+    fib_test_lb_bucket_t ip_o_10_10_10_3 = {
+        .type = FT_LB_ADJ,
+        .adj = {
+            .adj = ai_03,
+        },
+    };
+    fei = fib_table_entry_path_add(fib_index,
+                                   &pfx_10_10_10_3_s_32,
+                                   FIB_SOURCE_ADJ,
+                                   FIB_ENTRY_FLAG_NONE,
+                                   DPO_PROTO_IP4,
+                                   &nh_10_10_10_3,
+                                   tm->hw[0]->sw_if_index,
+                                   fib_index,
+                                   1,
+                                   NULL,
+                                   FIB_ROUTE_PATH_FLAG_NONE);
+    fei = fib_table_entry_path_add(fib_index,
+                                   &pfx_10_10_10_3_s_32,
+                                   FIB_SOURCE_ADJ,
+                                   FIB_ENTRY_FLAG_NONE,
+                                   DPO_PROTO_IP4,
+                                   &nh_12_12_12_12,
+                                   tm->hw[1]->sw_if_index,
+                                   fib_index,
+                                   1,
+                                   NULL,
+                                   FIB_ROUTE_PATH_FLAG_NONE);
+    FIB_TEST(fib_test_validate_entry(fei,
+                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                     1,
+                                     &ip_o_10_10_10_3),
+             "10.10.10.3 via 10.10.10.3/Eth0 only");
+
+    /*
+     * remove the path that refines the cover, should go unresolved
+     */
+    fib_table_entry_path_remove(fib_index,
+                                &pfx_10_10_10_3_s_32,
+                                FIB_SOURCE_ADJ,
+                                DPO_PROTO_IP4,
+                                &nh_10_10_10_3,
+                                tm->hw[0]->sw_if_index,
+                                fib_index,
+                                1,
+                                FIB_ROUTE_PATH_FLAG_NONE);
+    dpo = fib_entry_contribute_ip_forwarding(fei);
+    FIB_TEST(!dpo_id_is_valid(dpo),
+             "wrong interface adj-fib fails refinement");
+
+    /*
+     * add back the path that refines the cover
+     */
+    fei = fib_table_entry_path_add(fib_index,
+                                   &pfx_10_10_10_3_s_32,
+                                   FIB_SOURCE_ADJ,
+                                   FIB_ENTRY_FLAG_NONE,
+                                   DPO_PROTO_IP4,
+                                   &nh_10_10_10_3,
+                                   tm->hw[0]->sw_if_index,
+                                   fib_index,
+                                   1,
+                                   NULL,
+                                   FIB_ROUTE_PATH_FLAG_NONE);
+    FIB_TEST(fib_test_validate_entry(fei,
+                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                     1,
+                                     &ip_o_10_10_10_3),
+             "10.10.10.3 via 10.10.10.3/Eth0 only");
+
+    /*
+     * remove the path that does not refine the cover
+     */
+    fib_table_entry_path_remove(fib_index,
+                                &pfx_10_10_10_3_s_32,
+                                FIB_SOURCE_ADJ,
+                                DPO_PROTO_IP4,
+                                &nh_12_12_12_12,
+                                tm->hw[1]->sw_if_index,
+                                fib_index,
+                                1,
+                                FIB_ROUTE_PATH_FLAG_NONE);
+    FIB_TEST(fib_test_validate_entry(fei,
+                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                     1,
+                                     &ip_o_10_10_10_3),
+             "10.10.10.3 via 10.10.10.3/Eth0 only");
+
+    /*
+     * remove the path that does refine, it's the last path, so
+     * the entry should be gone
+     */
+    fib_table_entry_path_remove(fib_index,
+                                &pfx_10_10_10_3_s_32,
+                                FIB_SOURCE_ADJ,
+                                DPO_PROTO_IP4,
+                                &nh_10_10_10_3,
+                                tm->hw[0]->sw_if_index,
+                                fib_index,
+                                1,
+                                FIB_ROUTE_PATH_FLAG_NONE);
+    fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
+    FIB_TEST((fei == FIB_NODE_INDEX_INVALID), "10.10.10.3 gone");
+
+    adj_unlock(ai_03);
+
+    /*
+     * change the table's flow-hash config - expect the update to propagete to
+     * the entries' load-balance objects
+     */
+    flow_hash_config_t old_hash_config, new_hash_config;
+
+    old_hash_config = fib_table_get_flow_hash_config(fib_index,
+                                                     FIB_PROTOCOL_IP4);
+    new_hash_config = (IP_FLOW_HASH_SRC_ADDR |
+                       IP_FLOW_HASH_DST_ADDR);
+
+    fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
+    dpo = fib_entry_contribute_ip_forwarding(fei);
+    lb = load_balance_get(dpo->dpoi_index);
+    FIB_TEST((lb->lb_hash_config == old_hash_config),
+             "Table and LB hash config match: %U",
+             format_ip_flow_hash_config, lb->lb_hash_config);
+
+    fib_table_set_flow_hash_config(fib_index, FIB_PROTOCOL_IP4, new_hash_config);
+
+    FIB_TEST((lb->lb_hash_config == new_hash_config),
+             "Table and LB newhash config match: %U",
+             format_ip_flow_hash_config, lb->lb_hash_config);
+
     /*
      * CLEANUP
      *    remove adj-fibs: 
@@ -3918,7 +4151,7 @@ fib_test_v4 (void)
                                              FIB_SOURCE_INTERFACE)),
              "NO INterface Source'd prefixes");
 
-    fib_table_unlock(fib_index, FIB_PROTOCOL_IP4);
+    fib_table_unlock(fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
 
     FIB_TEST((0  == fib_path_list_db_size()), "path list DB population:%d",
             fib_path_list_db_size());
@@ -3969,7 +4202,8 @@ fib_test_v6 (void)
     dpo_drop = drop_dpo_get(DPO_PROTO_IP6);
 
     /* Find or create FIB table 11 */
-    fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, 11);
+    fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, 11,
+                                                  FIB_SOURCE_API);
 
     for (ii = 0; ii < 4; ii++)
     {
@@ -4037,7 +4271,7 @@ fib_test_v6 (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_ATTACHED),
-                                   FIB_PROTOCOL_IP6,
+                                   DPO_PROTO_IP6,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0,
@@ -4068,7 +4302,7 @@ fib_test_v6 (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_LOCAL),
-                                   FIB_PROTOCOL_IP6,
+                                   DPO_PROTO_IP6,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -4113,7 +4347,7 @@ fib_test_v6 (void)
     fib_table_entry_path_add(fib_index, &pfx_0_0,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP6,
+                            DPO_PROTO_IP6,
                             &nh_2001_2,
                             tm->hw[0]->sw_if_index,
                             ~0,
@@ -4157,7 +4391,7 @@ fib_test_v6 (void)
      */
     fib_table_entry_path_remove(fib_index, &pfx_0_0,
                                FIB_SOURCE_API, 
-                               FIB_PROTOCOL_IP6,
+                               DPO_PROTO_IP6,
                                &nh_2001_2,
                                tm->hw[0]->sw_if_index,
                                ~0,
@@ -4230,17 +4464,17 @@ fib_test_v6 (void)
                                    &adj->sub_type.nbr.next_hop)),
              "adj nbr next-hop ok");
 
-    fib_table_entry_update_one_path(fib_index,
-                                   &pfx_2001_1_2_s_128,
-                                   FIB_SOURCE_ADJ,
-                                   FIB_ENTRY_FLAG_ATTACHED,
-                                   FIB_PROTOCOL_IP6,
-                                   &pfx_2001_1_2_s_128.fp_addr,
-                                   tm->hw[0]->sw_if_index,
-                                   ~0,
-                                   1,
-                                   NULL,
-                                   FIB_ROUTE_PATH_FLAG_NONE);
+    fib_table_entry_path_add(fib_index,
+                             &pfx_2001_1_2_s_128,
+                             FIB_SOURCE_ADJ,
+                             FIB_ENTRY_FLAG_ATTACHED,
+                             DPO_PROTO_IP6,
+                             &pfx_2001_1_2_s_128.fp_addr,
+                             tm->hw[0]->sw_if_index,
+                             ~0,
+                             1,
+                             NULL,
+                             FIB_ROUTE_PATH_FLAG_NONE);
 
     fei = fib_table_lookup(fib_index, &pfx_2001_1_2_s_128);
     ai = fib_entry_get_adj(fei);
@@ -4269,17 +4503,17 @@ fib_test_v6 (void)
              "adj nbr next-hop ok");
     FIB_TEST((ai_01 != ai_02), "ADJs are different");
 
-    fib_table_entry_update_one_path(fib_index,
-                                   &pfx_2001_1_3_s_128,
-                                   FIB_SOURCE_ADJ,
-                                   FIB_ENTRY_FLAG_ATTACHED,
-                                   FIB_PROTOCOL_IP6,
-                                   &pfx_2001_1_3_s_128.fp_addr,
-                                   tm->hw[0]->sw_if_index,
-                                   ~0,
-                                   1,
-                                   NULL,
-                                   FIB_ROUTE_PATH_FLAG_NONE);
+    fib_table_entry_path_add(fib_index,
+                             &pfx_2001_1_3_s_128,
+                             FIB_SOURCE_ADJ,
+                             FIB_ENTRY_FLAG_ATTACHED,
+                             DPO_PROTO_IP6,
+                             &pfx_2001_1_3_s_128.fp_addr,
+                             tm->hw[0]->sw_if_index,
+                             ~0,
+                             1,
+                             NULL,
+                             FIB_ROUTE_PATH_FLAG_NONE);
 
     fei = fib_table_lookup(fib_index, &pfx_2001_1_3_s_128);
     ai = fib_entry_get_adj(fei);
@@ -4327,7 +4561,7 @@ fib_test_v6 (void)
                             &pfx_2001_a_s_64,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP6,
+                            DPO_PROTO_IP6,
                             &nh_2001_2,
                             tm->hw[0]->sw_if_index,
                             ~0,
@@ -4341,7 +4575,7 @@ fib_test_v6 (void)
                             &pfx_2001_b_s_64,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP6,
+                            DPO_PROTO_IP6,
                             &nh_2001_2,
                             tm->hw[0]->sw_if_index,
                             ~0,
@@ -4376,7 +4610,7 @@ fib_test_v6 (void)
                                   &pfx_1_1_1_1_s_32,
                                   FIB_SOURCE_API,
                                   FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP6,
+                                  DPO_PROTO_IP6,
                                   &nh_2001_2,
                                   tm->hw[0]->sw_if_index,
                                   ~0,
@@ -4414,7 +4648,7 @@ fib_test_v6 (void)
                             &pfx_2001_c_s_64,
                             FIB_SOURCE_CLI,
                             FIB_ENTRY_FLAG_ATTACHED,
-                            FIB_PROTOCOL_IP6,
+                            DPO_PROTO_IP6,
                             NULL,
                             tm->hw[0]->sw_if_index,
                             ~0,
@@ -4431,7 +4665,7 @@ fib_test_v6 (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_2001_c_s_64,
                                FIB_SOURCE_CLI,
-                               FIB_PROTOCOL_IP6,
+                               DPO_PROTO_IP6,
                                NULL,
                                tm->hw[0]->sw_if_index,
                                ~0,
@@ -4516,7 +4750,7 @@ fib_test_v6 (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_ATTACHED),
-                                   FIB_PROTOCOL_IP6,
+                                   DPO_PROTO_IP6,
                                    NULL,
                                    tm->hw[1]->sw_if_index,
                                    ~0,
@@ -4535,7 +4769,7 @@ fib_test_v6 (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_LOCAL),
-                                   FIB_PROTOCOL_IP6,
+                                   DPO_PROTO_IP6,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -4793,7 +5027,7 @@ fib_test_v6 (void)
     /*
      * now remove the VRF
      */
-    fib_table_unlock(fib_index, FIB_PROTOCOL_IP6);
+    fib_table_unlock(fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
 
     FIB_TEST((0 == fib_path_list_db_size()),   "path list DB population:%d",
             fib_path_list_db_size());
@@ -4863,7 +5097,7 @@ fib_test_ae (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_ATTACHED),
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0,
@@ -4879,7 +5113,7 @@ fib_test_ae (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_LOCAL),
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -4904,17 +5138,17 @@ fib_test_ae (void)
     };
     fib_node_index_t ai;
 
-    fib_table_entry_update_one_path(fib_index,
-                                   &pfx_10_10_10_1_s_32,
-                                   FIB_SOURCE_ADJ,
-                                   FIB_ENTRY_FLAG_ATTACHED,
-                                   FIB_PROTOCOL_IP4,
-                                   &pfx_10_10_10_1_s_32.fp_addr,
-                                   tm->hw[0]->sw_if_index,
-                                   ~0, // invalid fib index
-                                   1,
-                                   NULL,
-                                   FIB_ROUTE_PATH_FLAG_NONE);
+    fib_table_entry_path_add(fib_index,
+                             &pfx_10_10_10_1_s_32,
+                             FIB_SOURCE_ADJ,
+                             FIB_ENTRY_FLAG_ATTACHED,
+                             DPO_PROTO_IP4,
+                             &pfx_10_10_10_1_s_32.fp_addr,
+                             tm->hw[0]->sw_if_index,
+                             ~0, // invalid fib index
+                             1,
+                             NULL,
+                             FIB_ROUTE_PATH_FLAG_NONE);
 
     fei = fib_table_lookup(fib_index, &pfx_10_10_10_1_s_32);
     FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 created");
@@ -4925,7 +5159,9 @@ fib_test_ae (void)
      */
     u32 import_fib_index1;
 
-    import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11);
+    import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
+                                                          11,
+                                                          FIB_SOURCE_CLI);
 
     /*
      * Add an attached route in the import FIB
@@ -4935,7 +5171,7 @@ fib_test_ae (void)
                                    &local_pfx,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -4973,17 +5209,17 @@ fib_test_ae (void)
        },
     };
 
-    fib_table_entry_update_one_path(fib_index,
-                                   &pfx_10_10_10_2_s_32,
-                                   FIB_SOURCE_ADJ,
-                                   FIB_ENTRY_FLAG_ATTACHED,
-                                   FIB_PROTOCOL_IP4,
-                                   &pfx_10_10_10_2_s_32.fp_addr,
-                                   tm->hw[0]->sw_if_index,
-                                   ~0, // invalid fib index
-                                   1,
-                                   NULL,
-                                   FIB_ROUTE_PATH_FLAG_NONE);
+    fib_table_entry_path_add(fib_index,
+                             &pfx_10_10_10_2_s_32,
+                             FIB_SOURCE_ADJ,
+                             FIB_ENTRY_FLAG_ATTACHED,
+                             DPO_PROTO_IP4,
+                             &pfx_10_10_10_2_s_32.fp_addr,
+                             tm->hw[0]->sw_if_index,
+                             ~0, // invalid fib index
+                             1,
+                             NULL,
+                             FIB_ROUTE_PATH_FLAG_NONE);
     fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
     FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 present");
     ai = fib_entry_get_adj(fei);
@@ -5001,7 +5237,8 @@ fib_test_ae (void)
      */
     u32 import_fib_index2;
 
-    import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12);
+    import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12,
+                                                          FIB_SOURCE_CLI);
 
     /*
      * Add an attached route in the import FIB
@@ -5011,7 +5248,7 @@ fib_test_ae (void)
                                    &local_pfx,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -5044,17 +5281,17 @@ fib_test_ae (void)
        },
     };
 
-    fib_table_entry_update_one_path(fib_index,
-                                   &pfx_10_10_10_3_s_32,
-                                   FIB_SOURCE_ADJ,
-                                   FIB_ENTRY_FLAG_ATTACHED,
-                                   FIB_PROTOCOL_IP4,
-                                   &pfx_10_10_10_3_s_32.fp_addr,
-                                   tm->hw[0]->sw_if_index,
-                                   ~0, // invalid fib index
-                                   1,
-                                   NULL,
-                                   FIB_ROUTE_PATH_FLAG_NONE);
+    fib_table_entry_path_add(fib_index,
+                             &pfx_10_10_10_3_s_32,
+                             FIB_SOURCE_ADJ,
+                             FIB_ENTRY_FLAG_ATTACHED,
+                             DPO_PROTO_IP4,
+                             &pfx_10_10_10_3_s_32.fp_addr,
+                             tm->hw[0]->sw_if_index,
+                             ~0, // invalid fib index
+                             1,
+                             NULL,
+                             FIB_ROUTE_PATH_FLAG_NONE);
     fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
     FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 present");
     ai = fib_entry_get_adj(fei);
@@ -5120,7 +5357,7 @@ fib_test_ae (void)
                                    &local_pfx,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &pfx_10_10_10_2_s_32.fp_addr,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -5143,7 +5380,7 @@ fib_test_ae (void)
                                    &local_pfx,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -5175,7 +5412,7 @@ fib_test_ae (void)
                                           &pfx_10_0_0_0_s_8,
                                           FIB_SOURCE_API,
                                           FIB_ENTRY_FLAG_NONE,
-                                         FIB_PROTOCOL_IP4,
+                                         DPO_PROTO_IP4,
                                           &pfx_10_10_10_3_s_32.fp_addr,
                                           tm->hw[0]->sw_if_index,
                                           ~0, // invalid fib index
@@ -5231,7 +5468,7 @@ fib_test_ae (void)
                                           &local_pfx,
                                           FIB_SOURCE_API,
                                           FIB_ENTRY_FLAG_NONE,
-                                         FIB_PROTOCOL_IP4,
+                                         DPO_PROTO_IP4,
                                           &pfx_10_10_10_1_s_32.fp_addr,
                                           tm->hw[0]->sw_if_index,
                                           ~0, // invalid fib index
@@ -5267,7 +5504,7 @@ fib_test_ae (void)
                                    &local_pfx,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -5306,7 +5543,7 @@ fib_test_ae (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_ATTACHED),
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0,
@@ -5363,8 +5600,8 @@ fib_test_ae (void)
                           &local_pfx,
                           FIB_SOURCE_API);
 
-    fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4);
-    fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4);
+    fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
+    fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
 
     FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
             adj_nbr_db_size());
@@ -5372,6 +5609,459 @@ fib_test_ae (void)
     return (0);
 }
 
+/*
+ * Test Path Preference
+ */
+static int
+fib_test_pref (void)
+{
+    test_main_t *tm = &test_main;
+
+    const fib_prefix_t pfx_1_1_1_1_s_32 = {
+        .fp_len = 32,
+        .fp_proto = FIB_PROTOCOL_IP4,
+        .fp_addr = {
+            .ip4 = {
+                .as_u32 = clib_host_to_net_u32(0x01010101),
+            },
+        },
+    };
+
+    /*
+     * 2 high, 2 medium and 2 low preference non-recursive paths
+     */
+    fib_route_path_t nr_path_hi_1 = {
+        .frp_proto = DPO_PROTO_IP4,
+        .frp_sw_if_index = tm->hw[0]->sw_if_index,
+        .frp_fib_index = ~0,
+        .frp_weight = 1,
+        .frp_preference = 0,
+        .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
+        .frp_addr = {
+            .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
+        },
+    };
+    fib_route_path_t nr_path_hi_2 = {
+        .frp_proto = DPO_PROTO_IP4,
+        .frp_sw_if_index = tm->hw[0]->sw_if_index,
+        .frp_fib_index = ~0,
+        .frp_weight = 1,
+        .frp_preference = 0,
+        .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
+        .frp_addr = {
+            .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
+        },
+    };
+    fib_route_path_t nr_path_med_1 = {
+        .frp_proto = DPO_PROTO_IP4,
+        .frp_sw_if_index = tm->hw[1]->sw_if_index,
+        .frp_fib_index = ~0,
+        .frp_weight = 1,
+        .frp_preference = 1,
+        .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
+        .frp_addr = {
+            .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
+        },
+    };
+    fib_route_path_t nr_path_med_2 = {
+        .frp_proto = DPO_PROTO_IP4,
+        .frp_sw_if_index = tm->hw[1]->sw_if_index,
+        .frp_fib_index = ~0,
+        .frp_weight = 1,
+        .frp_preference = 1,
+        .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
+        .frp_addr = {
+            .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
+        },
+    };
+    fib_route_path_t nr_path_low_1 = {
+        .frp_proto = DPO_PROTO_IP4,
+        .frp_sw_if_index = tm->hw[2]->sw_if_index,
+        .frp_fib_index = ~0,
+        .frp_weight = 1,
+        .frp_preference = 2,
+        .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
+        .frp_addr = {
+            .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b01),
+        },
+    };
+    fib_route_path_t nr_path_low_2 = {
+        .frp_proto = DPO_PROTO_IP4,
+        .frp_sw_if_index = tm->hw[2]->sw_if_index,
+        .frp_fib_index = ~0,
+        .frp_weight = 1,
+        .frp_preference = 2,
+        .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
+        .frp_addr = {
+            .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b02),
+        },
+    };
+    fib_route_path_t *nr_paths = NULL;
+
+    vec_add1(nr_paths, nr_path_hi_1);
+    vec_add1(nr_paths, nr_path_hi_2);
+    vec_add1(nr_paths, nr_path_med_1);
+    vec_add1(nr_paths, nr_path_med_2);
+    vec_add1(nr_paths, nr_path_low_1);
+    vec_add1(nr_paths, nr_path_low_2);
+
+    adj_index_t ai_hi_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
+                                              VNET_LINK_IP4,
+                                              &nr_path_hi_1.frp_addr,
+                                              nr_path_hi_1.frp_sw_if_index);
+    adj_index_t ai_hi_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
+                                              VNET_LINK_IP4,
+                                              &nr_path_hi_2.frp_addr,
+                                              nr_path_hi_2.frp_sw_if_index);
+    adj_index_t ai_med_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
+                                               VNET_LINK_IP4,
+                                               &nr_path_med_1.frp_addr,
+                                               nr_path_med_1.frp_sw_if_index);
+    adj_index_t ai_med_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
+                                               VNET_LINK_IP4,
+                                               &nr_path_med_2.frp_addr,
+                                               nr_path_med_2.frp_sw_if_index);
+    adj_index_t ai_low_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
+                                               VNET_LINK_IP4,
+                                               &nr_path_low_1.frp_addr,
+                                               nr_path_low_1.frp_sw_if_index);
+    adj_index_t ai_low_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
+                                               VNET_LINK_IP4,
+                                               &nr_path_low_2.frp_addr,
+                                               nr_path_low_2.frp_sw_if_index);
+
+    fib_test_lb_bucket_t ip_hi_1 = {
+        .type = FT_LB_ADJ,
+        .adj = {
+            .adj = ai_hi_1,
+        },
+    };
+    fib_test_lb_bucket_t ip_hi_2 = {
+        .type = FT_LB_ADJ,
+        .adj = {
+            .adj = ai_hi_2,
+        },
+    };
+    fib_test_lb_bucket_t ip_med_1 = {
+        .type = FT_LB_ADJ,
+        .adj = {
+            .adj = ai_med_1,
+        },
+    };
+    fib_test_lb_bucket_t ip_med_2 = {
+        .type = FT_LB_ADJ,
+        .adj = {
+            .adj = ai_med_2,
+        },
+    };
+    fib_test_lb_bucket_t ip_low_1 = {
+        .type = FT_LB_ADJ,
+        .adj = {
+            .adj = ai_low_1,
+        },
+    };
+    fib_test_lb_bucket_t ip_low_2 = {
+        .type = FT_LB_ADJ,
+        .adj = {
+            .adj = ai_low_2,
+        },
+    };
+
+    fib_node_index_t fei;
+
+    fei = fib_table_entry_path_add2(0,
+                                    &pfx_1_1_1_1_s_32,
+                                    FIB_SOURCE_API,
+                                    FIB_ENTRY_FLAG_NONE,
+                                    nr_paths);
+
+    FIB_TEST(fib_test_validate_entry(fei,
+                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                     2,
+                                     &ip_hi_1,
+                                     &ip_hi_2),
+             "1.1.1.1/32 via high preference paths");
+
+    /*
+     * bring down the interface on which the high preference path lie
+     */
+    vnet_sw_interface_set_flags(vnet_get_main(),
+                                tm->hw[0]->sw_if_index,
+                                0);
+
+    FIB_TEST(fib_test_validate_entry(fei,
+                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                     2,
+                                     &ip_med_1,
+                                     &ip_med_2),
+             "1.1.1.1/32 via medium preference paths");
+
+    /*
+     * bring down the interface on which the medium preference path lie
+     */
+    vnet_sw_interface_set_flags(vnet_get_main(),
+                                tm->hw[1]->sw_if_index,
+                                0);
+
+    FIB_TEST(fib_test_validate_entry(fei,
+                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                     2,
+                                     &ip_low_1,
+                                     &ip_low_2),
+             "1.1.1.1/32 via low preference paths");
+
+    /*
+     * bring up the interface on which the high preference path lie
+     */
+    vnet_sw_interface_set_flags(vnet_get_main(),
+                                tm->hw[0]->sw_if_index,
+                                VNET_SW_INTERFACE_FLAG_ADMIN_UP);
+
+    FIB_TEST(fib_test_validate_entry(fei,
+                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                     2,
+                                     &ip_hi_1,
+                                     &ip_hi_2),
+             "1.1.1.1/32 via high preference paths");
+
+    /*
+     * bring up the interface on which the medium preference path lie
+     */
+    vnet_sw_interface_set_flags(vnet_get_main(),
+                                tm->hw[1]->sw_if_index,
+                                VNET_SW_INTERFACE_FLAG_ADMIN_UP);
+
+    FIB_TEST(fib_test_validate_entry(fei,
+                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                     2,
+                                     &ip_hi_1,
+                                     &ip_hi_2),
+             "1.1.1.1/32 via high preference paths");
+
+    dpo_id_t ip_1_1_1_1 = DPO_INVALID;
+    fib_entry_contribute_forwarding(fei,
+                                    FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                    &ip_1_1_1_1);
+
+    /*
+     * 3 recursive paths of different preference
+     */
+    const fib_prefix_t pfx_1_1_1_2_s_32 = {
+        .fp_len = 32,
+        .fp_proto = FIB_PROTOCOL_IP4,
+        .fp_addr = {
+            .ip4 = {
+                .as_u32 = clib_host_to_net_u32(0x01010102),
+            },
+        },
+    };
+    const fib_prefix_t pfx_1_1_1_3_s_32 = {
+        .fp_len = 32,
+        .fp_proto = FIB_PROTOCOL_IP4,
+        .fp_addr = {
+            .ip4 = {
+                .as_u32 = clib_host_to_net_u32(0x01010103),
+            },
+        },
+    };
+    fei = fib_table_entry_path_add2(0,
+                                    &pfx_1_1_1_2_s_32,
+                                    FIB_SOURCE_API,
+                                    FIB_ENTRY_FLAG_NONE,
+                                    nr_paths);
+    dpo_id_t ip_1_1_1_2 = DPO_INVALID;
+    fib_entry_contribute_forwarding(fei,
+                                    FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                    &ip_1_1_1_2);
+    fei = fib_table_entry_path_add2(0,
+                                    &pfx_1_1_1_3_s_32,
+                                    FIB_SOURCE_API,
+                                    FIB_ENTRY_FLAG_NONE,
+                                    nr_paths);
+    dpo_id_t ip_1_1_1_3 = DPO_INVALID;
+    fib_entry_contribute_forwarding(fei,
+                                    FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                    &ip_1_1_1_3);
+
+    fib_test_lb_bucket_t ip_o_1_1_1_1 = {
+        .type = FT_LB_O_LB,
+        .lb = {
+            .lb = ip_1_1_1_1.dpoi_index,
+        },
+    };
+    fib_test_lb_bucket_t ip_o_1_1_1_2 = {
+        .type = FT_LB_O_LB,
+        .lb = {
+            .lb = ip_1_1_1_2.dpoi_index,
+        },
+    };
+    fib_test_lb_bucket_t ip_o_1_1_1_3 = {
+        .type = FT_LB_O_LB,
+        .lb = {
+            .lb = ip_1_1_1_3.dpoi_index,
+        },
+    };
+    fib_route_path_t r_path_hi = {
+        .frp_proto = DPO_PROTO_IP4,
+        .frp_sw_if_index = ~0,
+        .frp_fib_index = 0,
+        .frp_weight = 1,
+        .frp_preference = 0,
+        .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
+        .frp_addr = pfx_1_1_1_1_s_32.fp_addr,
+    };
+    fib_route_path_t r_path_med = {
+        .frp_proto = DPO_PROTO_IP4,
+        .frp_sw_if_index = ~0,
+        .frp_fib_index = 0,
+        .frp_weight = 1,
+        .frp_preference = 10,
+        .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
+        .frp_addr = pfx_1_1_1_2_s_32.fp_addr,
+    };
+    fib_route_path_t r_path_low = {
+        .frp_proto = DPO_PROTO_IP4,
+        .frp_sw_if_index = ~0,
+        .frp_fib_index = 0,
+        .frp_weight = 1,
+        .frp_preference = 255,
+        .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
+        .frp_addr = pfx_1_1_1_3_s_32.fp_addr,
+    };
+    fib_route_path_t *r_paths = NULL;
+
+    vec_add1(r_paths, r_path_hi);
+    vec_add1(r_paths, r_path_low);
+    vec_add1(r_paths, r_path_med);
+
+    /*
+     * add many recursive so we get the LB MAp created
+     */
+    #define N_PFXS 64
+    fib_prefix_t pfx_r[N_PFXS];
+    unsigned int n_pfxs;
+    for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
+    {
+        pfx_r[n_pfxs].fp_len = 32;
+        pfx_r[n_pfxs].fp_proto = FIB_PROTOCOL_IP4;
+        pfx_r[n_pfxs].fp_addr.ip4.as_u32 =
+            clib_host_to_net_u32(0x02000000 + n_pfxs);
+
+        fei = fib_table_entry_path_add2(0,
+                                        &pfx_r[n_pfxs],
+                                        FIB_SOURCE_API,
+                                        FIB_ENTRY_FLAG_NONE,
+                                        r_paths);
+
+        FIB_TEST(fib_test_validate_entry(fei,
+                                         FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                         1,
+                                         &ip_o_1_1_1_1),
+                 "recursive via high preference paths");
+
+        /*
+         * withdraw hig pref resolving entry
+         */
+        fib_table_entry_delete(0,
+                               &pfx_1_1_1_1_s_32,
+                               FIB_SOURCE_API);
+
+        /* suspend so the update walk kicks int */
+        vlib_process_suspend(vlib_get_main(), 1e-5);
+
+        FIB_TEST(fib_test_validate_entry(fei,
+                                         FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                         1,
+                                         &ip_o_1_1_1_2),
+                 "recursive via medium preference paths");
+
+        /*
+         * withdraw medium pref resolving entry
+         */
+        fib_table_entry_delete(0,
+                               &pfx_1_1_1_2_s_32,
+                               FIB_SOURCE_API);
+
+        /* suspend so the update walk kicks int */
+        vlib_process_suspend(vlib_get_main(), 1e-5);
+
+        FIB_TEST(fib_test_validate_entry(fei,
+                                         FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                         1,
+                                         &ip_o_1_1_1_3),
+                 "recursive via low preference paths");
+
+        /*
+         * add back paths for next iteration
+         */
+        fei = fib_table_entry_update(0,
+                                     &pfx_1_1_1_2_s_32,
+                                     FIB_SOURCE_API,
+                                     FIB_ENTRY_FLAG_NONE,
+                                     nr_paths);
+        fei = fib_table_entry_update(0,
+                                     &pfx_1_1_1_1_s_32,
+                                     FIB_SOURCE_API,
+                                     FIB_ENTRY_FLAG_NONE,
+                                     nr_paths);
+
+        /* suspend so the update walk kicks int */
+        vlib_process_suspend(vlib_get_main(), 1e-5);
+
+        fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
+        FIB_TEST(fib_test_validate_entry(fei,
+                                         FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                         1,
+                                         &ip_o_1_1_1_1),
+                 "recursive via high preference paths");
+    }
+
+
+    fib_table_entry_delete(0,
+                           &pfx_1_1_1_1_s_32,
+                           FIB_SOURCE_API);
+
+    /* suspend so the update walk kicks int */
+    vlib_process_suspend(vlib_get_main(), 1e-5);
+
+    for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
+    {
+        fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
+
+        FIB_TEST(fib_test_validate_entry(fei,
+                                         FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                         1,
+                                         &ip_o_1_1_1_2),
+                 "recursive via medium preference paths");
+    }
+    for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
+    {
+        fib_table_entry_delete(0,
+                               &pfx_r[n_pfxs],
+                               FIB_SOURCE_API);
+    }
+
+    /*
+     * Cleanup
+     */
+    fib_table_entry_delete(0,
+                           &pfx_1_1_1_2_s_32,
+                           FIB_SOURCE_API);
+    fib_table_entry_delete(0,
+                           &pfx_1_1_1_3_s_32,
+                           FIB_SOURCE_API);
+
+    dpo_reset(&ip_1_1_1_1);
+    dpo_reset(&ip_1_1_1_2);
+    dpo_reset(&ip_1_1_1_3);
+    adj_unlock(ai_low_2);
+    adj_unlock(ai_low_1);
+    adj_unlock(ai_med_2);
+    adj_unlock(ai_med_1);
+    adj_unlock(ai_hi_2);
+    adj_unlock(ai_hi_1);
+    return (0);
+}
 
 /*
  * Test the recursive route route handling for GRE tunnels
@@ -5414,7 +6104,7 @@ fib_test_label (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_ATTACHED),
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0,
@@ -5430,7 +6120,7 @@ fib_test_label (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_LOCAL),
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -5460,7 +6150,7 @@ fib_test_label (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_ATTACHED),
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[1]->sw_if_index,
                                    ~0,
@@ -5476,7 +6166,7 @@ fib_test_label (void)
                                    FIB_SOURCE_INTERFACE,
                                    (FIB_ENTRY_FLAG_CONNECTED |
                                     FIB_ENTRY_FLAG_LOCAL),
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[1]->sw_if_index,
                                    ~0, // invalid fib index
@@ -5558,7 +6248,7 @@ fib_test_label (void)
                                    &pfx_1_1_1_1_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &nh_10_10_10_1,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -5597,7 +6287,7 @@ fib_test_label (void)
                                   &pfx_1_1_1_1_s_32,
                                   FIB_SOURCE_API,
                                   FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                   &nh_10_10_11_1,
                                   tm->hw[1]->sw_if_index,
                                   ~0, // invalid fib index
@@ -5675,7 +6365,7 @@ fib_test_label (void)
                                   &pfx_1_1_1_1_s_32,
                                   FIB_SOURCE_API,
                                   FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                   &nh_10_10_11_2,
                                   tm->hw[1]->sw_if_index,
                                   ~0, // invalid fib index
@@ -5755,7 +6445,7 @@ fib_test_label (void)
                                    &pfx_2_2_2_2_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &pfx_1_1_1_1_s_32.fp_addr,
                                    ~0,
                                    fib_index,
@@ -5927,7 +6617,7 @@ fib_test_label (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_1_1_1_1_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_10_1,
                                tm->hw[0]->sw_if_index,
                                ~0, // invalid fib index
@@ -5984,7 +6674,7 @@ fib_test_label (void)
     fib_table_entry_path_remove(fib_index,
                                &pfx_1_1_1_1_s_32,
                                FIB_SOURCE_API,
-                               FIB_PROTOCOL_IP4,
+                               DPO_PROTO_IP4,
                                &nh_10_10_11_1,
                                tm->hw[1]->sw_if_index,
                                ~0, // invalid fib index
@@ -6026,7 +6716,7 @@ fib_test_label (void)
                             &pfx_1_1_1_1_s_32,
                             FIB_SOURCE_API,
                             FIB_ENTRY_FLAG_NONE,
-                            FIB_PROTOCOL_IP4,
+                            DPO_PROTO_IP4,
                             &nh_10_10_10_1,
                             tm->hw[0]->sw_if_index,
                             ~0, // invalid fib index
@@ -6157,7 +6847,7 @@ fib_test_label (void)
                                          &pfx_1_1_1_2_s_32,
                                          FIB_SOURCE_API,
                                          FIB_ENTRY_FLAG_NONE,
-                                         FIB_PROTOCOL_IP4,
+                                         DPO_PROTO_IP4,
                                          &nh_10_10_10_1,
                                          tm->hw[0]->sw_if_index,
                                          ~0, // invalid fib index
@@ -6199,7 +6889,7 @@ fib_test_label (void)
                                   &pfx_2_2_2_2_s_32,
                                   FIB_SOURCE_API,
                                   FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                   &pfx_1_1_1_2_s_32.fp_addr,
                                   ~0,
                                   fib_index,
@@ -6227,7 +6917,7 @@ fib_test_label (void)
                                          &pfx_1_1_1_2_s_32,
                                          FIB_SOURCE_API,
                                          FIB_ENTRY_FLAG_NONE,
-                                         FIB_PROTOCOL_IP4,
+                                         DPO_PROTO_IP4,
                                          &nh_10_10_11_1,
                                          tm->hw[1]->sw_if_index,
                                          ~0, // invalid fib index
@@ -6260,7 +6950,7 @@ fib_test_label (void)
                                          &pfx_1_1_1_2_s_32,
                                          FIB_SOURCE_API,
                                          FIB_ENTRY_FLAG_NONE,
-                                         FIB_PROTOCOL_IP4,
+                                         DPO_PROTO_IP4,
                                          &nh_10_10_11_1,
                                          tm->hw[1]->sw_if_index,
                                          ~0, // invalid fib index
@@ -6302,7 +6992,7 @@ fib_test_label (void)
                                    &pfx_2_2_2_3_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &pfx_1_1_1_1_s_32.fp_addr,
                                    ~0,
                                    fib_index,
@@ -6346,7 +7036,7 @@ fib_test_label (void)
                                    &pfx_2_2_2_4_s_32,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &pfx_1_1_1_1_s_32.fp_addr,
                                    ~0,
                                    fib_index,
@@ -6396,7 +7086,7 @@ fib_test_label (void)
                                          &pfx_2_2_5_5_s_32,
                                          FIB_SOURCE_API,
                                          FIB_ENTRY_FLAG_NONE,
-                                         FIB_PROTOCOL_IP4,
+                                         DPO_PROTO_IP4,
                                          &nh_10_10_11_1,
                                          tm->hw[1]->sw_if_index,
                                          ~0, // invalid fib index
@@ -7004,7 +7694,7 @@ fib_test_bfd (void)
                                     FIB_SOURCE_INTERFACE,
                                     (FIB_ENTRY_FLAG_CONNECTED |
                                      FIB_ENTRY_FLAG_ATTACHED),
-                                    FIB_PROTOCOL_IP4,
+                                    DPO_PROTO_IP4,
                                     NULL,
                                     tm->hw[0]->sw_if_index,
                                     ~0, // invalid fib index
@@ -7021,7 +7711,7 @@ fib_test_bfd (void)
                                     FIB_SOURCE_INTERFACE,
                                     (FIB_ENTRY_FLAG_CONNECTED |
                                      FIB_ENTRY_FLAG_LOCAL),
-                                    FIB_PROTOCOL_IP4,
+                                    DPO_PROTO_IP4,
                                     NULL,
                                     tm->hw[0]->sw_if_index,
                                     ~0, // invalid fib index
@@ -7091,17 +7781,17 @@ fib_test_bfd (void)
     /*
      * source the entry via the ADJ fib
      */
-    fei = fib_table_entry_update_one_path(0,
-                                          &pfx_10_10_10_1_s_32,
-                                          FIB_SOURCE_ADJ,
-                                          FIB_ENTRY_FLAG_ATTACHED,
-                                          FIB_PROTOCOL_IP4,
-                                          &nh_10_10_10_1,
-                                          tm->hw[0]->sw_if_index,
-                                          ~0, // invalid fib index
-                                          1,
-                                          NULL,
-                                          FIB_ROUTE_PATH_FLAG_NONE);
+    fei = fib_table_entry_path_add(0,
+                                   &pfx_10_10_10_1_s_32,
+                                   FIB_SOURCE_ADJ,
+                                   FIB_ENTRY_FLAG_ATTACHED,
+                                   DPO_PROTO_IP4,
+                                   &nh_10_10_10_1,
+                                   tm->hw[0]->sw_if_index,
+                                   ~0, // invalid fib index
+                                   1,
+                                   NULL,
+                                   FIB_ROUTE_PATH_FLAG_NONE);
 
     /*
      * Delete the BFD session. Expect the fib_entry to remain
@@ -7130,17 +7820,17 @@ fib_test_bfd (void)
         .fp_len = 32,
         .fp_proto = FIB_PROTOCOL_IP4,
     };
-    fib_table_entry_update_one_path(0,
-                                    &pfx_10_10_10_2_s_32,
-                                    FIB_SOURCE_ADJ,
-                                    FIB_ENTRY_FLAG_ATTACHED,
-                                    FIB_PROTOCOL_IP4,
-                                    &nh_10_10_10_2,
-                                    tm->hw[0]->sw_if_index,
-                                    ~0, // invalid fib index
-                                    1,
-                                    NULL,
-                                    FIB_ROUTE_PATH_FLAG_NONE);
+    fib_table_entry_path_add(0,
+                             &pfx_10_10_10_2_s_32,
+                             FIB_SOURCE_ADJ,
+                             FIB_ENTRY_FLAG_ATTACHED,
+                             DPO_PROTO_IP4,
+                             &nh_10_10_10_2,
+                             tm->hw[0]->sw_if_index,
+                             ~0, // invalid fib index
+                             1,
+                             NULL,
+                             FIB_ROUTE_PATH_FLAG_NONE);
     /*
      * A BFD session for the new ADJ FIB
      */
@@ -7162,17 +7852,17 @@ fib_test_bfd (void)
      * then add it back
      */
     fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
-    fib_table_entry_update_one_path(0,
-                                    &pfx_10_10_10_2_s_32,
-                                    FIB_SOURCE_ADJ,
-                                    FIB_ENTRY_FLAG_ATTACHED,
-                                    FIB_PROTOCOL_IP4,
-                                    &nh_10_10_10_2,
-                                    tm->hw[0]->sw_if_index,
-                                    ~0, // invalid fib index
-                                    1,
-                                    NULL,
-                                    FIB_ROUTE_PATH_FLAG_NONE);
+    fib_table_entry_path_add(0,
+                             &pfx_10_10_10_2_s_32,
+                             FIB_SOURCE_ADJ,
+                             FIB_ENTRY_FLAG_ATTACHED,
+                             DPO_PROTO_IP4,
+                             &nh_10_10_10_2,
+                             tm->hw[0]->sw_if_index,
+                             ~0, // invalid fib index
+                             1,
+                             NULL,
+                             FIB_ROUTE_PATH_FLAG_NONE);
 
     /*
      * Before adding a recursive via the BFD tracked ADJ-FIBs,
@@ -7222,7 +7912,7 @@ fib_test_bfd (void)
                                    &pfx_200_0_0_0_s_24,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &nh_10_10_10_2,
                                    ~0, // recursive
                                    0, // default fib index
@@ -7241,7 +7931,7 @@ fib_test_bfd (void)
                                    &pfx_200_0_0_0_s_24,
                                    FIB_SOURCE_API,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &nh_10_10_10_1,
                                    ~0, // recursive
                                    0, // default fib index
@@ -7380,7 +8070,7 @@ fib_test_bfd (void)
                                    &pfx_5_5_5_5_s_32,
                                    FIB_SOURCE_CLI,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &nh_10_10_10_1,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -7411,7 +8101,7 @@ fib_test_bfd (void)
                                    &pfx_5_5_5_5_s_32,
                                    FIB_SOURCE_CLI,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &nh_10_10_10_2,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -7483,9 +8173,10 @@ lfib_test (void)
     /*
      * MPLS enable an interface so we get the MPLS table created
      */
+    mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
     mpls_sw_interface_enable_disable(&mpls_main,
                                      tm->hw[0]->sw_if_index,
-                                     1);
+                                     1, 1);
 
     ip46_address_t nh_10_10_10_1 = {
        .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
@@ -7549,7 +8240,7 @@ lfib_test (void)
                                   &pfx,
                                   FIB_SOURCE_CLI,
                                   FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                   &zero_addr,
                                   ~0,
                                   fib_index,
@@ -7600,7 +8291,7 @@ lfib_test (void)
                                   &pfx,
                                   FIB_SOURCE_CLI,
                                   FIB_ENTRY_FLAG_NONE,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                   &zero_addr,
                                   ~0,
                                   lfib_index,
@@ -7678,7 +8369,7 @@ lfib_test (void)
                                          &pfx_1200,
                                          FIB_SOURCE_API,
                                          FIB_ENTRY_FLAG_NONE,
-                                         FIB_PROTOCOL_IP4,
+                                         DPO_PROTO_IP4,
                                          &nh_10_10_10_1,
                                          tm->hw[0]->sw_if_index,
                                          ~0, // invalid fib index
@@ -7704,7 +8395,7 @@ lfib_test (void)
        },
     };
     fib_route_path_t *rpaths = NULL, rpath = {
-       .frp_proto = FIB_PROTOCOL_MPLS,
+        .frp_proto = DPO_PROTO_MPLS,
        .frp_local_label = 1200,
         .frp_eos = MPLS_NON_EOS,
        .frp_sw_if_index = ~0, // recurive
@@ -7814,8 +8505,8 @@ lfib_test (void)
     FIB_TEST(fib_test_validate_entry(lfe,
                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
                                     1,
-                                    &ip_o_1200),
-            "2.2.2.2.4/32 LB 1 buckets via: label 1200 EOS");
+                                    &bucket_drop),
+            "2.2.2.2.4/32 LB 1 buckets via: drop");
     lfe = fib_table_lookup(fib_index, &pfx_1200);
     FIB_TEST(fib_test_validate_entry(lfe,
                                     FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
@@ -7838,7 +8529,7 @@ lfib_test (void)
      */
     dpo_id_t idpo = DPO_INVALID;
 
-    interface_dpo_add_or_lock(DPO_PROTO_IP4,
+    interface_rx_dpo_add_or_lock(DPO_PROTO_IP4,
                               tm->hw[0]->sw_if_index,
                               &idpo);
 
@@ -7860,7 +8551,7 @@ lfib_test (void)
                                          &pfx_2500,
                                          FIB_SOURCE_API,
                                          FIB_ENTRY_FLAG_NONE,
-                                         FIB_PROTOCOL_IP4,
+                                         DPO_PROTO_IP4,
                                          NULL,
                                          tm->hw[0]->sw_if_index,
                                          ~0, // invalid fib index
@@ -7905,7 +8596,7 @@ lfib_test (void)
                                          &pfx_3500,
                                          FIB_SOURCE_API,
                                          FIB_ENTRY_FLAG_MULTICAST,
-                                         FIB_PROTOCOL_IP4,
+                                         DPO_PROTO_IP4,
                                          &nh_10_10_10_1,
                                          tm->hw[0]->sw_if_index,
                                          ~0, // invalid fib index
@@ -7925,7 +8616,7 @@ lfib_test (void)
                                   &pfx_3500,
                                   FIB_SOURCE_API,
                                   FIB_ENTRY_FLAG_MULTICAST,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                    NULL,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -7952,7 +8643,7 @@ lfib_test (void)
                                   &pfx_3500,
                                   FIB_SOURCE_API,
                                   FIB_ENTRY_FLAG_MULTICAST,
-                                  FIB_PROTOCOL_IP4,
+                                  DPO_PROTO_IP4,
                                    NULL,
                                    5, // rpf-id
                                    0, // default table
@@ -7977,14 +8668,15 @@ lfib_test (void)
      */
     mpls_sw_interface_enable_disable(&mpls_main,
                                      tm->hw[0]->sw_if_index,
-                                     0);
+                                     0, 1);
+    mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
 
     FIB_TEST(lb_count == pool_elts(load_balance_pool),
             "Load-balance resources freed %d of %d",
              lb_count, pool_elts(load_balance_pool));
-    FIB_TEST(0 == pool_elts(interface_dpo_pool),
-            "interface_dpo resources freed %d of %d",
-             0, pool_elts(interface_dpo_pool));
+    FIB_TEST(0 == pool_elts(interface_rx_dpo_pool),
+            "interface_rx_dpo resources freed %d of %d",
+             0, pool_elts(interface_rx_dpo_pool));
 
     return (0);
 }
@@ -8017,6 +8709,10 @@ fib_test (vlib_main_t * vm,
     {
        res += fib_test_ae();
     }
+    else if (unformat (input, "pref"))
+    {
+       res += fib_test_pref();
+    }
     else if (unformat (input, "lfib"))
     {
        res += lfib_test();
@@ -8035,6 +8731,7 @@ fib_test (vlib_main_t * vm,
        res += fib_test_v6();
        res += fib_test_ae();
        res += fib_test_bfd();
+       res += fib_test_pref();
        res += fib_test_label();
        res += lfib_test();