X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Finterface.c;h=b72dcd41f4622feef56bbda4c5f8e1d1e45bb661;hb=d7cb1b5f22948eba272e1a8844c75a2b87706fc4;hp=7a808add832a601e2257a26d23858a02b5e968bf;hpb=064f55da7798f3a4c790b656dba71b32a3b82a5c;p=vpp.git diff --git a/vnet/vnet/interface.c b/vnet/vnet/interface.c index 7a808add832..b72dcd41f46 100644 --- a/vnet/vnet/interface.c +++ b/vnet/vnet/interface.c @@ -240,17 +240,25 @@ unserialize_vnet_interface_state (serialize_main_t * m, va_list * va) static clib_error_t * call_elf_section_interface_callbacks (vnet_main_t * vnm, u32 if_index, u32 flags, - _vnet_interface_function_list_elt_t * - elt) + _vnet_interface_function_list_elt_t ** + elts) { + _vnet_interface_function_list_elt_t *elt; + vnet_interface_function_priority_t prio; clib_error_t *error = 0; - while (elt) + for (prio = VNET_ITF_FUNC_PRIORITY_LOW; + prio <= VNET_ITF_FUNC_PRIORITY_HIGH; prio++) { - error = elt->fp (vnm, if_index, flags); - if (error) - return error; - elt = elt->next_interface_function; + elt = elts[prio]; + + while (elt) + { + error = elt->fp (vnm, if_index, flags); + if (error) + return error; + elt = elt->next_interface_function; + } } return error; } @@ -623,6 +631,16 @@ vnet_delete_sw_interface (vnet_main_t * vnm, u32 sw_if_index) vnet_sw_interface_t *sw = pool_elt_at_index (im->sw_interfaces, sw_if_index); + /* Make sure the interface is in L3 mode (removed from L2 BD or XConnect) */ + vlib_main_t *vm = vlib_get_main (); + l2_input_config_t *config; + config = vec_elt_at_index (l2input_main.configs, sw_if_index); + if (config->xconnect) + set_int_l2_mode (vm, vnm, MODE_L3, config->output_sw_if_index, 0, 0, 0, + 0); + if (config->xconnect || config->bridge) + set_int_l2_mode (vm, vnm, MODE_L3, sw_if_index, 0, 0, 0, 0); + /* Bring down interface in case it is up. */ if (sw->flags != 0) vnet_sw_interface_set_flags (vnm, sw_if_index, /* flags */ 0); @@ -669,7 +687,9 @@ vnet_register_interface (vnet_main_t * vnm, vnet_hw_interface_class_t *hw_class = vnet_get_hw_interface_class (vnm, hw_class_index); vlib_main_t *vm = vnm->vlib_main; - u32 hw_index; + vnet_feature_config_main_t *fcm; + vnet_config_main_t *cm; + u32 hw_index, i; char *tx_node_name, *output_node_name; pool_get (im->hw_interfaces, hw); @@ -694,11 +714,11 @@ vnet_register_interface (vnet_main_t * vnm, /* Make hardware interface point to software interface. */ { - vnet_sw_interface_t sw; - - memset (&sw, 0, sizeof (sw)); - sw.type = VNET_SW_INTERFACE_TYPE_HARDWARE; - sw.hw_if_index = hw_index; + vnet_sw_interface_t sw = { + .type = VNET_SW_INTERFACE_TYPE_HARDWARE, + .flood_class = VNET_FLOOD_CLASS_NORMAL, + .hw_if_index = hw_index + }; hw->sw_if_index = vnet_create_sw_interface_no_callbacks (vnm, &sw); } @@ -747,8 +767,8 @@ vnet_register_interface (vnet_main_t * vnm, /* 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 = dev_class->no_flatten_output_chains ? - vnet_interface_output_node_no_flatten_multiarch_select () : + node->function = dev_class->flatten_output_chains ? + vnet_interface_output_node_flatten_multiarch_select () : vnet_interface_output_node_multiarch_select (); node->format_trace = format_vnet_interface_output_trace; nrt = vlib_node_get_runtime (vm, hw->output_node_index); @@ -792,8 +812,8 @@ vnet_register_interface (vnet_main_t * vnm, r.flags = 0; r.name = output_node_name; - r.function = dev_class->no_flatten_output_chains ? - vnet_interface_output_node_no_flatten_multiarch_select () : + r.function = dev_class->flatten_output_chains ? + vnet_interface_output_node_flatten_multiarch_select () : vnet_interface_output_node_multiarch_select (); r.format_trace = format_vnet_interface_output_trace; @@ -808,17 +828,34 @@ vnet_register_interface (vnet_main_t * vnm, } hw->output_node_index = vlib_register_node (vm, &r); -#define _(sym,str) vlib_node_add_named_next_with_slot (vm, \ - hw->output_node_index, str, \ - VNET_INTERFACE_OUTPUT_NEXT_##sym); - foreach_intf_output_feat -#undef _ - vlib_node_add_named_next_with_slot (vm, hw->output_node_index, - "error-drop", - VNET_INTERFACE_OUTPUT_NEXT_DROP); + vlib_node_add_named_next_with_slot (vm, hw->output_node_index, + "error-drop", + VNET_INTERFACE_OUTPUT_NEXT_DROP); 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); + cm = &fcm->config_main; + i = vec_len (cm->start_node_indices); + vec_validate (cm->start_node_indices, i); + cm->start_node_indices[i] = hw->output_node_index; + if (hw_index) + { + /* copy nexts from 1st interface */ + vnet_hw_interface_t *first_hw; + vlib_node_t *first_node; + + first_hw = vnet_get_hw_interface (vnm, /* hw_if_index */ 0); + first_node = vlib_get_node (vm, first_hw->output_node_index); + + /* 1st 2 nexts are already added above */ + for (i = 2; i < vec_len (first_node->next_nodes); i++) + vlib_node_add_next_with_slot (vm, hw->output_node_index, + first_node->next_nodes[i], i); + } } setup_output_node (vm, hw->output_node_index, hw_class); @@ -883,6 +920,27 @@ vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index) pool_put (im->hw_interfaces, hw); } +void +vnet_hw_interface_walk_sw (vnet_main_t * vnm, + u32 hw_if_index, + vnet_hw_sw_interface_walk_t fn, void *ctx) +{ + vnet_hw_interface_t *hi; + u32 id, sw_if_index; + + hi = vnet_get_hw_interface (vnm, hw_if_index); + /* the super first, then the and sub interfaces */ + fn (vnm, hi->sw_if_index, ctx); + + /* *INDENT-OFF* */ + hash_foreach (id, sw_if_index, + hi->sub_interface_sw_if_index_by_id, + ({ + fn (vnm, sw_if_index, ctx); + })); + /* *INDENT-ON* */ +} + static void serialize_vnet_hw_interface_set_class (serialize_main_t * m, va_list * va) { @@ -1168,6 +1226,7 @@ vnet_interface_init (vlib_main_t * vm) return error; } + vnm->interface_tag_by_sw_if_index = hash_create (0, sizeof (uword)); } VLIB_INIT_FUNCTION (vnet_interface_init); @@ -1202,34 +1261,6 @@ vnet_interface_name_renumber (u32 sw_if_index, u32 new_show_dev_instance) return rv; } -int -vnet_interface_add_del_feature (vnet_main_t * vnm, - vlib_main_t * vm, - u32 sw_if_index, - intf_output_feat_t feature, int is_add) -{ - vnet_sw_interface_t *sw; - - sw = vnet_get_sw_interface (vnm, sw_if_index); - - if (is_add) - { - - sw->output_feature_bitmap |= (1 << feature); - sw->output_feature_bitmap |= (1 << INTF_OUTPUT_FEAT_DONE); - - } - else - { /* delete */ - - sw->output_feature_bitmap &= ~(1 << feature); - if (sw->output_feature_bitmap == (1 << INTF_OUTPUT_FEAT_DONE)) - sw->output_feature_bitmap = 0; - - } - return 0; -} - clib_error_t * vnet_rename_interface (vnet_main_t * vnm, u32 hw_if_index, char *new_name) {