From 2928ea4fedd0902a8f85af2aceca90e24c116759 Mon Sep 17 00:00:00 2001 From: Huisong Li Date: Fri, 19 May 2023 17:31:55 +0800 Subject: [PATCH] ethdev: fix MAC address occupies two entries [ upstream commit 8f02f472a29432650d999969359d6a49ea6aadca ] The dev->data->mac_addrs[0] will be changed to a new MAC address when applications modify the default MAC address by .mac_addr_set(). However, if the new default one has been added as a non-default MAC address by .mac_addr_add(), the .mac_addr_set() didn't check this address. As a result, this MAC address occupies two entries in the list. Like: add(MAC1) add(MAC2) add(MAC3) add(MAC4) set_default(MAC3) default=MAC3, the rest of the list=MAC1, MAC2, MAC3, MAC4 Note: MAC3 occupies two entries. But .mac_addr_set() cannot remove it implicitly in case of MAC address shrinking in the list. So this patch adds a check on whether the new default address was already in the list and if so requires the user to remove it first. In addition, this patch documents the position of the default MAC address and address unique in the list. Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") Signed-off-by: Huisong Li Acked-by: Chengwen Feng Acked-by: Thomas Monjalon Reviewed-by: Ferruh Yigit --- lib/librte_ethdev/rte_ethdev.c | 10 ++++++++++ lib/librte_ethdev/rte_ethdev.h | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index 4b59854c12..b5c5af3cf5 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -4150,6 +4150,7 @@ int rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) { struct rte_eth_dev *dev; + int index; int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); @@ -4160,6 +4161,15 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) dev = &rte_eth_devices[port_id]; RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP); + /* Keep address unique in dev->data->mac_addrs[]. */ + index = eth_dev_get_mac_addr_index(port_id, addr); + if (index > 0) { + RTE_ETHDEV_LOG(ERR, + "New default address for port %u was already in the address list. Please remove it first.\n", + port_id); + return -EEXIST; + } + ret = (*dev->dev_ops->mac_addr_set)(dev, addr); if (ret < 0) return ret; diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h index 5e8331da1c..709563215f 100644 --- a/lib/librte_ethdev/rte_ethdev.h +++ b/lib/librte_ethdev/rte_ethdev.h @@ -3840,6 +3840,9 @@ int rte_eth_dev_mac_addr_remove(uint16_t port_id, /** * Set the default MAC address. + * It replaces the address at index 0 of the MAC address list. + * If the address was already in the MAC address list, + * please remove it first. * * @param port_id * The port identifier of the Ethernet device. @@ -3850,6 +3853,7 @@ int rte_eth_dev_mac_addr_remove(uint16_t port_id, * - (-ENOTSUP) if hardware doesn't support. * - (-ENODEV) if *port* invalid. * - (-EINVAL) if MAC address is invalid. + * - (-EEXIST) if MAC address was already in the address list. */ int rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *mac_addr);