aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/ethernet/arp.c10
-rw-r--r--src/vnet/fib/fib_entry.c12
-rw-r--r--src/vnet/fib/fib_entry.h2
-rw-r--r--src/vnet/fib/fib_entry_src.c289
-rw-r--r--src/vnet/fib/fib_entry_src_adj.c242
-rw-r--r--src/vnet/fib/fib_entry_src_api.c72
-rw-r--r--src/vnet/fib/fib_path.c6
-rw-r--r--src/vnet/fib/fib_path.h6
-rw-r--r--src/vnet/fib/fib_path_ext.c213
-rw-r--r--src/vnet/fib/fib_path_ext.h88
-rw-r--r--src/vnet/fib/fib_path_list.c31
-rw-r--r--src/vnet/fib/fib_path_list.h11
-rw-r--r--src/vnet/fib/fib_test.c791
-rw-r--r--src/vnet/fib/fib_types.h17
-rw-r--r--src/vnet/ip/ip6_neighbor.c12
-rw-r--r--src/vnet/mfib/mfib_entry.c8
-rw-r--r--src/vnet/mpls/mpls_tunnel.c117
-rw-r--r--src/vnet/mpls/mpls_tunnel.h2
18 files changed, 1194 insertions, 735 deletions
diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c
index f44cb594dea..ad0c2c8ceab 100644
--- a/src/vnet/ethernet/arp.c
+++ b/src/vnet/ethernet/arp.c
@@ -582,11 +582,11 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm,
fib_index =
ip4_fib_table_get_index_for_sw_if_index (e->sw_if_index);
e->fib_entry_index =
- fib_table_entry_update_one_path (fib_index, &pfx, FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4, &pfx.fp_addr,
- e->sw_if_index, ~0, 1, NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add (fib_index, &pfx, FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4, &pfx.fp_addr,
+ e->sw_if_index, ~0, 1, NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
}
else
{
diff --git a/src/vnet/fib/fib_entry.c b/src/vnet/fib/fib_entry.c
index 29f5b35965d..cdebfbce0a9 100644
--- a/src/vnet/fib/fib_entry.c
+++ b/src/vnet/fib/fib_entry.c
@@ -88,7 +88,6 @@ format_fib_entry (u8 * s, va_list * args)
{
fib_forward_chain_type_t fct;
fib_entry_attribute_t attr;
- fib_path_ext_t *path_ext;
fib_entry_t *fib_entry;
fib_entry_src_t *src;
fib_node_index_t fei;
@@ -126,14 +125,7 @@ format_fib_entry (u8 * s, va_list * args)
{
s = fib_path_list_format(src->fes_pl, s);
}
- if (NULL != src->fes_path_exts)
- {
- s = format(s, " Extensions:");
- vec_foreach(path_ext, src->fes_path_exts)
- {
- s = format(s, "\n %U", format_fib_path_ext, path_ext);
- }
- }
+ s = format(s, "%U", format_fib_path_ext_list, &src->fes_path_exts);
}));
s = format (s, "\n forwarding: ");
@@ -328,7 +320,7 @@ fib_entry_show_memory (void)
n_srcs += vec_len(entry->fe_srcs);
vec_foreach(esrc, entry->fe_srcs)
{
- n_exts += vec_len(esrc->fes_path_exts);
+ n_exts += fib_path_ext_list_length(&esrc->fes_path_exts);
}
}));
diff --git a/src/vnet/fib/fib_entry.h b/src/vnet/fib/fib_entry.h
index aa1000e04ec..5f6ff31297e 100644
--- a/src/vnet/fib/fib_entry.h
+++ b/src/vnet/fib/fib_entry.h
@@ -290,7 +290,7 @@ typedef struct fib_entry_src_t_ {
/**
* A vector of path extensions
*/
- struct fib_path_ext_t_ *fes_path_exts;
+ fib_path_ext_list_t fes_path_exts;
/**
* The path-list created by the source
diff --git a/src/vnet/fib/fib_entry_src.c b/src/vnet/fib/fib_entry_src.c
index ab72565d903..8c5082846a8 100644
--- a/src/vnet/fib/fib_entry_src.c
+++ b/src/vnet/fib/fib_entry_src.c
@@ -146,7 +146,7 @@ fib_entry_src_action_deinit (fib_entry_t *fib_entry,
fib_entry_src_vft[source].fesv_deinit(esrc);
}
- vec_free(esrc->fes_path_exts);
+ fib_path_ext_list_flush(&esrc->fes_path_exts);
vec_del1(fib_entry->fe_srcs, index);
}
@@ -188,7 +188,7 @@ fib_entry_src_action_cover_update (fib_entry_t *fib_entry,
typedef struct fib_entry_src_collect_forwarding_ctx_t_
{
- load_balance_path_t * next_hops;
+ load_balance_path_t *next_hops;
const fib_entry_t *fib_entry;
const fib_entry_src_t *esrc;
fib_forward_chain_type_t fct;
@@ -264,95 +264,46 @@ fib_entry_chain_type_fixup (const fib_entry_t *entry,
return (dfct);
}
-static int
-fib_entry_src_collect_forwarding (fib_node_index_t pl_index,
- fib_node_index_t path_index,
- void *arg)
+static void
+fib_entry_src_get_path_forwarding (fib_node_index_t path_index,
+ fib_entry_src_collect_forwarding_ctx_t *ctx)
{
- fib_entry_src_collect_forwarding_ctx_t *ctx;
- fib_path_ext_t *path_ext;
- int have_path_ext;
-
- ctx = arg;
-
- /*
- * if the path is not resolved, don't include it.
- */
- if (!fib_path_is_resolved(path_index))
- {
- return (!0);
- }
-
- if (fib_path_is_recursive_constrained(path_index))
- {
- ctx->n_recursive_constrained += 1;
- }
+ load_balance_path_t *nh;
/*
- * get the matching path-extension for the path being visited.
+ * no extension => no out-going label for this path. that's OK
+ * in the case of an IP or EOS chain, but not for non-EOS
*/
- have_path_ext = 0;
- vec_foreach(path_ext, ctx->esrc->fes_path_exts)
- {
- if (path_ext->fpe_path_index == path_index)
- {
- have_path_ext = 1;
- break;
- }
- }
-
- if (have_path_ext &&
- fib_entry_src_valid_out_label(path_ext->fpe_label_stack[0]))
+ switch (ctx->fct)
{
+ case FIB_FORW_CHAIN_TYPE_UNICAST_IP4:
+ case FIB_FORW_CHAIN_TYPE_UNICAST_IP6:
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP4:
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP6:
/*
- * found a matching extension. stack it to obtain the forwarding
- * info for this path.
+ * EOS traffic with no label to stack, we need the IP Adj
*/
- ctx->next_hops =
- fib_path_ext_stack(path_ext,
- ctx->fct,
- fib_entry_chain_type_fixup(ctx->fib_entry,
- ctx->fct),
- ctx->next_hops);
- }
- else
- {
- load_balance_path_t *nh;
+ vec_add2(ctx->next_hops, nh, 1);
- /*
- * no extension => no out-going label for this path. that's OK
- * in the case of an IP or EOS chain, but not for non-EOS
- */
- switch (ctx->fct)
+ nh->path_index = path_index;
+ nh->path_weight = fib_path_get_weight(path_index);
+ fib_path_contribute_forwarding(path_index, ctx->fct, &nh->path_dpo);
+
+ break;
+ case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS:
+ if (fib_path_is_exclusive(path_index) ||
+ fib_path_is_deag(path_index))
{
- case FIB_FORW_CHAIN_TYPE_UNICAST_IP4:
- case FIB_FORW_CHAIN_TYPE_UNICAST_IP6:
- case FIB_FORW_CHAIN_TYPE_MCAST_IP4:
- case FIB_FORW_CHAIN_TYPE_MCAST_IP6:
- /*
- * EOS traffic with no label to stack, we need the IP Adj
- */
vec_add2(ctx->next_hops, nh, 1);
nh->path_index = path_index;
nh->path_weight = fib_path_get_weight(path_index);
- fib_path_contribute_forwarding(path_index, ctx->fct, &nh->path_dpo);
-
- break;
- case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS:
- if (fib_path_is_exclusive(path_index) ||
- fib_path_is_deag(path_index))
- {
- vec_add2(ctx->next_hops, nh, 1);
-
- nh->path_index = path_index;
- nh->path_weight = fib_path_get_weight(path_index);
- fib_path_contribute_forwarding(path_index,
- FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
- &nh->path_dpo);
- }
- break;
- case FIB_FORW_CHAIN_TYPE_MPLS_EOS:
+ fib_path_contribute_forwarding(path_index,
+ FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
+ &nh->path_dpo);
+ }
+ break;
+ case FIB_FORW_CHAIN_TYPE_MPLS_EOS:
{
/*
* no label. we need a chain based on the payload. fixup.
@@ -371,14 +322,85 @@ fib_entry_src_collect_forwarding (fib_node_index_t pl_index,
break;
}
- case FIB_FORW_CHAIN_TYPE_ETHERNET:
- case FIB_FORW_CHAIN_TYPE_NSH:
- ASSERT(0);
- break;
+ case FIB_FORW_CHAIN_TYPE_ETHERNET:
+ case FIB_FORW_CHAIN_TYPE_NSH:
+ ASSERT(0);
+ break;
+ }
+}
+
+static fib_path_list_walk_rc_t
+fib_entry_src_collect_forwarding (fib_node_index_t pl_index,
+ fib_node_index_t path_index,
+ void *arg)
+{
+ fib_entry_src_collect_forwarding_ctx_t *ctx;
+ fib_path_ext_t *path_ext;
+
+ ctx = arg;
+
+ /*
+ * if the path is not resolved, don't include it.
+ */
+ if (!fib_path_is_resolved(path_index))
+ {
+ return (FIB_PATH_LIST_WALK_CONTINUE);
+ }
+
+ if (fib_path_is_recursive_constrained(path_index))
+ {
+ ctx->n_recursive_constrained += 1;
+ }
+
+ /*
+ * get the matching path-extension for the path being visited.
+ */
+ path_ext = fib_path_ext_list_find_by_path_index(&ctx->esrc->fes_path_exts,
+ path_index);
+
+ if (NULL != path_ext)
+ {
+ switch (path_ext->fpe_type)
+ {
+ case FIB_PATH_EXT_MPLS:
+ if (fib_entry_src_valid_out_label(path_ext->fpe_label_stack[0]))
+ {
+ /*
+ * found a matching extension. stack it to obtain the forwarding
+ * info for this path.
+ */
+ ctx->next_hops =
+ fib_path_ext_stack(path_ext,
+ ctx->fct,
+ fib_entry_chain_type_fixup(ctx->fib_entry,
+ ctx->fct),
+ ctx->next_hops);
+ }
+ else
+ {
+ fib_entry_src_get_path_forwarding(path_index, ctx);
+ }
+ break;
+ case FIB_PATH_EXT_ADJ:
+ if (FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER & path_ext->fpe_adj_flags)
+ {
+ fib_entry_src_get_path_forwarding(path_index, ctx);
+ }
+ /*
+ * else
+ * the path does not refine the cover, meaning that
+ * the adjacency doesdoes not match the sub-net on the link.
+ * So this path does not contribute forwarding.
+ */
+ break;
}
}
+ else
+ {
+ fib_entry_src_get_path_forwarding(path_index, ctx);
+ }
- return (!0);
+ return (FIB_PATH_LIST_WALK_CONTINUE);
}
void
@@ -1036,58 +1058,6 @@ fib_entry_flags_update (const fib_entry_t *fib_entry,
}
/*
- * fib_entry_src_path_ext_add
- *
- * append a path extension to the entry's list
- */
-static void
-fib_entry_src_path_ext_append (fib_entry_src_t *esrc,
- const fib_route_path_t *rpath)
-{
- if (NULL != rpath->frp_label_stack)
- {
- fib_path_ext_t *path_ext;
-
- vec_add2(esrc->fes_path_exts, path_ext, 1);
-
- fib_path_ext_init(path_ext, esrc->fes_pl, rpath);
- }
-}
-
-/*
- * fib_entry_src_path_ext_insert
- *
- * insert, sorted, a path extension to the entry's list.
- * It's not strictly necessary in sort the path extensions, since each
- * extension has the path index to which it resolves. However, by being
- * sorted the load-balance produced has a deterministic order, not an order
- * based on the sequence of extension additions. this is a considerable benefit.
- */
-static void
-fib_entry_src_path_ext_insert (fib_entry_src_t *esrc,
- const fib_route_path_t *rpath)
-{
- if (0 == vec_len(esrc->fes_path_exts))
- return (fib_entry_src_path_ext_append(esrc, rpath));
-
- if (NULL != rpath->frp_label_stack)
- {
- fib_path_ext_t path_ext;
- int i = 0;
-
- fib_path_ext_init(&path_ext, esrc->fes_pl, rpath);
-
- while (i < vec_len(esrc->fes_path_exts) &&
- (fib_path_ext_cmp(&esrc->fes_path_exts[i], rpath) < 0))
- {
- i++;
- }
-
- vec_insert_elts(esrc->fes_path_exts, &path_ext, 1, i);
- }
-}
-
-/*
* fib_entry_src_action_add
*
* Adding a source can result in a new fib_entry being created, which
@@ -1103,7 +1073,6 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry,
{
fib_node_index_t old_path_list, fib_entry_index;
fib_path_list_flags_t pl_flags;
- fib_path_ext_t *path_ext;
fib_entry_src_t *esrc;
/*
@@ -1140,18 +1109,6 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry,
fib_entry_src_vft[source].fesv_path_add(esrc, fib_entry, pl_flags, rpath);
fib_entry = fib_entry_get(fib_entry_index);
- /*
- * re-resolve all the path-extensions with the new path-list
- */
- vec_foreach(path_ext, esrc->fes_path_exts)
- {
- fib_path_ext_resolve(path_ext, esrc->fes_pl);
- }
- /*
- * if the path has a label we need to add a path extension
- */
- fib_entry_src_path_ext_insert(esrc, rpath);
-
fib_path_list_lock(esrc->fes_pl);
fib_path_list_unlock(old_path_list);
@@ -1176,7 +1133,6 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
fib_node_index_t old_path_list, fib_entry_index;
fib_path_list_flags_t pl_flags;
const fib_route_path_t *rpath;
- fib_path_ext_t *path_ext;
fib_entry_src_t *esrc;
esrc = fib_entry_src_find(fib_entry, source, NULL);
@@ -1218,17 +1174,6 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry,
pl_flags,
rpaths);
- vec_foreach(path_ext, esrc->fes_path_exts)
- {
- vec_free(path_ext->fpe_label_stack);
- }
- vec_free(esrc->fes_path_exts);
-
- vec_foreach(rpath, rpaths)
- {
- fib_entry_src_path_ext_append(esrc, rpath);
- }
-
fib_entry = fib_entry_get(fib_entry_index);
fib_path_list_lock(esrc->fes_pl);
@@ -1244,7 +1189,6 @@ fib_entry_src_action_path_remove (fib_entry_t *fib_entry,
{
fib_path_list_flags_t pl_flags;
fib_node_index_t old_path_list;
- fib_path_ext_t *path_ext;
fib_entry_src_t *esrc;
esrc = fib_entry_src_find(fib_entry, source, NULL);
@@ -1266,29 +1210,6 @@ fib_entry_src_action_path_remove (fib_entry_t *fib_entry,
fib_entry_flags_update(fib_entry, rpath, &pl_flags, esrc);
fib_entry_src_vft[source].fesv_path_remove(esrc, pl_flags, rpath);
- /*
- * find the matching path extension and remove it
- */
- vec_foreach(path_ext, esrc->fes_path_exts)
- {
- if (!fib_path_ext_cmp(path_ext, rpath))
- {
- /*
- * delete the element moving the remaining elements down 1 position.
- * this preserves the sorted order.
- */
- vec_free(path_ext->fpe_label_stack);
- vec_delete(esrc->fes_path_exts, 1, (path_ext - esrc->fes_path_exts));
- break;
- }
- }
- /*
- * re-resolve all the path-extensions with the new path-list
- */
- vec_foreach(path_ext, esrc->fes_path_exts)
- {
- fib_path_ext_resolve(path_ext, esrc->fes_pl);
- }
/*
* lock the new path-list, unlock the old if it had one
diff --git a/src/vnet/fib/fib_entry_src_adj.c b/src/vnet/fib/fib_entry_src_adj.c
index 9990223037a..9ea2b17e6b9 100644
--- a/src/vnet/fib/fib_entry_src_adj.c
+++ b/src/vnet/fib/fib_entry_src_adj.c
@@ -19,9 +19,10 @@
#include "fib_table.h"
#include "fib_entry_cover.h"
#include "fib_attached_export.h"
+#include "fib_path_ext.h"
/**
- * Source initialisation Function
+ * Source initialisation Function
*/
static void
fib_entry_src_adj_init (fib_entry_src_t *src)
@@ -31,12 +32,93 @@ fib_entry_src_adj_init (fib_entry_src_t *src)
}
static void
+fib_entry_src_adj_path_add (fib_entry_src_t *src,
+ const fib_entry_t *entry,
+ fib_path_list_flags_t pl_flags,
+ const fib_route_path_t *paths)
+{
+ const fib_route_path_t *rpath;
+
+ if (FIB_NODE_INDEX_INVALID == src->fes_pl)
+ {
+ src->fes_pl = fib_path_list_create(pl_flags, paths);
+ }
+ else
+ {
+ src->fes_pl = fib_path_list_copy_and_path_add(src->fes_pl,
+ pl_flags,
+ paths);
+ }
+
+ /*
+ * resolve the existing extensions
+ */
+ fib_path_ext_list_resolve(&src->fes_path_exts, src->fes_pl);
+
+ /*
+ * and new extensions
+ */
+ vec_foreach(rpath, paths)
+ {
+ fib_path_ext_list_insert(&src->fes_path_exts,
+ src->fes_pl,
+ FIB_PATH_EXT_ADJ,
+ rpath);
+ }
+}
+
+static void
+fib_entry_src_adj_path_remove (fib_entry_src_t *src,
+ fib_path_list_flags_t pl_flags,
+ const fib_route_path_t *rpaths)
+{
+ const fib_route_path_t *rpath;
+
+ if (FIB_NODE_INDEX_INVALID != src->fes_pl)
+ {
+ src->fes_pl = fib_path_list_copy_and_path_remove(src->fes_pl,
+ pl_flags,
+ rpaths);
+ }
+
+ /*
+ * remove the path-extension for the path
+ */
+ vec_foreach(rpath, rpaths)
+ {
+ fib_path_ext_list_remove(&src->fes_path_exts, FIB_PATH_EXT_ADJ, rpath);
+ };
+ /*
+ * resolve the remaining extensions
+ */
+ fib_path_ext_list_resolve(&src->fes_path_exts, src->fes_pl);
+}
+
+static void
fib_entry_src_adj_path_swap (fib_entry_src_t *src,
- const fib_entry_t *entry,
- fib_path_list_flags_t pl_flags,
- const fib_route_path_t *paths)
+ const fib_entry_t *entry,
+ fib_path_list_flags_t pl_flags,
+ const fib_route_path_t *paths)
{
+ const fib_route_path_t *rpath;
+
+ /*
+ * flush all the old extensions before we create a brand new path-list
+ */
+ fib_path_ext_list_flush(&src->fes_path_exts);
+
src->fes_pl = fib_path_list_create(pl_flags, paths);
+
+ /*
+ * and new extensions
+ */
+ vec_foreach(rpath, paths)
+ {
+ fib_path_ext_list_push_back(&src->fes_path_exts,
+ src->fes_pl,
+ FIB_PATH_EXT_ADJ,
+ rpath);
+ }
}
static void
@@ -45,14 +127,87 @@ fib_entry_src_adj_remove (fib_entry_src_t *src)
src->fes_pl = FIB_NODE_INDEX_INVALID;
}
+/*
+ * Add a path-extension indicating whether this path is resolved,
+ * because it passed the refinement check
+ */
+static void
+fib_enty_src_adj_update_path_ext (fib_entry_src_t *src,
+ fib_node_index_t path_index,
+ fib_path_ext_adj_flags_t flags)
+{
+ fib_path_ext_t *path_ext;
+
+ path_ext = fib_path_ext_list_find_by_path_index(&src->fes_path_exts,
+ path_index);
+
+ if (NULL != path_ext)
+ {
+ path_ext->fpe_adj_flags = flags;
+ }
+ else
+ {
+ ASSERT(!"no path extension");
+ }
+}
+
+typedef struct fib_entry_src_path_list_walk_cxt_t_
+{
+ fib_entry_src_t *src;
+ u32 cover_itf;
+ fib_path_ext_adj_flags_t flags;
+} fib_entry_src_path_list_walk_cxt_t;
+
+static fib_path_list_walk_rc_t
+fib_entry_src_adj_path_list_walk (fib_node_index_t pl_index,
+ fib_node_index_t path_index,
+ void *arg)
+{
+ fib_entry_src_path_list_walk_cxt_t *ctx;
+ u32 adj_itf;
+
+ ctx = arg;
+ adj_itf = fib_path_get_resolving_interface(path_index);
+
+ if (ctx->cover_itf == adj_itf)
+ {
+ fib_enty_src_adj_update_path_ext(ctx->src, path_index,
+ FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER);
+ ctx->flags |= FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER;
+ }
+ else
+ {
+ /*
+ * if the interface the adj is on is unnumbered to the
+ * cover's, then allow that too.
+ */
+ vnet_sw_interface_t *swif;
+
+ swif = vnet_get_sw_interface (vnet_get_main(), adj_itf);
+
+ if (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED &&
+ ctx->cover_itf == swif->unnumbered_sw_if_index)
+ {
+ fib_enty_src_adj_update_path_ext(ctx->src, path_index,
+ FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER);
+ ctx->flags |= FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER;
+ }
+ else
+ {
+ fib_enty_src_adj_update_path_ext(ctx->src, path_index,
+ FIB_PATH_EXT_ADJ_FLAG_NONE);
+ }
+ }
+ return (FIB_PATH_LIST_WALK_CONTINUE);
+}
/*
- * Source activate.
+ * Source activate.
* Called when the source is the new longer best source on the entry
*/
static int
fib_entry_src_adj_activate (fib_entry_src_t *src,
- const fib_entry_t *fib_entry)
+ const fib_entry_t *fib_entry)
{
fib_entry_t *cover;
@@ -61,7 +216,7 @@ fib_entry_src_adj_activate (fib_entry_src_t *src,
* there should always be a cover, though it may be the default route.
*/
src->adj.fesa_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
- &fib_entry->fe_prefix);
+ &fib_entry->fe_prefix);
ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
ASSERT(fib_entry_get_index(fib_entry) != src->adj.fesa_cover);
@@ -71,8 +226,8 @@ fib_entry_src_adj_activate (fib_entry_src_t *src,
ASSERT(cover != fib_entry);
src->adj.fesa_sibling =
- fib_entry_cover_track(cover,
- fib_entry_get_index(fib_entry));
+ fib_entry_cover_track(cover,
+ fib_entry_get_index(fib_entry));
/*
* if the cover is attached on the same interface as this adj source then
@@ -88,40 +243,31 @@ fib_entry_src_adj_activate (fib_entry_src_t *src,
*/
if (FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags_i(cover))
{
- u32 cover_itf = fib_entry_get_resolving_interface(src->adj.fesa_cover);
- u32 adj_itf = fib_path_list_get_resolving_interface(src->fes_pl);
-
- if (cover_itf == adj_itf)
- {
- return (1);
- }
- else
- {
- /*
- * if the interface the adj is on is unnumbered to the
- * cover's, then allow that too.
- */
- vnet_sw_interface_t *swif;
-
- swif = vnet_get_sw_interface (vnet_get_main(), adj_itf);
-
- if (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED &&
- cover_itf == swif->unnumbered_sw_if_index)
- {
- return (1);
- }
- }
+ fib_entry_src_path_list_walk_cxt_t ctx = {
+ .cover_itf = fib_entry_get_resolving_interface(src->adj.fesa_cover),
+ .flags = FIB_PATH_EXT_ADJ_FLAG_NONE,
+ .src = src,
+ };
+
+ fib_path_list_walk(src->fes_pl,
+ fib_entry_src_adj_path_list_walk,
+ &ctx);
+
+ /*
+ * active the entry is one of the paths refines the cover.
+ */
+ return (FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER & ctx.flags);
}
return (0);
}
/*
- * Source Deactivate.
+ * Source Deactivate.
* Called when the source is no longer best source on the entry
*/
static void
fib_entry_src_adj_deactivate (fib_entry_src_t *src,
- const fib_entry_t *fib_entry)
+ const fib_entry_t *fib_entry)
{
fib_entry_t *cover;
@@ -143,14 +289,14 @@ fib_entry_src_adj_deactivate (fib_entry_src_t *src,
static u8*
fib_entry_src_adj_format (fib_entry_src_t *src,
- u8* s)
+ u8* s)
{
return (format(s, "cover:%d", src->adj.fesa_cover));
}
static void
fib_entry_src_adj_installed (fib_entry_src_t *src,
- const fib_entry_t *fib_entry)
+ const fib_entry_t *fib_entry)
{
/*
* The adj source now rules! poke our cover to get exported
@@ -161,16 +307,16 @@ fib_entry_src_adj_installed (fib_entry_src_t *src,
cover = fib_entry_get(src->adj.fesa_cover);
fib_attached_export_covered_added(cover,
- fib_entry_get_index(fib_entry));
+ fib_entry_get_index(fib_entry));
}
static fib_entry_src_cover_res_t
fib_entry_src_adj_cover_change (fib_entry_src_t *src,
- const fib_entry_t *fib_entry)
+ const fib_entry_t *fib_entry)
{
fib_entry_src_cover_res_t res = {
- .install = !0,
- .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
+ .install = !0,
+ .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
};
fib_entry_src_adj_deactivate(src, fib_entry);
@@ -178,10 +324,10 @@ fib_entry_src_adj_cover_change (fib_entry_src_t *src,
res.install = fib_entry_src_adj_activate(src, fib_entry);
if (res.install) {
- /*
- * ADJ fib can install
- */
- res.bw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE;
+ /*
+ * ADJ fib can install
+ */
+ res.bw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE;
}
return (res);
@@ -196,12 +342,12 @@ fib_entry_src_adj_cover_update (fib_entry_src_t *src,
{
/*
* the cover has updated, i.e. its forwarding or flags
- * have changed. do'nt decativate/activate here, since this
+ * have changed. don't decativate/activate here, since this
* prefix is updated during the covers walk.
*/
fib_entry_src_cover_res_t res = {
- .install = !0,
- .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
+ .install = !0,
+ .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
};
fib_entry_t *cover;
@@ -217,6 +363,8 @@ fib_entry_src_adj_cover_update (fib_entry_src_t *src,
const static fib_entry_src_vft_t adj_src_vft = {
.fesv_init = fib_entry_src_adj_init,
.fesv_path_swap = fib_entry_src_adj_path_swap,
+ .fesv_path_add = fib_entry_src_adj_path_add,
+ .fesv_path_remove = fib_entry_src_adj_path_remove,
.fesv_remove = fib_entry_src_adj_remove,
.fesv_activate = fib_entry_src_adj_activate,
.fesv_deactivate = fib_entry_src_adj_deactivate,
diff --git a/src/vnet/fib/fib_entry_src_api.c b/src/vnet/fib/fib_entry_src_api.c
index 19db8819ede..f895886bc0e 100644
--- a/src/vnet/fib/fib_entry_src_api.c
+++ b/src/vnet/fib/fib_entry_src_api.c
@@ -13,9 +13,10 @@
* limitations under the License.
*/
-#include "fib_entry.h"
-#include "fib_entry_src.h"
-#include "fib_path_list.h"
+#include <vnet/fib/fib_entry.h>
+#include <vnet/fib/fib_entry_src.h>
+#include <vnet/fib/fib_path_list.h>
+#include <vnet/fib/fib_path_ext.h>
/**
* Source initialisation Function
@@ -35,45 +36,94 @@ fib_entry_src_api_deinit (fib_entry_src_t *src)
static void
fib_entry_src_api_path_swap (fib_entry_src_t *src,
- const fib_entry_t *entry,
+ const fib_entry_t *entry,
fib_path_list_flags_t pl_flags,
- const fib_route_path_t *paths)
+ const fib_route_path_t *rpaths)
{
+ const fib_route_path_t *rpath;
+
+ fib_path_ext_list_flush(&src->fes_path_exts);
+
src->fes_pl = fib_path_list_create((FIB_PATH_LIST_FLAG_SHARED | pl_flags),
- paths);
+ rpaths);
+
+ vec_foreach(rpath, rpaths)
+ {
+ if (NULL != rpath->frp_label_stack)
+ {
+ fib_path_ext_list_push_back(&src->fes_path_exts,
+ src->fes_pl,
+ FIB_PATH_EXT_MPLS,
+ rpath);
+ }
+ }
}
static void
fib_entry_src_api_path_add (fib_entry_src_t *src,
const fib_entry_t *entry,
fib_path_list_flags_t pl_flags,
- const fib_route_path_t *paths)
+ const fib_route_path_t *rpaths)
{
+ const fib_route_path_t *rpath;
+
if (FIB_NODE_INDEX_INVALID == src->fes_pl)
{
src->fes_pl =
- fib_path_list_create((FIB_PATH_LIST_FLAG_SHARED | pl_flags), paths);
+ fib_path_list_create((FIB_PATH_LIST_FLAG_SHARED | pl_flags), rpaths);
}
else
{
src->fes_pl =
fib_path_list_copy_and_path_add(src->fes_pl,
(FIB_PATH_LIST_FLAG_SHARED | pl_flags),
- paths);
+ rpaths);
+ }
+
+ /*
+ * re-resolve all the path-extensions with the new path-list
+ */
+ fib_path_ext_list_resolve(&src->fes_path_exts, src->fes_pl);
+
+ /*
+ * if the path has a label we need to add a path extension
+ */
+ vec_foreach(rpath, rpaths)
+ {
+ if (NULL != rpath->frp_label_stack)
+ {
+ fib_path_ext_list_insert(&src->fes_path_exts,
+ src->fes_pl,
+ FIB_PATH_EXT_MPLS,
+ rpath);
+ }
}
}
static void
fib_entry_src_api_path_remove (fib_entry_src_t *src,
fib_path_list_flags_t pl_flags,
- const fib_route_path_t *paths)
+ const fib_route_path_t *rpaths)
{
+ const fib_route_path_t *rpath;
+
if (FIB_NODE_INDEX_INVALID != src->fes_pl)
{
src->fes_pl =
fib_path_list_copy_and_path_remove(src->fes_pl,
(FIB_PATH_LIST_FLAG_SHARED | pl_flags),
- paths);
+ rpaths);
+ /*
+ * remove the path-extension for the path
+ */
+ vec_foreach(rpath, rpaths)
+ {
+ fib_path_ext_list_remove(&src->fes_path_exts, FIB_PATH_EXT_MPLS, rpath);
+ };
+ /*
+ * resolve the remaining extensions
+ */
+ fib_path_ext_list_resolve(&src->fes_path_exts, src->fes_pl);
}
}
diff --git a/src/vnet/fib/fib_path.c b/src/vnet/fib/fib_path.c
index b47d51f8d51..255f0dd18c6 100644
--- a/src/vnet/fib/fib_path.c
+++ b/src/vnet/fib/fib_path.c
@@ -2084,7 +2084,7 @@ fib_path_is_looped (fib_node_index_t path_index)
return (path->fp_oper_flags & FIB_PATH_OPER_FLAG_RECURSIVE_LOOP);
}
-int
+fib_path_list_walk_rc_t
fib_path_encode (fib_node_index_t path_list_index,
fib_node_index_t path_index,
void *ctx)
@@ -2095,7 +2095,7 @@ fib_path_encode (fib_node_index_t path_list_index,
path = fib_path_get(path_index);
if (!path)
- return (0);
+ return (FIB_PATH_LIST_WALK_CONTINUE);
vec_add2(*api_rpaths, api_rpath, 1);
api_rpath->rpath.frp_weight = path->fp_weight;
api_rpath->rpath.frp_proto = path->fp_nh_proto;
@@ -2124,7 +2124,7 @@ fib_path_encode (fib_node_index_t path_list_index,
default:
break;
}
- return (1);
+ return (FIB_PATH_LIST_WALK_CONTINUE);
}
fib_protocol_t
diff --git a/src/vnet/fib/fib_path.h b/src/vnet/fib/fib_path.h
index b6bf1e4fa83..0b5e6072679 100644
--- a/src/vnet/fib/fib_path.h
+++ b/src/vnet/fib/fib_path.h
@@ -170,8 +170,8 @@ extern u32 fib_path_get_resolving_interface(fib_node_index_t fib_entry_index);
extern int fib_path_get_weight(fib_node_index_t path_index);
extern void fib_path_module_init(void);
-extern int fib_path_encode(fib_node_index_t path_list_index,
- fib_node_index_t path_index,
- void *ctx);
+extern fib_path_list_walk_rc_t fib_path_encode(fib_node_index_t path_list_index,
+ fib_node_index_t path_index,
+ void *ctx);
#endif
diff --git a/src/vnet/fib/fib_path_ext.c b/src/vnet/fib/fib_path_ext.c
index 08293bcf175..45ab1f1498d 100644
--- a/src/vnet/fib/fib_path_ext.c
+++ b/src/vnet/fib/fib_path_ext.c
@@ -24,6 +24,8 @@
#include <vnet/fib/fib_path_list.h>
#include <vnet/fib/fib_internal.h>
+const char *fib_path_ext_adj_flags_names[] = FIB_PATH_EXT_ADJ_ATTR_NAMES;
+
u8 *
format_fib_path_ext (u8 * s, va_list * args)
{
@@ -32,13 +34,37 @@ format_fib_path_ext (u8 * s, va_list * args)
path_ext = va_arg (*args, fib_path_ext_t *);
- s = format(s, "path:%d labels:",
- path_ext->fpe_path_index);
- for (ii = 0; ii < vec_len(path_ext->fpe_path.frp_label_stack); ii++)
+ s = format(s, "path:%d ", path_ext->fpe_path_index);
+
+ switch (path_ext->fpe_type)
{
- s = format(s, "%U ",
- format_mpls_unicast_label,
- path_ext->fpe_path.frp_label_stack[ii]);
+ case FIB_PATH_EXT_MPLS:
+ s = format(s, "labels:",
+ path_ext->fpe_path_index);
+ for (ii = 0; ii < vec_len(path_ext->fpe_path.frp_label_stack); ii++)
+ {
+ s = format(s, "%U ",
+ format_mpls_unicast_label,
+ path_ext->fpe_path.frp_label_stack[ii]);
+ }
+ break;
+ case FIB_PATH_EXT_ADJ: {
+ fib_path_ext_adj_attr_t attr;
+
+ s = format(s, "adj-flags:");
+ if (path_ext->fpe_adj_flags)
+ {
+ FOR_EACH_PATH_EXT_ADJ_ATTR(attr)
+ {
+ s = format(s, "%s", fib_path_ext_adj_flags_names[attr]);
+ }
+ }
+ else
+ {
+ s = format(s, "None");
+ }
+ break;
+ }
}
return (s);
}
@@ -50,7 +76,7 @@ fib_path_ext_cmp (fib_path_ext_t *path_ext,
return (fib_route_path_cmp(&path_ext->fpe_path, rpath));
}
-static int
+static fib_path_list_walk_rc_t
fib_path_ext_match (fib_node_index_t pl_index,
fib_node_index_t path_index,
void *ctx)
@@ -61,10 +87,9 @@ fib_path_ext_match (fib_node_index_t pl_index,
&path_ext->fpe_path))
{
path_ext->fpe_path_index = path_index;
- return (0);
+ return (FIB_PATH_LIST_WALK_STOP);
}
- // keep going
- return (1);
+ return (FIB_PATH_LIST_WALK_CONTINUE);
}
void
@@ -83,10 +108,13 @@ fib_path_ext_resolve (fib_path_ext_t *path_ext,
void
fib_path_ext_init (fib_path_ext_t *path_ext,
fib_node_index_t path_list_index,
+ fib_path_ext_type_t ext_type,
const fib_route_path_t *rpath)
{
path_ext->fpe_path = *rpath;
path_ext->fpe_path_index = FIB_NODE_INDEX_INVALID;
+ path_ext->fpe_adj_flags = FIB_PATH_EXT_ADJ_FLAG_NONE;
+ path_ext->fpe_type = ext_type;
fib_path_ext_resolve(path_ext, path_list_index);
}
@@ -229,3 +257,168 @@ fib_path_ext_stack (fib_path_ext_t *path_ext,
return (nhs);
}
+
+fib_path_ext_t *
+fib_path_ext_list_find (const fib_path_ext_list_t *list,
+ fib_path_ext_type_t ext_type,
+ const fib_route_path_t *rpath)
+{
+ fib_path_ext_t *path_ext;
+
+ vec_foreach(path_ext, list->fpel_exts)
+ {
+ if ((path_ext->fpe_type == ext_type) &&
+ !fib_path_ext_cmp(path_ext, rpath) )
+ {
+ return (path_ext);
+ }
+ }
+ return (NULL);
+}
+
+fib_path_ext_t *
+fib_path_ext_list_find_by_path_index (const fib_path_ext_list_t *list,
+ fib_node_index_t path_index)
+{
+ fib_path_ext_t *path_ext;
+
+ vec_foreach(path_ext, list->fpel_exts)
+ {
+ if (path_ext->fpe_path_index == path_index)
+ {
+ return (path_ext);
+ }
+ }
+ return (NULL);
+}
+
+
+fib_path_ext_t *
+fib_path_ext_list_push_back (fib_path_ext_list_t *list,
+ fib_node_index_t path_list_index,
+ fib_path_ext_type_t ext_type,
+ const fib_route_path_t *rpath)
+{
+ fib_path_ext_t *path_ext;
+
+ path_ext = fib_path_ext_list_find(list, ext_type, rpath);
+
+ if (NULL == path_ext)
+ {
+ vec_add2(list->fpel_exts, path_ext, 1);
+ fib_path_ext_init(path_ext, path_list_index, ext_type, rpath);
+ }
+
+ return (path_ext);
+}
+
+/*
+ * insert, sorted, a path extension to the entry's list.
+ * It's not strictly necessary to sort the path extensions, since each
+ * extension has the path index to which it resolves. However, by being
+ * sorted the load-balance produced has a deterministic order, not an order
+ * based on the sequence of extension additions. this is a considerable benefit.
+ */
+fib_path_ext_t *
+fib_path_ext_list_insert (fib_path_ext_list_t *list,
+ fib_node_index_t path_list_index,
+ fib_path_ext_type_t ext_type,
+ const fib_route_path_t *rpath)
+{
+ fib_path_ext_t new_path_ext, *path_ext;
+ int i = 0;
+
+ if (0 == fib_path_ext_list_length(list))
+ {
+ return (fib_path_ext_list_push_back(list, path_list_index,
+ ext_type, rpath));
+ }
+
+ fib_path_ext_init(&new_path_ext, path_list_index, ext_type, rpath);
+
+ vec_foreach(path_ext, list->fpel_exts)
+ {
+ if (fib_path_ext_cmp(path_ext, rpath) < 0)
+ {
+ i++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ vec_insert_elts(list->fpel_exts, &new_path_ext, 1, i);
+
+ return (&(list->fpel_exts[i]));
+}
+
+void
+fib_path_ext_list_resolve (fib_path_ext_list_t *list,
+ fib_node_index_t path_list_index)
+{
+ fib_path_ext_t *path_ext;
+
+ vec_foreach(path_ext, list->fpel_exts)
+ {
+ fib_path_ext_resolve(path_ext, path_list_index);
+ };
+}
+
+void
+fib_path_ext_list_remove (fib_path_ext_list_t *list,
+ fib_path_ext_type_t ext_type,
+ const fib_route_path_t *rpath)
+{
+ fib_path_ext_t *path_ext;
+
+ path_ext = fib_path_ext_list_find(list, ext_type, rpath);
+
+ if (NULL != path_ext)
+ {
+ /*
+ * delete the element moving the remaining elements down 1 position.
+ * this preserves the sorted order.
+ */
+ vec_free(path_ext->fpe_label_stack);
+ vec_delete(list->fpel_exts, 1, (path_ext - list->fpel_exts));
+ }
+}
+
+void
+fib_path_ext_list_flush (fib_path_ext_list_t *list)
+{
+ fib_path_ext_t *path_ext;
+
+ vec_foreach(path_ext, list->fpel_exts)
+ {
+ vec_free(path_ext->fpe_label_stack);
+ };
+ vec_free(list->fpel_exts);
+ list->fpel_exts = NULL;
+}
+
+u8*
+format_fib_path_ext_list (u8 * s, va_list * args)
+{
+ fib_path_ext_list_t *list;
+ fib_path_ext_t *path_ext;
+
+ list = va_arg (*args, fib_path_ext_list_t *);
+
+ if (fib_path_ext_list_length(list))
+ {
+ s = format(s, " Extensions:");
+ vec_foreach(path_ext, list->fpel_exts)
+ {
+ s = format(s, "\n %U", format_fib_path_ext, path_ext);
+ };
+ }
+
+ return (s);
+}
+
+int
+fib_path_ext_list_length (const fib_path_ext_list_t *list)
+{
+ return (vec_len(list->fpel_exts));
+}
diff --git a/src/vnet/fib/fib_path_ext.h b/src/vnet/fib/fib_path_ext.h
index d617700d026..d1571a1b4ee 100644
--- a/src/vnet/fib/fib_path_ext.h
+++ b/src/vnet/fib/fib_path_ext.h
@@ -21,6 +21,45 @@
#include <vnet/dpo/load_balance.h>
/**
+ * A description of the type of path extension
+ */
+typedef enum fib_path_ext_type_t_
+{
+ /**
+ * An MPLS extension that maintains the path's outgoing labels,
+ */
+ FIB_PATH_EXT_MPLS,
+ /**
+ * A adj-source extension indicating the path's refinement criteria
+ * result
+ */
+ FIB_PATH_EXT_ADJ,
+} fib_path_ext_type_t;
+
+/**
+ * Flags present on an ADJ sourced path-extension
+ */
+typedef enum fib_path_ext_adj_attr_t_
+{
+ FIB_PATH_EXT_ADJ_ATTR_REFINES_COVER,
+} fib_path_ext_adj_attr_t;
+
+typedef enum fib_path_ext_adj_flags_t_
+{
+ FIB_PATH_EXT_ADJ_FLAG_NONE = 0,
+ FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER = (1 << FIB_PATH_EXT_ADJ_ATTR_REFINES_COVER),
+} fib_path_ext_adj_flags_t;
+
+#define FIB_PATH_EXT_ADJ_ATTR_NAMES { \
+ [FIB_PATH_EXT_ADJ_ATTR_REFINES_COVER] = "refines-cover", \
+}
+
+#define FOR_EACH_PATH_EXT_ADJ_ATTR(_item) \
+ for (_item = FIB_PATH_EXT_ADJ_ATTR_REFINES_COVER; \
+ _item <= FIB_PATH_EXT_ADJ_ATTR_REFINES_COVER; \
+ _item++)
+
+/**
* A path extension is a per-entry addition to the forwarding information
* when packets are sent for that entry over that path.
*
@@ -33,6 +72,11 @@
typedef struct fib_path_ext_t_
{
/**
+ * The type of path extension
+ */
+ fib_path_ext_type_t fpe_type;
+
+ /**
* A description of the path that is being extended.
* This description is used to match this extension with the [changing]
* instance of a fib_path_t that is extended
@@ -40,21 +84,24 @@ typedef struct fib_path_ext_t_
fib_route_path_t fpe_path;
#define fpe_label_stack fpe_path.frp_label_stack
+ union {
+ /**
+ * For an ADJ type extension
+ *
+ * Flags describing the adj state
+ */
+ fib_path_ext_adj_flags_t fpe_adj_flags;
+ };
+
/**
* The index of the path. This is the global index, not the path's
* position in the path-list.
*/
fib_node_index_t fpe_path_index;
-} fib_path_ext_t;
-
-struct fib_entry_t_;
+} __attribute__ ((packed)) fib_path_ext_t;
extern u8 * format_fib_path_ext(u8 * s, va_list * args);
-extern void fib_path_ext_init(fib_path_ext_t *path_ext,
- fib_node_index_t path_list_index,
- const fib_route_path_t *rpath);
-
extern int fib_path_ext_cmp(fib_path_ext_t *path_ext,
const fib_route_path_t *rpath);
@@ -66,5 +113,32 @@ extern load_balance_path_t *fib_path_ext_stack(fib_path_ext_t *path_ext,
fib_forward_chain_type_t imp_null_fct,
load_balance_path_t *nhs);
+extern fib_path_ext_t * fib_path_ext_list_push_back (fib_path_ext_list_t *list,
+ fib_node_index_t path_list_index,
+ fib_path_ext_type_t ext_type,
+ const fib_route_path_t *rpath);
+
+extern fib_path_ext_t * fib_path_ext_list_insert (fib_path_ext_list_t *list,
+ fib_node_index_t path_list_index,
+ fib_path_ext_type_t ext_type,
+ const fib_route_path_t *rpath);
+
+extern u8* format_fib_path_ext_list (u8 * s, va_list * args);
+
+extern void fib_path_ext_list_remove (fib_path_ext_list_t *list,
+ fib_path_ext_type_t ext_type,
+ const fib_route_path_t *rpath);
+
+extern fib_path_ext_t * fib_path_ext_list_find (const fib_path_ext_list_t *list,
+ fib_path_ext_type_t ext_type,
+ const fib_route_path_t *rpath);
+extern fib_path_ext_t * fib_path_ext_list_find_by_path_index (const fib_path_ext_list_t *list,
+ fib_node_index_t path_index);
+extern void fib_path_ext_list_resolve(fib_path_ext_list_t *list,
+ fib_node_index_t path_list_index);
+
+extern int fib_path_ext_list_length(const fib_path_ext_list_t *list);
+extern void fib_path_ext_list_flush(fib_path_ext_list_t *list);
+
#endif
diff --git a/src/vnet/fib/fib_path_list.c b/src/vnet/fib/fib_path_list.c
index 64917f95107..3e4c3333a08 100644
--- a/src/vnet/fib/fib_path_list.c
+++ b/src/vnet/fib/fib_path_list.c
@@ -914,21 +914,32 @@ fib_path_list_copy_and_path_add (fib_node_index_t orig_path_list_index,
* If we find one then we can return the existing one and destroy the
* new one just created.
*/
- exist_path_list_index = fib_path_list_db_find(path_list);
- if (FIB_NODE_INDEX_INVALID != exist_path_list_index)
+ if (path_list->fpl_flags & FIB_PATH_LIST_FLAG_SHARED)
{
- fib_path_list_destroy(path_list);
+ exist_path_list_index = fib_path_list_db_find(path_list);
+ if (FIB_NODE_INDEX_INVALID != exist_path_list_index)
+ {
+ fib_path_list_destroy(path_list);
- path_list_index = exist_path_list_index;
+ path_list_index = exist_path_list_index;
+ }
+ else
+ {
+ /*
+ * if there was not a matching path-list, then this
+ * new one will need inserting into the DB and resolving.
+ */
+ fib_path_list_db_insert(path_list_index);
+
+ path_list = fib_path_list_resolve(path_list);
+ }
}
else
{
/*
- * if there was not a matching path-list, then this
- * new one will need inserting into the DB and resolving.
+ * no shared path list requested. resolve and use the one
+ * just created.
*/
- fib_path_list_db_insert(path_list_index);
-
path_list = fib_path_list_resolve(path_list);
}
@@ -1289,7 +1300,9 @@ fib_path_list_walk (fib_node_index_t path_list_index,
vec_foreach(path_index, path_list->fpl_paths)
{
- if (!func(path_list_index, *path_index, ctx))
+ if (FIB_PATH_LIST_WALK_STOP == func(path_list_index,
+ *path_index,
+ ctx))
break;
}
}
diff --git a/src/vnet/fib/fib_path_list.h b/src/vnet/fib/fib_path_list.h
index 376cb726dd6..b4b6985bd9a 100644
--- a/src/vnet/fib/fib_path_list.h
+++ b/src/vnet/fib/fib_path_list.h
@@ -19,8 +19,8 @@
#include <vlib/vlib.h>
#include <vnet/adj/adj.h>
-#include "fib_node.h"
-#include "fib_path.h"
+#include <vnet/fib/fib_node.h>
+#include <vnet/fib/fib_path.h>
/**
* Enumeration of path-list flags.
@@ -161,9 +161,10 @@ extern u32 fib_path_list_find_rpath (fib_node_index_t path_list_index,
/**
* A callback function type for walking a path-list's paths
*/
-typedef int (*fib_path_list_walk_fn_t)(fib_node_index_t pl_index,
- fib_node_index_t path_index,
- void *ctx);
+typedef fib_path_list_walk_rc_t (*fib_path_list_walk_fn_t)(
+ fib_node_index_t pl_index,
+ fib_node_index_t path_index,
+ void *ctx);
extern void fib_path_list_walk(fib_node_index_t pl_index,
fib_path_list_walk_fn_t func,
diff --git a/src/vnet/fib/fib_test.c b/src/vnet/fib/fib_test.c
index 486e5616798..06aeda62354 100644
--- a/src/vnet/fib/fib_test.c
+++ b/src/vnet/fib/fib_test.c
@@ -846,7 +846,8 @@ fib_test_v4 (void)
"Flags set on attached interface");
ai = fib_entry_get_adj(fei);
- FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "attached interface route adj present");
+ FIB_TEST((FIB_NODE_INDEX_INVALID != ai),
+ "attached interface route adj present %d", ai);
adj = adj_get(ai);
FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
"attached interface adj is glean");
@@ -1089,21 +1090,21 @@ fib_test_v4 (void)
/*
* add the adj fib
*/
- fei = fib_table_entry_update_one_path(fib_index,
- &pfx_10_10_10_1_s_32,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4,
- &pfx_10_10_10_1_s_32.fp_addr,
- tm->hw[0]->sw_if_index,
- ~0, // invalid fib index
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fei = fib_table_entry_path_add(fib_index,
+ &pfx_10_10_10_1_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4,
+ &pfx_10_10_10_1_s_32.fp_addr,
+ tm->hw[0]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
"Flags set on adj-fib");
ai = fib_entry_get_adj(fei);
- FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
+ FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj, %d", ai);
fib_table_entry_path_remove(fib_index,
&pfx_11_11_11_11_s_32,
@@ -1138,17 +1139,17 @@ fib_test_v4 (void)
"adj nbr next-hop ok");
FIB_TEST((ai_01 != ai_02), "ADJs are different");
- fib_table_entry_update_one_path(fib_index,
- &pfx_10_10_10_2_s_32,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4,
- &pfx_10_10_10_2_s_32.fp_addr,
- tm->hw[0]->sw_if_index,
- ~0, // invalid fib index
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add(fib_index,
+ &pfx_10_10_10_2_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4,
+ &pfx_10_10_10_2_s_32.fp_addr,
+ tm->hw[0]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
fei = fib_table_lookup(fib_index, &pfx_10_10_10_2_s_32);
ai = fib_entry_get_adj(fei);
@@ -1644,13 +1645,13 @@ fib_test_v4 (void)
.ip4.as_u32 = clib_host_to_net_u32(0x06060606),
},
};
- fib_test_lb_bucket_t ip_6_6_6_6_o_10_10_10_1 = {
+ fib_test_lb_bucket_t ip_o_10_10_10_1 = {
.type = FT_LB_ADJ,
.adj = {
.adj = ai_01,
},
};
- fib_test_lb_bucket_t ip_6_6_6_6_o_10_10_10_2 = {
+ fib_test_lb_bucket_t ip_o_10_10_10_2 = {
.type = FT_LB_ADJ,
.adj = {
.adj = ai_02,
@@ -1678,7 +1679,7 @@ fib_test_v4 (void)
FIB_TEST(fib_test_validate_entry(fei,
FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1,
- &ip_6_6_6_6_o_10_10_10_1),
+ &ip_o_10_10_10_1),
"6.6.6.6/32 via 10.10.10.1");
fib_table_entry_path_add(fib_index,
@@ -1697,70 +1698,70 @@ fib_test_v4 (void)
FIB_TEST(fib_test_validate_entry(fei,
FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
64,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_1),
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_1),
"6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
fib_table_entry_path_add(fib_index,
@@ -1779,71 +1780,71 @@ fib_test_v4 (void)
FIB_TEST(fib_test_validate_entry(fei,
FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
128,
- &ip_6_6_6_6_o_10_10_10_1,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
+ &ip_o_10_10_10_1,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
&ip_6_6_6_6_o_12_12_12_12,
&ip_6_6_6_6_o_12_12_12_12,
&ip_6_6_6_6_o_12_12_12_12,
@@ -1923,70 +1924,70 @@ fib_test_v4 (void)
FIB_TEST(fib_test_validate_entry(fei,
FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
64,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_2,
- &ip_6_6_6_6_o_10_10_10_1),
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_2,
+ &ip_o_10_10_10_1),
"6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
fib_table_entry_path_remove(fib_index,
@@ -2003,7 +2004,7 @@ fib_test_v4 (void)
FIB_TEST(fib_test_validate_entry(fei,
FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1,
- &ip_6_6_6_6_o_10_10_10_1),
+ &ip_o_10_10_10_1),
"6.6.6.6/32 via 10.10.10.1");
fib_table_entry_delete(fib_index, &pfx_6_6_6_6_s_32, FIB_SOURCE_API);
@@ -3808,17 +3809,17 @@ fib_test_v4 (void)
},
};
- fib_table_entry_update_one_path(fib_index,
- &pfx_12_10_10_2_s_32,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4,
- &pfx_12_10_10_2_s_32.fp_addr,
- tm->hw[0]->sw_if_index,
- ~0, // invalid fib index
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add(fib_index,
+ &pfx_12_10_10_2_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4,
+ &pfx_12_10_10_2_s_32.fp_addr,
+ tm->hw[0]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
fei = fib_table_lookup_exact_match(fib_index, &pfx_12_10_10_2_s_32);
dpo = fib_entry_contribute_ip_forwarding(fei);
@@ -3842,17 +3843,17 @@ fib_test_v4 (void)
},
};
- fib_table_entry_update_one_path(fib_index,
- &pfx_10_10_10_127_s_32,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4,
- &pfx_10_10_10_127_s_32.fp_addr,
- tm->hw[1]->sw_if_index,
- ~0, // invalid fib index
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add(fib_index,
+ &pfx_10_10_10_127_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4,
+ &pfx_10_10_10_127_s_32.fp_addr,
+ tm->hw[1]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_127_s_32);
dpo = fib_entry_contribute_ip_forwarding(fei);
@@ -3862,6 +3863,134 @@ fib_test_v4 (void)
fib_table_entry_delete(fib_index,
&pfx_10_10_10_127_s_32,
FIB_SOURCE_ADJ);
+
+ /*
+ * add a second path to an adj-fib
+ * this is a sumiluation of another ARP entry created
+ * on an interface on which the connected prefi does not exist.
+ * The second path fails refinement. Expect to forward through the
+ * first.
+ */
+ fib_prefix_t pfx_10_10_10_3_s_32 = {
+ .fp_len = 32,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_addr = {
+ /* 10.10.10.3 */
+ .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
+ },
+ };
+
+ ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
+ VNET_LINK_IP4,
+ &nh_10_10_10_3,
+ tm->hw[0]->sw_if_index);
+
+ fib_test_lb_bucket_t ip_o_10_10_10_3 = {
+ .type = FT_LB_ADJ,
+ .adj = {
+ .adj = ai_03,
+ },
+ };
+ fei = fib_table_entry_path_add(fib_index,
+ &pfx_10_10_10_3_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_NONE,
+ FIB_PROTOCOL_IP4,
+ &nh_10_10_10_3,
+ tm->hw[0]->sw_if_index,
+ fib_index,
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ fei = fib_table_entry_path_add(fib_index,
+ &pfx_10_10_10_3_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_NONE,
+ FIB_PROTOCOL_IP4,
+ &nh_12_12_12_12,
+ tm->hw[1]->sw_if_index,
+ fib_index,
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ FIB_TEST(fib_test_validate_entry(fei,
+ FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+ 1,
+ &ip_o_10_10_10_3),
+ "10.10.10.3 via 10.10.10.3/Eth0 only");
+
+ /*
+ * remove the path that refines the cover, should go unresolved
+ */
+ fib_table_entry_path_remove(fib_index,
+ &pfx_10_10_10_3_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_PROTOCOL_IP4,
+ &nh_10_10_10_3,
+ tm->hw[0]->sw_if_index,
+ fib_index,
+ 1,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ dpo = fib_entry_contribute_ip_forwarding(fei);
+ FIB_TEST(!dpo_id_is_valid(dpo),
+ "wrong interface adj-fib fails refinement");
+
+ /*
+ * add back the path that refines the cover
+ */
+ fei = fib_table_entry_path_add(fib_index,
+ &pfx_10_10_10_3_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_NONE,
+ FIB_PROTOCOL_IP4,
+ &nh_10_10_10_3,
+ tm->hw[0]->sw_if_index,
+ fib_index,
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ FIB_TEST(fib_test_validate_entry(fei,
+ FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+ 1,
+ &ip_o_10_10_10_3),
+ "10.10.10.3 via 10.10.10.3/Eth0 only");
+
+ /*
+ * remove the path that does not refine the cover
+ */
+ fib_table_entry_path_remove(fib_index,
+ &pfx_10_10_10_3_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_PROTOCOL_IP4,
+ &nh_12_12_12_12,
+ tm->hw[1]->sw_if_index,
+ fib_index,
+ 1,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ FIB_TEST(fib_test_validate_entry(fei,
+ FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+ 1,
+ &ip_o_10_10_10_3),
+ "10.10.10.3 via 10.10.10.3/Eth0 only");
+
+ /*
+ * remove the path that does refine, it's the last path, so
+ * the entry should be gone
+ */
+ fib_table_entry_path_remove(fib_index,
+ &pfx_10_10_10_3_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_PROTOCOL_IP4,
+ &nh_10_10_10_3,
+ tm->hw[0]->sw_if_index,
+ fib_index,
+ 1,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
+ FIB_TEST((fei == FIB_NODE_INDEX_INVALID), "10.10.10.3 gone");
+
+ adj_unlock(ai_03);
+
/*
* change the table's flow-hash config - expect the update to propagete to
* the entries' load-balance objects
@@ -4283,17 +4412,17 @@ fib_test_v6 (void)
&adj->sub_type.nbr.next_hop)),
"adj nbr next-hop ok");
- fib_table_entry_update_one_path(fib_index,
- &pfx_2001_1_2_s_128,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP6,
- &pfx_2001_1_2_s_128.fp_addr,
- tm->hw[0]->sw_if_index,
- ~0,
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add(fib_index,
+ &pfx_2001_1_2_s_128,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP6,
+ &pfx_2001_1_2_s_128.fp_addr,
+ tm->hw[0]->sw_if_index,
+ ~0,
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
fei = fib_table_lookup(fib_index, &pfx_2001_1_2_s_128);
ai = fib_entry_get_adj(fei);
@@ -4322,17 +4451,17 @@ fib_test_v6 (void)
"adj nbr next-hop ok");
FIB_TEST((ai_01 != ai_02), "ADJs are different");
- fib_table_entry_update_one_path(fib_index,
- &pfx_2001_1_3_s_128,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP6,
- &pfx_2001_1_3_s_128.fp_addr,
- tm->hw[0]->sw_if_index,
- ~0,
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add(fib_index,
+ &pfx_2001_1_3_s_128,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP6,
+ &pfx_2001_1_3_s_128.fp_addr,
+ tm->hw[0]->sw_if_index,
+ ~0,
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
fei = fib_table_lookup(fib_index, &pfx_2001_1_3_s_128);
ai = fib_entry_get_adj(fei);
@@ -4957,17 +5086,17 @@ fib_test_ae (void)
};
fib_node_index_t ai;
- fib_table_entry_update_one_path(fib_index,
- &pfx_10_10_10_1_s_32,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4,
- &pfx_10_10_10_1_s_32.fp_addr,
- tm->hw[0]->sw_if_index,
- ~0, // invalid fib index
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add(fib_index,
+ &pfx_10_10_10_1_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4,
+ &pfx_10_10_10_1_s_32.fp_addr,
+ tm->hw[0]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
fei = fib_table_lookup(fib_index, &pfx_10_10_10_1_s_32);
FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 created");
@@ -5026,17 +5155,17 @@ fib_test_ae (void)
},
};
- fib_table_entry_update_one_path(fib_index,
- &pfx_10_10_10_2_s_32,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4,
- &pfx_10_10_10_2_s_32.fp_addr,
- tm->hw[0]->sw_if_index,
- ~0, // invalid fib index
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add(fib_index,
+ &pfx_10_10_10_2_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4,
+ &pfx_10_10_10_2_s_32.fp_addr,
+ tm->hw[0]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 present");
ai = fib_entry_get_adj(fei);
@@ -5097,17 +5226,17 @@ fib_test_ae (void)
},
};
- fib_table_entry_update_one_path(fib_index,
- &pfx_10_10_10_3_s_32,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4,
- &pfx_10_10_10_3_s_32.fp_addr,
- tm->hw[0]->sw_if_index,
- ~0, // invalid fib index
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add(fib_index,
+ &pfx_10_10_10_3_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4,
+ &pfx_10_10_10_3_s_32.fp_addr,
+ tm->hw[0]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 present");
ai = fib_entry_get_adj(fei);
@@ -7144,17 +7273,17 @@ fib_test_bfd (void)
/*
* source the entry via the ADJ fib
*/
- fei = fib_table_entry_update_one_path(0,
- &pfx_10_10_10_1_s_32,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4,
- &nh_10_10_10_1,
- tm->hw[0]->sw_if_index,
- ~0, // invalid fib index
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fei = fib_table_entry_path_add(0,
+ &pfx_10_10_10_1_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4,
+ &nh_10_10_10_1,
+ tm->hw[0]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
/*
* Delete the BFD session. Expect the fib_entry to remain
@@ -7183,17 +7312,17 @@ fib_test_bfd (void)
.fp_len = 32,
.fp_proto = FIB_PROTOCOL_IP4,
};
- fib_table_entry_update_one_path(0,
- &pfx_10_10_10_2_s_32,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4,
- &nh_10_10_10_2,
- tm->hw[0]->sw_if_index,
- ~0, // invalid fib index
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add(0,
+ &pfx_10_10_10_2_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4,
+ &nh_10_10_10_2,
+ tm->hw[0]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
/*
* A BFD session for the new ADJ FIB
*/
@@ -7215,17 +7344,17 @@ fib_test_bfd (void)
* then add it back
*/
fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
- fib_table_entry_update_one_path(0,
- &pfx_10_10_10_2_s_32,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP4,
- &nh_10_10_10_2,
- tm->hw[0]->sw_if_index,
- ~0, // invalid fib index
- 1,
- NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add(0,
+ &pfx_10_10_10_2_s_32,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP4,
+ &nh_10_10_10_2,
+ tm->hw[0]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
/*
* Before adding a recursive via the BFD tracked ADJ-FIBs,
diff --git a/src/vnet/fib/fib_types.h b/src/vnet/fib/fib_types.h
index 4cb73e8a7a6..60873c4a9db 100644
--- a/src/vnet/fib/fib_types.h
+++ b/src/vnet/fib/fib_types.h
@@ -400,4 +400,21 @@ typedef struct fib_route_path_encode_t_ {
dpo_id_t dpo;
} fib_route_path_encode_t;
+/**
+ * return code to control pat-hlist walk
+ */
+typedef enum fib_path_list_walk_rc_t_
+{
+ FIB_PATH_LIST_WALK_STOP,
+ FIB_PATH_LIST_WALK_CONTINUE,
+} fib_path_list_walk_rc_t;
+
+/**
+ * A list of path-extensions
+ */
+typedef struct fib_path_ext_list_t_
+{
+ struct fib_path_ext_t_ *fpel_exts;
+} fib_path_ext_list_t;
+
#endif
diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c
index 4fd078dcf32..e140c55d428 100644
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -630,12 +630,12 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
fib_index = ip6_main.fib_index_by_sw_if_index[n->key.sw_if_index];
n->fib_entry_index =
- fib_table_entry_update_one_path (fib_index, &pfx,
- FIB_SOURCE_ADJ,
- FIB_ENTRY_FLAG_ATTACHED,
- FIB_PROTOCOL_IP6, &pfx.fp_addr,
- n->key.sw_if_index, ~0, 1, NULL,
- FIB_ROUTE_PATH_FLAG_NONE);
+ fib_table_entry_path_add (fib_index, &pfx,
+ FIB_SOURCE_ADJ,
+ FIB_ENTRY_FLAG_ATTACHED,
+ FIB_PROTOCOL_IP6, &pfx.fp_addr,
+ n->key.sw_if_index, ~0, 1, NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
}
else
{
diff --git a/src/vnet/mfib/mfib_entry.c b/src/vnet/mfib/mfib_entry.c
index a937842553c..49792f02ae4 100644
--- a/src/vnet/mfib/mfib_entry.c
+++ b/src/vnet/mfib/mfib_entry.c
@@ -527,7 +527,7 @@ typedef struct mfib_entry_collect_forwarding_ctx_t_
mfib_entry_src_t *msrc;
} mfib_entry_collect_forwarding_ctx_t;
-static int
+static fib_path_list_walk_rc_t
mfib_entry_src_collect_forwarding (fib_node_index_t pl_index,
fib_node_index_t path_index,
void *arg)
@@ -542,7 +542,7 @@ mfib_entry_src_collect_forwarding (fib_node_index_t pl_index,
*/
if (!fib_path_is_resolved(path_index))
{
- return (!0);
+ return (FIB_PATH_LIST_WALK_CONTINUE);
}
/*
@@ -556,7 +556,7 @@ mfib_entry_src_collect_forwarding (fib_node_index_t pl_index,
if (NULL != path_ext &&
!(path_ext->mfpe_flags & MFIB_ITF_FLAG_FORWARD))
{
- return (!0);
+ return (FIB_PATH_LIST_WALK_CONTINUE);
}
switch (ctx->fct)
@@ -583,7 +583,7 @@ mfib_entry_src_collect_forwarding (fib_node_index_t pl_index,
break;
}
- return (!0);
+ return (FIB_PATH_LIST_WALK_CONTINUE);
}
static void
diff --git a/src/vnet/mpls/mpls_tunnel.c b/src/vnet/mpls/mpls_tunnel.c
index 457d48eb6bf..d6e85e70b44 100644
--- a/src/vnet/mpls/mpls_tunnel.c
+++ b/src/vnet/mpls/mpls_tunnel.c
@@ -99,14 +99,13 @@ typedef struct mpls_tunnel_collect_forwarding_ctx_t_
fib_forward_chain_type_t fct;
} mpls_tunnel_collect_forwarding_ctx_t;
-static int
+static fib_path_list_walk_rc_t
mpls_tunnel_collect_forwarding (fib_node_index_t pl_index,
fib_node_index_t path_index,
void *arg)
{
mpls_tunnel_collect_forwarding_ctx_t *ctx;
fib_path_ext_t *path_ext;
- int have_path_ext;
ctx = arg;
@@ -115,23 +114,16 @@ mpls_tunnel_collect_forwarding (fib_node_index_t pl_index,
*/
if (!fib_path_is_resolved(path_index))
{
- return (!0);
+ return (FIB_PATH_LIST_WALK_CONTINUE);
}
/*
* get the matching path-extension for the path being visited.
*/
- have_path_ext = 0;
- vec_foreach(path_ext, ctx->mt->mt_path_exts)
- {
- if (path_ext->fpe_path_index == path_index)
- {
- have_path_ext = 1;
- break;
- }
- }
+ path_ext = fib_path_ext_list_find_by_path_index(&ctx->mt->mt_path_exts,
+ path_index);
- if (have_path_ext)
+ if (NULL != path_ext)
{
/*
* found a matching extension. stack it to obtain the forwarding
@@ -149,7 +141,7 @@ mpls_tunnel_collect_forwarding (fib_node_index_t pl_index,
* There should be a path-extenios associated with each path
*/
- return (!0);
+ return (FIB_PATH_LIST_WALK_CONTINUE);
}
static void
@@ -648,58 +640,6 @@ vnet_mpls_tunnel_create (u8 l2_only,
return (mt->mt_sw_if_index);
}
-/*
- * mpls_tunnel_path_ext_add
- *
- * append a path extension to the entry's list
- */
-static void
-mpls_tunnel_path_ext_append (mpls_tunnel_t *mt,
- const fib_route_path_t *rpath)
-{
- if (NULL != rpath->frp_label_stack)
- {
- fib_path_ext_t *path_ext;
-
- vec_add2(mt->mt_path_exts, path_ext, 1);
-
- fib_path_ext_init(path_ext, mt->mt_path_list, rpath);
- }
-}
-
-/*
- * mpls_tunnel_path_ext_insert
- *
- * insert, sorted, a path extension to the entry's list.
- * It's not strictly necessary in sort the path extensions, since each
- * extension has the path index to which it resolves. However, by being
- * sorted the load-balance produced has a deterministic order, not an order
- * based on the sequence of extension additions. this is a considerable benefit.
- */
-static void
-mpls_tunnel_path_ext_insert (mpls_tunnel_t *mt,
- const fib_route_path_t *rpath)
-{
- if (0 == vec_len(mt->mt_path_exts))
- return (mpls_tunnel_path_ext_append(mt, rpath));
-
- if (NULL != rpath->frp_label_stack)
- {
- fib_path_ext_t path_ext;
- int i = 0;
-
- fib_path_ext_init(&path_ext, mt->mt_path_list, rpath);
-
- while (i < vec_len(mt->mt_path_exts) &&
- (fib_path_ext_cmp(&mt->mt_path_exts[i], rpath) < 0))
- {
- i++;
- }
-
- vec_insert_elts(mt->mt_path_exts, &path_ext, 1, i);
- }
-}
-
void
vnet_mpls_tunnel_path_add (u32 sw_if_index,
fib_route_path_t *rpaths)
@@ -727,7 +667,6 @@ vnet_mpls_tunnel_path_add (u32 sw_if_index,
else
{
fib_node_index_t old_pl_index;
- fib_path_ext_t *path_ext;
old_pl_index = mt->mt_path_list;
@@ -744,12 +683,12 @@ vnet_mpls_tunnel_path_add (u32 sw_if_index,
/*
* re-resolve all the path-extensions with the new path-list
*/
- vec_foreach(path_ext, mt->mt_path_exts)
- {
- fib_path_ext_resolve(path_ext, mt->mt_path_list);
- }
+ fib_path_ext_list_resolve(&mt->mt_path_exts, mt->mt_path_list);
}
- mpls_tunnel_path_ext_insert(mt, rpaths);
+ fib_path_ext_list_insert(&mt->mt_path_exts,
+ mt->mt_path_list,
+ FIB_PATH_EXT_MPLS,
+ rpaths);
mpls_tunnel_restack(mt);
}
@@ -778,7 +717,6 @@ vnet_mpls_tunnel_path_remove (u32 sw_if_index,
else
{
fib_node_index_t old_pl_index;
- fib_path_ext_t *path_ext;
old_pl_index = mt->mt_path_list;
@@ -805,27 +743,15 @@ vnet_mpls_tunnel_path_remove (u32 sw_if_index,
/*
* find the matching path extension and remove it
*/
- vec_foreach(path_ext, mt->mt_path_exts)
- {
- if (!fib_path_ext_cmp(path_ext, rpaths))
- {
- /*
- * delete the element moving the remaining elements down 1 position.
- * this preserves the sorted order.
- */
- vec_free(path_ext->fpe_label_stack);
- vec_delete(mt->mt_path_exts, 1,
- (path_ext - mt->mt_path_exts));
- break;
- }
- }
- /*
+ fib_path_ext_list_remove(&mt->mt_path_exts,
+ FIB_PATH_EXT_MPLS,
+ rpaths);
+
+ /*
* re-resolve all the path-extensions with the new path-list
*/
- vec_foreach(path_ext, mt->mt_path_exts)
- {
- fib_path_ext_resolve(path_ext, mt->mt_path_list);
- }
+ fib_path_ext_list_resolve(&mt->mt_path_exts,
+ mt->mt_path_list);
mpls_tunnel_restack(mt);
}
@@ -960,7 +886,6 @@ format_mpls_tunnel (u8 * s, va_list * args)
{
mpls_tunnel_t *mt = va_arg (*args, mpls_tunnel_t *);
mpls_tunnel_attribute_t attr;
- fib_path_ext_t *path_ext;
s = format(s, "mpls_tunnel%d: sw_if_index:%d hw_if_index:%d",
mt - mpls_tunnel_pool,
@@ -976,11 +901,7 @@ format_mpls_tunnel (u8 * s, va_list * args)
}
s = format(s, "\n via:\n");
s = fib_path_list_format(mt->mt_path_list, s);
- s = format(s, " Extensions:");
- vec_foreach(path_ext, mt->mt_path_exts)
- {
- s = format(s, "\n %U", format_fib_path_ext, path_ext);
- }
+ s = format(s, "%U", format_fib_path_ext_list, &mt->mt_path_exts);
s = format(s, "\n");
return (s);
diff --git a/src/vnet/mpls/mpls_tunnel.h b/src/vnet/mpls/mpls_tunnel.h
index ec0729a0f91..4cb0a860802 100644
--- a/src/vnet/mpls/mpls_tunnel.h
+++ b/src/vnet/mpls/mpls_tunnel.h
@@ -82,7 +82,7 @@ typedef struct mpls_tunnel_t_
/**
* A vector of path extensions o hold the label stack for each path
*/
- fib_path_ext_t *mt_path_exts;
+ fib_path_ext_list_t mt_path_exts;
/**
* @brief Flag to indicate the tunnel is only for L2 traffic, that is