diff options
Diffstat (limited to 'src/vnet')
25 files changed, 752 insertions, 378 deletions
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]) { |