diff options
40 files changed, 889 insertions, 441 deletions
diff --git a/src/plugins/gbp/gbp_endpoint.c b/src/plugins/gbp/gbp_endpoint.c index 12865461d18..bef67770fd9 100644 --- a/src/plugins/gbp/gbp_endpoint.c +++ b/src/plugins/gbp/gbp_endpoint.c @@ -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); } diff --git a/src/plugins/gbp/gbp_route_domain.c b/src/plugins/gbp/gbp_route_domain.c index ab998591982..f0aa694d44a 100644 --- a/src/plugins/gbp/gbp_route_domain.c +++ b/src/plugins/gbp/gbp_route_domain.c @@ -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); } diff --git a/src/plugins/gbp/gbp_subnet.c b/src/plugins/gbp/gbp_subnet.c index bb069ffe892..2ef3fcfd534 100644 --- a/src/plugins/gbp/gbp_subnet.c +++ b/src/plugins/gbp/gbp_subnet.c @@ -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); } diff --git a/src/plugins/ila/ila.c b/src/plugins/ila/ila.c index bac76151c28..162d417d772 100644 --- a/src/plugins/ila/ila.c +++ b/src/plugins/ila/ila.c @@ -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; } diff --git a/src/plugins/lb/lb.c b/src/plugins/lb/lb.c index b1e0b237478..4dbf134cc4f 100644 --- a/src/plugins/lb/lb.c +++ b/src/plugins/lb/lb.c @@ -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; } diff --git a/src/plugins/nat/dslite.c b/src/plugins/nat/dslite.c index 339c12c5656..d9a17293fac 100644 --- a/src/plugins/nat/dslite.c +++ b/src/plugins/nat/dslite.c @@ -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; diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index 0a30caf0f21..d7133684b32 100755 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -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; diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h index b65ad1b676f..ee712f4748f 100644 --- a/src/plugins/nat/nat.h +++ b/src/plugins/nat/nat.h @@ -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; diff --git a/src/plugins/nat/nat64.c b/src/plugins/nat/nat64.c index 0fe29800420..e1afea6510e 100644 --- a/src/plugins/nat/nat64.c +++ b/src/plugins/nat/nat64.c @@ -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; } diff --git a/src/plugins/nat/nat64_cli.c b/src/plugins/nat/nat64_cli.c index 53152f11996..be468df1753 100644 --- a/src/plugins/nat/nat64_cli.c +++ b/src/plugins/nat/nat64_cli.c @@ -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); } } diff --git a/src/plugins/nat/nat66.c b/src/plugins/nat/nat66.c index 2caefab6480..e5e783b31f7 100644 --- a/src/plugins/nat/nat66.c +++ b/src/plugins/nat/nat66.c @@ -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); } diff --git a/src/plugins/pppoe/pppoe.c b/src/plugins/pppoe/pppoe.c index 2d63b3e8674..1f8a7288aeb 100644 --- a/src/plugins/pppoe/pppoe.c +++ b/src/plugins/pppoe/pppoe.c @@ -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; } diff --git a/src/plugins/svs/svs.c b/src/plugins/svs/svs.c index 8c1487c6ebc..555283397ff 100644 --- a/src/plugins/svs/svs.c +++ b/src/plugins/svs/svs.c @@ -26,10 +26,12 @@ 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); } diff --git a/src/plugins/unittest/fib_test.c b/src/plugins/unittest/fib_test.c index f220eb0d358..2d75f28a8ca 100644 --- a/src/plugins/unittest/fib_test.c +++ b/src/plugins/unittest/fib_test.c @@ -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, diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt index 11827734a60..21653ab7c7a 100644 --- a/src/vnet/CMakeLists.txt +++ b/src/vnet/CMakeLists.txt @@ -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) diff --git a/src/vnet/fib/fib.c b/src/vnet/fib/fib.c index 28e18dded23..ddfa830bb0f 100644 --- a/src/vnet/fib/fib.c +++ b/src/vnet/fib/fib.c @@ -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(); diff --git a/src/vnet/fib/fib_entry.c b/src/vnet/fib/fib_entry.c index fd69db989f2..0e5482840bf 100644 --- a/src/vnet/fib/fib_entry.c +++ b/src/vnet/fib/fib_entry.c @@ -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; @@ -98,16 +97,6 @@ fib_entry_get_default_chain_type (const fib_entry_t *fib_entry) } 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) { fib_entry_attribute_t attr; @@ -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); diff --git a/src/vnet/fib/fib_entry.h b/src/vnet/fib/fib_entry.h index f0e6e8d8aae..b97c80fd8bf 100644 --- a/src/vnet/fib/fib_entry.h +++ b/src/vnet/fib/fib_entry.h @@ -17,6 +17,7 @@ #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> @@ -26,176 +27,6 @@ * 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. - * The lower the value the higher the priority - */ typedef enum fib_entry_attribute_t_ { /** * Marker. Add new values after this one. diff --git a/src/vnet/fib/fib_entry_src.c b/src/vnet/fib/fib_entry_src.c index 176818abc0a..d534135d330 100644 --- a/src/vnet/fib/fib_entry_src.c +++ b/src/vnet/fib/fib_entry_src.c @@ -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(); diff --git a/src/vnet/fib/fib_entry_src.h b/src/vnet/fib/fib_entry_src.h index 8f13ae894bb..308005777a0 100644 --- a/src/vnet/fib/fib_entry_src.h +++ b/src/vnet/fib/fib_entry_src.h @@ -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); diff --git a/src/vnet/fib/fib_entry_src_adj.c b/src/vnet/fib/fib_entry_src_adj.c index 2a5b46a2c91..ec80a867d49 100644 --- a/src/vnet/fib/fib_entry_src_adj.c +++ b/src/vnet/fib/fib_entry_src_adj.c @@ -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); } diff --git a/src/vnet/fib/fib_entry_src_api.c b/src/vnet/fib/fib_entry_src_api.c index be93cc23c36..69102a15030 100644 --- a/src/vnet/fib/fib_entry_src_api.c +++ b/src/vnet/fib/fib_entry_src_api.c @@ -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); } diff --git a/src/vnet/fib/fib_entry_src_default.c b/src/vnet/fib/fib_entry_src_default.c index 18a039afbd6..534a28ca6f8 100644 --- a/src/vnet/fib/fib_entry_src_default.c +++ b/src/vnet/fib/fib_entry_src_default.c @@ -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); } diff --git a/src/vnet/fib/fib_entry_src_default_route.c b/src/vnet/fib/fib_entry_src_drop.c index 431abb66d17..886977100f4 100644 --- a/src/vnet/fib/fib_entry_src_default_route.c +++ b/src/vnet/fib/fib_entry_src_drop.c @@ -20,19 +20,19 @@ * 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); } diff --git a/src/vnet/fib/fib_entry_src_interface.c b/src/vnet/fib/fib_entry_src_interface.c index 5d609c5857a..140036012b9 100644 --- a/src/vnet/fib/fib_entry_src_interface.c +++ b/src/vnet/fib/fib_entry_src_interface.c @@ -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); } diff --git a/src/vnet/fib/fib_entry_src_interpose.c b/src/vnet/fib/fib_entry_src_interpose.c index 2220fa4debd..02db3911dfc 100644 --- a/src/vnet/fib/fib_entry_src_interpose.c +++ b/src/vnet/fib/fib_entry_src_interpose.c @@ -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); } diff --git a/src/vnet/fib/fib_entry_src_lisp.c b/src/vnet/fib/fib_entry_src_lisp.c index ec8c467d1cf..2fc9c924e6b 100644 --- a/src/vnet/fib/fib_entry_src_lisp.c +++ b/src/vnet/fib/fib_entry_src_lisp.c @@ -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); } diff --git a/src/vnet/fib/fib_entry_src_mpls.c b/src/vnet/fib/fib_entry_src_mpls.c index f3d1dc0bd50..7bbe34d0566 100644 --- a/src/vnet/fib/fib_entry_src_mpls.c +++ b/src/vnet/fib/fib_entry_src_mpls.c @@ -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); } diff --git a/src/vnet/fib/fib_entry_src_rr.c b/src/vnet/fib/fib_entry_src_rr.c index 9f4f68d88f5..d0256b9f24b 100755 --- a/src/vnet/fib/fib_entry_src_rr.c +++ b/src/vnet/fib/fib_entry_src_rr.c @@ -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 index 00000000000..2caa4fcc1e1 --- /dev/null +++ b/src/vnet/fib/fib_entry_src_simple.c @@ -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 index c976da9327a..00000000000 --- a/src/vnet/fib/fib_entry_src_special.c +++ /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 index 00000000000..0aeecae545f --- /dev/null +++ b/src/vnet/fib/fib_source.c @@ -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 index 00000000000..198ef194e2b --- /dev/null +++ b/src/vnet/fib/fib_source.h @@ -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 diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c index d3cf5dc88b1..6766028762d 100644 --- a/src/vnet/fib/fib_table.c +++ b/src/vnet/fib/fib_table.c @@ -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 diff --git a/src/vnet/fib/fib_table.h b/src/vnet/fib/fib_table.h index 74be63d326a..59ebb0b0161 100644 --- a/src/vnet/fib/fib_table.h +++ b/src/vnet/fib/fib_table.h @@ -23,12 +23,6 @@ #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 */ typedef enum fib_table_attribute_t_ { @@ -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 diff --git a/src/vnet/fib/ip4_fib.c b/src/vnet/fib/ip4_fib.c index 02348af87d8..e4ff1bf77cc 100644 --- a/src/vnet/fib/ip4_fib.c +++ b/src/vnet/fib/ip4_fib.c @@ -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]) { diff --git a/src/vnet/fib/ip6_fib.c b/src/vnet/fib/ip6_fib.c index 991fbc1151b..6d0eca4c8d7 100644 --- a/src/vnet/fib/ip6_fib.c +++ b/src/vnet/fib/ip6_fib.c @@ -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]) { diff --git a/src/vnet/fib/mpls_fib.c b/src/vnet/fib/mpls_fib.c index 6f59eb3ee44..9ec32d2fea6 100644 --- a/src/vnet/fib/mpls_fib.c +++ b/src/vnet/fib/mpls_fib.c @@ -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]) { diff --git a/src/vnet/ip/ip6_ll_table.c b/src/vnet/ip/ip6_ll_table.c index a7440ea543c..3672b635c87 100644 --- a/src/vnet/ip/ip6_ll_table.c +++ b/src/vnet/ip/ip6_ll_table.c @@ -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]) { diff --git a/test/test_fib.py b/test/test_fib.py index faafdad15b0..0eefcdf8b80 100644 --- a/test/test_fib.py +++ b/test/test_fib.py @@ -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) |