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
This commit is contained in:

committed by
Andrew Yourtchenko

parent
689666ca5d
commit
5d0136f099
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
if (ci != ~0)
|
||||
cm->config_index_by_sw_if_index[sw_if_index] = ci;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
Reference in New Issue
Block a user