e0 = (void *) (b0->data + b0->current_data);
- vnet_buffer (b0)->ethernet.start_of_ethernet_header = b0->current_data;
+ vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
vlib_buffer_advance (b0, sizeof (e0[0]));
tag = clib_net_to_host_u16 (h0->priority_cfi_and_id);
*outer_id = tag & 0xfff;
+ if (0 == *outer_id)
+ *match_flags &= ~SUBINT_CONFIG_MATCH_1_TAG;
*type = clib_net_to_host_u16 (h0->type);
vlib_buffer_advance (b0, sizeof (h0[0]));
vlan_count = 2;
-
if (*type == ETHERNET_TYPE_VLAN)
{
// More than double tagged packet
*match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_3_TAG;
+
+ vlib_buffer_advance (b0, sizeof (h0[0]));
vlan_count = 3; // "unknown" number, aka, 3-or-more
}
}
if (!(*is_l2))
{
ethernet_header_t *e0;
- e0 =
- (void *) (b0->data +
- vnet_buffer (b0)->ethernet.start_of_ethernet_header);
+ e0 = (void *) (b0->data + vnet_buffer (b0)->l2_hdr_offset);
if (!(ethernet_address_cast (e0->dst_address)))
{
{
*next0 = em->l2_next;
// record the L2 len and reset the buffer so the L2 header is preserved
- u32 eth_start = vnet_buffer (b0)->ethernet.start_of_ethernet_header;
+ u32 eth_start = vnet_buffer (b0)->l2_hdr_offset;
vnet_buffer (b0)->l2.l2_len = b0->current_data - eth_start;
+ ASSERT (vnet_buffer (b0)->l2.l2_len ==
+ ethernet_buffer_header_size (b0));
vlib_buffer_advance (b0, -ethernet_buffer_header_size (b0));
// check for common IP/MPLS ethertypes
{
*next0 = em->l3_next.input_next_ip6;
}
- else if (type0 == ETHERNET_TYPE_MPLS_UNICAST)
+ else if (type0 == ETHERNET_TYPE_MPLS)
{
*next0 = em->l3_next.input_next_mpls;
}
}
+static_always_inline int
+ethernet_frame_is_any_tagged (u16 type0, u16 type1)
+{
+#if __SSE4_2__
+ const __m128i ethertype_mask = _mm_set_epi16 (ETHERNET_TYPE_VLAN,
+ ETHERNET_TYPE_DOT1AD,
+ ETHERNET_TYPE_VLAN_9100,
+ ETHERNET_TYPE_VLAN_9200,
+ /* duplicate for type1 */
+ ETHERNET_TYPE_VLAN,
+ ETHERNET_TYPE_DOT1AD,
+ ETHERNET_TYPE_VLAN_9100,
+ ETHERNET_TYPE_VLAN_9200);
+
+ __m128i r =
+ _mm_set_epi16 (type0, type0, type0, type0, type1, type1, type1, type1);
+ r = _mm_cmpeq_epi16 (ethertype_mask, r);
+ return !_mm_test_all_zeros (r, r);
+#else
+ return ethernet_frame_is_tagged (type0) || ethernet_frame_is_tagged (type1);
+#endif
+}
+
static_always_inline uword
ethernet_input_inline (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_node_runtime_t *error_node;
u32 n_left_from, next_index, *from, *to_next;
u32 stats_sw_if_index, stats_n_packets, stats_n_bytes;
- u32 cpu_index = os_get_cpu_number ();
+ u32 thread_index = vlib_get_thread_index ();
u32 cached_sw_if_index = ~0;
u32 cached_is_l2 = 0; /* shut up gcc */
vnet_hw_interface_t *hi = NULL; /* used for main interface only */
/* Speed-path for the untagged case */
if (PREDICT_TRUE (variant == ETHERNET_INPUT_VARIANT_ETHERNET
- && !ethernet_frame_is_tagged (type0)
- && !ethernet_frame_is_tagged (type1)))
+ && !ethernet_frame_is_any_tagged (type0, type1)))
{
main_intf_t *intf0;
subint_config_t *subint0;
cached_is_l2 = is_l20 = subint0->flags & SUBINT_CONFIG_L2;
}
- vnet_buffer (b0)->ethernet.start_of_ethernet_header =
- b0->current_data;
- vnet_buffer (b1)->ethernet.start_of_ethernet_header =
- b1->current_data;
+ vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
+ vnet_buffer (b1)->l2_hdr_offset = b1->current_data;
if (PREDICT_TRUE (is_l20 != 0))
{
else
{
if (!ethernet_address_cast (e0->dst_address) &&
+ (hi->hw_address != 0) &&
!eth_mac_equal ((u8 *) e0, hi->hw_address))
error0 = ETHERNET_ERROR_L3_MAC_MISMATCH;
if (!ethernet_address_cast (e1->dst_address) &&
+ (hi->hw_address != 0) &&
!eth_mac_equal ((u8 *) e1, hi->hw_address))
error1 = ETHERNET_ERROR_L3_MAC_MISMATCH;
determine_next_node (em, variant, 0, type0, b0,
{
len0 = vlib_buffer_length_in_chain (vm, b0) + b0->current_data
- - vnet_buffer (b0)->ethernet.start_of_ethernet_header;
+ - vnet_buffer (b0)->l2_hdr_offset;
len1 = vlib_buffer_length_in_chain (vm, b1) + b1->current_data
- - vnet_buffer (b1)->ethernet.start_of_ethernet_header;
+ - vnet_buffer (b1)->l2_hdr_offset;
stats_n_packets += 2;
stats_n_bytes += len0 + len1;
interface_main.combined_sw_if_counters
+
VNET_INTERFACE_COUNTER_RX,
- cpu_index,
+ thread_index,
new_sw_if_index0, 1,
len0);
if (new_sw_if_index1 != old_sw_if_index1
interface_main.combined_sw_if_counters
+
VNET_INTERFACE_COUNTER_RX,
- cpu_index,
+ thread_index,
new_sw_if_index1, 1,
len1);
vlib_increment_combined_counter
(vnm->interface_main.combined_sw_if_counters
+ VNET_INTERFACE_COUNTER_RX,
- cpu_index,
+ thread_index,
stats_sw_if_index,
stats_n_packets, stats_n_bytes);
stats_n_packets = stats_n_bytes = 0;
cached_is_l2 = is_l20 = subint0->flags & SUBINT_CONFIG_L2;
}
- vnet_buffer (b0)->ethernet.start_of_ethernet_header =
- b0->current_data;
+ vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
if (PREDICT_TRUE (is_l20 != 0))
{
else
{
if (!ethernet_address_cast (e0->dst_address) &&
+ (hi->hw_address != 0) &&
!eth_mac_equal ((u8 *) e0, hi->hw_address))
error0 = ETHERNET_ERROR_L3_MAC_MISMATCH;
determine_next_node (em, variant, 0, type0, b0,
{
len0 = vlib_buffer_length_in_chain (vm, b0) + b0->current_data
- - vnet_buffer (b0)->ethernet.start_of_ethernet_header;
+ - vnet_buffer (b0)->l2_hdr_offset;
stats_n_packets += 1;
stats_n_bytes += len0;
vlib_increment_combined_counter
(vnm->interface_main.combined_sw_if_counters
+ VNET_INTERFACE_COUNTER_RX,
- cpu_index, new_sw_if_index0, 1, len0);
+ thread_index, new_sw_if_index0, 1, len0);
if (stats_n_packets > 0)
{
vlib_increment_combined_counter
(vnm->interface_main.combined_sw_if_counters
+ VNET_INTERFACE_COUNTER_RX,
- cpu_index,
+ thread_index,
stats_sw_if_index, stats_n_packets, stats_n_bytes);
stats_n_packets = stats_n_bytes = 0;
}
vlib_increment_combined_counter
(vnm->interface_main.combined_sw_if_counters
+ VNET_INTERFACE_COUNTER_RX,
- cpu_index, stats_sw_if_index, stats_n_packets, stats_n_bytes);
+ thread_index, stats_sw_if_index, stats_n_packets, stats_n_bytes);
node->runtime_data[0] = stats_sw_if_index;
}
{
l3_next->input_next_ip6 = next_index;
}
- else if (ethertype == ETHERNET_TYPE_MPLS_UNICAST)
+ else if (ethertype == ETHERNET_TYPE_MPLS)
{
l3_next->input_next_mpls = next_index;
}