aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/fib/fib_entry_src.c
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2018-02-21 04:57:17 -0800
committerNeale Ranns <nranns@cisco.com>2018-03-20 23:59:06 +0000
commit2303cb181b51f63c909cd506125c1f832432865a (patch)
treeea2389593abc50790e06b6ac2e80f2a38c536942 /src/vnet/fib/fib_entry_src.c
parentf55957e71c58e38770b12af0720e9d19a8f6a8d6 (diff)
FIB Interpose Source
The interpose source allows the source/provider to insert/interpose a DPO in the forwarding chain of the FIB entry ahead of the forwarding provided by the next best source. For example if the API source (i.e the 'control plane') has provided an adjacency for forwarding, then an interpose source (e.g. a monitoring service) couold interpose a replicatte DPO to copy the traffic to another location AND forward using the API's adjacency. To use the interose feature an existing source (i.e FIB_SOURCE_PLUGIN_HI) cn specifiy as a flag FIB_ENTRY_FLAG_INTERPOSE and provide a DPO to interpose. One might also consider using interpose in conjunction with FIB_ENTRY_FLAG_COVER_INHERIT to ensure the interpose object affects all prefixes in the sub-tree. Change-Id: I8b2737b985f8f7c08123406d0491881def347b52 Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/fib/fib_entry_src.c')
-rw-r--r--src/vnet/fib/fib_entry_src.c384
1 files changed, 235 insertions, 149 deletions
diff --git a/src/vnet/fib/fib_entry_src.c b/src/vnet/fib/fib_entry_src.c
index 0497672b268..1b2d7161060 100644
--- a/src/vnet/fib/fib_entry_src.c
+++ b/src/vnet/fib/fib_entry_src.c
@@ -29,11 +29,39 @@
*/
static fib_entry_src_vft_t fib_entry_src_vft[FIB_SOURCE_MAX];
+/**
+ * Get the VFT for a given source. This is a combination of the source
+ * enum and the interposer flags
+ */
+const fib_entry_src_vft_t*
+fib_entry_src_get_vft (const fib_entry_src_t *esrc)
+{
+ if (esrc->fes_entry_flags & FIB_ENTRY_FLAG_INTERPOSE)
+ {
+ return (&fib_entry_src_vft[FIB_SOURCE_INTERPOSE]);
+ }
+
+ return (&fib_entry_src_vft[esrc->fes_src]);
+}
+
+static void
+fib_entry_src_copy_default (const fib_entry_src_t *orig_src,
+ const fib_entry_t *fib_entry,
+ fib_entry_src_t *copy_src)
+{
+ clib_memcpy(&copy_src->u, &orig_src->u, sizeof(copy_src->u));
+}
+
void
fib_entry_src_register (fib_source_t source,
const fib_entry_src_vft_t *vft)
{
fib_entry_src_vft[source] = *vft;
+
+ if (NULL == fib_entry_src_vft[source].fesv_copy)
+ {
+ fib_entry_src_vft[source].fesv_copy = fib_entry_src_copy_default;
+ }
}
static int
@@ -45,21 +73,19 @@ fib_entry_src_cmp_for_sort (void * v1,
return (esrc1->fes_src - esrc2->fes_src);
}
-void
+static void
fib_entry_src_action_init (fib_entry_t *fib_entry,
- fib_source_t source)
-
+ fib_source_t source,
+ fib_entry_flag_t flags)
{
fib_entry_src_t esrc = {
.fes_pl = FIB_NODE_INDEX_INVALID,
.fes_flags = FIB_ENTRY_SRC_FLAG_NONE,
.fes_src = source,
+ .fes_entry_flags = flags,
};
- if (NULL != fib_entry_src_vft[source].fesv_init)
- {
- fib_entry_src_vft[source].fesv_init(&esrc);
- }
+ FIB_ENTRY_SRC_VFT_INVOKE(&esrc, fesv_init, (&esrc));
vec_add1(fib_entry->fe_srcs, esrc);
vec_sort_with_function(fib_entry->fe_srcs,
@@ -67,9 +93,9 @@ fib_entry_src_action_init (fib_entry_t *fib_entry,
}
static fib_entry_src_t *
-fib_entry_src_find (const fib_entry_t *fib_entry,
- fib_source_t source,
- u32 *index)
+fib_entry_src_find_i (const fib_entry_t *fib_entry,
+ fib_source_t source,
+ u32 *index)
{
fib_entry_src_t *esrc;
@@ -95,6 +121,14 @@ fib_entry_src_find (const fib_entry_t *fib_entry,
return (NULL);
}
+static fib_entry_src_t *
+fib_entry_src_find (const fib_entry_t *fib_entry,
+ fib_source_t source)
+
+{
+ return (fib_entry_src_find_i(fib_entry, source, NULL));
+}
+
int
fib_entry_is_sourced (fib_node_index_t fib_entry_index,
fib_source_t source)
@@ -103,26 +137,27 @@ fib_entry_is_sourced (fib_node_index_t fib_entry_index,
fib_entry = fib_entry_get(fib_entry_index);
- return (NULL != fib_entry_src_find(fib_entry, source, NULL));
+ return (NULL != fib_entry_src_find(fib_entry, source));
}
static fib_entry_src_t *
fib_entry_src_find_or_create (fib_entry_t *fib_entry,
- fib_source_t source)
+ fib_source_t source,
+ fib_entry_flag_t flags)
{
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
if (NULL == esrc)
{
- fib_entry_src_action_init(fib_entry, source);
+ fib_entry_src_action_init(fib_entry, source, flags);
}
- return (fib_entry_src_find(fib_entry, source, NULL));
+ return (fib_entry_src_find(fib_entry, source));
}
-void
+static void
fib_entry_src_action_deinit (fib_entry_t *fib_entry,
fib_source_t source)
@@ -130,14 +165,11 @@ fib_entry_src_action_deinit (fib_entry_t *fib_entry,
fib_entry_src_t *esrc;
u32 index = ~0;
- esrc = fib_entry_src_find(fib_entry, source, &index);
+ esrc = fib_entry_src_find_i(fib_entry, source, &index);
ASSERT(NULL != esrc);
- if (NULL != fib_entry_src_vft[source].fesv_deinit)
- {
- fib_entry_src_vft[source].fesv_deinit(esrc);
- }
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_deinit, (esrc));
fib_path_ext_list_flush(&esrc->fes_path_exts);
vec_del1(fib_entry->fe_srcs, index);
@@ -145,14 +177,10 @@ fib_entry_src_action_deinit (fib_entry_t *fib_entry,
fib_entry_src_cover_res_t
fib_entry_src_action_cover_change (fib_entry_t *fib_entry,
- fib_source_t source)
+ fib_entry_src_t *esrc)
{
- if (NULL != fib_entry_src_vft[source].fesv_cover_change)
- {
- return (fib_entry_src_vft[source].fesv_cover_change(
- fib_entry_src_find(fib_entry, source, NULL),
- fib_entry));
- }
+ FIB_ENTRY_SRC_VFT_INVOKE_AND_RETURN(esrc, fesv_cover_change,
+ (esrc, fib_entry));
fib_entry_src_cover_res_t res = {
.install = !0,
@@ -163,14 +191,10 @@ fib_entry_src_action_cover_change (fib_entry_t *fib_entry,
fib_entry_src_cover_res_t
fib_entry_src_action_cover_update (fib_entry_t *fib_entry,
- fib_source_t source)
+ fib_entry_src_t *esrc)
{
- if (NULL != fib_entry_src_vft[source].fesv_cover_update)
- {
- return (fib_entry_src_vft[source].fesv_cover_update(
- fib_entry_src_find(fib_entry, source, NULL),
- fib_entry));
- }
+ FIB_ENTRY_SRC_VFT_INVOKE_AND_RETURN(esrc, fesv_cover_update,
+ (esrc, fib_entry));
fib_entry_src_cover_res_t res = {
.install = !0,
@@ -350,8 +374,10 @@ fib_entry_src_collect_forwarding (fib_node_index_t pl_index,
{
fib_entry_src_collect_forwarding_ctx_t *ctx;
fib_path_ext_t *path_ext;
+ u32 n_nhs;
ctx = arg;
+ n_nhs = vec_len(ctx->next_hops);
/*
* if the path is not resolved, don't include it.
@@ -430,6 +456,41 @@ fib_entry_src_collect_forwarding (fib_node_index_t pl_index,
fib_entry_src_get_path_forwarding(path_index, ctx);
}
+ /*
+ * a this point 'ctx' has the DPO the path contributed, plus
+ * any labels from path extensions.
+ * check if there are any interpose sources that want to contribute
+ */
+ if (n_nhs < vec_len(ctx->next_hops))
+ {
+ /*
+ * the path contributed a new choice.
+ */
+ const fib_entry_src_vft_t *vft;
+
+ vft = fib_entry_src_get_vft(ctx->esrc);
+
+ if (NULL != vft->fesv_contribute_interpose)
+ {
+ const dpo_id_t *interposer;
+
+ interposer = vft->fesv_contribute_interpose(ctx->esrc,
+ ctx->fib_entry);
+
+ if (NULL != interposer)
+ {
+ dpo_id_t clone = DPO_INVALID;
+
+ dpo_mk_interpose(interposer,
+ &ctx->next_hops[n_nhs].path_dpo,
+ &clone);
+
+ dpo_copy(&ctx->next_hops[n_nhs].path_dpo, &clone);
+ dpo_reset(&clone);
+ }
+ }
+ }
+
return (FIB_PATH_LIST_WALK_CONTINUE);
}
@@ -585,7 +646,7 @@ fib_entry_src_action_install (fib_entry_t *fib_entry,
int insert;
fct = fib_entry_get_default_chain_type(fib_entry);
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
/*
* Every entry has its own load-balance object. All changes to the entry's
@@ -660,18 +721,34 @@ fib_entry_recursive_loop_detect_i (fib_node_index_t path_list_index)
*
* copy a source data from another entry to this one
*/
-fib_entry_t *
+static fib_entry_t *
fib_entry_src_action_copy (fib_entry_t *fib_entry,
const fib_entry_src_t *orig_src)
{
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find_or_create(fib_entry, orig_src->fes_src);
+ esrc = fib_entry_src_find_or_create(fib_entry,
+ orig_src->fes_src,
+ orig_src->fes_entry_flags);
+
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_copy,
+ (orig_src, fib_entry, esrc));
+
+ fib_path_list_unlock(esrc->fes_pl);
+
+ /*
+ * copy over all the data ...
+ */
+ esrc->fes_flags = orig_src->fes_flags;
+ esrc->fes_pl = orig_src->fes_pl;
- *esrc = *orig_src;
+ /*
+ * ... then update
+ */
esrc->fes_ref_count = 1;
esrc->fes_flags |= FIB_ENTRY_SRC_FLAG_INHERITED;
- esrc->fes_flags &= ~FIB_ENTRY_SRC_FLAG_ACTIVE;
+ esrc->fes_flags &= ~(FIB_ENTRY_SRC_FLAG_ACTIVE |
+ FIB_ENTRY_SRC_FLAG_CONTRIBUTING);
esrc->fes_entry_flags &= ~FIB_ENTRY_FLAG_COVERED_INHERIT;
/*
@@ -694,7 +771,9 @@ fib_entry_src_action_update_from_cover (fib_entry_t *fib_entry,
{
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find_or_create(fib_entry, orig_src->fes_src);
+ esrc = fib_entry_src_find_or_create(fib_entry,
+ orig_src->fes_src,
+ orig_src->fes_entry_flags);
/*
* the source owns a lock on the entry
@@ -712,7 +791,7 @@ fib_entry_src_covered_inherit_add_i (fib_entry_t *fib_entry,
{
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find(fib_entry, cover_src->fes_src, NULL);
+ esrc = fib_entry_src_find(fib_entry, cover_src->fes_src);
if (cover_src == esrc)
{
@@ -787,7 +866,7 @@ fib_entry_src_covered_inherit_walk_remove (fib_node_index_t fei,
fib_entry = fib_entry_get(fei);
cover_src = ctx;
- esrc = fib_entry_src_find(fib_entry, cover_src->fes_src, NULL);
+ esrc = fib_entry_src_find(fib_entry, cover_src->fes_src);
if (cover_src == esrc)
{
@@ -866,7 +945,7 @@ fib_entry_src_covered_inherit_add (fib_entry_t *fib_entry,
{
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
ASSERT(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ACTIVE);
@@ -904,19 +983,21 @@ fib_entry_src_action_activate (fib_entry_t *fib_entry,
{
int houston_we_are_go_for_install;
+ const fib_entry_src_vft_t *vft;
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
ASSERT(!(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ACTIVE));
ASSERT(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ADDED);
- esrc->fes_flags |= FIB_ENTRY_SRC_FLAG_ACTIVE;
+ esrc->fes_flags |= (FIB_ENTRY_SRC_FLAG_ACTIVE |
+ FIB_ENTRY_SRC_FLAG_CONTRIBUTING);
+ vft = fib_entry_src_get_vft(esrc);
- if (NULL != fib_entry_src_vft[source].fesv_activate)
+ if (NULL != vft->fesv_activate)
{
- houston_we_are_go_for_install =
- fib_entry_src_vft[source].fesv_activate(esrc, fib_entry);
+ houston_we_are_go_for_install = vft->fesv_activate(esrc, fib_entry);
}
else
{
@@ -965,16 +1046,15 @@ fib_entry_src_action_deactivate (fib_entry_t *fib_entry,
fib_node_index_t path_list_index;
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
ASSERT(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ACTIVE);
- if (NULL != fib_entry_src_vft[source].fesv_deactivate)
- {
- fib_entry_src_vft[source].fesv_deactivate(esrc, fib_entry);
- }
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_deactivate,
+ (esrc, fib_entry));
- esrc->fes_flags &= ~FIB_ENTRY_SRC_FLAG_ACTIVE;
+ esrc->fes_flags &= ~(FIB_ENTRY_SRC_FLAG_ACTIVE |
+ FIB_ENTRY_SRC_FLAG_CONTRIBUTING);
FIB_ENTRY_DBG(fib_entry, "deactivate: %d", fib_entry->fe_parent);
@@ -1009,12 +1089,8 @@ fib_entry_src_action_fwd_update (const fib_entry_t *fib_entry,
vec_foreach(esrc, fib_entry->fe_srcs)
{
- if (NULL != fib_entry_src_vft[esrc->fes_src].fesv_fwd_update)
- {
- fib_entry_src_vft[esrc->fes_src].fesv_fwd_update(esrc,
- fib_entry,
- source);
- }
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_fwd_update,
+ (esrc, fib_entry, source));
}
}
@@ -1023,9 +1099,11 @@ fib_entry_src_action_reactivate (fib_entry_t *fib_entry,
fib_source_t source)
{
fib_node_index_t path_list_index;
+ const fib_entry_src_vft_t *vft;
fib_entry_src_t *esrc;
+ int remain_installed;
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
ASSERT(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ACTIVE);
@@ -1033,10 +1111,22 @@ fib_entry_src_action_reactivate (fib_entry_t *fib_entry,
fib_entry->fe_parent,
esrc->fes_pl);
- if (fib_entry->fe_parent != esrc->fes_pl)
+ /*
+ * call the source to reactive and get the go/no-go to remain installed
+ */
+ vft = fib_entry_src_get_vft(esrc);
+
+ if (NULL != vft->fesv_reactivate)
{
- int remain_installed;
+ remain_installed = vft->fesv_reactivate(esrc, fib_entry);
+ }
+ else
+ {
+ remain_installed = 1;
+ }
+ if (fib_entry->fe_parent != esrc->fes_pl)
+ {
/*
* un-link from an old path-list. Check for any loops this will clear
*/
@@ -1072,30 +1162,19 @@ fib_entry_src_action_reactivate (fib_entry_t *fib_entry,
fib_path_list_unlock(path_list_index);
/*
- * call the source to reactive and get the go/no-go to remain installed
- */
- if (NULL != fib_entry_src_vft[source].fesv_reactivate)
- {
- remain_installed =
- fib_entry_src_vft[source].fesv_reactivate(esrc, fib_entry);
- }
- else
- {
- remain_installed = 1;
- }
-
- /*
* If this source should push its state to covered prefixs, do that now.
*/
fib_entry_src_covered_inherit_add(fib_entry, source);
+ }
- if (!remain_installed)
- {
- fib_entry_src_action_uninstall(fib_entry);
- return;
- }
+ if (!remain_installed)
+ {
+ fib_entry_src_action_uninstall(fib_entry);
+ }
+ else
+ {
+ fib_entry_src_action_install(fib_entry, source);
}
- fib_entry_src_action_install(fib_entry, source);
fib_entry_src_action_fwd_update(fib_entry, source);
}
@@ -1105,13 +1184,10 @@ fib_entry_src_action_installed (const fib_entry_t *fib_entry,
{
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
- if (NULL != fib_entry_src_vft[source].fesv_installed)
- {
- fib_entry_src_vft[source].fesv_installed(esrc,
- fib_entry);
- }
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_installed,
+ (esrc, fib_entry));
fib_entry_src_action_fwd_update(fib_entry, source);
}
@@ -1133,10 +1209,18 @@ fib_entry_src_action_add (fib_entry_t *fib_entry,
fib_node_index_t fib_entry_index;
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find_or_create(fib_entry, source);
+ esrc = fib_entry_src_find_or_create(fib_entry, source, flags);
+ ASSERT(esrc->fes_ref_count < 255);
esrc->fes_ref_count++;
+ if (flags != esrc->fes_entry_flags)
+ {
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_flags_change,
+ (esrc, fib_entry, flags));
+ }
+ esrc->fes_entry_flags = flags;
+
if (1 != esrc->fes_ref_count)
{
/*
@@ -1145,21 +1229,17 @@ fib_entry_src_action_add (fib_entry_t *fib_entry,
return (fib_entry);
}
- esrc->fes_entry_flags = flags;
-
/*
* save variable so we can recover from a fib_entry realloc.
*/
fib_entry_index = fib_entry_get_index(fib_entry);
- if (NULL != fib_entry_src_vft[source].fesv_add)
- {
- fib_entry_src_vft[source].fesv_add(esrc,
- fib_entry,
- flags,
- fib_entry_get_dpo_proto(fib_entry),
- dpo);
- }
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_add,
+ (esrc,
+ fib_entry,
+ flags,
+ fib_entry_get_dpo_proto(fib_entry),
+ dpo));
fib_entry = fib_entry_get(fib_entry_index);
@@ -1192,7 +1272,7 @@ fib_entry_src_action_update (fib_entry_t *fib_entry,
fib_node_index_t fib_entry_index, old_path_list_index;
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find_or_create(fib_entry, source);
+ esrc = fib_entry_src_find_or_create(fib_entry, source, flags);
if (NULL == esrc)
{
@@ -1207,14 +1287,12 @@ fib_entry_src_action_update (fib_entry_t *fib_entry,
*/
fib_entry_index = fib_entry_get_index(fib_entry);
- if (NULL != fib_entry_src_vft[source].fesv_add)
- {
- fib_entry_src_vft[source].fesv_add(esrc,
- fib_entry,
- flags,
- fib_entry_get_dpo_proto(fib_entry),
- dpo);
- }
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_add,
+ (esrc,
+ fib_entry,
+ flags,
+ fib_entry_get_dpo_proto(fib_entry),
+ dpo));
fib_entry = fib_entry_get(fib_entry_index);
@@ -1232,7 +1310,7 @@ fib_entry_src_action_remove_or_update_inherit (fib_entry_t *fib_entry,
{
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
if (NULL == esrc)
return (FIB_ENTRY_SRC_FLAG_ACTIVE);
@@ -1261,7 +1339,7 @@ fib_entry_src_action_remove_or_update_inherit (fib_entry_t *fib_entry,
ASSERT(coveri != fib_entry_get_index(fib_entry));
cover = fib_entry_get(coveri);
- cover_src = fib_entry_src_find(cover, source, NULL);
+ cover_src = fib_entry_src_find(cover, source);
ASSERT(NULL != cover_src);
@@ -1290,7 +1368,7 @@ fib_entry_src_action_remove (fib_entry_t *fib_entry,
fib_entry_src_flag_t sflags;
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
if (NULL == esrc)
return (FIB_ENTRY_SRC_FLAG_ACTIVE);
@@ -1310,13 +1388,16 @@ fib_entry_src_action_remove (fib_entry_t *fib_entry,
{
fib_entry_src_action_deactivate(fib_entry, source);
}
+ else if (esrc->fes_flags & FIB_ENTRY_SRC_FLAG_CONTRIBUTING)
+ {
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_deactivate,
+ (esrc, fib_entry));
+ esrc->fes_flags &= ~FIB_ENTRY_SRC_FLAG_CONTRIBUTING;
+ }
old_path_list = esrc->fes_pl;
- if (NULL != fib_entry_src_vft[source].fesv_remove)
- {
- fib_entry_src_vft[source].fesv_remove(esrc);
- }
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_remove, (esrc));
fib_path_list_unlock(old_path_list);
fib_entry_unlock(fib_entry_get_index(fib_entry));
@@ -1462,7 +1543,7 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry,
*/
fib_entry_index = fib_entry_get_index(fib_entry);
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
if (NULL == esrc)
{
fib_entry =
@@ -1471,7 +1552,7 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry,
flags,
drop_dpo_get(
fib_entry_get_dpo_proto(fib_entry)));
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
}
/*
@@ -1482,12 +1563,13 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry,
*/
old_path_list = esrc->fes_pl;
- ASSERT(NULL != fib_entry_src_vft[source].fesv_path_add);
+ ASSERT(FIB_ENTRY_SRC_VFT_EXISTS(esrc, fesv_path_add));
pl_flags = fib_entry_src_flags_2_path_list_flags(fib_entry_get_flags_i(fib_entry));
fib_entry_flags_update(fib_entry, rpath, &pl_flags, esrc);
- fib_entry_src_vft[source].fesv_path_add(esrc, fib_entry, pl_flags, rpath);
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_path_add,
+ (esrc, fib_entry, pl_flags, rpath));
fib_entry = fib_entry_get(fib_entry_index);
fib_path_list_lock(esrc->fes_pl);
@@ -1508,7 +1590,7 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry,
fib_entry_t*
fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
fib_source_t source,
- fib_entry_flag_t flags,
+ fib_entry_flag_t flags,
const fib_route_path_t *rpaths)
{
fib_node_index_t old_path_list, fib_entry_index;
@@ -1516,7 +1598,7 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
const fib_route_path_t *rpath;
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
/*
* save variable so we can recover from a fib_entry realloc.
@@ -1525,15 +1607,20 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
if (NULL == esrc)
{
- fib_entry = fib_entry_src_action_add(fib_entry,
+ fib_entry = fib_entry_src_action_add(fib_entry,
source,
flags,
drop_dpo_get(
fib_entry_get_dpo_proto(fib_entry)));
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
}
else
{
+ if (flags != esrc->fes_entry_flags)
+ {
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_flags_change,
+ (esrc, fib_entry, flags));
+ }
esrc->fes_entry_flags = flags;
}
@@ -1544,7 +1631,7 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
*/
old_path_list = esrc->fes_pl;
- ASSERT(NULL != fib_entry_src_vft[source].fesv_path_swap);
+ ASSERT(FIB_ENTRY_SRC_VFT_EXISTS(esrc, fesv_path_swap));
pl_flags = fib_entry_src_flags_2_path_list_flags(flags);
@@ -1553,10 +1640,9 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
fib_entry_flags_update(fib_entry, rpath, &pl_flags, esrc);
}
- fib_entry_src_vft[source].fesv_path_swap(esrc,
- fib_entry,
- pl_flags,
- rpaths);
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_path_swap,
+ (esrc, fib_entry,
+ pl_flags, rpaths));
fib_entry = fib_entry_get(fib_entry_index);
@@ -1575,7 +1661,7 @@ fib_entry_src_action_path_remove (fib_entry_t *fib_entry,
fib_node_index_t old_path_list;
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
ASSERT(NULL != esrc);
ASSERT(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ADDED);
@@ -1588,12 +1674,13 @@ fib_entry_src_action_path_remove (fib_entry_t *fib_entry,
*/
old_path_list = esrc->fes_pl;
- ASSERT(NULL != fib_entry_src_vft[source].fesv_path_remove);
+ ASSERT(FIB_ENTRY_SRC_VFT_EXISTS(esrc, fesv_path_remove));
pl_flags = fib_entry_src_flags_2_path_list_flags(fib_entry_get_flags_i(fib_entry));
fib_entry_flags_update(fib_entry, rpath, &pl_flags, esrc);
- fib_entry_src_vft[source].fesv_path_remove(esrc, pl_flags, rpath);
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_path_remove,
+ (esrc, pl_flags, rpath));
/*
* lock the new path-list, unlock the old if it had one
@@ -1621,12 +1708,10 @@ fib_entry_src_format (fib_entry_t *fib_entry,
{
fib_entry_src_t *esrc;
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
+
+ FIB_ENTRY_SRC_VFT_INVOKE_AND_RETURN(esrc, fesv_format, (esrc, s));
- if (NULL != fib_entry_src_vft[source].fesv_format)
- {
- return (fib_entry_src_vft[source].fesv_format(esrc, s));
- }
return (s);
}
@@ -1641,7 +1726,7 @@ fib_entry_get_adj_for_source (fib_node_index_t fib_entry_index,
return (ADJ_INDEX_INVALID);
fib_entry = fib_entry_get(fib_entry_index);
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
if (NULL != esrc)
{
@@ -1667,7 +1752,7 @@ fib_entry_get_dpo_for_source (fib_node_index_t fib_entry_index,
return (0);
fib_entry = fib_entry_get(fib_entry_index);
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
if (NULL != esrc)
{
@@ -1694,7 +1779,7 @@ fib_entry_get_resolving_interface_for_source (fib_node_index_t entry_index,
fib_entry = fib_entry_get(entry_index);
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
if (NULL != esrc)
{
@@ -1715,7 +1800,7 @@ fib_entry_get_flags_for_source (fib_node_index_t entry_index,
fib_entry = fib_entry_get(entry_index);
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
if (NULL != esrc)
{
@@ -1757,12 +1842,12 @@ fib_entry_set_source_data (fib_node_index_t fib_entry_index,
fib_entry_src_t *esrc;
fib_entry = fib_entry_get(fib_entry_index);
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
- if (NULL != esrc &&
- NULL != fib_entry_src_vft[source].fesv_set_data)
+ if (NULL != esrc)
{
- fib_entry_src_vft[source].fesv_set_data(esrc, fib_entry, data);
+ FIB_ENTRY_SRC_VFT_INVOKE(esrc, fesv_set_data,
+ (esrc, fib_entry, data));
}
}
@@ -1774,12 +1859,12 @@ fib_entry_get_source_data (fib_node_index_t fib_entry_index,
fib_entry_src_t *esrc;
fib_entry = fib_entry_get(fib_entry_index);
- esrc = fib_entry_src_find(fib_entry, source, NULL);
+ esrc = fib_entry_src_find(fib_entry, source);
- if (NULL != esrc &&
- NULL != fib_entry_src_vft[source].fesv_get_data)
+ if (NULL != esrc)
{
- return (fib_entry_src_vft[source].fesv_get_data(esrc, fib_entry));
+ FIB_ENTRY_SRC_VFT_INVOKE_AND_RETURN(esrc, fesv_get_data,
+ (esrc, fib_entry));
}
return (NULL);
}
@@ -1789,6 +1874,7 @@ 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_api_register();