FIB table add/delete API
[vpp.git] / src / vnet / fib / fib_test.c
index 06aeda6..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
@@ -860,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
@@ -910,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
@@ -962,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
@@ -1028,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
@@ -1094,7 +1096,7 @@ fib_test_v4 (void)
                                    &pfx_10_10_10_1_s_32,
                                    FIB_SOURCE_ADJ,
                                    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
@@ -1109,7 +1111,7 @@ fib_test_v4 (void)
     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
@@ -1143,7 +1145,7 @@ fib_test_v4 (void)
                              &pfx_10_10_10_2_s_32,
                              FIB_SOURCE_ADJ,
                              FIB_ENTRY_FLAG_ATTACHED,
-                             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
@@ -1180,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
@@ -1213,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
@@ -1240,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
@@ -1279,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,
@@ -1326,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
@@ -1362,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
@@ -1482,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
@@ -1532,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,
@@ -1543,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,
@@ -1584,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,
@@ -1595,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,
@@ -1667,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
@@ -1686,7 +1689,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_2,
                              tm->hw[0]->sw_if_index,
                              ~0, // invalid fib index
@@ -1768,7 +1771,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_12_12_12_12,
                              tm->hw[1]->sw_if_index,
                              ~0, // invalid fib index
@@ -1913,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
@@ -1993,7 +1996,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_10_10_10_2,
                                 tm->hw[0]->sw_if_index,
                                 ~0, // invalid fib index
@@ -2024,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,
@@ -2035,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,
@@ -2101,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)),
@@ -2148,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
@@ -2206,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
@@ -2241,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,
@@ -2272,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,
@@ -2285,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
@@ -2309,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
@@ -2320,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);
 
     /*
@@ -2333,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,
@@ -2369,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,
@@ -2410,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
@@ -2421,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
@@ -2447,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
@@ -2456,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
@@ -2471,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
@@ -2480,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
@@ -2510,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
@@ -2557,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,
@@ -2603,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
@@ -2612,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
@@ -2671,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,
@@ -2682,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,
@@ -2693,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,
@@ -2732,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,
@@ -2765,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,
@@ -2790,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
@@ -2832,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,
@@ -2856,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
@@ -2865,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
@@ -2874,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
@@ -2883,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
@@ -2907,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,
@@ -2921,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
@@ -2955,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,
@@ -2985,7 +3022,7 @@ fib_test_v4 (void)
                                   &pfx_0_0_0_0_s_0,
                                   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,
@@ -3015,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,
@@ -3045,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
@@ -3063,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
@@ -3080,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
@@ -3104,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
@@ -3116,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,
@@ -3141,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,
@@ -3152,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,
@@ -3202,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
@@ -3241,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
@@ -3271,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,
@@ -3284,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,
@@ -3318,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,
@@ -3355,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,
@@ -3376,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,
@@ -3385,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,
@@ -3394,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,
@@ -3445,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,
@@ -3456,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,
@@ -3467,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,
@@ -3503,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),
            },
@@ -3552,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,
@@ -3608,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,
@@ -3623,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,
@@ -3632,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
@@ -3641,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,
@@ -3650,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,
@@ -3659,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,
@@ -3701,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,
@@ -3755,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,
@@ -3813,7 +3864,7 @@ fib_test_v4 (void)
                              &pfx_12_10_10_2_s_32,
                              FIB_SOURCE_ADJ,
                              FIB_ENTRY_FLAG_ATTACHED,
-                             FIB_PROTOCOL_IP4,
+                             DPO_PROTO_IP4,
                              &pfx_12_10_10_2_s_32.fp_addr,
                              tm->hw[0]->sw_if_index,
                              ~0, // invalid fib index
@@ -3847,7 +3898,7 @@ fib_test_v4 (void)
                              &pfx_10_10_10_127_s_32,
                              FIB_SOURCE_ADJ,
                              FIB_ENTRY_FLAG_ATTACHED,
-                             FIB_PROTOCOL_IP4,
+                             DPO_PROTO_IP4,
                              &pfx_10_10_10_127_s_32.fp_addr,
                              tm->hw[1]->sw_if_index,
                              ~0, // invalid fib index
@@ -3895,7 +3946,7 @@ fib_test_v4 (void)
                                    &pfx_10_10_10_3_s_32,
                                    FIB_SOURCE_ADJ,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &nh_10_10_10_3,
                                    tm->hw[0]->sw_if_index,
                                    fib_index,
@@ -3906,7 +3957,7 @@ fib_test_v4 (void)
                                    &pfx_10_10_10_3_s_32,
                                    FIB_SOURCE_ADJ,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &nh_12_12_12_12,
                                    tm->hw[1]->sw_if_index,
                                    fib_index,
@@ -3925,7 +3976,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                 &pfx_10_10_10_3_s_32,
                                 FIB_SOURCE_ADJ,
-                                FIB_PROTOCOL_IP4,
+                                DPO_PROTO_IP4,
                                 &nh_10_10_10_3,
                                 tm->hw[0]->sw_if_index,
                                 fib_index,
@@ -3942,7 +3993,7 @@ fib_test_v4 (void)
                                    &pfx_10_10_10_3_s_32,
                                    FIB_SOURCE_ADJ,
                                    FIB_ENTRY_FLAG_NONE,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &nh_10_10_10_3,
                                    tm->hw[0]->sw_if_index,
                                    fib_index,
@@ -3961,7 +4012,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                 &pfx_10_10_10_3_s_32,
                                 FIB_SOURCE_ADJ,
-                                FIB_PROTOCOL_IP4,
+                                DPO_PROTO_IP4,
                                 &nh_12_12_12_12,
                                 tm->hw[1]->sw_if_index,
                                 fib_index,
@@ -3980,7 +4031,7 @@ fib_test_v4 (void)
     fib_table_entry_path_remove(fib_index,
                                 &pfx_10_10_10_3_s_32,
                                 FIB_SOURCE_ADJ,
-                                FIB_PROTOCOL_IP4,
+                                DPO_PROTO_IP4,
                                 &nh_10_10_10_3,
                                 tm->hw[0]->sw_if_index,
                                 fib_index,
@@ -4100,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());
@@ -4151,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++)
     {
@@ -4219,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,
@@ -4250,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
@@ -4295,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,
@@ -4339,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,
@@ -4416,7 +4468,7 @@ fib_test_v6 (void)
                              &pfx_2001_1_2_s_128,
                              FIB_SOURCE_ADJ,
                              FIB_ENTRY_FLAG_ATTACHED,
-                             FIB_PROTOCOL_IP6,
+                             DPO_PROTO_IP6,
                              &pfx_2001_1_2_s_128.fp_addr,
                              tm->hw[0]->sw_if_index,
                              ~0,
@@ -4455,7 +4507,7 @@ fib_test_v6 (void)
                              &pfx_2001_1_3_s_128,
                              FIB_SOURCE_ADJ,
                              FIB_ENTRY_FLAG_ATTACHED,
-                             FIB_PROTOCOL_IP6,
+                             DPO_PROTO_IP6,
                              &pfx_2001_1_3_s_128.fp_addr,
                              tm->hw[0]->sw_if_index,
                              ~0,
@@ -4509,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,
@@ -4523,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,
@@ -4558,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,
@@ -4596,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,
@@ -4613,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,
@@ -4698,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,
@@ -4717,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
@@ -4975,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());
@@ -5045,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,
@@ -5061,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
@@ -5090,7 +5142,7 @@ fib_test_ae (void)
                              &pfx_10_10_10_1_s_32,
                              FIB_SOURCE_ADJ,
                              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
@@ -5107,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
@@ -5117,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
@@ -5159,7 +5213,7 @@ fib_test_ae (void)
                              &pfx_10_10_10_2_s_32,
                              FIB_SOURCE_ADJ,
                              FIB_ENTRY_FLAG_ATTACHED,
-                             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
@@ -5183,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
@@ -5193,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
@@ -5230,7 +5285,7 @@ fib_test_ae (void)
                              &pfx_10_10_10_3_s_32,
                              FIB_SOURCE_ADJ,
                              FIB_ENTRY_FLAG_ATTACHED,
-                             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
@@ -5302,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
@@ -5325,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
@@ -5357,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
@@ -5413,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
@@ -5449,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
@@ -5488,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,
@@ -5545,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());
@@ -5554,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
@@ -5596,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,
@@ -5612,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
@@ -5642,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,
@@ -5658,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
@@ -5740,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
@@ -5779,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
@@ -5857,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
@@ -5937,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,
@@ -6109,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
@@ -6166,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
@@ -6208,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
@@ -6339,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
@@ -6381,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,
@@ -6409,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
@@ -6442,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
@@ -6484,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,
@@ -6528,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,
@@ -6578,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
@@ -7186,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
@@ -7203,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
@@ -7277,7 +7785,7 @@ fib_test_bfd (void)
                                    &pfx_10_10_10_1_s_32,
                                    FIB_SOURCE_ADJ,
                                    FIB_ENTRY_FLAG_ATTACHED,
-                                   FIB_PROTOCOL_IP4,
+                                   DPO_PROTO_IP4,
                                    &nh_10_10_10_1,
                                    tm->hw[0]->sw_if_index,
                                    ~0, // invalid fib index
@@ -7316,7 +7824,7 @@ fib_test_bfd (void)
                              &pfx_10_10_10_2_s_32,
                              FIB_SOURCE_ADJ,
                              FIB_ENTRY_FLAG_ATTACHED,
-                             FIB_PROTOCOL_IP4,
+                             DPO_PROTO_IP4,
                              &nh_10_10_10_2,
                              tm->hw[0]->sw_if_index,
                              ~0, // invalid fib index
@@ -7348,7 +7856,7 @@ fib_test_bfd (void)
                              &pfx_10_10_10_2_s_32,
                              FIB_SOURCE_ADJ,
                              FIB_ENTRY_FLAG_ATTACHED,
-                             FIB_PROTOCOL_IP4,
+                             DPO_PROTO_IP4,
                              &nh_10_10_10_2,
                              tm->hw[0]->sw_if_index,
                              ~0, // invalid fib index
@@ -7404,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
@@ -7423,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
@@ -7562,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
@@ -7593,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
@@ -7665,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),
@@ -7731,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,
@@ -7782,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,
@@ -7860,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
@@ -7886,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
@@ -7996,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,
@@ -8020,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);
 
@@ -8042,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
@@ -8087,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
@@ -8107,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
@@ -8134,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
@@ -8159,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);
 }
@@ -8199,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();
@@ -8217,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();