X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fdevices%2Faf_packet%2Fnode.c;h=efe701642bb4870fcda78a96a59de069499414f3;hb=9adcc9778c316d4c94c6734b8c8e4ce0daede820;hp=e2f87b10b359ad8b6967a80f5e4e3ff24e932560;hpb=f5462369f3ad22c9d19f54832faa2b6e61449f66;p=vpp.git diff --git a/src/vnet/devices/af_packet/node.c b/src/vnet/devices/af_packet/node.c index e2f87b10b35..efe701642bb 100644 --- a/src/vnet/devices/af_packet/node.c +++ b/src/vnet/devices/af_packet/node.c @@ -194,7 +194,7 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node, { af_packet_main_t *apm = &af_packet_main; struct tpacket2_hdr *tph; - u32 next_index = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT; + u32 next_index; u32 block = 0; u32 rx_frame; u32 n_free_bufs; @@ -209,6 +209,23 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node, u32 thread_index = vm->thread_index; u32 n_buffer_bytes = vlib_buffer_get_default_data_size (vm); u32 min_bufs = apif->rx_req->tp_frame_size / n_buffer_bytes; + u32 eth_header_size = 0; + vlib_buffer_t bt; + + if (apif->mode == AF_PACKET_IF_MODE_IP) + { + next_index = VNET_DEVICE_INPUT_NEXT_IP4_INPUT; + } + else + { + eth_header_size = sizeof (ethernet_header_t); + next_index = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT; + if (PREDICT_FALSE (apif->per_interface_next_index != ~0)) + next_index = apif->per_interface_next_index; + + /* redirect if feature path enabled */ + vnet_feature_start_device_input_x1 (apif->sw_if_index, &next_index, &bt); + } n_free_bufs = vec_len (apm->rx_buffers[thread_index]); if (PREDICT_FALSE (n_free_bufs < VLIB_FRAME_SIZE)) @@ -292,7 +309,10 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node, first_b0 = vlib_get_buffer (vm, first_bi0); if (tph->tp_status & TP_STATUS_CSUMNOTREADY) mark_tcp_udp_cksum_calc (first_b0, &l4_hdr_sz); - if (tph->tp_snaplen > apif->host_mtu) + /* This is a trade-off for GSO. As kernel isn't passing + * us the GSO state or size, we guess it by comparing it + * to the host MTU of the interface */ + if (tph->tp_snaplen > (apif->host_mtu + eth_header_size)) fill_gso_buffer_flags (first_b0, apif->host_mtu, l4_hdr_sz); } @@ -317,14 +337,30 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node, } else { - next0 = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT; - - if (PREDICT_FALSE (apif->per_interface_next_index != ~0)) - next0 = apif->per_interface_next_index; - - /* redirect if feature path enabled */ - vnet_feature_start_device_input_x1 (apif->sw_if_index, &next0, - first_b0); + if (PREDICT_FALSE (apif->mode == AF_PACKET_IF_MODE_IP)) + { + switch (first_b0->data[0] & 0xf0) + { + case 0x40: + next0 = VNET_DEVICE_INPUT_NEXT_IP4_INPUT; + break; + case 0x60: + next0 = VNET_DEVICE_INPUT_NEXT_IP6_INPUT; + break; + default: + next0 = VNET_DEVICE_INPUT_NEXT_DROP; + break; + } + if (PREDICT_FALSE (apif->per_interface_next_index != ~0)) + next0 = apif->per_interface_next_index; + } + else + { + /* copy feature arc data from template */ + first_b0->current_config_index = bt.current_config_index; + vnet_buffer (first_b0)->feature_arc_index = + vnet_buffer (&bt)->feature_arc_index; + } } /* trace */