summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2020-05-12 08:51:02 +0000
committerAndrew Yourtchenko <ayourtch@gmail.com>2020-05-13 11:30:34 +0000
commit5d0136f09944b0d7ea9d1db5c368d4d0b36cedd2 (patch)
tree4b8eec68f58d1837f2b52cf7e394ca00b3d2040c
parent689666ca5d4149ec5d48b7fbd195f6c2b2c016f3 (diff)
feature: Config end nodes are user specific
Type: fix it is possible for a user to change the end node of a feature arc, but this change should only apply to that 'instnace' of the arc, not all arcs. for example, if a tunnel has its ipx-output end node changed to adj-midchain-tx, this shouldn't affect all ipx-output arcs. obviously... Signed-off-by: Neale Ranns <nranns@cisco.com> Change-Id: I41daea7ba6907963e42140307d065c8bcfdcb585
-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
-rw-r--r--test/test_ipsec_tun_if_esp.py12
6 files changed, 53 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
diff --git a/test/test_ipsec_tun_if_esp.py b/test/test_ipsec_tun_if_esp.py
index 3ab0e73ff74..a59baf1dfbf 100644
--- a/test/test_ipsec_tun_if_esp.py
+++ b/test/test_ipsec_tun_if_esp.py
@@ -21,6 +21,7 @@ from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint
from vpp_teib import VppTeib
from util import ppp
from vpp_papi import VppEnum
+from vpp_acl import AclRule, VppAcl, VppAclInterface
def config_tun_params(p, encryption_type, tun_if):
@@ -2027,6 +2028,17 @@ class TestIpsec4TunProtectTun(TemplateIpsec,
self.config_sa_tun(p)
self.config_protect(p)
+ # also add an output features on the tunnel and physical interface
+ # so we test they still work
+ r_all = AclRule(True,
+ src_prefix="0.0.0.0/0",
+ dst_prefix="0.0.0.0/0",
+ proto=0)
+ a = VppAcl(self, [r_all]).add_vpp_config()
+
+ VppAclInterface(self, self.pg0.sw_if_index, [a]).add_vpp_config()
+ VppAclInterface(self, p.tun_if.sw_if_index, [a]).add_vpp_config()
+
self.verify_tun_44(p, count=127)
c = p.tun_if.get_rx_stats()