X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Fethernet%2Fnode.c;h=0261815a1c2c342091c7788b49527b88cc928ac3;hb=e70dcc8676b6b2db74989e43f116bbb200239bf8;hp=eae0a2b4c7be3aec9d164b48c3870a9f8369966c;hpb=81b52c5506ad3ded98dc82fbe4603eec7ad72b8a;p=vpp.git diff --git a/vnet/vnet/ethernet/node.c b/vnet/vnet/ethernet/node.c index eae0a2b4c7b..0261815a1c2 100644 --- a/vnet/vnet/ethernet/node.c +++ b/vnet/vnet/ethernet/node.c @@ -47,24 +47,27 @@ #define foreach_ethernet_input_next \ _ (PUNT, "error-punt") \ _ (DROP, "error-drop") \ - _ (LLC, "llc-input") + _ (LLC, "llc-input") -typedef enum { +typedef enum +{ #define _(s,n) ETHERNET_INPUT_NEXT_##s, foreach_ethernet_input_next #undef _ - ETHERNET_INPUT_N_NEXT, + ETHERNET_INPUT_N_NEXT, } ethernet_input_next_t; -typedef struct { +typedef struct +{ u8 packet_data[32]; } ethernet_input_trace_t; -static u8 * format_ethernet_input_trace (u8 * s, va_list * va) +static u8 * +format_ethernet_input_trace (u8 * s, va_list * va) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *); - ethernet_input_trace_t * t = va_arg (*va, ethernet_input_trace_t *); + ethernet_input_trace_t *t = va_arg (*va, ethernet_input_trace_t *); s = format (s, "%U", format_ethernet_header, t->packet_data); @@ -73,7 +76,8 @@ static u8 * format_ethernet_input_trace (u8 * s, va_list * va) vlib_node_registration_t ethernet_input_node; -typedef enum { +typedef enum +{ ETHERNET_INPUT_VARIANT_ETHERNET, ETHERNET_INPUT_VARIANT_ETHERNET_TYPE, ETHERNET_INPUT_VARIANT_NOT_L2, @@ -83,35 +87,37 @@ typedef enum { // Parse the ethernet header to extract vlan tags and innermost ethertype static_always_inline void parse_header (ethernet_input_variant_t variant, - vlib_buffer_t * b0, - u16 * type, - u16 * orig_type, - u16 * outer_id, - u16 * inner_id, - u32 * match_flags) { + vlib_buffer_t * b0, + u16 * type, + u16 * orig_type, + u16 * outer_id, u16 * inner_id, u32 * match_flags) +{ u8 vlan_count; - if (variant == ETHERNET_INPUT_VARIANT_ETHERNET - || variant == ETHERNET_INPUT_VARIANT_NOT_L2) { - ethernet_header_t * e0; + if (variant == ETHERNET_INPUT_VARIANT_ETHERNET + || variant == ETHERNET_INPUT_VARIANT_NOT_L2) + { + ethernet_header_t *e0; - e0 = (void *) (b0->data + b0->current_data); + e0 = (void *) (b0->data + b0->current_data); - vnet_buffer (b0)->ethernet.start_of_ethernet_header = b0->current_data; + vnet_buffer (b0)->ethernet.start_of_ethernet_header = b0->current_data; - vlib_buffer_advance (b0, sizeof (e0[0])); + vlib_buffer_advance (b0, sizeof (e0[0])); - *type = clib_net_to_host_u16(e0->type); - } else if (variant == ETHERNET_INPUT_VARIANT_ETHERNET_TYPE) { - // here when prior node was LLC/SNAP processing - u16 * e0; + *type = clib_net_to_host_u16 (e0->type); + } + else if (variant == ETHERNET_INPUT_VARIANT_ETHERNET_TYPE) + { + // here when prior node was LLC/SNAP processing + u16 *e0; - e0 = (void *) (b0->data + b0->current_data); + e0 = (void *) (b0->data + b0->current_data); - vlib_buffer_advance (b0, sizeof (e0[0])); + vlib_buffer_advance (b0, sizeof (e0[0])); - *type = clib_net_to_host_u16(e0[0]); - } + *type = clib_net_to_host_u16 (e0[0]); + } // save for distinguishing between dot1q and dot1ad later *orig_type = *type; @@ -128,46 +134,48 @@ parse_header (ethernet_input_variant_t variant, (*type == ETHERNET_TYPE_DOT1AD) || (*type == ETHERNET_TYPE_VLAN_9100) || (*type == ETHERNET_TYPE_VLAN_9200)) - { - ethernet_vlan_header_t * h0; - u16 tag; - - *match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_1_TAG; + { + ethernet_vlan_header_t *h0; + u16 tag; - h0 = (void *) (b0->data + b0->current_data); + *match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_1_TAG; - tag = clib_net_to_host_u16 (h0->priority_cfi_and_id); + h0 = (void *) (b0->data + b0->current_data); - *outer_id = tag & 0xfff; + tag = clib_net_to_host_u16 (h0->priority_cfi_and_id); - *type = clib_net_to_host_u16(h0->type); + *outer_id = tag & 0xfff; - vlib_buffer_advance (b0, sizeof (h0[0])); - vlan_count = 1; + *type = clib_net_to_host_u16 (h0->type); - if (*type == ETHERNET_TYPE_VLAN) { - // Double tagged packet - *match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_2_TAG; + vlib_buffer_advance (b0, sizeof (h0[0])); + vlan_count = 1; - h0 = (void *) (b0->data + b0->current_data); + if (*type == ETHERNET_TYPE_VLAN) + { + // Double tagged packet + *match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_2_TAG; - tag = clib_net_to_host_u16 (h0->priority_cfi_and_id); + h0 = (void *) (b0->data + b0->current_data); - *inner_id = tag & 0xfff; + tag = clib_net_to_host_u16 (h0->priority_cfi_and_id); - *type = clib_net_to_host_u16(h0->type); + *inner_id = tag & 0xfff; - vlib_buffer_advance (b0, sizeof (h0[0])); - vlan_count = 2; + *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; - vlan_count = 3; // "unknown" number, aka, 3-or-more - } + if (*type == ETHERNET_TYPE_VLAN) + { + // More than double tagged packet + *match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_3_TAG; + vlan_count = 3; // "unknown" number, aka, 3-or-more + } + } } - } - ethernet_buffer_set_vlan_count(b0, vlan_count); + ethernet_buffer_set_vlan_count (b0, vlan_count); } // Determine the subinterface for this packet, given the result of the @@ -175,86 +183,103 @@ parse_header (ethernet_input_variant_t variant, // matches first. static_always_inline void identify_subint (vnet_hw_interface_t * hi, - vlib_buffer_t * b0, - u32 match_flags, - main_intf_t * main_intf, - vlan_intf_t * vlan_intf, - qinq_intf_t * qinq_intf, - u32 * new_sw_if_index, - u8 * error0, - u32 * is_l2) + vlib_buffer_t * b0, + u32 match_flags, + main_intf_t * main_intf, + vlan_intf_t * vlan_intf, + qinq_intf_t * qinq_intf, + u32 * new_sw_if_index, u8 * error0, u32 * is_l2) { u32 matched; - matched = eth_identify_subint (hi, b0, match_flags, - main_intf, vlan_intf, qinq_intf, - new_sw_if_index, error0, is_l2); + matched = eth_identify_subint (hi, b0, match_flags, + main_intf, vlan_intf, qinq_intf, + new_sw_if_index, error0, is_l2); - if (matched) { + if (matched) + { - // Perform L3 my-mac filter - // A unicast packet arriving on an L3 interface must have a dmac matching the interface mac. - // This is required for promiscuous mode, else we will forward packets we aren't supposed to. - if (!(*is_l2)) { - ethernet_header_t * e0; - e0 = (void *) (b0->data + vnet_buffer (b0)->ethernet.start_of_ethernet_header); + // Perform L3 my-mac filter + // A unicast packet arriving on an L3 interface must have a dmac matching the interface mac. + // This is required for promiscuous mode, else we will forward packets we aren't supposed to. + if (!(*is_l2)) + { + ethernet_header_t *e0; + e0 = + (void *) (b0->data + + vnet_buffer (b0)->ethernet.start_of_ethernet_header); + + if (!(ethernet_address_cast (e0->dst_address))) + { + if (!eth_mac_equal ((u8 *) e0, hi->hw_address)) + { + *error0 = ETHERNET_ERROR_L3_MAC_MISMATCH; + } + } + } - if (!(ethernet_address_cast(e0->dst_address))) { - if (!eth_mac_equal((u8 *)e0, hi->hw_address)) { - *error0 = ETHERNET_ERROR_L3_MAC_MISMATCH; - } - } + // Check for down subinterface + *error0 = (*new_sw_if_index) != ~0 ? (*error0) : ETHERNET_ERROR_DOWN; } - - // Check for down subinterface - *error0 = (*new_sw_if_index) != ~0 ? (*error0) : ETHERNET_ERROR_DOWN; - } } static_always_inline void determine_next_node (ethernet_main_t * em, - ethernet_input_variant_t variant, - u32 is_l20, - u32 type0, - vlib_buffer_t * b0, - u8 * error0, - u8 * next0) + ethernet_input_variant_t variant, + u32 is_l20, + u32 type0, vlib_buffer_t * b0, u8 * error0, u8 * next0) { - if (PREDICT_FALSE (*error0 != ETHERNET_ERROR_NONE)) { - // some error occurred - *next0 = ETHERNET_INPUT_NEXT_DROP; - } else if (is_l20) { - *next0 = em->l2_next; - // record the L2 len and reset the buffer so the L2 header is preserved - vnet_buffer(b0)->l2.l2_len = b0->current_data; - vlib_buffer_advance(b0, - ethernet_buffer_header_size(b0)); - - // check for common IP/MPLS ethertypes - } else if (type0 == ETHERNET_TYPE_IP4) { - *next0 = em->l3_next.input_next_ip4; - } else if (type0 == ETHERNET_TYPE_IP6) { - *next0 = em->l3_next.input_next_ip6; - } else if (type0 == ETHERNET_TYPE_MPLS_UNICAST) { - *next0 = em->l3_next.input_next_mpls; - - } else if (em->redirect_l3) { - // L3 Redirect is on, the cached common next nodes will be - // pointing to the redirect node, catch the uncommon types here - *next0 = em->redirect_l3_next; - } else { - // uncommon ethertype, check table - u32 i0; - i0 = sparse_vec_index (em->l3_next.input_next_by_type, type0); - *next0 = vec_elt (em->l3_next.input_next_by_type, i0); - *error0 = i0 == SPARSE_VEC_INVALID_INDEX ? ETHERNET_ERROR_UNKNOWN_TYPE : *error0; - - // The table is not populated with LLC values, so check that now. - // If variant is variant_ethernet then we came from LLC processing. Don't - // go back there; drop instead using by keeping the drop/bad table result. - if ((type0 < 0x600) && (variant == ETHERNET_INPUT_VARIANT_ETHERNET)) { - *next0 = ETHERNET_INPUT_NEXT_LLC; + if (PREDICT_FALSE (*error0 != ETHERNET_ERROR_NONE)) + { + // some error occurred + *next0 = ETHERNET_INPUT_NEXT_DROP; + } + else if (is_l20) + { + *next0 = em->l2_next; + // record the L2 len and reset the buffer so the L2 header is preserved + vnet_buffer (b0)->l2.l2_len = b0->current_data; + vlib_buffer_advance (b0, -ethernet_buffer_header_size (b0)); + + // check for common IP/MPLS ethertypes + } + else if (type0 == ETHERNET_TYPE_IP4) + { + *next0 = em->l3_next.input_next_ip4; + } + else if (type0 == ETHERNET_TYPE_IP6) + { + *next0 = em->l3_next.input_next_ip6; + } + else if (type0 == ETHERNET_TYPE_MPLS_UNICAST) + { + *next0 = em->l3_next.input_next_mpls; + + } + else if (em->redirect_l3) + { + // L3 Redirect is on, the cached common next nodes will be + // pointing to the redirect node, catch the uncommon types here + *next0 = em->redirect_l3_next; + } + else + { + // uncommon ethertype, check table + u32 i0; + i0 = sparse_vec_index (em->l3_next.input_next_by_type, type0); + *next0 = vec_elt (em->l3_next.input_next_by_type, i0); + *error0 = + i0 == + SPARSE_VEC_INVALID_INDEX ? ETHERNET_ERROR_UNKNOWN_TYPE : *error0; + + // The table is not populated with LLC values, so check that now. + // If variant is variant_ethernet then we came from LLC processing. Don't + // go back there; drop instead using by keeping the drop/bad table result. + if ((type0 < 0x600) && (variant == ETHERNET_INPUT_VARIANT_ETHERNET)) + { + *next0 = ETHERNET_INPUT_NEXT_LLC; + } } - } } static_always_inline uword @@ -263,12 +288,12 @@ ethernet_input_inline (vlib_main_t * vm, vlib_frame_t * from_frame, ethernet_input_variant_t variant) { - vnet_main_t * vnm = vnet_get_main(); - ethernet_main_t * em = ðernet_main; - vlib_node_runtime_t * error_node; - u32 n_left_from, next_index, * from, * to_next; + vnet_main_t *vnm = vnet_get_main (); + ethernet_main_t *em = ðernet_main; + 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 cpu_index = os_get_cpu_number (); if (variant != ETHERNET_INPUT_VARIANT_ETHERNET) error_node = vlib_node_get_runtime (vm, ethernet_input_node.index); @@ -298,21 +323,22 @@ ethernet_input_inline (vlib_main_t * vm, while (n_left_from >= 4 && n_left_to_next >= 2) { u32 bi0, bi1; - vlib_buffer_t * b0, * b1; + vlib_buffer_t *b0, *b1; u8 next0, next1, error0, error1; - u16 type0, orig_type0, type1, orig_type1; - u16 outer_id0, inner_id0, outer_id1, inner_id1; - u32 match_flags0, match_flags1; - u32 old_sw_if_index0, new_sw_if_index0, len0, old_sw_if_index1, new_sw_if_index1, len1; - vnet_hw_interface_t * hi0, * hi1; - main_intf_t * main_intf0, * main_intf1; - vlan_intf_t * vlan_intf0, * vlan_intf1; - qinq_intf_t * qinq_intf0, * qinq_intf1; - u32 is_l20, is_l21; + u16 type0, orig_type0, type1, orig_type1; + u16 outer_id0, inner_id0, outer_id1, inner_id1; + u32 match_flags0, match_flags1; + u32 old_sw_if_index0, new_sw_if_index0, len0, old_sw_if_index1, + new_sw_if_index1, len1; + vnet_hw_interface_t *hi0, *hi1; + main_intf_t *main_intf0, *main_intf1; + vlan_intf_t *vlan_intf0, *vlan_intf1; + qinq_intf_t *qinq_intf0, *qinq_intf1; + u32 is_l20, is_l21; /* Prefetch next iteration. */ { - vlib_buffer_t * b2, * b3; + vlib_buffer_t *b2, *b3; b2 = vlib_get_buffer (vm, from[2]); b3 = vlib_get_buffer (vm, from[3]); @@ -338,116 +364,110 @@ ethernet_input_inline (vlib_main_t * vm, error0 = error1 = ETHERNET_ERROR_NONE; - parse_header (variant, - b0, - &type0, - &orig_type0, - &outer_id0, - &inner_id0, - &match_flags0); - - parse_header (variant, - b1, - &type1, - &orig_type1, - &outer_id1, - &inner_id1, - &match_flags1); - - old_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - old_sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; - - eth_vlan_table_lookups (em, - vnm, - old_sw_if_index0, - orig_type0, - outer_id0, - inner_id0, - &hi0, - &main_intf0, - &vlan_intf0, - &qinq_intf0); - - eth_vlan_table_lookups (em, - vnm, - old_sw_if_index1, - orig_type1, - outer_id1, - inner_id1, - &hi1, - &main_intf1, - &vlan_intf1, - &qinq_intf1); + parse_header (variant, + b0, + &type0, + &orig_type0, &outer_id0, &inner_id0, &match_flags0); + + parse_header (variant, + b1, + &type1, + &orig_type1, &outer_id1, &inner_id1, &match_flags1); + + old_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; + old_sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; + + eth_vlan_table_lookups (em, + vnm, + old_sw_if_index0, + orig_type0, + outer_id0, + inner_id0, + &hi0, + &main_intf0, &vlan_intf0, &qinq_intf0); + + eth_vlan_table_lookups (em, + vnm, + old_sw_if_index1, + orig_type1, + outer_id1, + inner_id1, + &hi1, + &main_intf1, &vlan_intf1, &qinq_intf1); identify_subint (hi0, - b0, - match_flags0, - main_intf0, - vlan_intf0, - qinq_intf0, - &new_sw_if_index0, - &error0, - &is_l20); + b0, + match_flags0, + main_intf0, + vlan_intf0, + qinq_intf0, &new_sw_if_index0, &error0, &is_l20); identify_subint (hi1, - b1, - match_flags1, - main_intf1, - vlan_intf1, - qinq_intf1, - &new_sw_if_index1, - &error1, - &is_l21); - - // Save RX sw_if_index for later nodes - vnet_buffer (b0)->sw_if_index[VLIB_RX] = error0 != ETHERNET_ERROR_NONE ? old_sw_if_index0 : new_sw_if_index0; - vnet_buffer (b1)->sw_if_index[VLIB_RX] = error1 != ETHERNET_ERROR_NONE ? old_sw_if_index1 : new_sw_if_index1; - - // Check if there is a stat to take (valid and non-main sw_if_index for pkt 0 or pkt 1) - if (((new_sw_if_index0 != ~0) && (new_sw_if_index0 != old_sw_if_index0)) || - ((new_sw_if_index1 != ~0) && (new_sw_if_index1 != old_sw_if_index1))) { - - len0 = vlib_buffer_length_in_chain (vm, b0) + b0->current_data - - vnet_buffer (b0)->ethernet.start_of_ethernet_header; - len1 = vlib_buffer_length_in_chain (vm, b1) + b1->current_data - - vnet_buffer (b1)->ethernet.start_of_ethernet_header; - - stats_n_packets += 2; - stats_n_bytes += len0 + len1; - - if (PREDICT_FALSE (! (new_sw_if_index0 == stats_sw_if_index && new_sw_if_index1 == stats_sw_if_index))) + b1, + match_flags1, + main_intf1, + vlan_intf1, + qinq_intf1, &new_sw_if_index1, &error1, &is_l21); + + // Save RX sw_if_index for later nodes + vnet_buffer (b0)->sw_if_index[VLIB_RX] = + error0 != + ETHERNET_ERROR_NONE ? old_sw_if_index0 : new_sw_if_index0; + vnet_buffer (b1)->sw_if_index[VLIB_RX] = + error1 != + ETHERNET_ERROR_NONE ? old_sw_if_index1 : new_sw_if_index1; + + // Check if there is a stat to take (valid and non-main sw_if_index for pkt 0 or pkt 1) + if (((new_sw_if_index0 != ~0) + && (new_sw_if_index0 != old_sw_if_index0)) + || ((new_sw_if_index1 != ~0) + && (new_sw_if_index1 != old_sw_if_index1))) + { + + len0 = vlib_buffer_length_in_chain (vm, b0) + b0->current_data + - vnet_buffer (b0)->ethernet.start_of_ethernet_header; + len1 = vlib_buffer_length_in_chain (vm, b1) + b1->current_data + - vnet_buffer (b1)->ethernet.start_of_ethernet_header; + + stats_n_packets += 2; + stats_n_bytes += len0 + len1; + + if (PREDICT_FALSE + (!(new_sw_if_index0 == stats_sw_if_index + && new_sw_if_index1 == stats_sw_if_index))) { stats_n_packets -= 2; stats_n_bytes -= len0 + len1; - if (new_sw_if_index0 != old_sw_if_index0 && new_sw_if_index0 != ~0) - vlib_increment_combined_counter - (vnm->interface_main.combined_sw_if_counters - + VNET_INTERFACE_COUNTER_RX, - cpu_index, - new_sw_if_index0, - 1, - len0); - if (new_sw_if_index1 != old_sw_if_index1 && new_sw_if_index1 != ~0) - vlib_increment_combined_counter - (vnm->interface_main.combined_sw_if_counters - + VNET_INTERFACE_COUNTER_RX, - cpu_index, - new_sw_if_index1, - 1, - len1); + if (new_sw_if_index0 != old_sw_if_index0 + && new_sw_if_index0 != ~0) + vlib_increment_combined_counter (vnm-> + interface_main.combined_sw_if_counters + + + VNET_INTERFACE_COUNTER_RX, + cpu_index, + new_sw_if_index0, 1, + len0); + if (new_sw_if_index1 != old_sw_if_index1 + && new_sw_if_index1 != ~0) + vlib_increment_combined_counter (vnm-> + interface_main.combined_sw_if_counters + + + VNET_INTERFACE_COUNTER_RX, + cpu_index, + new_sw_if_index1, 1, + len1); if (new_sw_if_index0 == new_sw_if_index1) { if (stats_n_packets > 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); + 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); stats_n_packets = stats_n_bytes = 0; } stats_sw_if_index = new_sw_if_index0; @@ -455,44 +475,49 @@ ethernet_input_inline (vlib_main_t * vm, } } - if (variant == ETHERNET_INPUT_VARIANT_NOT_L2) - is_l20 = is_l21 = 0; + if (variant == ETHERNET_INPUT_VARIANT_NOT_L2) + is_l20 = is_l21 = 0; + + determine_next_node (em, variant, is_l20, type0, b0, &error0, + &next0); + determine_next_node (em, variant, is_l21, type1, b1, &error1, + &next1); - determine_next_node(em, variant, is_l20, type0, b0, &error0, &next0); - determine_next_node(em, variant, is_l21, type1, b1, &error1, &next1); - b0->error = error_node->errors[error0]; b1->error = error_node->errors[error1]; - // verify speculative enqueue - vlib_validate_buffer_enqueue_x2(vm,node,next_index,to_next,n_left_to_next,bi0,bi1,next0,next1); + // verify speculative enqueue + vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next, + n_left_to_next, bi0, bi1, next0, + next1); } while (n_left_from > 0 && n_left_to_next > 0) { u32 bi0; - vlib_buffer_t * b0; + vlib_buffer_t *b0; u8 error0, next0; - u16 type0, orig_type0; - u16 outer_id0, inner_id0; - u32 match_flags0; - u32 old_sw_if_index0, new_sw_if_index0, len0; - vnet_hw_interface_t * hi0; - main_intf_t * main_intf0; - vlan_intf_t * vlan_intf0; - qinq_intf_t * qinq_intf0; - u32 is_l20; - - // Prefetch next iteration - if (n_left_from > 1) { - vlib_buffer_t * p2; - - p2 = vlib_get_buffer (vm, from[1]); - vlib_prefetch_buffer_header (p2, STORE); - CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, LOAD); - } + u16 type0, orig_type0; + u16 outer_id0, inner_id0; + u32 match_flags0; + u32 old_sw_if_index0, new_sw_if_index0, len0; + vnet_hw_interface_t *hi0; + main_intf_t *main_intf0; + vlan_intf_t *vlan_intf0; + qinq_intf_t *qinq_intf0; + u32 is_l20; + + // Prefetch next iteration + if (n_left_from > 1) + { + vlib_buffer_t *p2; + + p2 = vlib_get_buffer (vm, from[1]); + vlib_prefetch_buffer_header (p2, STORE); + CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, LOAD); + } - bi0 = from[0]; + bi0 = from[0]; to_next[0] = bi0; from += 1; to_next += 1; @@ -503,93 +528,87 @@ ethernet_input_inline (vlib_main_t * vm, error0 = ETHERNET_ERROR_NONE; - parse_header (variant, - b0, - &type0, - &orig_type0, - &outer_id0, - &inner_id0, - &match_flags0); - - old_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - - eth_vlan_table_lookups (em, - vnm, - old_sw_if_index0, - orig_type0, - outer_id0, - inner_id0, - &hi0, - &main_intf0, - &vlan_intf0, - &qinq_intf0); + parse_header (variant, + b0, + &type0, + &orig_type0, &outer_id0, &inner_id0, &match_flags0); + + old_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; + + eth_vlan_table_lookups (em, + vnm, + old_sw_if_index0, + orig_type0, + outer_id0, + inner_id0, + &hi0, + &main_intf0, &vlan_intf0, &qinq_intf0); identify_subint (hi0, - b0, - match_flags0, - main_intf0, - vlan_intf0, - qinq_intf0, - &new_sw_if_index0, - &error0, - &is_l20); - - // Save RX sw_if_index for later nodes - vnet_buffer (b0)->sw_if_index[VLIB_RX] = error0 != ETHERNET_ERROR_NONE ? old_sw_if_index0 : new_sw_if_index0; - - // Increment subinterface stats - // Note that interface-level counters have already been incremented - // prior to calling this function. Thus only subinterface counters - // are incremented here. - // - // Interface level counters include packets received on the main - // interface and all subinterfaces. Subinterface level counters - // include only those packets received on that subinterface + b0, + match_flags0, + main_intf0, + vlan_intf0, + qinq_intf0, &new_sw_if_index0, &error0, &is_l20); + + // Save RX sw_if_index for later nodes + vnet_buffer (b0)->sw_if_index[VLIB_RX] = + error0 != + ETHERNET_ERROR_NONE ? old_sw_if_index0 : new_sw_if_index0; + + // Increment subinterface stats + // Note that interface-level counters have already been incremented + // prior to calling this function. Thus only subinterface counters + // are incremented here. + // + // Interface level counters include packets received on the main + // interface and all subinterfaces. Subinterface level counters + // include only those packets received on that subinterface // Increment stats if the subint is valid and it is not the main intf - if ((new_sw_if_index0 != ~0) && (new_sw_if_index0 != old_sw_if_index0)) { - - len0 = vlib_buffer_length_in_chain (vm, b0) + b0->current_data - - vnet_buffer (b0)->ethernet.start_of_ethernet_header; - - stats_n_packets += 1; - stats_n_bytes += len0; - - // Batch stat increments from the same subinterface so counters - // don't need to be incremented for every packet. - if (PREDICT_FALSE (new_sw_if_index0 != stats_sw_if_index)) { - stats_n_packets -= 1; - stats_n_bytes -= len0; - - if (new_sw_if_index0 != ~0) - vlib_increment_combined_counter - (vnm->interface_main.combined_sw_if_counters - + VNET_INTERFACE_COUNTER_RX, - cpu_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, - stats_sw_if_index, - stats_n_packets, - stats_n_bytes); - stats_n_packets = stats_n_bytes = 0; - } - stats_sw_if_index = new_sw_if_index0; + if ((new_sw_if_index0 != ~0) + && (new_sw_if_index0 != old_sw_if_index0)) + { + + len0 = vlib_buffer_length_in_chain (vm, b0) + b0->current_data + - vnet_buffer (b0)->ethernet.start_of_ethernet_header; + + stats_n_packets += 1; + stats_n_bytes += len0; + + // Batch stat increments from the same subinterface so counters + // don't need to be incremented for every packet. + if (PREDICT_FALSE (new_sw_if_index0 != stats_sw_if_index)) + { + stats_n_packets -= 1; + stats_n_bytes -= len0; + + if (new_sw_if_index0 != ~0) + vlib_increment_combined_counter + (vnm->interface_main.combined_sw_if_counters + + VNET_INTERFACE_COUNTER_RX, + cpu_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, + stats_sw_if_index, stats_n_packets, stats_n_bytes); + stats_n_packets = stats_n_bytes = 0; + } + stats_sw_if_index = new_sw_if_index0; + } } - } - if (variant == ETHERNET_INPUT_VARIANT_NOT_L2) - is_l20 = 0; + if (variant == ETHERNET_INPUT_VARIANT_NOT_L2) + is_l20 = 0; + + determine_next_node (em, variant, is_l20, type0, b0, &error0, + &next0); - determine_next_node(em, variant, is_l20, type0, b0, &error0, &next0); + b0->error = error_node->errors[error0]; - b0->error = error_node->errors[error0]; - - // verify speculative enqueue + // verify speculative enqueue vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, bi0, next0); @@ -598,16 +617,13 @@ ethernet_input_inline (vlib_main_t * vm, vlib_put_next_frame (vm, node, next_index, n_left_to_next); } - // Increment any remaining batched stats - if (stats_n_packets > 0) + // Increment any remaining batched stats + if (stats_n_packets > 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); + 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); node->runtime_data[0] = stats_sw_if_index; } @@ -616,21 +632,27 @@ ethernet_input_inline (vlib_main_t * vm, static uword ethernet_input (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) -{ return ethernet_input_inline (vm, node, from_frame, ETHERNET_INPUT_VARIANT_ETHERNET); } + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return ethernet_input_inline (vm, node, from_frame, + ETHERNET_INPUT_VARIANT_ETHERNET); +} static uword ethernet_input_type (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) -{ return ethernet_input_inline (vm, node, from_frame, ETHERNET_INPUT_VARIANT_ETHERNET_TYPE); } + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return ethernet_input_inline (vm, node, from_frame, + ETHERNET_INPUT_VARIANT_ETHERNET_TYPE); +} static uword ethernet_input_not_l2 (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) -{ return ethernet_input_inline (vm, node, from_frame, ETHERNET_INPUT_VARIANT_NOT_L2); } + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return ethernet_input_inline (vm, node, from_frame, + ETHERNET_INPUT_VARIANT_NOT_L2); +} // Return the subinterface config struct for the given sw_if_index @@ -639,23 +661,24 @@ ethernet_input_not_l2 (vlib_main_t * vm, // On error (unsupported or not ethernet) return 0. static subint_config_t * ethernet_sw_interface_get_config (vnet_main_t * vnm, - u32 sw_if_index, - u32 * flags, - u32 * unsupported) { - ethernet_main_t * em = ðernet_main; - vnet_hw_interface_t * hi; - vnet_sw_interface_t * si; - main_intf_t * main_intf; - vlan_table_t * vlan_table; - qinq_table_t * qinq_table; - subint_config_t * subint = 0; - + u32 sw_if_index, + u32 * flags, u32 * unsupported) +{ + ethernet_main_t *em = ðernet_main; + vnet_hw_interface_t *hi; + vnet_sw_interface_t *si; + main_intf_t *main_intf; + vlan_table_t *vlan_table; + qinq_table_t *qinq_table; + subint_config_t *subint = 0; + hi = vnet_get_sup_hw_interface (vnm, sw_if_index); - if (!hi || (hi->hw_class_index != ethernet_hw_interface_class.index)) { - *unsupported = 0; - goto done; // non-ethernet interface - } + if (!hi || (hi->hw_class_index != ethernet_hw_interface_class.index)) + { + *unsupported = 0; + goto done; // non-ethernet interface + } // ensure there's an entry for the main intf (shouldn't really be necessary) vec_validate (em->main_intfs, hi->hw_if_index); @@ -664,123 +687,162 @@ ethernet_sw_interface_get_config (vnet_main_t * vnm, // Locate the subint for the given ethernet config si = vnet_get_sw_interface (vnm, sw_if_index); - if (si->sub.eth.flags.default_sub) { - subint = &main_intf->default_subint; - *flags = SUBINT_CONFIG_MATCH_0_TAG | - SUBINT_CONFIG_MATCH_1_TAG | - SUBINT_CONFIG_MATCH_2_TAG | - SUBINT_CONFIG_MATCH_3_TAG; - } else if ((si->sub.eth.flags.no_tags) || - (si->sub.eth.raw_flags == 0)) { - // if no flags are set then this is a main interface - // so treat as untagged - subint = &main_intf->untagged_subint; - *flags = SUBINT_CONFIG_MATCH_0_TAG; - } else { - // one or two tags - // first get the vlan table - if (si->sub.eth.flags.dot1ad) { - if (main_intf->dot1ad_vlans == 0) { - // Allocate a vlan table from the pool - pool_get(em->vlan_pool, vlan_table); - main_intf->dot1ad_vlans = vlan_table - em->vlan_pool; - } else { - // Get ptr to existing vlan table - vlan_table = vec_elt_at_index (em->vlan_pool, main_intf->dot1ad_vlans); - } - } else { // dot1q - if (main_intf->dot1q_vlans == 0) { - // Allocate a vlan table from the pool - pool_get(em->vlan_pool, vlan_table); - main_intf->dot1q_vlans = vlan_table - em->vlan_pool; - } else { - // Get ptr to existing vlan table - vlan_table = vec_elt_at_index (em->vlan_pool, main_intf->dot1q_vlans); - } + if (si->sub.eth.flags.default_sub) + { + subint = &main_intf->default_subint; + *flags = SUBINT_CONFIG_MATCH_0_TAG | + SUBINT_CONFIG_MATCH_1_TAG | + SUBINT_CONFIG_MATCH_2_TAG | SUBINT_CONFIG_MATCH_3_TAG; } + else if ((si->sub.eth.flags.no_tags) || (si->sub.eth.raw_flags == 0)) + { + // if no flags are set then this is a main interface + // so treat as untagged + subint = &main_intf->untagged_subint; + *flags = SUBINT_CONFIG_MATCH_0_TAG; + } + else + { + // one or two tags + // first get the vlan table + if (si->sub.eth.flags.dot1ad) + { + if (main_intf->dot1ad_vlans == 0) + { + // Allocate a vlan table from the pool + pool_get (em->vlan_pool, vlan_table); + main_intf->dot1ad_vlans = vlan_table - em->vlan_pool; + } + else + { + // Get ptr to existing vlan table + vlan_table = + vec_elt_at_index (em->vlan_pool, main_intf->dot1ad_vlans); + } + } + else + { // dot1q + if (main_intf->dot1q_vlans == 0) + { + // Allocate a vlan table from the pool + pool_get (em->vlan_pool, vlan_table); + main_intf->dot1q_vlans = vlan_table - em->vlan_pool; + } + else + { + // Get ptr to existing vlan table + vlan_table = + vec_elt_at_index (em->vlan_pool, main_intf->dot1q_vlans); + } + } + + if (si->sub.eth.flags.one_tag) + { + *flags = si->sub.eth.flags.exact_match ? + SUBINT_CONFIG_MATCH_1_TAG : + (SUBINT_CONFIG_MATCH_1_TAG | + SUBINT_CONFIG_MATCH_2_TAG | SUBINT_CONFIG_MATCH_3_TAG); + + if (si->sub.eth.flags.outer_vlan_id_any) + { + // not implemented yet + *unsupported = 1; + goto done; + } + else + { + // a single vlan, a common case + subint = + &vlan_table->vlans[si->sub.eth. + outer_vlan_id].single_tag_subint; + } + + } + else + { + // Two tags + *flags = si->sub.eth.flags.exact_match ? + SUBINT_CONFIG_MATCH_2_TAG : + (SUBINT_CONFIG_MATCH_2_TAG | SUBINT_CONFIG_MATCH_3_TAG); + + if (si->sub.eth.flags.outer_vlan_id_any + && si->sub.eth.flags.inner_vlan_id_any) + { + // not implemented yet + *unsupported = 1; + goto done; + } - if (si->sub.eth.flags.one_tag) { - *flags = si->sub.eth.flags.exact_match ? - SUBINT_CONFIG_MATCH_1_TAG : - (SUBINT_CONFIG_MATCH_1_TAG | - SUBINT_CONFIG_MATCH_2_TAG | - SUBINT_CONFIG_MATCH_3_TAG); - - if (si->sub.eth.flags.outer_vlan_id_any) { - // not implemented yet - *unsupported =1; - goto done; - } else { - // a single vlan, a common case - subint = &vlan_table->vlans[si->sub.eth.outer_vlan_id].single_tag_subint; - } - - } else { - // Two tags - *flags = si->sub.eth.flags.exact_match ? - SUBINT_CONFIG_MATCH_2_TAG : - (SUBINT_CONFIG_MATCH_2_TAG | - SUBINT_CONFIG_MATCH_3_TAG); - - if (si->sub.eth.flags.outer_vlan_id_any && si->sub.eth.flags.inner_vlan_id_any) { - // not implemented yet - *unsupported = 1; - goto done; - } - - if (si->sub.eth.flags.inner_vlan_id_any) { - // a specific outer and "any" inner - // don't need a qinq table for this - subint = &vlan_table->vlans[si->sub.eth.outer_vlan_id].inner_any_subint; - if (si->sub.eth.flags.exact_match) { - *flags = SUBINT_CONFIG_MATCH_2_TAG; - } else { - *flags = SUBINT_CONFIG_MATCH_2_TAG | - SUBINT_CONFIG_MATCH_3_TAG; - } - } else { - // a specific outer + specifc innner vlan id, a common case - - // get the qinq table - if (vlan_table->vlans[si->sub.eth.outer_vlan_id].qinqs == 0) { - // Allocate a qinq table from the pool - pool_get(em->qinq_pool, qinq_table); - vlan_table->vlans[si->sub.eth.outer_vlan_id].qinqs = qinq_table - em->qinq_pool; - } else { - // Get ptr to existing qinq table - qinq_table = vec_elt_at_index (em->qinq_pool, vlan_table->vlans[si->sub.eth.outer_vlan_id].qinqs); - } - subint = &qinq_table->vlans[si->sub.eth.inner_vlan_id].subint; - } + if (si->sub.eth.flags.inner_vlan_id_any) + { + // a specific outer and "any" inner + // don't need a qinq table for this + subint = + &vlan_table->vlans[si->sub.eth. + outer_vlan_id].inner_any_subint; + if (si->sub.eth.flags.exact_match) + { + *flags = SUBINT_CONFIG_MATCH_2_TAG; + } + else + { + *flags = SUBINT_CONFIG_MATCH_2_TAG | + SUBINT_CONFIG_MATCH_3_TAG; + } + } + else + { + // a specific outer + specifc innner vlan id, a common case + + // get the qinq table + if (vlan_table->vlans[si->sub.eth.outer_vlan_id].qinqs == 0) + { + // Allocate a qinq table from the pool + pool_get (em->qinq_pool, qinq_table); + vlan_table->vlans[si->sub.eth.outer_vlan_id].qinqs = + qinq_table - em->qinq_pool; + } + else + { + // Get ptr to existing qinq table + qinq_table = + vec_elt_at_index (em->qinq_pool, + vlan_table->vlans[si->sub. + eth.outer_vlan_id]. + qinqs); + } + subint = &qinq_table->vlans[si->sub.eth.inner_vlan_id].subint; + } + } } - } - done: +done: return subint; } clib_error_t * -ethernet_sw_interface_up_down (vnet_main_t * vnm, - u32 sw_if_index, - u32 flags) +ethernet_sw_interface_up_down (vnet_main_t * vnm, u32 sw_if_index, u32 flags) { - subint_config_t * subint; + subint_config_t *subint; u32 dummy_flags; u32 dummy_unsup; - clib_error_t * error = 0; + clib_error_t *error = 0; // Find the config for this subinterface - subint = ethernet_sw_interface_get_config (vnm, sw_if_index, &dummy_flags, &dummy_unsup); + subint = + ethernet_sw_interface_get_config (vnm, sw_if_index, &dummy_flags, + &dummy_unsup); - if (subint == 0) { - // not implemented yet or not ethernet - goto done; - } + if (subint == 0) + { + // not implemented yet or not ethernet + goto done; + } subint->sw_if_index = ((flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? sw_if_index : ~0); - done: +done: return error; } @@ -789,44 +851,48 @@ VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (ethernet_sw_interface_up_down); // Set the L2/L3 mode for the subinterface void -ethernet_sw_interface_set_l2_mode (vnet_main_t * vnm, - u32 sw_if_index, - u32 l2) +ethernet_sw_interface_set_l2_mode (vnet_main_t * vnm, u32 sw_if_index, u32 l2) { subint_config_t *subint; u32 dummy_flags; u32 dummy_unsup; int is_port; - vnet_sw_interface_t * sw = vnet_get_sw_interface (vnm, sw_if_index); + vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index); is_port = !(sw->type == VNET_SW_INTERFACE_TYPE_SUB); // Find the config for this subinterface - subint = ethernet_sw_interface_get_config (vnm, sw_if_index, &dummy_flags, &dummy_unsup); + subint = + ethernet_sw_interface_get_config (vnm, sw_if_index, &dummy_flags, + &dummy_unsup); - if (subint == 0) { - // unimplemented or not ethernet - goto done; - } + if (subint == 0) + { + // unimplemented or not ethernet + goto done; + } // Double check that the config we found is for our interface (or the interface is down) ASSERT ((subint->sw_if_index == sw_if_index) | (subint->sw_if_index == ~0)); - if (l2) { - subint->flags |= SUBINT_CONFIG_L2; - if (is_port) - subint->flags |= - SUBINT_CONFIG_MATCH_0_TAG | SUBINT_CONFIG_MATCH_1_TAG - | SUBINT_CONFIG_MATCH_2_TAG | SUBINT_CONFIG_MATCH_3_TAG; - } else { - subint->flags &= ~SUBINT_CONFIG_L2; - if (is_port) - subint->flags &= - ~(SUBINT_CONFIG_MATCH_1_TAG | SUBINT_CONFIG_MATCH_2_TAG - | SUBINT_CONFIG_MATCH_3_TAG); - } + if (l2) + { + subint->flags |= SUBINT_CONFIG_L2; + if (is_port) + subint->flags |= + SUBINT_CONFIG_MATCH_0_TAG | SUBINT_CONFIG_MATCH_1_TAG + | SUBINT_CONFIG_MATCH_2_TAG | SUBINT_CONFIG_MATCH_3_TAG; + } + else + { + subint->flags &= ~SUBINT_CONFIG_L2; + if (is_port) + subint->flags &= + ~(SUBINT_CONFIG_MATCH_1_TAG | SUBINT_CONFIG_MATCH_2_TAG + | SUBINT_CONFIG_MATCH_3_TAG); + } - done: +done: return; } @@ -835,20 +901,22 @@ ethernet_sw_interface_set_l2_mode (vnet_main_t * vnm, */ void ethernet_sw_interface_set_l2_mode_noport (vnet_main_t * vnm, - u32 sw_if_index, - u32 l2) + u32 sw_if_index, u32 l2) { subint_config_t *subint; u32 dummy_flags; u32 dummy_unsup; /* Find the config for this subinterface */ - subint = ethernet_sw_interface_get_config (vnm, sw_if_index, &dummy_flags, &dummy_unsup); + subint = + ethernet_sw_interface_get_config (vnm, sw_if_index, &dummy_flags, + &dummy_unsup); - if (subint == 0) { - /* unimplemented or not ethernet */ - goto done; - } + if (subint == 0) + { + /* unimplemented or not ethernet */ + goto done; + } /* * Double check that the config we found is for our interface (or the @@ -856,94 +924,105 @@ ethernet_sw_interface_set_l2_mode_noport (vnet_main_t * vnm, */ ASSERT ((subint->sw_if_index == sw_if_index) | (subint->sw_if_index == ~0)); - if (l2) { - subint->flags |= SUBINT_CONFIG_L2; - } else { - subint->flags &= ~SUBINT_CONFIG_L2; - } + if (l2) + { + subint->flags |= SUBINT_CONFIG_L2; + } + else + { + subint->flags &= ~SUBINT_CONFIG_L2; + } - done: +done: return; } static clib_error_t * ethernet_sw_interface_add_del (vnet_main_t * vnm, - u32 sw_if_index, - u32 is_create) + u32 sw_if_index, u32 is_create) { - clib_error_t * error = 0; + clib_error_t *error = 0; subint_config_t *subint; u32 match_flags; - u32 unsupported=0; + u32 unsupported = 0; // Find the config for this subinterface - subint = ethernet_sw_interface_get_config (vnm, sw_if_index, &match_flags, &unsupported); + subint = + ethernet_sw_interface_get_config (vnm, sw_if_index, &match_flags, + &unsupported); - if (subint == 0) { - // not implemented yet or not ethernet - if (unsupported) { - // this is the NYI case - error = clib_error_return (0, "not implemented yet"); + if (subint == 0) + { + // not implemented yet or not ethernet + if (unsupported) + { + // this is the NYI case + error = clib_error_return (0, "not implemented yet"); + } + goto done; } - goto done; - } - if (!is_create) { - subint->flags = 0; - return error; - } + if (!is_create) + { + subint->flags = 0; + return error; + } // Initialize the subint - if (subint->flags & SUBINT_CONFIG_VALID) { - // Error vlan already in use - error = clib_error_return (0, "vlan is already in use"); - } else { - // Note that config is L3 by defaulty - subint->flags = SUBINT_CONFIG_VALID | match_flags; - subint->sw_if_index = ~0; // because interfaces are initially down - } + if (subint->flags & SUBINT_CONFIG_VALID) + { + // Error vlan already in use + error = clib_error_return (0, "vlan is already in use"); + } + else + { + // Note that config is L3 by defaulty + subint->flags = SUBINT_CONFIG_VALID | match_flags; + subint->sw_if_index = ~0; // because interfaces are initially down + } - done: +done: return error; } VNET_SW_INTERFACE_ADD_DEL_FUNCTION (ethernet_sw_interface_add_del); -static char * ethernet_error_strings[] = { +static char *ethernet_error_strings[] = { #define ethernet_error(n,c,s) s, #include "error.def" #undef ethernet_error }; +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ethernet_input_node) = { .function = ethernet_input, .name = "ethernet-input", /* Takes a vector of packets. */ .vector_size = sizeof (u32), - .n_errors = ETHERNET_N_ERROR, .error_strings = ethernet_error_strings, - .n_next_nodes = ETHERNET_INPUT_N_NEXT, .next_nodes = { #define _(s,n) [ETHERNET_INPUT_NEXT_##s] = n, foreach_ethernet_input_next #undef _ }, - .format_buffer = format_ethernet_header_with_length, .format_trace = format_ethernet_input_trace, .unformat_buffer = unformat_ethernet_header, }; +/* *INDENT-ON* */ +/* *INDENT-OFF* */ VLIB_NODE_FUNCTION_MULTIARCH (ethernet_input_node, ethernet_input) +/* *INDENT-ON* */ -VLIB_REGISTER_NODE (ethernet_input_type_node,static) = { +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (ethernet_input_type_node, static) = { .function = ethernet_input_type, .name = "ethernet-input-type", /* Takes a vector of packets. */ .vector_size = sizeof (u32), - .n_next_nodes = ETHERNET_INPUT_N_NEXT, .next_nodes = { #define _(s,n) [ETHERNET_INPUT_NEXT_##s] = n, @@ -951,15 +1030,18 @@ VLIB_REGISTER_NODE (ethernet_input_type_node,static) = { #undef _ }, }; +/* *INDENT-ON* */ +/* *INDENT-OFF* */ VLIB_NODE_FUNCTION_MULTIARCH (ethernet_input_type_node, ethernet_input_type) +/* *INDENT-ON* */ -VLIB_REGISTER_NODE (ethernet_input_not_l2_node,static) = { +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (ethernet_input_not_l2_node, static) = { .function = ethernet_input_not_l2, .name = "ethernet-input-not-l2", /* Takes a vector of packets. */ .vector_size = sizeof (u32), - .n_next_nodes = ETHERNET_INPUT_N_NEXT, .next_nodes = { #define _(s,n) [ETHERNET_INPUT_NEXT_##s] = n, @@ -967,17 +1049,23 @@ VLIB_REGISTER_NODE (ethernet_input_not_l2_node,static) = { #undef _ }, }; +/* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (ethernet_input_not_l2_node, ethernet_input_not_l2) -void ethernet_set_rx_redirect (vnet_main_t * vnm, - vnet_hw_interface_t * hi, - u32 enable) +/* *INDENT-OFF* */ +VLIB_NODE_FUNCTION_MULTIARCH (ethernet_input_not_l2_node, + ethernet_input_not_l2) +/* *INDENT-ON* */ + + +void +ethernet_set_rx_redirect (vnet_main_t * vnm, + vnet_hw_interface_t * hi, u32 enable) { // Insure all packets go to ethernet-input (i.e. untagged ipv4 packets // don't go directly to ip4-input) - vnet_hw_interface_rx_redirect_to_node - (vnm, hi->hw_if_index, enable ? ethernet_input_node.index : ~0); + vnet_hw_interface_rx_redirect_to_node + (vnm, hi->hw_if_index, enable ? ethernet_input_node.index : ~0); } @@ -985,44 +1073,47 @@ void ethernet_set_rx_redirect (vnet_main_t * vnm, * Initialization and registration for the next_by_ethernet structure */ -clib_error_t * next_by_ethertype_init (next_by_ethertype_t * l3_next) +clib_error_t * +next_by_ethertype_init (next_by_ethertype_t * l3_next) { l3_next->input_next_by_type = sparse_vec_new - (/* elt bytes */ sizeof (l3_next->input_next_by_type[0]), + ( /* elt bytes */ sizeof (l3_next->input_next_by_type[0]), /* bits in index */ BITS (((ethernet_header_t *) 0)->type)); - vec_validate (l3_next->sparse_index_by_input_next_index, ETHERNET_INPUT_NEXT_DROP); - vec_validate (l3_next->sparse_index_by_input_next_index, ETHERNET_INPUT_NEXT_PUNT); - l3_next->sparse_index_by_input_next_index[ETHERNET_INPUT_NEXT_DROP] - = SPARSE_VEC_INVALID_INDEX; - l3_next->sparse_index_by_input_next_index[ETHERNET_INPUT_NEXT_PUNT] - = SPARSE_VEC_INVALID_INDEX; - + vec_validate (l3_next->sparse_index_by_input_next_index, + ETHERNET_INPUT_NEXT_DROP); + vec_validate (l3_next->sparse_index_by_input_next_index, + ETHERNET_INPUT_NEXT_PUNT); + l3_next->sparse_index_by_input_next_index[ETHERNET_INPUT_NEXT_DROP] = + SPARSE_VEC_INVALID_INDEX; + l3_next->sparse_index_by_input_next_index[ETHERNET_INPUT_NEXT_PUNT] = + SPARSE_VEC_INVALID_INDEX; + /* * Make sure we don't wipe out an ethernet registration by mistake * Can happen if init function ordering constraints are missing. */ if (CLIB_DEBUG > 0) { - ethernet_main_t * em = ðernet_main; - ASSERT(em->next_by_ethertype_register_called == 0); + ethernet_main_t *em = ðernet_main; + ASSERT (em->next_by_ethertype_register_called == 0); } return 0; } // Add an ethertype -> next index mapping to the structure -clib_error_t * next_by_ethertype_register (next_by_ethertype_t * l3_next, - u32 ethertype, - u32 next_index) +clib_error_t * +next_by_ethertype_register (next_by_ethertype_t * l3_next, + u32 ethertype, u32 next_index) { u32 i; - u16 * n; - ethernet_main_t * em = ðernet_main; + u16 *n; + ethernet_main_t *em = ðernet_main; if (CLIB_DEBUG > 0) { - ethernet_main_t * em = ðernet_main; + ethernet_main_t *em = ðernet_main; em->next_by_ethertype_register_called = 1; } @@ -1034,45 +1125,53 @@ clib_error_t * next_by_ethertype_register (next_by_ethertype_t * l3_next, is updated. */ vec_validate (l3_next->sparse_index_by_input_next_index, next_index); for (i = 1; i < vec_len (l3_next->input_next_by_type); i++) - l3_next->sparse_index_by_input_next_index[l3_next->input_next_by_type[i]] = i; + l3_next-> + sparse_index_by_input_next_index[l3_next->input_next_by_type[i]] = i; // do not allow the cached next index's to be updated if L3 // redirect is enabled, as it will have overwritten them - if (!em->redirect_l3) { - // Cache common ethertypes directly - if (ethertype == ETHERNET_TYPE_IP4) { - l3_next->input_next_ip4 = next_index; - } else if (ethertype == ETHERNET_TYPE_IP6) { - l3_next->input_next_ip6 = next_index; - } else if (ethertype == ETHERNET_TYPE_MPLS_UNICAST) { - l3_next->input_next_mpls = next_index; + if (!em->redirect_l3) + { + // Cache common ethertypes directly + if (ethertype == ETHERNET_TYPE_IP4) + { + l3_next->input_next_ip4 = next_index; + } + else if (ethertype == ETHERNET_TYPE_IP6) + { + l3_next->input_next_ip6 = next_index; + } + else if (ethertype == ETHERNET_TYPE_MPLS_UNICAST) + { + l3_next->input_next_mpls = next_index; + } } - } return 0; } -static clib_error_t * ethernet_input_init (vlib_main_t * vm) +static clib_error_t * +ethernet_input_init (vlib_main_t * vm) { - ethernet_main_t * em = ðernet_main; - __attribute__((unused)) vlan_table_t * invalid_vlan_table; - __attribute__((unused)) qinq_table_t * invalid_qinq_table; + ethernet_main_t *em = ðernet_main; + __attribute__ ((unused)) vlan_table_t *invalid_vlan_table; + __attribute__ ((unused)) qinq_table_t *invalid_qinq_table; ethernet_setup_node (vm, ethernet_input_node.index); ethernet_setup_node (vm, ethernet_input_type_node.index); ethernet_setup_node (vm, ethernet_input_not_l2_node.index); next_by_ethertype_init (&em->l3_next); - + // Initialize pools and vector for vlan parsing - vec_validate (em->main_intfs, 10); // 10 main interfaces - pool_alloc(em->vlan_pool, 10); - pool_alloc(em->qinq_pool, 1); + vec_validate (em->main_intfs, 10); // 10 main interfaces + pool_alloc (em->vlan_pool, 10); + pool_alloc (em->qinq_pool, 1); // The first vlan pool will always be reserved for an invalid table - pool_get(em->vlan_pool, invalid_vlan_table); // first id = 0 + pool_get (em->vlan_pool, invalid_vlan_table); // first id = 0 // The first qinq pool will always be reserved for an invalid table - pool_get(em->qinq_pool, invalid_qinq_table); // first id = 0 + pool_get (em->qinq_pool, invalid_qinq_table); // first id = 0 return 0; } @@ -1081,32 +1180,26 @@ VLIB_INIT_FUNCTION (ethernet_input_init); void ethernet_register_input_type (vlib_main_t * vm, - ethernet_type_t type, - u32 node_index) + ethernet_type_t type, u32 node_index) { - ethernet_main_t * em = ðernet_main; - ethernet_type_info_t * ti; + ethernet_main_t *em = ðernet_main; + ethernet_type_info_t *ti; u32 i; { - clib_error_t * error = vlib_call_init_function (vm, ethernet_init); + clib_error_t *error = vlib_call_init_function (vm, ethernet_init); if (error) clib_error_report (error); } ti = ethernet_get_type_info (em, type); ti->node_index = node_index; - ti->next_index = vlib_node_add_next (vm, - ethernet_input_node.index, - node_index); - i = vlib_node_add_next (vm, - ethernet_input_type_node.index, - node_index); + ti->next_index = vlib_node_add_next (vm, + ethernet_input_node.index, node_index); + i = vlib_node_add_next (vm, ethernet_input_type_node.index, node_index); ASSERT (i == ti->next_index); - i = vlib_node_add_next (vm, - ethernet_input_not_l2_node.index, - node_index); + i = vlib_node_add_next (vm, ethernet_input_not_l2_node.index, node_index); ASSERT (i == ti->next_index); // Add the L3 node for this ethertype to the next nodes structure @@ -1117,13 +1210,13 @@ ethernet_register_input_type (vlib_main_t * vm, } void -ethernet_register_l2_input (vlib_main_t * vm, - u32 node_index) +ethernet_register_l2_input (vlib_main_t * vm, u32 node_index) { - ethernet_main_t * em = ðernet_main; + ethernet_main_t *em = ðernet_main; u32 i; - em->l2_next = vlib_node_add_next (vm, ethernet_input_node.index, node_index); + em->l2_next = + vlib_node_add_next (vm, ethernet_input_node.index, node_index); /* * Even if we never use these arcs, we have to align the next indices... @@ -1132,24 +1225,21 @@ ethernet_register_l2_input (vlib_main_t * vm, ASSERT (i == em->l2_next); - i = vlib_node_add_next (vm, - ethernet_input_not_l2_node.index, - node_index); + i = vlib_node_add_next (vm, ethernet_input_not_l2_node.index, node_index); ASSERT (i == em->l2_next); } // Register a next node for L3 redirect, and enable L3 redirect void -ethernet_register_l3_redirect (vlib_main_t * vm, - u32 node_index) +ethernet_register_l3_redirect (vlib_main_t * vm, u32 node_index) { - ethernet_main_t * em = ðernet_main; + ethernet_main_t *em = ðernet_main; u32 i; em->redirect_l3 = 1; - em->redirect_l3_next = vlib_node_add_next(vm, - ethernet_input_node.index, - node_index); + em->redirect_l3_next = vlib_node_add_next (vm, + ethernet_input_node.index, + node_index); /* * Change the cached next nodes to the redirect node */ @@ -1164,3 +1254,11 @@ ethernet_register_l3_redirect (vlib_main_t * vm, ASSERT (i == em->redirect_l3_next); } + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */