X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Finterface.c;h=e2e4e9166bf65cb23115effb78135521df3e2557;hb=b85b0df2a039b694fb2f3c09a01decfb89d7bce2;hp=b2166dcebaee4f9492d93bb6097428768c5bb6f5;hpb=5f8f6173328f8d77feea5fd100e150c3094c11f0;p=vpp.git diff --git a/src/vnet/interface.c b/src/vnet/interface.c index b2166dcebae..e2e4e9166bf 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -39,10 +39,19 @@ #include #include -#include #include #include -#include +#include +#include + +/* *INDENT-OFF* */ +VLIB_REGISTER_LOG_CLASS (if_default_log, static) = { + .class_name = "interface", +}; +/* *INDENT-ON* */ + +#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_ { @@ -132,22 +141,22 @@ serialize_vnet_interface_state (serialize_main_t * m, va_list * va) /* Serialize hardware interface classes since they may have changed. Must do this before sending up/down flags. */ /* *INDENT-OFF* */ - pool_foreach (hif, im->hw_interfaces, ({ + pool_foreach (hif, im->hw_interfaces) { vnet_hw_interface_class_t * hw_class = vnet_get_hw_interface_class (vnm, hif->hw_class_index); serialize_cstring (m, hw_class->name); - })); + } /* *INDENT-ON* */ /* Send sw/hw interface state when non-zero. */ /* *INDENT-OFF* */ - pool_foreach (sif, im->sw_interfaces, ({ + pool_foreach (sif, im->sw_interfaces) { if (sif->flags != 0) { vec_add2 (sts, st, 1); st->sw_hw_if_index = sif->sw_if_index; st->flags = sif->flags; } - })); + } /* *INDENT-ON* */ vec_serialize (m, sts, serialize_vec_vnet_sw_hw_interface_state); @@ -156,14 +165,14 @@ serialize_vnet_interface_state (serialize_main_t * m, va_list * va) _vec_len (sts) = 0; /* *INDENT-OFF* */ - pool_foreach (hif, im->hw_interfaces, ({ + pool_foreach (hif, im->hw_interfaces) { if (hif->flags != 0) { vec_add2 (sts, st, 1); st->sw_hw_if_index = hif->hw_if_index; st->flags = vnet_hw_interface_flags_to_sw(hif->flags); } - })); + } /* *INDENT-ON* */ vec_serialize (m, sts, serialize_vec_vnet_sw_hw_interface_state); @@ -197,15 +206,21 @@ unserialize_vnet_interface_state (serialize_main_t * m, va_list * va) clib_error_t *error; /* *INDENT-OFF* */ - pool_foreach (hif, im->hw_interfaces, ({ + pool_foreach (hif, im->hw_interfaces) { unserialize_cstring (m, &class_name); p = hash_get_mem (im->hw_interface_class_by_name, class_name); - ASSERT (p != 0); - error = vnet_hw_interface_set_class_helper (vnm, hif->hw_if_index, p[0], /* redistribute */ 0); + if (p) + { + error = vnet_hw_interface_set_class_helper + (vnm, hif->hw_if_index, p[0], /* redistribute */ 0); + } + else + error = clib_error_return (0, "hw class %s AWOL?", class_name); + if (error) clib_error_report (error); vec_free (class_name); - })); + } /* *INDENT-ON* */ } @@ -333,6 +348,8 @@ vnet_hw_interface_set_flags_helper (vnet_main_t * vnm, u32 hw_if_index, hi->flags |= flags; done: + if (error) + log_err ("hw_set_flags_helper: %U", format_clib_error, error); return error; } @@ -478,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); } } @@ -485,6 +503,8 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, si->flags |= flags; done: + if (error) + log_err ("sw_set_flags_helper: %U", format_clib_error, error); return error; } @@ -492,6 +512,7 @@ clib_error_t * vnet_hw_interface_set_flags (vnet_main_t * vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags) { + log_debug ("hw_set_flags: hw_if_index %u flags 0x%x", hw_if_index, flags); return vnet_hw_interface_set_flags_helper (vnm, hw_if_index, flags, VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE); @@ -501,6 +522,7 @@ clib_error_t * vnet_sw_interface_set_flags (vnet_main_t * vnm, u32 sw_if_index, vnet_sw_interface_flags_t flags) { + log_debug ("sw_set_flags: sw_if_index %u flags 0x%x", sw_if_index, flags); return vnet_sw_interface_set_flags_helper (vnm, sw_if_index, flags, VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE); @@ -510,6 +532,7 @@ void vnet_sw_interface_admin_up (vnet_main_t * vnm, u32 sw_if_index) { u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index); + log_debug ("sw_admin_up: sw_if_index %u", sw_if_index); if (!(flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)) { @@ -522,6 +545,7 @@ void vnet_sw_interface_admin_down (vnet_main_t * vnm, u32 sw_if_index) { u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index); + log_debug ("sw_admin_down: sw_if_index %u", sw_if_index); if (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) { @@ -578,10 +602,22 @@ clib_error_t * vnet_create_sw_interface (vnet_main_t * vnm, vnet_sw_interface_t * template, u32 * sw_if_index) { + vnet_interface_main_t *im = &vnm->interface_main; clib_error_t *error; vnet_hw_interface_t *hi; vnet_device_class_t *dev_class; + if (template->sub.eth.flags.two_tags == 1 + && template->sub.eth.flags.exact_match == 1 + && (template->sub.eth.flags.inner_vlan_id_any == 1 + || template->sub.eth.flags.outer_vlan_id_any == 1)) + { + char *str = "inner-dot1q any exact-match is unsupported"; + error = clib_error_return (0, str); + log_err ("create_sw_interface: %s", str); + return error; + } + hi = vnet_get_sup_hw_interface (vnm, template->sup_sw_if_index); dev_class = vnet_get_device_class (vnm, hi->dev_class_index); @@ -603,11 +639,19 @@ vnet_create_sw_interface (vnet_main_t * vnm, vnet_sw_interface_t * template, if (error) { /* undo the work done by vnet_create_sw_interface_no_callbacks() */ - vnet_interface_main_t *im = &vnm->interface_main; + log_err ("create_sw_interface: set flags failed\n %U", + format_clib_error, error); vnet_sw_interface_t *sw = pool_elt_at_index (im->sw_interfaces, *sw_if_index); pool_put (im->sw_interfaces, sw); } + else + { + vnet_sw_interface_t *sw = + pool_elt_at_index (im->sw_interfaces, *sw_if_index); + log_debug ("create_sw_interface: interface %U (sw_if_index %u) created", + format_vnet_sw_interface_name, vnm, sw, *sw_if_index); + } return error; } @@ -619,19 +663,10 @@ 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); + log_debug ("delete_sw_interface: sw_if_index %u, name '%U'", + sw_if_index, format_vnet_sw_if_index_name, vnm, sw_if_index); + /* Check if the interface has config and is removed from L2 BD or XConnect */ - vlib_main_t *vm = vlib_get_main (); - l2_input_config_t *config; - if (sw_if_index < vec_len (l2input_main.configs)) - { - 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, - L2_BD_PORT_TYPE_NORMAL, 0, 0); - if (config->xconnect || config->bridge) - set_int_l2_mode (vm, vnm, MODE_L3, sw_if_index, 0, - L2_BD_PORT_TYPE_NORMAL, 0, 0); - } vnet_clear_sw_interface_tag (vnm, sw_if_index); /* Bring down interface in case it is up. */ @@ -658,6 +693,9 @@ vnet_sw_interface_set_mtu (vnet_main_t * vnm, u32 sw_if_index, u32 mtu) if (si->mtu[VNET_MTU_L3] != mtu) { si->mtu[VNET_MTU_L3] = mtu; + log_debug ("set_mtu: interface %U, new mtu %u", + format_vnet_sw_if_index_name, vnm, sw_if_index, mtu); + call_sw_interface_mtu_change_callbacks (vnm, sw_if_index); } } @@ -680,7 +718,13 @@ vnet_sw_interface_set_protocol_mtu (vnet_main_t * vnm, u32 sw_if_index, } /* Notify interested parties */ if (changed) - call_sw_interface_mtu_change_callbacks (vnm, sw_if_index); + { + log_debug ("set_protocol_mtu: interface %U l3 %u ip4 %u ip6 %u mpls %u", + format_vnet_sw_if_index_name, vnm, sw_if_index, + mtu[VNET_MTU_L3], mtu[VNET_MTU_IP4], mtu[VNET_MTU_IP6], + mtu[VNET_MTU_MPLS]); + call_sw_interface_mtu_change_callbacks (vnm, sw_if_index); + } } void @@ -733,9 +777,10 @@ setup_tx_node (vlib_main_t * vm, n->function = dev_class->tx_function; n->format_trace = dev_class->format_tx_trace; + /// XXX: Update this to use counter structure vlib_register_errors (vm, node_index, dev_class->tx_function_n_errors, - dev_class->tx_function_error_strings); + dev_class->tx_function_error_strings, 0); } static void @@ -765,6 +810,7 @@ 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 (vm); pool_get (im->hw_interfaces, hw); clib_memset (hw, 0, sizeof (*hw)); @@ -772,7 +818,7 @@ vnet_register_interface (vnet_main_t * vnm, hw_index = hw - im->hw_interfaces; hw->hw_if_index = hw_index; - hw->default_rx_mode = VNET_HW_INTERFACE_RX_MODE_POLLING; + hw->default_rx_mode = VNET_HW_IF_RX_MODE_POLLING; if (dev_class->format_device_name) hw->name = format (0, "%U", dev_class->format_device_name, dev_instance); @@ -850,12 +896,14 @@ 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 = vnet_interface_output_node; + 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* */ @@ -866,6 +914,8 @@ vnet_register_interface (vnet_main_t * vnm, 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* */ @@ -900,7 +950,7 @@ vnet_register_interface (vnet_main_t * vnm, r.flags = 0; r.name = output_node_name; - r.function = vnet_interface_output_node; + r.function = output_node; r.format_trace = format_vnet_interface_output_trace; { @@ -975,6 +1025,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; @@ -1024,8 +1078,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); } @@ -1062,11 +1115,11 @@ vnet_hw_interface_walk (vnet_main_t * vnm, im = &vnm->interface_main; /* *INDENT-OFF* */ - pool_foreach (hi, im->hw_interfaces, - ({ + pool_foreach (hi, im->hw_interfaces) + { if (WALK_STOP == fn(vnm, hi->hw_if_index, ctx)) break; - })); + } /* *INDENT-ON* */ } @@ -1080,11 +1133,11 @@ vnet_sw_interface_walk (vnet_main_t * vnm, im = &vnm->interface_main; /* *INDENT-OFF* */ - pool_foreach (si, im->sw_interfaces, + pool_foreach (si, im->sw_interfaces) { if (WALK_STOP == fn (vnm, si, ctx)) break; - }); + } /* *INDENT-ON* */ } @@ -1329,6 +1382,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)); { @@ -1475,6 +1530,8 @@ vnet_hw_interface_add_del_mac_address (vnet_main_t * vnm, mac_address, is_add); done: + if (error) + log_err ("hw_add_del_mac_address: %U", format_clib_error, error); return error; } @@ -1672,6 +1729,44 @@ default_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) } } +clib_error_t * +vnet_hw_interface_set_rss_queues (vnet_main_t * vnm, + vnet_hw_interface_t * hi, + clib_bitmap_t * bitmap) +{ + clib_error_t *error = 0; + vnet_device_class_t *dev_class = + vnet_get_device_class (vnm, hi->dev_class_index); + + if (dev_class->set_rss_queues_function) + { + if (clib_bitmap_count_set_bits (bitmap) == 0) + { + error = clib_error_return (0, + "must assign at least one valid rss queue"); + goto done; + } + + error = dev_class->set_rss_queues_function (vnm, hi, bitmap); + } + else + { + error = clib_error_return (0, + "setting rss queues is not supported on this interface"); + } + + if (!error) + { + clib_bitmap_free (hi->rss_queues); + hi->rss_queues = clib_bitmap_dup (bitmap); + } + +done: + if (error) + log_err ("hw_set_rss_queues: %U", format_clib_error, error); + return error; +} + int collect_detailed_interface_stats_flag = 0; void