summaryrefslogtreecommitdiffstats
path: root/src/vnet/fib
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/fib')
-rw-r--r--src/vnet/fib/fib.c1
-rw-r--r--src/vnet/fib/fib_entry.c60
-rw-r--r--src/vnet/fib/fib_entry.h171
-rw-r--r--src/vnet/fib/fib_entry_src.c27
-rw-r--r--src/vnet/fib/fib_entry_src.h8
-rw-r--r--src/vnet/fib/fib_entry_src_adj.c2
-rw-r--r--src/vnet/fib/fib_entry_src_api.c10
-rw-r--r--src/vnet/fib/fib_entry_src_default.c7
-rw-r--r--src/vnet/fib/fib_entry_src_drop.c (renamed from src/vnet/fib/fib_entry_src_default_route.c)19
-rw-r--r--src/vnet/fib/fib_entry_src_interface.c3
-rw-r--r--src/vnet/fib/fib_entry_src_interpose.c15
-rw-r--r--src/vnet/fib/fib_entry_src_lisp.c5
-rw-r--r--src/vnet/fib/fib_entry_src_mpls.c2
-rwxr-xr-xsrc/vnet/fib/fib_entry_src_rr.c3
-rw-r--r--src/vnet/fib/fib_entry_src_simple.c77
-rw-r--r--src/vnet/fib/fib_entry_src_special.c82
-rw-r--r--src/vnet/fib/fib_source.c222
-rw-r--r--src/vnet/fib/fib_source.h302
-rw-r--r--src/vnet/fib/fib_table.c68
-rw-r--r--src/vnet/fib/fib_table.h11
-rw-r--r--src/vnet/fib/ip4_fib.c9
-rw-r--r--src/vnet/fib/ip6_fib.c7
-rw-r--r--src/vnet/fib/mpls_fib.c3
23 files changed, 743 insertions, 371 deletions
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])
{