From f0b3966a5072bd0a6c7f7e8652aef793afa4f4d0 Mon Sep 17 00:00:00 2001 From: Huisong Li Date: Wed, 6 Apr 2022 16:45:37 +0800 Subject: [PATCH] app/testpmd: fix MTU verification The macro RTE_ETHER_MIN_LEN isn't the minimum value of MTU. But testpmd used it when execute 'port config mtu 0 xx' cmd. This patch fixes it. Fixes: 1bb4a528c41f ("ethdev: fix max Rx packet length") Cc: stable@dpdk.org Signed-off-by: Huisong Li Signed-off-by: Min Hu (Connor) Acked-by: Ferruh Yigit --- app/test-pmd/cmdline.c | 4 --- app/test-pmd/config.c | 55 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 6ffea8e21a..91e4090582 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -2050,10 +2050,6 @@ cmd_config_mtu_parsed(void *parsed_result, { struct cmd_config_mtu_result *res = parsed_result; - if (res->value < RTE_ETHER_MIN_LEN) { - fprintf(stderr, "mtu cannot be less than %d\n", RTE_ETHER_MIN_LEN); - return; - } port_mtu_set(res->port_id, res->value); } diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index bd689f9f86..1b1e738f83 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1254,6 +1254,57 @@ port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t reg_v) display_port_reg_value(port_id, reg_off, reg_v); } +static uint32_t +eth_dev_get_overhead_len(uint32_t max_rx_pktlen, uint16_t max_mtu) +{ + uint32_t overhead_len; + + if (max_mtu != UINT16_MAX && max_rx_pktlen > max_mtu) + overhead_len = max_rx_pktlen - max_mtu; + else + overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; + + return overhead_len; +} + +static int +eth_dev_validate_mtu(uint16_t port_id, uint16_t mtu) +{ + struct rte_eth_dev_info dev_info; + uint32_t overhead_len; + uint32_t frame_size; + int ret; + + ret = rte_eth_dev_info_get(port_id, &dev_info); + if (ret != 0) + return ret; + + if (mtu < dev_info.min_mtu) { + fprintf(stderr, + "MTU (%u) < device min MTU (%u) for port_id %u\n", + mtu, dev_info.min_mtu, port_id); + return -EINVAL; + } + if (mtu > dev_info.max_mtu) { + fprintf(stderr, + "MTU (%u) > device max MTU (%u) for port_id %u\n", + mtu, dev_info.max_mtu, port_id); + return -EINVAL; + } + + overhead_len = eth_dev_get_overhead_len(dev_info.max_rx_pktlen, + dev_info.max_mtu); + frame_size = mtu + overhead_len; + if (frame_size > dev_info.max_rx_pktlen) { + fprintf(stderr, + "Frame size (%u) > device max frame size (%u) for port_id %u\n", + frame_size, dev_info.max_rx_pktlen, port_id); + return -EINVAL; + } + + return 0; +} + void port_mtu_set(portid_t port_id, uint16_t mtu) { @@ -1263,6 +1314,10 @@ port_mtu_set(portid_t port_id, uint16_t mtu) if (port_id_is_invalid(port_id, ENABLED_WARN)) return; + diag = eth_dev_validate_mtu(port_id, mtu); + if (diag != 0) + return; + if (port->need_reconfig == 0) { diag = rte_eth_dev_set_mtu(port_id, mtu); if (diag != 0) { -- 2.39.5