X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Finterface.c;h=cd734cedd5c6a5dc44a4a58efe19a7d40ccc5c50;hb=600d7a85fbdd9f3c7c6977faa07fee7e2e13ce21;hp=82dc29b3744fb12e77a089b933dc38e5d8f7d840;hpb=b2c31b685fd2cf28436ca32bc93e23eb24c74878;p=vpp.git diff --git a/src/vnet/interface.c b/src/vnet/interface.c index 82dc29b3744..cd734cedd5c 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -42,6 +42,7 @@ #include #include #include +#include /* *INDENT-OFF* */ VLIB_REGISTER_LOG_CLASS (if_default_log, static) = { @@ -51,6 +52,7 @@ VLIB_REGISTER_LOG_CLASS (if_default_log, static) = { #define log_debug(fmt,...) vlib_log_debug(if_default_log.class, fmt, __VA_ARGS__) #define log_err(fmt,...) vlib_log_err(if_default_log.class, fmt, __VA_ARGS__) + typedef enum vnet_interface_helper_flags_t_ { VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE = (1 << 0), @@ -493,6 +495,7 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, hi->flags & ~VNET_HW_INTERFACE_FLAG_LINK_UP, helper_flags); + vnet_hw_if_update_runtime_data (vnm, si->hw_if_index); } } @@ -551,6 +554,21 @@ vnet_sw_interface_admin_down (vnet_main_t * vnm, u32 sw_if_index) } } +static void +vnet_if_update_lookup_tables (vnet_main_t *vnm, u32 sw_if_index) +{ + vnet_interface_main_t *im = &vnm->interface_main; + vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index); + + vec_validate_init_empty (im->hw_if_index_by_sw_if_index, sw_if_index, ~0); + vec_validate_init_empty (im->if_out_arc_end_next_index_by_sw_if_index, + sw_if_index, ~0); + + im->hw_if_index_by_sw_if_index[sw_if_index] = hi->hw_if_index; + im->if_out_arc_end_next_index_by_sw_if_index[sw_if_index] = + hi->if_out_arc_end_node_next_index; +} + static u32 vnet_create_sw_interface_no_callbacks (vnet_main_t * vnm, vnet_sw_interface_t * template) @@ -592,6 +610,7 @@ vnet_create_sw_interface_no_callbacks (vnet_main_t * vnm, vnet_interface_counter_unlock (im); } + vnet_if_update_lookup_tables (vnm, sw_if_index); return sw_if_index; } @@ -771,7 +790,6 @@ setup_tx_node (vlib_main_t * vm, { vlib_node_t *n = vlib_get_node (vm, node_index); - n->function = dev_class->tx_function; n->format_trace = dev_class->format_tx_trace; /// XXX: Update this to use counter structure @@ -807,7 +825,8 @@ vnet_register_interface (vnet_main_t * vnm, vnet_config_main_t *cm; u32 hw_index, i; char *tx_node_name = NULL, *output_node_name = NULL; - vlib_node_function_t *output_node = vnet_interface_output_node_get (); + vlib_node_t *if_out_node = + vlib_get_node (vm, vnet_interface_output_node.index); pool_get (im->hw_interfaces, hw); clib_memset (hw, 0, sizeof (*hw)); @@ -851,7 +870,7 @@ vnet_register_interface (vnet_main_t * vnm, hw->min_packet_bytes = 0; vnet_sw_interface_set_mtu (vnm, hw->sw_if_index, 0); - if (dev_class->tx_function == 0) + if (dev_class->tx_function == 0 && dev_class->tx_fn_registrations == 0) goto no_output_nodes; /* No output/tx nodes to create */ tx_node_name = (char *) format (0, "%v-tx", hw->name); @@ -872,49 +891,57 @@ vnet_register_interface (vnet_main_t * vnm, vlib_node_rename (vm, hw->tx_node_index, "%v", tx_node_name); vlib_node_rename (vm, hw->output_node_index, "%v", output_node_name); - /* *INDENT-OFF* */ - foreach_vlib_main ({ - vnet_interface_output_runtime_t *rt; - - rt = vlib_node_get_runtime_data (this_vlib_main, hw->output_node_index); - ASSERT (rt->is_deleted == 1); - rt->is_deleted = 0; - rt->hw_if_index = hw_index; - rt->sw_if_index = hw->sw_if_index; - rt->dev_instance = hw->dev_instance; + foreach_vlib_main () + { + vnet_interface_output_runtime_t *rt; - rt = vlib_node_get_runtime_data (this_vlib_main, hw->tx_node_index); - rt->hw_if_index = hw_index; - rt->sw_if_index = hw->sw_if_index; - rt->dev_instance = hw->dev_instance; - }); - /* *INDENT-ON* */ + rt = + vlib_node_get_runtime_data (this_vlib_main, hw->output_node_index); + ASSERT (rt->is_deleted == 1); + rt->is_deleted = 0; + rt->hw_if_index = hw_index; + rt->sw_if_index = hw->sw_if_index; + rt->dev_instance = hw->dev_instance; + + rt = vlib_node_get_runtime_data (this_vlib_main, hw->tx_node_index); + rt->hw_if_index = hw_index; + rt->sw_if_index = hw->sw_if_index; + rt->dev_instance = hw->dev_instance; + } /* The new class may differ from the old one. * Functions have to be updated. */ node = vlib_get_node (vm, hw->output_node_index); - node->function = output_node; node->format_trace = format_vnet_interface_output_trace; - /* *INDENT-OFF* */ - foreach_vlib_main ({ - nrt = vlib_node_get_runtime (this_vlib_main, hw->output_node_index); - nrt->function = node->function; - vlib_node_runtime_perf_counter (this_vlib_main, nrt, 0, 0, 0, - VLIB_NODE_RUNTIME_PERF_RESET); - }); - /* *INDENT-ON* */ + node->node_fn_registrations = if_out_node->node_fn_registrations; + node->function = if_out_node->function; + + foreach_vlib_main () + { + nrt = vlib_node_get_runtime (this_vlib_main, hw->output_node_index); + nrt->function = node->function; + vlib_node_runtime_perf_counter (this_vlib_main, nrt, 0, 0, 0, + VLIB_NODE_RUNTIME_PERF_RESET); + } node = vlib_get_node (vm, hw->tx_node_index); - node->function = dev_class->tx_function; + if (dev_class->tx_fn_registrations) + { + node->node_fn_registrations = dev_class->tx_fn_registrations; + node->function = vlib_node_get_preferred_node_fn_variant ( + vm, dev_class->tx_fn_registrations); + } + else + node->function = dev_class->tx_function; node->format_trace = dev_class->format_tx_trace; - /* *INDENT-OFF* */ - foreach_vlib_main ({ - nrt = vlib_node_get_runtime (this_vlib_main, hw->tx_node_index); - nrt->function = node->function; - vlib_node_runtime_perf_counter (this_vlib_main, nrt, 0, 0, 0, - VLIB_NODE_RUNTIME_PERF_RESET); - }); - /* *INDENT-ON* */ + + foreach_vlib_main () + { + nrt = vlib_node_get_runtime (this_vlib_main, hw->tx_node_index); + nrt->function = node->function; + vlib_node_runtime_perf_counter (this_vlib_main, nrt, 0, 0, 0, + VLIB_NODE_RUNTIME_PERF_RESET); + } _vec_len (im->deleted_hw_interface_nodes) -= 1; } @@ -937,7 +964,13 @@ vnet_register_interface (vnet_main_t * vnm, r.flags = VLIB_NODE_FLAG_IS_OUTPUT; r.name = tx_node_name; - r.function = dev_class->tx_function; + if (dev_class->tx_fn_registrations) + { + r.function = 0; + r.node_fn_registrations = dev_class->tx_fn_registrations; + } + else + r.function = dev_class->tx_function; hw->tx_node_index = vlib_register_node (vm, &r); @@ -947,8 +980,14 @@ vnet_register_interface (vnet_main_t * vnm, r.flags = 0; r.name = output_node_name; - r.function = output_node; r.format_trace = format_vnet_interface_output_trace; + if (if_out_node->node_fn_registrations) + { + r.function = 0; + r.node_fn_registrations = if_out_node->node_fn_registrations; + } + else + r.function = if_out_node->function; { static char *e[] = { @@ -968,7 +1007,6 @@ vnet_register_interface (vnet_main_t * vnm, vlib_node_add_next_with_slot (vm, hw->output_node_index, hw->tx_node_index, VNET_INTERFACE_OUTPUT_NEXT_TX); - /* add interface to the list of "output-interface" feature arc start nodes and clone nexts from 1st interface if it exists */ fcm = vnet_feature_get_config_main (im->output_feature_arc_index); @@ -992,6 +1030,9 @@ vnet_register_interface (vnet_main_t * vnm, } } + hw->if_out_arc_end_node_next_index = vlib_node_add_next ( + vm, vnet_interface_output_arc_end_node.index, hw->tx_node_index); + vnet_if_update_lookup_tables (vnm, hw->sw_if_index); setup_output_node (vm, hw->output_node_index, hw_class); setup_tx_node (vm, hw->tx_node_index, dev_class); @@ -1022,6 +1063,10 @@ vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index) /* Call delete callbacks. */ call_hw_interface_add_del_callbacks (vnm, hw_if_index, /* is_create */ 0); + /* delete rx queues */ + vnet_hw_if_unregister_all_rx_queues (vnm, hw_if_index); + vnet_hw_if_update_runtime_data (vnm, hw_if_index); + /* Delete any sub-interfaces. */ { u32 id, sw_if_index; @@ -1046,17 +1091,15 @@ vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index) /* Put output/tx nodes into recycle pool */ vnet_hw_interface_nodes_t *dn; - /* *INDENT-OFF* */ - foreach_vlib_main - ({ + foreach_vlib_main () + { vnet_interface_output_runtime_t *rt = vlib_node_get_runtime_data (this_vlib_main, hw->output_node_index); /* Mark node runtime as deleted so output node (if called) * will drop packets. */ rt->is_deleted = 1; - }); - /* *INDENT-ON* */ + } vlib_node_rename (vm, hw->output_node_index, "interface-%d-output-deleted", hw_if_index); @@ -1071,8 +1114,7 @@ vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index) vec_free (hw->name); vec_free (hw->hw_address); vec_free (hw->input_node_thread_index_by_queue); - vec_free (hw->dq_runtime_index_by_queue); - + vec_free (hw->rx_queue_indices); pool_put (im->hw_interfaces, hw); } @@ -1348,25 +1390,13 @@ vnet_interface_init (vlib_main_t * vm) c->index = vec_len (im->device_classes); hash_set_mem (im->device_class_by_name, c->name, c->index); + /* to avoid confusion, please remove ".tx_function" statement + from VNET_DEVICE_CLASS() if using function candidates */ + ASSERT (c->tx_fn_registrations == 0 || c->tx_function == 0); + if (c->tx_fn_registrations) - { - vlib_node_fn_registration_t *fnr = c->tx_fn_registrations; - int priority = -1; - - /* to avoid confusion, please remove ".tx_function" statement - from VNET_DEVICE_CLASS() if using function candidates */ - ASSERT (c->tx_function == 0); - - while (fnr) - { - if (fnr->priority > priority) - { - priority = fnr->priority; - c->tx_function = fnr->function; - } - fnr = fnr->next_registration; - } - } + c->tx_function = vlib_node_get_preferred_node_fn_variant ( + vm, c->tx_fn_registrations); vec_add1 (im->device_classes, c[0]); c = c->next_class_registration; @@ -1376,6 +1406,8 @@ vnet_interface_init (vlib_main_t * vm) im->hw_interface_class_by_name = hash_create_string ( /* size */ 0, sizeof (uword)); + im->rxq_index_by_hw_if_index_and_queue_id = + hash_create_mem (0, sizeof (u64), sizeof (u32)); im->sw_if_index_by_sup_and_sub = hash_create_mem (0, sizeof (u64), sizeof (uword)); {