fib: Decouple source from priority and behaviour 77/23777/4
authorNeale Ranns <nranns@cisco.com>
Wed, 4 Dec 2019 06:11:00 +0000 (06:11 +0000)
committerOle Trøan <otroan@employees.org>
Wed, 4 Dec 2019 22:47:12 +0000 (22:47 +0000)
Type: feature

the fib_source_t enum alone no longer defines the priority and
behaviour, instead each source must be allocated these attributes.
This allows the creation of other sources by the plugins (and
soon over the API).

Signed-off-by: Neale Ranns <nranns@cisco.com>
Change-Id: I890ee820fbc16079ee417ea1fbc163192806e853

40 files changed:
src/plugins/gbp/gbp_endpoint.c
src/plugins/gbp/gbp_route_domain.c
src/plugins/gbp/gbp_subnet.c
src/plugins/ila/ila.c
src/plugins/lb/lb.c
src/plugins/nat/dslite.c
src/plugins/nat/nat.c
src/plugins/nat/nat.h
src/plugins/nat/nat64.c
src/plugins/nat/nat64_cli.c
src/plugins/nat/nat66.c
src/plugins/pppoe/pppoe.c
src/plugins/svs/svs.c
src/plugins/unittest/fib_test.c
src/vnet/CMakeLists.txt
src/vnet/fib/fib.c
src/vnet/fib/fib_entry.c
src/vnet/fib/fib_entry.h
src/vnet/fib/fib_entry_src.c
src/vnet/fib/fib_entry_src.h
src/vnet/fib/fib_entry_src_adj.c
src/vnet/fib/fib_entry_src_api.c
src/vnet/fib/fib_entry_src_default.c
src/vnet/fib/fib_entry_src_drop.c [moved from src/vnet/fib/fib_entry_src_default_route.c with 68% similarity]
src/vnet/fib/fib_entry_src_interface.c
src/vnet/fib/fib_entry_src_interpose.c
src/vnet/fib/fib_entry_src_lisp.c
src/vnet/fib/fib_entry_src_mpls.c
src/vnet/fib/fib_entry_src_rr.c
src/vnet/fib/fib_entry_src_simple.c [new file with mode: 0644]
src/vnet/fib/fib_entry_src_special.c [deleted file]
src/vnet/fib/fib_source.c [new file with mode: 0644]
src/vnet/fib/fib_source.h [new file with mode: 0644]
src/vnet/fib/fib_table.c
src/vnet/fib/fib_table.h
src/vnet/fib/ip4_fib.c
src/vnet/fib/ip6_fib.c
src/vnet/fib/mpls_fib.c
src/vnet/ip/ip6_ll_table.c
test/test_fib.py

index 1286546..bef6777 100644 (file)
@@ -41,9 +41,10 @@ static const char *gbp_endpoint_attr_names[] = GBP_ENDPOINT_ATTR_NAMES;
  */
 gbp_ep_db_t gbp_ep_db;
 
-fib_node_type_t gbp_endpoint_fib_type;
-
-vlib_log_class_t gbp_ep_logger;
+static fib_source_t gbp_fib_source_hi;
+static fib_source_t gbp_fib_source_low;
+static fib_node_type_t gbp_endpoint_fib_type;
+static vlib_log_class_t gbp_ep_logger;
 
 #define GBP_ENDPOINT_DBG(...)                           \
     vlib_log_debug (gbp_ep_logger, __VA_ARGS__);
@@ -588,10 +589,10 @@ gbb_endpoint_fwd_reset (gbp_endpoint_t * ge)
      */
     if (gbp_endpoint_is_remote (ge))
       {
-       fib_table_entry_special_remove (fib_index, pfx, FIB_SOURCE_PLUGIN_HI);
+       fib_table_entry_special_remove (fib_index, pfx, gbp_fib_source_hi);
       }
 
-    fib_table_entry_delete (fib_index, pfx, FIB_SOURCE_PLUGIN_LOW);
+    fib_table_entry_delete (fib_index, pfx, gbp_fib_source_low);
   }
   vec_foreach (ai, gef->gef_adjs)
   {
@@ -726,7 +727,7 @@ gbb_endpoint_fwd_recalc (gbp_endpoint_t * ge)
       }
 
     fib_table_entry_path_add (fib_index, pfx,
-                             FIB_SOURCE_PLUGIN_LOW,
+                             gbp_fib_source_low,
                              FIB_ENTRY_FLAG_NONE,
                              fib_proto_to_dpo (pfx->fp_proto),
                              &pfx->fp_addr, ip_sw_if_index,
@@ -759,7 +760,7 @@ gbb_endpoint_fwd_recalc (gbp_endpoint_t * ge)
                                        gg->gg_sclass, ~0, &policy_dpo);
 
            fib_table_entry_special_dpo_add (fib_index, pfx,
-                                            FIB_SOURCE_PLUGIN_HI,
+                                            gbp_fib_source_hi,
                                             FIB_ENTRY_FLAG_INTERPOSE,
                                             &policy_dpo);
            dpo_reset (&policy_dpo);
@@ -1576,6 +1577,12 @@ gbp_endpoint_init (vlib_main_t * vm)
 
   gbp_ep_logger = vlib_log_register_class ("gbp", "ep");
   gbp_endpoint_fib_type = fib_node_register_new_type (&gbp_endpoint_vft);
+  gbp_fib_source_hi = fib_source_allocate ("gbp-endpoint-hi",
+                                          FIB_SOURCE_PRIORITY_HI,
+                                          FIB_SOURCE_BH_SIMPLE);
+  gbp_fib_source_low = fib_source_allocate ("gbp-endpoint-low",
+                                           FIB_SOURCE_PRIORITY_LOW,
+                                           FIB_SOURCE_BH_SIMPLE);
 
   return (NULL);
 }
index ab99859..f0aa694 100644 (file)
@@ -53,6 +53,7 @@ typedef struct gbp_route_domain_db_t
 } gbp_route_domain_db_t;
 
 static gbp_route_domain_db_t gbp_route_domain_db;
+static fib_source_t gbp_fib_source;
 
 /**
  * logger
@@ -154,7 +155,7 @@ gbp_route_domain_add_and_lock (u32 rd_id,
        grd->grd_fib_index[fproto] =
          fib_table_find_or_create_and_lock (fproto,
                                             grd->grd_table_id[fproto],
-                                            FIB_SOURCE_PLUGIN_HI);
+                                            gbp_fib_source);
 
        if (~0 != grd->grd_uu_sw_if_index[fproto])
          {
@@ -221,8 +222,7 @@ gbp_route_domain_unlock (index_t index)
 
       FOR_EACH_FIB_IP_PROTOCOL (fproto)
       {
-       fib_table_unlock (grd->grd_fib_index[fproto],
-                         fproto, FIB_SOURCE_PLUGIN_HI);
+       fib_table_unlock (grd->grd_fib_index[fproto], fproto, gbp_fib_source);
        if (INDEX_INVALID != grd->grd_adj[fproto])
          adj_unlock (grd->grd_adj[fproto]);
       }
@@ -430,6 +430,9 @@ static clib_error_t *
 gbp_route_domain_init (vlib_main_t * vm)
 {
   grd_logger = vlib_log_register_class ("gbp", "rd");
+  gbp_fib_source = fib_source_allocate ("gbp-rd",
+                                       FIB_SOURCE_PRIORITY_HI,
+                                       FIB_SOURCE_BH_DROP);
 
   return (NULL);
 }
index bb069ff..2ef3fcf 100644 (file)
@@ -65,6 +65,8 @@ uword *gbp_subnet_db;
  */
 gbp_subnet_t *gbp_subnet_pool;
 
+static fib_source_t gbp_fib_source;
+
 static index_t
 gbp_subnet_db_find (u32 fib_index, const fib_prefix_t * pfx)
 {
@@ -122,7 +124,7 @@ gbp_subnet_transport_add (gbp_subnet_t * gs)
 
   gs->gs_fei = fib_table_entry_update_one_path (gs->gs_key->gsk_fib_index,
                                                &gs->gs_key->gsk_pfx,
-                                               FIB_SOURCE_PLUGIN_HI,
+                                               gbp_fib_source,
                                                FIB_ENTRY_FLAG_NONE,
                                                fib_proto_to_dpo (fproto),
                                                &ADJ_BCAST_ADDR,
@@ -145,7 +147,7 @@ gbp_subnet_internal_add (gbp_subnet_t * gs)
 
   gs->gs_fei = fib_table_entry_special_dpo_update (gs->gs_key->gsk_fib_index,
                                                   &gs->gs_key->gsk_pfx,
-                                                  FIB_SOURCE_PLUGIN_HI,
+                                                  gbp_fib_source,
                                                   FIB_ENTRY_FLAG_EXCLUSIVE,
                                                   &gfd);
 
@@ -169,7 +171,7 @@ gbp_subnet_external_add (gbp_subnet_t * gs, u32 sw_if_index, sclass_t sclass)
 
   gs->gs_fei = fib_table_entry_special_dpo_update (gs->gs_key->gsk_fib_index,
                                                   &gs->gs_key->gsk_pfx,
-                                                  FIB_SOURCE_PLUGIN_HI,
+                                                  gbp_fib_source,
                                                   (FIB_ENTRY_FLAG_EXCLUSIVE |
                                                    FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT),
                                                   &gpd);
@@ -216,7 +218,7 @@ gbp_subnet_del_i (index_t gsi)
                                (GBP_SUBNET_L3_OUT == gs->gs_type
                                 || GBP_SUBNET_ANON_L3_OUT ==
                                 gs->gs_type) ? FIB_SOURCE_SPECIAL :
-                               FIB_SOURCE_PLUGIN_HI);
+                               gbp_fib_source);
 
   gbp_subnet_db_del (gs);
   gbp_route_domain_unlock (gs->gs_rd);
@@ -578,6 +580,9 @@ gbp_subnet_init (vlib_main_t * vm)
 {
   gbp_subnet_db = hash_create_mem (0,
                                   sizeof (gbp_subnet_key_t), sizeof (u32));
+  gbp_fib_source = fib_source_allocate ("gbp-subnet",
+                                       FIB_SOURCE_PRIORITY_HI,
+                                       FIB_SOURCE_BH_SIMPLE);
 
   return (NULL);
 }
index bac7615..162d417 100644 (file)
@@ -68,6 +68,11 @@ static dpo_type_t ila_dpo_type;
  */
 static fib_node_type_t ila_fib_node_type;
 
+/**
+ * FIB source for adding entries
+ */
+static fib_source_t ila_fib_src;
+
 u8 *
 format_half_ip6_address (u8 * s, va_list * va)
 {
@@ -758,7 +763,7 @@ ila_add_del_entry (ila_add_del_entry_args_t * args)
 
          fib_table_entry_special_dpo_add(0,
                                          &pfx,
-                                         FIB_SOURCE_PLUGIN_HI,
+                                         ila_fib_src,
                                          FIB_ENTRY_FLAG_EXCLUSIVE,
                                          &dpo);
          dpo_reset(&dpo);
@@ -794,7 +799,7 @@ ila_add_del_entry (ila_add_del_entry_args_t * args)
              .fp_proto = FIB_PROTOCOL_IP6,
          };
 
-         fib_table_entry_special_remove(0, &pfx, FIB_SOURCE_PLUGIN_HI);
+         fib_table_entry_special_remove(0, &pfx, ila_fib_src);
          /*
           * remove this ILA entry as child of the FIB netry for the next-hop
           */
@@ -935,7 +940,9 @@ ila_init (vlib_main_t * vm)
 
   ila_dpo_type = dpo_register_new_type(&ila_vft, ila_nodes);
   ila_fib_node_type = fib_node_register_new_type(&ila_fib_node_vft);
-
+  ila_fib_src = fib_source_allocate("ila",
+                                    FIB_SOURCE_PRIORITY_HI,
+                                    FIB_SOURCE_BH_SIMPLE);
   return NULL;
 }
 
index b1e0b23..4dbf134 100644 (file)
@@ -26,6 +26,9 @@
 //After so many seconds. It is assumed that inter-core race condition will not occur.
 #define LB_CONCURRENCY_TIMEOUT 10
 
+// FIB source for adding routes
+static fib_source_t lb_fib_src;
+
 lb_main_t lb_main;
 
 #define lb_get_writer_lock() clib_spinlock_lock (&lb_main.writer_lock)
@@ -948,7 +951,7 @@ static void lb_vip_add_adjacency(lb_main_t *lbm, lb_vip_t *vip,
   dpo_set(&dpo, dpo_type, proto, *vip_prefix_index);
   fib_table_entry_special_dpo_add(0,
                                   &pfx,
-                                  FIB_SOURCE_PLUGIN_HI,
+                                  lb_fib_src,
                                   FIB_ENTRY_FLAG_EXCLUSIVE,
                                   &dpo);
   dpo_reset(&dpo);
@@ -1037,7 +1040,7 @@ static void lb_vip_del_adjacency(lb_main_t *lbm, lb_vip_t *vip)
       pfx.fp_len = vip->plen;
       pfx.fp_proto = FIB_PROTOCOL_IP6;
   }
-  fib_table_entry_special_remove(0, &pfx, FIB_SOURCE_PLUGIN_HI);
+  fib_table_entry_special_remove(0, &pfx, lb_fib_src);
 }
 
 int lb_vip_add(lb_vip_add_args_t args, u32 *vip_index)
@@ -1445,6 +1448,11 @@ lb_init (vlib_main_t * vm)
 #define _(a,b,c) lbm->vip_counters[c].name = b;
   lb_foreach_vip_counter
 #undef _
+
+  lb_fib_src = fib_source_allocate("lb",
+                                   FIB_SOURCE_PRIORITY_HI,
+                                   FIB_SOURCE_BH_SIMPLE);
+
   return NULL;
 }
 
index 339c12c..d9a1729 100644 (file)
@@ -109,7 +109,7 @@ dslite_set_aftr_ip6_addr (dslite_main_t * dm, ip6_address_t * addr)
        .fp_len = 0,
        .fp_addr.ip4.as_u32 = 0,
       };
-      fib_table_entry_special_dpo_add (0, &pfx, FIB_SOURCE_PLUGIN_HI,
+      fib_table_entry_special_dpo_add (0, &pfx, nat_fib_src_hi,
                                       FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
     }
   else
@@ -121,7 +121,7 @@ dslite_set_aftr_ip6_addr (dslite_main_t * dm, ip6_address_t * addr)
        .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
        .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
       };
-      fib_table_entry_special_dpo_add (0, &pfx, FIB_SOURCE_PLUGIN_HI,
+      fib_table_entry_special_dpo_add (0, &pfx, nat_fib_src_hi,
                                       FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
     }
 
@@ -153,7 +153,7 @@ dslite_set_b4_ip6_addr (dslite_main_t * dm, ip6_address_t * addr)
        .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
        .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
       };
-      fib_table_entry_special_dpo_add (0, &pfx, FIB_SOURCE_PLUGIN_HI,
+      fib_table_entry_special_dpo_add (0, &pfx, nat_fib_src_hi,
                                       FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
 
       dpo_reset (&dpo);
@@ -218,7 +218,7 @@ dslite_add_del_pool_addr (dslite_main_t * dm, ip4_address_t * addr, u8 is_add)
       foreach_snat_protocol
 #undef _
        dslite_dpo_create (DPO_PROTO_IP4, 0, &dpo_v4);
-      fib_table_entry_special_dpo_add (0, &pfx, FIB_SOURCE_PLUGIN_HI,
+      fib_table_entry_special_dpo_add (0, &pfx, nat_fib_src_hi,
                                       FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4);
       dpo_reset (&dpo_v4);
     }
@@ -231,7 +231,7 @@ dslite_add_del_pool_addr (dslite_main_t * dm, ip4_address_t * addr, u8 is_add)
       vec_free (a->busy_##n##_ports_per_thread);
       foreach_snat_protocol
 #undef _
-       fib_table_entry_special_remove (0, &pfx, FIB_SOURCE_PLUGIN_HI);
+       fib_table_entry_special_remove (0, &pfx, nat_fib_src_hi);
       vec_del1 (dm->addr_pool, i);
     }
   return 0;
index 0a30caf..d713368 100755 (executable)
@@ -38,6 +38,9 @@
 
 snat_main_t snat_main;
 
+fib_source_t nat_fib_src_hi;
+fib_source_t nat_fib_src_low;
+
 /* *INDENT-OFF* */
 /* Hook up input features */
 VNET_FEATURE_INIT (nat_pre_in2out, static) = {
@@ -536,7 +539,7 @@ snat_add_del_addr_to_fib (ip4_address_t * addr, u8 p_len, u32 sw_if_index,
   if (is_add)
     fib_table_entry_update_one_path (fib_index,
                                     &prefix,
-                                    FIB_SOURCE_PLUGIN_LOW,
+                                    nat_fib_src_low,
                                     (FIB_ENTRY_FLAG_CONNECTED |
                                      FIB_ENTRY_FLAG_LOCAL |
                                      FIB_ENTRY_FLAG_EXCLUSIVE),
@@ -545,7 +548,7 @@ snat_add_del_addr_to_fib (ip4_address_t * addr, u8 p_len, u32 sw_if_index,
                                     sw_if_index,
                                     ~0, 1, NULL, FIB_ROUTE_PATH_FLAG_NONE);
   else
-    fib_table_entry_delete (fib_index, &prefix, FIB_SOURCE_PLUGIN_LOW);
+    fib_table_entry_delete (fib_index, &prefix, nat_fib_src_low);
 }
 
 int
@@ -577,7 +580,7 @@ snat_add_address (snat_main_t * sm, ip4_address_t * addr, u32 vrf_id,
   if (vrf_id != ~0)
     ap->fib_index =
       fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id,
-                                        FIB_SOURCE_PLUGIN_LOW);
+                                        nat_fib_src_low);
   else
     ap->fib_index = ~0;
 #define _(N, i, n, s) \
@@ -813,7 +816,7 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
              local->vrf_id = vrf_id;
              local->fib_index =
                fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id,
-                                                  FIB_SOURCE_PLUGIN_LOW);
+                                                  nat_fib_src_low);
              m_key.addr = m->local_addr;
              m_key.port = m->local_port;
              m_key.protocol = m->proto;
@@ -834,13 +837,13 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
       if (vrf_id != ~0)
        fib_index =
          fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id,
-                                            FIB_SOURCE_PLUGIN_LOW);
+                                            nat_fib_src_low);
       /* If not specified use inside VRF id from SNAT plugin startup config */
       else
        {
          fib_index = sm->inside_fib_index;
          vrf_id = sm->inside_vrf_id;
-         fib_table_lock (fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_PLUGIN_LOW);
+         fib_table_lock (fib_index, FIB_PROTOCOL_IP4, nat_fib_src_low);
        }
 
       if (!(out2in_only || identity_nat))
@@ -1133,7 +1136,7 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
            }
        }
 
-      fib_table_unlock (fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_PLUGIN_LOW);
+      fib_table_unlock (fib_index, FIB_PROTOCOL_IP4, nat_fib_src_low);
       if (pool_elts (m->locals))
        return 0;
 
@@ -1291,7 +1294,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
          locals[i].fib_index =
            fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
                                               locals[i].vrf_id,
-                                              FIB_SOURCE_PLUGIN_LOW);
+                                              nat_fib_src_low);
          m_key.addr = locals[i].addr;
          m_key.fib_index = locals[i].fib_index;
          if (!out2in_only)
@@ -1381,7 +1384,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
       pool_foreach (local, m->locals,
       ({
           fib_table_unlock (local->fib_index, FIB_PROTOCOL_IP4,
-                            FIB_SOURCE_PLUGIN_LOW);
+                            nat_fib_src_low);
           m_key.addr = local->addr;
           if (!out2in_only)
             {
@@ -1514,7 +1517,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
       local->vrf_id = vrf_id;
       local->fib_index =
        fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id,
-                                          FIB_SOURCE_PLUGIN_LOW);
+                                          nat_fib_src_low);
 
       if (!is_out2in_only_static_mapping (m))
        {
@@ -1536,7 +1539,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
        return VNET_API_ERROR_UNSPECIFIED;
 
       fib_table_unlock (match_local->fib_index, FIB_PROTOCOL_IP4,
-                       FIB_SOURCE_PLUGIN_LOW);
+                       nat_fib_src_low);
 
       if (!is_out2in_only_static_mapping (m))
        {
@@ -1687,7 +1690,7 @@ snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm,
     }
 
   if (a->fib_index != ~0)
-    fib_table_unlock (a->fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_PLUGIN_LOW);
+    fib_table_unlock (a->fib_index, FIB_PROTOCOL_IP4, nat_fib_src_low);
 
   /* Delete sessions using address */
   if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports)
@@ -2464,6 +2467,13 @@ snat_init (vlib_main_t * vm)
   };
   vec_add1 (ip4_main.table_bind_callbacks, cbt4);
 
+  nat_fib_src_hi = fib_source_allocate ("nat-hi",
+                                       FIB_SOURCE_PRIORITY_HI,
+                                       FIB_SOURCE_BH_SIMPLE);
+  nat_fib_src_low = fib_source_allocate ("nat-low",
+                                        FIB_SOURCE_PRIORITY_LOW,
+                                        FIB_SOURCE_BH_SIMPLE);
+
   /* Init virtual fragmenentation reassembly */
   return nat_reass_init (vm);
 }
@@ -2915,13 +2925,13 @@ nat44_add_del_address_dpo (ip4_address_t addr, u8 is_add)
   if (is_add)
     {
       nat_dpo_create (DPO_PROTO_IP4, 0, &dpo_v4);
-      fib_table_entry_special_dpo_add (0, &pfx, FIB_SOURCE_PLUGIN_HI,
+      fib_table_entry_special_dpo_add (0, &pfx, nat_fib_src_hi,
                                       FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4);
       dpo_reset (&dpo_v4);
     }
   else
     {
-      fib_table_entry_special_remove (0, &pfx, FIB_SOURCE_PLUGIN_HI);
+      fib_table_entry_special_remove (0, &pfx, nat_fib_src_hi);
     }
 }
 
@@ -3836,15 +3846,15 @@ snat_config (vlib_main_t * vm, unformat_input_t * input)
   sm->outside_vrf_id = outside_vrf_id;
   sm->outside_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
                                                             outside_vrf_id,
-                                                            FIB_SOURCE_PLUGIN_HI);
+                                                            nat_fib_src_hi);
   nm->outside_vrf_id = outside_ip6_vrf_id;
   nm->outside_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6,
                                                             outside_ip6_vrf_id,
-                                                            FIB_SOURCE_PLUGIN_HI);
+                                                            nat_fib_src_hi);
   sm->inside_vrf_id = inside_vrf_id;
   sm->inside_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
                                                            inside_vrf_id,
-                                                           FIB_SOURCE_PLUGIN_HI);
+                                                           nat_fib_src_hi);
   sm->static_mapping_only = static_mapping_only;
   sm->static_mapping_connection_tracking = static_mapping_connection_tracking;
 
index b65ad1b..ee712f4 100644 (file)
@@ -23,6 +23,7 @@
 #include <vnet/ethernet/ethernet.h>
 #include <vnet/ip/icmp46_packet.h>
 #include <vnet/api_errno.h>
+#include <vnet/fib/fib_source.h>
 #include <vppinfra/elog.h>
 #include <vppinfra/bihash_8_8.h>
 #include <vppinfra/bihash_16_8.h>
@@ -742,6 +743,9 @@ extern vlib_node_registration_t nat44_ed_in2out_worker_handoff_node;
 extern vlib_node_registration_t nat44_ed_in2out_output_worker_handoff_node;
 extern vlib_node_registration_t nat44_ed_out2in_worker_handoff_node;
 
+extern fib_source_t nat_fib_src_hi;
+extern fib_source_t nat_fib_src_low;
+
 /* format functions */
 format_function_t format_snat_user;
 format_function_t format_snat_static_mapping;
index 0fe2980..e1afea6 100644 (file)
@@ -343,7 +343,7 @@ nat64_add_del_pool_addr (u32 thread_index,
       if (vrf_id != ~0)
        a->fib_index =
          fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id,
-                                            FIB_SOURCE_PLUGIN_HI);
+                                            nat_fib_src_hi);
 #define _(N, id, n, s) \
       clib_bitmap_alloc (a->busy_##n##_port_bitmap, 65535); \
       a->busy_##n##_ports = 0; \
@@ -357,8 +357,7 @@ nat64_add_del_pool_addr (u32 thread_index,
        return VNET_API_ERROR_NO_SUCH_ENTRY;
 
       if (a->fib_index != ~0)
-       fib_table_unlock (a->fib_index, FIB_PROTOCOL_IP6,
-                         FIB_SOURCE_PLUGIN_HI);
+       fib_table_unlock (a->fib_index, FIB_PROTOCOL_IP6, nat_fib_src_hi);
       /* Delete sessions using address */
         /* *INDENT-OFF* */
         vec_foreach (db, nm->db)
@@ -688,7 +687,7 @@ nat64_add_del_static_bib_entry (ip6_address_t * in_addr,
   nat64_main_t *nm = &nat64_main;
   nat64_db_bib_entry_t *bibe;
   u32 fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id,
-                                                    FIB_SOURCE_PLUGIN_HI);
+                                                    nat_fib_src_hi);
   snat_protocol_t p = ip_proto_to_snat_proto (proto);
   ip46_address_t addr;
   int i;
@@ -1027,7 +1026,7 @@ nat64_add_del_prefix (ip6_address_t * prefix, u8 plen, u32 vrf_id, u8 is_add)
          vec_add2 (nm->pref64, p, 1);
          p->fib_index =
            fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id,
-                                              FIB_SOURCE_PLUGIN_HI);
+                                              nat_fib_src_hi);
          p->vrf_id = vrf_id;
        }
 
index 53152f1..be468df 100644 (file)
@@ -633,9 +633,9 @@ nat64_add_del_prefix_command_fn (vlib_main_t * vm, unformat_input_t * input,
        {
          fib_index =
            fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6,
-                                              vrf_id, FIB_SOURCE_PLUGIN_HI);
+                                              vrf_id, nat_fib_src_hi);
          fib_table_entry_update_one_path (fib_index, &fibpfx,
-                                          FIB_SOURCE_PLUGIN_HI,
+                                          nat_fib_src_hi,
                                           FIB_ENTRY_FLAG_NONE,
                                           DPO_PROTO_IP6, NULL,
                                           sw_if_index, ~0, 0,
@@ -645,12 +645,11 @@ nat64_add_del_prefix_command_fn (vlib_main_t * vm, unformat_input_t * input,
        {
          fib_index = fib_table_find (FIB_PROTOCOL_IP6, vrf_id);
          fib_table_entry_path_remove (fib_index, &fibpfx,
-                                      FIB_SOURCE_PLUGIN_HI,
+                                      nat_fib_src_hi,
                                       DPO_PROTO_IP6, NULL,
                                       sw_if_index, ~0, 1,
                                       FIB_ROUTE_PATH_INTF_RX);
-         fib_table_unlock (fib_index, FIB_PROTOCOL_IP6,
-                           FIB_SOURCE_PLUGIN_HI);
+         fib_table_unlock (fib_index, FIB_PROTOCOL_IP6, nat_fib_src_hi);
        }
     }
 
index 2caefab..e5e783b 100644 (file)
@@ -170,7 +170,7 @@ nat66_static_mapping_add_del (ip6_address_t * l_addr, ip6_address_t * e_addr,
        return VNET_API_ERROR_VALUE_EXIST;
 
       fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id,
-                                                    FIB_SOURCE_PLUGIN_HI);
+                                                    nat_fib_src_hi);
       pool_get (nm->sm, sm);
       clib_memset (sm, 0, sizeof (*sm));
       sm->l_addr.as_u64[0] = l_addr->as_u64[0];
@@ -214,8 +214,7 @@ nat66_static_mapping_add_del (ip6_address_t * l_addr, ip6_address_t * e_addr,
       kv.key[2] = sm_key.as_u64[2];
       if (clib_bihash_add_del_24_8 (&nm->sm_e, &kv, 0))
        nat_elog_warn ("nat66-static-map-by-external delete key failed");
-      fib_table_unlock (sm->fib_index, FIB_PROTOCOL_IP6,
-                       FIB_SOURCE_PLUGIN_HI);
+      fib_table_unlock (sm->fib_index, FIB_PROTOCOL_IP6, nat_fib_src_hi);
       pool_put (nm->sm, sm);
     }
 
index 2d63b3e..1f8a728 100644 (file)
@@ -37,6 +37,8 @@
 
 pppoe_main_t pppoe_main;
 
+static fib_source_t pppoe_fib_src;
+
 u8 *
 format_pppoe_session (u8 * s, va_list * args)
 {
@@ -376,7 +378,7 @@ int vnet_pppoe_add_del_session
 
       /* add reverse route for client ip */
       fib_table_entry_path_add (a->decap_fib_index, &pfx,
-                               FIB_SOURCE_PLUGIN_HI, FIB_ENTRY_FLAG_NONE,
+                               pppoe_fib_src, FIB_ENTRY_FLAG_NONE,
                                fib_proto_to_dpo (pfx.fp_proto),
                                &pfx.fp_addr, sw_if_index, ~0,
                                1, NULL, FIB_ROUTE_PATH_FLAG_NONE);
@@ -408,7 +410,7 @@ int vnet_pppoe_add_del_session
 
       /* delete reverse route for client ip */
       fib_table_entry_path_remove (a->decap_fib_index, &pfx,
-                                  FIB_SOURCE_PLUGIN_HI,
+                                  pppoe_fib_src,
                                   fib_proto_to_dpo (pfx.fp_proto),
                                   &pfx.fp_addr,
                                   sw_if_index, ~0, 1,
@@ -721,6 +723,10 @@ pppoe_init (vlib_main_t * vm)
   ethernet_register_input_type (vm, ETHERNET_TYPE_PPPOE_DISCOVERY,
                                pppoe_cp_dispatch_node.index);
 
+  pppoe_fib_src = fib_source_allocate ("pppoe",
+                                      FIB_SOURCE_PRIORITY_HI,
+                                      FIB_SOURCE_BH_API);
+
   return 0;
 }
 
index 8c1487c..5552833 100644 (file)
 
 u32 *svs_itf_db[FIB_PROTOCOL_IP_MAX];
 
+static fib_source_t svs_fib_src;
+
 int
 svs_table_add (fib_protocol_t fproto, u32 table_id)
 {
-  fib_table_find_or_create_and_lock (fproto, table_id, FIB_SOURCE_PLUGIN_LOW);
+  fib_table_find_or_create_and_lock (fproto, table_id, svs_fib_src);
 
   return (0);
 }
@@ -50,7 +52,7 @@ svs_table_delete (fib_protocol_t fproto, u32 table_id)
   if (~0 == fib_index)
     return VNET_API_ERROR_NO_SUCH_FIB;
 
-  fib_table_unlock (fib_index, fproto, FIB_SOURCE_PLUGIN_LOW);
+  fib_table_unlock (fib_index, fproto, svs_fib_src);
 
   return (0);
 }
@@ -68,7 +70,7 @@ svs_route_add_i (u32 fib_index, const fib_prefix_t * pfx, u32 src_fib_index)
                                      LOOKUP_TABLE_FROM_CONFIG, &dpo);
 
   fib_table_entry_special_dpo_add (fib_index, pfx,
-                                  FIB_SOURCE_PLUGIN_LOW,
+                                  svs_fib_src,
                                   FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
 
   dpo_unlock (&dpo);
@@ -107,7 +109,7 @@ svs_route_delete (u32 table_id, const fib_prefix_t * pfx)
   if (~0 == fib_index)
     return VNET_API_ERROR_NO_SUCH_FIB;
 
-  fib_table_entry_special_remove (fib_index, pfx, FIB_SOURCE_PLUGIN_LOW);
+  fib_table_entry_special_remove (fib_index, pfx, svs_fib_src);
 
   return (0);
 }
@@ -214,7 +216,7 @@ svs_disable (fib_protocol_t fproto, u32 table_id, u32 sw_if_index)
                                "svs-ip4" :
                                "svs-ip6"), sw_if_index, 0, NULL, 0);
 
-  fib_table_entry_special_remove (fib_index, &pfx, FIB_SOURCE_PLUGIN_LOW);
+  fib_table_entry_special_remove (fib_index, &pfx, svs_fib_src);
 
   return (0);
 }
@@ -607,6 +609,10 @@ svs_init (vlib_main_t * vm)
   };
   vec_add1 (ip4_main.table_bind_callbacks, cbt4);
 
+  svs_fib_src = fib_source_allocate ("svs",
+                                    FIB_SOURCE_PRIORITY_LOW,
+                                    FIB_SOURCE_BH_SIMPLE);
+
   return (NULL);
 }
 
index f220eb0..2d75f28 100644 (file)
@@ -9310,13 +9310,16 @@ fib_test_inherit (void)
              "%U via 10.10.10.2",
              format_fib_prefix, &pfx_10_10_10_0_s_24);
 
+    fib_source_t hi_src = fib_source_allocate("test", 0x50,
+                                              FIB_SOURCE_BH_SIMPLE);
+
     /*
      * add the source that replaces inherited state.
      * inheriting source is not the best, so it doesn't push state.
      */
     fib_table_entry_update_one_path(0,
                                     &pfx_10_10_10_0_s_24,
-                                    FIB_SOURCE_PLUGIN_HI,
+                                    hi_src,
                                     FIB_ENTRY_FLAG_NONE,
                                     DPO_PROTO_IP4,
                                     &nh_10_10_10_1,
@@ -9354,7 +9357,7 @@ fib_test_inherit (void)
      * withdraw the higher priority source and expect the inherited to return
      * throughout the sub-tree
      */
-    fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_PLUGIN_HI);
+    fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, hi_src);
 
     fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
     FIB_TEST(!fib_test_validate_entry(fei,
index 1182773..21653ab 100644 (file)
@@ -1248,21 +1248,22 @@ list(APPEND VNET_SOURCES
   fib/fib_node_list.c
   fib/fib_entry.c
   fib/fib_entry_src.c
-  fib/fib_entry_src_rr.c
+  fib/fib_entry_src_adj.c
+  fib/fib_entry_src_api.c
+  fib/fib_entry_src_drop.c
   fib/fib_entry_src_interface.c
   fib/fib_entry_src_interpose.c
-  fib/fib_entry_src_default_route.c
-  fib/fib_entry_src_special.c
-  fib/fib_entry_src_api.c
-  fib/fib_entry_src_adj.c
-  fib/fib_entry_src_mpls.c
   fib/fib_entry_src_lisp.c
+  fib/fib_entry_src_mpls.c
+  fib/fib_entry_src_simple.c
+  fib/fib_entry_src_rr.c
   fib/fib_entry_cover.c
   fib/fib_entry_delegate.c
   fib/fib_entry_track.c
   fib/fib_path_list.c
   fib/fib_path.c
   fib/fib_path_ext.c
+  fib/fib_source.c
   fib/fib_urpf_list.c
   fib/fib_attached_export.c
   fib/fib_api.c
@@ -1280,6 +1281,7 @@ list(APPEND VNET_HEADERS
   fib/fib_node_list.h
   fib/fib_entry.h
   fib/fib_entry_delegate.h
+  fib/fib_source.h
 )
 
 list(APPEND VNET_API_FILES fib/fib_types.api)
index 28e18dd..ddfa830 100644 (file)
@@ -22,6 +22,7 @@
 static clib_error_t *
 fib_module_init (vlib_main_t * vm)
 {
+    fib_source_module_init();
     fib_entry_module_init();
     fib_entry_src_module_init();
     fib_path_module_init();
index fd69db9..0e54828 100644 (file)
@@ -34,7 +34,6 @@
 /*
  * Array of strings/names for the FIB sources
  */
-static const char *fib_source_names[] = FIB_SOURCES;
 static const char *fib_attribute_names[] = FIB_ENTRY_ATTRIBUTES;
 static const char *fib_src_attribute_names[] = FIB_ENTRY_SRC_ATTRIBUTES;
 
@@ -97,16 +96,6 @@ fib_entry_get_default_chain_type (const fib_entry_t *fib_entry)
     return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
 }
 
-u8 *
-format_fib_source (u8 * s, va_list * args)
-{
-    fib_source_t source = va_arg (*args, int);
-
-    s = format (s, "src:%s", fib_source_names[source]);
-
-    return (s);
-}
-
 u8 *
 format_fib_entry_flags (u8 *s, va_list *args)
 {
@@ -285,7 +274,7 @@ fib_entry_src_get_source (const fib_entry_src_t *esrc)
     {
        return (esrc->fes_src);
     }
-    return (FIB_SOURCE_MAX);
+    return (FIB_SOURCE_INVALID);
 }
 
 static fib_entry_flag_t
@@ -836,16 +825,17 @@ fib_entry_source_change_w_flags (fib_entry_t *fib_entry,
                                  fib_entry_flag_t old_flags,
                                  fib_source_t new_source)
 {
-    if (new_source < old_source)
+    switch (fib_source_cmp(new_source, old_source))
     {
+    case FIB_SOURCE_CMP_BETTER:
        /*
         * we have a new winning source.
         */
        fib_entry_src_action_deactivate(fib_entry, old_source);
        fib_entry_src_action_activate(fib_entry, new_source);
-    }
-    else if (new_source > old_source)
-    {
+        break;
+
+    case FIB_SOURCE_CMP_WORSE:
         /*
          * the new source loses. Re-activate the winning sources
          * in case it is an interposer and hence relied on the losing
@@ -853,15 +843,15 @@ fib_entry_source_change_w_flags (fib_entry_t *fib_entry,
          */
         fib_entry_src_action_reactivate(fib_entry, old_source);
         return;
-    }
-    else
-    {
+
+    case FIB_SOURCE_CMP_EQUAL:
        /*
         * the new source is one this entry already has.
         * But the path-list was updated, which will contribute new forwarding,
         * so install it.
         */
         fib_entry_src_action_reactivate(fib_entry, new_source);
+        break;
     }
 
     fib_entry_post_update_actions(fib_entry, new_source, old_flags);
@@ -984,7 +974,7 @@ fib_entry_source_removed (fib_entry_t *fib_entry,
     bsrc = fib_entry_get_best_src_i(fib_entry);
     best_source = fib_entry_src_get_source(bsrc);
 
-    if (FIB_SOURCE_MAX == best_source)
+    if (FIB_SOURCE_INVALID == best_source)
     {
         /*
          * no more sources left. this entry is toast.
@@ -1040,16 +1030,16 @@ fib_entry_path_remove (fib_node_index_t fib_entry_index,
      * then we need to create a new one. else we are updating
      * an existing.
      */
-    if (source < best_source)
+    switch (fib_source_cmp(source, best_source))
     {
+    case FIB_SOURCE_CMP_BETTER:
        /*
         * Que! removing a path from a source that is better than the
         * one this entry is using.
         */
        ASSERT(0);
-    }
-    else if (source > best_source )
-    {
+        break;
+    case FIB_SOURCE_CMP_WORSE:
        /*
         * the source is not the best. no need to update forwarding
         */
@@ -1067,10 +1057,9 @@ fib_entry_path_remove (fib_node_index_t fib_entry_index,
              * that remain are non-inherited
              */
             return (fib_entry_src_burn_only_inherited(fib_entry));
-       }
-    }
-    else
-    {
+        }
+        break;
+    case FIB_SOURCE_CMP_EQUAL:
        /*
         * removing a path from the path-list we were using.
         */
@@ -1089,6 +1078,7 @@ fib_entry_path_remove (fib_node_index_t fib_entry_index,
             */
            fib_entry_src_action_reactivate(fib_entry, source);
        }
+        break;
     }
 
     fib_entry_post_update_actions(fib_entry, source, bflags);
@@ -1131,16 +1121,17 @@ fib_entry_special_remove (fib_node_index_t fib_entry_index,
      * then we need to create a new one. else we are updating
      * an existing.
      */
-    if (source < best_source )
+    switch (fib_source_cmp(source, best_source))
     {
+    case FIB_SOURCE_CMP_BETTER:
        /*
         * Que! removing a path from a source that is better than the
         * one this entry is using. This can only mean it is a source
          * this prefix does not have.
         */
         return (FIB_ENTRY_SRC_FLAG_ADDED);
-    }
-    else if (source > best_source ) {
+
+    case FIB_SOURCE_CMP_WORSE:
        /*
         * the source is not the best. no need to update forwarding
         */
@@ -1174,9 +1165,9 @@ fib_entry_special_remove (fib_node_index_t fib_entry_index,
 
             return (FIB_ENTRY_SRC_FLAG_ADDED);
         }
-    }
-    else
-    {
+        break;
+
+    case FIB_SOURCE_CMP_EQUAL:
        if (!(FIB_ENTRY_SRC_FLAG_ADDED & sflag))
        {
            /*
@@ -1191,6 +1182,7 @@ fib_entry_special_remove (fib_node_index_t fib_entry_index,
             */
            fib_entry_src_action_reactivate(fib_entry, source);
        }
+        break;
     }
 
     fib_entry_post_update_actions(fib_entry, source, bflags);
index f0e6e8d..b97c80f 100644 (file)
 #define __FIB_ENTRY_H__
 
 #include <vnet/fib/fib_node.h>
+#include <vnet/fib/fib_source.h>
 #include <vnet/adj/adj.h>
 #include <vnet/ip/ip.h>
 #include <vnet/dpo/dpo.h>
 
-/**
- * The different sources that can create a route.
- * The sources are defined here with their relative priority order.
- * The lower the value the higher the priority
- */
-typedef enum fib_source_t_ {
-    /**
-     * An invalid source
-     * This is not a real source, so don't use it to source a prefix.
-     * It exists here to provide a value for inexistant/uninitialized source
-     */
-    FIB_SOURCE_INVALID = 0,
-    /**
-     * Marker. Add new values after this one.
-     */
-    FIB_SOURCE_FIRST,
-    /**
-     * Special sources. These are for entries that are added to all
-     * FIBs by default, and should never be over-ridden (hence they
-     * are the highest priority)
-     */
-    FIB_SOURCE_SPECIAL = FIB_SOURCE_FIRST,
-    /**
-     * Classify. A route that links directly to a classify adj
-     */
-    FIB_SOURCE_CLASSIFY,
-    /**
-     * A route the is being 'proxied' on behalf of another device
-     */
-    FIB_SOURCE_PROXY,
-    /**
-     * Route added as a result of interface configuration.
-     * this will also come from the API/CLI, but the distinction is
-     * that is from confiiguration on an interface, not a 'ip route' command
-     */
-    FIB_SOURCE_INTERFACE,
-    /**
-     * SRv6 and SR-MPLS
-     */
-    FIB_SOURCE_SR,
-    /**
-     * A high priority source a plugin can use
-     */
-    FIB_SOURCE_PLUGIN_HI,
-    /**
-     * From the BIER subsystem
-     */
-    FIB_SOURCE_BIER,
-    /**
-     * From 6RD.
-     */
-    FIB_SOURCE_6RD,
-    /**
-     * From the control plane API
-     */
-    FIB_SOURCE_API,
-    /**
-     * From the CLI.
-     */
-    FIB_SOURCE_CLI,
-    /**
-     * A low (below routing) priority source a plugin can use
-     */
-    FIB_SOURCE_PLUGIN_LOW,
-    /**
-     * LISP
-     */
-    FIB_SOURCE_LISP,
-    /**
-     * IPv[46] Mapping
-     */
-    FIB_SOURCE_MAP,
-    /**
-     * DHCP
-     */
-    FIB_SOURCE_DHCP,
-    /**
-     * IPv6 Proxy ND
-     */
-    FIB_SOURCE_IP6_ND_PROXY,
-    /**
-     * IPv6 ND (seen in the link-local tables)
-     */
-    FIB_SOURCE_IP6_ND,
-    /**
-     * Adjacency source.
-     * routes created as a result of ARP/ND entries. This is lower priority
-     * then the API/CLI. This is on purpose. trust me.
-     */
-    FIB_SOURCE_ADJ,
-    /**
-     * MPLS label. The prefix has been assigned a local label. This source
-     * never provides forwarding information, instead it acts as a place-holder
-     * so the association of label to prefix can be maintained
-     */
-    FIB_SOURCE_MPLS,
-    /**
-     * Attached Export source.
-     * routes created as a result of attahced export. routes thus sourced
-     * will be present in the export tables
-     */
-    FIB_SOURCE_AE,
-    /**
-     * Recursive resolution source.
-     * Used to install an entry that is the resolution traget of another.
-     */
-    FIB_SOURCE_RR,
-    /**
-     * uRPF bypass/exemption.
-     * Used to install an entry that is exempt from the loose uRPF check
-     */
-    FIB_SOURCE_URPF_EXEMPT,
-    /**
-     * The default route source.
-     * The default route is always added to the FIB table (like the
-     * special sources) but we need to be able to over-ride it with
-     * 'ip route' sources when provided
-     */
-    FIB_SOURCE_DEFAULT_ROUTE,
-    /**
-     * The interpose source.
-     * This is not a real source, so don't use it to source a prefix.
-     * It exists here to provide a value against which to register to the
-     * VFT for providing the interpose actions to a real source.
-     */
-    FIB_SOURCE_INTERPOSE,
-    /**
-     * Marker. add new entries before this one.
-     */
-    FIB_SOURCE_LAST = FIB_SOURCE_INTERPOSE,
-} __attribute__ ((packed)) fib_source_t;
-
-STATIC_ASSERT (sizeof(fib_source_t) == 1,
-              "FIB too many sources");
-
-/**
- * The maximum number of sources
- */
-#define FIB_SOURCE_MAX (FIB_SOURCE_LAST+1)
-
-#define FIB_SOURCES {                                  \
-    [FIB_SOURCE_INVALID] = "invalid",                  \
-    [FIB_SOURCE_SPECIAL] = "special",                  \
-    [FIB_SOURCE_INTERFACE] = "interface",              \
-    [FIB_SOURCE_PROXY] = "proxy",                       \
-    [FIB_SOURCE_BIER] = "BIER",                                \
-    [FIB_SOURCE_6RD] = "6RD",                          \
-    [FIB_SOURCE_API] = "API",                          \
-    [FIB_SOURCE_CLI] = "CLI",                          \
-    [FIB_SOURCE_ADJ] = "adjacency",                    \
-    [FIB_SOURCE_MAP] = "MAP",                          \
-    [FIB_SOURCE_SR] = "SR",                            \
-    [FIB_SOURCE_LISP] = "LISP",                        \
-    [FIB_SOURCE_CLASSIFY] = "classify",                        \
-    [FIB_SOURCE_DHCP] = "DHCP",                        \
-    [FIB_SOURCE_IP6_ND_PROXY] = "IPv6-proxy-nd",        \
-    [FIB_SOURCE_IP6_ND] = "IPv6-nd",                    \
-    [FIB_SOURCE_RR] = "recursive-resolution",          \
-    [FIB_SOURCE_AE] = "attached_export",               \
-    [FIB_SOURCE_MPLS] = "mpls",                        \
-    [FIB_SOURCE_URPF_EXEMPT] = "urpf-exempt",          \
-    [FIB_SOURCE_DEFAULT_ROUTE] = "default-route",      \
-    [FIB_SOURCE_PLUGIN_HI] = "plugin-hi",               \
-    [FIB_SOURCE_PLUGIN_LOW] = "plugin-low",             \
-    [FIB_SOURCE_INTERPOSE] = "interpose",               \
-}
-
-#define FOR_EACH_FIB_SOURCE(_item) \
-    for (_item = FIB_SOURCE_FIRST; _item < FIB_SOURCE_MAX; _item++)
-
 /**
  * The different sources that can create a route.
  * The sources are defined here with their relative priority order.
index 176818a..d534135 100644 (file)
@@ -28,7 +28,7 @@
 /*
  * per-source type vft
  */
-static fib_entry_src_vft_t fib_entry_src_vft[FIB_SOURCE_MAX];
+static fib_entry_src_vft_t fib_entry_src_bh_vft[FIB_SOURCE_BH_MAX];
 
 /**
  * Get the VFT for a given source. This is a combination of the source
@@ -37,12 +37,16 @@ static fib_entry_src_vft_t fib_entry_src_vft[FIB_SOURCE_MAX];
 const fib_entry_src_vft_t*
 fib_entry_src_get_vft (const fib_entry_src_t *esrc)
 {
+    fib_source_behaviour_t bh;
+
+    bh = fib_source_get_behaviour(esrc->fes_src);
+
     if (esrc->fes_entry_flags & FIB_ENTRY_FLAG_INTERPOSE)
     {
-        return (&fib_entry_src_vft[FIB_SOURCE_INTERPOSE]);
+        return (&fib_entry_src_bh_vft[FIB_SOURCE_BH_INTERPOSE]);
     }
 
-    return (&fib_entry_src_vft[esrc->fes_src]);
+    return (&fib_entry_src_bh_vft[bh]);
 }
 
 static void
@@ -54,14 +58,14 @@ fib_entry_src_copy_default (const fib_entry_src_t *orig_src,
 }
 
 void
-fib_entry_src_register (fib_source_t source,
-                       const fib_entry_src_vft_t *vft)
+fib_entry_src_behaviour_register (fib_source_behaviour_t bh,
+                                  const fib_entry_src_vft_t *vft)
 {
-    fib_entry_src_vft[source] = *vft;
+    fib_entry_src_bh_vft[bh] = *vft;
 
-    if (NULL == fib_entry_src_vft[source].fesv_copy)
+    if (NULL == fib_entry_src_bh_vft[bh].fesv_copy)
     {
-        fib_entry_src_vft[source].fesv_copy = fib_entry_src_copy_default;
+        fib_entry_src_bh_vft[bh].fesv_copy = fib_entry_src_copy_default;
     }
 }
 
@@ -71,7 +75,8 @@ fib_entry_src_cmp_for_sort (void * v1,
 {
     fib_entry_src_t *esrc1 = v1, *esrc2 = v2;
 
-    return (esrc1->fes_src - esrc2->fes_src);
+    return (fib_source_get_prio(esrc1->fes_src) -
+            fib_source_get_prio(esrc2->fes_src));
 }
 
 static void
@@ -1925,8 +1930,8 @@ fib_entry_src_module_init (void)
     fib_entry_src_rr_register();
     fib_entry_src_interface_register();
     fib_entry_src_interpose_register();
-    fib_entry_src_default_route_register();
-    fib_entry_src_special_register();
+    fib_entry_src_drop_register();
+    fib_entry_src_simple_register();
     fib_entry_src_api_register();
     fib_entry_src_adj_register();
     fib_entry_src_mpls_register();
index 8f13ae8..3080057 100644 (file)
@@ -260,8 +260,8 @@ extern u8* fib_entry_src_format(fib_entry_t *entry,
                                fib_source_t source,
                                u8* s);
 
-extern void fib_entry_src_register(fib_source_t source,
-                                  const fib_entry_src_vft_t *vft);
+extern void fib_entry_src_behaviour_register (fib_source_behaviour_t source,
+                                              const fib_entry_src_vft_t *vft);
 
 extern fib_entry_src_cover_res_t fib_entry_src_action_cover_change(
     fib_entry_t *entry,
@@ -348,8 +348,8 @@ extern void fib_entry_src_default_register(void);
 extern void fib_entry_src_rr_register(void);
 extern void fib_entry_src_interface_register(void);
 extern void fib_entry_src_interpose_register(void);
-extern void fib_entry_src_default_route_register(void);
-extern void fib_entry_src_special_register(void);
+extern void fib_entry_src_drop_register(void);
+extern void fib_entry_src_simple_register(void);
 extern void fib_entry_src_api_register(void);
 extern void fib_entry_src_adj_register(void);
 extern void fib_entry_src_mpls_register(void);
index 2a5b46a..ec80a86 100644 (file)
@@ -411,5 +411,5 @@ const static fib_entry_src_vft_t adj_src_vft = {
 void
 fib_entry_src_adj_register (void)
 {
-    fib_entry_src_register(FIB_SOURCE_ADJ, &adj_src_vft);
+    fib_entry_src_behaviour_register(FIB_SOURCE_BH_ADJ, &adj_src_vft);
 }
index be93cc2..69102a1 100644 (file)
@@ -162,13 +162,5 @@ const static fib_entry_src_vft_t api_src_vft = {
 void
 fib_entry_src_api_register (void)
 {
-    fib_entry_src_register(FIB_SOURCE_PLUGIN_HI, &api_src_vft);
-    fib_entry_src_register(FIB_SOURCE_PLUGIN_LOW, &api_src_vft);
-    fib_entry_src_register(FIB_SOURCE_API, &api_src_vft);
-    fib_entry_src_register(FIB_SOURCE_CLI, &api_src_vft);
-    fib_entry_src_register(FIB_SOURCE_6RD, &api_src_vft);
-    fib_entry_src_register(FIB_SOURCE_DHCP, &api_src_vft);
-    fib_entry_src_register(FIB_SOURCE_IP6_ND_PROXY, &api_src_vft);
-    fib_entry_src_register(FIB_SOURCE_IP6_ND, &api_src_vft);
-    fib_entry_src_register(FIB_SOURCE_SR, &api_src_vft);
+    fib_entry_src_behaviour_register(FIB_SOURCE_BH_API, &api_src_vft);
 }
index 18a039a..534a28c 100644 (file)
@@ -113,9 +113,6 @@ const static fib_entry_src_vft_t default_src_vft = {
 void
 fib_entry_src_default_register (void)
 {
-    fib_source_t source;
-
-    FOR_EACH_FIB_SOURCE(source) {
-       fib_entry_src_register(source, &default_src_vft);    
-    }
+    fib_entry_src_behaviour_register (FIB_SOURCE_BH_DROP,
+                                      &default_src_vft);
 }
similarity index 68%
rename from src/vnet/fib/fib_entry_src_default_route.c
rename to src/vnet/fib/fib_entry_src_drop.c
index 431abb6..8869771 100644 (file)
  * Source initialisation Function 
  */
 static void
-fib_entry_src_default_route_init (fib_entry_src_t *src)
+fib_entry_src_drop_init (fib_entry_src_t *src)
 {
     src->fes_flags = FIB_ENTRY_SRC_FLAG_NONE;
 }
 
 static void
-fib_entry_src_default_route_remove (fib_entry_src_t *src)
+fib_entry_src_drop_remove (fib_entry_src_t *src)
 {
     src->fes_pl = FIB_NODE_INDEX_INVALID;
 }
 
 static void
-fib_entry_src_default_route_add (fib_entry_src_t *src,
+fib_entry_src_drop_add (fib_entry_src_t *src,
                                 const fib_entry_t *entry,
                                 fib_entry_flag_t flags,
                                 dpo_proto_t proto,
@@ -43,16 +43,17 @@ fib_entry_src_default_route_add (fib_entry_src_t *src,
                                               dpo);
 }
 
-const static fib_entry_src_vft_t interface_src_vft = {
-    .fesv_init = fib_entry_src_default_route_init,
-    .fesv_add = fib_entry_src_default_route_add,
-    .fesv_remove = fib_entry_src_default_route_remove,
+const static fib_entry_src_vft_t drop_src_vft = {
+    .fesv_init = fib_entry_src_drop_init,
+    .fesv_add = fib_entry_src_drop_add,
+    .fesv_remove = fib_entry_src_drop_remove,
 };
 
 void
-fib_entry_src_default_route_register (void)
+fib_entry_src_drop_register (void)
 {
-    fib_entry_src_register(FIB_SOURCE_DEFAULT_ROUTE, &interface_src_vft);    
+    fib_entry_src_behaviour_register(FIB_SOURCE_BH_DROP,
+                                     &drop_src_vft);
 }
 
 
index 5d609c5..1400360 100644 (file)
@@ -213,5 +213,6 @@ const static fib_entry_src_vft_t interface_src_vft = {
 void
 fib_entry_src_interface_register (void)
 {
-    fib_entry_src_register(FIB_SOURCE_INTERFACE, &interface_src_vft);    
+    fib_entry_src_behaviour_register(FIB_SOURCE_BH_INTERFACE,
+                                     &interface_src_vft);
 }
index 2220fa4..02db391 100644 (file)
@@ -61,17 +61,17 @@ fib_entry_src_rr_get_next_best (const fib_entry_src_t *src,
         /*
          * skip to the next best source after this one
          */
-        if (source <= src->fes_src)
+        switch (fib_source_cmp(source, src->fes_src))
         {
+        case FIB_SOURCE_CMP_BETTER:
+        case FIB_SOURCE_CMP_EQUAL:
             continue;
-        }
-        else
-        {
+        case FIB_SOURCE_CMP_WORSE:
             best_src = next_src;
-            break;
+            goto out;
         }
     }));
-
+ out:
     return (best_src);
 }
 
@@ -366,5 +366,6 @@ const static fib_entry_src_vft_t interpose_src_vft = {
 void
 fib_entry_src_interpose_register (void)
 {
-    fib_entry_src_register(FIB_SOURCE_INTERPOSE, &interpose_src_vft);
+    fib_entry_src_behaviour_register(FIB_SOURCE_BH_INTERPOSE,
+                                     &interpose_src_vft);
 }
index ec8c467..2fc9c92 100644 (file)
@@ -114,7 +114,7 @@ fib_entry_src_lisp_get_data (fib_entry_src_t *src,
     return (&(src->u.lisp.fesl_fib_index));
 }
 
-const static fib_entry_src_vft_t api_src_vft = {
+const static fib_entry_src_vft_t lisp_src_vft = {
     .fesv_init = fib_entry_src_lisp_init,
     .fesv_deinit = fib_entry_src_lisp_deinit,
     .fesv_add = fib_entry_src_lisp_add,
@@ -129,5 +129,6 @@ const static fib_entry_src_vft_t api_src_vft = {
 void
 fib_entry_src_lisp_register (void)
 {
-    fib_entry_src_register(FIB_SOURCE_LISP, &api_src_vft);
+    fib_entry_src_behaviour_register(FIB_SOURCE_BH_LISP,
+                                     &lisp_src_vft);
 }
index f3d1dc0..7bbe34d 100644 (file)
@@ -193,5 +193,5 @@ const static fib_entry_src_vft_t mpls_src_vft = {
 void
 fib_entry_src_mpls_register (void)
 {
-    fib_entry_src_register(FIB_SOURCE_MPLS, &mpls_src_vft);
+    fib_entry_src_behaviour_register(FIB_SOURCE_BH_MPLS, &mpls_src_vft);
 }
index 9f4f68d..d0256b9 100755 (executable)
@@ -306,6 +306,5 @@ const static fib_entry_src_vft_t rr_src_vft = {
 void
 fib_entry_src_rr_register (void)
 {
-    fib_entry_src_register(FIB_SOURCE_RR, &rr_src_vft);    
-    fib_entry_src_register(FIB_SOURCE_URPF_EXEMPT, &rr_src_vft);    
+    fib_entry_src_behaviour_register(FIB_SOURCE_BH_RR, &rr_src_vft);
 }
diff --git a/src/vnet/fib/fib_entry_src_simple.c b/src/vnet/fib/fib_entry_src_simple.c
new file mode 100644 (file)
index 0000000..2caa4fc
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "fib_entry.h"
+#include "fib_entry_src.h"
+
+/**
+ * Source initialisation Function
+ */
+static void
+fib_entry_src_simple_init (fib_entry_src_t *src)
+{
+    src->fes_flags = FIB_ENTRY_SRC_FLAG_NONE;
+}
+
+/**
+ * Source deinitialisation Function
+ */
+static void
+fib_entry_src_simple_deinit (fib_entry_src_t *src)
+{
+}
+
+static void
+fib_entry_src_simple_remove (fib_entry_src_t *src)
+{
+    src->fes_pl = FIB_NODE_INDEX_INVALID;
+}
+
+static void
+fib_entry_src_simple_add (fib_entry_src_t *src,
+                          const fib_entry_t *entry,
+                          fib_entry_flag_t flags,
+                          dpo_proto_t proto,
+                          const dpo_id_t *dpo)
+{
+    src->fes_pl =
+       fib_path_list_create_special(proto,
+                                     fib_entry_src_flags_2_path_list_flags(flags),
+                                     dpo);
+}
+
+static void
+fib_entry_src_simple_path_swap (fib_entry_src_t *src,
+                                const fib_entry_t *entry,
+                                fib_path_list_flags_t pl_flags,
+                                const fib_route_path_t *rpaths)
+{
+    src->fes_pl = fib_path_list_create((FIB_PATH_LIST_FLAG_SHARED | pl_flags),
+                                      rpaths);
+}
+
+const static fib_entry_src_vft_t simple_src_vft = {
+    .fesv_init = fib_entry_src_simple_init,
+    .fesv_deinit = fib_entry_src_simple_deinit,
+    .fesv_add = fib_entry_src_simple_add,
+    .fesv_remove = fib_entry_src_simple_remove,
+    .fesv_path_swap = fib_entry_src_simple_path_swap,
+};
+
+void
+fib_entry_src_simple_register (void)
+{
+    fib_entry_src_behaviour_register(FIB_SOURCE_BH_SIMPLE, &simple_src_vft);
+}
diff --git a/src/vnet/fib/fib_entry_src_special.c b/src/vnet/fib/fib_entry_src_special.c
deleted file mode 100644 (file)
index c976da9..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "fib_entry.h"
-#include "fib_entry_src.h"
-
-/**
- * Source initialisation Function
- */
-static void
-fib_entry_src_special_init (fib_entry_src_t *src)
-{
-    src->fes_flags = FIB_ENTRY_SRC_FLAG_NONE;
-}
-
-/**
- * Source deinitialisation Function
- */
-static void
-fib_entry_src_special_deinit (fib_entry_src_t *src)
-{
-}
-
-static void
-fib_entry_src_special_remove (fib_entry_src_t *src)
-{
-    src->fes_pl = FIB_NODE_INDEX_INVALID;
-}
-
-static void
-fib_entry_src_special_add (fib_entry_src_t *src,
-                          const fib_entry_t *entry,
-                          fib_entry_flag_t flags,
-                          dpo_proto_t proto,
-                          const dpo_id_t *dpo)
-{
-    src->fes_pl =
-       fib_path_list_create_special(proto,
-                                    fib_entry_src_flags_2_path_list_flags(flags),
-                                    dpo);
-}
-
-static void
-fib_entry_src_special_path_swap (fib_entry_src_t *src,
-                                 const fib_entry_t *entry,
-                                 fib_path_list_flags_t pl_flags,
-                                 const fib_route_path_t *rpaths)
-{
-    src->fes_pl = fib_path_list_create((FIB_PATH_LIST_FLAG_SHARED | pl_flags),
-                                      rpaths);
-}
-
-const static fib_entry_src_vft_t special_src_vft = {
-    .fesv_init = fib_entry_src_special_init,
-    .fesv_deinit = fib_entry_src_special_deinit,
-    .fesv_add = fib_entry_src_special_add,
-    .fesv_remove = fib_entry_src_special_remove,
-    .fesv_path_swap = fib_entry_src_special_path_swap,
-};
-
-void
-fib_entry_src_special_register (void)
-{
-    fib_entry_src_register(FIB_SOURCE_SPECIAL, &special_src_vft);
-    fib_entry_src_register(FIB_SOURCE_MAP, &special_src_vft);
-    fib_entry_src_register(FIB_SOURCE_CLASSIFY, &special_src_vft);
-    fib_entry_src_register(FIB_SOURCE_AE, &special_src_vft);
-    fib_entry_src_register(FIB_SOURCE_PROXY, &special_src_vft);
-    fib_entry_src_register(FIB_SOURCE_BIER, &special_src_vft);
-}
diff --git a/src/vnet/fib/fib_source.c b/src/vnet/fib/fib_source.c
new file mode 100644 (file)
index 0000000..0aeecae
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/fib/fib_source.h>
+
+static const char *fib_source_names[] = FIB_SOURCES;
+static const char *fib_source_behaviour_names[] = FIB_SOURCE_BEHAVIOURS;
+
+static fib_source_t fib_source_id = FIB_SOURCE_LAST+1;
+
+typedef struct fib_source_prio_t_
+{
+    fib_source_priority_t fsp_class;
+    fib_source_priority_t fsp_slot;
+} fib_source_prio_t;
+
+/**
+ * for each client requested priority count the number pf uses of
+ * that prio so we can asign is usage a slot number, and therefore
+ * each request will have a unique value.
+ */
+STATIC_ASSERT_SIZEOF(fib_source_priority_t, 1);
+static fib_source_priority_t fib_source_prio_by_class[0x100];
+
+typedef struct fib_source_reg_t_
+{
+    fib_source_t fsr_source;
+    const char *fsr_name;
+    fib_source_behaviour_t fsr_behaviour;
+    fib_source_prio_t fsr_prio;
+} fib_source_reg_t;
+
+static fib_source_reg_t *fib_source_regs;
+
+
+u16
+fib_source_get_prio (fib_source_t src)
+{
+    ASSERT(vec_len(fib_source_regs) > src);
+
+    return (((u16)fib_source_regs[src].fsr_prio.fsp_class << 8) |
+            fib_source_regs[src].fsr_prio.fsp_slot);
+}
+
+fib_source_behaviour_t
+fib_source_get_behaviour (fib_source_t src)
+{
+    ASSERT(vec_len(fib_source_regs) > src);
+
+    return (fib_source_regs[src].fsr_behaviour);
+}
+
+u8 *
+format_fib_source (u8 *s, va_list *a)
+{
+    fib_source_t src = va_arg(*a, int);
+
+    ASSERT(vec_len(fib_source_regs) > src);
+
+    return (format(s, "%s", fib_source_regs[src].fsr_name));
+}
+
+fib_source_priority_cmp_t
+fib_source_cmp (fib_source_t s1,
+                fib_source_t s2)
+{
+    if (fib_source_get_prio(s1) <
+        fib_source_get_prio(s2))
+    {
+        return (FIB_SOURCE_CMP_BETTER);
+    }
+    else if (fib_source_get_prio(s1) >
+             fib_source_get_prio(s2))
+    {
+        return (FIB_SOURCE_CMP_WORSE);
+    }
+    return (FIB_SOURCE_CMP_EQUAL);
+}
+
+static void
+fib_source_reg_init (fib_source_t src,
+                     const char *name,
+                     fib_source_priority_t prio,
+                     fib_source_behaviour_t bh)
+{
+    fib_source_priority_t slot;
+    fib_source_reg_t *fsr;
+
+    /*
+     * ensure we assign a unique priority to each request
+     * otherwise different source will be treated like ECMP
+     */
+    slot = fib_source_prio_by_class[prio]++;
+
+    vec_validate(fib_source_regs, src);
+
+    fsr = &fib_source_regs[src];
+    fsr->fsr_source = src;
+    fsr->fsr_name = strdup(name);
+    fsr->fsr_prio.fsp_class = prio;
+    fsr->fsr_prio.fsp_slot = slot;
+    fsr->fsr_behaviour = bh;
+}
+
+fib_source_t
+fib_source_allocate (const char *name,
+                     fib_source_priority_t prio,
+                     fib_source_behaviour_t bh)
+{
+    fib_source_t src;
+
+    // max value range
+    ASSERT(fib_source_id < 255);
+    if (fib_source_id == 255)
+        return (FIB_SOURCE_INVALID);
+
+    src = fib_source_id++;
+
+    fib_source_reg_init(src, name, prio, bh);
+
+    return (src);
+}
+
+void
+fib_source_register (fib_source_t src,
+                     fib_source_priority_t prio,
+                     fib_source_behaviour_t bh)
+{
+    fib_source_reg_init(src, fib_source_names[src], prio, bh);
+}
+
+static u8 *
+format_fib_source_reg (u8 *s, va_list *a)
+{
+    fib_source_reg_t *fsr = va_arg(*a, fib_source_reg_t*);
+
+    s = format(s, "[%d] %U prio:%d.%d behaviour:%s",
+               fsr->fsr_source,
+               format_fib_source, fsr->fsr_source,
+               fsr->fsr_prio.fsp_class, fsr->fsr_prio.fsp_slot,
+               fib_source_behaviour_names[fsr->fsr_behaviour]);
+
+    return (s);
+}
+
+static int
+fib_source_reg_cmp_for_sort (void * v1,
+                             void * v2)
+{
+    fib_source_reg_t *fsr1 = v1, *fsr2 = v2;
+
+    return (fib_source_get_prio(fsr1->fsr_source) -
+            fib_source_get_prio(fsr2->fsr_source));
+}
+
+void
+fib_source_walk (fib_source_walk_t fn,
+                 void *ctx)
+{
+    fib_source_reg_t *fsr;
+
+    vec_foreach(fsr, fib_source_regs)
+    {
+        if (WALK_STOP == fn(fsr->fsr_source,
+                            fsr->fsr_name,
+                            fsr->fsr_prio.fsp_class,
+                            fsr->fsr_behaviour,
+                            ctx))
+            break;
+    }
+}
+
+static clib_error_t *
+fib_source_show (vlib_main_t * vm,
+                unformat_input_t * input,
+                vlib_cli_command_t * cmd)
+{
+    fib_source_reg_t *fsr, *fsrs;
+
+    fsrs = vec_dup(fib_source_regs);
+
+    while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+       if (unformat (input, "prio")   ||
+           unformat (input, "priority"))
+            vec_sort_with_function(fsrs, fib_source_reg_cmp_for_sort);
+    }
+    vec_foreach(fsr, fsrs)
+    {
+        vlib_cli_output(vm, "%U", format_fib_source_reg, fsr);
+    }
+    vec_free(fsrs);
+
+    return (NULL);
+}
+
+VLIB_CLI_COMMAND (show_fib_sources, static) = {
+    .path = "show fib source",
+    .function = fib_source_show,
+    .short_help = "show fib source [prio]",
+};
+
+
+void
+fib_source_module_init (void)
+{
+#define _(s,p,b) fib_source_register(s,p,b);
+    foreach_fib_source
+#undef _
+}
diff --git a/src/vnet/fib/fib_source.h b/src/vnet/fib/fib_source.h
new file mode 100644 (file)
index 0000000..198ef19
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FIB_SOURCE_H__
+#define __FIB_SOURCE_H__
+
+#include <vnet/vnet.h>
+
+/**
+ * The different sources that can create a route.
+ * The sources are defined here with their relative priority order.
+ * The lower the value the higher the priority
+ */
+typedef enum fib_source_t_ {
+    /**
+     * An invalid source
+     * This is not a real source, so don't use it to source a prefix.
+     * It exists here to provide a value for inexistant/uninitialized source
+     */
+    FIB_SOURCE_INVALID = 0,
+    /**
+     * Marker. Add new values after this one.
+     */
+    FIB_SOURCE_FIRST,
+    /**
+     * Special sources. These are for entries that are added to all
+     * FIBs by default, and should never be over-ridden (hence they
+     * are the highest priority)
+     */
+    FIB_SOURCE_SPECIAL = FIB_SOURCE_FIRST,
+    /**
+     * Classify. A route that links directly to a classify adj
+     */
+    FIB_SOURCE_CLASSIFY,
+    /**
+     * A route the is being 'proxied' on behalf of another device
+     */
+    FIB_SOURCE_PROXY,
+    /**
+     * Route added as a result of interface configuration.
+     * this will also come from the API/CLI, but the distinction is
+     * that is from confiiguration on an interface, not a 'ip route' command
+     */
+    FIB_SOURCE_INTERFACE,
+    /**
+     * SRv6 and SR-MPLS
+     */
+    FIB_SOURCE_SR,
+    /**
+     * From the BIER subsystem
+     */
+    FIB_SOURCE_BIER,
+    /**
+     * From 6RD.
+     */
+    FIB_SOURCE_6RD,
+    /**
+     * From the control plane API
+     */
+    FIB_SOURCE_API,
+    /**
+     * From the CLI.
+     */
+    FIB_SOURCE_CLI,
+    /**
+     * LISP
+     */
+    FIB_SOURCE_LISP,
+    /**
+     * IPv[46] Mapping
+     */
+    FIB_SOURCE_MAP,
+    /**
+     * DHCP
+     */
+    FIB_SOURCE_DHCP,
+    /**
+     * IPv6 Proxy ND
+     */
+    FIB_SOURCE_IP6_ND_PROXY,
+    /**
+     * IPv6 ND (seen in the link-local tables)
+     */
+    FIB_SOURCE_IP6_ND,
+    /**
+     * Adjacency source.
+     * routes created as a result of ARP/ND entries. This is lower priority
+     * then the API/CLI. This is on purpose. trust me.
+     */
+    FIB_SOURCE_ADJ,
+    /**
+     * MPLS label. The prefix has been assigned a local label. This source
+     * never provides forwarding information, instead it acts as a place-holder
+     * so the association of label to prefix can be maintained
+     */
+    FIB_SOURCE_MPLS,
+    /**
+     * Attached Export source.
+     * routes created as a result of attahced export. routes thus sourced
+     * will be present in the export tables
+     */
+    FIB_SOURCE_AE,
+    /**
+     * Recursive resolution source.
+     * Used to install an entry that is the resolution traget of another.
+     */
+    FIB_SOURCE_RR,
+    /**
+     * uRPF bypass/exemption.
+     * Used to install an entry that is exempt from the loose uRPF check
+     */
+    FIB_SOURCE_URPF_EXEMPT,
+    /**
+     * The default route source.
+     * The default route is always added to the FIB table (like the
+     * special sources) but we need to be able to over-ride it with
+     * 'ip route' sources when provided
+     */
+    FIB_SOURCE_DEFAULT_ROUTE,
+    /**
+     * The interpose source.
+     * This is not a real source, so don't use it to source a prefix.
+     * It exists here to provide a value against which to register to the
+     * VFT for providing the interpose actions to a real source.
+     */
+    FIB_SOURCE_INTERPOSE,
+    /**
+     * Marker. add new entries before this one.
+     */
+    FIB_SOURCE_LAST = FIB_SOURCE_INTERPOSE,
+} __attribute__ ((packed)) fib_source_t;
+
+STATIC_ASSERT (sizeof(fib_source_t) == 1,
+              "FIB too many sources");
+
+#define FIB_SOURCES {                                  \
+    [FIB_SOURCE_INVALID] = "invalid",                  \
+    [FIB_SOURCE_SPECIAL] = "special",                  \
+    [FIB_SOURCE_INTERFACE] = "interface",              \
+    [FIB_SOURCE_PROXY] = "proxy",                       \
+    [FIB_SOURCE_BIER] = "BIER",                                \
+    [FIB_SOURCE_6RD] = "6RD",                          \
+    [FIB_SOURCE_API] = "API",                          \
+    [FIB_SOURCE_CLI] = "CLI",                          \
+    [FIB_SOURCE_ADJ] = "adjacency",                    \
+    [FIB_SOURCE_MAP] = "MAP",                          \
+    [FIB_SOURCE_SR] = "SR",                            \
+    [FIB_SOURCE_LISP] = "LISP",                        \
+    [FIB_SOURCE_CLASSIFY] = "classify",                        \
+    [FIB_SOURCE_DHCP] = "DHCP",                        \
+    [FIB_SOURCE_IP6_ND_PROXY] = "IPv6-proxy-nd",        \
+    [FIB_SOURCE_IP6_ND] = "IPv6-nd",                    \
+    [FIB_SOURCE_RR] = "recursive-resolution",          \
+    [FIB_SOURCE_AE] = "attached_export",               \
+    [FIB_SOURCE_MPLS] = "mpls",                        \
+    [FIB_SOURCE_URPF_EXEMPT] = "urpf-exempt",          \
+    [FIB_SOURCE_DEFAULT_ROUTE] = "default-route",      \
+    [FIB_SOURCE_INTERPOSE] = "interpose",               \
+}
+
+/**
+ * Each source is assigned a priority. lower priority is beeter.
+ * the source with the best source with have its contribution added
+ * to forwarding. the lesser sources will be 'remembered' by FIB and
+ * added to forwarding should the best source be removed.
+ */
+typedef u8 fib_source_priority_t;
+
+/**
+ * source comparison
+ */
+typedef enum fib_source_priority_cmp_t_
+{
+    FIB_SOURCE_CMP_BETTER,
+    FIB_SOURCE_CMP_WORSE,
+    FIB_SOURCE_CMP_EQUAL,
+} fib_source_priority_cmp_t;
+
+/**
+ * Each source has a defined behaviour that controls how entries
+ * behave that have that source
+ */
+typedef enum fib_source_behaviour_t_
+{
+    /**
+     * If your adding a new source from a plugin pick one of these
+     */
+    /** Default behaviour - always install a drop */
+    FIB_SOURCE_BH_DROP,
+    /** add paths with [mpls] path extensions */
+    FIB_SOURCE_BH_API,
+    /** add paths without path extensions */
+    FIB_SOURCE_BH_SIMPLE,
+
+    /**
+     * If your adding a new source from a plugin
+     * these are probably not the behaviour you're lokking for.
+     */
+    /** recursive resolution w/ cover tracking*/
+    FIB_SOURCE_BH_RR,
+    /** associated label stored in private data */
+    FIB_SOURCE_BH_MPLS,
+    /** cover tracking w/ glean management */
+    FIB_SOURCE_BH_INTERFACE,
+    /** interpose */
+    FIB_SOURCE_BH_INTERPOSE,
+    /** simple + source fib tracking */
+    FIB_SOURCE_BH_LISP,
+    /** adj w/ cover tracking + refinement */
+    FIB_SOURCE_BH_ADJ,
+} fib_source_behaviour_t;
+
+#define FIB_SOURCE_BH_MAX (FIB_SOURCE_BH_ADJ+1)
+
+#define FIB_SOURCE_BEHAVIOURS {                 \
+    [FIB_SOURCE_BH_DROP] = "drop",             \
+    [FIB_SOURCE_BH_RR] = "rr",                  \
+    [FIB_SOURCE_BH_MPLS] = "mpls",              \
+    [FIB_SOURCE_BH_INTERFACE] = "interface",    \
+    [FIB_SOURCE_BH_INTERPOSE] = "interpose",    \
+    [FIB_SOURCE_BH_LISP] = "lisp",              \
+    [FIB_SOURCE_BH_ADJ] = "adjacency",          \
+    [FIB_SOURCE_BH_API] = "api",                \
+    [FIB_SOURCE_BH_SIMPLE] = "simple",          \
+}
+
+/**
+ * The fixed source to priority mappings.
+ * Declared here so those adding new sources can better determine their respective
+ * priority values.
+ */
+#define foreach_fib_source                                      \
+    /** you can't do better then the special source */         \
+    _(FIB_SOURCE_SPECIAL,       0x00, FIB_SOURCE_BH_SIMPLE)    \
+    _(FIB_SOURCE_CLASSIFY,      0x01, FIB_SOURCE_BH_SIMPLE)    \
+    _(FIB_SOURCE_PROXY,         0x02, FIB_SOURCE_BH_SIMPLE)    \
+    _(FIB_SOURCE_INTERFACE,     0x03, FIB_SOURCE_BH_INTERFACE) \
+    _(FIB_SOURCE_SR,            0x10, FIB_SOURCE_BH_API)       \
+    _(FIB_SOURCE_BIER,          0x20, FIB_SOURCE_BH_SIMPLE)    \
+    _(FIB_SOURCE_6RD,           0x30, FIB_SOURCE_BH_API)       \
+    _(FIB_SOURCE_API,           0x80, FIB_SOURCE_BH_API)       \
+    _(FIB_SOURCE_CLI,           0x81, FIB_SOURCE_BH_API)       \
+    _(FIB_SOURCE_LISP,          0x90, FIB_SOURCE_BH_LISP)      \
+    _(FIB_SOURCE_MAP,           0xa0, FIB_SOURCE_BH_SIMPLE)    \
+    _(FIB_SOURCE_DHCP,          0xb0, FIB_SOURCE_BH_API)       \
+    _(FIB_SOURCE_IP6_ND_PROXY,  0xc0, FIB_SOURCE_BH_API)       \
+    _(FIB_SOURCE_IP6_ND,        0xc1, FIB_SOURCE_BH_API)       \
+    _(FIB_SOURCE_ADJ,           0xd0, FIB_SOURCE_BH_ADJ)       \
+    _(FIB_SOURCE_MPLS,          0xe0, FIB_SOURCE_BH_MPLS)      \
+    _(FIB_SOURCE_AE,            0xf0, FIB_SOURCE_BH_SIMPLE)    \
+    _(FIB_SOURCE_RR,            0xfb, FIB_SOURCE_BH_RR)        \
+    _(FIB_SOURCE_URPF_EXEMPT,   0xfc, FIB_SOURCE_BH_RR)        \
+    _(FIB_SOURCE_DEFAULT_ROUTE, 0xfd, FIB_SOURCE_BH_DROP)      \
+    _(FIB_SOURCE_INTERPOSE,     0xfe, FIB_SOURCE_BH_INTERPOSE) \
+    _(FIB_SOURCE_INVALID,       0xff, FIB_SOURCE_BH_DROP)
+
+/**
+ * Some priority values that plugins might use when they are not to concerned
+ * where in the list they'll go.
+ */
+#define FIB_SOURCE_PRIORITY_HI 0x10
+#define FIB_SOURCE_PRIORITY_LOW 0xd0
+
+
+extern u16 fib_source_get_prio(fib_source_t src);
+extern fib_source_behaviour_t fib_source_get_behaviour(fib_source_t src);
+extern fib_source_priority_cmp_t fib_source_cmp(fib_source_t s1,
+                                                fib_source_t s2);
+
+extern u8 *format_fib_source(u8 *s, va_list *a);
+
+extern fib_source_t fib_source_allocate(const char *name,
+                                        fib_source_priority_t prio,
+                                        fib_source_behaviour_t bh);
+
+extern void fib_source_register(fib_source_t src,
+                                fib_source_priority_t prio,
+                                fib_source_behaviour_t bh);
+
+typedef walk_rc_t (*fib_source_walk_t)(fib_source_t id,
+                                       const char *name,
+                                       fib_source_priority_t prio,
+                                       fib_source_behaviour_t bh,
+                                       void *ctx);
+extern void fib_source_walk(fib_source_walk_t fn,
+                            void *ctx);
+
+extern void fib_source_module_init(void);
+
+#endif
index d3cf5dc..6766028 100644 (file)
@@ -304,6 +304,21 @@ fib_table_fwding_dpo_remove (u32 fib_index,
     }
 }
 
+static void
+fib_table_source_count_inc (fib_table_t *fib_table,
+                            fib_source_t source)
+{
+    vec_validate (fib_table->ft_src_route_counts, source);
+    fib_table->ft_src_route_counts[source]++;
+}
+
+static void
+fib_table_source_count_dec (fib_table_t *fib_table,
+                            fib_source_t source)
+{
+    vec_validate (fib_table->ft_src_route_counts, source);
+    fib_table->ft_src_route_counts[source]--;
+}
 
 fib_node_index_t
 fib_table_entry_special_dpo_add (u32 fib_index,
@@ -325,7 +340,7 @@ fib_table_entry_special_dpo_add (u32 fib_index,
                                                   dpo);
 
        fib_table_entry_insert(fib_table, prefix, fib_entry_index);
-        fib_table->ft_src_route_counts[source]++;
+        fib_table_source_count_inc(fib_table, source);
     }
     else
     {
@@ -336,7 +351,7 @@ fib_table_entry_special_dpo_add (u32 fib_index,
 
         if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
         {
-            fib_table->ft_src_route_counts[source]++;
+        fib_table_source_count_inc(fib_table, source);
         }
     }
 
@@ -364,7 +379,7 @@ fib_table_entry_special_dpo_update (u32 fib_index,
                                                   dpo);
 
        fib_table_entry_insert(fib_table, prefix, fib_entry_index);
-        fib_table->ft_src_route_counts[source]++;
+        fib_table_source_count_inc(fib_table, source);
     }
     else
     {
@@ -379,7 +394,7 @@ fib_table_entry_special_dpo_update (u32 fib_index,
 
         if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
         {
-            fib_table->ft_src_route_counts[source]++;
+            fib_table_source_count_inc(fib_table, source);
         }
     }
 
@@ -461,7 +476,7 @@ fib_table_entry_special_remove (u32 fib_index,
         */
         if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
         {
-            fib_table->ft_src_route_counts[source]--;
+            fib_table_source_count_dec(fib_table, source);
         }
 
        fib_entry_unlock(fib_entry_index);
@@ -591,7 +606,7 @@ fib_table_entry_path_add2 (u32 fib_index,
                                           rpaths);
 
        fib_table_entry_insert(fib_table, prefix, fib_entry_index);
-        fib_table->ft_src_route_counts[source]++;
+        fib_table_source_count_inc(fib_table, source);
     }
     else
     {
@@ -602,7 +617,7 @@ fib_table_entry_path_add2 (u32 fib_index,
 
         if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
         {
-            fib_table->ft_src_route_counts[source]++;
+            fib_table_source_count_inc(fib_table, source);
         }
     }
 
@@ -684,7 +699,7 @@ fib_table_entry_path_remove2 (u32 fib_index,
         */
         if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
         {
-            fib_table->ft_src_route_counts[source]--;
+            fib_table_source_count_dec(fib_table, source);
         }
 
        fib_entry_unlock(fib_entry_index);
@@ -763,7 +778,7 @@ fib_table_entry_update (u32 fib_index,
                                           paths);
 
        fib_table_entry_insert(fib_table, prefix, fib_entry_index);
-        fib_table->ft_src_route_counts[source]++;
+        fib_table_source_count_inc(fib_table, source);
     }
     else
     {
@@ -774,7 +789,7 @@ fib_table_entry_update (u32 fib_index,
 
         if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
         {
-            fib_table->ft_src_route_counts[source]++;
+            fib_table_source_count_inc(fib_table, source);
         }
     }
 
@@ -856,7 +871,7 @@ fib_table_entry_delete_i (u32 fib_index,
      */
     if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
     {
-        fib_table->ft_src_route_counts[source]--;
+        fib_table_source_count_dec(fib_table, source);
     }
 
     fib_entry_unlock(fib_entry_index);
@@ -1246,6 +1261,27 @@ fib_table_sub_tree_walk (u32 fib_index,
     }
 }
 
+static void
+fib_table_lock_dec (fib_table_t *fib_table,
+                    fib_source_t source)
+{
+    vec_validate(fib_table->ft_locks, source);
+
+    fib_table->ft_locks[source]--;
+    fib_table->ft_total_locks--;
+}
+
+static void
+fib_table_lock_inc (fib_table_t *fib_table,
+                    fib_source_t source)
+{
+    vec_validate(fib_table->ft_locks, source);
+
+    ASSERT(fib_table->ft_locks[source] < (0xffff - 1));
+    fib_table->ft_locks[source]++;
+    fib_table->ft_total_locks++;
+}
+
 void
 fib_table_unlock (u32 fib_index,
                  fib_protocol_t proto,
@@ -1254,10 +1290,9 @@ fib_table_unlock (u32 fib_index,
     fib_table_t *fib_table;
 
     fib_table = fib_table_get(fib_index, proto);
-    fib_table->ft_locks[source]--;
-    fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]--;
+    fib_table_lock_dec(fib_table, source);
 
-    if (0 == fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS])
+    if (0 == fib_table->ft_total_locks)
     {
         /*
          * no more locak from any source - kill it
@@ -1275,10 +1310,7 @@ fib_table_lock (u32 fib_index,
 
     fib_table = fib_table_get(fib_index, proto);
 
-    ASSERT(fib_table->ft_locks[source] < (0xffff - 1));
-
-    fib_table->ft_locks[source]++;
-    fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]++;
+    fib_table_lock_inc(fib_table, source);
 }
 
 u32
index 74be63d..59ebb0b 100644 (file)
 #include <vnet/mpls/mpls.h>
 #include <vnet/mpls/packet.h>
 
-/**
- * Keep a lock per-source and a total
- */
-#define FIB_TABLE_N_LOCKS (FIB_SOURCE_MAX+1)
-#define FIB_TABLE_TOTAL_LOCKS FIB_SOURCE_MAX
-
 /**
  * Flags for the source data
  */
@@ -89,7 +83,8 @@ typedef struct fib_table_t_
     /**
      * per-source number of locks on the table
      */
-    u16 ft_locks[FIB_TABLE_N_LOCKS];
+    u16 *ft_locks;
+    u32 ft_total_locks;
 
     /**
      * Table ID (hash key) for this FIB.
@@ -109,7 +104,7 @@ typedef struct fib_table_t_
     /**
      * Per-source route counters
      */
-    u32 ft_src_route_counts[FIB_SOURCE_MAX];
+    u32 *ft_src_route_counts;
 
     /**
      * Total route counters
index 02348af..e4ff1bf 100644 (file)
@@ -160,6 +160,7 @@ ip4_fib_table_destroy (u32 fib_index)
 {
     fib_table_t *fib_table = pool_elt_at_index(ip4_main.fibs, fib_index);
     ip4_fib_t *v4_fib = pool_elt_at_index(ip4_main.v4_fibs, fib_index);
+    u32 *n_locks;
     int ii;
 
     /*
@@ -182,9 +183,10 @@ ip4_fib_table_destroy (u32 fib_index)
      * validate no more routes.
      */
     ASSERT(0 == fib_table->ft_total_route_counts);
-    FOR_EACH_FIB_SOURCE(ii)
+
+    vec_foreach(n_locks, fib_table->ft_src_route_counts)
     {
-       ASSERT(0 == fib_table->ft_src_route_counts[ii]);
+       ASSERT(0 == *n_locks);
     }
 
     if (~0 != fib_table->ft_table_id)
@@ -192,6 +194,7 @@ ip4_fib_table_destroy (u32 fib_index)
        hash_unset (ip4_main.fib_index_by_table_id, fib_table->ft_table_id);
     }
 
+    vec_free(fib_table->ft_src_route_counts);
     ip4_mtrie_free(&v4_fib->mtrie);
 
     pool_put(ip4_main.v4_fibs, v4_fib);
@@ -679,7 +682,7 @@ ip4_show_fib (vlib_main_t * vm,
                    fib_table->ft_flow_hash_config,
                    fib_table->ft_epoch,
                    format_fib_table_flags, fib_table->ft_flags);
-       FOR_EACH_FIB_SOURCE(source)
+        vec_foreach_index(source, fib_table->ft_locks)
         {
             if (0 != fib_table->ft_locks[source])
             {
index 991fbc1..6d0eca4 100644 (file)
@@ -151,11 +151,11 @@ ip6_fib_table_destroy (u32 fib_index)
     fib_table_t *fib_table = fib_table_get(fib_index, FIB_PROTOCOL_IP6);
     fib_source_t source;
 
-     /*
+    /*
      * validate no more routes.
      */
     ASSERT(0 == fib_table->ft_total_route_counts);
-    FOR_EACH_FIB_SOURCE(source)
+    vec_foreach_index(source, fib_table->ft_src_route_counts)
     {
        ASSERT(0 == fib_table->ft_src_route_counts[source]);
     }
@@ -164,6 +164,7 @@ ip6_fib_table_destroy (u32 fib_index)
     {
        hash_unset (ip6_main.fib_index_by_table_id, fib_table->ft_table_id);
     }
+    vec_free(fib_table->ft_src_route_counts);
     pool_put_index(ip6_main.v6_fibs, fib_table->ft_index);
     pool_put(ip6_main.fibs, fib_table);
 }
@@ -688,7 +689,7 @@ ip6_show_fib (vlib_main_t * vm,
                    fib_table->ft_epoch,
                    format_fib_table_flags, fib_table->ft_flags);
 
-       FOR_EACH_FIB_SOURCE(source)
+        vec_foreach_index(source, fib_table->ft_locks)
         {
             if (0 != fib_table->ft_locks[source])
             {
index 6f59eb3..9ec32d2 100644 (file)
@@ -275,6 +275,7 @@ mpls_fib_table_destroy (u32 fib_index)
     }
     hash_free(mf->mf_entries);
 
+    vec_free(fib_table->ft_src_route_counts);
     pool_put(mpls_main.mpls_fibs, mf);
     pool_put(mpls_main.fibs, fib_table);
 }
@@ -450,7 +451,7 @@ mpls_fib_show (vlib_main_t * vm,
 
        s = format (s, "%v, fib_index:%d locks:[",
                     fib_table->ft_desc, mpls_main.fibs - fib_table);
-       FOR_EACH_FIB_SOURCE(source)
+        vec_foreach_index(source, fib_table->ft_locks)
         {
             if (0 != fib_table->ft_locks[source])
             {
index a7440ea..3672b63 100644 (file)
@@ -283,7 +283,7 @@ ip6_ll_show_fib (vlib_main_t * vm,
     s = format (s, "%U, fib_index:%d, locks:[",
                format_fib_table_name, fib_index,
                FIB_PROTOCOL_IP6, fib_index);
-    FOR_EACH_FIB_SOURCE (source)
+    vec_foreach_index (source, fib_table->ft_locks)
     {
       if (0 != fib_table->ft_locks[source])
        {
index faafdad..0eefcdf 100644 (file)
@@ -20,6 +20,24 @@ class TestFIB(VppTestCase):
         """ FIB Unit Tests """
         error = self.vapi.cli("test fib")
 
+        # shameless test of CLIs to bump lcov results...
+        # no i mean to ensure they don't crash
+        self.logger.info(self.vapi.cli("sh fib source"))
+        self.logger.info(self.vapi.cli("sh fib source prio"))
+        self.logger.info(self.vapi.cli("sh fib memory"))
+        self.logger.info(self.vapi.cli("sh fib entry"))
+        self.logger.info(self.vapi.cli("sh fib entry 0"))
+        self.logger.info(self.vapi.cli("sh fib entry 10000"))
+        self.logger.info(self.vapi.cli("sh fib entry-delegate"))
+        self.logger.info(self.vapi.cli("sh fib paths"))
+        self.logger.info(self.vapi.cli("sh fib paths 0"))
+        self.logger.info(self.vapi.cli("sh fib paths 10000"))
+        self.logger.info(self.vapi.cli("sh fib path-list"))
+        self.logger.info(self.vapi.cli("sh fib path-list 0"))
+        self.logger.info(self.vapi.cli("sh fib path-list 10000"))
+        self.logger.info(self.vapi.cli("sh fib walk"))
+        self.logger.info(self.vapi.cli("sh fib uRPF"))
+
         if error:
             self.logger.critical(error)
         self.assertNotIn("Failed", error)