summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vnet/adj/adj_midchain.c10
-rw-r--r--src/vnet/config.c32
-rw-r--r--src/vnet/config.h3
-rw-r--r--src/vnet/feature/feature.c18
-rw-r--r--src/vnet/feature/feature.h2
5 files changed, 41 insertions, 24 deletions
diff --git a/src/vnet/adj/adj_midchain.c b/src/vnet/adj/adj_midchain.c
index 4741ec9a953..050c25a9e34 100644
--- a/src/vnet/adj/adj_midchain.c
+++ b/src/vnet/adj/adj_midchain.c
@@ -361,7 +361,7 @@ adj_midchain_teardown (ip_adjacency_t *adj)
dpo_reset(&adj->sub_type.midchain.next_dpo);
vlib_worker_thread_barrier_sync(vm);
- vnet_feature_modify_end_node(
+ adj->ia_cfg_index = vnet_feature_modify_end_node(
adj_midchain_get_feature_arc_index_for_link_type (adj),
adj->rewrite_header.sw_if_index,
vlib_get_node_by_name (vlib_get_main(),
@@ -405,7 +405,7 @@ adj_midchain_setup (adj_index_t adj_index,
tx_node = adj_nbr_midchain_get_tx_node(adj);
vlib_worker_thread_barrier_sync(vm);
- vnet_feature_modify_end_node(
+ adj->ia_cfg_index = vnet_feature_modify_end_node(
adj_midchain_get_feature_arc_index_for_link_type (adj),
adj->rewrite_header.sw_if_index,
tx_node);
@@ -481,7 +481,7 @@ adj_nbr_midchain_update_next_node (adj_index_t adj_index,
adj->ia_node_index,
next_node);
- vnet_feature_modify_end_node(
+ adj->ia_cfg_index = vnet_feature_modify_end_node(
adj_midchain_get_feature_arc_index_for_link_type (adj),
adj->rewrite_header.sw_if_index,
next_node);
@@ -490,7 +490,7 @@ adj_nbr_midchain_update_next_node (adj_index_t adj_index,
}
void
-adj_nbr_midchain_reset_next_node(adj_index_t adj_index)
+adj_nbr_midchain_reset_next_node (adj_index_t adj_index)
{
ip_adjacency_t *adj;
vlib_main_t * vm;
@@ -507,7 +507,7 @@ adj_nbr_midchain_reset_next_node(adj_index_t adj_index)
adj->ia_node_index,
adj_nbr_midchain_get_tx_node(adj));
- vnet_feature_modify_end_node(
+ adj->ia_cfg_index = vnet_feature_modify_end_node(
adj_midchain_get_feature_arc_index_for_link_type (adj),
adj->rewrite_header.sw_if_index,
adj_nbr_midchain_get_tx_node(adj));
diff --git a/src/vnet/config.c b/src/vnet/config.c
index e341c697044..59375746af5 100644
--- a/src/vnet/config.c
+++ b/src/vnet/config.c
@@ -85,7 +85,8 @@ add_next (vlib_main_t * vm,
static vnet_config_t *
find_config_with_features (vlib_main_t * vm,
vnet_config_main_t * cm,
- vnet_config_feature_t * feature_vector)
+ vnet_config_feature_t * feature_vector,
+ u32 end_node_index)
{
u32 last_node_index = ~0;
vnet_config_feature_t *f;
@@ -112,9 +113,9 @@ find_config_with_features (vlib_main_t * vm,
}
/* Terminate config string with next for end node. */
- if (last_node_index == ~0 || last_node_index != cm->end_node_index)
+ if (last_node_index == ~0 || last_node_index != end_node_index)
{
- u32 next_index = add_next (vm, cm, last_node_index, cm->end_node_index);
+ u32 next_index = add_next (vm, cm, last_node_index, end_node_index);
vec_add1 (config_string, next_index);
}
@@ -152,6 +153,12 @@ find_config_with_features (vlib_main_t * vm,
hash_set_mem (cm->config_string_hash, config_string, c->index);
c->reference_count = 0; /* will be incremented by caller. */
+
+ vec_validate_init_empty (cm->end_node_indices_by_user_index,
+ c->config_string_heap_index + 1,
+ cm->default_end_node_index);
+ cm->end_node_indices_by_user_index[c->config_string_heap_index + 1]
+ = end_node_index;
}
return c;
@@ -197,7 +204,7 @@ vnet_config_init (vlib_main_t * vm,
if (n)
{
if (i + 1 == n_feature_node_names)
- cm->end_node_index = n->index;
+ cm->default_end_node_index = n->index;
cm->node_index_by_feature_index[i] = n->index;
}
else
@@ -263,7 +270,7 @@ vnet_config_modify_end_node (vlib_main_t * vm,
{
/* is the last feature the cuurent end node */
u32 last = vec_len (new_features) - 1;
- if (new_features[last].node_index == cm->end_node_index)
+ if (new_features[last].node_index == cm->default_end_node_index)
{
vec_free (new_features->feature_config);
_vec_len (new_features) = last;
@@ -273,9 +280,7 @@ vnet_config_modify_end_node (vlib_main_t * vm,
if (old)
remove_reference (cm, old);
- cm->end_node_index = end_node_index;
-
- new = find_config_with_features (vm, cm, new_features);
+ new = find_config_with_features (vm, cm, new_features, end_node_index);
new->reference_count += 1;
/*
@@ -299,7 +304,7 @@ vnet_config_add_feature (vlib_main_t * vm,
{
vnet_config_t *old, *new;
vnet_config_feature_t *new_features, *f;
- u32 n_feature_config_u32s;
+ u32 n_feature_config_u32s, end_node_index;
u32 node_index = vec_elt (cm->node_index_by_feature_index, feature_index);
if (node_index == ~0) // feature node does not exist
@@ -309,12 +314,15 @@ vnet_config_add_feature (vlib_main_t * vm,
{
old = 0;
new_features = 0;
+ end_node_index = cm->default_end_node_index;
}
else
{
u32 *p = vnet_get_config_heap (cm, config_string_heap_index);
old = pool_elt_at_index (cm->config_pool, p[-1]);
new_features = old->features;
+ end_node_index =
+ cm->end_node_indices_by_user_index[config_string_heap_index];
if (new_features)
new_features = duplicate_feature_vector (new_features);
}
@@ -336,7 +344,7 @@ vnet_config_add_feature (vlib_main_t * vm,
if (old)
remove_reference (cm, old);
- new = find_config_with_features (vm, cm, new_features);
+ new = find_config_with_features (vm, cm, new_features, end_node_index);
new->reference_count += 1;
/*
@@ -398,7 +406,9 @@ vnet_config_del_feature (vlib_main_t * vm,
adds a new config because none of existing config's has matching features
and so can be reused */
remove_reference (cm, old);
- new = find_config_with_features (vm, cm, new_features);
+ new = find_config_with_features (vm, cm, new_features,
+ cm->end_node_indices_by_user_index
+ [config_string_heap_index]);
new->reference_count += 1;
vec_validate (cm->config_pool_index_by_user_index,
diff --git a/src/vnet/config.h b/src/vnet/config.h
index ab9e4b19886..7eb3cf0ae1f 100644
--- a/src/vnet/config.h
+++ b/src/vnet/config.h
@@ -95,7 +95,8 @@ typedef struct
u32 *config_string_heap;
/* Node index which starts/ends feature processing. */
- u32 *start_node_indices, end_node_index;
+ u32 *start_node_indices, *end_node_indices_by_user_index,
+ default_end_node_index;
/* Interior feature processing nodes (not including start and end nodes). */
u32 *node_index_by_feature_index;
diff --git a/src/vnet/feature/feature.c b/src/vnet/feature/feature.c
index 4a5127db6ac..09dd9cc965f 100644
--- a/src/vnet/feature/feature.c
+++ b/src/vnet/feature/feature.c
@@ -321,7 +321,7 @@ vnet_feature_enable_disable (const char *arc_name, const char *node_name,
n_feature_config_bytes);
}
-int
+u32
vnet_feature_modify_end_node (u8 arc_index,
u32 sw_if_index, u32 end_node_index)
{
@@ -342,12 +342,10 @@ vnet_feature_modify_end_node (u8 arc_index,
ci = vnet_config_modify_end_node (vlib_get_main (), &cm->config_main,
ci, end_node_index);
- if (ci == ~0)
- return 0;
-
- cm->config_index_by_sw_if_index[sw_if_index] = ci;
+ if (ci != ~0)
+ cm->config_index_by_sw_if_index[sw_if_index] = ci;
- return 0;
+ return ci;
}
static int
@@ -495,6 +493,14 @@ vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index, int verbose)
else
vlib_cli_output (vm, " %v", n->name);
}
+ if (verbose)
+ {
+ n =
+ vlib_get_node (vm,
+ vcm->end_node_indices_by_user_index
+ [current_config_index]);
+ vlib_cli_output (vm, " [end] %v", n->name);
+ }
}
}
diff --git a/src/vnet/feature/feature.h b/src/vnet/feature/feature.h
index 4d568a512a8..6eb6de3fba7 100644
--- a/src/vnet/feature/feature.h
+++ b/src/vnet/feature/feature.h
@@ -219,7 +219,7 @@ vnet_feature_enable_disable (const char *arc_name, const char *node_name,
void *feature_config,
u32 n_feature_config_bytes);
-int
+u32
vnet_feature_modify_end_node (u8 arc_index, u32 sw_if_index, u32 node_index);
static_always_inline u32