// convenience
vlib_main_t *vlib_main;
- // node index of ip4-drop node
- u32 ip4_drop_idx;
u32 ip4_full_reass_expire_node_idx;
/** Worker handoff */
always_inline void
ip4_full_reass_drop_all (vlib_main_t *vm, vlib_node_runtime_t *node,
- ip4_full_reass_t *reass)
+ ip4_full_reass_t *reass, u32 offending_bi)
{
u32 range_bi = reass->first_bi;
vlib_buffer_t *range_b;
while (~0 != bi)
{
vec_add1 (to_free, bi);
+ if (offending_bi == bi)
+ {
+ offending_bi = ~0;
+ }
vlib_buffer_t *b = vlib_get_buffer (vm, bi);
if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
{
}
range_bi = range_vnb->ip.reass.next_range_bi;
}
+ if (~0 != offending_bi)
+ {
+ vec_add1 (to_free, offending_bi);
+ }
/* send to next_error_index */
if (~0 != reass->error_next_index)
{
if (now > reass->last_heard + rm->timeout)
{
- ip4_full_reass_drop_all (vm, node, reass);
+ ip4_full_reass_drop_all (vm, node, reass, ~0);
ip4_full_reass_free (rm, rt, reass);
reass = NULL;
}
{
vlib_node_increment_counter (vm, node->node_index, counter,
1);
- ip4_full_reass_drop_all (vm, node, reass);
+ ip4_full_reass_drop_all (vm, node, reass, bi0);
ip4_full_reass_free (rm, rt, reass);
goto next_packet;
}
nbuckets = ip4_full_reass_get_nbuckets ();
clib_bihash_init_16_8 (&rm->hash, "ip4-dr", nbuckets, nbuckets * 1024);
- node = vlib_get_node_by_name (vm, (u8 *) "ip4-drop");
- ASSERT (node);
- rm->ip4_drop_idx = node->index;
-
rm->fq_index = vlib_frame_queue_main_init (ip4_full_reass_node.index, 0);
rm->fq_local_index =
vlib_frame_queue_main_init (ip4_local_full_reass_node.index, 0);
vec_foreach (i, pool_indexes_to_free)
{
ip4_full_reass_t *reass = pool_elt_at_index (rt->pool, i[0]);
- ip4_full_reass_drop_all (vm, node, reass);
+ ip4_full_reass_drop_all (vm, node, reass, ~0);
ip4_full_reass_free (rm, rt, reass);
}
false /* is_local */);
}
-
VLIB_REGISTER_NODE (ip4_full_reass_feature_handoff_node) = {
.name = "ip4-full-reass-feature-hoff",
.vector_size = sizeof (u32),
false /* is_local */);
}
-
VLIB_REGISTER_NODE (ip4_full_reass_custom_handoff_node) = {
.name = "ip4-full-reass-custom-hoff",
.vector_size = sizeof (u32),
IP6_FULL_REASS_RC_NO_BUF,
IP6_FULL_REASS_RC_HANDOFF,
IP6_FULL_REASS_RC_INVALID_FRAG_LEN,
+ IP6_FULL_REASS_RC_OVERLAP,
} ip6_full_reass_rc_t;
typedef struct
// convenience
vlib_main_t *vlib_main;
- // node index of ip6-drop node
- u32 ip6_drop_idx;
u32 ip6_icmp_error_idx;
u32 ip6_full_reass_expire_node_idx;
always_inline void
ip6_full_reass_drop_all (vlib_main_t *vm, vlib_node_runtime_t *node,
- ip6_full_reass_t *reass)
+ ip6_full_reass_t *reass, u32 offending_bi)
{
u32 range_bi = reass->first_bi;
vlib_buffer_t *range_b;
while (~0 != bi)
{
vec_add1 (to_free, bi);
+ if (bi == offending_bi)
+ {
+ offending_bi = ~0;
+ }
vlib_buffer_t *b = vlib_get_buffer (vm, bi);
if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
{
}
range_bi = range_vnb->ip.reass.next_range_bi;
}
+ if (~0 != offending_bi)
+ {
+ vec_add1 (to_free, offending_bi);
+ }
/* send to next_error_index */
if (~0 != reass->error_next_index)
{
0);
}
}
- ip6_full_reass_drop_all (vm, node, reass);
+ ip6_full_reass_drop_all (vm, node, reass, ~0);
}
always_inline ip6_full_reass_t *
if (trim_front > tmp->current_length)
{
/* drop whole buffer */
- vec_add1 (vec_drop_compress, tmp_bi);
- trim_front -= tmp->current_length;
if (!(tmp->flags & VLIB_BUFFER_NEXT_PRESENT))
{
rv = IP6_FULL_REASS_RC_INTERNAL_ERROR;
goto free_buffers_and_return;
}
+ trim_front -= tmp->current_length;
+ vec_add1 (vec_drop_compress, tmp_bi);
tmp->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
tmp_bi = tmp->next_buffer;
tmp = vlib_get_buffer (vm, tmp_bi);
}
else
{
- vec_add1 (vec_drop_compress, tmp_bi);
if (reass->first_bi == tmp_bi)
{
rv = IP6_FULL_REASS_RC_INTERNAL_ERROR;
goto free_buffers_and_return;
}
+ vec_add1 (vec_drop_compress, tmp_bi);
++dropped_cnt;
}
if (tmp->flags & VLIB_BUFFER_NEXT_PRESENT)
ip6_full_reass_add_trace (vm, node, reass, *bi0, frag_hdr,
RANGE_OVERLAP, ~0);
}
- ip6_full_reass_drop_all (vm, node, reass);
- ip6_full_reass_free (rm, rt, reass);
- *next0 = IP6_FULL_REASSEMBLY_NEXT_DROP;
- *error0 = IP6_ERROR_REASS_OVERLAPPING_FRAGMENT;
- return IP6_FULL_REASS_RC_OK;
+ return IP6_FULL_REASS_RC_OVERLAP;
}
break;
}
case IP6_FULL_REASS_RC_INVALID_FRAG_LEN:
counter = IP6_ERROR_REASS_INVALID_FRAG_LEN;
break;
+ case IP6_FULL_REASS_RC_OVERLAP:
+ counter = IP6_ERROR_REASS_OVERLAPPING_FRAGMENT;
+ break;
}
if (~0 != counter)
{
vlib_node_increment_counter (vm, node->node_index, counter,
1);
- ip6_full_reass_drop_all (vm, node, reass);
+ ip6_full_reass_drop_all (vm, node, reass, bi0);
ip6_full_reass_free (rm, rt, reass);
goto next_packet;
+ break;
}
}
else
clib_bihash_init_48_8 (&rm->hash, "ip6-full-reass", nbuckets,
nbuckets * 1024);
- node = vlib_get_node_by_name (vm, (u8 *) "ip6-drop");
- ASSERT (node);
- rm->ip6_drop_idx = node->index;
node = vlib_get_node_by_name (vm, (u8 *) "ip6-icmp-error");
ASSERT (node);
rm->ip6_icmp_error_idx = node->index;
vm, node, frame, true /* is_feature */, false /* is_local */);
}
-
VLIB_REGISTER_NODE (ip6_full_reassembly_feature_handoff_node) = {
.name = "ip6-full-reass-feature-hoff",
.vector_size = sizeof (u32),