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(),
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);
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);
}
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;
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));
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;
}
/* 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);
}
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;
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
{
/* 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;
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;
/*
{
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
{
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);
}
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;
/*
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,
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):
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()