X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Finterface.c;h=28c46110851aeaea9e5ba361cf016bbe6883f2b5;hb=70083ee;hp=7516aec0e712ae5aa7e33acfc36681ed190cc41e;hpb=438f63094465d35c278155484fe85153e438873e;p=vpp.git diff --git a/src/vnet/interface.c b/src/vnet/interface.c index 7516aec0e71..28c46110851 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -122,20 +122,55 @@ unserialize_vnet_sw_interface_set_flags (serialize_main_t * m, va_list * va) /* helper_flags no redistribution */ 0); } -void -vnet_hw_interface_set_mtu (vnet_main_t * vnm, u32 hw_if_index, u32 mtu) +static void +vnet_sw_interface_set_mtu_cb (vnet_main_t * vnm, u32 sw_if_index, void *ctx) { - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); + u32 *mtu = ctx; + vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); + ASSERT (si); - if (hi->max_packet_bytes != mtu) + si->max_l3_packet_bytes[VLIB_TX] = si->max_l3_packet_bytes[VLIB_RX] = *mtu; + adj_mtu_update (sw_if_index); +} + +/* + * MTU is set per software interface. Setting MTU on a parent + * interface will override the MTU setting on sub-interfaces. + * TODO: If sub-interface MTU is ~0 inherit from parent? + */ +int +vnet_sw_interface_set_mtu (vnet_main_t * vnm, u32 sw_if_index, u32 mtu) +{ + vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); + vnet_hw_interface_t *hi = vnet_get_sw_hw_interface (vnm, sw_if_index); + + if (mtu < hi->min_packet_bytes) + return VNET_API_ERROR_INVALID_VALUE; + if (mtu > hi->max_packet_bytes) + return VNET_API_ERROR_INVALID_VALUE; + + /* If done on a parent interface */ + if (si->sw_if_index == si->sup_sw_if_index) { - u16 l3_pad = hi->max_packet_bytes - hi->max_l3_packet_bytes[VLIB_TX]; - hi->max_packet_bytes = mtu; - hi->max_l3_packet_bytes[VLIB_TX] = - hi->max_l3_packet_bytes[VLIB_RX] = mtu - l3_pad; - ethernet_set_flags (vnm, hw_if_index, ETHERNET_INTERFACE_FLAG_MTU); - adj_mtu_update (hw_if_index); + if (hi->hw_class_index == ethernet_hw_interface_class.index) + { + ethernet_set_flags (vnm, hi->hw_if_index, + ETHERNET_INTERFACE_FLAG_MTU); + } + + /* Override MTU on any sub-interface */ + vnet_hw_interface_walk_sw (vnm, + hi->hw_if_index, + vnet_sw_interface_set_mtu_cb, &mtu); } + else + { + si->max_l3_packet_bytes[VLIB_TX] = si->max_l3_packet_bytes[VLIB_RX] = + mtu; + adj_mtu_update (sw_if_index); + } + + return 0; } static void @@ -584,6 +619,9 @@ vnet_create_sw_interface_no_callbacks (vnet_main_t * vnm, if (sw->type == VNET_SW_INTERFACE_TYPE_HARDWARE) sw->sup_sw_if_index = sw->sw_if_index; + sw->max_l3_packet_bytes[VLIB_RX] = ~0; + sw->max_l3_packet_bytes[VLIB_TX] = ~0; + /* Allocate counters for this interface. */ { u32 i; @@ -758,9 +796,7 @@ vnet_register_interface (vnet_main_t * vnm, hw->max_rate_bits_per_sec = 0; hw->min_packet_bytes = 0; - hw->per_packet_overhead_bytes = 0; - hw->max_l3_packet_bytes[VLIB_RX] = ~0; - hw->max_l3_packet_bytes[VLIB_TX] = ~0; + hw->max_packet_bytes = 9000; /* default */ if (dev_class->tx_function == 0) goto no_output_nodes; /* No output/tx nodes to create */ @@ -1237,7 +1273,19 @@ vnet_interface_init (vlib_main_t * vm) vec_validate (im->combined_sw_if_counters, VNET_N_COMBINED_INTERFACE_COUNTER - 1); im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX].name = "rx"; + im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX_UNICAST].name = + "rx-unicast"; + im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX_MULTICAST].name = + "rx-multicast"; + im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX_BROADCAST].name = + "rx-broadcast"; im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX].name = "tx"; + im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX_UNICAST].name = + "tx-unicast"; + im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX_MULTICAST].name = + "tx-multicast"; + im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX_BROADCAST].name = + "tx-broadcast"; im->sw_if_counter_lock[0] = 0; @@ -1414,6 +1462,51 @@ vnet_hw_interface_change_mac_address (vnet_main_t * vnm, u32 hw_if_index, (vnm, hw_if_index, mac_address); } +/* update the unnumbered state of an interface*/ +void +vnet_sw_interface_update_unnumbered (u32 unnumbered_sw_if_index, + u32 ip_sw_if_index, u8 enable) +{ + vnet_main_t *vnm = vnet_get_main (); + vnet_sw_interface_t *si; + u32 was_unnum; + + si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index); + was_unnum = (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED); + + if (enable) + { + si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED; + si->unnumbered_sw_if_index = ip_sw_if_index; + + ip4_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = + ip4_main. + lookup_main.if_address_pool_index_by_sw_if_index[ip_sw_if_index]; + ip6_main. + lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = + ip6_main. + lookup_main.if_address_pool_index_by_sw_if_index[ip_sw_if_index]; + } + else + { + si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED); + si->unnumbered_sw_if_index = (u32) ~ 0; + + ip4_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = ~0; + ip6_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = ~0; + } + + if (was_unnum != (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)) + { + ip4_sw_interface_enable_disable (unnumbered_sw_if_index, enable); + ip6_sw_interface_enable_disable (unnumbered_sw_if_index, enable); + } +} + vnet_l3_packet_type_t vnet_link_to_l3_proto (vnet_link_t link) { @@ -1453,8 +1546,10 @@ default_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) switch (adj->lookup_next_index) { - case IP_LOOKUP_NEXT_ARP: case IP_LOOKUP_NEXT_GLEAN: + adj_glean_update_rewrite (ai); + break; + case IP_LOOKUP_NEXT_ARP: /* * default rewirte in neighbour adj */ @@ -1490,6 +1585,60 @@ default_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) } } +int collect_detailed_interface_stats_flag = 0; + +void +collect_detailed_interface_stats_flag_set (void) +{ + collect_detailed_interface_stats_flag = 1; +} + +void +collect_detailed_interface_stats_flag_clear (void) +{ + collect_detailed_interface_stats_flag = 0; +} + +static clib_error_t * +collect_detailed_interface_stats_cli (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *error = NULL; + + /* Get a line of input. */ + if (!unformat_user (input, unformat_line_input, line_input)) + return clib_error_return (0, "expected enable | disable"); + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "enable") || unformat (line_input, "on")) + collect_detailed_interface_stats_flag_set (); + else if (unformat (line_input, "disable") + || unformat (line_input, "off")) + collect_detailed_interface_stats_flag_clear (); + else + { + error = clib_error_return (0, "unknown input `%U'", + format_unformat_error, line_input); + goto done; + } + } + +done: + unformat_free (line_input); + return error; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (collect_detailed_interface_stats_command, static) = { + .path = "interface collect detailed-stats", + .short_help = "interface collect detailed-stats ", + .function = collect_detailed_interface_stats_cli, +}; +/* *INDENT-ON* */ + /* * fd.io coding-style-patch-verification: ON *