diff options
author | Damjan Marion <damarion@cisco.com> | 2022-01-17 14:49:17 +0100 |
---|---|---|
committer | Ole Tr�an <otroan@employees.org> | 2022-01-18 13:20:21 +0000 |
commit | 1cd0e5dd533f4209dde453eaa43215e52cd42985 (patch) | |
tree | 88ed4b47252cfe27c13ac0f85a6cfc86a7052d5b | |
parent | 49378f206b8e780a898e632f7dd8db912b9b118e (diff) |
vnet: distinguish between max_frame_size and MTU
Type: improvement
Change-Id: I3659de6599f402c92e3855e3bf0e5e3388f2bea0
Signed-off-by: Damjan Marion <damarion@cisco.com>
-rw-r--r-- | src/plugins/af_xdp/device.c | 5 | ||||
-rw-r--r-- | src/plugins/dpdk/device/common.c | 63 | ||||
-rw-r--r-- | src/plugins/dpdk/device/dpdk.h | 7 | ||||
-rw-r--r-- | src/plugins/dpdk/device/format.c | 4 | ||||
-rw-r--r-- | src/plugins/dpdk/device/init.c | 26 | ||||
-rw-r--r-- | src/plugins/rdma/device.c | 5 | ||||
-rw-r--r-- | src/vnet/devices/af_packet/af_packet.c | 10 | ||||
-rw-r--r-- | src/vnet/devices/tap/tap.c | 10 | ||||
-rw-r--r-- | src/vnet/ethernet/ethernet.h | 6 | ||||
-rw-r--r-- | src/vnet/ethernet/interface.c | 26 | ||||
-rw-r--r-- | src/vnet/gre/interface.c | 8 | ||||
-rw-r--r-- | src/vnet/interface.c | 34 | ||||
-rw-r--r-- | src/vnet/interface.h | 22 | ||||
-rw-r--r-- | src/vnet/interface_api.c | 2 | ||||
-rw-r--r-- | src/vnet/interface_cli.c | 10 | ||||
-rw-r--r-- | src/vnet/interface_funcs.h | 6 | ||||
-rw-r--r-- | src/vnet/ipip/ipip.c | 10 |
17 files changed, 148 insertions, 106 deletions
diff --git a/src/plugins/af_xdp/device.c b/src/plugins/af_xdp/device.c index a5e0b739300..87d1251c229 100644 --- a/src/plugins/af_xdp/device.c +++ b/src/plugins/af_xdp/device.c @@ -68,7 +68,8 @@ af_xdp_mac_change (vnet_hw_interface_t * hw, const u8 * old, const u8 * new) } static clib_error_t * -af_xdp_set_mtu (vnet_main_t *vnm, vnet_hw_interface_t *hw, u32 mtu) +af_xdp_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hw, + u32 frame_size) { af_xdp_main_t *am = &af_xdp_main; af_xdp_device_t *ad = vec_elt_at_index (am->devices, hw->dev_instance); @@ -657,7 +658,7 @@ af_xdp_create_if (vlib_main_t * vm, af_xdp_create_if_args_t * args) eir.dev_instance = ad->dev_instance; eir.address = ad->hwaddr; eir.cb.flag_change = af_xdp_flag_change; - eir.cb.set_mtu = af_xdp_set_mtu; + eir.cb.set_max_frame_size = af_xdp_set_max_frame_size; ad->hw_if_index = vnet_eth_register_interface (vnm, &eir); sw = vnet_get_hw_sw_interface (vnm, ad->hw_if_index); diff --git a/src/plugins/dpdk/device/common.c b/src/plugins/dpdk/device/common.c index 3eca847de79..0f54a616773 100644 --- a/src/plugins/dpdk/device/common.c +++ b/src/plugins/dpdk/device/common.c @@ -61,6 +61,7 @@ dpdk_device_setup (dpdk_device_t * xd) vlib_thread_main_t *tm = vlib_get_thread_main (); vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, xd->sw_if_index); vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, xd->hw_if_index); + u16 buf_sz = vlib_buffer_get_default_data_size (vm); vnet_hw_if_caps_change_t caps = {}; struct rte_eth_dev_info dev_info; struct rte_eth_conf conf = {}; @@ -161,49 +162,51 @@ dpdk_device_setup (dpdk_device_t * xd) #if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) if (rxo & DEV_RX_OFFLOAD_JUMBO_FRAME) - conf.rxmode.max_rx_pkt_len = - clib_min (ETHERNET_MAX_PACKET_BYTES, dev_info.max_rx_pktlen); + { + conf.rxmode.max_rx_pkt_len = dev_info.max_rx_pktlen; + xd->max_supported_frame_size = dev_info.max_rx_pktlen; + mtu = xd->max_supported_frame_size - xd->driver_frame_overhead; + } + else + { + mtu = 1500; + xd->max_supported_frame_size = mtu + xd->driver_frame_overhead; + } #else - dpdk_log_debug ("[%u] min_mtu: %u, max_mtu: %u, min_rx_bufsize: %u, " - "max_rx_pktlen: %u, max_lro_pkt_size: %u", - xd->port_id, dev_info.min_mtu, dev_info.max_mtu, - dev_info.min_rx_bufsize, dev_info.max_rx_pktlen, - dev_info.max_lro_pkt_size); - - mtu = xd->conf.disable_multi_seg ? 2000 : ETHERNET_MAX_PACKET_BYTES; - conf.rxmode.mtu = clib_min (mtu, dev_info.max_rx_pktlen); + if (xd->conf.disable_multi_seg) + xd->max_supported_frame_size = clib_min (dev_info.max_rx_pktlen, buf_sz); + else + xd->max_supported_frame_size = dev_info.max_rx_pktlen; +#endif + + mtu = clib_min (xd->max_supported_frame_size - xd->driver_frame_overhead, + ethernet_main.default_mtu); + mtu = mtu + hi->frame_overhead - xd->driver_frame_overhead; + +#if RTE_VERSION >= RTE_VERSION_NUM(21, 11, 0, 0) + conf.rxmode.mtu = mtu; #endif retry: rv = rte_eth_dev_configure (xd->port_id, xd->conf.n_rx_queues, xd->conf.n_tx_queues, &conf); - if (rv < 0 && conf.intr_conf.rxq) { conf.intr_conf.rxq = 0; goto retry; } - if (rv < 0) - { - dpdk_device_error (xd, "rte_eth_dev_configure", rv); - goto error; - } - - rte_eth_dev_get_mtu (xd->port_id, &mtu); - dpdk_log_debug ("[%u] device default mtu %u", xd->port_id, mtu); +#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) + rte_eth_dev_set_mtu (xd->port_id, mtu); +#endif - hi->max_supported_packet_bytes = mtu; - if (hi->max_packet_bytes > mtu) - { - vnet_hw_interface_set_mtu (vnm, xd->hw_if_index, mtu); - } - else - { - rte_eth_dev_set_mtu (xd->port_id, hi->max_packet_bytes); - dpdk_log_debug ("[%u] port mtu set to %u", xd->port_id, - hi->max_packet_bytes); - } + hi->max_frame_size = 0; + vnet_hw_interface_set_max_frame_size (vnm, xd->hw_if_index, + mtu + hi->frame_overhead); + dpdk_log_debug ("[%u] mtu %u max_frame_size %u max max_frame_size %u " + "driver_frame_overhead %u", + xd->port_id, mtu, hi->max_frame_size, + xd->max_supported_frame_size, xd->driver_frame_overhead); vec_validate_aligned (xd->tx_queues, xd->conf.n_tx_queues - 1, CLIB_CACHE_LINE_BYTES); diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h index f1cd17da1cd..196f68f9756 100644 --- a/src/plugins/dpdk/device/dpdk.h +++ b/src/plugins/dpdk/device/dpdk.h @@ -200,6 +200,13 @@ typedef struct /* mac address */ u8 *default_mac_address; + /* maximum supported max frame size */ + u16 max_supported_frame_size; + + /* due to lack of API to get ethernet max_frame_size we store information + * deducted from device info */ + u8 driver_frame_overhead; + /* error string */ clib_error_t *errors; dpdk_port_conf_t conf; diff --git a/src/plugins/dpdk/device/format.c b/src/plugins/dpdk/device/format.c index 4a4b4110b9f..4ef22729532 100644 --- a/src/plugins/dpdk/device/format.c +++ b/src/plugins/dpdk/device/format.c @@ -199,8 +199,8 @@ format_dpdk_link_status (u8 * s, va_list * args) s = format (s, "%s duplex ", (l->link_duplex == ETH_LINK_FULL_DUPLEX) ? "full" : "half"); - s = format (s, "mtu %d %s\n", hi->max_packet_bytes, promisc ? - " promisc" : ""); + s = format (s, "max-frame-size %d %s\n", hi->max_frame_size, + promisc ? " promisc" : ""); } else s = format (s, "\n"); diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index 4faf6290dba..096b8d382fe 100644 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -70,11 +70,15 @@ const struct }; static clib_error_t * -dpdk_set_mtu (vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 mtu) +dpdk_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hi, + u32 frame_size) { dpdk_main_t *dm = &dpdk_main; dpdk_device_t *xd = vec_elt_at_index (dm->devices, hi->dev_instance); int rv; + u32 mtu; + + mtu = frame_size - xd->driver_frame_overhead; rv = rte_eth_dev_set_mtu (xd->port_id, mtu); @@ -99,7 +103,8 @@ dpdk_set_mtu (vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 mtu) } } else - dpdk_log_debug ("[%u] mtu set to %u", xd->port_id, mtu); + dpdk_log_debug ("[%u] max_frame_size set to %u by setting MTU to %u", + xd->port_id, frame_size, mtu); return 0; } @@ -376,6 +381,21 @@ dpdk_lib_init (dpdk_main_t * dm) xd->conf.rss_hf &= di.flow_type_rss_offloads; } + xd->driver_frame_overhead = + RTE_ETHER_HDR_LEN + 2 * RTE_VLAN_HLEN + RTE_ETHER_CRC_LEN; +#if RTE_VERSION >= RTE_VERSION_NUM(21, 11, 0, 0) + q = di.max_rx_pktlen - di.max_mtu; + + if (q < xd->driver_frame_overhead && q > 0) + xd->driver_frame_overhead = q; + dpdk_log_debug ("[%u] min_mtu: %u, max_mtu: %u, min_rx_bufsize: %u, " + "max_rx_pktlen: %u, max_lro_pkt_size: %u", + xd->port_id, di.min_mtu, di.max_mtu, di.min_rx_bufsize, + di.max_rx_pktlen, di.max_lro_pkt_size); +#endif + dpdk_log_debug ("[%u] driver frame overhead is %u", port_id, + xd->driver_frame_overhead); + /* number of RX and TX tescriptors */ if (devconf->num_rx_desc) xd->conf.n_rx_desc = devconf->num_rx_desc; @@ -397,7 +417,7 @@ dpdk_lib_init (dpdk_main_t * dm) eir.dev_instance = xd->device_index; eir.address = addr; eir.cb.flag_change = dpdk_flag_change; - eir.cb.set_mtu = dpdk_set_mtu; + eir.cb.set_max_frame_size = dpdk_set_max_frame_size; xd->hw_if_index = vnet_eth_register_interface (vnm, &eir); hi = vnet_get_hw_interface (vnm, xd->hw_if_index); hi->numa_node = xd->cpu_socket = (i8) rte_eth_dev_socket_id (port_id); diff --git a/src/plugins/rdma/device.c b/src/plugins/rdma/device.c index 167a23213cc..3fdc399a4e3 100644 --- a/src/plugins/rdma/device.c +++ b/src/plugins/rdma/device.c @@ -184,7 +184,8 @@ rdma_mac_change (vnet_hw_interface_t * hw, const u8 * old, const u8 * new) } static clib_error_t * -rdma_set_mtu (vnet_main_t *vnm, vnet_hw_interface_t *hw, u32 mtu) +rdma_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hw, + u32 frame_size) { return vnet_error (VNET_ERR_UNSUPPORTED, 0); } @@ -358,7 +359,7 @@ rdma_register_interface (vnet_main_t * vnm, rdma_device_t * rd) eir.dev_instance = rd->dev_instance; eir.address = rd->hwaddr.bytes; eir.cb.flag_change = rdma_flag_change; - eir.cb.set_mtu = rdma_set_mtu; + eir.cb.set_max_frame_size = rdma_set_max_frame_size; rd->hw_if_index = vnet_eth_register_interface (vnm, &eir); /* Indicate ability to support L3 DMAC filtering and * initialize interface to L3 non-promisc mode */ diff --git a/src/vnet/devices/af_packet/af_packet.c b/src/vnet/devices/af_packet/af_packet.c index cf4f91e2fcd..208537996e3 100644 --- a/src/vnet/devices/af_packet/af_packet.c +++ b/src/vnet/devices/af_packet/af_packet.c @@ -57,13 +57,15 @@ unsigned int if_nametoindex (const char *ifname); typedef struct tpacket_req tpacket_req_t; static clib_error_t * -af_packet_eth_set_mtu (vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 mtu) +af_packet_eth_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hi, + u32 frame_size) { clib_error_t *error, *rv; af_packet_main_t *apm = &af_packet_main; af_packet_if_t *apif = pool_elt_at_index (apm->interfaces, hi->dev_instance); - error = vnet_netlink_set_link_mtu (apif->host_if_index, mtu); + error = vnet_netlink_set_link_mtu (apif->host_if_index, + frame_size + hi->frame_overhead); if (error) { @@ -75,7 +77,7 @@ af_packet_eth_set_mtu (vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 mtu) return rv; } else - apif->host_mtu = mtu; + apif->host_mtu = frame_size + hi->frame_overhead; return 0; } @@ -398,7 +400,7 @@ af_packet_create_if (af_packet_create_if_arg_t *arg) eir.dev_class_index = af_packet_device_class.index; eir.dev_instance = if_index; eir.address = hw_addr; - eir.cb.set_mtu = af_packet_eth_set_mtu; + eir.cb.set_max_frame_size = af_packet_eth_set_max_frame_size; apif->hw_if_index = vnet_eth_register_interface (vnm, &eir); } else diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c index 2e7ad39f3b4..f5ed30ad7b0 100644 --- a/src/vnet/devices/tap/tap.c +++ b/src/vnet/devices/tap/tap.c @@ -683,12 +683,10 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) } if (vif->type == VIRTIO_IF_TYPE_TUN) { - hw->max_supported_packet_bytes = TUN_MAX_PACKET_BYTES; - hw->min_packet_bytes = hw->min_supported_packet_bytes = - TUN_MIN_PACKET_BYTES; - hw->max_packet_bytes = - args->host_mtu_size ? args->host_mtu_size : TUN_DEFAULT_PACKET_BYTES; - vnet_sw_interface_set_mtu (vnm, hw->sw_if_index, hw->max_packet_bytes); + hw->min_frame_size = TUN_MIN_PACKET_BYTES; + vnet_hw_interface_set_mtu ( + vnm, hw->sw_if_index, + args->host_mtu_size ? args->host_mtu_size : TUN_DEFAULT_PACKET_BYTES); } vnet_hw_if_change_caps (vnm, vif->hw_if_index, &cc); diff --git a/src/vnet/ethernet/ethernet.h b/src/vnet/ethernet/ethernet.h index b6adeb6f44d..858400d08d8 100644 --- a/src/vnet/ethernet/ethernet.h +++ b/src/vnet/ethernet/ethernet.h @@ -133,8 +133,8 @@ typedef struct /* ethernet interface flags change */ ethernet_flag_change_function_t *flag_change; - /* set MTU callback */ - vnet_interface_set_mtu_function_t *set_mtu; + /* set Max Frame Size callback */ + vnet_interface_set_max_frame_size_function_t *set_max_frame_size; } vnet_eth_if_callbacks_t; #define ETHERNET_MIN_PACKET_BYTES 64 @@ -576,6 +576,8 @@ typedef struct { u32 dev_class_index; u32 dev_instance; + u16 max_frame_size; + u16 frame_overhead; vnet_eth_if_callbacks_t cb; const u8 *address; } vnet_eth_interface_registration_t; diff --git a/src/vnet/ethernet/interface.c b/src/vnet/ethernet/interface.c index bac882228cb..a0ad7989867 100644 --- a/src/vnet/ethernet/interface.c +++ b/src/vnet/ethernet/interface.c @@ -311,15 +311,18 @@ ethernet_mac_change (vnet_hw_interface_t * hi, } static clib_error_t * -ethernet_set_mtu (vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 mtu) +ethernet_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hi, + u32 frame_size) { ethernet_interface_t *ei = pool_elt_at_index (ethernet_main.interfaces, hi->hw_instance); - if (ei->cb.set_mtu) - return ei->cb.set_mtu (vnm, hi, mtu); + if (ei->cb.set_max_frame_size) + return ei->cb.set_max_frame_size (vnm, hi, frame_size); - return 0; + return vnet_error ( + VNET_ERR_UNSUPPORTED, + "underlying driver doesn't support changing Max Frame Size"); } /* *INDENT-OFF* */ @@ -333,7 +336,7 @@ VNET_HW_INTERFACE_CLASS (ethernet_hw_interface_class) = { .build_rewrite = ethernet_build_rewrite, .update_adjacency = ethernet_update_adjacency, .mac_addr_change_function = ethernet_mac_change, - .set_mtu = ethernet_set_mtu, + .set_max_frame_size = ethernet_set_max_frame_size, }; /* *INDENT-ON* */ @@ -378,10 +381,15 @@ vnet_eth_register_interface (vnet_main_t *vnm, ethernet_setup_node (vnm->vlib_main, hi->output_node_index); - hi->min_packet_bytes = hi->min_supported_packet_bytes = - ETHERNET_MIN_PACKET_BYTES; - hi->max_supported_packet_bytes = ETHERNET_MAX_PACKET_BYTES; - hi->max_packet_bytes = em->default_mtu; + hi->min_frame_size = ETHERNET_MIN_PACKET_BYTES; + hi->frame_overhead = + r->frame_overhead ? + r->max_frame_size : + sizeof (ethernet_header_t) + 2 * sizeof (ethernet_vlan_header_t); + hi->max_frame_size = r->max_frame_size ? + r->max_frame_size : + ethernet_main.default_mtu + hi->frame_overhead; + ; /* Default ethernet MTU, 9000 unless set by ethernet_config see below */ vnet_sw_interface_set_mtu (vnm, hi->sw_if_index, em->default_mtu); diff --git a/src/vnet/gre/interface.c b/src/vnet/gre/interface.c index bc78c605068..bb0be865664 100644 --- a/src/vnet/gre/interface.c +++ b/src/vnet/gre/interface.c @@ -447,13 +447,13 @@ vnet_gre_tunnel_add (vnet_gre_tunnel_add_del_args_t * a, if (!is_ipv6) { - hi->min_packet_bytes = - 64 + sizeof (gre_header_t) + sizeof (ip4_header_t); + hi->frame_overhead = sizeof (gre_header_t) + sizeof (ip4_header_t); + hi->min_frame_size = hi->frame_overhead + 64; } else { - hi->min_packet_bytes = - 64 + sizeof (gre_header_t) + sizeof (ip6_header_t); + hi->frame_overhead = sizeof (gre_header_t) + sizeof (ip6_header_t); + hi->min_frame_size = hi->frame_overhead + 64; } /* Standard default gre MTU. */ diff --git a/src/vnet/interface.c b/src/vnet/interface.c index a1493c66c23..412c6755ea8 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -769,30 +769,41 @@ sw_interface_walk_callback (vnet_main_t * vnm, u32 sw_if_index, void *ctx) } clib_error_t * -vnet_hw_interface_set_mtu (vnet_main_t *vnm, u32 hw_if_index, u32 mtu) +vnet_hw_interface_set_max_frame_size (vnet_main_t *vnm, u32 hw_if_index, + u32 fs) { vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); vnet_hw_interface_class_t *hw_if_class = vnet_get_hw_interface_class (vnm, hi->hw_class_index); clib_error_t *err = 0; - if (hi->max_packet_bytes != mtu) + log_debug ("set_max_frame_size: interface %s, max_frame_size %u -> %u", + hi->name, hi->max_frame_size, fs); + + if (hw_if_class->set_max_frame_size == 0) + return vnet_error (VNET_ERR_UNSUPPORTED, + "hw class doesn't support changing Max Frame Size"); + + if (hi->max_frame_size != fs) { - if (mtu > hi->max_supported_packet_bytes || - mtu < hi->min_supported_packet_bytes) - return vnet_error (VNET_ERR_INVALID_VALUE, - "requested mtu must be in the %u to %u range", - hi->min_supported_packet_bytes, - hi->max_supported_packet_bytes); - if (hw_if_class->set_mtu) - if ((err = hw_if_class->set_mtu (vnm, hi, mtu))) + u32 mtu; + if (hw_if_class->set_max_frame_size) + if ((err = hw_if_class->set_max_frame_size (vnm, hi, fs))) return err; - hi->max_packet_bytes = mtu; + hi->max_frame_size = fs; + mtu = fs - hi->frame_overhead; vnet_hw_interface_walk_sw (vnm, hw_if_index, sw_interface_walk_callback, &mtu); } return 0; } +clib_error_t * +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); + return vnet_hw_interface_set_max_frame_size (vnm, hw_if_index, + mtu + hi->frame_overhead); +} static void setup_tx_node (vlib_main_t * vm, @@ -910,7 +921,6 @@ vnet_register_interface (vnet_main_t * vnm, hw->hw_instance = hw_instance; hw->max_rate_bits_per_sec = 0; - hw->min_packet_bytes = 0; vnet_sw_interface_set_mtu (vnm, hw->sw_if_index, 0); if (dev_class->tx_function == 0 && dev_class->tx_fn_registrations == 0) diff --git a/src/vnet/interface.h b/src/vnet/interface.h index 2eb50aed5e8..c8fbc61ec7b 100644 --- a/src/vnet/interface.h +++ b/src/vnet/interface.h @@ -71,7 +71,7 @@ typedef clib_error_t *(vnet_subif_add_del_function_t) struct vnet_sw_interface_t * template, int is_add); /* Interface set mtu callback. */ -typedef clib_error_t *(vnet_interface_set_mtu_function_t) ( +typedef clib_error_t *(vnet_interface_set_max_frame_size_function_t) ( struct vnet_main_t *vnm, struct vnet_hw_interface_t *hi, u32 mtu); /* Interface set mac address callback. */ @@ -432,8 +432,9 @@ typedef struct _vnet_hw_interface_class /* Function to add/delete additional MAC addresses */ vnet_interface_add_del_mac_address_function_t *mac_addr_add_del_function; - /* Function to set mtu. */ - vnet_interface_set_mtu_function_t *set_mtu; + + /* Function to set max frame size. */ + vnet_interface_set_max_frame_size_function_t *set_max_frame_size; /* Format function to display interface name. */ format_function_t *format_interface_name; @@ -701,17 +702,14 @@ typedef struct vnet_hw_interface_t /* Maximum transmit rate for this interface in bits/sec. */ f64 max_rate_bits_per_sec; - /* Smallest packet size supported by this interface. */ - u32 min_supported_packet_bytes; - - /* Largest packet size supported by this interface. */ - u32 max_supported_packet_bytes; - /* Smallest packet size for this interface. */ - u32 min_packet_bytes; + u32 min_frame_size; + + /* Largest frame size for this interface. */ + u32 max_frame_size; - /* Largest packet size for this interface. */ - u32 max_packet_bytes; + /* Layer 2 overhead */ + u16 frame_overhead; /* Hash table mapping sub interface id to sw_if_index. */ uword *sub_interface_sw_if_index_by_id; diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c index d70cd1e42f8..938f3bb327e 100644 --- a/src/vnet/interface_api.c +++ b/src/vnet/interface_api.c @@ -258,7 +258,7 @@ send_sw_interface_details (vpe_api_main_t * am, mp->link_duplex = ntohl (((hi->flags & VNET_HW_INTERFACE_FLAG_DUPLEX_MASK) >> VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT)); mp->link_speed = ntohl (hi->link_speed); - mp->link_mtu = ntohs (hi->max_packet_bytes); + mp->link_mtu = ntohs (hi->max_frame_size - hi->frame_overhead); mp->mtu[VNET_MTU_L3] = ntohl (swif->mtu[VNET_MTU_L3]); mp->mtu[VNET_MTU_IP4] = ntohl (swif->mtu[VNET_MTU_IP4]); mp->mtu[VNET_MTU_IP6] = ntohl (swif->mtu[VNET_MTU_IP6]); diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c index 740a8af78ec..b6d38578714 100644 --- a/src/vnet/interface_cli.c +++ b/src/vnet/interface_cli.c @@ -1167,21 +1167,11 @@ mtu_cmd (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) * Change physical MTU on interface. Only supported for Ethernet * interfaces */ - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); ethernet_interface_t *eif = ethernet_get_interface (em, hw_if_index); if (!eif) return clib_error_return (0, "not supported"); - if (mtu < hi->min_supported_packet_bytes) - return clib_error_return (0, "Invalid mtu (%d): " - "must be >= min pkt bytes (%d)", mtu, - hi->min_supported_packet_bytes); - - if (mtu > hi->max_supported_packet_bytes) - return clib_error_return (0, "Invalid mtu (%d): must be <= (%d)", mtu, - hi->max_supported_packet_bytes); - err = vnet_hw_interface_set_mtu (vnm, hw_if_index, mtu); if (err) return err; diff --git a/src/vnet/interface_funcs.h b/src/vnet/interface_funcs.h index 57e0d33b406..5434542cd7c 100644 --- a/src/vnet/interface_funcs.h +++ b/src/vnet/interface_funcs.h @@ -310,7 +310,7 @@ always_inline u32 vnet_hw_interface_get_mtu (vnet_main_t * vnm, u32 hw_if_index) { vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index); - return hw->max_packet_bytes; + return hw->max_frame_size - hw->frame_overhead; } always_inline u32 @@ -430,6 +430,10 @@ clib_error_t *set_hw_interface_rx_placement (u32 hw_if_index, u32 queue_id, /* Set tx-queue placement on the interface */ int set_hw_interface_tx_queue (u32 hw_if_index, u32 queue_id, uword *bitmap); +/* Set the Max Frame Size on the HW interface */ +clib_error_t *vnet_hw_interface_set_max_frame_size (vnet_main_t *vnm, + u32 hw_if_index, + u32 max_frame_size); /* Set the MTU on the HW interface */ clib_error_t *vnet_hw_interface_set_mtu (vnet_main_t *vnm, u32 hw_if_index, u32 mtu); diff --git a/src/vnet/ipip/ipip.c b/src/vnet/ipip/ipip.c index 2ac234eb7ca..600f5421125 100644 --- a/src/vnet/ipip/ipip.c +++ b/src/vnet/ipip/ipip.c @@ -782,13 +782,11 @@ ipip_add_tunnel (ipip_transport_t transport, gm->tunnel_index_by_sw_if_index[sw_if_index] = t_idx; if (t->transport == IPIP_TRANSPORT_IP4) - { - hi->min_packet_bytes = 64 + sizeof (ip4_header_t); - } + hi->frame_overhead = sizeof (ip4_header_t); else - { - hi->min_packet_bytes = 64 + sizeof (ip6_header_t); - } + hi->frame_overhead = sizeof (ip6_header_t); + + hi->min_frame_size = hi->frame_overhead + 64; /* Standard default ipip MTU. */ vnet_sw_interface_set_mtu (vnm, sw_if_index, 9000); |