X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Fethernet%2Finterface.c;h=fd640308c95a162552dcf46265da0a713097d9ce;hb=78ea9c2869967693b77949ec154deef6340d01f5;hp=fe7eb76bf46fe28baee73f1673ec067560528c84;hpb=cb9cadad578297ffd78fa8a33670bdf1ab669e7e;p=vpp.git diff --git a/vnet/vnet/ethernet/interface.c b/vnet/vnet/ethernet/interface.c index fe7eb76bf46..fd640308c95 100644 --- a/vnet/vnet/ethernet/interface.c +++ b/vnet/vnet/ethernet/interface.c @@ -41,6 +41,7 @@ #include #include #include +#include static uword ethernet_set_rewrite (vnet_main_t * vnm, u32 sw_if_index, @@ -89,9 +90,9 @@ static uword ethernet_set_rewrite (vnet_main_t * vnm, } ei = pool_elt_at_index (em->interfaces, hw->hw_instance); - memcpy (h->src_address, ei->address, sizeof (h->src_address)); + clib_memcpy (h->src_address, ei->address, sizeof (h->src_address)); if (dst_address) - memcpy (h->dst_address, dst_address, sizeof (h->dst_address)); + clib_memcpy (h->dst_address, dst_address, sizeof (h->dst_address)); else memset (h->dst_address, ~0, sizeof (h->dst_address)); /* broadcast */ @@ -180,15 +181,15 @@ ethernet_register_interface (vnet_main_t * vnm, ethernet_setup_node (vnm->vlib_main, hi->output_node_index); - hi->min_packet_bytes = ETHERNET_MIN_PACKET_BYTES; - hi->max_packet_bytes = ETHERNET_MAX_PACKET_BYTES; + hi->min_packet_bytes = hi->min_supported_packet_bytes = ETHERNET_MIN_PACKET_BYTES; + hi->max_packet_bytes = hi->max_supported_packet_bytes = ETHERNET_MAX_PACKET_BYTES; hi->per_packet_overhead_bytes = /* preamble */ 8 + /* inter frame gap */ 12; /* Standard default ethernet MTU. */ - hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] = 1500; + hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] = 9000; - memcpy (ei->address, address, sizeof (ei->address)); + clib_memcpy (ei->address, address, sizeof (ei->address)); vec_free (hi->hw_address); vec_add (hi->hw_address, address, sizeof (ei->address)); @@ -255,9 +256,7 @@ ethernet_set_flags (vnet_main_t * vnm, u32 hw_if_index, u32 flags) return (u32)~0; } -#define VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT VNET_INTERFACE_TX_N_NEXT - -/* Echo packets back to ethernet input. */ +/* Echo packets back to ethernet/l2-input. */ static uword simulated_ethernet_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node, @@ -265,9 +264,22 @@ simulated_ethernet_interface_tx (vlib_main_t * vm, { u32 n_left_from, n_left_to_next, n_copy, * from, * to_next; u32 next_index = VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT; - u32 i; + u32 i, next_node_index, bvi_flag, sw_if_index; + u32 n_pkts = 0, n_bytes = 0; + u32 cpu_index = vm->cpu_index; + vnet_main_t * vnm = vnet_get_main(); + vnet_interface_main_t * im = &vnm->interface_main; + vlib_node_main_t * nm = &vm->node_main; + vlib_node_t *loop_node; vlib_buffer_t * b; + // check tx node index, it is ethernet-input on loopback create + // but can be changed to l2-input if loopback is configured as + // BVI of a BD (Bridge Domain). + loop_node = vec_elt (nm->nodes, node->node_index); + next_node_index = loop_node->next_nodes[next_index]; + bvi_flag = (next_node_index == l2input_node.index)? 1 : 0; + n_left_from = frame->n_vectors; from = vlib_frame_args (frame); @@ -277,19 +289,35 @@ simulated_ethernet_interface_tx (vlib_main_t * vm, n_copy = clib_min (n_left_from, n_left_to_next); - memcpy (to_next, from, n_copy * sizeof (from[0])); + clib_memcpy (to_next, from, n_copy * sizeof (from[0])); n_left_to_next -= n_copy; n_left_from -= n_copy; - for (i = 0; i < n_copy; i++) + i = 0; + b = vlib_get_buffer (vm, from[i]); + sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_TX]; + while (1) { - b = vlib_get_buffer (vm, from[i]); - /* Set up RX and TX indices as if received from a real driver */ - vnet_buffer (b)->sw_if_index[VLIB_RX] = - vnet_buffer (b)->sw_if_index[VLIB_TX]; - vnet_buffer (b)->sw_if_index[VLIB_TX] = (u32) ~0; + // Set up RX and TX indices as if received from a real driver + // unless loopback is used as a BVI. For BVI case, leave TX index + // and update l2_len in packet as required for l2 forwarding path + vnet_buffer (b)->sw_if_index[VLIB_RX] = sw_if_index; + if (bvi_flag) vnet_update_l2_len(b); + else vnet_buffer (b)->sw_if_index[VLIB_TX] = (u32) ~0; + + i++; + n_pkts++; + n_bytes += vlib_buffer_length_in_chain (vm, b); + + if (i < n_copy) b = vlib_get_buffer (vm, from[i]); + else break; } vlib_put_next_frame (vm, node, next_index, n_left_to_next); + + /* increment TX interface stat */ + vlib_increment_combined_counter ( + im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, + cpu_index, sw_if_index, n_pkts, n_bytes); } return n_left_from; @@ -301,10 +329,20 @@ static u8 * format_simulated_ethernet_name (u8 * s, va_list * args) return format (s, "loop%d", dev_instance); } +static clib_error_t * +simulated_ethernet_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags) +{ + u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? + VNET_HW_INTERFACE_FLAG_LINK_UP : 0; + vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags); + return 0; +} + VNET_DEVICE_CLASS (ethernet_simulated_device_class) = { .name = "Loopback", .format_device_name = format_simulated_ethernet_name, .tx_function = simulated_ethernet_interface_tx, + .admin_up_down_function = simulated_ethernet_admin_up_down, }; int vnet_create_loopback_interface (u32 * sw_if_indexp, u8 *mac_address) @@ -331,7 +369,7 @@ int vnet_create_loopback_interface (u32 * sw_if_indexp, u8 *mac_address) * address is programmed on the loopback interface. */ if (memcmp (address, mac_address, sizeof (address))) - memcpy (address, mac_address, sizeof (address)); + clib_memcpy (address, mac_address, sizeof (address)); else { address[0] = 0xde; @@ -393,6 +431,7 @@ create_simulated_ethernet_interfaces (vlib_main_t * vm, if (rv) return clib_error_return (0, "vnet_create_loopback_interface failed"); + vlib_cli_output(vm, "%U\n", format_vnet_sw_if_index_name, vnet_get_main(), sw_if_index); return 0; } @@ -402,6 +441,12 @@ VLIB_CLI_COMMAND (create_simulated_ethernet_interface_command, static) = { .function = create_simulated_ethernet_interfaces, }; +VLIB_CLI_COMMAND (create_loopback_interface_command, static) = { + .path = "create loopback interface", + .short_help = "create loopback interface [mac ]", + .function = create_simulated_ethernet_interfaces, +}; + ethernet_interface_t * ethernet_get_interface (ethernet_main_t * em, u32 hw_if_index) { @@ -460,3 +505,9 @@ VLIB_CLI_COMMAND (delete_simulated_ethernet_interface_command, static) = { .short_help = "Delete Loopback ethernet interface intfc ", .function = delete_simulated_ethernet_interfaces, }; + +VLIB_CLI_COMMAND (delete_loopback_interface_command, static) = { + .path = "delete loopback interface", + .short_help = "delete loopback interface intfc ", + .function = delete_simulated_ethernet_interfaces, +};