u32 fq_index;
u32 fq_feature_index;
- // reference count for enabling/disabling feature
- u32 feature_use_refcount;
+ // reference count for enabling/disabling feature - per interface
+ u32 *feature_use_refcount_per_intf;
} ip6_sv_reass_main_t;
extern ip6_sv_reass_main_t ip6_sv_reass_main;
typedef enum
{
- ICMP_ERROR_FL_TOO_BIG,
- ICMP_ERROR_FL_NOT_MULT_8,
REASS_FRAGMENT_CACHE,
REASS_FINISH,
REASS_FRAGMENT_FORWARD,
s = format (s, "reass id: %u, op id: %u ", t->reass_id, t->op_id);
switch (t->action)
{
- case ICMP_ERROR_FL_TOO_BIG:
- s = format (s, "\n%Uicmp-error - frag_len > 65535 %U");
- break;
- case ICMP_ERROR_FL_NOT_MULT_8:
- s = format (s, "\n%Uicmp-error - frag_len mod 8 != 0 %U");
- break;
case REASS_FRAGMENT_CACHE:
s = format (s, "[cached]");
break;
next0 = IP6_SV_REASSEMBLY_NEXT_HANDOFF;
vnet_buffer (b0)->ip.reass.owner_thread_index =
kv.v.thread_index;
+ goto packet_enqueue;
}
if (!reass)
rm->fq_feature_index =
vlib_frame_queue_main_init (ip6_sv_reass_node_feature.index, 0);
+ rm->feature_use_refcount_per_intf = NULL;
+
return error;
}
uword thread_index = 0;
int index;
const uword nthreads = vlib_num_workers () + 1;
- u32 *vec_icmp_bi = NULL;
for (thread_index = 0; thread_index < nthreads; ++thread_index)
{
ip6_sv_reass_per_thread_t *rt = &rm->per_thread_data[thread_index];
clib_spinlock_unlock (&rt->lock);
}
- while (vec_len (vec_icmp_bi) > 0)
- {
- vlib_frame_t *f =
- vlib_get_frame_to_node (vm, rm->ip6_icmp_error_idx);
- u32 *to_next = vlib_frame_vector_args (f);
- u32 n_left_to_next = VLIB_FRAME_SIZE - f->n_vectors;
- int trace_frame = 0;
- while (vec_len (vec_icmp_bi) > 0 && n_left_to_next > 0)
- {
- u32 bi = vec_pop (vec_icmp_bi);
- vlib_buffer_t *b = vlib_get_buffer (vm, bi);
- if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
- {
- trace_frame = 1;
- }
- b->error = node->errors[IP6_ERROR_REASS_TIMEOUT];
- to_next[0] = bi;
- ++f->n_vectors;
- to_next += 1;
- n_left_to_next -= 1;
- }
- f->frame_flags |= (trace_frame * VLIB_FRAME_TRACE);
- vlib_put_frame_to_node (vm, rm->ip6_icmp_error_idx, f);
- }
-
vec_free (pool_indexes_to_free);
- vec_free (vec_icmp_bi);
if (event_data)
{
_vec_len (event_data) = 0;
ip6_sv_reass_enable_disable_with_refcnt (u32 sw_if_index, int is_enable)
{
ip6_sv_reass_main_t *rm = &ip6_sv_reass_main;
+ vec_validate (rm->feature_use_refcount_per_intf, sw_if_index);
if (is_enable)
{
- if (!rm->feature_use_refcount)
+ if (!rm->feature_use_refcount_per_intf[sw_if_index])
{
- ++rm->feature_use_refcount;
+ ++rm->feature_use_refcount_per_intf[sw_if_index];
return vnet_feature_enable_disable ("ip6-unicast",
"ip6-sv-reassembly-feature",
sw_if_index, 1, 0, 0);
}
- ++rm->feature_use_refcount;
+ ++rm->feature_use_refcount_per_intf[sw_if_index];
}
else
{
- --rm->feature_use_refcount;
- if (!rm->feature_use_refcount)
+ --rm->feature_use_refcount_per_intf[sw_if_index];
+ if (!rm->feature_use_refcount_per_intf[sw_if_index])
return vnet_feature_enable_disable ("ip6-unicast",
"ip6-sv-reassembly-feature",
sw_if_index, 0, 0, 0);