- ip4_reass_kv_t kv;
- u8 do_handoff = 0;
-
- kv.k.as_u64[0] =
- (u64) vec_elt (ip4_main.fib_index_by_sw_if_index,
- vnet_buffer (b0)->sw_if_index[VLIB_RX]) |
- (u64) ip0->src_address.as_u32 << 32;
- kv.k.as_u64[1] =
- (u64) ip0->dst_address.as_u32 |
- (u64) ip0->fragment_id << 32 | (u64) ip0->protocol << 48;
-
- ip4_reass_t *reass =
- ip4_reass_find_or_create (vm, node, rm, rt, &kv,
- &do_handoff);
- if (reass)
- {
- const u32 fragment_first =
- ip4_get_fragment_offset_bytes (ip0);
- if (0 == fragment_first)
- {
- reass->sendout_thread_index = vm->thread_index;
- }
- }
- if (PREDICT_FALSE (do_handoff))
- {
- next0 = IP4_REASSEMBLY_NEXT_HANDOFF;
- if (is_feature)
- vnet_buffer (b0)->ip.
- reass.owner_feature_thread_index =
- kv.v.memory_owner_thread_index;
- else
- vnet_buffer (b0)->ip.reass.owner_thread_index =
- kv.v.memory_owner_thread_index;
- }
- else if (reass)
- {
- u32 handoff_thread_idx;
- switch (ip4_reass_update
- (vm, node, rm, rt, reass, &bi0, &next0,
- &error0, is_custom_app, &handoff_thread_idx))
- {
- case IP4_REASS_RC_OK:
- /* nothing to do here */
- break;
- case IP4_REASS_RC_HANDOFF:
- next0 = IP4_REASSEMBLY_NEXT_HANDOFF;
- b0 = vlib_get_buffer (vm, bi0);
- if (is_feature)
- vnet_buffer (b0)->ip.
- reass.owner_feature_thread_index =
- handoff_thread_idx;
- else
- vnet_buffer (b0)->ip.reass.owner_thread_index =
- handoff_thread_idx;
- break;
- case IP4_REASS_RC_TOO_MANY_FRAGMENTS:
- vlib_node_increment_counter (vm, node->node_index,
- IP4_ERROR_REASS_FRAGMENT_CHAIN_TOO_LONG,
- 1);
- ip4_reass_drop_all (vm, node, rm, reass);
- ip4_reass_free (vm, rm, rt, reass);
- goto next_packet;
- break;
- case IP4_REASS_RC_NO_BUF:
- vlib_node_increment_counter (vm, node->node_index,
- IP4_ERROR_REASS_NO_BUF,
- 1);
- ip4_reass_drop_all (vm, node, rm, reass);
- ip4_reass_free (vm, rm, rt, reass);
- goto next_packet;
- break;
- case IP4_REASS_RC_INTERNAL_ERROR:
- /* drop everything and start with a clean slate */
- vlib_node_increment_counter (vm, node->node_index,
- IP4_ERROR_REASS_INTERNAL_ERROR,
- 1);
- ip4_reass_drop_all (vm, node, rm, reass);
- ip4_reass_free (vm, rm, rt, reass);
- goto next_packet;
- break;
- }
- }