[dpdk-dev] [v3] net/i40e: fix vlan packets drop

Kevin Traynor ktraynor at redhat.com
Fri Nov 8 20:28:47 CET 2019


Hi Xiao,

On 29/10/2019 05:12, Xiao Zhang wrote:
> VLAN packets with ip length bigger than 1496 will not be received by
> i40e/i40evf due to wrong packets size checking. This patch fixes the
> issue by correcting the maximum frame size during checking.
> 
> Fixes: 43e5488c0ac6 ("net/i40e: support MTU configuration")
> Cc: stable at dpdk.org
> 
> Signed-off-by: Xiao Zhang <xiao.zhang at intel.com>
> ---
> v3
> Checking more places using max packet len.
> v2
> Add fix for i40evf and correct the checking when using the max_pkt_len.
> ---
>  drivers/net/i40e/i40e_ethdev.c    |  2 +-
>  drivers/net/i40e/i40e_ethdev_vf.c | 11 +++++++----
>  drivers/net/i40e/i40e_fdir.c      |  2 +-
>  drivers/net/i40e/i40e_rxtx.c      |  9 ++++++---
>  lib/librte_ethdev/rte_ethdev.c    | 10 ++++++++--
>  lib/librte_net/rte_ether.h        |  1 +
>  6 files changed, 24 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 77a4683..b0e23c7 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -12105,7 +12105,7 @@ i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
>  		return -EBUSY;
>  	}
>  
> -	if (frame_size > RTE_ETHER_MAX_LEN)
> +	if (frame_size > RTE_ETHER_MAX_LEN + I40E_VLAN_TAG_SIZE * 2)
>  		dev_data->dev_conf.rxmode.offloads |=
>  			DEV_RX_OFFLOAD_JUMBO_FRAME;
>  	else
> diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
> index 5dba092..1e0b50f 100644
> --- a/drivers/net/i40e/i40e_ethdev_vf.c
> +++ b/drivers/net/i40e/i40e_ethdev_vf.c
> @@ -1772,7 +1772,8 @@ i40evf_rxq_init(struct rte_eth_dev *dev, struct i40e_rx_queue *rxq)
>  	 * Check if the jumbo frame and maximum packet length are set correctly
>  	 */
>  	if (dev_data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
> -		if (rxq->max_pkt_len <= RTE_ETHER_MAX_LEN ||
> +		if (rxq->max_pkt_len <= RTE_ETHER_MAX_LEN +
> +				I40E_VLAN_TAG_SIZE * 2 ||
>  		    rxq->max_pkt_len > I40E_FRAME_SIZE_MAX) {
>  			PMD_DRV_LOG(ERR, "maximum packet length must be "
>  				"larger than %u and smaller than %u, as jumbo "

The log needs to be match the check

> @@ -1782,12 +1783,14 @@ i40evf_rxq_init(struct rte_eth_dev *dev, struct i40e_rx_queue *rxq)
>  		}
>  	} else {
>  		if (rxq->max_pkt_len < RTE_ETHER_MIN_LEN ||
> -		    rxq->max_pkt_len > RTE_ETHER_MAX_LEN) {
> +		    rxq->max_pkt_len > RTE_ETHER_MAX_LEN +
> +				I40E_VLAN_TAG_SIZE * 2) {
>  			PMD_DRV_LOG(ERR, "maximum packet length must be "
>  				"larger than %u and smaller than %u, as jumbo "
>  				"frame is disabled",
>  				(uint32_t)RTE_ETHER_MIN_LEN,
> -				(uint32_t)RTE_ETHER_MAX_LEN);
> +				(uint32_t)RTE_ETHER_MAX_LEN +
> +					I40E_VLAN_TAG_SIZE * 2);
>  			return I40E_ERR_CONFIG;
>  		}
>  	}
> @@ -2747,7 +2750,7 @@ i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
>  		return -EBUSY;
>  	}
>  
> -	if (frame_size > RTE_ETHER_MAX_LEN)
> +	if (frame_size > RTE_ETHER_MAX_LEN + I40E_VLAN_TAG_SIZE * 2)
>  		dev_data->dev_conf.rxmode.offloads |=
>  			DEV_RX_OFFLOAD_JUMBO_FRAME;
>  	else
> diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
> index dee007d..8b813cb 100644
> --- a/drivers/net/i40e/i40e_fdir.c
> +++ b/drivers/net/i40e/i40e_fdir.c
> @@ -113,7 +113,7 @@ i40e_fdir_rx_queue_init(struct i40e_rx_queue *rxq)
>  #endif
>  	rx_ctx.dtype = i40e_header_split_none;
>  	rx_ctx.hsplit_0 = I40E_HEADER_SPLIT_NONE;
> -	rx_ctx.rxmax = RTE_ETHER_MAX_LEN;
> +	rx_ctx.rxmax = RTE_ETHER_MAX_LEN + I40E_VLAN_TAG_SIZE * 2;
>  	rx_ctx.tphrdesc_ena = 1;
>  	rx_ctx.tphwdesc_ena = 1;
>  	rx_ctx.tphdata_ena = 1;
> diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
> index 6a66cec..a93b11f 100644
> --- a/drivers/net/i40e/i40e_rxtx.c
> +++ b/drivers/net/i40e/i40e_rxtx.c
> @@ -2617,7 +2617,8 @@ i40e_rx_queue_config(struct i40e_rx_queue *rxq)
>  		RTE_MIN((uint32_t)(hw->func_caps.rx_buf_chain_len *
>  			rxq->rx_buf_len), data->dev_conf.rxmode.max_rx_pkt_len);
>  	if (data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
> -		if (rxq->max_pkt_len <= RTE_ETHER_MAX_LEN ||
> +		if (rxq->max_pkt_len <= RTE_ETHER_MAX_LEN +
> +				I40E_VLAN_TAG_SIZE * 2 ||
>  			rxq->max_pkt_len > I40E_FRAME_SIZE_MAX) {
>  			PMD_DRV_LOG(ERR, "maximum packet length must "
>  				    "be larger than %u and smaller than %u,"

The log needs to be match the check

> @@ -2628,12 +2629,14 @@ i40e_rx_queue_config(struct i40e_rx_queue *rxq)
>  		}
>  	} else {
>  		if (rxq->max_pkt_len < RTE_ETHER_MIN_LEN ||
> -			rxq->max_pkt_len > RTE_ETHER_MAX_LEN) {
> +			rxq->max_pkt_len > RTE_ETHER_MAX_LEN +
> +				I40E_VLAN_TAG_SIZE * 2) {
>  			PMD_DRV_LOG(ERR, "maximum packet length must be "
>  				    "larger than %u and smaller than %u, "
>  				    "as jumbo frame is disabled",
>  				    (uint32_t)RTE_ETHER_MIN_LEN,
> -				    (uint32_t)RTE_ETHER_MAX_LEN);
> +				    (uint32_t)RTE_ETHER_MAX_LEN +
> +						I40E_VLAN_TAG_SIZE * 2);
>  			return I40E_ERR_CONFIG;
>  		}
>  	}
> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
> index 7743205..f6722be 100644
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> @@ -1257,11 +1257,17 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>  			goto rollback;
>  		}
>  	} else {
> +		/**
> +		 * The overhead from MTU to max frame size.
> +		 * Considering VLAN and QinQ packet, the VLAN tag size
> +		 * needs to be added to RTE_ETHER_MAX_LEN.
> +		 */
>  		if (dev_conf->rxmode.max_rx_pkt_len < RTE_ETHER_MIN_LEN ||
> -			dev_conf->rxmode.max_rx_pkt_len > RTE_ETHER_MAX_LEN)
> +			dev_conf->rxmode.max_rx_pkt_len > RTE_ETHER_MAX_LEN
> +				+ RTE_ETHER_VLAN_LEN * 2)
>  			/* Use default value */
>  			dev->data->dev_conf.rxmode.max_rx_pkt_len =
> -							RTE_ETHER_MAX_LEN;
> +				RTE_ETHER_MAX_LEN + RTE_ETHER_VLAN_LEN * 2;

+cc ethdev maintainers

This looks ok to me for i40e case, but I don't know if there is a
consequence for other PMDs. It seems late to change this, so maybe you
can live without this part for now.

Even on the i40e parts, there can be some subtle bug and I requested
i40e maintainers to review carefully but it has not happened, so for me
it shouldn't be merged at present.

>  	}
>  
>  	/* Any requested offloading must be within its device capabilities */
> diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> index e069dc7..9c5eee7 100644
> --- a/lib/librte_net/rte_ether.h
> +++ b/lib/librte_net/rte_ether.h
> @@ -26,6 +26,7 @@ extern "C" {
>  #define RTE_ETHER_ADDR_LEN  6 /**< Length of Ethernet address. */
>  #define RTE_ETHER_TYPE_LEN  2 /**< Length of Ethernet type field. */
>  #define RTE_ETHER_CRC_LEN   4 /**< Length of Ethernet CRC. */
> +#define RTE_ETHER_VLAN_LEN  4 /**< Length of Ethernet VLAN tag. */
>  #define RTE_ETHER_HDR_LEN   \
>  	(RTE_ETHER_ADDR_LEN * 2 + \
>  		RTE_ETHER_TYPE_LEN) /**< Length of Ethernet header. */
> 



More information about the dev mailing list