From d723161e038d00e59766aa67a6a0dcc350227e4b Mon Sep 17 00:00:00 2001 From: Ole Troan Date: Thu, 7 Jun 2018 10:17:57 +0200 Subject: MTU: Software interface / Per-protocol MTU support This patch separates setting of hardware interfaec and software interface MTU. Software MTU is L2 payload MTU (i.e. not including L2 header). Per-protocol MTU for IPv4, IPv6 and MPLS can also be set. Currently only IP4, IP6 are enabled in adjacency / rewrite code. Documentation in src/vnet/MTU.md Change-Id: Iee2fd6f0bbc8210748dd8e073ab9fab87d323690 Signed-off-by: Ole Troan --- src/vnet/interface.c | 101 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 82 insertions(+), 19 deletions(-) (limited to 'src/vnet/interface.c') diff --git a/src/vnet/interface.c b/src/vnet/interface.c index 797fe44419a..7a2c3abd2d4 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -122,22 +122,6 @@ 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) -{ - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); - - if (hi->max_packet_bytes != mtu) - { - 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); - } -} - static void unserialize_vnet_hw_interface_set_flags (serialize_main_t * m, va_list * va) { @@ -681,6 +665,71 @@ vnet_delete_sw_interface (vnet_main_t * vnm, u32 sw_if_index) pool_put (im->sw_interfaces, sw); } +static clib_error_t * +call_sw_interface_mtu_change_callbacks (vnet_main_t * vnm, u32 sw_if_index) +{ + return call_elf_section_interface_callbacks + (vnm, sw_if_index, 0, vnm->sw_interface_mtu_change_functions); +} + +void +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); + + if (si->mtu[VNET_MTU_L3] != mtu) + { + si->mtu[VNET_MTU_L3] = mtu; + call_sw_interface_mtu_change_callbacks (vnm, sw_if_index); + } +} + +void +vnet_sw_interface_set_protocol_mtu (vnet_main_t * vnm, u32 sw_if_index, + u32 mtu[]) +{ + vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); + bool changed = false; + int i; + + for (i = 0; i < VNET_N_MTU; i++) + { + if (si->mtu[i] != mtu[i]) + { + si->mtu[i] = mtu[i]; + changed = true; + } + } + /* Notify interested parties */ + if (changed) + call_sw_interface_mtu_change_callbacks (vnm, sw_if_index); +} + +/* + * Reflect a change in hardware MTU on protocol MTUs + */ +static walk_rc_t +sw_interface_walk_callback (vnet_main_t * vnm, u32 sw_if_index, void *ctx) +{ + u32 *link_mtu = ctx; + vnet_sw_interface_set_mtu (vnm, sw_if_index, *link_mtu); + return WALK_CONTINUE; +} + +void +vnet_hw_interface_set_mtu (vnet_main_t * vnm, u32 hw_if_index, u32 mtu) +{ + vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); + + if (hi->max_packet_bytes != mtu) + { + hi->max_packet_bytes = mtu; + ethernet_set_flags (vnm, hw_if_index, ETHERNET_INTERFACE_FLAG_MTU); + vnet_hw_interface_walk_sw (vnm, hw_if_index, sw_interface_walk_callback, + &mtu); + } +} + static void setup_tx_node (vlib_main_t * vm, u32 node_index, vnet_device_class_t * dev_class) @@ -762,9 +811,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; + vnet_sw_interface_set_mtu (vnm, hw->sw_if_index, 0); if (dev_class->tx_function == 0) goto no_output_nodes; /* No output/tx nodes to create */ @@ -1523,6 +1570,22 @@ vnet_link_to_l3_proto (vnet_link_t link) return (0); } +vnet_mtu_t +vnet_link_to_mtu (vnet_link_t link) +{ + switch (link) + { + case VNET_LINK_IP4: + return (VNET_MTU_IP4); + case VNET_LINK_IP6: + return (VNET_MTU_IP6); + case VNET_LINK_MPLS: + return (VNET_MTU_MPLS); + default: + return (VNET_MTU_L3); + } +} + u8 * default_build_rewrite (vnet_main_t * vnm, u32 sw_if_index, -- cgit 1.2.3-korg