From: Huisong Li <lihuisong@huawei.com> Use the testpmd to perform the following operations: 1) mac_addr add 0 00:18:2D:00:00:90 2) mac_addr add 0 00:18:2D:00:00:91 3) mac_addr add 0 00:18:2D:00:00:92 4) mac_addr set 0 00:18:2D:00:00:91 5) show port 0 macs Number of MAC address added: 4 00:18:2D:00:00:91 00:18:2D:00:00:90 00:18:2D:00:00:91 00:18:2D:00:00:92 This is due to the reason that if the address has been added as a non-default MAC address by rte_eth_dev_mac_addr_add API, it doesn't remove from dev->data->mac_addrs[] when set default MAC address with the same address. Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") Cc: stable@dpdk.org Signed-off-by: Huisong Li <lihuisong@huawei.com> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> --- lib/ethdev/rte_ethdev.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index daf5ca9242..77657a3314 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -4360,6 +4360,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); @@ -4381,6 +4382,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) if (ret < 0) return ret; + /* + * If the address has been added as a non-default MAC address by + * rte_eth_dev_mac_addr_add API, it should be removed from + * dev->data->mac_addrs[]. + */ + index = eth_dev_get_mac_addr_index(port_id, addr); + if (index > 0) { + /* remove address in NIC data structure */ + rte_ether_addr_copy(&null_mac_addr, + &dev->data->mac_addrs[index]); + /* reset pool bitmap */ + dev->data->mac_pool_sel[index] = 0; + } + /* Update default address in NIC data structure */ rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); -- 2.33.0
On 9/22/21 6:36 AM, Min Hu (Connor) wrote:
> From: Huisong Li <lihuisong@huawei.com>
>
> Use the testpmd to perform the following operations:
> 1) mac_addr add 0 00:18:2D:00:00:90
> 2) mac_addr add 0 00:18:2D:00:00:91
> 3) mac_addr add 0 00:18:2D:00:00:92
> 4) mac_addr set 0 00:18:2D:00:00:91
> 5) show port 0 macs
> Number of MAC address added: 4
> 00:18:2D:00:00:91
> 00:18:2D:00:00:90
> 00:18:2D:00:00:91
> 00:18:2D:00:00:92
>
> This is due to the reason that if the address has been added as a
> non-default MAC address by rte_eth_dev_mac_addr_add API, it doesn't remove
> from dev->data->mac_addrs[] when set default MAC address with the same
> address.
>
> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
> Cc: stable@dpdk.org
>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index daf5ca9242..77657a3314 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -4360,6 +4360,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);
> @@ -4381,6 +4382,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
> if (ret < 0)
> return ret;
>
> + /*
> + * If the address has been added as a non-default MAC address by
> + * rte_eth_dev_mac_addr_add API, it should be removed from
> + * dev->data->mac_addrs[].
> + */
> + index = eth_dev_get_mac_addr_index(port_id, addr);
> + if (index > 0) {
> + /* remove address in NIC data structure */
> + rte_ether_addr_copy(&null_mac_addr,
> + &dev->data->mac_addrs[index]);
> + /* reset pool bitmap */
> + dev->data->mac_pool_sel[index] = 0;
> + }
> +
> /* Update default address in NIC data structure */
> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
>
>
If I change default MAC to something else later, should the old
default MAC be returned to some specific pools? I guess it is
hard to do. If the change is accepted, the behaviour must be
documented in rte_eth_dev_default_mac_addr_set() description.
在 2021/9/22 14:39, Andrew Rybchenko 写道: > On 9/22/21 6:36 AM, Min Hu (Connor) wrote: >> From: Huisong Li <lihuisong@huawei.com> >> >> Use the testpmd to perform the following operations: >> 1) mac_addr add 0 00:18:2D:00:00:90 >> 2) mac_addr add 0 00:18:2D:00:00:91 >> 3) mac_addr add 0 00:18:2D:00:00:92 >> 4) mac_addr set 0 00:18:2D:00:00:91 >> 5) show port 0 macs >> Number of MAC address added: 4 >> 00:18:2D:00:00:91 >> 00:18:2D:00:00:90 >> 00:18:2D:00:00:91 >> 00:18:2D:00:00:92 >> >> This is due to the reason that if the address has been added as a >> non-default MAC address by rte_eth_dev_mac_addr_add API, it doesn't remove >> from dev->data->mac_addrs[] when set default MAC address with the same >> address. >> >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >> Cc: stable@dpdk.org >> >> Signed-off-by: Huisong Li <lihuisong@huawei.com> >> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> >> --- >> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++ >> 1 file changed, 15 insertions(+) >> >> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >> index daf5ca9242..77657a3314 100644 >> --- a/lib/ethdev/rte_ethdev.c >> +++ b/lib/ethdev/rte_ethdev.c >> @@ -4360,6 +4360,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); >> @@ -4381,6 +4382,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) >> if (ret < 0) >> return ret; >> >> + /* >> + * If the address has been added as a non-default MAC address by >> + * rte_eth_dev_mac_addr_add API, it should be removed from >> + * dev->data->mac_addrs[]. >> + */ >> + index = eth_dev_get_mac_addr_index(port_id, addr); >> + if (index > 0) { >> + /* remove address in NIC data structure */ >> + rte_ether_addr_copy(&null_mac_addr, >> + &dev->data->mac_addrs[index]); >> + /* reset pool bitmap */ >> + dev->data->mac_pool_sel[index] = 0; >> + } >> + >> /* Update default address in NIC data structure */ >> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >> >> > If I change default MAC to something else later, should the old > default MAC be returned to some specific pools? I guess it is Since the old default MAC address is invalid, which has been removed from hardware. This MAC address does not need to be added to some specific pools, and occupies one position in mac addrs. > hard to do. If the change is accepted, the behaviour must be > documented in rte_eth_dev_default_mac_addr_set() description. > . I think it's not necessary. Because old default MAC is no longer valid if we modify default MAC with a new MAC address. This is a definition of rte_eth_dev_default_mac_addr_set(). The current modification does not change the definition of the interface.
On 9/22/21 10:43 AM, Huisong Li wrote:
>
> 在 2021/9/22 14:39, Andrew Rybchenko 写道:
>> On 9/22/21 6:36 AM, Min Hu (Connor) wrote:
>>> From: Huisong Li <lihuisong@huawei.com>
>>>
>>> Use the testpmd to perform the following operations:
>>> 1) mac_addr add 0 00:18:2D:00:00:90
>>> 2) mac_addr add 0 00:18:2D:00:00:91
>>> 3) mac_addr add 0 00:18:2D:00:00:92
>>> 4) mac_addr set 0 00:18:2D:00:00:91
>>> 5) show port 0 macs
>>> Number of MAC address added: 4
>>> 00:18:2D:00:00:91
>>> 00:18:2D:00:00:90
>>> 00:18:2D:00:00:91
>>> 00:18:2D:00:00:92
>>>
>>> This is due to the reason that if the address has been added as a
>>> non-default MAC address by rte_eth_dev_mac_addr_add API, it doesn't
>>> remove
>>> from dev->data->mac_addrs[] when set default MAC address with the same
>>> address.
>>>
>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
>>> Cc: stable@dpdk.org
>>>
>>> Signed-off-by: Huisong Li <lihuisong@huawei.com>
>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>> ---
>>> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++
>>> 1 file changed, 15 insertions(+)
>>>
>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>>> index daf5ca9242..77657a3314 100644
>>> --- a/lib/ethdev/rte_ethdev.c
>>> +++ b/lib/ethdev/rte_ethdev.c
>>> @@ -4360,6 +4360,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);
>>> @@ -4381,6 +4382,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t
>>> port_id, struct rte_ether_addr *addr)
>>> if (ret < 0)
>>> return ret;
>>> + /*
>>> + * If the address has been added as a non-default MAC address by
>>> + * rte_eth_dev_mac_addr_add API, it should be removed from
>>> + * dev->data->mac_addrs[].
>>> + */
>>> + index = eth_dev_get_mac_addr_index(port_id, addr);
>>> + if (index > 0) {
>>> + /* remove address in NIC data structure */
>>> + rte_ether_addr_copy(&null_mac_addr,
>>> + &dev->data->mac_addrs[index]);
>>> + /* reset pool bitmap */
>>> + dev->data->mac_pool_sel[index] = 0;
>>> + }
>>> +
>>> /* Update default address in NIC data structure */
>>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
>>>
>> If I change default MAC to something else later, should the old
>> default MAC be returned to some specific pools? I guess it is
>
> Since the old default MAC address is invalid, which has been removed
> from hardware.
>
> This MAC address does not need to be added to some specific pools, and
> occupies
>
> one position in mac addrs.
>
>> hard to do. If the change is accepted, the behaviour must be
>> documented in rte_eth_dev_default_mac_addr_set() description.
>> .
>
> I think it's not necessary. Because old default MAC is no longer valid
> if we modify
>
> default MAC with a new MAC address. This is a definition of
> rte_eth_dev_default_mac_addr_set().
>
> The current modification does not change the definition of the interface.
Not sure that I understand:
set default MAC-A
add MAC-B to pool 1
set default MAC-B
set default MAC-C
since I've not removed MAC-B from pool 1, I'd expect it to be
there.
在 2021/9/22 16:02, Andrew Rybchenko 写道:
> On 9/22/21 10:43 AM, Huisong Li wrote:
>> 在 2021/9/22 14:39, Andrew Rybchenko 写道:
>>> On 9/22/21 6:36 AM, Min Hu (Connor) wrote:
>>>> From: Huisong Li <lihuisong@huawei.com>
>>>>
>>>> Use the testpmd to perform the following operations:
>>>> 1) mac_addr add 0 00:18:2D:00:00:90
>>>> 2) mac_addr add 0 00:18:2D:00:00:91
>>>> 3) mac_addr add 0 00:18:2D:00:00:92
>>>> 4) mac_addr set 0 00:18:2D:00:00:91
>>>> 5) show port 0 macs
>>>> Number of MAC address added: 4
>>>> 00:18:2D:00:00:91
>>>> 00:18:2D:00:00:90
>>>> 00:18:2D:00:00:91
>>>> 00:18:2D:00:00:92
>>>>
>>>> This is due to the reason that if the address has been added as a
>>>> non-default MAC address by rte_eth_dev_mac_addr_add API, it doesn't
>>>> remove
>>>> from dev->data->mac_addrs[] when set default MAC address with the same
>>>> address.
>>>>
>>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
>>>> Cc: stable@dpdk.org
>>>>
>>>> Signed-off-by: Huisong Li <lihuisong@huawei.com>
>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>>> ---
>>>> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++
>>>> 1 file changed, 15 insertions(+)
>>>>
>>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>>>> index daf5ca9242..77657a3314 100644
>>>> --- a/lib/ethdev/rte_ethdev.c
>>>> +++ b/lib/ethdev/rte_ethdev.c
>>>> @@ -4360,6 +4360,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);
>>>> @@ -4381,6 +4382,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t
>>>> port_id, struct rte_ether_addr *addr)
>>>> if (ret < 0)
>>>> return ret;
>>>> + /*
>>>> + * If the address has been added as a non-default MAC address by
>>>> + * rte_eth_dev_mac_addr_add API, it should be removed from
>>>> + * dev->data->mac_addrs[].
>>>> + */
>>>> + index = eth_dev_get_mac_addr_index(port_id, addr);
>>>> + if (index > 0) {
>>>> + /* remove address in NIC data structure */
>>>> + rte_ether_addr_copy(&null_mac_addr,
>>>> + &dev->data->mac_addrs[index]);
>>>> + /* reset pool bitmap */
>>>> + dev->data->mac_pool_sel[index] = 0;
>>>> + }
>>>> +
>>>> /* Update default address in NIC data structure */
>>>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
>>>>
>>> If I change default MAC to something else later, should the old
>>> default MAC be returned to some specific pools? I guess it is
>> Since the old default MAC address is invalid, which has been removed
>> from hardware.
>>
>> This MAC address does not need to be added to some specific pools, and
>> occupies
>>
>> one position in mac addrs.
>>
>>> hard to do. If the change is accepted, the behaviour must be
>>> documented in rte_eth_dev_default_mac_addr_set() description.
>>> .
>> I think it's not necessary. Because old default MAC is no longer valid
>> if we modify
>>
>> default MAC with a new MAC address. This is a definition of
>> rte_eth_dev_default_mac_addr_set().
>>
>> The current modification does not change the definition of the interface.
> Not sure that I understand:
>
> set default MAC-A
> add MAC-B to pool 1
> set default MAC-B
> set default MAC-C
>
> since I've not removed MAC-B from pool 1, I'd expect it to be
> there.
> .
Yes. You are right.
But MAC-B is removed from hardware after executing "set default MAC-C"
cmd, and
new default MAC-C takes effect.
View from interface rte_eth_dev_mac_addr_remove(), if one MAC address is
removed,
the API removes the MAC from dev->data->mac_addrs[] and reset
"mac_pool_sel"(that is,
all pools do not have the MAC address.).
This also means that above MAC-B should not exist in any of the pools and
in dev->data->mac_addrs[] after executing "set default MAC-C" cmd.
22/09/2021 05:36, Min Hu (Connor): > From: Huisong Li <lihuisong@huawei.com> > > Use the testpmd to perform the following operations: > 1) mac_addr add 0 00:18:2D:00:00:90 > 2) mac_addr add 0 00:18:2D:00:00:91 > 3) mac_addr add 0 00:18:2D:00:00:92 > 4) mac_addr set 0 00:18:2D:00:00:91 > 5) show port 0 macs > Number of MAC address added: 4 > 00:18:2D:00:00:91 > 00:18:2D:00:00:90 > 00:18:2D:00:00:91 > 00:18:2D:00:00:92 Please describe with words. Reading similar MAC addresses is not a fun game. > This is due to the reason that if the address has been added as a > non-default MAC address by rte_eth_dev_mac_addr_add API, it doesn't remove > from dev->data->mac_addrs[] when set default MAC address with the same > address. > > Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") > Cc: stable@dpdk.org > > Signed-off-by: Huisong Li <lihuisong@huawei.com> > Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
Hi, Thomas, 在 2021/10/6 3:21, Thomas Monjalon 写道: > 22/09/2021 05:36, Min Hu (Connor): >> From: Huisong Li <lihuisong@huawei.com> >> >> Use the testpmd to perform the following operations: >> 1) mac_addr add 0 00:18:2D:00:00:90 >> 2) mac_addr add 0 00:18:2D:00:00:91 >> 3) mac_addr add 0 00:18:2D:00:00:92 >> 4) mac_addr set 0 00:18:2D:00:00:91 >> 5) show port 0 macs >> Number of MAC address added: 4 >> 00:18:2D:00:00:91 >> 00:18:2D:00:00:90 >> 00:18:2D:00:00:91 >> 00:18:2D:00:00:92 > > Please describe with words. > Reading similar MAC addresses is not a fun game. I do not catch you, could you please be more detailed, thanks. > >> This is due to the reason that if the address has been added as a >> non-default MAC address by rte_eth_dev_mac_addr_add API, it doesn't remove >> from dev->data->mac_addrs[] when set default MAC address with the same >> address. >> >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >> Cc: stable@dpdk.org >> >> Signed-off-by: Huisong Li <lihuisong@huawei.com> >> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> > > > > . >
08/10/2021 09:02, Min Hu (Connor): > Hi, Thomas, > > 在 2021/10/6 3:21, Thomas Monjalon 写道: > > 22/09/2021 05:36, Min Hu (Connor): > >> From: Huisong Li <lihuisong@huawei.com> > >> > >> Use the testpmd to perform the following operations: > >> 1) mac_addr add 0 00:18:2D:00:00:90 > >> 2) mac_addr add 0 00:18:2D:00:00:91 > >> 3) mac_addr add 0 00:18:2D:00:00:92 > >> 4) mac_addr set 0 00:18:2D:00:00:91 > >> 5) show port 0 macs > >> Number of MAC address added: 4 > >> 00:18:2D:00:00:91 > >> 00:18:2D:00:00:90 > >> 00:18:2D:00:00:91 > >> 00:18:2D:00:00:92 > > > > Please describe with words. > > Reading similar MAC addresses is not a fun game. > > I do not catch you, could you please be > more detailed, thanks. Me too, I don't catch you. Please explain the problem in the commit log so we can understand without the example. > >> This is due to the reason that if the address has been added as a > >> non-default MAC address by rte_eth_dev_mac_addr_add API, it doesn't remove > >> from dev->data->mac_addrs[] when set default MAC address with the same > >> address. > >> > >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") > >> Cc: stable@dpdk.org > >> > >> Signed-off-by: Huisong Li <lihuisong@huawei.com> > >> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
Hi, Thomas,
The dev->data->mac_addrs[0] will be changed to a new MAC address when
applications modify
the default MAC address by rte_eth_dev_default_mac_addr_set() API.
However, If the new default
MAC address has been added as a non-default MAC address by
rte_eth_dev_mac_addr_add() API, the
rte_eth_dev_default_mac_addr_set() API doesn't remove it from
dev->data->mac_addrs[].
As a result, one MAC address occupies two index capacities in
dev->data->mac_addrs[].
This patch adds the logic of removing MAC addresses for this scenario.
Is that will be more clear? Hope for your reply
在 2021/10/8 18:04, Thomas Monjalon 写道:
> 08/10/2021 09:02, Min Hu (Connor):
>> Hi, Thomas,
>>
>> 在 2021/10/6 3:21, Thomas Monjalon 写道:
>>> 22/09/2021 05:36, Min Hu (Connor):
>>>> From: Huisong Li <lihuisong@huawei.com>
>>>>
>>>> Use the testpmd to perform the following operations:
>>>> 1) mac_addr add 0 00:18:2D:00:00:90
>>>> 2) mac_addr add 0 00:18:2D:00:00:91
>>>> 3) mac_addr add 0 00:18:2D:00:00:92
>>>> 4) mac_addr set 0 00:18:2D:00:00:91
>>>> 5) show port 0 macs
>>>> Number of MAC address added: 4
>>>> 00:18:2D:00:00:91
>>>> 00:18:2D:00:00:90
>>>> 00:18:2D:00:00:91
>>>> 00:18:2D:00:00:92
>>>
>>> Please describe with words.
>>> Reading similar MAC addresses is not a fun game.
>>
>> I do not catch you, could you please be
>> more detailed, thanks.
>
> Me too, I don't catch you.
> Please explain the problem in the commit log
> so we can understand without the example.
>
>>>> This is due to the reason that if the address has been added as a
>>>> non-default MAC address by rte_eth_dev_mac_addr_add API, it doesn't remove
>>>> from dev->data->mac_addrs[] when set default MAC address with the same
>>>> address.
>>>>
>>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
>>>> Cc: stable@dpdk.org
>>>>
>>>> Signed-off-by: Huisong Li <lihuisong@huawei.com>
>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>
>
>
> .
>
09/10/2021 11:53, Min Hu (Connor): > Hi, Thomas, > > The dev->data->mac_addrs[0] will be changed to a new MAC address when > applications modify > the default MAC address by rte_eth_dev_default_mac_addr_set() API. > However, If the new default > MAC address has been added as a non-default MAC address by > rte_eth_dev_mac_addr_add() API, the > rte_eth_dev_default_mac_addr_set() API doesn't remove it from > dev->data->mac_addrs[]. > As a result, one MAC address occupies two index capacities in > dev->data->mac_addrs[]. > This patch adds the logic of removing MAC addresses for this scenario. > > Is that will be more clear? Hope for your reply Yes, that's the explanation I was expecting. Thank you! > 在 2021/10/8 18:04, Thomas Monjalon 写道: > > 08/10/2021 09:02, Min Hu (Connor): > >> Hi, Thomas, > >> > >> 在 2021/10/6 3:21, Thomas Monjalon 写道: > >>> 22/09/2021 05:36, Min Hu (Connor): > >>>> From: Huisong Li <lihuisong@huawei.com> > >>>> > >>>> Use the testpmd to perform the following operations: > >>>> 1) mac_addr add 0 00:18:2D:00:00:90 > >>>> 2) mac_addr add 0 00:18:2D:00:00:91 > >>>> 3) mac_addr add 0 00:18:2D:00:00:92 > >>>> 4) mac_addr set 0 00:18:2D:00:00:91 > >>>> 5) show port 0 macs > >>>> Number of MAC address added: 4 > >>>> 00:18:2D:00:00:91 > >>>> 00:18:2D:00:00:90 > >>>> 00:18:2D:00:00:91 > >>>> 00:18:2D:00:00:92 > >>> > >>> Please describe with words. > >>> Reading similar MAC addresses is not a fun game. > >> > >> I do not catch you, could you please be > >> more detailed, thanks. > > > > Me too, I don't catch you. > > Please explain the problem in the commit log > > so we can understand without the example. > > > >>>> This is due to the reason that if the address has been added as a > >>>> non-default MAC address by rte_eth_dev_mac_addr_add API, it doesn't remove > >>>> from dev->data->mac_addrs[] when set default MAC address with the same > >>>> address. > >>>> > >>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") > >>>> Cc: stable@dpdk.org > >>>> > >>>> Signed-off-by: Huisong Li <lihuisong@huawei.com> > >>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
From: Huisong Li <lihuisong@huawei.com> The dev->data->mac_addrs[0] will be changed to a new MAC address when applications modify the default MAC address by rte_eth_dev_default_mac_addr_set() API. However, If the new default MAC address has been added as a non-default MAC address by rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set() API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC address occupies two index capacities in dev->data->mac_addrs[]. This patch adds the logic of removing MAC addresses for this scenario. Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") Cc: stable@dpdk.org Signed-off-by: Huisong Li <lihuisong@huawei.com> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> --- v2: * fixed commit log. --- lib/ethdev/rte_ethdev.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 028907bc4b..7faff17d9a 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -4340,6 +4340,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); @@ -4361,6 +4362,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) if (ret < 0) return ret; + /* + * If the address has been added as a non-default MAC address by + * rte_eth_dev_mac_addr_add API, it should be removed from + * dev->data->mac_addrs[]. + */ + index = eth_dev_get_mac_addr_index(port_id, addr); + if (index > 0) { + /* remove address in NIC data structure */ + rte_ether_addr_copy(&null_mac_addr, + &dev->data->mac_addrs[index]); + /* reset pool bitmap */ + dev->data->mac_pool_sel[index] = 0; + } + /* Update default address in NIC data structure */ rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); -- 2.33.0
11/10/2021 11:28, Min Hu (Connor):
> From: Huisong Li <lihuisong@huawei.com>
>
> The dev->data->mac_addrs[0] will be changed to a new MAC address when
> applications modify the default MAC address by
> rte_eth_dev_default_mac_addr_set() API. However, If the new default
> MAC address has been added as a non-default MAC address by
> rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set()
> API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC
> address occupies two index capacities in dev->data->mac_addrs[].
>
> This patch adds the logic of removing MAC addresses for this scenario.
>
> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
> Cc: stable@dpdk.org
>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
> + /*
> + * If the address has been added as a non-default MAC address by
> + * rte_eth_dev_mac_addr_add API, it should be removed from
> + * dev->data->mac_addrs[].
> + */
This is the definition of mac_addrs:
struct rte_ether_addr *mac_addrs;
/**< Device Ethernet link address.
* @see rte_eth_dev_release_port()
*/
I feel we need to explain there can be multiple addresses,
the first one being the default.
Another comment,
If we remove the duplicate, we may have to copy to previous default one
to avoid completely deleting the previous default address.
Not sure what should be the behaviour.
在 2021/10/11 18:35, Thomas Monjalon 写道: > 11/10/2021 11:28, Min Hu (Connor): >> From: Huisong Li <lihuisong@huawei.com> >> >> The dev->data->mac_addrs[0] will be changed to a new MAC address when >> applications modify the default MAC address by >> rte_eth_dev_default_mac_addr_set() API. However, If the new default >> MAC address has been added as a non-default MAC address by >> rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set() >> API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC >> address occupies two index capacities in dev->data->mac_addrs[]. >> >> This patch adds the logic of removing MAC addresses for this scenario. >> >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >> Cc: stable@dpdk.org >> >> Signed-off-by: Huisong Li <lihuisong@huawei.com> >> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> >> --- >> + /* >> + * If the address has been added as a non-default MAC address by >> + * rte_eth_dev_mac_addr_add API, it should be removed from >> + * dev->data->mac_addrs[]. >> + */ > This is the definition of mac_addrs: > > struct rte_ether_addr *mac_addrs; > /**< Device Ethernet link address. > * @see rte_eth_dev_release_port() > */ > > I feel we need to explain there can be multiple addresses, > the first one being the default. Do you mean that the problem mentioned in this patch is not a problem? Should we accept this scenario? > > Another comment, > If we remove the duplicate, we may have to copy to previous default one > to avoid completely deleting the previous default address. That's not necessary. Because the previous default address has been removed from hardware. After the default MAC address is modified, the previous default one is invalid. > Not sure what should be the behaviour. > > > .
12/10/2021 04:58, lihuisong (C): > 在 2021/10/11 18:35, Thomas Monjalon 写道: > > 11/10/2021 11:28, Min Hu (Connor): > >> From: Huisong Li <lihuisong@huawei.com> > >> > >> The dev->data->mac_addrs[0] will be changed to a new MAC address when > >> applications modify the default MAC address by > >> rte_eth_dev_default_mac_addr_set() API. However, If the new default > >> MAC address has been added as a non-default MAC address by > >> rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set() > >> API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC > >> address occupies two index capacities in dev->data->mac_addrs[]. > >> > >> This patch adds the logic of removing MAC addresses for this scenario. > >> > >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") > >> Cc: stable@dpdk.org > >> > >> Signed-off-by: Huisong Li <lihuisong@huawei.com> > >> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> > >> --- > >> + /* > >> + * If the address has been added as a non-default MAC address by > >> + * rte_eth_dev_mac_addr_add API, it should be removed from > >> + * dev->data->mac_addrs[]. > >> + */ > > This is the definition of mac_addrs: > > > > struct rte_ether_addr *mac_addrs; > > /**< Device Ethernet link address. > > * @see rte_eth_dev_release_port() > > */ > > > > I feel we need to explain there can be multiple addresses, > > the first one being the default. > > Do you mean that the problem mentioned in this patch is not a problem? It is not a problem if it is expected, but nothing is defined. > Should we accept this scenario? We need to decide what is the correct behaviour. I see pros and cons on both sides. > > Another comment, > > If we remove the duplicate, we may have to copy to previous default one > > to avoid completely deleting the previous default address. > > That's not necessary. > > Because the previous default address has been removed from hardware. > > After the default MAC address is modified, the previous default one is > invalid. No you don't get it. With the current behaviour, the app could keep all the MAC addresses, and copy one as the default while keeping it in the rest of the list. You are suggesting a different behaviour where there is no duplicate. > > Not sure what should be the behaviour.
在 2021/10/12 15:14, Thomas Monjalon 写道: > 12/10/2021 04:58, lihuisong (C): >> 在 2021/10/11 18:35, Thomas Monjalon 写道: >>> 11/10/2021 11:28, Min Hu (Connor): >>>> From: Huisong Li <lihuisong@huawei.com> >>>> >>>> The dev->data->mac_addrs[0] will be changed to a new MAC address when >>>> applications modify the default MAC address by >>>> rte_eth_dev_default_mac_addr_set() API. However, If the new default >>>> MAC address has been added as a non-default MAC address by >>>> rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set() >>>> API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC >>>> address occupies two index capacities in dev->data->mac_addrs[]. >>>> >>>> This patch adds the logic of removing MAC addresses for this scenario. >>>> >>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>>> Cc: stable@dpdk.org >>>> >>>> Signed-off-by: Huisong Li <lihuisong@huawei.com> >>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> >>>> --- >>>> + /* >>>> + * If the address has been added as a non-default MAC address by >>>> + * rte_eth_dev_mac_addr_add API, it should be removed from >>>> + * dev->data->mac_addrs[]. >>>> + */ >>> This is the definition of mac_addrs: >>> >>> struct rte_ether_addr *mac_addrs; >>> /**< Device Ethernet link address. >>> * @see rte_eth_dev_release_port() >>> */ >>> >>> I feel we need to explain there can be multiple addresses, >>> the first one being the default. >> Do you mean that the problem mentioned in this patch is not a problem? > It is not a problem if it is expected, > but nothing is defined. > >> Should we accept this scenario? > We need to decide what is the correct behaviour. > I see pros and cons on both sides. Where's the bright side of this behavior? >>> Another comment, >>> If we remove the duplicate, we may have to copy to previous default one >>> to avoid completely deleting the previous default address. >> That's not necessary. >> >> Because the previous default address has been removed from hardware. >> >> After the default MAC address is modified, the previous default one is >> invalid. > No you don't get it. > With the current behaviour, the app could keep all the MAC addresses, > and copy one as the default while keeping it in the rest of the list. > You are suggesting a different behaviour where there is no duplicate. This behavior seems to be contrary to the rte_eth_dev_mac_addr_add() API. If the pmd does not support the dev_ops->mac_addr_set, the rte_eth_dev_mac_addr_add() is used to set default MAC in ethdev layer. Namely, the rte_eth_dev_mac_addr_add() can be used to set default MAC in the special scenario and add MAC address. But the API does not allow the rest of the list to be the same as the default MAC which occupies idx 0. If the app uses the MAC address in dev->data->mac_addrs[] to set the default MAC, the PMD actually has only one entry. As far as I know, the dev->data->mac_addrs[] in ethdev layer should be consistent with the hardware entry of the PMD. So I think the behavior referred to in this patch is inappropriate. > >>> Not sure what should be the behaviour. > > > .
On 10/11/2021 10:28 AM, Min Hu (Connor) wrote: > From: Huisong Li <lihuisong@huawei.com> > > The dev->data->mac_addrs[0] will be changed to a new MAC address when > applications modify the default MAC address by > rte_eth_dev_default_mac_addr_set() API. However, If the new default > MAC address has been added as a non-default MAC address by > rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set() > API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC > address occupies two index capacities in dev->data->mac_addrs[]. > Hi Connor, I see the problem, but can you please clarify what is the impact to the end user? If application does as following: rte_eth_dev_mac_addr_add(MAC1); rte_eth_dev_mac_addr_add(MAC2); rte_eth_dev_mac_addr_add(MAC3); rte_eth_dev_default_mac_addr_set(MAC2); The 'dev->data->mac_addrs[]' will have: "MAC2,MAC2,MAC3" which has 'MAC2' duplicated. Will this cause any problem for the application to receive the packets with 'MAC2' address? Or is the only problem one extra space used in 'dev->data->mac_addrs[]' without any other impact to the application? > This patch adds the logic of removing MAC addresses for this scenario. > > Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") > Cc: stable@dpdk.org > > Signed-off-by: Huisong Li <lihuisong@huawei.com> > Signed-off-by: Min Hu (Connor) <humin29@huawei.com> > --- > v2: > * fixed commit log. > --- > lib/ethdev/rte_ethdev.c | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > > diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c > index 028907bc4b..7faff17d9a 100644 > --- a/lib/ethdev/rte_ethdev.c > +++ b/lib/ethdev/rte_ethdev.c > @@ -4340,6 +4340,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); > @@ -4361,6 +4362,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) > if (ret < 0) > return ret; > > + /* > + * If the address has been added as a non-default MAC address by > + * rte_eth_dev_mac_addr_add API, it should be removed from > + * dev->data->mac_addrs[]. > + */ > + index = eth_dev_get_mac_addr_index(port_id, addr); > + if (index > 0) { > + /* remove address in NIC data structure */ > + rte_ether_addr_copy(&null_mac_addr, > + &dev->data->mac_addrs[index]); > + /* reset pool bitmap */ > + dev->data->mac_pool_sel[index] = 0; > + } > + Here only 'dev->data->mac_addrs[]' array is updated and it assumes driver removes similar duplication itself, but I am not sure if this is valid for all drivers. If driver is not removing the duplicate in the HW configuration, the driver config and 'dev->data->mac_addrs[]' will diverge, which is not good. What about following logic to be sure HW configuration and 'dev->data->mac_addrs[]' is same: index = eth_dev_get_mac_addr_index(port_id, addr); if (index > 0) rte_eth_dev_mac_addr_remove(port_id, addr); (*dev->dev_ops->mac_addr_set)(dev, addr); > /* Update default address in NIC data structure */ > rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); > >
Hi Ferruh 在 2021/10/20 1:45, Ferruh Yigit 写道: > On 10/11/2021 10:28 AM, Min Hu (Connor) wrote: >> From: Huisong Li <lihuisong@huawei.com> >> >> The dev->data->mac_addrs[0] will be changed to a new MAC address when >> applications modify the default MAC address by >> rte_eth_dev_default_mac_addr_set() API. However, If the new default >> MAC address has been added as a non-default MAC address by >> rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set() >> API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC >> address occupies two index capacities in dev->data->mac_addrs[]. >> > > Hi Connor, > > I see the problem, but can you please clarify what is the impact to > the end user? > > If application does as following: > rte_eth_dev_mac_addr_add(MAC1); > rte_eth_dev_mac_addr_add(MAC2); > rte_eth_dev_mac_addr_add(MAC3); > rte_eth_dev_default_mac_addr_set(MAC2); > > The 'dev->data->mac_addrs[]' will have: "MAC2,MAC2,MAC3" which has > 'MAC2' duplicated. > > Will this cause any problem for the application to receive the packets > with 'MAC2' address? > Or is the only problem one extra space used in 'dev->data->mac_addrs[]' > without any other impact to the application? I think it's just a waste of space. > >> This patch adds the logic of removing MAC addresses for this scenario. >> >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >> Cc: stable@dpdk.org >> >> Signed-off-by: Huisong Li <lihuisong@huawei.com> >> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> >> --- >> v2: >> * fixed commit log. >> --- >> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++ >> 1 file changed, 15 insertions(+) >> >> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >> index 028907bc4b..7faff17d9a 100644 >> --- a/lib/ethdev/rte_ethdev.c >> +++ b/lib/ethdev/rte_ethdev.c >> @@ -4340,6 +4340,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); >> @@ -4361,6 +4362,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t >> port_id, struct rte_ether_addr *addr) >> if (ret < 0) >> return ret; >> + /* >> + * If the address has been added as a non-default MAC address by >> + * rte_eth_dev_mac_addr_add API, it should be removed from >> + * dev->data->mac_addrs[]. >> + */ >> + index = eth_dev_get_mac_addr_index(port_id, addr); >> + if (index > 0) { >> + /* remove address in NIC data structure */ >> + rte_ether_addr_copy(&null_mac_addr, >> + &dev->data->mac_addrs[index]); >> + /* reset pool bitmap */ >> + dev->data->mac_pool_sel[index] = 0; >> + } >> + > > Here only 'dev->data->mac_addrs[]' array is updated and it assumes > driver removes similar duplication itself, but I am not sure if this is > valid for all drivers. > > If driver is not removing the duplicate in the HW configuration, the > driver > config and 'dev->data->mac_addrs[]' will diverge, which is not good. The same MAC address does not occupy two HW entries, which is also a waste for HW. After all, HW entry resources are also limited. The PMD should also take this into account. So, I think, we don't have to think about it here. > > What about following logic to be sure HW configuration and > 'dev->data->mac_addrs[]' is same: > > index = eth_dev_get_mac_addr_index(port_id, addr); > if (index > 0) > rte_eth_dev_mac_addr_remove(port_id, addr); > (*dev->dev_ops->mac_addr_set)(dev, addr); The logic above seems to be good. But if .mac_addr_set() failed to execute, the addr has been removed from HW and 'dev->data->mac_addrs[]'. It's not good. Hope for your reply. Thanks. >> /* Update default address in NIC data structure */ >> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >> > > .
On 10/20/2021 7:49 AM, lihuisong (C) wrote: > Hi Ferruh > > 在 2021/10/20 1:45, Ferruh Yigit 写道: >> On 10/11/2021 10:28 AM, Min Hu (Connor) wrote: >>> From: Huisong Li <lihuisong@huawei.com> >>> >>> The dev->data->mac_addrs[0] will be changed to a new MAC address when >>> applications modify the default MAC address by >>> rte_eth_dev_default_mac_addr_set() API. However, If the new default >>> MAC address has been added as a non-default MAC address by >>> rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set() >>> API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC >>> address occupies two index capacities in dev->data->mac_addrs[]. >>> >> >> Hi Connor, >> >> I see the problem, but can you please clarify what is the impact to the end user? >> >> If application does as following: >> rte_eth_dev_mac_addr_add(MAC1); >> rte_eth_dev_mac_addr_add(MAC2); >> rte_eth_dev_mac_addr_add(MAC3); >> rte_eth_dev_default_mac_addr_set(MAC2); >> >> The 'dev->data->mac_addrs[]' will have: "MAC2,MAC2,MAC3" which has 'MAC2' duplicated. >> >> Will this cause any problem for the application to receive the packets >> with 'MAC2' address? >> Or is the only problem one extra space used in 'dev->data->mac_addrs[]' >> without any other impact to the application? > I think it's just a waste of space. True, it is a waste. But if there is no other visible user impact, we can handle the issue with lower priority and clarifying the impact in commit log helps to others. >> >>> This patch adds the logic of removing MAC addresses for this scenario. >>> >>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>> Cc: stable@dpdk.org >>> >>> Signed-off-by: Huisong Li <lihuisong@huawei.com> >>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> >>> --- >>> v2: >>> * fixed commit log. >>> --- >>> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++ >>> 1 file changed, 15 insertions(+) >>> >>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >>> index 028907bc4b..7faff17d9a 100644 >>> --- a/lib/ethdev/rte_ethdev.c >>> +++ b/lib/ethdev/rte_ethdev.c >>> @@ -4340,6 +4340,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); >>> @@ -4361,6 +4362,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) >>> if (ret < 0) >>> return ret; >>> + /* >>> + * If the address has been added as a non-default MAC address by >>> + * rte_eth_dev_mac_addr_add API, it should be removed from >>> + * dev->data->mac_addrs[]. >>> + */ >>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>> + if (index > 0) { >>> + /* remove address in NIC data structure */ >>> + rte_ether_addr_copy(&null_mac_addr, >>> + &dev->data->mac_addrs[index]); >>> + /* reset pool bitmap */ >>> + dev->data->mac_pool_sel[index] = 0; >>> + } >>> + >> >> Here only 'dev->data->mac_addrs[]' array is updated and it assumes >> driver removes similar duplication itself, but I am not sure if this is >> valid for all drivers. >> >> If driver is not removing the duplicate in the HW configuration, the driver >> config and 'dev->data->mac_addrs[]' will diverge, which is not good. > The same MAC address does not occupy two HW entries, which is also a > waste for HW. After all, HW entry resources are also limited. > The PMD should also take this into account. > So, I think, we don't have to think about it here. I am not sure all PMD take this into account, I briefly checked the ixgbe code and I am not sure if it handles this. Also it is possible to think that this responsibility is pushed to the application, like application should remove a MAC address before setting it as default MAC... >> >> What about following logic to be sure HW configuration and >> 'dev->data->mac_addrs[]' is same: >> >> index = eth_dev_get_mac_addr_index(port_id, addr); >> if (index > 0) >> rte_eth_dev_mac_addr_remove(port_id, addr); >> (*dev->dev_ops->mac_addr_set)(dev, addr); > The logic above seems to be good. But if .mac_addr_set() failed to > execute, the addr has been removed from HW and 'dev->data->mac_addrs[]'. > It's not good. > Agree. So may need to get a copy of 'addr' and add it back on failure. The concern I have to call 'rte_eth_dev_mac_addr_remove()' after 'dev_ops->mac_addr_set()' is, it may result different behavior on different PMDs. For the PMDs that clean the redundant MAC address via 'dev_ops->mac_addr_set()' may try to remove (although it will fail) the new set default MAC address. That is why first remove the MAC and later add it back as default seems safer to me. > Hope for your reply. Thanks. >>> /* Update default address in NIC data structure */ >>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>> >> >> .
On 20/10/2021 08:41, Ferruh Yigit wrote: > On 10/20/2021 7:49 AM, lihuisong (C) wrote: >> Hi Ferruh >> >> 在 2021/10/20 1:45, Ferruh Yigit 写道: >>> On 10/11/2021 10:28 AM, Min Hu (Connor) wrote: >>>> From: Huisong Li <lihuisong@huawei.com> >>>> >>>> The dev->data->mac_addrs[0] will be changed to a new MAC address when >>>> applications modify the default MAC address by >>>> rte_eth_dev_default_mac_addr_set() API. However, If the new default >>>> MAC address has been added as a non-default MAC address by >>>> rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set() >>>> API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC >>>> address occupies two index capacities in dev->data->mac_addrs[]. >>>> >>> >>> Hi Connor, >>> >>> I see the problem, but can you please clarify what is the impact to the end user? >>> >>> If application does as following: >>> rte_eth_dev_mac_addr_add(MAC1); >>> rte_eth_dev_mac_addr_add(MAC2); >>> rte_eth_dev_mac_addr_add(MAC3); >>> rte_eth_dev_default_mac_addr_set(MAC2); >>> >>> The 'dev->data->mac_addrs[]' will have: "MAC2,MAC2,MAC3" which has 'MAC2' duplicated. >>> >>> Will this cause any problem for the application to receive the packets >>> with 'MAC2' address? >>> Or is the only problem one extra space used in 'dev->data->mac_addrs[]' >>> without any other impact to the application? >> I think it's just a waste of space. > > True, it is a waste. But if there is no other visible user impact, we can > handle the issue with lower priority and clarifying the impact in commit log > helps to others. > >>> >>>> This patch adds the logic of removing MAC addresses for this scenario. >>>> >>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>>> Cc: stable@dpdk.org >>>> >>>> Signed-off-by: Huisong Li <lihuisong@huawei.com> >>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> >>>> --- >>>> v2: >>>> * fixed commit log. >>>> --- >>>> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++ >>>> 1 file changed, 15 insertions(+) >>>> >>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >>>> index 028907bc4b..7faff17d9a 100644 >>>> --- a/lib/ethdev/rte_ethdev.c >>>> +++ b/lib/ethdev/rte_ethdev.c >>>> @@ -4340,6 +4340,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); >>>> @@ -4361,6 +4362,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) >>>> if (ret < 0) >>>> return ret; >>>> + /* >>>> + * If the address has been added as a non-default MAC address by >>>> + * rte_eth_dev_mac_addr_add API, it should be removed from >>>> + * dev->data->mac_addrs[]. >>>> + */ >>>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>>> + if (index > 0) { >>>> + /* remove address in NIC data structure */ >>>> + rte_ether_addr_copy(&null_mac_addr, >>>> + &dev->data->mac_addrs[index]); >>>> + /* reset pool bitmap */ >>>> + dev->data->mac_pool_sel[index] = 0; >>>> + } >>>> + >>> >>> Here only 'dev->data->mac_addrs[]' array is updated and it assumes >>> driver removes similar duplication itself, but I am not sure if this is >>> valid for all drivers. >>> >>> If driver is not removing the duplicate in the HW configuration, the driver >>> config and 'dev->data->mac_addrs[]' will diverge, which is not good. >> The same MAC address does not occupy two HW entries, which is also a >> waste for HW. After all, HW entry resources are also limited. >> The PMD should also take this into account. >> So, I think, we don't have to think about it here. > > I am not sure all PMD take this into account, I briefly checked the ixgbe > code and I am not sure if it handles this. > > Also it is possible to think that this responsibility is pushed to the > application, like application should remove a MAC address before setting > it as default MAC... > Yes, the API view is more important than saving one entry in an array. From API perspective with this patch, set_default(MAC1) add(MAC2) add(MAC3) add(MAC4) default=MAC1, Filters=MAC2, MAC3, MAC4 set_default(MAC2) default=MAC2, Filters= MAC3, MAC4 set_default(MAC3) default=MAC3, Filters= MAC4 set_default(MAC4) default=MAC4, Filters= set_default(MAC5) default=MAC5, Filters= Did I get it right? If so, it seems wrong to silently remove the filters. In which case, it would be easier to just not remove them in the first place (current behaviour). If they really need to be removed from the filter list when they are set_default(), then perhaps they should be restored to it when there is a new set_default(). >>> >>> What about following logic to be sure HW configuration and >>> 'dev->data->mac_addrs[]' is same: >>> >>> index = eth_dev_get_mac_addr_index(port_id, addr); >>> if (index > 0) >>> rte_eth_dev_mac_addr_remove(port_id, addr); >>> (*dev->dev_ops->mac_addr_set)(dev, addr); >> The logic above seems to be good. But if .mac_addr_set() failed to >> execute, the addr has been removed from HW and 'dev->data->mac_addrs[]'. >> It's not good. >> > > Agree. So may need to get a copy of 'addr' and add it back on failure. > > The concern I have to call 'rte_eth_dev_mac_addr_remove()' after > 'dev_ops->mac_addr_set()' is, it may result different behavior on > different PMDs. > For the PMDs that clean the redundant MAC address via 'dev_ops->mac_addr_set()' > may try to remove (although it will fail) the new set default MAC address. > That is why first remove the MAC and later add it back as default > seems safer to me. > >> Hope for your reply. Thanks. >>>> /* Update default address in NIC data structure */ >>>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>>> >>> >>> . >
On 10/20/2021 11:15 AM, Kevin Traynor wrote: > On 20/10/2021 08:41, Ferruh Yigit wrote: >> On 10/20/2021 7:49 AM, lihuisong (C) wrote: >>> Hi Ferruh >>> >>> 在 2021/10/20 1:45, Ferruh Yigit 写道: >>>> On 10/11/2021 10:28 AM, Min Hu (Connor) wrote: >>>>> From: Huisong Li <lihuisong@huawei.com> >>>>> >>>>> The dev->data->mac_addrs[0] will be changed to a new MAC address when >>>>> applications modify the default MAC address by >>>>> rte_eth_dev_default_mac_addr_set() API. However, If the new default >>>>> MAC address has been added as a non-default MAC address by >>>>> rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set() >>>>> API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC >>>>> address occupies two index capacities in dev->data->mac_addrs[]. >>>>> >>>> >>>> Hi Connor, >>>> >>>> I see the problem, but can you please clarify what is the impact to the end user? >>>> >>>> If application does as following: >>>> rte_eth_dev_mac_addr_add(MAC1); >>>> rte_eth_dev_mac_addr_add(MAC2); >>>> rte_eth_dev_mac_addr_add(MAC3); >>>> rte_eth_dev_default_mac_addr_set(MAC2); >>>> >>>> The 'dev->data->mac_addrs[]' will have: "MAC2,MAC2,MAC3" which has 'MAC2' duplicated. >>>> >>>> Will this cause any problem for the application to receive the packets >>>> with 'MAC2' address? >>>> Or is the only problem one extra space used in 'dev->data->mac_addrs[]' >>>> without any other impact to the application? >>> I think it's just a waste of space. >> >> True, it is a waste. But if there is no other visible user impact, we can >> handle the issue with lower priority and clarifying the impact in commit log >> helps to others. >> >>>> >>>>> This patch adds the logic of removing MAC addresses for this scenario. >>>>> >>>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>>>> Cc: stable@dpdk.org >>>>> >>>>> Signed-off-by: Huisong Li <lihuisong@huawei.com> >>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> >>>>> --- >>>>> v2: >>>>> * fixed commit log. >>>>> --- >>>>> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++ >>>>> 1 file changed, 15 insertions(+) >>>>> >>>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >>>>> index 028907bc4b..7faff17d9a 100644 >>>>> --- a/lib/ethdev/rte_ethdev.c >>>>> +++ b/lib/ethdev/rte_ethdev.c >>>>> @@ -4340,6 +4340,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); >>>>> @@ -4361,6 +4362,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) >>>>> if (ret < 0) >>>>> return ret; >>>>> + /* >>>>> + * If the address has been added as a non-default MAC address by >>>>> + * rte_eth_dev_mac_addr_add API, it should be removed from >>>>> + * dev->data->mac_addrs[]. >>>>> + */ >>>>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>>>> + if (index > 0) { >>>>> + /* remove address in NIC data structure */ >>>>> + rte_ether_addr_copy(&null_mac_addr, >>>>> + &dev->data->mac_addrs[index]); >>>>> + /* reset pool bitmap */ >>>>> + dev->data->mac_pool_sel[index] = 0; >>>>> + } >>>>> + >>>> >>>> Here only 'dev->data->mac_addrs[]' array is updated and it assumes >>>> driver removes similar duplication itself, but I am not sure if this is >>>> valid for all drivers. >>>> >>>> If driver is not removing the duplicate in the HW configuration, the driver >>>> config and 'dev->data->mac_addrs[]' will diverge, which is not good. >>> The same MAC address does not occupy two HW entries, which is also a >>> waste for HW. After all, HW entry resources are also limited. >>> The PMD should also take this into account. >>> So, I think, we don't have to think about it here. >> >> I am not sure all PMD take this into account, I briefly checked the ixgbe >> code and I am not sure if it handles this. >> >> Also it is possible to think that this responsibility is pushed to the >> application, like application should remove a MAC address before setting >> it as default MAC... >> > > Yes, the API view is more important than saving one entry in an array. From API perspective with this patch, > > set_default(MAC1) > add(MAC2) > add(MAC3) > add(MAC4) > default=MAC1, Filters=MAC2, MAC3, MAC4 > > set_default(MAC2) > default=MAC2, Filters= MAC3, MAC4 > > set_default(MAC3) > default=MAC3, Filters= MAC4 > > set_default(MAC4) > default=MAC4, Filters= > > set_default(MAC5) > default=MAC5, Filters= > > Did I get it right? If so, it seems wrong to silently remove the filters. In which case, it would be easier to just not remove them in the first place (current behaviour). > Yep, this is the updated behavior. And agree it looks wrong when you show like this. (btw, this is only ethdev record of MAC filters, what is updated in this patch, HW still may be keeping all filters.) > If they really need to be removed from the filter list when they are set_default(), then perhaps they should be restored to it when there is a new set_default(). > I am for keeping current behavior. Application always can explicitly remove a MAC filter before setting it default if required. >>>> >>>> What about following logic to be sure HW configuration and >>>> 'dev->data->mac_addrs[]' is same: >>>> >>>> index = eth_dev_get_mac_addr_index(port_id, addr); >>>> if (index > 0) >>>> rte_eth_dev_mac_addr_remove(port_id, addr); >>>> (*dev->dev_ops->mac_addr_set)(dev, addr); >>> The logic above seems to be good. But if .mac_addr_set() failed to >>> execute, the addr has been removed from HW and 'dev->data->mac_addrs[]'. >>> It's not good. >>> >> >> Agree. So may need to get a copy of 'addr' and add it back on failure. >> >> The concern I have to call 'rte_eth_dev_mac_addr_remove()' after >> 'dev_ops->mac_addr_set()' is, it may result different behavior on >> different PMDs. >> For the PMDs that clean the redundant MAC address via 'dev_ops->mac_addr_set()' >> may try to remove (although it will fail) the new set default MAC address. >> That is why first remove the MAC and later add it back as default >> seems safer to me. >> >>> Hope for your reply. Thanks. >>>>> /* Update default address in NIC data structure */ >>>>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>>>> >>>> >>>> . >> >
在 2021/10/21 0:32, Ferruh Yigit 写道: > On 10/20/2021 11:15 AM, Kevin Traynor wrote: >> On 20/10/2021 08:41, Ferruh Yigit wrote: >>> On 10/20/2021 7:49 AM, lihuisong (C) wrote: >>>> Hi Ferruh >>>> >>>> 在 2021/10/20 1:45, Ferruh Yigit 写道: >>>>> On 10/11/2021 10:28 AM, Min Hu (Connor) wrote: >>>>>> From: Huisong Li <lihuisong@huawei.com> >>>>>> >>>>>> The dev->data->mac_addrs[0] will be changed to a new MAC address >>>>>> when >>>>>> applications modify the default MAC address by >>>>>> rte_eth_dev_default_mac_addr_set() API. However, If the new default >>>>>> MAC address has been added as a non-default MAC address by >>>>>> rte_eth_dev_mac_addr_add() API, the >>>>>> rte_eth_dev_default_mac_addr_set() >>>>>> API doesn't remove it from dev->data->mac_addrs[]. As a result, >>>>>> one MAC >>>>>> address occupies two index capacities in dev->data->mac_addrs[]. >>>>>> >>>>> >>>>> Hi Connor, >>>>> >>>>> I see the problem, but can you please clarify what is the impact >>>>> to the end user? >>>>> >>>>> If application does as following: >>>>> rte_eth_dev_mac_addr_add(MAC1); >>>>> rte_eth_dev_mac_addr_add(MAC2); >>>>> rte_eth_dev_mac_addr_add(MAC3); >>>>> rte_eth_dev_default_mac_addr_set(MAC2); >>>>> >>>>> The 'dev->data->mac_addrs[]' will have: "MAC2,MAC2,MAC3" which has >>>>> 'MAC2' duplicated. >>>>> >>>>> Will this cause any problem for the application to receive the >>>>> packets >>>>> with 'MAC2' address? >>>>> Or is the only problem one extra space used in >>>>> 'dev->data->mac_addrs[]' >>>>> without any other impact to the application? >>>> I think it's just a waste of space. >>> >>> True, it is a waste. But if there is no other visible user impact, >>> we can >>> handle the issue with lower priority and clarifying the impact in >>> commit log >>> helps to others. >>> >>>>> >>>>>> This patch adds the logic of removing MAC addresses for this >>>>>> scenario. >>>>>> >>>>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>>>>> Cc: stable@dpdk.org >>>>>> >>>>>> Signed-off-by: Huisong Li <lihuisong@huawei.com> >>>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> >>>>>> --- >>>>>> v2: >>>>>> * fixed commit log. >>>>>> --- >>>>>> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++ >>>>>> 1 file changed, 15 insertions(+) >>>>>> >>>>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >>>>>> index 028907bc4b..7faff17d9a 100644 >>>>>> --- a/lib/ethdev/rte_ethdev.c >>>>>> +++ b/lib/ethdev/rte_ethdev.c >>>>>> @@ -4340,6 +4340,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); >>>>>> @@ -4361,6 +4362,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t >>>>>> port_id, struct rte_ether_addr *addr) >>>>>> if (ret < 0) >>>>>> return ret; >>>>>> + /* >>>>>> + * If the address has been added as a non-default MAC >>>>>> address by >>>>>> + * rte_eth_dev_mac_addr_add API, it should be removed from >>>>>> + * dev->data->mac_addrs[]. >>>>>> + */ >>>>>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>>>>> + if (index > 0) { >>>>>> + /* remove address in NIC data structure */ >>>>>> + rte_ether_addr_copy(&null_mac_addr, >>>>>> + &dev->data->mac_addrs[index]); >>>>>> + /* reset pool bitmap */ >>>>>> + dev->data->mac_pool_sel[index] = 0; >>>>>> + } >>>>>> + >>>>> >>>>> Here only 'dev->data->mac_addrs[]' array is updated and it assumes >>>>> driver removes similar duplication itself, but I am not sure if >>>>> this is >>>>> valid for all drivers. >>>>> >>>>> If driver is not removing the duplicate in the HW configuration, >>>>> the driver >>>>> config and 'dev->data->mac_addrs[]' will diverge, which is not good. >>>> The same MAC address does not occupy two HW entries, which is also a >>>> waste for HW. After all, HW entry resources are also limited. >>>> The PMD should also take this into account. >>>> So, I think, we don't have to think about it here. >>> >>> I am not sure all PMD take this into account, I briefly checked the >>> ixgbe >>> code and I am not sure if it handles this. >>> >>> Also it is possible to think that this responsibility is pushed to the >>> application, like application should remove a MAC address before >>> setting >>> it as default MAC... >>> >> >> Yes, the API view is more important than saving one entry in an >> array. From API perspective with this patch, >> >> set_default(MAC1) >> add(MAC2) >> add(MAC3) >> add(MAC4) >> default=MAC1, Filters=MAC2, MAC3, MAC4 >> >> set_default(MAC2) >> default=MAC2, Filters= MAC3, MAC4 >> >> set_default(MAC3) >> default=MAC3, Filters= MAC4 >> >> set_default(MAC4) >> default=MAC4, Filters= >> >> set_default(MAC5) >> default=MAC5, Filters= >> >> Did I get it right? If so, it seems wrong to silently remove the >> filters. In which case, it would be easier to just not remove them in >> the first place (current behaviour). >> > > Yep, this is the updated behavior. And agree it looks wrong when you > show like this. (btw, this is only ethdev record of MAC filters, what > is updated in this patch, HW still may be keeping all filters.) Whether HW saves all filters depends on the implementation of the set_default() in the driver. According to the implementation of this API of all PMDs, some drivers will first remove the old default MAC in HW and then add the new one when calling the set_default(). I am not sure if the HW that didn't do this would remove the old default MAC. If not, we may need to standardize this API in the ethdev layer. > >> If they really need to be removed from the filter list when they are >> set_default(), then perhaps they should be restored to it when there >> is a new set_default(). >> > > I am for keeping current behavior. Application always can explicitly > remove a > MAC filter before setting it default if required. But application can not remove the duplicate MAC if the MAC is the current default MAC by rte_eth_dev_mac_addr_remove(). In this case, it will failed to remove. > > >>>>> >>>>> What about following logic to be sure HW configuration and >>>>> 'dev->data->mac_addrs[]' is same: >>>>> >>>>> index = eth_dev_get_mac_addr_index(port_id, addr); >>>>> if (index > 0) >>>>> rte_eth_dev_mac_addr_remove(port_id, addr); >>>>> (*dev->dev_ops->mac_addr_set)(dev, addr); >>>> The logic above seems to be good. But if .mac_addr_set() failed to >>>> execute, the addr has been removed from HW and >>>> 'dev->data->mac_addrs[]'. >>>> It's not good. >>>> >>> >>> Agree. So may need to get a copy of 'addr' and add it back on failure. >>> >>> The concern I have to call 'rte_eth_dev_mac_addr_remove()' after >>> 'dev_ops->mac_addr_set()' is, it may result different behavior on >>> different PMDs. >>> For the PMDs that clean the redundant MAC address via >>> 'dev_ops->mac_addr_set()' >>> may try to remove (although it will fail) the new set default MAC >>> address. >>> That is why first remove the MAC and later add it back as default >>> seems safer to me. >>> >>>> Hope for your reply. Thanks. >>>>>> /* Update default address in NIC data structure */ >>>>>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>>>>> >>>>> >>>>> . >>> >> > > .
On 10/21/2021 3:05 AM, lihuisong (C) wrote: > > 在 2021/10/21 0:32, Ferruh Yigit 写道: >> On 10/20/2021 11:15 AM, Kevin Traynor wrote: >>> On 20/10/2021 08:41, Ferruh Yigit wrote: >>>> On 10/20/2021 7:49 AM, lihuisong (C) wrote: >>>>> Hi Ferruh >>>>> >>>>> 在 2021/10/20 1:45, Ferruh Yigit 写道: >>>>>> On 10/11/2021 10:28 AM, Min Hu (Connor) wrote: >>>>>>> From: Huisong Li <lihuisong@huawei.com> >>>>>>> >>>>>>> The dev->data->mac_addrs[0] will be changed to a new MAC address when >>>>>>> applications modify the default MAC address by >>>>>>> rte_eth_dev_default_mac_addr_set() API. However, If the new default >>>>>>> MAC address has been added as a non-default MAC address by >>>>>>> rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set() >>>>>>> API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC >>>>>>> address occupies two index capacities in dev->data->mac_addrs[]. >>>>>>> >>>>>> >>>>>> Hi Connor, >>>>>> >>>>>> I see the problem, but can you please clarify what is the impact to the end user? >>>>>> >>>>>> If application does as following: >>>>>> rte_eth_dev_mac_addr_add(MAC1); >>>>>> rte_eth_dev_mac_addr_add(MAC2); >>>>>> rte_eth_dev_mac_addr_add(MAC3); >>>>>> rte_eth_dev_default_mac_addr_set(MAC2); >>>>>> >>>>>> The 'dev->data->mac_addrs[]' will have: "MAC2,MAC2,MAC3" which has 'MAC2' duplicated. >>>>>> >>>>>> Will this cause any problem for the application to receive the packets >>>>>> with 'MAC2' address? >>>>>> Or is the only problem one extra space used in 'dev->data->mac_addrs[]' >>>>>> without any other impact to the application? >>>>> I think it's just a waste of space. >>>> >>>> True, it is a waste. But if there is no other visible user impact, we can >>>> handle the issue with lower priority and clarifying the impact in commit log >>>> helps to others. >>>> >>>>>> >>>>>>> This patch adds the logic of removing MAC addresses for this scenario. >>>>>>> >>>>>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>>>>>> Cc: stable@dpdk.org >>>>>>> >>>>>>> Signed-off-by: Huisong Li <lihuisong@huawei.com> >>>>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> >>>>>>> --- >>>>>>> v2: >>>>>>> * fixed commit log. >>>>>>> --- >>>>>>> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++ >>>>>>> 1 file changed, 15 insertions(+) >>>>>>> >>>>>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >>>>>>> index 028907bc4b..7faff17d9a 100644 >>>>>>> --- a/lib/ethdev/rte_ethdev.c >>>>>>> +++ b/lib/ethdev/rte_ethdev.c >>>>>>> @@ -4340,6 +4340,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); >>>>>>> @@ -4361,6 +4362,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) >>>>>>> if (ret < 0) >>>>>>> return ret; >>>>>>> + /* >>>>>>> + * If the address has been added as a non-default MAC address by >>>>>>> + * rte_eth_dev_mac_addr_add API, it should be removed from >>>>>>> + * dev->data->mac_addrs[]. >>>>>>> + */ >>>>>>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>>>>>> + if (index > 0) { >>>>>>> + /* remove address in NIC data structure */ >>>>>>> + rte_ether_addr_copy(&null_mac_addr, >>>>>>> + &dev->data->mac_addrs[index]); >>>>>>> + /* reset pool bitmap */ >>>>>>> + dev->data->mac_pool_sel[index] = 0; >>>>>>> + } >>>>>>> + >>>>>> >>>>>> Here only 'dev->data->mac_addrs[]' array is updated and it assumes >>>>>> driver removes similar duplication itself, but I am not sure if this is >>>>>> valid for all drivers. >>>>>> >>>>>> If driver is not removing the duplicate in the HW configuration, the driver >>>>>> config and 'dev->data->mac_addrs[]' will diverge, which is not good. >>>>> The same MAC address does not occupy two HW entries, which is also a >>>>> waste for HW. After all, HW entry resources are also limited. >>>>> The PMD should also take this into account. >>>>> So, I think, we don't have to think about it here. >>>> >>>> I am not sure all PMD take this into account, I briefly checked the ixgbe >>>> code and I am not sure if it handles this. >>>> >>>> Also it is possible to think that this responsibility is pushed to the >>>> application, like application should remove a MAC address before setting >>>> it as default MAC... >>>> >>> >>> Yes, the API view is more important than saving one entry in an array. From API perspective with this patch, >>> >>> set_default(MAC1) >>> add(MAC2) >>> add(MAC3) >>> add(MAC4) >>> default=MAC1, Filters=MAC2, MAC3, MAC4 >>> >>> set_default(MAC2) >>> default=MAC2, Filters= MAC3, MAC4 >>> >>> set_default(MAC3) >>> default=MAC3, Filters= MAC4 >>> >>> set_default(MAC4) >>> default=MAC4, Filters= >>> >>> set_default(MAC5) >>> default=MAC5, Filters= >>> >>> Did I get it right? If so, it seems wrong to silently remove the filters. In which case, it would be easier to just not remove them in the first place (current behaviour). >>> >> >> Yep, this is the updated behavior. And agree it looks wrong when you >> show like this. (btw, this is only ethdev record of MAC filters, what >> is updated in this patch, HW still may be keeping all filters.) > > Whether HW saves all filters depends on the implementation of the set_default() > > in the driver. According to the implementation of this API of all PMDs, some drivers > > will first remove the old default MAC in HW and then add the new one when calling > > the set_default(). I am not sure if the HW that didn't do this would remove the old > > default MAC. If not, we may need to standardize this API in the ethdev layer. > >> >>> If they really need to be removed from the filter list when they are set_default(), then perhaps they should be restored to it when there is a new set_default(). >>> >> >> I am for keeping current behavior. Application always can explicitly remove a >> MAC filter before setting it default if required. > > But application can not remove the duplicate MAC if the MAC is the current default > > MAC by rte_eth_dev_mac_addr_remove(). In this case, it will failed to remove. > But can do other-way around, first remove (the non default one), later 'rte_eth_dev_default_mac_addr_set()'. >> >> >>>>>> >>>>>> What about following logic to be sure HW configuration and >>>>>> 'dev->data->mac_addrs[]' is same: >>>>>> >>>>>> index = eth_dev_get_mac_addr_index(port_id, addr); >>>>>> if (index > 0) >>>>>> rte_eth_dev_mac_addr_remove(port_id, addr); >>>>>> (*dev->dev_ops->mac_addr_set)(dev, addr); >>>>> The logic above seems to be good. But if .mac_addr_set() failed to >>>>> execute, the addr has been removed from HW and 'dev->data->mac_addrs[]'. >>>>> It's not good. >>>>> >>>> >>>> Agree. So may need to get a copy of 'addr' and add it back on failure. >>>> >>>> The concern I have to call 'rte_eth_dev_mac_addr_remove()' after >>>> 'dev_ops->mac_addr_set()' is, it may result different behavior on >>>> different PMDs. >>>> For the PMDs that clean the redundant MAC address via 'dev_ops->mac_addr_set()' >>>> may try to remove (although it will fail) the new set default MAC address. >>>> That is why first remove the MAC and later add it back as default >>>> seems safer to me. >>>> >>>>> Hope for your reply. Thanks. >>>>>>> /* Update default address in NIC data structure */ >>>>>>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>>>>>> >>>>>> >>>>>> . >>>> >>> >> >> .
在 2021/10/21 16:30, Ferruh Yigit 写道: > On 10/21/2021 3:05 AM, lihuisong (C) wrote: >> >> 在 2021/10/21 0:32, Ferruh Yigit 写道: >>> On 10/20/2021 11:15 AM, Kevin Traynor wrote: >>>> On 20/10/2021 08:41, Ferruh Yigit wrote: >>>>> On 10/20/2021 7:49 AM, lihuisong (C) wrote: >>>>>> Hi Ferruh >>>>>> >>>>>> 在 2021/10/20 1:45, Ferruh Yigit 写道: >>>>>>> On 10/11/2021 10:28 AM, Min Hu (Connor) wrote: >>>>>>>> From: Huisong Li <lihuisong@huawei.com> >>>>>>>> >>>>>>>> The dev->data->mac_addrs[0] will be changed to a new MAC >>>>>>>> address when >>>>>>>> applications modify the default MAC address by >>>>>>>> rte_eth_dev_default_mac_addr_set() API. However, If the new >>>>>>>> default >>>>>>>> MAC address has been added as a non-default MAC address by >>>>>>>> rte_eth_dev_mac_addr_add() API, the >>>>>>>> rte_eth_dev_default_mac_addr_set() >>>>>>>> API doesn't remove it from dev->data->mac_addrs[]. As a result, >>>>>>>> one MAC >>>>>>>> address occupies two index capacities in dev->data->mac_addrs[]. >>>>>>>> >>>>>>> >>>>>>> Hi Connor, >>>>>>> >>>>>>> I see the problem, but can you please clarify what is the impact >>>>>>> to the end user? >>>>>>> >>>>>>> If application does as following: >>>>>>> rte_eth_dev_mac_addr_add(MAC1); >>>>>>> rte_eth_dev_mac_addr_add(MAC2); >>>>>>> rte_eth_dev_mac_addr_add(MAC3); >>>>>>> rte_eth_dev_default_mac_addr_set(MAC2); >>>>>>> >>>>>>> The 'dev->data->mac_addrs[]' will have: "MAC2,MAC2,MAC3" which >>>>>>> has 'MAC2' duplicated. >>>>>>> >>>>>>> Will this cause any problem for the application to receive the >>>>>>> packets >>>>>>> with 'MAC2' address? >>>>>>> Or is the only problem one extra space used in >>>>>>> 'dev->data->mac_addrs[]' >>>>>>> without any other impact to the application? >>>>>> I think it's just a waste of space. >>>>> >>>>> True, it is a waste. But if there is no other visible user impact, >>>>> we can >>>>> handle the issue with lower priority and clarifying the impact in >>>>> commit log >>>>> helps to others. >>>>> >>>>>>> >>>>>>>> This patch adds the logic of removing MAC addresses for this >>>>>>>> scenario. >>>>>>>> >>>>>>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>>>>>>> Cc: stable@dpdk.org >>>>>>>> >>>>>>>> Signed-off-by: Huisong Li <lihuisong@huawei.com> >>>>>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> >>>>>>>> --- >>>>>>>> v2: >>>>>>>> * fixed commit log. >>>>>>>> --- >>>>>>>> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++ >>>>>>>> 1 file changed, 15 insertions(+) >>>>>>>> >>>>>>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >>>>>>>> index 028907bc4b..7faff17d9a 100644 >>>>>>>> --- a/lib/ethdev/rte_ethdev.c >>>>>>>> +++ b/lib/ethdev/rte_ethdev.c >>>>>>>> @@ -4340,6 +4340,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); >>>>>>>> @@ -4361,6 +4362,20 @@ >>>>>>>> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct >>>>>>>> rte_ether_addr *addr) >>>>>>>> if (ret < 0) >>>>>>>> return ret; >>>>>>>> + /* >>>>>>>> + * If the address has been added as a non-default MAC >>>>>>>> address by >>>>>>>> + * rte_eth_dev_mac_addr_add API, it should be removed from >>>>>>>> + * dev->data->mac_addrs[]. >>>>>>>> + */ >>>>>>>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>>>>>>> + if (index > 0) { >>>>>>>> + /* remove address in NIC data structure */ >>>>>>>> + rte_ether_addr_copy(&null_mac_addr, >>>>>>>> + &dev->data->mac_addrs[index]); >>>>>>>> + /* reset pool bitmap */ >>>>>>>> + dev->data->mac_pool_sel[index] = 0; >>>>>>>> + } >>>>>>>> + >>>>>>> >>>>>>> Here only 'dev->data->mac_addrs[]' array is updated and it assumes >>>>>>> driver removes similar duplication itself, but I am not sure if >>>>>>> this is >>>>>>> valid for all drivers. >>>>>>> >>>>>>> If driver is not removing the duplicate in the HW configuration, >>>>>>> the driver >>>>>>> config and 'dev->data->mac_addrs[]' will diverge, which is not >>>>>>> good. >>>>>> The same MAC address does not occupy two HW entries, which is also a >>>>>> waste for HW. After all, HW entry resources are also limited. >>>>>> The PMD should also take this into account. >>>>>> So, I think, we don't have to think about it here. >>>>> >>>>> I am not sure all PMD take this into account, I briefly checked >>>>> the ixgbe >>>>> code and I am not sure if it handles this. >>>>> >>>>> Also it is possible to think that this responsibility is pushed to >>>>> the >>>>> application, like application should remove a MAC address before >>>>> setting >>>>> it as default MAC... >>>>> >>>> >>>> Yes, the API view is more important than saving one entry in an >>>> array. From API perspective with this patch, >>>> >>>> set_default(MAC1) >>>> add(MAC2) >>>> add(MAC3) >>>> add(MAC4) >>>> default=MAC1, Filters=MAC2, MAC3, MAC4 >>>> >>>> set_default(MAC2) >>>> default=MAC2, Filters= MAC3, MAC4 >>>> >>>> set_default(MAC3) >>>> default=MAC3, Filters= MAC4 >>>> >>>> set_default(MAC4) >>>> default=MAC4, Filters= >>>> >>>> set_default(MAC5) >>>> default=MAC5, Filters= >>>> >>>> Did I get it right? If so, it seems wrong to silently remove the >>>> filters. In which case, it would be easier to just not remove them >>>> in the first place (current behaviour). >>>> >>> >>> Yep, this is the updated behavior. And agree it looks wrong when you >>> show like this. (btw, this is only ethdev record of MAC filters, what >>> is updated in this patch, HW still may be keeping all filters.) >> >> Whether HW saves all filters depends on the implementation of the >> set_default() >> >> in the driver. According to the implementation of this API of all >> PMDs, some drivers >> >> will first remove the old default MAC in HW and then add the new one >> when calling >> >> the set_default(). I am not sure if the HW that didn't do this would >> remove the old >> >> default MAC. If not, we may need to standardize this API in the >> ethdev layer. >> >>> >>>> If they really need to be removed from the filter list when they >>>> are set_default(), then perhaps they should be restored to it when >>>> there is a new set_default(). >>>> >>> >>> I am for keeping current behavior. Application always can explicitly >>> remove a >>> MAC filter before setting it default if required. >> >> But application can not remove the duplicate MAC if the MAC is the >> current default >> >> MAC by rte_eth_dev_mac_addr_remove(). In this case, it will failed to >> remove. >> > > But can do other-way around, first remove (the non default one), later > 'rte_eth_dev_default_mac_addr_set()'. This introduces a usage dependency on the user. We don't have a statement in some place for the dependency. What's more, if the user does not follow this dependency, the user will no longer be able to remove the MAC. So it may be more appropriate to deal with problem in ethdev layer. **Scheme A:** The decision is left to the user, but there are usage dependency and irremovable possibility.** ** *Scheme B:* index = eth_dev_get_mac_addr_index(port_id, addr); if (index > 0) { mac_pool_sel_bk = dev->data->mac_pool_sel[index]; rte_eth_dev_mac_addr_remove(port_id, addr); } ret = (*dev->dev_ops->mac_addr_set)(dev, addr); if (ret < 0) { if (index > 0) { rte_eth_dev_mac_addr_add(port_id, addr, 0); dev->data->mac_pool_sel[index] = mac_pool_sel_bk; } return ret; } * Scheme C:* Use the method in this patch. It assumes that the driver has only one HW entry for a MAC. What do you think we should do? > >>> >>> >>>>>>> >>>>>>> What about following logic to be sure HW configuration and >>>>>>> 'dev->data->mac_addrs[]' is same: >>>>>>> >>>>>>> index = eth_dev_get_mac_addr_index(port_id, addr); >>>>>>> if (index > 0) >>>>>>> rte_eth_dev_mac_addr_remove(port_id, addr); >>>>>>> (*dev->dev_ops->mac_addr_set)(dev, addr); >>>>>> The logic above seems to be good. But if .mac_addr_set() failed to >>>>>> execute, the addr has been removed from HW and >>>>>> 'dev->data->mac_addrs[]'. >>>>>> It's not good. >>>>>> >>>>> >>>>> Agree. So may need to get a copy of 'addr' and add it back on >>>>> failure. >>>>> >>>>> The concern I have to call 'rte_eth_dev_mac_addr_remove()' after >>>>> 'dev_ops->mac_addr_set()' is, it may result different behavior on >>>>> different PMDs. >>>>> For the PMDs that clean the redundant MAC address via >>>>> 'dev_ops->mac_addr_set()' >>>>> may try to remove (although it will fail) the new set default MAC >>>>> address. >>>>> That is why first remove the MAC and later add it back as default >>>>> seems safer to me. >>>>> >>>>>> Hope for your reply. Thanks. >>>>>>>> /* Update default address in NIC data structure */ >>>>>>>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>>>>>>> >>>>>>> >>>>>>> . >>>>> >>>> >>> >>> . > > .
On 10/22/2021 3:04 AM, lihuisong (C) wrote:
>
> 在 2021/10/21 16:30, Ferruh Yigit 写道:
>> On 10/21/2021 3:05 AM, lihuisong (C) wrote:
>>>
>>> 在 2021/10/21 0:32, Ferruh Yigit 写道:
>>>> On 10/20/2021 11:15 AM, Kevin Traynor wrote:
>>>>> On 20/10/2021 08:41, Ferruh Yigit wrote:
>>>>>> On 10/20/2021 7:49 AM, lihuisong (C) wrote:
>>>>>>> Hi Ferruh
>>>>>>>
>>>>>>> 在 2021/10/20 1:45, Ferruh Yigit 写道:
>>>>>>>> On 10/11/2021 10:28 AM, Min Hu (Connor) wrote:
>>>>>>>>> From: Huisong Li <lihuisong@huawei.com>
>>>>>>>>>
>>>>>>>>> The dev->data->mac_addrs[0] will be changed to a new MAC address when
>>>>>>>>> applications modify the default MAC address by
>>>>>>>>> rte_eth_dev_default_mac_addr_set() API. However, If the new default
>>>>>>>>> MAC address has been added as a non-default MAC address by
>>>>>>>>> rte_eth_dev_mac_addr_add() API, the rte_eth_dev_default_mac_addr_set()
>>>>>>>>> API doesn't remove it from dev->data->mac_addrs[]. As a result, one MAC
>>>>>>>>> address occupies two index capacities in dev->data->mac_addrs[].
>>>>>>>>>
>>>>>>>>
>>>>>>>> Hi Connor,
>>>>>>>>
>>>>>>>> I see the problem, but can you please clarify what is the impact to the end user?
>>>>>>>>
>>>>>>>> If application does as following:
>>>>>>>> rte_eth_dev_mac_addr_add(MAC1);
>>>>>>>> rte_eth_dev_mac_addr_add(MAC2);
>>>>>>>> rte_eth_dev_mac_addr_add(MAC3);
>>>>>>>> rte_eth_dev_default_mac_addr_set(MAC2);
>>>>>>>>
>>>>>>>> The 'dev->data->mac_addrs[]' will have: "MAC2,MAC2,MAC3" which has 'MAC2' duplicated.
>>>>>>>>
>>>>>>>> Will this cause any problem for the application to receive the packets
>>>>>>>> with 'MAC2' address?
>>>>>>>> Or is the only problem one extra space used in 'dev->data->mac_addrs[]'
>>>>>>>> without any other impact to the application?
>>>>>>> I think it's just a waste of space.
>>>>>>
>>>>>> True, it is a waste. But if there is no other visible user impact, we can
>>>>>> handle the issue with lower priority and clarifying the impact in commit log
>>>>>> helps to others.
>>>>>>
>>>>>>>>
>>>>>>>>> This patch adds the logic of removing MAC addresses for this scenario.
>>>>>>>>>
>>>>>>>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
>>>>>>>>> Cc: stable@dpdk.org
>>>>>>>>>
>>>>>>>>> Signed-off-by: Huisong Li <lihuisong@huawei.com>
>>>>>>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>>>>>>>> ---
>>>>>>>>> v2:
>>>>>>>>> * fixed commit log.
>>>>>>>>> ---
>>>>>>>>> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++
>>>>>>>>> 1 file changed, 15 insertions(+)
>>>>>>>>>
>>>>>>>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>>>>>>>>> index 028907bc4b..7faff17d9a 100644
>>>>>>>>> --- a/lib/ethdev/rte_ethdev.c
>>>>>>>>> +++ b/lib/ethdev/rte_ethdev.c
>>>>>>>>> @@ -4340,6 +4340,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);
>>>>>>>>> @@ -4361,6 +4362,20 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
>>>>>>>>> if (ret < 0)
>>>>>>>>> return ret;
>>>>>>>>> + /*
>>>>>>>>> + * If the address has been added as a non-default MAC address by
>>>>>>>>> + * rte_eth_dev_mac_addr_add API, it should be removed from
>>>>>>>>> + * dev->data->mac_addrs[].
>>>>>>>>> + */
>>>>>>>>> + index = eth_dev_get_mac_addr_index(port_id, addr);
>>>>>>>>> + if (index > 0) {
>>>>>>>>> + /* remove address in NIC data structure */
>>>>>>>>> + rte_ether_addr_copy(&null_mac_addr,
>>>>>>>>> + &dev->data->mac_addrs[index]);
>>>>>>>>> + /* reset pool bitmap */
>>>>>>>>> + dev->data->mac_pool_sel[index] = 0;
>>>>>>>>> + }
>>>>>>>>> +
>>>>>>>>
>>>>>>>> Here only 'dev->data->mac_addrs[]' array is updated and it assumes
>>>>>>>> driver removes similar duplication itself, but I am not sure if this is
>>>>>>>> valid for all drivers.
>>>>>>>>
>>>>>>>> If driver is not removing the duplicate in the HW configuration, the driver
>>>>>>>> config and 'dev->data->mac_addrs[]' will diverge, which is not good.
>>>>>>> The same MAC address does not occupy two HW entries, which is also a
>>>>>>> waste for HW. After all, HW entry resources are also limited.
>>>>>>> The PMD should also take this into account.
>>>>>>> So, I think, we don't have to think about it here.
>>>>>>
>>>>>> I am not sure all PMD take this into account, I briefly checked the ixgbe
>>>>>> code and I am not sure if it handles this.
>>>>>>
>>>>>> Also it is possible to think that this responsibility is pushed to the
>>>>>> application, like application should remove a MAC address before setting
>>>>>> it as default MAC...
>>>>>>
>>>>>
>>>>> Yes, the API view is more important than saving one entry in an array. From API perspective with this patch,
>>>>>
>>>>> set_default(MAC1)
>>>>> add(MAC2)
>>>>> add(MAC3)
>>>>> add(MAC4)
>>>>> default=MAC1, Filters=MAC2, MAC3, MAC4
>>>>>
>>>>> set_default(MAC2)
>>>>> default=MAC2, Filters= MAC3, MAC4
>>>>>
>>>>> set_default(MAC3)
>>>>> default=MAC3, Filters= MAC4
>>>>>
>>>>> set_default(MAC4)
>>>>> default=MAC4, Filters=
>>>>>
>>>>> set_default(MAC5)
>>>>> default=MAC5, Filters=
>>>>>
>>>>> Did I get it right? If so, it seems wrong to silently remove the filters. In which case, it would be easier to just not remove them in the first place (current behaviour).
>>>>>
>>>>
>>>> Yep, this is the updated behavior. And agree it looks wrong when you
>>>> show like this. (btw, this is only ethdev record of MAC filters, what
>>>> is updated in this patch, HW still may be keeping all filters.)
>>>
>>> Whether HW saves all filters depends on the implementation of the set_default()
>>>
>>> in the driver. According to the implementation of this API of all PMDs, some drivers
>>>
>>> will first remove the old default MAC in HW and then add the new one when calling
>>>
>>> the set_default(). I am not sure if the HW that didn't do this would remove the old
>>>
>>> default MAC. If not, we may need to standardize this API in the ethdev layer.
>>>
>>>>
>>>>> If they really need to be removed from the filter list when they are set_default(), then perhaps they should be restored to it when there is a new set_default().
>>>>>
>>>>
>>>> I am for keeping current behavior. Application always can explicitly remove a
>>>> MAC filter before setting it default if required.
>>>
>>> But application can not remove the duplicate MAC if the MAC is the current default
>>>
>>> MAC by rte_eth_dev_mac_addr_remove(). In this case, it will failed to remove.
>>>
>>
>> But can do other-way around, first remove (the non default one), later
>> 'rte_eth_dev_default_mac_addr_set()'.
>
> This introduces a usage dependency on the user. We don't have a statement in some place
>
> for the dependency. What's more, if the user does not follow this dependency, the user
>
> will no longer be able to remove the MAC.
>
> So it may be more appropriate to deal with problem in ethdev layer.
>
>
> **Scheme A:**
>
> The decision is left to the user, but there are usage dependency and irremovable possibility.**
> **
>
> *Scheme B:*
>
> index = eth_dev_get_mac_addr_index(port_id, addr);
> if (index > 0) {
> mac_pool_sel_bk = dev->data->mac_pool_sel[index];
> rte_eth_dev_mac_addr_remove(port_id, addr);
> }
> ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
> if (ret < 0) {
> if (index > 0) {
> rte_eth_dev_mac_addr_add(port_id, addr, 0);
> dev->data->mac_pool_sel[index] = mac_pool_sel_bk;
> }
>
> return ret;
> }
>
> * Scheme C:*
>
> Use the method in this patch. It assumes that the driver has only one HW entry for a MAC.
>
> What do you think we should do?
>
If the impact is only loosing one entry in the array without any functional
effect, I am OK to keep behavior as it is.
If there is more motivation for fix, I would prefer option B to be sure all
drivers behave same by explicit remove.
在 2021/10/26 18:21, Ferruh Yigit 写道:
> On 10/22/2021 3:04 AM, lihuisong (C) wrote:
>>
>> 在 2021/10/21 16:30, Ferruh Yigit 写道:
>>> On 10/21/2021 3:05 AM, lihuisong (C) wrote:
>>>>
>>>> 在 2021/10/21 0:32, Ferruh Yigit 写道:
>>>>> On 10/20/2021 11:15 AM, Kevin Traynor wrote:
>>>>>> On 20/10/2021 08:41, Ferruh Yigit wrote:
>>>>>>> On 10/20/2021 7:49 AM, lihuisong (C) wrote:
>>>>>>>> Hi Ferruh
>>>>>>>>
>>>>>>>> 在 2021/10/20 1:45, Ferruh Yigit 写道:
>>>>>>>>> On 10/11/2021 10:28 AM, Min Hu (Connor) wrote:
>>>>>>>>>> From: Huisong Li <lihuisong@huawei.com>
>>>>>>>>>>
>>>>>>>>>> The dev->data->mac_addrs[0] will be changed to a new MAC
>>>>>>>>>> address when
>>>>>>>>>> applications modify the default MAC address by
>>>>>>>>>> rte_eth_dev_default_mac_addr_set() API. However, If the new
>>>>>>>>>> default
>>>>>>>>>> MAC address has been added as a non-default MAC address by
>>>>>>>>>> rte_eth_dev_mac_addr_add() API, the
>>>>>>>>>> rte_eth_dev_default_mac_addr_set()
>>>>>>>>>> API doesn't remove it from dev->data->mac_addrs[]. As a
>>>>>>>>>> result, one MAC
>>>>>>>>>> address occupies two index capacities in dev->data->mac_addrs[].
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Hi Connor,
>>>>>>>>>
>>>>>>>>> I see the problem, but can you please clarify what is the
>>>>>>>>> impact to the end user?
>>>>>>>>>
>>>>>>>>> If application does as following:
>>>>>>>>> rte_eth_dev_mac_addr_add(MAC1);
>>>>>>>>> rte_eth_dev_mac_addr_add(MAC2);
>>>>>>>>> rte_eth_dev_mac_addr_add(MAC3);
>>>>>>>>> rte_eth_dev_default_mac_addr_set(MAC2);
>>>>>>>>>
>>>>>>>>> The 'dev->data->mac_addrs[]' will have: "MAC2,MAC2,MAC3" which
>>>>>>>>> has 'MAC2' duplicated.
>>>>>>>>>
>>>>>>>>> Will this cause any problem for the application to receive the
>>>>>>>>> packets
>>>>>>>>> with 'MAC2' address?
>>>>>>>>> Or is the only problem one extra space used in
>>>>>>>>> 'dev->data->mac_addrs[]'
>>>>>>>>> without any other impact to the application?
>>>>>>>> I think it's just a waste of space.
>>>>>>>
>>>>>>> True, it is a waste. But if there is no other visible user
>>>>>>> impact, we can
>>>>>>> handle the issue with lower priority and clarifying the impact
>>>>>>> in commit log
>>>>>>> helps to others.
>>>>>>>
>>>>>>>>>
>>>>>>>>>> This patch adds the logic of removing MAC addresses for this
>>>>>>>>>> scenario.
>>>>>>>>>>
>>>>>>>>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
>>>>>>>>>> Cc: stable@dpdk.org
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Huisong Li <lihuisong@huawei.com>
>>>>>>>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>>>>>>>>> ---
>>>>>>>>>> v2:
>>>>>>>>>> * fixed commit log.
>>>>>>>>>> ---
>>>>>>>>>> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++
>>>>>>>>>> 1 file changed, 15 insertions(+)
>>>>>>>>>>
>>>>>>>>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>>>>>>>>>> index 028907bc4b..7faff17d9a 100644
>>>>>>>>>> --- a/lib/ethdev/rte_ethdev.c
>>>>>>>>>> +++ b/lib/ethdev/rte_ethdev.c
>>>>>>>>>> @@ -4340,6 +4340,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);
>>>>>>>>>> @@ -4361,6 +4362,20 @@
>>>>>>>>>> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct
>>>>>>>>>> rte_ether_addr *addr)
>>>>>>>>>> if (ret < 0)
>>>>>>>>>> return ret;
>>>>>>>>>> + /*
>>>>>>>>>> + * If the address has been added as a non-default MAC
>>>>>>>>>> address by
>>>>>>>>>> + * rte_eth_dev_mac_addr_add API, it should be removed from
>>>>>>>>>> + * dev->data->mac_addrs[].
>>>>>>>>>> + */
>>>>>>>>>> + index = eth_dev_get_mac_addr_index(port_id, addr);
>>>>>>>>>> + if (index > 0) {
>>>>>>>>>> + /* remove address in NIC data structure */
>>>>>>>>>> + rte_ether_addr_copy(&null_mac_addr,
>>>>>>>>>> + &dev->data->mac_addrs[index]);
>>>>>>>>>> + /* reset pool bitmap */
>>>>>>>>>> + dev->data->mac_pool_sel[index] = 0;
>>>>>>>>>> + }
>>>>>>>>>> +
>>>>>>>>>
>>>>>>>>> Here only 'dev->data->mac_addrs[]' array is updated and it
>>>>>>>>> assumes
>>>>>>>>> driver removes similar duplication itself, but I am not sure
>>>>>>>>> if this is
>>>>>>>>> valid for all drivers.
>>>>>>>>>
>>>>>>>>> If driver is not removing the duplicate in the HW
>>>>>>>>> configuration, the driver
>>>>>>>>> config and 'dev->data->mac_addrs[]' will diverge, which is not
>>>>>>>>> good.
>>>>>>>> The same MAC address does not occupy two HW entries, which is
>>>>>>>> also a
>>>>>>>> waste for HW. After all, HW entry resources are also limited.
>>>>>>>> The PMD should also take this into account.
>>>>>>>> So, I think, we don't have to think about it here.
>>>>>>>
>>>>>>> I am not sure all PMD take this into account, I briefly checked
>>>>>>> the ixgbe
>>>>>>> code and I am not sure if it handles this.
>>>>>>>
>>>>>>> Also it is possible to think that this responsibility is pushed
>>>>>>> to the
>>>>>>> application, like application should remove a MAC address before
>>>>>>> setting
>>>>>>> it as default MAC...
>>>>>>>
>>>>>>
>>>>>> Yes, the API view is more important than saving one entry in an
>>>>>> array. From API perspective with this patch,
>>>>>>
>>>>>> set_default(MAC1)
>>>>>> add(MAC2)
>>>>>> add(MAC3)
>>>>>> add(MAC4)
>>>>>> default=MAC1, Filters=MAC2, MAC3, MAC4
>>>>>>
>>>>>> set_default(MAC2)
>>>>>> default=MAC2, Filters= MAC3, MAC4
>>>>>>
>>>>>> set_default(MAC3)
>>>>>> default=MAC3, Filters= MAC4
>>>>>>
>>>>>> set_default(MAC4)
>>>>>> default=MAC4, Filters=
>>>>>>
>>>>>> set_default(MAC5)
>>>>>> default=MAC5, Filters=
>>>>>>
>>>>>> Did I get it right? If so, it seems wrong to silently remove the
>>>>>> filters. In which case, it would be easier to just not remove
>>>>>> them in the first place (current behaviour).
>>>>>>
>>>>>
>>>>> Yep, this is the updated behavior. And agree it looks wrong when you
>>>>> show like this. (btw, this is only ethdev record of MAC filters, what
>>>>> is updated in this patch, HW still may be keeping all filters.)
>>>>
>>>> Whether HW saves all filters depends on the implementation of the
>>>> set_default()
>>>>
>>>> in the driver. According to the implementation of this API of all
>>>> PMDs, some drivers
>>>>
>>>> will first remove the old default MAC in HW and then add the new
>>>> one when calling
>>>>
>>>> the set_default(). I am not sure if the HW that didn't do this
>>>> would remove the old
>>>>
>>>> default MAC. If not, we may need to standardize this API in the
>>>> ethdev layer.
>>>>
>>>>>
>>>>>> If they really need to be removed from the filter list when they
>>>>>> are set_default(), then perhaps they should be restored to it
>>>>>> when there is a new set_default().
>>>>>>
>>>>>
>>>>> I am for keeping current behavior. Application always can
>>>>> explicitly remove a
>>>>> MAC filter before setting it default if required.
>>>>
>>>> But application can not remove the duplicate MAC if the MAC is the
>>>> current default
>>>>
>>>> MAC by rte_eth_dev_mac_addr_remove(). In this case, it will failed
>>>> to remove.
>>>>
>>>
>>> But can do other-way around, first remove (the non default one), later
>>> 'rte_eth_dev_default_mac_addr_set()'.
>>
>> This introduces a usage dependency on the user. We don't have a
>> statement in some place
>>
>> for the dependency. What's more, if the user does not follow this
>> dependency, the user
>>
>> will no longer be able to remove the MAC.
>>
>> So it may be more appropriate to deal with problem in ethdev layer.
>>
>>
>> **Scheme A:**
>>
>> The decision is left to the user, but there are usage dependency and
>> irremovable possibility.**
>> **
>>
>> *Scheme B:*
>>
>> index = eth_dev_get_mac_addr_index(port_id, addr);
>> if (index > 0) {
>> mac_pool_sel_bk = dev->data->mac_pool_sel[index];
>> rte_eth_dev_mac_addr_remove(port_id, addr);
>> }
>> ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
>> if (ret < 0) {
>> if (index > 0) {
>> rte_eth_dev_mac_addr_add(port_id, addr, 0);
>> dev->data->mac_pool_sel[index] = mac_pool_sel_bk;
>> }
>>
>> return ret;
>> }
>>
>> * Scheme C:*
>>
>> Use the method in this patch. It assumes that the driver has only
>> one HW entry for a MAC.
>>
>> What do you think we should do?
>>
>
> If the impact is only loosing one entry in the array without any
> functional
> effect, I am OK to keep behavior as it is.
>
> If there is more motivation for fix, I would prefer option B to be
> sure all
> drivers behave same by explicit remove.
> .
Hi, Ferruh
There may be a functional problem in one scenario if we don't fix this.
Testpmd does the following steps:
1) add MAC1/2/3
mac_addr add 0 MAC1
mac_addr add 0 MAC2
mac_addr add 0 MAC3
2) then set new default MAC3
mac_addr set 0 MAC3
3)show mac_addrs list
MAC3
MAC1
MAC2
MAC3
4)then set new default MAC4
mac_addr set 0 MAC4
5) now, the mac_addrs list is as follows:
MAC4
MAC1
MAC2
MAC3
As a result, the network engine cannot receive packets from MAC3.
But application can see the MAC3 in mac_addrs list.
Btw, rte_eth_dev_default_mac_addr_set() will replace the old default MAC
with
the new one, and the old one will be deleted.
So, we should fix it. What do you think? Thanks.
Hi, Ferruh,
what do you think of this patch?
在 2021/11/8 14:55, lihuisong (C) 写道:
>
> 在 2021/10/26 18:21, Ferruh Yigit 写道:
>> On 10/22/2021 3:04 AM, lihuisong (C) wrote:
>>>
>>> 在 2021/10/21 16:30, Ferruh Yigit 写道:
>>>> On 10/21/2021 3:05 AM, lihuisong (C) wrote:
>>>>>
>>>>> 在 2021/10/21 0:32, Ferruh Yigit 写道:
>>>>>> On 10/20/2021 11:15 AM, Kevin Traynor wrote:
>>>>>>> On 20/10/2021 08:41, Ferruh Yigit wrote:
>>>>>>>> On 10/20/2021 7:49 AM, lihuisong (C) wrote:
>>>>>>>>> Hi Ferruh
>>>>>>>>>
>>>>>>>>> 在 2021/10/20 1:45, Ferruh Yigit 写道:
>>>>>>>>>> On 10/11/2021 10:28 AM, Min Hu (Connor) wrote:
>>>>>>>>>>> From: Huisong Li <lihuisong@huawei.com>
>>>>>>>>>>>
>>>>>>>>>>> The dev->data->mac_addrs[0] will be changed to a new MAC
>>>>>>>>>>> address when
>>>>>>>>>>> applications modify the default MAC address by
>>>>>>>>>>> rte_eth_dev_default_mac_addr_set() API. However, If the new
>>>>>>>>>>> default
>>>>>>>>>>> MAC address has been added as a non-default MAC address by
>>>>>>>>>>> rte_eth_dev_mac_addr_add() API, the
>>>>>>>>>>> rte_eth_dev_default_mac_addr_set()
>>>>>>>>>>> API doesn't remove it from dev->data->mac_addrs[]. As a
>>>>>>>>>>> result, one MAC
>>>>>>>>>>> address occupies two index capacities in dev->data->mac_addrs[].
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Hi Connor,
>>>>>>>>>>
>>>>>>>>>> I see the problem, but can you please clarify what is the
>>>>>>>>>> impact to the end user?
>>>>>>>>>>
>>>>>>>>>> If application does as following:
>>>>>>>>>> rte_eth_dev_mac_addr_add(MAC1);
>>>>>>>>>> rte_eth_dev_mac_addr_add(MAC2);
>>>>>>>>>> rte_eth_dev_mac_addr_add(MAC3);
>>>>>>>>>> rte_eth_dev_default_mac_addr_set(MAC2);
>>>>>>>>>>
>>>>>>>>>> The 'dev->data->mac_addrs[]' will have: "MAC2,MAC2,MAC3" which
>>>>>>>>>> has 'MAC2' duplicated.
>>>>>>>>>>
>>>>>>>>>> Will this cause any problem for the application to receive the
>>>>>>>>>> packets
>>>>>>>>>> with 'MAC2' address?
>>>>>>>>>> Or is the only problem one extra space used in
>>>>>>>>>> 'dev->data->mac_addrs[]'
>>>>>>>>>> without any other impact to the application?
>>>>>>>>> I think it's just a waste of space.
>>>>>>>>
>>>>>>>> True, it is a waste. But if there is no other visible user
>>>>>>>> impact, we can
>>>>>>>> handle the issue with lower priority and clarifying the impact
>>>>>>>> in commit log
>>>>>>>> helps to others.
>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> This patch adds the logic of removing MAC addresses for this
>>>>>>>>>>> scenario.
>>>>>>>>>>>
>>>>>>>>>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
>>>>>>>>>>> Cc: stable@dpdk.org
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Huisong Li <lihuisong@huawei.com>
>>>>>>>>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>>>>>>>>>> ---
>>>>>>>>>>> v2:
>>>>>>>>>>> * fixed commit log.
>>>>>>>>>>> ---
>>>>>>>>>>> lib/ethdev/rte_ethdev.c | 15 +++++++++++++++
>>>>>>>>>>> 1 file changed, 15 insertions(+)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>>>>>>>>>>> index 028907bc4b..7faff17d9a 100644
>>>>>>>>>>> --- a/lib/ethdev/rte_ethdev.c
>>>>>>>>>>> +++ b/lib/ethdev/rte_ethdev.c
>>>>>>>>>>> @@ -4340,6 +4340,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);
>>>>>>>>>>> @@ -4361,6 +4362,20 @@
>>>>>>>>>>> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct
>>>>>>>>>>> rte_ether_addr *addr)
>>>>>>>>>>> if (ret < 0)
>>>>>>>>>>> return ret;
>>>>>>>>>>> + /*
>>>>>>>>>>> + * If the address has been added as a non-default MAC
>>>>>>>>>>> address by
>>>>>>>>>>> + * rte_eth_dev_mac_addr_add API, it should be removed from
>>>>>>>>>>> + * dev->data->mac_addrs[].
>>>>>>>>>>> + */
>>>>>>>>>>> + index = eth_dev_get_mac_addr_index(port_id, addr);
>>>>>>>>>>> + if (index > 0) {
>>>>>>>>>>> + /* remove address in NIC data structure */
>>>>>>>>>>> + rte_ether_addr_copy(&null_mac_addr,
>>>>>>>>>>> + &dev->data->mac_addrs[index]);
>>>>>>>>>>> + /* reset pool bitmap */
>>>>>>>>>>> + dev->data->mac_pool_sel[index] = 0;
>>>>>>>>>>> + }
>>>>>>>>>>> +
>>>>>>>>>>
>>>>>>>>>> Here only 'dev->data->mac_addrs[]' array is updated and it
>>>>>>>>>> assumes
>>>>>>>>>> driver removes similar duplication itself, but I am not sure
>>>>>>>>>> if this is
>>>>>>>>>> valid for all drivers.
>>>>>>>>>>
>>>>>>>>>> If driver is not removing the duplicate in the HW
>>>>>>>>>> configuration, the driver
>>>>>>>>>> config and 'dev->data->mac_addrs[]' will diverge, which is not
>>>>>>>>>> good.
>>>>>>>>> The same MAC address does not occupy two HW entries, which is
>>>>>>>>> also a
>>>>>>>>> waste for HW. After all, HW entry resources are also limited.
>>>>>>>>> The PMD should also take this into account.
>>>>>>>>> So, I think, we don't have to think about it here.
>>>>>>>>
>>>>>>>> I am not sure all PMD take this into account, I briefly checked
>>>>>>>> the ixgbe
>>>>>>>> code and I am not sure if it handles this.
>>>>>>>>
>>>>>>>> Also it is possible to think that this responsibility is pushed
>>>>>>>> to the
>>>>>>>> application, like application should remove a MAC address before
>>>>>>>> setting
>>>>>>>> it as default MAC...
>>>>>>>>
>>>>>>>
>>>>>>> Yes, the API view is more important than saving one entry in an
>>>>>>> array. From API perspective with this patch,
>>>>>>>
>>>>>>> set_default(MAC1)
>>>>>>> add(MAC2)
>>>>>>> add(MAC3)
>>>>>>> add(MAC4)
>>>>>>> default=MAC1, Filters=MAC2, MAC3, MAC4
>>>>>>>
>>>>>>> set_default(MAC2)
>>>>>>> default=MAC2, Filters= MAC3, MAC4
>>>>>>>
>>>>>>> set_default(MAC3)
>>>>>>> default=MAC3, Filters= MAC4
>>>>>>>
>>>>>>> set_default(MAC4)
>>>>>>> default=MAC4, Filters=
>>>>>>>
>>>>>>> set_default(MAC5)
>>>>>>> default=MAC5, Filters=
>>>>>>>
>>>>>>> Did I get it right? If so, it seems wrong to silently remove the
>>>>>>> filters. In which case, it would be easier to just not remove
>>>>>>> them in the first place (current behaviour).
>>>>>>>
>>>>>>
>>>>>> Yep, this is the updated behavior. And agree it looks wrong when you
>>>>>> show like this. (btw, this is only ethdev record of MAC filters, what
>>>>>> is updated in this patch, HW still may be keeping all filters.)
>>>>>
>>>>> Whether HW saves all filters depends on the implementation of the
>>>>> set_default()
>>>>>
>>>>> in the driver. According to the implementation of this API of all
>>>>> PMDs, some drivers
>>>>>
>>>>> will first remove the old default MAC in HW and then add the new
>>>>> one when calling
>>>>>
>>>>> the set_default(). I am not sure if the HW that didn't do this
>>>>> would remove the old
>>>>>
>>>>> default MAC. If not, we may need to standardize this API in the
>>>>> ethdev layer.
>>>>>
>>>>>>
>>>>>>> If they really need to be removed from the filter list when they
>>>>>>> are set_default(), then perhaps they should be restored to it
>>>>>>> when there is a new set_default().
>>>>>>>
>>>>>>
>>>>>> I am for keeping current behavior. Application always can
>>>>>> explicitly remove a
>>>>>> MAC filter before setting it default if required.
>>>>>
>>>>> But application can not remove the duplicate MAC if the MAC is the
>>>>> current default
>>>>>
>>>>> MAC by rte_eth_dev_mac_addr_remove(). In this case, it will failed
>>>>> to remove.
>>>>>
>>>>
>>>> But can do other-way around, first remove (the non default one), later
>>>> 'rte_eth_dev_default_mac_addr_set()'.
>>>
>>> This introduces a usage dependency on the user. We don't have a
>>> statement in some place
>>>
>>> for the dependency. What's more, if the user does not follow this
>>> dependency, the user
>>>
>>> will no longer be able to remove the MAC.
>>>
>>> So it may be more appropriate to deal with problem in ethdev layer.
>>>
>>>
>>> **Scheme A:**
>>>
>>> The decision is left to the user, but there are usage dependency and
>>> irremovable possibility.**
>>> **
>>>
>>> *Scheme B:*
>>>
>>> index = eth_dev_get_mac_addr_index(port_id, addr);
>>> if (index > 0) {
>>> mac_pool_sel_bk = dev->data->mac_pool_sel[index];
>>> rte_eth_dev_mac_addr_remove(port_id, addr);
>>> }
>>> ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
>>> if (ret < 0) {
>>> if (index > 0) {
>>> rte_eth_dev_mac_addr_add(port_id, addr, 0);
>>> dev->data->mac_pool_sel[index] = mac_pool_sel_bk;
>>> }
>>>
>>> return ret;
>>> }
>>>
>>> * Scheme C:*
>>>
>>> Use the method in this patch. It assumes that the driver has only
>>> one HW entry for a MAC.
>>>
>>> What do you think we should do?
>>>
>>
>> If the impact is only loosing one entry in the array without any
>> functional
>> effect, I am OK to keep behavior as it is.
>>
>> If there is more motivation for fix, I would prefer option B to be
>> sure all
>> drivers behave same by explicit remove.
>> .
>
> Hi, Ferruh
>
> There may be a functional problem in one scenario if we don't fix this.
>
> Testpmd does the following steps:
>
> 1) add MAC1/2/3
>
> mac_addr add 0 MAC1
>
> mac_addr add 0 MAC2
>
> mac_addr add 0 MAC3
>
> 2) then set new default MAC3
>
> mac_addr set 0 MAC3
>
> 3)show mac_addrs list
>
> MAC3
>
> MAC1
>
> MAC2
>
> MAC3
>
> 4)then set new default MAC4
>
> mac_addr set 0 MAC4
>
> 5) now, the mac_addrs list is as follows:
>
> MAC4
>
> MAC1
>
> MAC2
>
> MAC3
>
>
> As a result, the network engine cannot receive packets from MAC3.
>
> But application can see the MAC3 in mac_addrs list.
>
> Btw, rte_eth_dev_default_mac_addr_set() will replace the old default MAC
> with
>
> the new one, and the old one will be deleted.
>
>
> So, we should fix it. What do you think? Thanks.
>
>
>
>
>
>
>
> .
From: Huisong Li <lihuisong@huawei.com> The index zero of rte_eth_dev_data::mac_addrs array is as the default MAC index, and other indexes can't be the same as the address corresponding to index 0. If we break it, may cause following problems: 1) waste of MAC address spaces. 2) a fake MAC address in the MAC list, isn't in hardware MAC entries. 3) a MAC address is assigned to diffent pool. Huisong Li (2): ethdev: fix one address occupies two indexes in MAC addrs ethdev: document default and non-default MAC address --- v3: - first explicitly remove the non-default MAC, then set default one. - document default and non-default MAC address v2: - fixed commit log. lib/ethdev/ethdev_driver.h | 7 ++++++- lib/ethdev/rte_ethdev.c | 39 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) -- 2.33.0
From: Huisong Li <lihuisong@huawei.com> The dev->data->mac_addrs[0] will be changed to a new MAC address when applications modify the default MAC address by rte_eth_dev_default_mac_addr_set(). However, if the new default one has been added as a non-default MAC address by rte_eth_dev_mac_addr_add(), the the rte_eth_dev_default_mac_addr_set() doesn't remove it from the mac_addrs list. As a result, one MAC address occupies two indexes in the list. Like: add(MAC1) add(MAC2) add(MAC3) add(MAC4) set_default(MAC3) default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the old default MAC when set default MAC. If user continues to do set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, MAC2, MAC3, MAC4). At this moment, user can still view MAC3 from the list, but packets with MAC3 aren't actually received by the PMD. Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") Cc: stable@dpdk.org Signed-off-by: Huisong Li <lihuisong@huawei.com> Signed-off-by: Min Hu <humin29@huawei.com> --- lib/ethdev/rte_ethdev.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 29a3d80466..ab4a16487f 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -4248,7 +4248,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) int rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) { + uint64_t mac_pool_sel_bk = 0; struct rte_eth_dev *dev; + uint32_t pool; + int index; int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); @@ -4266,16 +4269,48 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP); + /* + * If the address has been added as a non-default MAC address by + * rte_eth_dev_mac_addr_add API, it should be removed from + * dev->data->mac_addrs[]. + */ + index = eth_dev_get_mac_addr_index(port_id, addr); + if (index > 0) { + /* remove address in NIC data structure */ + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; + ret = rte_eth_dev_mac_addr_remove(port_id, addr); + if (ret < 0) { + RTE_ETHDEV_LOG(ERR, + "Delete MAC address from the MAC list of ethdev port %u.\n", + port_id); + return ret; + } + /* reset pool bitmap */ + dev->data->mac_pool_sel[index] = 0; + } + ret = (*dev->dev_ops->mac_addr_set)(dev, addr); if (ret < 0) - return ret; + goto back; /* Update default address in NIC data structure */ rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); return 0; -} +back: + if (index > 0) { + pool = 0; + do { + if (mac_pool_sel_bk & UINT64_C(1)) + rte_eth_dev_mac_addr_add(port_id, addr, pool); + mac_pool_sel_bk >>= 1; + pool++; + } while (mac_pool_sel_bk); + } + + return ret; +} /* * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find -- 2.33.0
From: Huisong Li <lihuisong@huawei.com> The rte_eth_dev_data::mac_addrs is a MAC address array. The index zero of this array is as the default address index, and other indexes can't be the same as the address corresponding to index 0. If we break it, may cause following problems: 1) waste of MAC address spaces. 2) a fake MAC address in the MAC list, isn't in hardware MAC entries. 3) a MAC address is assigned to diffent pool. Signed-off-by: Huisong Li <lihuisong@huawei.com> Signed-off-by: Min Hu <humin29@huawei.com> --- lib/ethdev/ethdev_driver.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index 69d9dc21d8..d49e9138c6 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -115,7 +115,12 @@ struct rte_eth_dev_data { uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ + /** + * Device Ethernet link address. The index zero of the array is as the + * index of the default address, and other indexes can't be the same + * as the address corresponding to index 0. + * @see rte_eth_dev_release_port() + */ struct rte_ether_addr *mac_addrs; /** Bitmap associating MAC addresses to pools */ uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; -- 2.33.0
On 5/14/22 05:00, Min Hu (Connor) wrote:
> From: Huisong Li <lihuisong@huawei.com>
>
> The index zero of rte_eth_dev_data::mac_addrs array is as the default MAC
> index, and other indexes can't be the same as the address corresponding to
> index 0. If we break it, may cause following problems:
> 1) waste of MAC address spaces.
> 2) a fake MAC address in the MAC list, isn't in hardware MAC entries.
> 3) a MAC address is assigned to diffent pool.
The series looks broken in the patchwork. As the result unit tests
are run in a strange way. Please, format patches once again and send v4.
The index zero of rte_eth_dev_data::mac_addrs array is as the default MAC index, and other indexes can't be the same as the address corresponding to index 0. If we break it, may cause following problems: 1) waste of MAC address spaces. 2) a fake MAC address in the MAC list, isn't in hardware MAC entries. 3) a MAC address is assigned to diffent pool. Huisong Li (2): ethdev: fix one address occupies two indexes in MAC addrs ethdev: document default and non-default MAC address --- v4: - fix broken in the patchwork v3: - first explicitly remove the non-default MAC, then set default one. - document default and non-default MAC address v2: - fixed commit log. lib/ethdev/ethdev_driver.h | 7 ++++++- lib/ethdev/rte_ethdev.c | 39 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) -- 2.33.0
From: Huisong Li <lihuisong@huawei.com> The dev->data->mac_addrs[0] will be changed to a new MAC address when applications modify the default MAC address by rte_eth_dev_default_mac_addr_set(). However, if the new default one has been added as a non-default MAC address by rte_eth_dev_mac_addr_add(), the the rte_eth_dev_default_mac_addr_set() doesn't remove it from the mac_addrs list. As a result, one MAC address occupies two indexes in the list. Like: add(MAC1) add(MAC2) add(MAC3) add(MAC4) set_default(MAC3) default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the old default MAC when set default MAC. If user continues to do set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, MAC2, MAC3, MAC4). At this moment, user can still view MAC3 from the list, but packets with MAC3 aren't actually received by the PMD. Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") Cc: stable@dpdk.org Signed-off-by: Huisong Li <lihuisong@huawei.com> Signed-off-by: Min Hu <humin29@huawei.com> --- lib/ethdev/rte_ethdev.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 46c088dc88..fc9ca8d6fd 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -4260,7 +4260,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) int rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) { + uint64_t mac_pool_sel_bk = 0; struct rte_eth_dev *dev; + uint32_t pool; + int index; int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); @@ -4278,16 +4281,48 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP); + /* + * If the address has been added as a non-default MAC address by + * rte_eth_dev_mac_addr_add API, it should be removed from + * dev->data->mac_addrs[]. + */ + index = eth_dev_get_mac_addr_index(port_id, addr); + if (index > 0) { + /* remove address in NIC data structure */ + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; + ret = rte_eth_dev_mac_addr_remove(port_id, addr); + if (ret < 0) { + RTE_ETHDEV_LOG(ERR, + "Delete MAC address from the MAC list of ethdev port %u.\n", + port_id); + return ret; + } + /* reset pool bitmap */ + dev->data->mac_pool_sel[index] = 0; + } + ret = (*dev->dev_ops->mac_addr_set)(dev, addr); if (ret < 0) - return ret; + goto back; /* Update default address in NIC data structure */ rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); return 0; -} +back: + if (index > 0) { + pool = 0; + do { + if (mac_pool_sel_bk & UINT64_C(1)) + rte_eth_dev_mac_addr_add(port_id, addr, pool); + mac_pool_sel_bk >>= 1; + pool++; + } while (mac_pool_sel_bk); + } + + return ret; +} /* * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find -- 2.33.0
From: Huisong Li <lihuisong@huawei.com> The rte_eth_dev_data::mac_addrs is a MAC address array. The index zero of this array is as the default address index, and other indexes can't be the same as the address corresponding to index 0. If we break it, may cause following problems: 1) waste of MAC address spaces. 2) a fake MAC address in the MAC list, isn't in hardware MAC entries. 3) a MAC address is assigned to diffent pool. Signed-off-by: Huisong Li <lihuisong@huawei.com> Signed-off-by: Min Hu <humin29@huawei.com> --- lib/ethdev/ethdev_driver.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index 69d9dc21d8..d49e9138c6 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -115,7 +115,12 @@ struct rte_eth_dev_data { uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ + /** + * Device Ethernet link address. The index zero of the array is as the + * index of the default address, and other indexes can't be the same + * as the address corresponding to index 0. + * @see rte_eth_dev_release_port() + */ struct rte_ether_addr *mac_addrs; /** Bitmap associating MAC addresses to pools */ uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; -- 2.33.0
Hi, Andrew,
v4 has been sent. Thanks.
在 2022/5/31 23:22, Andrew Rybchenko 写道:
> On 5/14/22 05:00, Min Hu (Connor) wrote:
>> From: Huisong Li <lihuisong@huawei.com>
>>
>> The index zero of rte_eth_dev_data::mac_addrs array is as the default MAC
>> index, and other indexes can't be the same as the address
>> corresponding to
>> index 0. If we break it, may cause following problems:
>> 1) waste of MAC address spaces.
>> 2) a fake MAC address in the MAC list, isn't in hardware MAC entries.
>> 3) a MAC address is assigned to diffent pool.
>
> The series looks broken in the patchwork. As the result unit tests
> are run in a strange way. Please, format patches once again and send v4.
>
> .
On 6/1/22 09:39, Min Hu (Connor) wrote:
> The index zero of rte_eth_dev_data::mac_addrs array is as the default MAC
> index, and other indexes can't be the same as the address corresponding to
> index 0. If we break it, may cause following problems:
> 1) waste of MAC address spaces.
> 2) a fake MAC address in the MAC list, isn't in hardware MAC entries.
> 3) a MAC address is assigned to diffent pool.
>
> Huisong Li (2):
> ethdev: fix one address occupies two indexes in MAC addrs
> ethdev: document default and non-default MAC address
> ---
> v4:
> - fix broken in the patchwork
>
> v3:
> - first explicitly remove the non-default MAC, then set default one.
> - document default and non-default MAC address
>
> v2:
> - fixed commit log.
>
> lib/ethdev/ethdev_driver.h | 7 ++++++-
> lib/ethdev/rte_ethdev.c | 39 ++++++++++++++++++++++++++++++++++++--
> 2 files changed, 43 insertions(+), 3 deletions(-)
>
Please, don't forget to add maintainers in Cc when you send patches.
--cc-cmd ./devtools/get-maintainers.sh
or
--to-cmd ./devtools/get-maintainers.sh
(I'd prefer To and have dev@dpdk.org in Cc)
Don't worry about it right now. I'll add Thomas and Ferrh in my replies.
On 6/1/22 09:39, Min Hu (Connor) wrote: > From: Huisong Li <lihuisong@huawei.com> > > The dev->data->mac_addrs[0] will be changed to a new MAC address when > applications modify the default MAC address by > rte_eth_dev_default_mac_addr_set(). However, if the new default one has > been added as a non-default MAC address by rte_eth_dev_mac_addr_add(), the > the rte_eth_dev_default_mac_addr_set() doesn't remove it from the mac_addrs > list. As a result, one MAC address occupies two indexes in the list. Like: > add(MAC1) > add(MAC2) > add(MAC3) > add(MAC4) > set_default(MAC3) > default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 > > In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the > old default MAC when set default MAC. If user continues to do > set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, > MAC2, MAC3, MAC4). At this moment, user can still view MAC3 from the list, > but packets with MAC3 aren't actually received by the PMD. IMHO, the main problem is inconsistency which exists right now. rte_eth_dev_mac_addr_add() checks for duplicate MAC addition including the default one (index zero) and extends the entry pool mask (including zero entry case). However, the patch above does not extend zero entry pool mask. So, the result will depend on order which is bad: A. Set default to A, add MAC A with pool 2 => pool mask has 2 B. Add MAC A with pool 2, set default to A => pool mask is empty Am I missing something in the code? What is the right/intended behaviour? > > Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") > Cc: stable@dpdk.org > > Signed-off-by: Huisong Li <lihuisong@huawei.com> > Signed-off-by: Min Hu <humin29@huawei.com> > --- > lib/ethdev/rte_ethdev.c | 39 +++++++++++++++++++++++++++++++++++++-- > 1 file changed, 37 insertions(+), 2 deletions(-) > > diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c > index 46c088dc88..fc9ca8d6fd 100644 > --- a/lib/ethdev/rte_ethdev.c > +++ b/lib/ethdev/rte_ethdev.c > @@ -4260,7 +4260,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) > int > rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) > { > + uint64_t mac_pool_sel_bk = 0; > struct rte_eth_dev *dev; > + uint32_t pool; > + int index; > int ret; > > RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); > @@ -4278,16 +4281,48 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) > > RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP); > > + /* > + * If the address has been added as a non-default MAC address by > + * rte_eth_dev_mac_addr_add API, it should be removed from > + * dev->data->mac_addrs[]. > + */ > + index = eth_dev_get_mac_addr_index(port_id, addr); > + if (index > 0) { > + /* remove address in NIC data structure */ > + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; > + ret = rte_eth_dev_mac_addr_remove(port_id, addr); > + if (ret < 0) { > + RTE_ETHDEV_LOG(ERR, > + "Delete MAC address from the MAC list of ethdev port %u.\n", > + port_id); > + return ret; > + } > + /* reset pool bitmap */ > + dev->data->mac_pool_sel[index] = 0; > + } > + > ret = (*dev->dev_ops->mac_addr_set)(dev, addr); > if (ret < 0) > - return ret; > + goto back; > > /* Update default address in NIC data structure */ > rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); > > return 0; > -} > > +back: > + if (index > 0) { > + pool = 0; > + do { > + if (mac_pool_sel_bk & UINT64_C(1)) > + rte_eth_dev_mac_addr_add(port_id, addr, pool); Don't we want to have at least error logs in the case of rollback failure here? > + mac_pool_sel_bk >>= 1; > + pool++; > + } while (mac_pool_sel_bk); Please, compare vs 0 explicitly. > + } > + > + return ret; > +} > > /* > * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
On 6/1/22 09:39, Min Hu (Connor) wrote:
> From: Huisong Li <lihuisong@huawei.com>
>
> The rte_eth_dev_data::mac_addrs is a MAC address array. The index zero of
> this array is as the default address index, and other indexes can't be the
> same as the address corresponding to index 0. If we break it, may cause
> following problems:
> 1) waste of MAC address spaces.
> 2) a fake MAC address in the MAC list, isn't in hardware MAC entries.
> 3) a MAC address is assigned to diffent pool.
>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> Signed-off-by: Min Hu <humin29@huawei.com>
> ---
> lib/ethdev/ethdev_driver.h | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> index 69d9dc21d8..d49e9138c6 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -115,7 +115,12 @@ struct rte_eth_dev_data {
>
> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */
>
> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */
> + /**
> + * Device Ethernet link address. The index zero of the array is as the
> + * index of the default address, and other indexes can't be the same
> + * as the address corresponding to index 0.
> + * @see rte_eth_dev_release_port()
> + */
> struct rte_ether_addr *mac_addrs;
> /** Bitmap associating MAC addresses to pools */
> uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR];
The patch itself does not make sense since it documents what happens
in the first patch of the series. So, it should be a part of the first
patch.
在 2022/6/2 1:49, Andrew Rybchenko 写道: > On 6/1/22 09:39, Min Hu (Connor) wrote: >> From: Huisong Li <lihuisong@huawei.com> >> >> The dev->data->mac_addrs[0] will be changed to a new MAC address when >> applications modify the default MAC address by >> rte_eth_dev_default_mac_addr_set(). However, if the new default one has >> been added as a non-default MAC address by >> rte_eth_dev_mac_addr_add(), the >> the rte_eth_dev_default_mac_addr_set() doesn't remove it from the >> mac_addrs >> list. As a result, one MAC address occupies two indexes in the list. >> Like: >> add(MAC1) >> add(MAC2) >> add(MAC3) >> add(MAC4) >> set_default(MAC3) >> default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 >> >> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the >> old default MAC when set default MAC. If user continues to do >> set_default(MAC5), and the mac_addrs list is default=MAC5, >> filters=(MAC1, >> MAC2, MAC3, MAC4). At this moment, user can still view MAC3 from the >> list, >> but packets with MAC3 aren't actually received by the PMD. > > IMHO, the main problem is inconsistency which exists right now. > rte_eth_dev_mac_addr_add() checks for duplicate MAC addition > including the default one (index zero) and extends the entry > pool mask (including zero entry case). > > However, the patch above does not extend zero entry pool mask. > So, the result will depend on order which is bad: > A. Set default to A, add MAC A with pool 2 => pool mask has 2 > B. Add MAC A with pool 2, set default to A => pool mask is empty > I don't know how this MAC pool works in which driver. However, the 'eth_dev_mac_restore' API show that 1) the default MAC has only pool zero if set it by the 'mac_addr_add', 2) the default one hasn't pool information if set it by 'default_mac_addr_set'. Do you mean we should inherit its pool mask in this case? > Am I missing something in the code? > What is the right/intended behaviour? > >> >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >> Cc: stable@dpdk.org >> >> Signed-off-by: Huisong Li <lihuisong@huawei.com> >> Signed-off-by: Min Hu <humin29@huawei.com> >> --- >> lib/ethdev/rte_ethdev.c | 39 +++++++++++++++++++++++++++++++++++++-- >> 1 file changed, 37 insertions(+), 2 deletions(-) >> >> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >> index 46c088dc88..fc9ca8d6fd 100644 >> --- a/lib/ethdev/rte_ethdev.c >> +++ b/lib/ethdev/rte_ethdev.c >> @@ -4260,7 +4260,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, >> struct rte_ether_addr *addr) >> int >> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct >> rte_ether_addr *addr) >> { >> + uint64_t mac_pool_sel_bk = 0; >> struct rte_eth_dev *dev; >> + uint32_t pool; >> + int index; >> int ret; >> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); >> @@ -4278,16 +4281,48 @@ rte_eth_dev_default_mac_addr_set(uint16_t >> port_id, struct rte_ether_addr *addr) >> RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP); >> + /* >> + * If the address has been added as a non-default MAC address by >> + * rte_eth_dev_mac_addr_add API, it should be removed from >> + * dev->data->mac_addrs[]. >> + */ >> + index = eth_dev_get_mac_addr_index(port_id, addr); >> + if (index > 0) { >> + /* remove address in NIC data structure */ >> + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; >> + ret = rte_eth_dev_mac_addr_remove(port_id, addr); >> + if (ret < 0) { >> + RTE_ETHDEV_LOG(ERR, >> + "Delete MAC address from the MAC list of ethdev port >> %u.\n", >> + port_id); >> + return ret; >> + } >> + /* reset pool bitmap */ >> + dev->data->mac_pool_sel[index] = 0; >> + } >> + >> ret = (*dev->dev_ops->mac_addr_set)(dev, addr); >> if (ret < 0) >> - return ret; >> + goto back; >> /* Update default address in NIC data structure */ >> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >> return 0; >> -} >> +back: >> + if (index > 0) { >> + pool = 0; >> + do { >> + if (mac_pool_sel_bk & UINT64_C(1)) >> + rte_eth_dev_mac_addr_add(port_id, addr, pool); > > Don't we want to have at least error logs in the case of rollback > failure here? It doesn't feel necessary. It may trigger the printing of a large number of error logs in abnormal scenarios. > >> + mac_pool_sel_bk >>= 1; >> + pool++; >> + } while (mac_pool_sel_bk); > > Please, compare vs 0 explicitly. Ack > >> + } >> + >> + return ret; >> +} >> /* >> * Returns index into MAC address array of addr. Use >> 00:00:00:00:00:00 to find > > .
Cc more driver maintainers On 6/2/22 06:16, lihuisong (C) wrote: > > 在 2022/6/2 1:49, Andrew Rybchenko 写道: >> On 6/1/22 09:39, Min Hu (Connor) wrote: >>> From: Huisong Li <lihuisong@huawei.com> >>> >>> The dev->data->mac_addrs[0] will be changed to a new MAC address when >>> applications modify the default MAC address by >>> rte_eth_dev_default_mac_addr_set(). However, if the new default one has >>> been added as a non-default MAC address by >>> rte_eth_dev_mac_addr_add(), the >>> the rte_eth_dev_default_mac_addr_set() doesn't remove it from the >>> mac_addrs >>> list. As a result, one MAC address occupies two indexes in the list. >>> Like: >>> add(MAC1) >>> add(MAC2) >>> add(MAC3) >>> add(MAC4) >>> set_default(MAC3) >>> default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 >>> >>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the >>> old default MAC when set default MAC. If user continues to do >>> set_default(MAC5), and the mac_addrs list is default=MAC5, >>> filters=(MAC1, >>> MAC2, MAC3, MAC4). At this moment, user can still view MAC3 from the >>> list, >>> but packets with MAC3 aren't actually received by the PMD. >> >> IMHO, the main problem is inconsistency which exists right now. >> rte_eth_dev_mac_addr_add() checks for duplicate MAC addition >> including the default one (index zero) and extends the entry >> pool mask (including zero entry case). >> >> However, the patch above does not extend zero entry pool mask. >> So, the result will depend on order which is bad: >> A. Set default to A, add MAC A with pool 2 => pool mask has 2 >> B. Add MAC A with pool 2, set default to A => pool mask is empty >> > I don't know how this MAC pool works in which driver. Me too > However, the 'eth_dev_mac_restore' API show that 1) the default MAC has > only pool zero > if set it by the 'mac_addr_add', 2) the default one hasn't pool > information if set it > by 'default_mac_addr_set'. > > Do you mean we should inherit its pool mask in this case? I simply want to make it consistent >> Am I missing something in the code? >> What is the right/intended behaviour? >> >>> >>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>> Cc: stable@dpdk.org >>> >>> Signed-off-by: Huisong Li <lihuisong@huawei.com> >>> Signed-off-by: Min Hu <humin29@huawei.com> >>> --- >>> lib/ethdev/rte_ethdev.c | 39 +++++++++++++++++++++++++++++++++++++-- >>> 1 file changed, 37 insertions(+), 2 deletions(-) >>> >>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >>> index 46c088dc88..fc9ca8d6fd 100644 >>> --- a/lib/ethdev/rte_ethdev.c >>> +++ b/lib/ethdev/rte_ethdev.c >>> @@ -4260,7 +4260,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, >>> struct rte_ether_addr *addr) >>> int >>> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct >>> rte_ether_addr *addr) >>> { >>> + uint64_t mac_pool_sel_bk = 0; >>> struct rte_eth_dev *dev; >>> + uint32_t pool; >>> + int index; >>> int ret; >>> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); >>> @@ -4278,16 +4281,48 @@ rte_eth_dev_default_mac_addr_set(uint16_t >>> port_id, struct rte_ether_addr *addr) >>> RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP); >>> + /* >>> + * If the address has been added as a non-default MAC address by >>> + * rte_eth_dev_mac_addr_add API, it should be removed from >>> + * dev->data->mac_addrs[]. >>> + */ >>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>> + if (index > 0) { >>> + /* remove address in NIC data structure */ >>> + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; >>> + ret = rte_eth_dev_mac_addr_remove(port_id, addr); >>> + if (ret < 0) { >>> + RTE_ETHDEV_LOG(ERR, >>> + "Delete MAC address from the MAC list of ethdev port >>> %u.\n", >>> + port_id); >>> + return ret; >>> + } >>> + /* reset pool bitmap */ >>> + dev->data->mac_pool_sel[index] = 0; >>> + } >>> + >>> ret = (*dev->dev_ops->mac_addr_set)(dev, addr); >>> if (ret < 0) >>> - return ret; >>> + goto back; >>> /* Update default address in NIC data structure */ >>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>> return 0; >>> -} >>> +back: >>> + if (index > 0) { >>> + pool = 0; >>> + do { >>> + if (mac_pool_sel_bk & UINT64_C(1)) >>> + rte_eth_dev_mac_addr_add(port_id, addr, pool); >> >> Don't we want to have at least error logs in the case of rollback >> failure here? > It doesn't feel necessary. It may trigger the printing of a large number > of error logs > in abnormal scenarios. Otherwise how will user know that rollback failed and configuration is inconsistent? >> >>> + mac_pool_sel_bk >>= 1; >>> + pool++; >>> + } while (mac_pool_sel_bk); >> >> Please, compare vs 0 explicitly. > Ack >> >>> + } >>> + >>> + return ret; >>> +} >>> /* >>> * Returns index into MAC address array of addr. Use >>> 00:00:00:00:00:00 to find >> >> .
在 2022/6/2 21:54, Andrew Rybchenko 写道: > Cc more driver maintainers > > On 6/2/22 06:16, lihuisong (C) wrote: >> >> 在 2022/6/2 1:49, Andrew Rybchenko 写道: >>> On 6/1/22 09:39, Min Hu (Connor) wrote: >>>> From: Huisong Li <lihuisong@huawei.com> >>>> >>>> The dev->data->mac_addrs[0] will be changed to a new MAC address when >>>> applications modify the default MAC address by >>>> rte_eth_dev_default_mac_addr_set(). However, if the new default one >>>> has >>>> been added as a non-default MAC address by >>>> rte_eth_dev_mac_addr_add(), the >>>> the rte_eth_dev_default_mac_addr_set() doesn't remove it from the >>>> mac_addrs >>>> list. As a result, one MAC address occupies two indexes in the >>>> list. Like: >>>> add(MAC1) >>>> add(MAC2) >>>> add(MAC3) >>>> add(MAC4) >>>> set_default(MAC3) >>>> default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 >>>> >>>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do >>>> remove the >>>> old default MAC when set default MAC. If user continues to do >>>> set_default(MAC5), and the mac_addrs list is default=MAC5, >>>> filters=(MAC1, >>>> MAC2, MAC3, MAC4). At this moment, user can still view MAC3 from >>>> the list, >>>> but packets with MAC3 aren't actually received by the PMD. >>> >>> IMHO, the main problem is inconsistency which exists right now. >>> rte_eth_dev_mac_addr_add() checks for duplicate MAC addition >>> including the default one (index zero) and extends the entry >>> pool mask (including zero entry case). >>> >>> However, the patch above does not extend zero entry pool mask. >>> So, the result will depend on order which is bad: >>> A. Set default to A, add MAC A with pool 2 => pool mask has 2 >>> B. Add MAC A with pool 2, set default to A => pool mask is empty >>> >> I don't know how this MAC pool works in which driver. > > Me too > >> However, the 'eth_dev_mac_restore' API show that 1) the default MAC >> has only pool zero >> if set it by the 'mac_addr_add', 2) the default one hasn't pool >> information if set it >> by 'default_mac_addr_set'. >> >> Do you mean we should inherit its pool mask in this case? > > I simply want to make it consistent I know what you mean. However, from the implementations mentioned above, it seems that drivers used pool mask don't care the pool mask of the default MAC. Do we need to set pool mask for the default MAC? > >>> Am I missing something in the code? >>> What is the right/intended behaviour? >>> >>>> >>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>>> Cc: stable@dpdk.org >>>> >>>> Signed-off-by: Huisong Li <lihuisong@huawei.com> >>>> Signed-off-by: Min Hu <humin29@huawei.com> >>>> --- >>>> lib/ethdev/rte_ethdev.c | 39 +++++++++++++++++++++++++++++++++++++-- >>>> 1 file changed, 37 insertions(+), 2 deletions(-) >>>> >>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >>>> index 46c088dc88..fc9ca8d6fd 100644 >>>> --- a/lib/ethdev/rte_ethdev.c >>>> +++ b/lib/ethdev/rte_ethdev.c >>>> @@ -4260,7 +4260,10 @@ rte_eth_dev_mac_addr_remove(uint16_t >>>> port_id, struct rte_ether_addr *addr) >>>> int >>>> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct >>>> rte_ether_addr *addr) >>>> { >>>> + uint64_t mac_pool_sel_bk = 0; >>>> struct rte_eth_dev *dev; >>>> + uint32_t pool; >>>> + int index; >>>> int ret; >>>> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); >>>> @@ -4278,16 +4281,48 @@ rte_eth_dev_default_mac_addr_set(uint16_t >>>> port_id, struct rte_ether_addr *addr) >>>> RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP); >>>> + /* >>>> + * If the address has been added as a non-default MAC address by >>>> + * rte_eth_dev_mac_addr_add API, it should be removed from >>>> + * dev->data->mac_addrs[]. >>>> + */ >>>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>>> + if (index > 0) { >>>> + /* remove address in NIC data structure */ >>>> + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; >>>> + ret = rte_eth_dev_mac_addr_remove(port_id, addr); >>>> + if (ret < 0) { >>>> + RTE_ETHDEV_LOG(ERR, >>>> + "Delete MAC address from the MAC list of ethdev port >>>> %u.\n", >>>> + port_id); >>>> + return ret; >>>> + } >>>> + /* reset pool bitmap */ >>>> + dev->data->mac_pool_sel[index] = 0; >>>> + } >>>> + >>>> ret = (*dev->dev_ops->mac_addr_set)(dev, addr); >>>> if (ret < 0) >>>> - return ret; >>>> + goto back; >>>> /* Update default address in NIC data structure */ >>>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>>> return 0; >>>> -} >>>> +back: >>>> + if (index > 0) { >>>> + pool = 0; >>>> + do { >>>> + if (mac_pool_sel_bk & UINT64_C(1)) >>>> + rte_eth_dev_mac_addr_add(port_id, addr, pool); >>> >>> Don't we want to have at least error logs in the case of rollback >>> failure here? >> It doesn't feel necessary. It may trigger the printing of a large >> number of error logs >> in abnormal scenarios. > > Otherwise how will user know that rollback failed and configuration > is inconsistent? Ack. > >>> >>>> + mac_pool_sel_bk >>= 1; >>>> + pool++; >>>> + } while (mac_pool_sel_bk); >>> >>> Please, compare vs 0 explicitly. >> Ack >>> >>>> + } >>>> + >>>> + return ret; >>>> +} >>>> /* >>>> * Returns index into MAC address array of addr. Use >>>> 00:00:00:00:00:00 to find >>> >>> . > > .
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() doesn't remove it from the mac_addrs list. As a result, one MAC address occupies two indexes in the list. Like: add(MAC1) add(MAC2) add(MAC3) add(MAC4) set_default(MAC3) default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the old default MAC when set default MAC. If user continues to do set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, but packets with MAC3 aren't actually received by the PMD. So this patch adds a remove operation in set default MAC API documents this behavior. Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") Cc: stable@dpdk.org Signed-off-by: Huisong Li <lihuisong@huawei.com> Signed-off-by: Min Hu (Connor) <humin29@huawei.com> --- v5: - merge the second patch into the first patch. - add error log when rollback failed. v4: - fix broken in the patchwork v3: - first explicitly remove the non-default MAC, then set default one. - document default and non-default MAC address v2: - fixed commit log. --- lib/ethdev/ethdev_driver.h | 7 ++++++- lib/ethdev/rte_ethdev.c | 41 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index 1300acc95d..6291be783c 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -116,7 +116,12 @@ struct rte_eth_dev_data { uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ + /** + * Device Ethernet link address. The index zero of the array is as the + * index of the default address, and other indexes can't be the same + * as the address corresponding to index 0. + * @see rte_eth_dev_release_port() + */ struct rte_ether_addr *mac_addrs; /** Bitmap associating MAC addresses to pools */ uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 5d5e18db1e..be4b37c9c1 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) int rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) { + uint64_t mac_pool_sel_bk = 0; struct rte_eth_dev *dev; + uint32_t pool; + int index; int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); @@ -4517,16 +4520,50 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) if (*dev->dev_ops->mac_addr_set == NULL) return -ENOTSUP; + /* + * If the address has been added as a non-default MAC address by + * rte_eth_dev_mac_addr_add API, it should be removed from + * dev->data->mac_addrs[]. + */ + index = eth_dev_get_mac_addr_index(port_id, addr); + if (index > 0) { + /* Remove address in dev data structure */ + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; + ret = rte_eth_dev_mac_addr_remove(port_id, addr); + if (ret < 0) { + RTE_ETHDEV_LOG(ERR, "Delete MAC address from the MAC list of ethdev port %u.\n", + port_id); + return ret; + } + /* Reset pool bitmap */ + dev->data->mac_pool_sel[index] = 0; + } ret = (*dev->dev_ops->mac_addr_set)(dev, addr); if (ret < 0) - return ret; + goto out; /* Update default address in NIC data structure */ rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); return 0; -} +out: + if (index > 0) { + pool = 0; + do { + if (mac_pool_sel_bk & UINT64_C(1)) { + if (rte_eth_dev_mac_addr_add(port_id, addr, + pool) != 0) + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n", + pool, port_id); + } + mac_pool_sel_bk >>= 1; + pool++; + } while (mac_pool_sel_bk != 0); + } + + return ret; +} /* * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find -- 2.22.0
Kindly ping.
在 2022/10/20 17:31, Huisong Li 写道:
> 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() doesn't remove it from the mac_addrs
> list. As a result, one MAC address occupies two indexes in the list. Like:
> add(MAC1)
> add(MAC2)
> add(MAC3)
> add(MAC4)
> set_default(MAC3)
> default=MAC3, filters=MAC1, MAC2, MAC3, MAC4
>
> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the
> old default MAC when set default MAC. If user continues to do
> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1,
> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list,
> but packets with MAC3 aren't actually received by the PMD.
>
> So this patch adds a remove operation in set default MAC API documents
> this behavior.
>
> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
> Cc: stable@dpdk.org
>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
> v5:
> - merge the second patch into the first patch.
> - add error log when rollback failed.
>
> v4:
> - fix broken in the patchwork
>
> v3:
> - first explicitly remove the non-default MAC, then set default one.
> - document default and non-default MAC address
>
> v2:
> - fixed commit log.
>
> ---
> lib/ethdev/ethdev_driver.h | 7 ++++++-
> lib/ethdev/rte_ethdev.c | 41 ++++++++++++++++++++++++++++++++++++--
> 2 files changed, 45 insertions(+), 3 deletions(-)
>
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> index 1300acc95d..6291be783c 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -116,7 +116,12 @@ struct rte_eth_dev_data {
>
> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */
>
> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */
> + /**
> + * Device Ethernet link address. The index zero of the array is as the
> + * index of the default address, and other indexes can't be the same
> + * as the address corresponding to index 0.
> + * @see rte_eth_dev_release_port()
> + */
> struct rte_ether_addr *mac_addrs;
> /** Bitmap associating MAC addresses to pools */
> uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR];
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index 5d5e18db1e..be4b37c9c1 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
> int
> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
> {
> + uint64_t mac_pool_sel_bk = 0;
> struct rte_eth_dev *dev;
> + uint32_t pool;
> + int index;
> int ret;
>
> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> @@ -4517,16 +4520,50 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
> if (*dev->dev_ops->mac_addr_set == NULL)
> return -ENOTSUP;
>
> + /*
> + * If the address has been added as a non-default MAC address by
> + * rte_eth_dev_mac_addr_add API, it should be removed from
> + * dev->data->mac_addrs[].
> + */
> + index = eth_dev_get_mac_addr_index(port_id, addr);
> + if (index > 0) {
> + /* Remove address in dev data structure */
> + mac_pool_sel_bk = dev->data->mac_pool_sel[index];
> + ret = rte_eth_dev_mac_addr_remove(port_id, addr);
> + if (ret < 0) {
> + RTE_ETHDEV_LOG(ERR, "Delete MAC address from the MAC list of ethdev port %u.\n",
> + port_id);
> + return ret;
> + }
> + /* Reset pool bitmap */
> + dev->data->mac_pool_sel[index] = 0;
> + }
> ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
> if (ret < 0)
> - return ret;
> + goto out;
>
> /* Update default address in NIC data structure */
> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
>
> return 0;
> -}
>
> +out:
> + if (index > 0) {
> + pool = 0;
> + do {
> + if (mac_pool_sel_bk & UINT64_C(1)) {
> + if (rte_eth_dev_mac_addr_add(port_id, addr,
> + pool) != 0)
> + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n",
> + pool, port_id);
> + }
> + mac_pool_sel_bk >>= 1;
> + pool++;
> + } while (mac_pool_sel_bk != 0);
> + }
> +
> + return ret;
> +}
>
> /*
> * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
Hi Andrew and PMD maintainers,
Can you have a look?
在 2022/10/20 17:31, Huisong Li 写道:
> 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() doesn't remove it from the mac_addrs
> list. As a result, one MAC address occupies two indexes in the list. Like:
> add(MAC1)
> add(MAC2)
> add(MAC3)
> add(MAC4)
> set_default(MAC3)
> default=MAC3, filters=MAC1, MAC2, MAC3, MAC4
>
> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the
> old default MAC when set default MAC. If user continues to do
> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1,
> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list,
> but packets with MAC3 aren't actually received by the PMD.
>
> So this patch adds a remove operation in set default MAC API documents
> this behavior.
>
> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
> Cc: stable@dpdk.org
>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
> v5:
> - merge the second patch into the first patch.
> - add error log when rollback failed.
>
> v4:
> - fix broken in the patchwork
>
> v3:
> - first explicitly remove the non-default MAC, then set default one.
> - document default and non-default MAC address
>
> v2:
> - fixed commit log.
>
> ---
> lib/ethdev/ethdev_driver.h | 7 ++++++-
> lib/ethdev/rte_ethdev.c | 41 ++++++++++++++++++++++++++++++++++++--
> 2 files changed, 45 insertions(+), 3 deletions(-)
>
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> index 1300acc95d..6291be783c 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -116,7 +116,12 @@ struct rte_eth_dev_data {
>
> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */
>
> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */
> + /**
> + * Device Ethernet link address. The index zero of the array is as the
> + * index of the default address, and other indexes can't be the same
> + * as the address corresponding to index 0.
> + * @see rte_eth_dev_release_port()
> + */
> struct rte_ether_addr *mac_addrs;
> /** Bitmap associating MAC addresses to pools */
> uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR];
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index 5d5e18db1e..be4b37c9c1 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
> int
> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
> {
> + uint64_t mac_pool_sel_bk = 0;
> struct rte_eth_dev *dev;
> + uint32_t pool;
> + int index;
> int ret;
>
> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> @@ -4517,16 +4520,50 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
> if (*dev->dev_ops->mac_addr_set == NULL)
> return -ENOTSUP;
>
> + /*
> + * If the address has been added as a non-default MAC address by
> + * rte_eth_dev_mac_addr_add API, it should be removed from
> + * dev->data->mac_addrs[].
> + */
> + index = eth_dev_get_mac_addr_index(port_id, addr);
> + if (index > 0) {
> + /* Remove address in dev data structure */
> + mac_pool_sel_bk = dev->data->mac_pool_sel[index];
> + ret = rte_eth_dev_mac_addr_remove(port_id, addr);
> + if (ret < 0) {
> + RTE_ETHDEV_LOG(ERR, "Delete MAC address from the MAC list of ethdev port %u.\n",
> + port_id);
> + return ret;
> + }
> + /* Reset pool bitmap */
> + dev->data->mac_pool_sel[index] = 0;
> + }
> ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
> if (ret < 0)
> - return ret;
> + goto out;
>
> /* Update default address in NIC data structure */
> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
>
> return 0;
> -}
>
> +out:
> + if (index > 0) {
> + pool = 0;
> + do {
> + if (mac_pool_sel_bk & UINT64_C(1)) {
> + if (rte_eth_dev_mac_addr_add(port_id, addr,
> + pool) != 0)
> + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n",
> + pool, port_id);
> + }
> + mac_pool_sel_bk >>= 1;
> + pool++;
> + } while (mac_pool_sel_bk != 0);
> + }
> +
> + return ret;
> +}
>
> /*
> * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
LGTM
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
On 2022/10/20 17:31, Huisong Li wrote:
> 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() doesn't remove it from the mac_addrs
> list. As a result, one MAC address occupies two indexes in the list. Like:
> add(MAC1)
> add(MAC2)
> add(MAC3)
> add(MAC4)
> set_default(MAC3)
> default=MAC3, filters=MAC1, MAC2, MAC3, MAC4
>
> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the
> old default MAC when set default MAC. If user continues to do
> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1,
> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list,
> but packets with MAC3 aren't actually received by the PMD.
>
> So this patch adds a remove operation in set default MAC API documents
> this behavior.
>
> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
> Cc: stable@dpdk.org
>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
> v5:
> - merge the second patch into the first patch.
> - add error log when rollback failed.
>
> v4:
> - fix broken in the patchwork
>
> v3:
> - first explicitly remove the non-default MAC, then set default one.
> - document default and non-default MAC address
>
> v2:
> - fixed commit log.
>
> ---
> lib/ethdev/ethdev_driver.h | 7 ++++++-
> lib/ethdev/rte_ethdev.c | 41 ++++++++++++++++++++++++++++++++++++--
> 2 files changed, 45 insertions(+), 3 deletions(-)
>
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> index 1300acc95d..6291be783c 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -116,7 +116,12 @@ struct rte_eth_dev_data {
>
> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */
>
> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */
> + /**
> + * Device Ethernet link address. The index zero of the array is as the
> + * index of the default address, and other indexes can't be the same
> + * as the address corresponding to index 0.
> + * @see rte_eth_dev_release_port()
> + */
> struct rte_ether_addr *mac_addrs;
> /** Bitmap associating MAC addresses to pools */
> uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR];
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index 5d5e18db1e..be4b37c9c1 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
> int
> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
> {
> + uint64_t mac_pool_sel_bk = 0;
> struct rte_eth_dev *dev;
> + uint32_t pool;
> + int index;
> int ret;
>
> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> @@ -4517,16 +4520,50 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
> if (*dev->dev_ops->mac_addr_set == NULL)
> return -ENOTSUP;
>
> + /*
> + * If the address has been added as a non-default MAC address by
> + * rte_eth_dev_mac_addr_add API, it should be removed from
> + * dev->data->mac_addrs[].
> + */
> + index = eth_dev_get_mac_addr_index(port_id, addr);
> + if (index > 0) {
> + /* Remove address in dev data structure */
> + mac_pool_sel_bk = dev->data->mac_pool_sel[index];
> + ret = rte_eth_dev_mac_addr_remove(port_id, addr);
> + if (ret < 0) {
> + RTE_ETHDEV_LOG(ERR, "Delete MAC address from the MAC list of ethdev port %u.\n",
> + port_id);
> + return ret;
> + }
> + /* Reset pool bitmap */
> + dev->data->mac_pool_sel[index] = 0;
> + }
> ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
> if (ret < 0)
> - return ret;
> + goto out;
>
> /* Update default address in NIC data structure */
> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
>
> return 0;
> -}
>
> +out:
> + if (index > 0) {
> + pool = 0;
> + do {
> + if (mac_pool_sel_bk & UINT64_C(1)) {
> + if (rte_eth_dev_mac_addr_add(port_id, addr,
> + pool) != 0)
> + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n",
> + pool, port_id);
> + }
> + mac_pool_sel_bk >>= 1;
> + pool++;
> + } while (mac_pool_sel_bk != 0);
> + }
> +
> + return ret;
> +}
>
> /*
> * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
>
20/10/2022 11:31, Huisong Li: > 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() doesn't remove it from the mac_addrs > list. As a result, one MAC address occupies two indexes in the list. Like: > add(MAC1) > add(MAC2) > add(MAC3) > add(MAC4) > set_default(MAC3) > default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 I agree it would be simpler to ensure that the addresses are uniques. > In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the > old default MAC when set default MAC. If user continues to do > set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, > MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, > but packets with MAC3 aren't actually received by the PMD. If MAC3 is not removed with rte_eth_dev_mac_addr_remove() by the app, MAC3 packets should be received. The MAC address should not be removed by the PMD. > So this patch adds a remove operation in set default MAC API documents > this behavior. Let's be clear here: only the new default address is removed from the rest of the list. > Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") > Cc: stable@dpdk.org > --- a/lib/ethdev/ethdev_driver.h > +++ b/lib/ethdev/ethdev_driver.h > @@ -116,7 +116,12 @@ struct rte_eth_dev_data { > > uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ > > - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ > + /** > + * Device Ethernet link address. The index zero of the array is as the It should be "addresses" as there can be multiple. What means "as" above? Can we say the first entry (index zero) is the default address? > + * index of the default address, and other indexes can't be the same You can split the sentence in 2 instead of ", and". indexes -> entries can't -> cannot > + * as the address corresponding to index 0. simpler: as the default address. > + * @see rte_eth_dev_release_port() Why referencing this function here? > + */ > --- a/lib/ethdev/rte_ethdev.c > +++ b/lib/ethdev/rte_ethdev.c > @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) > int > rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) > { > + uint64_t mac_pool_sel_bk = 0; > struct rte_eth_dev *dev; > + uint32_t pool; > + int index; > int ret; > > RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); > @@ -4517,16 +4520,50 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) > if (*dev->dev_ops->mac_addr_set == NULL) > return -ENOTSUP; > > + /* > + * If the address has been added as a non-default MAC address by > + * rte_eth_dev_mac_addr_add API, it should be removed from > + * dev->data->mac_addrs[]. > + */ Make is simpler: "Keep address unique in dev->data->mac_addrs[]." > + index = eth_dev_get_mac_addr_index(port_id, addr); > + if (index > 0) { > + /* Remove address in dev data structure */ > + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; > + ret = rte_eth_dev_mac_addr_remove(port_id, addr); > + if (ret < 0) { > + RTE_ETHDEV_LOG(ERR, "Delete MAC address from the MAC list of ethdev port %u.\n", > + port_id); It is not clear with this log that it failed. > + return ret; > + } > + /* Reset pool bitmap */ > + dev->data->mac_pool_sel[index] = 0; mac_pool_sel[index] is already reset in rte_eth_dev_mac_addr_remove(). > + } > ret = (*dev->dev_ops->mac_addr_set)(dev, addr); > if (ret < 0) > - return ret; > + goto out; > > /* Update default address in NIC data structure */ > rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); > > return 0; > -} > > +out: > + if (index > 0) { > + pool = 0; > + do { > + if (mac_pool_sel_bk & UINT64_C(1)) { > + if (rte_eth_dev_mac_addr_add(port_id, addr, > + pool) != 0) > + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n", > + pool, port_id); > + } > + mac_pool_sel_bk >>= 1; > + pool++; > + } while (mac_pool_sel_bk != 0); > + } > + > + return ret; > +} Can we avoid this rollback by removing the address after mac_addr_set() succeed?
18/01/2023 09:26, Thomas Monjalon: > 20/10/2022 11:31, Huisong Li: > > 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() doesn't remove it from the mac_addrs > > list. As a result, one MAC address occupies two indexes in the list. Like: > > add(MAC1) > > add(MAC2) > > add(MAC3) > > add(MAC4) > > set_default(MAC3) > > default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 > > I agree it may be simpler to ensure that the addresses are uniques. > > > In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the > > old default MAC when set default MAC. If user continues to do > > set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, > > MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, > > but packets with MAC3 aren't actually received by the PMD. > > If MAC3 is not removed with rte_eth_dev_mac_addr_remove() by the app, > MAC3 packets should be received. > The MAC address should not be removed by the PMD. Sorry for the confusion. I mean the opposite. With the new behavior, if we want the old default address to be kept in the list, we need to add it explicitly with rte_eth_dev_mac_addr_add. This is a behavior change and must be highlighted in the release notes. > > So this patch adds a remove operation in set default MAC API documents > > this behavior. > > Let's be clear here: only the new default address is removed from the rest of the list. > > > Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") > > Cc: stable@dpdk.org > > > --- a/lib/ethdev/ethdev_driver.h > > +++ b/lib/ethdev/ethdev_driver.h > > @@ -116,7 +116,12 @@ struct rte_eth_dev_data { > > > > uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ > > > > - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ > > + /** > > + * Device Ethernet link address. The index zero of the array is as the > > It should be "addresses" as there can be multiple. > > What means "as" above? > Can we say the first entry (index zero) is the default address? > > > + * index of the default address, and other indexes can't be the same > > You can split the sentence in 2 instead of ", and". > indexes -> entries > can't -> cannot > > > + * as the address corresponding to index 0. > > simpler: as the default address. > > > + * @see rte_eth_dev_release_port() > > Why referencing this function here? > > > + */ > > > --- a/lib/ethdev/rte_ethdev.c > > +++ b/lib/ethdev/rte_ethdev.c > > @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) > > int > > rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) > > { > > + uint64_t mac_pool_sel_bk = 0; > > struct rte_eth_dev *dev; > > + uint32_t pool; > > + int index; > > int ret; > > > > RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); > > @@ -4517,16 +4520,50 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) > > if (*dev->dev_ops->mac_addr_set == NULL) > > return -ENOTSUP; > > > > + /* > > + * If the address has been added as a non-default MAC address by > > + * rte_eth_dev_mac_addr_add API, it should be removed from > > + * dev->data->mac_addrs[]. > > + */ > > Make is simpler: > "Keep address unique in dev->data->mac_addrs[]." > > > + index = eth_dev_get_mac_addr_index(port_id, addr); > > + if (index > 0) { > > + /* Remove address in dev data structure */ > > + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; > > + ret = rte_eth_dev_mac_addr_remove(port_id, addr); > > + if (ret < 0) { > > + RTE_ETHDEV_LOG(ERR, "Delete MAC address from the MAC list of ethdev port %u.\n", > > + port_id); > > It is not clear with this log that it failed. > > > + return ret; > > + } > > + /* Reset pool bitmap */ > > + dev->data->mac_pool_sel[index] = 0; > > mac_pool_sel[index] is already reset in rte_eth_dev_mac_addr_remove(). > > > + } > > ret = (*dev->dev_ops->mac_addr_set)(dev, addr); > > if (ret < 0) > > - return ret; > > + goto out; > > > > /* Update default address in NIC data structure */ > > rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); > > > > return 0; > > -} > > > > +out: > > + if (index > 0) { > > + pool = 0; > > + do { > > + if (mac_pool_sel_bk & UINT64_C(1)) { > > + if (rte_eth_dev_mac_addr_add(port_id, addr, > > + pool) != 0) > > + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n", > > + pool, port_id); > > + } > > + mac_pool_sel_bk >>= 1; > > + pool++; > > + } while (mac_pool_sel_bk != 0); > > + } > > + > > + return ret; > > +} > > Can we avoid this rollback by removing the address after mac_addr_set() succeed?
在 2023/1/18 16:26, Thomas Monjalon 写道: > 20/10/2022 11:31, Huisong Li: >> 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() doesn't remove it from the mac_addrs >> list. As a result, one MAC address occupies two indexes in the list. Like: >> add(MAC1) >> add(MAC2) >> add(MAC3) >> add(MAC4) >> set_default(MAC3) >> default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 > I agree it would be simpler to ensure that the addresses are uniques. > >> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the >> old default MAC when set default MAC. If user continues to do >> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, >> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, >> but packets with MAC3 aren't actually received by the PMD. > If MAC3 is not removed with rte_eth_dev_mac_addr_remove() by the app, > MAC3 packets should be received. > The MAC address should not be removed by the PMD. > >> So this patch adds a remove operation in set default MAC API documents >> this behavior. > Let's be clear here: only the new default address is removed from the rest of the list. > >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >> Cc: stable@dpdk.org >> --- a/lib/ethdev/ethdev_driver.h >> +++ b/lib/ethdev/ethdev_driver.h >> @@ -116,7 +116,12 @@ struct rte_eth_dev_data { >> >> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ >> >> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ >> + /** >> + * Device Ethernet link address. The index zero of the array is as the > It should be "addresses" as there can be multiple. > > What means "as" above? > Can we say the first entry (index zero) is the default address? > >> + * index of the default address, and other indexes can't be the same > You can split the sentence in 2 instead of ", and". > indexes -> entries > can't -> cannot > >> + * as the address corresponding to index 0. > simpler: as the default address. > >> + * @see rte_eth_dev_release_port() > Why referencing this function here? > >> + */ >> --- a/lib/ethdev/rte_ethdev.c >> +++ b/lib/ethdev/rte_ethdev.c >> @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) >> int >> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) >> { >> + uint64_t mac_pool_sel_bk = 0; >> struct rte_eth_dev *dev; >> + uint32_t pool; >> + int index; >> int ret; >> >> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); >> @@ -4517,16 +4520,50 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) >> if (*dev->dev_ops->mac_addr_set == NULL) >> return -ENOTSUP; >> >> + /* >> + * If the address has been added as a non-default MAC address by >> + * rte_eth_dev_mac_addr_add API, it should be removed from >> + * dev->data->mac_addrs[]. >> + */ > Make is simpler: > "Keep address unique in dev->data->mac_addrs[]." Ack > >> + index = eth_dev_get_mac_addr_index(port_id, addr); >> + if (index > 0) { >> + /* Remove address in dev data structure */ >> + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; >> + ret = rte_eth_dev_mac_addr_remove(port_id, addr); >> + if (ret < 0) { >> + RTE_ETHDEV_LOG(ERR, "Delete MAC address from the MAC list of ethdev port %u.\n", >> + port_id); > It is not clear with this log that it failed. Adjust as follows? "Delete old address entry from the MAC list of ethdev port %u.\n" > >> + return ret; >> + } >> + /* Reset pool bitmap */ >> + dev->data->mac_pool_sel[index] = 0; > mac_pool_sel[index] is already reset in rte_eth_dev_mac_addr_remove(). Yes, this can be deleted. > >> + } >> ret = (*dev->dev_ops->mac_addr_set)(dev, addr); >> if (ret < 0) >> - return ret; >> + goto out; >> >> /* Update default address in NIC data structure */ >> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >> >> return 0; >> -} >> >> +out: >> + if (index > 0) { >> + pool = 0; >> + do { >> + if (mac_pool_sel_bk & UINT64_C(1)) { >> + if (rte_eth_dev_mac_addr_add(port_id, addr, >> + pool) != 0) >> + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n", >> + pool, port_id); >> + } >> + mac_pool_sel_bk >>= 1; >> + pool++; >> + } while (mac_pool_sel_bk != 0); >> + } >> + >> + return ret; >> +} > Can we avoid this rollback by removing the address after mac_addr_set() succeed? No, the new default address will be removed if we do that. we need to remove it first if the new default address has been added as a non-default MAC address to the MAC list. > > > > .
在 2023/1/18 16:38, Thomas Monjalon 写道: > 18/01/2023 09:26, Thomas Monjalon: >> 20/10/2022 11:31, Huisong Li: >>> 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() doesn't remove it from the mac_addrs >>> list. As a result, one MAC address occupies two indexes in the list. Like: >>> add(MAC1) >>> add(MAC2) >>> add(MAC3) >>> add(MAC4) >>> set_default(MAC3) >>> default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 >> I agree it may be simpler to ensure that the addresses are uniques. >> >>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the >>> old default MAC when set default MAC. If user continues to do >>> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, >>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, >>> but packets with MAC3 aren't actually received by the PMD. >> If MAC3 is not removed with rte_eth_dev_mac_addr_remove() by the app, >> MAC3 packets should be received. >> The MAC address should not be removed by the PMD. > Sorry for the confusion. I mean the opposite. > With the new behavior, if we want the old default address to be kept > in the list, we need to add it explicitly with rte_eth_dev_mac_addr_add. > This is a behavior change and must be highlighted in the release notes. Hi Thomas, Sorry for your confusion. Maybe my cmmmit log is misleading. Please ignore the second paragraph description in my commit. It has nothing to do with the old defalut address. The purpose of this patch is to solve the problem that one address occupies two entries in MAC list. All network engines have this problem. If the new defalut address has been added as a non-default MAC address to the MAC list, this address will occupy two entries in MAC list. It's still a problem for some network engines, like, hns3 and i40e. That's what I described in the second paragraph in my commit. /Huisong >>> So this patch adds a remove operation in set default MAC API documents >>> this behavior. >> Let's be clear here: only the new default address is removed from the rest of the list. >> >>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>> Cc: stable@dpdk.org >>> --- a/lib/ethdev/ethdev_driver.h >>> +++ b/lib/ethdev/ethdev_driver.h >>> @@ -116,7 +116,12 @@ struct rte_eth_dev_data { >>> >>> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ >>> >>> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ >>> + /** >>> + * Device Ethernet link address. The index zero of the array is as the >> It should be "addresses" as there can be multiple. >> >> What means "as" above? >> Can we say the first entry (index zero) is the default address? >> >>> + * index of the default address, and other indexes can't be the same >> You can split the sentence in 2 instead of ", and". >> indexes -> entries >> can't -> cannot >> >>> + * as the address corresponding to index 0. >> simpler: as the default address. >> >>> + * @see rte_eth_dev_release_port() >> Why referencing this function here? >> >>> + */ >>> --- a/lib/ethdev/rte_ethdev.c >>> +++ b/lib/ethdev/rte_ethdev.c >>> @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) >>> int >>> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) >>> { >>> + uint64_t mac_pool_sel_bk = 0; >>> struct rte_eth_dev *dev; >>> + uint32_t pool; >>> + int index; >>> int ret; >>> >>> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); >>> @@ -4517,16 +4520,50 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) >>> if (*dev->dev_ops->mac_addr_set == NULL) >>> return -ENOTSUP; >>> >>> + /* >>> + * If the address has been added as a non-default MAC address by >>> + * rte_eth_dev_mac_addr_add API, it should be removed from >>> + * dev->data->mac_addrs[]. >>> + */ >> Make is simpler: >> "Keep address unique in dev->data->mac_addrs[]." >> >>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>> + if (index > 0) { >>> + /* Remove address in dev data structure */ >>> + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; >>> + ret = rte_eth_dev_mac_addr_remove(port_id, addr); >>> + if (ret < 0) { >>> + RTE_ETHDEV_LOG(ERR, "Delete MAC address from the MAC list of ethdev port %u.\n", >>> + port_id); >> It is not clear with this log that it failed. >> >>> + return ret; >>> + } >>> + /* Reset pool bitmap */ >>> + dev->data->mac_pool_sel[index] = 0; >> mac_pool_sel[index] is already reset in rte_eth_dev_mac_addr_remove(). >> >>> + } >>> ret = (*dev->dev_ops->mac_addr_set)(dev, addr); >>> if (ret < 0) >>> - return ret; >>> + goto out; >>> >>> /* Update default address in NIC data structure */ >>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>> >>> return 0; >>> -} >>> >>> +out: >>> + if (index > 0) { >>> + pool = 0; >>> + do { >>> + if (mac_pool_sel_bk & UINT64_C(1)) { >>> + if (rte_eth_dev_mac_addr_add(port_id, addr, >>> + pool) != 0) >>> + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n", >>> + pool, port_id); >>> + } >>> + mac_pool_sel_bk >>= 1; >>> + pool++; >>> + } while (mac_pool_sel_bk != 0); >>> + } >>> + >>> + return ret; >>> +} >> Can we avoid this rollback by removing the address after mac_addr_set() succeed? > > > .
Hi,
You missed some questions and comments below.
19/01/2023 10:57, lihuisong (C):
> 在 2023/1/18 16:26, Thomas Monjalon 写道:
> > 20/10/2022 11:31, Huisong Li:
> >> 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() doesn't remove it from the mac_addrs
> >> list. As a result, one MAC address occupies two indexes in the list. Like:
> >> add(MAC1)
> >> add(MAC2)
> >> add(MAC3)
> >> add(MAC4)
> >> set_default(MAC3)
> >> default=MAC3, filters=MAC1, MAC2, MAC3, MAC4
> > I agree it would be simpler to ensure that the addresses are uniques.
> >
> >> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the
> >> old default MAC when set default MAC. If user continues to do
> >> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1,
> >> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list,
> >> but packets with MAC3 aren't actually received by the PMD.
> > If MAC3 is not removed with rte_eth_dev_mac_addr_remove() by the app,
> > MAC3 packets should be received.
> > The MAC address should not be removed by the PMD.
> >
> >> So this patch adds a remove operation in set default MAC API documents
> >> this behavior.
> > Let's be clear here: only the new default address is removed from the rest of the list.
> >
> >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
> >> Cc: stable@dpdk.org
> >> --- a/lib/ethdev/ethdev_driver.h
> >> +++ b/lib/ethdev/ethdev_driver.h
> >> @@ -116,7 +116,12 @@ struct rte_eth_dev_data {
> >>
> >> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */
> >>
> >> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */
> >> + /**
> >> + * Device Ethernet link address. The index zero of the array is as the
> > It should be "addresses" as there can be multiple.
> >
> > What means "as" above?
> > Can we say the first entry (index zero) is the default address?
> >
> >> + * index of the default address, and other indexes can't be the same
> > You can split the sentence in 2 instead of ", and".
> > indexes -> entries
> > can't -> cannot
> >
> >> + * as the address corresponding to index 0.
> > simpler: as the default address.
> >
> >> + * @see rte_eth_dev_release_port()
> > Why referencing this function here?
> >
> >> + */
> >> --- a/lib/ethdev/rte_ethdev.c
> >> +++ b/lib/ethdev/rte_ethdev.c
> >> @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
> >> int
> >> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
> >> {
> >> + uint64_t mac_pool_sel_bk = 0;
> >> struct rte_eth_dev *dev;
> >> + uint32_t pool;
> >> + int index;
> >> int ret;
> >>
> >> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> >> @@ -4517,16 +4520,50 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
> >> if (*dev->dev_ops->mac_addr_set == NULL)
> >> return -ENOTSUP;
> >>
> >> + /*
> >> + * If the address has been added as a non-default MAC address by
> >> + * rte_eth_dev_mac_addr_add API, it should be removed from
> >> + * dev->data->mac_addrs[].
> >> + */
> > Make is simpler:
> > "Keep address unique in dev->data->mac_addrs[]."
> Ack
> >
> >> + index = eth_dev_get_mac_addr_index(port_id, addr);
> >> + if (index > 0) {
> >> + /* Remove address in dev data structure */
> >> + mac_pool_sel_bk = dev->data->mac_pool_sel[index];
> >> + ret = rte_eth_dev_mac_addr_remove(port_id, addr);
> >> + if (ret < 0) {
> >> + RTE_ETHDEV_LOG(ERR, "Delete MAC address from the MAC list of ethdev port %u.\n",
> >> + port_id);
> > It is not clear with this log that it failed.
> Adjust as follows?
> "Delete old address entry from the MAC list of ethdev port %u.\n"
> >
> >> + return ret;
> >> + }
> >> + /* Reset pool bitmap */
> >> + dev->data->mac_pool_sel[index] = 0;
> > mac_pool_sel[index] is already reset in rte_eth_dev_mac_addr_remove().
> Yes, this can be deleted.
> >
> >> + }
> >> ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
> >> if (ret < 0)
> >> - return ret;
> >> + goto out;
> >>
> >> /* Update default address in NIC data structure */
> >> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
> >>
> >> return 0;
> >> -}
> >>
> >> +out:
> >> + if (index > 0) {
> >> + pool = 0;
> >> + do {
> >> + if (mac_pool_sel_bk & UINT64_C(1)) {
> >> + if (rte_eth_dev_mac_addr_add(port_id, addr,
> >> + pool) != 0)
> >> + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n",
> >> + pool, port_id);
> >> + }
> >> + mac_pool_sel_bk >>= 1;
> >> + pool++;
> >> + } while (mac_pool_sel_bk != 0);
> >> + }
> >> +
> >> + return ret;
> >> +}
> > Can we avoid this rollback by removing the address after mac_addr_set() succeed?
> No, the new default address will be removed if we do that.
> we need to remove it first if the new default address has been added as a
> non-default MAC address to the MAC list.
OK yes.
在 2023/1/19 22:38, Thomas Monjalon 写道: > Hi, > > You missed some questions and comments below. Sorry for my later reply. I just got back from vacation. Please take a look again. > > 19/01/2023 10:57, lihuisong (C): >> 在 2023/1/18 16:26, Thomas Monjalon 写道: >>> 20/10/2022 11:31, Huisong Li: >>>> 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() doesn't remove it from the mac_addrs >>>> list. As a result, one MAC address occupies two indexes in the list. Like: >>>> add(MAC1) >>>> add(MAC2) >>>> add(MAC3) >>>> add(MAC4) >>>> set_default(MAC3) >>>> default=MAC3, filters=MAC1, MAC2, MAC3, MAC4 >>> I agree it would be simpler to ensure that the addresses are uniques. >>> >>>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the >>>> old default MAC when set default MAC. If user continues to do >>>> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, >>>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, >>>> but packets with MAC3 aren't actually received by the PMD. >>> If MAC3 is not removed with rte_eth_dev_mac_addr_remove() by the app, >>> MAC3 packets should be received. >>> The MAC address should not be removed by the PMD. Please review another thread you pulled. >>> >>>> So this patch adds a remove operation in set default MAC API documents >>>> this behavior. >>> Let's be clear here: only the new default address is removed from the rest of the list. ok. Your expression is more explicit. >>> >>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>>> Cc: stable@dpdk.org >>>> --- a/lib/ethdev/ethdev_driver.h >>>> +++ b/lib/ethdev/ethdev_driver.h >>>> @@ -116,7 +116,12 @@ struct rte_eth_dev_data { >>>> >>>> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ >>>> >>>> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ >>>> + /** >>>> + * Device Ethernet link address. The index zero of the array is as the >>> It should be "addresses" as there can be multiple. >>> >>> What means "as" above? >>> Can we say the first entry (index zero) is the default address? >>> >>>> + * index of the default address, and other indexes can't be the same >>> You can split the sentence in 2 instead of ", and". >>> indexes -> entries >>> can't -> cannot >>> >>>> + * as the address corresponding to index 0. >>> simpler: as the default address. Above all will be fixed. Thank you for your suggestion. >>> >>>> + * @see rte_eth_dev_release_port() >>> Why referencing this function here? It was here before, and I didn't care too much, but I think it is redundant. I will remove it. >>> >>>> + */ >>>> --- a/lib/ethdev/rte_ethdev.c >>>> +++ b/lib/ethdev/rte_ethdev.c >>>> @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) >>>> int >>>> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) >>>> { >>>> + uint64_t mac_pool_sel_bk = 0; >>>> struct rte_eth_dev *dev; >>>> + uint32_t pool; >>>> + int index; >>>> int ret; >>>> >>>> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); >>>> @@ -4517,16 +4520,50 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) >>>> if (*dev->dev_ops->mac_addr_set == NULL) >>>> return -ENOTSUP; >>>> >>>> + /* >>>> + * If the address has been added as a non-default MAC address by >>>> + * rte_eth_dev_mac_addr_add API, it should be removed from >>>> + * dev->data->mac_addrs[]. >>>> + */ >>> Make is simpler: >>> "Keep address unique in dev->data->mac_addrs[]." >> Ack >>>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>>> + if (index > 0) { >>>> + /* Remove address in dev data structure */ >>>> + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; >>>> + ret = rte_eth_dev_mac_addr_remove(port_id, addr); >>>> + if (ret < 0) { >>>> + RTE_ETHDEV_LOG(ERR, "Delete MAC address from the MAC list of ethdev port %u.\n", >>>> + port_id); >>> It is not clear with this log that it failed. >> Adjust as follows? >> "Delete old address entry from the MAC list of ethdev port %u.\n" >>>> + return ret; >>>> + } >>>> + /* Reset pool bitmap */ >>>> + dev->data->mac_pool_sel[index] = 0; >>> mac_pool_sel[index] is already reset in rte_eth_dev_mac_addr_remove(). >> Yes, this can be deleted. >>>> + } >>>> ret = (*dev->dev_ops->mac_addr_set)(dev, addr); >>>> if (ret < 0) >>>> - return ret; >>>> + goto out; >>>> >>>> /* Update default address in NIC data structure */ >>>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>>> >>>> return 0; >>>> -} >>>> >>>> +out: >>>> + if (index > 0) { >>>> + pool = 0; >>>> + do { >>>> + if (mac_pool_sel_bk & UINT64_C(1)) { >>>> + if (rte_eth_dev_mac_addr_add(port_id, addr, >>>> + pool) != 0) >>>> + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n", >>>> + pool, port_id); >>>> + } >>>> + mac_pool_sel_bk >>= 1; >>>> + pool++; >>>> + } while (mac_pool_sel_bk != 0); >>>> + } >>>> + >>>> + return ret; >>>> +} >>> Can we avoid this rollback by removing the address after mac_addr_set() succeed? >> No, the new default address will be removed if we do that. >> we need to remove it first if the new default address has been added as a >> non-default MAC address to the MAC list. > OK yes. > > > .
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() doesn't remove it from the mac_addrs list. As a result, one 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 list=MAC1, MAC2, MAC3, MAC4 Note: MAC3 occupies two entries. In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the old default MAC when set default MAC. If user continues to do set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, but packets with MAC3 aren't actually received by the PMD. So need to ensure that the new default address is removed from the rest of the list. Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") Cc: stable@dpdk.org Signed-off-by: Huisong Li <lihuisong@huawei.com> Acked-by: Chengwen Feng <fengchengwen@huawei.com> --- v6: fix commit log and some code comments. v5: - merge the second patch into the first patch. - add error log when rollback failed. v4: - fix broken in the patchwork v3: - first explicitly remove the non-default MAC, then set default one. - document default and non-default MAC address v2: - fixed commit log. --- lib/ethdev/ethdev_driver.h | 6 +++++- lib/ethdev/rte_ethdev.c | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index dde3ec84ef..77acdfb95f 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -117,7 +117,11 @@ struct rte_eth_dev_data { uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ + /** + * Device Ethernet link addresses. The first entry (index zero) is the + * default address. The rest of list cannot be the same as the default + * address. + */ struct rte_ether_addr *mac_addrs; /** Bitmap associating MAC addresses to pools */ uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 86ca303ab5..de25183619 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) int rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) { + uint64_t mac_pool_sel_bk = 0; struct rte_eth_dev *dev; + uint32_t pool; + int index; int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); @@ -4517,16 +4520,44 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) if (*dev->dev_ops->mac_addr_set == NULL) return -ENOTSUP; + /* Keep address unique in dev->data->mac_addrs[]. */ + index = eth_dev_get_mac_addr_index(port_id, addr); + if (index > 0) { + /* Remove address in dev data structure */ + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; + ret = rte_eth_dev_mac_addr_remove(port_id, addr); + if (ret < 0) { + RTE_ETHDEV_LOG(ERR, "Cannot remove the port %u address from the rest of list.\n", + port_id); + return ret; + } + } ret = (*dev->dev_ops->mac_addr_set)(dev, addr); if (ret < 0) - return ret; + goto out; /* Update default address in NIC data structure */ rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); return 0; -} +out: + if (index > 0) { + pool = 0; + do { + if (mac_pool_sel_bk & UINT64_C(1)) { + if (rte_eth_dev_mac_addr_add(port_id, addr, + pool) != 0) + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n", + pool, port_id); + } + mac_pool_sel_bk >>= 1; + pool++; + } while (mac_pool_sel_bk != 0); + } + + return ret; +} /* * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find -- 2.22.0
31/01/2023 07:41, Huisong Li: > 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() doesn't remove it from the mac_addrs > list. As a result, one 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 list=MAC1, MAC2, MAC3, MAC4 > Note: MAC3 occupies two entries. > > In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the > old default MAC when set default MAC. If user continues to do > set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, > MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, > but packets with MAC3 aren't actually received by the PMD. > > So need to ensure that the new default address is removed from the rest of > the list. > > Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") > Cc: stable@dpdk.org > > Signed-off-by: Huisong Li <lihuisong@huawei.com> > Acked-by: Chengwen Feng <fengchengwen@huawei.com> > --- > lib/ethdev/ethdev_driver.h | 6 +++++- > lib/ethdev/rte_ethdev.c | 35 +++++++++++++++++++++++++++++++++-- > 2 files changed, 38 insertions(+), 3 deletions(-) This is a behavior change. It must be noted in the release notes in the API section. > - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ > + /** > + * Device Ethernet link addresses. The first entry (index zero) is the > + * default address. The rest of list cannot be the same as the default > + * address. > + */ Please split the lines after a dot. rest of "the" list Maybe better for this field: All entries are unique. The first entry (index zero) is the default address. > struct rte_ether_addr *mac_addrs; and for the function rte_eth_dev_default_mac_addr_set: Set the default MAC address. It replaces the address at index 0 of the address list. If the address was already in the MAC address list, it is removed from the rest of the list.
在 2023/2/1 18:42, Thomas Monjalon 写道: > 31/01/2023 07:41, Huisong Li: >> 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() doesn't remove it from the mac_addrs >> list. As a result, one 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 list=MAC1, MAC2, MAC3, MAC4 >> Note: MAC3 occupies two entries. >> >> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the >> old default MAC when set default MAC. If user continues to do >> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, >> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, >> but packets with MAC3 aren't actually received by the PMD. >> >> So need to ensure that the new default address is removed from the rest of >> the list. >> >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >> Cc: stable@dpdk.org >> >> Signed-off-by: Huisong Li <lihuisong@huawei.com> >> Acked-by: Chengwen Feng <fengchengwen@huawei.com> >> --- >> lib/ethdev/ethdev_driver.h | 6 +++++- >> lib/ethdev/rte_ethdev.c | 35 +++++++++++++++++++++++++++++++++-- >> 2 files changed, 38 insertions(+), 3 deletions(-) > This is a behavior change. > It must be noted in the release notes in the API section. ok. I will add an announcement. >> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ >> + /** >> + * Device Ethernet link addresses. The first entry (index zero) is the >> + * default address. The rest of list cannot be the same as the default >> + * address. >> + */ > Please split the lines after a dot. > > rest of "the" list > > Maybe better for this field: > All entries are unique. > The first entry (index zero) is the default address. It's more simpler. Thank you for your suggestion. >> struct rte_ether_addr *mac_addrs; > and for the function rte_eth_dev_default_mac_addr_set: > Set the default MAC address. > It replaces the address at index 0 of the address list. > If the address was already in the MAC address list, > it is removed from the rest of the list. Indeed, It's better to document it. > > > > .
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() doesn't remove it from the mac_addrs list. As a result, one 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 list=MAC1, MAC2, MAC3, MAC4 Note: MAC3 occupies two entries. In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the old default MAC when set default MAC. If user continues to do set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, but packets with MAC3 aren't actually received by the PMD. So need to ensure that the new default address is removed from the rest of the list if the address was already in the list. Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") Cc: stable@dpdk.org Signed-off-by: Huisong Li <lihuisong@huawei.com> Acked-by: Chengwen Feng <fengchengwen@huawei.com> --- v7: add announcement in the release notes and document this behavior. v6: fix commit log and some code comments. v5: - merge the second patch into the first patch. - add error log when rollback failed. v4: - fix broken in the patchwork v3: - first explicitly remove the non-default MAC, then set default one. - document default and non-default MAC address v2: - fixed commit log. --- doc/guides/rel_notes/release_23_03.rst | 6 +++++ lib/ethdev/ethdev_driver.h | 6 ++++- lib/ethdev/rte_ethdev.c | 35 ++++++++++++++++++++++++-- lib/ethdev/rte_ethdev.h | 3 +++ 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst index 84b112a8b1..f63ec2b399 100644 --- a/doc/guides/rel_notes/release_23_03.rst +++ b/doc/guides/rel_notes/release_23_03.rst @@ -101,10 +101,16 @@ API Changes Use fixed width quotes for ``function_names`` or ``struct_names``. Use the past tense. + This section is a comment. Do not overwrite or remove it. Also, make sure to start the actual text at the margin. ======================================================= + * ethdev: ensured all entries in MAC address list is unique. + The function ``rte_eth_dev_default_mac_addr_set`` replaces the address + at index 0 of the address list. If the address was already in the + address list, it is removed from the rest of the list. + ABI Changes ----------- diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index dde3ec84ef..14a1d9adad 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -117,7 +117,11 @@ struct rte_eth_dev_data { uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ + /** + * Device Ethernet link addresses. + * All entries are unique. The first entry (index zero) is the + * default address. + */ struct rte_ether_addr *mac_addrs; /** Bitmap associating MAC addresses to pools */ uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 86ca303ab5..de25183619 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) int rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) { + uint64_t mac_pool_sel_bk = 0; struct rte_eth_dev *dev; + uint32_t pool; + int index; int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); @@ -4517,16 +4520,44 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) if (*dev->dev_ops->mac_addr_set == NULL) return -ENOTSUP; + /* Keep address unique in dev->data->mac_addrs[]. */ + index = eth_dev_get_mac_addr_index(port_id, addr); + if (index > 0) { + /* Remove address in dev data structure */ + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; + ret = rte_eth_dev_mac_addr_remove(port_id, addr); + if (ret < 0) { + RTE_ETHDEV_LOG(ERR, "Cannot remove the port %u address from the rest of list.\n", + port_id); + return ret; + } + } ret = (*dev->dev_ops->mac_addr_set)(dev, addr); if (ret < 0) - return ret; + goto out; /* Update default address in NIC data structure */ rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); return 0; -} +out: + if (index > 0) { + pool = 0; + do { + if (mac_pool_sel_bk & UINT64_C(1)) { + if (rte_eth_dev_mac_addr_add(port_id, addr, + pool) != 0) + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n", + pool, port_id); + } + mac_pool_sel_bk >>= 1; + pool++; + } while (mac_pool_sel_bk != 0); + } + + return ret; +} /* * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index d22de196db..609328f1e3 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -4356,6 +4356,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, it is removed from + * the rest of the list. * * @param port_id * The port identifier of the Ethernet device. -- 2.22.0
01/02/2023 14:15, Huisong Li: > 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() doesn't remove it from the mac_addrs > list. As a result, one 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 list=MAC1, MAC2, MAC3, MAC4 > Note: MAC3 occupies two entries. > > In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the > old default MAC when set default MAC. If user continues to do > set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, > MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, > but packets with MAC3 aren't actually received by the PMD. > > So need to ensure that the new default address is removed from the rest of > the list if the address was already in the list. > > Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") > Cc: stable@dpdk.org > > Signed-off-by: Huisong Li <lihuisong@huawei.com> > Acked-by: Chengwen Feng <fengchengwen@huawei.com> [...] > --- a/doc/guides/rel_notes/release_23_03.rst > +++ b/doc/guides/rel_notes/release_23_03.rst > @@ -101,10 +101,16 @@ API Changes > Use fixed width quotes for ``function_names`` or ``struct_names``. > Use the past tense. > > + useless line? > This section is a comment. Do not overwrite or remove it. > Also, make sure to start the actual text at the margin. > ======================================================= Please check the comment: "make sure to start the actual text at the margin." > + * ethdev: ensured all entries in MAC address list is unique. is -> are uniques > + The function ``rte_eth_dev_default_mac_addr_set`` replaces the address > + at index 0 of the address list. If the address was already in the > + address list, it is removed from the rest of the list. You need to highlight what changed: When setting a default MAC address with the function ``rte_eth_dev_default_mac_addr_set``, the address is now removed from the rest of the address list in order to ensure it is only at index 0 of the list. [...] > --- a/lib/ethdev/ethdev_driver.h > +++ b/lib/ethdev/ethdev_driver.h > @@ -117,7 +117,11 @@ struct rte_eth_dev_data { > > uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ > > - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ > + /** > + * Device Ethernet link addresses. > + * All entries are unique. The first entry (index zero) is the > + * default address. > + */ You remember I asked to split lines after the dot? > /** > * 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, it is removed from > + * the rest of the list. Here you can split after the comma.
在 2023/2/2 0:37, Thomas Monjalon 写道: > 01/02/2023 14:15, Huisong Li: >> 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() doesn't remove it from the mac_addrs >> list. As a result, one 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 list=MAC1, MAC2, MAC3, MAC4 >> Note: MAC3 occupies two entries. >> >> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the >> old default MAC when set default MAC. If user continues to do >> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, >> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, >> but packets with MAC3 aren't actually received by the PMD. >> >> So need to ensure that the new default address is removed from the rest of >> the list if the address was already in the list. >> >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >> Cc: stable@dpdk.org >> >> Signed-off-by: Huisong Li <lihuisong@huawei.com> >> Acked-by: Chengwen Feng <fengchengwen@huawei.com> > [...] >> --- a/doc/guides/rel_notes/release_23_03.rst >> +++ b/doc/guides/rel_notes/release_23_03.rst >> @@ -101,10 +101,16 @@ API Changes >> Use fixed width quotes for ``function_names`` or ``struct_names``. >> Use the past tense. >> >> + > useless line? will remove. > >> This section is a comment. Do not overwrite or remove it. >> Also, make sure to start the actual text at the margin. >> ======================================================= > Please check the comment: "make sure to start the actual text at the margin." It means to start the actual text at the beginning of the line, right? > >> + * ethdev: ensured all entries in MAC address list is unique. > is -> are uniques All right. > >> + The function ``rte_eth_dev_default_mac_addr_set`` replaces the address >> + at index 0 of the address list. If the address was already in the >> + address list, it is removed from the rest of the list. > You need to highlight what changed: > > When setting a default MAC address with the function > ``rte_eth_dev_default_mac_addr_set``, > the address is now removed from the rest of the address list > in order to ensure it is only at index 0 of the list. ok, highlight it. > > [...] >> --- a/lib/ethdev/ethdev_driver.h >> +++ b/lib/ethdev/ethdev_driver.h >> @@ -117,7 +117,11 @@ struct rte_eth_dev_data { >> >> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ >> >> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ >> + /** >> + * Device Ethernet link addresses. >> + * All entries are unique. The first entry (index zero) is the >> + * default address. >> + */ > You remember I asked to split lines after the dot? Sorry for my misunderstanding. Need to occupy one line for each sentence here? Do we generally use this style to make comments? or are we just trying to highlight it here? > >> /** >> * 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, it is removed from >> + * the rest of the list. > Here you can split after the comma. Ack > > > > .
02/02/2023 02:11, lihuisong (C): > 在 2023/2/2 0:37, Thomas Monjalon 写道: > > 01/02/2023 14:15, Huisong Li: > >> This section is a comment. Do not overwrite or remove it. > >> Also, make sure to start the actual text at the margin. > >> ======================================================= > > Please check the comment: "make sure to start the actual text at the margin." > > It means to start the actual text at the beginning of the line, right? It means no extra space at the beginning of the line. > >> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ > >> + /** > >> + * Device Ethernet link addresses. > >> + * All entries are unique. The first entry (index zero) is the > >> + * default address. > >> + */ > > You remember I asked to split lines after the dot? > Sorry for my misunderstanding. Need to occupy one line for each sentence > here? A sentence may be longer than one line, but it is better split lines logically (after dots, commas, etc). > Do we generally use this style to make comments? or are we just trying > to highlight it here? That's a recommendation when writing text (comments and rst doc). Having lines split logically may help reading, and will make simpler patches when updating in future, because in general we change a single sentence.
在 2023/2/2 19:50, Thomas Monjalon 写道: > 02/02/2023 02:11, lihuisong (C): >> 在 2023/2/2 0:37, Thomas Monjalon 写道: >>> 01/02/2023 14:15, Huisong Li: >>>> This section is a comment. Do not overwrite or remove it. >>>> Also, make sure to start the actual text at the margin. >>>> ======================================================= >>> Please check the comment: "make sure to start the actual text at the margin." >> It means to start the actual text at the beginning of the line, right? > It means no extra space at the beginning of the line. > >>>> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ >>>> + /** >>>> + * Device Ethernet link addresses. >>>> + * All entries are unique. The first entry (index zero) is the >>>> + * default address. >>>> + */ >>> You remember I asked to split lines after the dot? >> Sorry for my misunderstanding. Need to occupy one line for each sentence >> here? > A sentence may be longer than one line, > but it is better split lines logically (after dots, commas, etc). > >> Do we generally use this style to make comments? or are we just trying >> to highlight it here? > That's a recommendation when writing text (comments and rst doc). > Having lines split logically may help reading, > and will make simpler patches when updating in future, > because in general we change a single sentence. All right, got it. The next version will be out soon. > > > .
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() doesn't remove it from the mac_addrs list. As a result, one 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. In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the old default MAC when set default MAC. If user continues to do set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, but packets with MAC3 aren't actually received by the PMD. So need to ensure that the new default address is removed from the rest of the list if the address was already in the list. Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") Cc: stable@dpdk.org Signed-off-by: Huisong Li <lihuisong@huawei.com> Acked-by: Chengwen Feng <fengchengwen@huawei.com> --- v8: fix some comments. v7: add announcement in the release notes and document this behavior. v6: fix commit log and some code comments. v5: - merge the second patch into the first patch. - add error log when rollback failed. v4: - fix broken in the patchwork v3: - first explicitly remove the non-default MAC, then set default one. - document default and non-default MAC address v2: - fixed commit log. --- doc/guides/rel_notes/release_23_03.rst | 6 +++++ lib/ethdev/ethdev_driver.h | 6 ++++- lib/ethdev/rte_ethdev.c | 35 ++++++++++++++++++++++++-- lib/ethdev/rte_ethdev.h | 3 +++ 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst index 84b112a8b1..1c9b9912c2 100644 --- a/doc/guides/rel_notes/release_23_03.rst +++ b/doc/guides/rel_notes/release_23_03.rst @@ -105,6 +105,12 @@ API Changes Also, make sure to start the actual text at the margin. ======================================================= +* ethdev: ensured all entries in MAC address list are uniques. + When setting a default MAC address with the function + ``rte_eth_dev_default_mac_addr_set``, + the address is now removed from the rest of the address list + in order to ensure it is only at index 0 of the list. + ABI Changes ----------- diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index dde3ec84ef..3994c61b86 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -117,7 +117,11 @@ struct rte_eth_dev_data { uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ + /** + * Device Ethernet link addresses. + * All entries are unique. + * The first entry (index zero) is the default address. + */ struct rte_ether_addr *mac_addrs; /** Bitmap associating MAC addresses to pools */ uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 86ca303ab5..de25183619 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) int rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) { + uint64_t mac_pool_sel_bk = 0; struct rte_eth_dev *dev; + uint32_t pool; + int index; int ret; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); @@ -4517,16 +4520,44 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) if (*dev->dev_ops->mac_addr_set == NULL) return -ENOTSUP; + /* Keep address unique in dev->data->mac_addrs[]. */ + index = eth_dev_get_mac_addr_index(port_id, addr); + if (index > 0) { + /* Remove address in dev data structure */ + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; + ret = rte_eth_dev_mac_addr_remove(port_id, addr); + if (ret < 0) { + RTE_ETHDEV_LOG(ERR, "Cannot remove the port %u address from the rest of list.\n", + port_id); + return ret; + } + } ret = (*dev->dev_ops->mac_addr_set)(dev, addr); if (ret < 0) - return ret; + goto out; /* Update default address in NIC data structure */ rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); return 0; -} +out: + if (index > 0) { + pool = 0; + do { + if (mac_pool_sel_bk & UINT64_C(1)) { + if (rte_eth_dev_mac_addr_add(port_id, addr, + pool) != 0) + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n", + pool, port_id); + } + mac_pool_sel_bk >>= 1; + pool++; + } while (mac_pool_sel_bk != 0); + } + + return ret; +} /* * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index d22de196db..2456153457 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -4356,6 +4356,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, + * it is removed from the rest of the list. * * @param port_id * The port identifier of the Ethernet device. -- 2.22.0
02/02/2023 13:36, Huisong Li:
> 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() doesn't remove it from the mac_addrs
> list. As a result, one 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.
>
> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the
> old default MAC when set default MAC. If user continues to do
> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1,
> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list,
> but packets with MAC3 aren't actually received by the PMD.
>
> So need to ensure that the new default address is removed from the rest of
> the list if the address was already in the list.
>
> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
> Cc: stable@dpdk.org
>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> Acked-by: Chengwen Feng <fengchengwen@huawei.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
Thank you
On 2/2/2023 12:36 PM, Huisong Li wrote: > 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() doesn't remove it from the mac_addrs > list. As a result, one 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. > > In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the > old default MAC when set default MAC. If user continues to do > set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, > MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, > but packets with MAC3 aren't actually received by the PMD. > > So need to ensure that the new default address is removed from the rest of > the list if the address was already in the list. > Same comment from past seems already valid, I am not looking to the set for a while, sorry if this is already discussed and decided, if not, I am referring to the side effect that setting MAC addresses cause to remove MAC addresses, think following case: add(MAC1) -> MAC1 add(MAC2) -> MAC1, MAC2 add(MAC3) -> MAC1, MAC2, MAC3 add(MAC4) -> MAC1, MAC2, MAC3, MAC4 set(MAC3) -> MAC3, MAC2, MAC4 set(MAC4) -> MAC4, MAC2 set(MAC2) -> MAC2 I am not exactly clear what is the intention with set(), if there is single MAC I guess intention is to replace it with new one, but if there are multiple MACs and one of them are already in the list intention may be just to change the default MAC. If above assumption is correct, what about following: set(MAC) { if only_default_mac_exist replace_default_mac if MAC exists in list swap MAC and list[0] else replace_default_mac } This swap prevents removing MAC side affect, does it make sense? > Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") > Cc: stable@dpdk.org > > Signed-off-by: Huisong Li <lihuisong@huawei.com> > Acked-by: Chengwen Feng <fengchengwen@huawei.com> > --- > v8: fix some comments. > v7: add announcement in the release notes and document this behavior. > v6: fix commit log and some code comments. > v5: > - merge the second patch into the first patch. > - add error log when rollback failed. > v4: > - fix broken in the patchwork > v3: > - first explicitly remove the non-default MAC, then set default one. > - document default and non-default MAC address > v2: > - fixed commit log. > --- > doc/guides/rel_notes/release_23_03.rst | 6 +++++ > lib/ethdev/ethdev_driver.h | 6 ++++- > lib/ethdev/rte_ethdev.c | 35 ++++++++++++++++++++++++-- > lib/ethdev/rte_ethdev.h | 3 +++ > 4 files changed, 47 insertions(+), 3 deletions(-) > > diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst > index 84b112a8b1..1c9b9912c2 100644 > --- a/doc/guides/rel_notes/release_23_03.rst > +++ b/doc/guides/rel_notes/release_23_03.rst > @@ -105,6 +105,12 @@ API Changes > Also, make sure to start the actual text at the margin. > ======================================================= > > +* ethdev: ensured all entries in MAC address list are uniques. > + When setting a default MAC address with the function > + ``rte_eth_dev_default_mac_addr_set``, > + the address is now removed from the rest of the address list > + in order to ensure it is only at index 0 of the list. > + > > ABI Changes > ----------- > diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h > index dde3ec84ef..3994c61b86 100644 > --- a/lib/ethdev/ethdev_driver.h > +++ b/lib/ethdev/ethdev_driver.h > @@ -117,7 +117,11 @@ struct rte_eth_dev_data { > > uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ > > - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ > + /** > + * Device Ethernet link addresses. > + * All entries are unique. > + * The first entry (index zero) is the default address. > + */ > struct rte_ether_addr *mac_addrs; > /** Bitmap associating MAC addresses to pools */ > uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; > diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c > index 86ca303ab5..de25183619 100644 > --- a/lib/ethdev/rte_ethdev.c > +++ b/lib/ethdev/rte_ethdev.c > @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr) > int > rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) > { > + uint64_t mac_pool_sel_bk = 0; > struct rte_eth_dev *dev; > + uint32_t pool; > + int index; > int ret; > > RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); > @@ -4517,16 +4520,44 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) > if (*dev->dev_ops->mac_addr_set == NULL) > return -ENOTSUP; > > + /* Keep address unique in dev->data->mac_addrs[]. */ > + index = eth_dev_get_mac_addr_index(port_id, addr); > + if (index > 0) { > + /* Remove address in dev data structure */ > + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; > + ret = rte_eth_dev_mac_addr_remove(port_id, addr); > + if (ret < 0) { > + RTE_ETHDEV_LOG(ERR, "Cannot remove the port %u address from the rest of list.\n", > + port_id); > + return ret; > + } > + } > ret = (*dev->dev_ops->mac_addr_set)(dev, addr); > if (ret < 0) > - return ret; > + goto out; > > /* Update default address in NIC data structure */ > rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); > > return 0; > -} > > +out: > + if (index > 0) { > + pool = 0; > + do { > + if (mac_pool_sel_bk & UINT64_C(1)) { > + if (rte_eth_dev_mac_addr_add(port_id, addr, > + pool) != 0) > + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n", > + pool, port_id); > + } > + mac_pool_sel_bk >>= 1; > + pool++; > + } while (mac_pool_sel_bk != 0); > + } > + > + return ret; > +} > > /* > * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find > diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h > index d22de196db..2456153457 100644 > --- a/lib/ethdev/rte_ethdev.h > +++ b/lib/ethdev/rte_ethdev.h > @@ -4356,6 +4356,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, > + * it is removed from the rest of the list. > * > * @param port_id > * The port identifier of the Ethernet device.
02/02/2023 19:09, Ferruh Yigit: > On 2/2/2023 12:36 PM, Huisong Li wrote: > > 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() doesn't remove it from the mac_addrs > > list. As a result, one 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. > > > > In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the > > old default MAC when set default MAC. If user continues to do > > set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, > > MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, > > but packets with MAC3 aren't actually received by the PMD. > > > > So need to ensure that the new default address is removed from the rest of > > the list if the address was already in the list. > > > > Same comment from past seems already valid, I am not looking to the set > for a while, sorry if this is already discussed and decided, > if not, I am referring to the side effect that setting MAC addresses > cause to remove MAC addresses, think following case: > > add(MAC1) -> MAC1 > add(MAC2) -> MAC1, MAC2 > add(MAC3) -> MAC1, MAC2, MAC3 > add(MAC4) -> MAC1, MAC2, MAC3, MAC4 > set(MAC3) -> MAC3, MAC2, MAC4 > set(MAC4) -> MAC4, MAC2 > set(MAC2) -> MAC2 > > I am not exactly clear what is the intention with set(), That's the problem, nobody is clear with the current behavior. The doc says "Set the default MAC address." and nothing else. > if there is > single MAC I guess intention is to replace it with new one, but if there > are multiple MACs and one of them are already in the list intention may > be just to change the default MAC. The assumption in this patch is that "Set" means "Replace", not "Swap". So this patch takes the approach 1/ Replace and keep Unique. > If above assumption is correct, what about following: > > set(MAC) { > if only_default_mac_exist > replace_default_mac > > if MAC exists in list > swap MAC and list[0] > else > replace_default_mac > } This approach 2/ is a mix of Swap and Replace. The old default MAC destiny depends on whether we have added the new MAC as "secondary" before setting as new default. > This swap prevents removing MAC side affect, does it make sense? Another approach would be 3/ to do an "Always Swap" even if the new MAC didn't exist before, you keep the old default MAC as a secondary MAC. And the current approach 0/ is to Replace default MAC address without touching the secondary addresses at all. So we have 4 choices. We could vote, roll a dice, or find a strong argument?
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Thursday, 2 February 2023 22.11
>
> 02/02/2023 19:09, Ferruh Yigit:
> > On 2/2/2023 12:36 PM, Huisong Li wrote:
> > > 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() doesn't remove it from the
> mac_addrs
> > > list. As a result, one 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.
> > >
> > > In addition, some PMDs, such as i40e, ice, hns3 and so on, do
> remove the
> > > old default MAC when set default MAC. If user continues to do
> > > set_default(MAC5), and the mac_addrs list is default=MAC5,
> filters=(MAC1,
> > > MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the
> list,
> > > but packets with MAC3 aren't actually received by the PMD.
> > >
> > > So need to ensure that the new default address is removed from the
> rest of
> > > the list if the address was already in the list.
> > >
> >
> > Same comment from past seems already valid, I am not looking to the
> set
> > for a while, sorry if this is already discussed and decided,
> > if not, I am referring to the side effect that setting MAC addresses
> > cause to remove MAC addresses, think following case:
> >
> > add(MAC1) -> MAC1
> > add(MAC2) -> MAC1, MAC2
> > add(MAC3) -> MAC1, MAC2, MAC3
> > add(MAC4) -> MAC1, MAC2, MAC3, MAC4
> > set(MAC3) -> MAC3, MAC2, MAC4
> > set(MAC4) -> MAC4, MAC2
> > set(MAC2) -> MAC2
> >
> > I am not exactly clear what is the intention with set(),
>
> That's the problem, nobody is clear with the current behavior.
> The doc says "Set the default MAC address." and nothing else.
>
> > if there is
> > single MAC I guess intention is to replace it with new one, but if
> there
> > are multiple MACs and one of them are already in the list intention
> may
> > be just to change the default MAC.
>
> The assumption in this patch is that "Set" means "Replace", not "Swap".
> So this patch takes the approach 1/ Replace and keep Unique.
>
> > If above assumption is correct, what about following:
> >
> > set(MAC) {
> > if only_default_mac_exist
> > replace_default_mac
> >
> > if MAC exists in list
> > swap MAC and list[0]
> > else
> > replace_default_mac
> > }
>
> This approach 2/ is a mix of Swap and Replace.
> The old default MAC destiny depends on whether
> we have added the new MAC as "secondary" before setting as new default.
>
> > This swap prevents removing MAC side affect, does it make sense?
>
> Another approach would be 3/ to do an "Always Swap"
> even if the new MAC didn't exist before,
> you keep the old default MAC as a secondary MAC.
>
> And the current approach 0/ is to Replace default MAC address
> without touching the secondary addresses at all.
>
> So we have 4 choices.
> We could vote, roll a dice, or find a strong argument?
If there is only one MAC, MAC1, I would certainly expect Set(MAC2) to replace MAC1 with MAC2.
If there is a list of MACs, I might expect Set() to select one in the list. And, if calling Set() with a MAC not in the list, we could either 1. return an error, or 2. implicitly add it to the list and then set it.
If we implicitly add it to the list (i.e. follow option 2 described above), it should not be implicitly be removed from the list if another MAC is Set(). This behavior seems weird, which speaks for returning an error if setting a MAC not in the list (i.e. option 1).
Disclaimer: I have no experience configuring NICs with multiple MACs - we promiscuous mode or one MAC address. So my input regarding multiple MACs is purely theoretical.
在 2023/2/3 5:10, Thomas Monjalon 写道: > 02/02/2023 19:09, Ferruh Yigit: >> On 2/2/2023 12:36 PM, Huisong Li wrote: >>> 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() doesn't remove it from the mac_addrs >>> list. As a result, one 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. >>> >>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the >>> old default MAC when set default MAC. If user continues to do >>> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, >>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, >>> but packets with MAC3 aren't actually received by the PMD. >>> >>> So need to ensure that the new default address is removed from the rest of >>> the list if the address was already in the list. >>> >> Same comment from past seems already valid, I am not looking to the set >> for a while, sorry if this is already discussed and decided, >> if not, I am referring to the side effect that setting MAC addresses >> cause to remove MAC addresses, think following case: >> >> add(MAC1) -> MAC1 >> add(MAC2) -> MAC1, MAC2 >> add(MAC3) -> MAC1, MAC2, MAC3 >> add(MAC4) -> MAC1, MAC2, MAC3, MAC4 >> set(MAC3) -> MAC3, MAC2, MAC4 >> set(MAC4) -> MAC4, MAC2 >> set(MAC2) -> MAC2 >> >> I am not exactly clear what is the intention with set(), > That's the problem, nobody is clear with the current behavior. > The doc says "Set the default MAC address." and nothing else. Indeed. But we can see the following information. From the ethdev layer, this set() API always replaces the old default address (index 0) without adding the old one. From the PMD layer, set() interface of some PMDs, such as i40e, ice, hns3 and so on (as far as I know), also do remove the hardware entry of the old default address. > >> if there is >> single MAC I guess intention is to replace it with new one, but if there >> are multiple MACs and one of them are already in the list intention may >> be just to change the default MAC. > The assumption in this patch is that "Set" means "Replace", not "Swap". > So this patch takes the approach 1/ Replace and keep Unique. > >> If above assumption is correct, what about following: >> >> set(MAC) { >> if only_default_mac_exist >> replace_default_mac >> >> if MAC exists in list >> swap MAC and list[0] >> else >> replace_default_mac >> } > This approach 2/ is a mix of Swap and Replace. > The old default MAC destiny depends on whether > we have added the new MAC as "secondary" before setting as new default. > >> This swap prevents removing MAC side affect, does it make sense? > Another approach would be 3/ to do an "Always Swap" > even if the new MAC didn't exist before, > you keep the old default MAC as a secondary MAC. > > And the current approach 0/ is to Replace default MAC address > without touching the secondary addresses at all. > > So we have 4 choices. > We could vote, roll a dice, or find a strong argument? According to the implement of set() in ethdev and PMD layer, it always use "Replace", not "Swap". If we use "Swap" now, the behavior of this API will be changed. I'm not sure if the application can accept this change or has other effects. BTW, it seems that the ethernet port in kernel also replaces the old address if we modify the one. Use the test command: ifconfig eth0 hw ether new_mac > > > .
On 2/3/2023 1:56 AM, lihuisong (C) wrote: > > 在 2023/2/3 5:10, Thomas Monjalon 写道: >> 02/02/2023 19:09, Ferruh Yigit: >>> On 2/2/2023 12:36 PM, Huisong Li wrote: >>>> 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() doesn't remove it from the >>>> mac_addrs >>>> list. As a result, one 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. >>>> >>>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove >>>> the >>>> old default MAC when set default MAC. If user continues to do >>>> set_default(MAC5), and the mac_addrs list is default=MAC5, >>>> filters=(MAC1, >>>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the >>>> list, >>>> but packets with MAC3 aren't actually received by the PMD. >>>> >>>> So need to ensure that the new default address is removed from the >>>> rest of >>>> the list if the address was already in the list. >>>> >>> Same comment from past seems already valid, I am not looking to the set >>> for a while, sorry if this is already discussed and decided, >>> if not, I am referring to the side effect that setting MAC addresses >>> cause to remove MAC addresses, think following case: >>> >>> add(MAC1) -> MAC1 >>> add(MAC2) -> MAC1, MAC2 >>> add(MAC3) -> MAC1, MAC2, MAC3 >>> add(MAC4) -> MAC1, MAC2, MAC3, MAC4 >>> set(MAC3) -> MAC3, MAC2, MAC4 >>> set(MAC4) -> MAC4, MAC2 >>> set(MAC2) -> MAC2 >>> >>> I am not exactly clear what is the intention with set(), >> That's the problem, nobody is clear with the current behavior. >> The doc says "Set the default MAC address." and nothing else. > Indeed. But we can see the following information. > From the ethdev layer, this set() API always replaces the old default > address (index 0) without adding the old one. > From the PMD layer, set() interface of some PMDs, such as i40e, ice, > hns3 and so on (as far as I know), > also do remove the hardware entry of the old default address. If we define behavior clearly, I think we can adapt PMD implementation according it, unless there is HW limitation. >> >>> if there is >>> single MAC I guess intention is to replace it with new one, but if there >>> are multiple MACs and one of them are already in the list intention may >>> be just to change the default MAC. >> The assumption in this patch is that "Set" means "Replace", not "Swap". >> So this patch takes the approach 1/ Replace and keep Unique. >> >>> If above assumption is correct, what about following: >>> >>> set(MAC) { >>> if only_default_mac_exist >>> replace_default_mac >>> >>> if MAC exists in list >>> swap MAC and list[0] >>> else >>> replace_default_mac >>> } >> This approach 2/ is a mix of Swap and Replace. >> The old default MAC destiny depends on whether >> we have added the new MAC as "secondary" before setting as new default. >> >>> This swap prevents removing MAC side affect, does it make sense? >> Another approach would be 3/ to do an "Always Swap" >> even if the new MAC didn't exist before, >> you keep the old default MAC as a secondary MAC. >> >> And the current approach 0/ is to Replace default MAC address >> without touching the secondary addresses at all. >> >> So we have 4 choices. >> We could vote, roll a dice, or find a strong argument? > According to the implement of set() in ethdev and PMD layer, it always > use "Replace", not "Swap". > If we use "Swap" now, the behavior of this API will be changed. > I'm not sure if the application can accept this change or has other > effects. > This patch is also changing behavior, because of implied remove address, same concern is valid with this patch. As I checked again current implementation may have one more problem (this from reading code, I did not test this): add(MAC1) -> MAC1 add(MAC2) -> MAC1, MAC2 set(MAC2) -> MAC2, MAC2 del(MAC2) -> FAILS This fails because `rte_eth_dev_mac_addr_remove()` can't remove default MAC, and it only tries to remove first address it finds, it can't find and remove second 'MAC2'. I wasn't too much bothered with wasting one MAC address slot, so wasn't sure if a change is required at all, but if above analysis is correct I think this is more serious problem to justify the change. I don't think always swap (option /3) is good idea, specially for single MAC address exists case, and current case has (option 0/) has mentioned problems. Remaining ones are mix of swap and replace (option 2/) and this patch (option /1). I think mix of swap and replace (option 2/ above) has some benefits: - It always replaces default MAC - Prevents duplication MAC address in the list - Doesn't implicitly remove address from list BUT, if the agreement is this patch (option 1/) I am OK with that too, I just want to make sure that it is discussed. > BTW, it seems that the ethernet port in kernel also replaces the old > address if we modify the one. > Use the test command: ifconfig eth0 hw ether new_mac For default MAC address it is more clear that intention is to replace it, but question is about what to do with the list of MAC addresses.
在 2023/2/3 20:58, Ferruh Yigit 写道: > On 2/3/2023 1:56 AM, lihuisong (C) wrote: >> 在 2023/2/3 5:10, Thomas Monjalon 写道: >>> 02/02/2023 19:09, Ferruh Yigit: >>>> On 2/2/2023 12:36 PM, Huisong Li wrote: >>>>> 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() doesn't remove it from the >>>>> mac_addrs >>>>> list. As a result, one 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. >>>>> >>>>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove >>>>> the >>>>> old default MAC when set default MAC. If user continues to do >>>>> set_default(MAC5), and the mac_addrs list is default=MAC5, >>>>> filters=(MAC1, >>>>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the >>>>> list, >>>>> but packets with MAC3 aren't actually received by the PMD. >>>>> >>>>> So need to ensure that the new default address is removed from the >>>>> rest of >>>>> the list if the address was already in the list. >>>>> >>>> Same comment from past seems already valid, I am not looking to the set >>>> for a while, sorry if this is already discussed and decided, >>>> if not, I am referring to the side effect that setting MAC addresses >>>> cause to remove MAC addresses, think following case: >>>> >>>> add(MAC1) -> MAC1 >>>> add(MAC2) -> MAC1, MAC2 >>>> add(MAC3) -> MAC1, MAC2, MAC3 >>>> add(MAC4) -> MAC1, MAC2, MAC3, MAC4 >>>> set(MAC3) -> MAC3, MAC2, MAC4 >>>> set(MAC4) -> MAC4, MAC2 >>>> set(MAC2) -> MAC2 >>>> >>>> I am not exactly clear what is the intention with set(), >>> That's the problem, nobody is clear with the current behavior. >>> The doc says "Set the default MAC address." and nothing else. >> Indeed. But we can see the following information. >> From the ethdev layer, this set() API always replaces the old default >> address (index 0) without adding the old one. >> From the PMD layer, set() interface of some PMDs, such as i40e, ice, >> hns3 and so on (as far as I know), >> also do remove the hardware entry of the old default address. > If we define behavior clearly, I think we can adapt PMD implementation > according it, unless there is HW limitation. Right. I think this is another point (issue 2/) to be discussed. Namely, whether the old default address should be removed when set new default one. If we want to explicitly unify the behavior of all PMDs in ethdev layer as described above, there may be no problem if do the following: 1) In the ethdev layer, remove the old default address if the old one is exist. 2) For PMD i40e, ice and hns3, remvoe the code of deleting the old default address before adding the new one. For other PMDs, we probably don't need to do anything because they have supported remove_addr() API. (Without explicitly removing the old default address, I don't know if their hardware or firmware removes the old one when set a new address. But, we explicitly remove the old one in ethdev layer now, I'm not sure if this has an effect on these PMDs.) >>>> if there is >>>> single MAC I guess intention is to replace it with new one, but if there >>>> are multiple MACs and one of them are already in the list intention may >>>> be just to change the default MAC. >>> The assumption in this patch is that "Set" means "Replace", not "Swap". >>> So this patch takes the approach 1/ Replace and keep Unique. >>> >>>> If above assumption is correct, what about following: >>>> >>>> set(MAC) { >>>> if only_default_mac_exist >>>> replace_default_mac >>>> >>>> if MAC exists in list >>>> swap MAC and list[0] >>>> else >>>> replace_default_mac >>>> } >>> This approach 2/ is a mix of Swap and Replace. >>> The old default MAC destiny depends on whether >>> we have added the new MAC as "secondary" before setting as new default. >>> >>>> This swap prevents removing MAC side affect, does it make sense? >>> Another approach would be 3/ to do an "Always Swap" >>> even if the new MAC didn't exist before, >>> you keep the old default MAC as a secondary MAC. >>> >>> And the current approach 0/ is to Replace default MAC address >>> without touching the secondary addresses at all. >>> >>> So we have 4 choices. >>> We could vote, roll a dice, or find a strong argument? >> According to the implement of set() in ethdev and PMD layer, it always >> use "Replace", not "Swap". >> If we use "Swap" now, the behavior of this API will be changed. >> I'm not sure if the application can accept this change or has other >> effects. >> > This patch is also changing behavior, because of implied remove address, > same concern is valid with this patch. Indeed, it changes the behavior. But this patch only resolves the problem (issue 1/) that the entries of the MAC address list possibly are not uniques. Fixing it may be little impact on the application. > > > As I checked again current implementation may have one more problem > (this from reading code, I did not test this): > add(MAC1) -> MAC1 > add(MAC2) -> MAC1, MAC2 > set(MAC2) -> MAC2, MAC2 > del(MAC2) -> FAILS > > This fails because `rte_eth_dev_mac_addr_remove()` can't remove default > MAC, and it only tries to remove first address it finds, it can't find > and remove second 'MAC2'. > I wasn't too much bothered with wasting one MAC address slot, so wasn't > sure if a change is required at all, but if above analysis is correct I > think this is more serious problem to justify the change. Your analysis is fully correct. > > > I don't think always swap (option /3) is good idea, specially for single > MAC address exists case, and current case has (option 0/) has mentioned > problems. +1 > Remaining ones are mix of swap and replace (option 2/) and this patch > (option /1). > > I think mix of swap and replace (option 2/ above) has some benefits: > - It always replaces default MAC > - Prevents duplication MAC address in the list > - Doesn't implicitly remove address from list As far as I know, the first entry (index 0) always be the default address in all PMDs, but it's not documented. (So this patch did it, that's what was discussed earlier). The 'Swap' may be inappropriate. It may need to be discussed. > > BUT, if the agreement is this patch (option 1/) I am OK with that too, I > just want to make sure that it is discussed. > > >> BTW, it seems that the ethernet port in kernel also replaces the old >> address if we modify the one. >> Use the test command: ifconfig eth0 hw ether new_mac > For default MAC address it is more clear that intention is to replace > it, but question is about what to do with the list of MAC addresses. Hi Ferruh and Thomas, As mentioned above, they are actually two problems (issue /1 and issue /2). Can we deal with them separately? #1 For issue /1, it's really a problem. This patch is responsible for it. #2 For issue /2, I will send a RFC to discuss as described above. It may require the participation of all PMD maintainers. What do you think? /Huisong > > .
在 2023/2/4 10:57, lihuisong (C) 写道: > > 在 2023/2/3 20:58, Ferruh Yigit 写道: >> On 2/3/2023 1:56 AM, lihuisong (C) wrote: >>> 在 2023/2/3 5:10, Thomas Monjalon 写道: >>>> 02/02/2023 19:09, Ferruh Yigit: >>>>> On 2/2/2023 12:36 PM, Huisong Li wrote: >>>>>> 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() doesn't remove it from the >>>>>> mac_addrs >>>>>> list. As a result, one 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. >>>>>> >>>>>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove >>>>>> the >>>>>> old default MAC when set default MAC. If user continues to do >>>>>> set_default(MAC5), and the mac_addrs list is default=MAC5, >>>>>> filters=(MAC1, >>>>>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the >>>>>> list, >>>>>> but packets with MAC3 aren't actually received by the PMD. >>>>>> >>>>>> So need to ensure that the new default address is removed from the >>>>>> rest of >>>>>> the list if the address was already in the list. >>>>>> >>>>> Same comment from past seems already valid, I am not looking to >>>>> the set >>>>> for a while, sorry if this is already discussed and decided, >>>>> if not, I am referring to the side effect that setting MAC addresses >>>>> cause to remove MAC addresses, think following case: >>>>> >>>>> add(MAC1) -> MAC1 >>>>> add(MAC2) -> MAC1, MAC2 >>>>> add(MAC3) -> MAC1, MAC2, MAC3 >>>>> add(MAC4) -> MAC1, MAC2, MAC3, MAC4 >>>>> set(MAC3) -> MAC3, MAC2, MAC4 >>>>> set(MAC4) -> MAC4, MAC2 >>>>> set(MAC2) -> MAC2 >>>>> >>>>> I am not exactly clear what is the intention with set(), >>>> That's the problem, nobody is clear with the current behavior. >>>> The doc says "Set the default MAC address." and nothing else. >>> Indeed. But we can see the following information. >>> From the ethdev layer, this set() API always replaces the old default >>> address (index 0) without adding the old one. >>> From the PMD layer, set() interface of some PMDs, such as i40e, ice, >>> hns3 and so on (as far as I know), >>> also do remove the hardware entry of the old default address. >> If we define behavior clearly, I think we can adapt PMD implementation >> according it, unless there is HW limitation. > Right. I think this is another point (issue 2/) to be discussed. > Namely, whether the old default address should be removed when set new > default one. > If we want to explicitly unify the behavior of all PMDs in ethdev > layer as described above, > there may be no problem if do the following: > 1) In the ethdev layer, remove the old default address if the old one > is exist. > 2) For PMD i40e, ice and hns3, remvoe the code of deleting the old > default address before adding the new one. > For other PMDs, we probably don't need to do anything because they > have supported remove_addr() API. > (Without explicitly removing the old default address, I don't know > if their hardware or firmware > removes the old one when set a new address. But, we explicitly > remove the old one in ethdev layer now, > I'm not sure if this has an effect on these PMDs.) >>>>> if there is >>>>> single MAC I guess intention is to replace it with new one, but if >>>>> there >>>>> are multiple MACs and one of them are already in the list >>>>> intention may >>>>> be just to change the default MAC. >>>> The assumption in this patch is that "Set" means "Replace", not >>>> "Swap". >>>> So this patch takes the approach 1/ Replace and keep Unique. >>>> >>>>> If above assumption is correct, what about following: >>>>> >>>>> set(MAC) { >>>>> if only_default_mac_exist >>>>> replace_default_mac >>>>> >>>>> if MAC exists in list >>>>> swap MAC and list[0] >>>>> else >>>>> replace_default_mac >>>>> } >>>> This approach 2/ is a mix of Swap and Replace. >>>> The old default MAC destiny depends on whether >>>> we have added the new MAC as "secondary" before setting as new >>>> default. >>>> >>>>> This swap prevents removing MAC side affect, does it make sense? >>>> Another approach would be 3/ to do an "Always Swap" >>>> even if the new MAC didn't exist before, >>>> you keep the old default MAC as a secondary MAC. >>>> >>>> And the current approach 0/ is to Replace default MAC address >>>> without touching the secondary addresses at all. >>>> >>>> So we have 4 choices. >>>> We could vote, roll a dice, or find a strong argument? >>> According to the implement of set() in ethdev and PMD layer, it always >>> use "Replace", not "Swap". >>> If we use "Swap" now, the behavior of this API will be changed. >>> I'm not sure if the application can accept this change or has other >>> effects. >>> >> This patch is also changing behavior, because of implied remove address, >> same concern is valid with this patch. > Indeed, it changes the behavior. > But this patch only resolves the problem (issue 1/) that the entries > of the MAC address list possibly are not uniques. > Fixing it may be little impact on the application. >> >> >> As I checked again current implementation may have one more problem >> (this from reading code, I did not test this): >> add(MAC1) -> MAC1 >> add(MAC2) -> MAC1, MAC2 >> set(MAC2) -> MAC2, MAC2 >> del(MAC2) -> FAILS >> >> This fails because `rte_eth_dev_mac_addr_remove()` can't remove default >> MAC, and it only tries to remove first address it finds, it can't find >> and remove second 'MAC2'. >> I wasn't too much bothered with wasting one MAC address slot, so wasn't >> sure if a change is required at all, but if above analysis is correct I >> think this is more serious problem to justify the change. > Your analysis is fully correct. >> >> >> I don't think always swap (option /3) is good idea, specially for single >> MAC address exists case, and current case has (option 0/) has mentioned >> problems. > +1 >> Remaining ones are mix of swap and replace (option 2/) and this patch >> (option /1). >> >> I think mix of swap and replace (option 2/ above) has some benefits: >> - It always replaces default MAC >> - Prevents duplication MAC address in the list >> - Doesn't implicitly remove address from list > As far as I know, the first entry (index 0) always be the default > address in all PMDs, > but it's not documented. (So this patch did it, that's what was > discussed earlier). > The 'Swap' may be inappropriate. It may need to be discussed. >> >> BUT, if the agreement is this patch (option 1/) I am OK with that too, I >> just want to make sure that it is discussed. >> >> >>> BTW, it seems that the ethernet port in kernel also replaces the old >>> address if we modify the one. >>> Use the test command: ifconfig eth0 hw ether new_mac >> For default MAC address it is more clear that intention is to replace >> it, but question is about what to do with the list of MAC addresses. > Hi Ferruh and Thomas, > > As mentioned above, they are actually two problems (issue /1 and issue > /2). > Can we deal with them separately? > #1 For issue /1, it's really a problem. This patch is responsible for it. > #2 For issue /2, I will send a RFC to discuss as described above. > It may require the participation of all PMD maintainers. > > What do you think? > > Hi Ferruh and Thomas, What do you think of the above proposal? Looking forward to your reply. /Huisong >> >> . > .
On 2/4/2023 2:57 AM, lihuisong (C) wrote: > > 在 2023/2/3 20:58, Ferruh Yigit 写道: >> On 2/3/2023 1:56 AM, lihuisong (C) wrote: >>> 在 2023/2/3 5:10, Thomas Monjalon 写道: >>>> 02/02/2023 19:09, Ferruh Yigit: >>>>> On 2/2/2023 12:36 PM, Huisong Li wrote: >>>>>> 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() doesn't remove it from the >>>>>> mac_addrs >>>>>> list. As a result, one 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. >>>>>> >>>>>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove >>>>>> the >>>>>> old default MAC when set default MAC. If user continues to do >>>>>> set_default(MAC5), and the mac_addrs list is default=MAC5, >>>>>> filters=(MAC1, >>>>>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the >>>>>> list, >>>>>> but packets with MAC3 aren't actually received by the PMD. >>>>>> >>>>>> So need to ensure that the new default address is removed from the >>>>>> rest of >>>>>> the list if the address was already in the list. >>>>>> >>>>> Same comment from past seems already valid, I am not looking to the >>>>> set >>>>> for a while, sorry if this is already discussed and decided, >>>>> if not, I am referring to the side effect that setting MAC addresses >>>>> cause to remove MAC addresses, think following case: >>>>> >>>>> add(MAC1) -> MAC1 >>>>> add(MAC2) -> MAC1, MAC2 >>>>> add(MAC3) -> MAC1, MAC2, MAC3 >>>>> add(MAC4) -> MAC1, MAC2, MAC3, MAC4 >>>>> set(MAC3) -> MAC3, MAC2, MAC4 >>>>> set(MAC4) -> MAC4, MAC2 >>>>> set(MAC2) -> MAC2 >>>>> >>>>> I am not exactly clear what is the intention with set(), >>>> That's the problem, nobody is clear with the current behavior. >>>> The doc says "Set the default MAC address." and nothing else. >>> Indeed. But we can see the following information. >>> From the ethdev layer, this set() API always replaces the old default >>> address (index 0) without adding the old one. >>> From the PMD layer, set() interface of some PMDs, such as i40e, ice, >>> hns3 and so on (as far as I know), >>> also do remove the hardware entry of the old default address. >> If we define behavior clearly, I think we can adapt PMD implementation >> according it, unless there is HW limitation. > Right. I think this is another point (issue 2/) to be discussed. > Namely, whether the old default address should be removed when set new > default one. > If we want to explicitly unify the behavior of all PMDs in ethdev layer > as described above, > there may be no problem if do the following: > 1) In the ethdev layer, remove the old default address if the old one is > exist. > 2) For PMD i40e, ice and hns3, remvoe the code of deleting the old > default address before adding the new one. > For other PMDs, we probably don't need to do anything because they > have supported remove_addr() API. > (Without explicitly removing the old default address, I don't know if > their hardware or firmware > removes the old one when set a new address. But, we explicitly > remove the old one in ethdev layer now, > I'm not sure if this has an effect on these PMDs.) >>>>> if there is >>>>> single MAC I guess intention is to replace it with new one, but if >>>>> there >>>>> are multiple MACs and one of them are already in the list intention >>>>> may >>>>> be just to change the default MAC. >>>> The assumption in this patch is that "Set" means "Replace", not "Swap". >>>> So this patch takes the approach 1/ Replace and keep Unique. >>>> >>>>> If above assumption is correct, what about following: >>>>> >>>>> set(MAC) { >>>>> if only_default_mac_exist >>>>> replace_default_mac >>>>> >>>>> if MAC exists in list >>>>> swap MAC and list[0] >>>>> else >>>>> replace_default_mac >>>>> } >>>> This approach 2/ is a mix of Swap and Replace. >>>> The old default MAC destiny depends on whether >>>> we have added the new MAC as "secondary" before setting as new default. >>>> >>>>> This swap prevents removing MAC side affect, does it make sense? >>>> Another approach would be 3/ to do an "Always Swap" >>>> even if the new MAC didn't exist before, >>>> you keep the old default MAC as a secondary MAC. >>>> >>>> And the current approach 0/ is to Replace default MAC address >>>> without touching the secondary addresses at all. >>>> >>>> So we have 4 choices. >>>> We could vote, roll a dice, or find a strong argument? >>> According to the implement of set() in ethdev and PMD layer, it always >>> use "Replace", not "Swap". >>> If we use "Swap" now, the behavior of this API will be changed. >>> I'm not sure if the application can accept this change or has other >>> effects. >>> >> This patch is also changing behavior, because of implied remove address, >> same concern is valid with this patch. > Indeed, it changes the behavior. > But this patch only resolves the problem (issue 1/) that the entries of > the MAC address list possibly are not uniques. > Fixing it may be little impact on the application. >> >> >> As I checked again current implementation may have one more problem >> (this from reading code, I did not test this): >> add(MAC1) -> MAC1 >> add(MAC2) -> MAC1, MAC2 >> set(MAC2) -> MAC2, MAC2 >> del(MAC2) -> FAILS >> >> This fails because `rte_eth_dev_mac_addr_remove()` can't remove default >> MAC, and it only tries to remove first address it finds, it can't find >> and remove second 'MAC2'. >> I wasn't too much bothered with wasting one MAC address slot, so wasn't >> sure if a change is required at all, but if above analysis is correct I >> think this is more serious problem to justify the change. > Your analysis is fully correct. >> >> >> I don't think always swap (option /3) is good idea, specially for single >> MAC address exists case, and current case has (option 0/) has mentioned >> problems. > +1 >> Remaining ones are mix of swap and replace (option 2/) and this patch >> (option /1). >> >> I think mix of swap and replace (option 2/ above) has some benefits: >> - It always replaces default MAC >> - Prevents duplication MAC address in the list >> - Doesn't implicitly remove address from list > As far as I know, the first entry (index 0) always be the default > address in all PMDs, > but it's not documented. (So this patch did it, that's what was > discussed earlier). > The 'Swap' may be inappropriate. It may need to be discussed. Yes, index 0 always holds the default MAC, +1 to document this. In option /2, MAC swap is done only if the MAC address is already in the list. Another option can be to store an enabled/disabled flag for each MAC address in the list. In set(MAC), if MAC is already in the list, the existing one in the list can be disabled. Next time default MAC changed, disabled MAC can be enabled again. Like: (d) => disabled add(MAC1) -> MAC1 add(MAC2) -> MAC1, MAC2 add(MAC3) -> MAC1, MAC2, MAC3 add(MAC4) -> MAC1, MAC2, MAC3, MAC4 set(MAC3) -> MAC3, MAC2, MAC3(d), MAC4 set(MAC4) -> MAC4, MAC2, MAC3, MAC4(d) set(MAC2) -> MAC2, MAC2(d), MAC3, MAC4 set(MAC5) -> MAC5, MAC2, MAC3, MAC4 The ones disabled in the ethdev layer can be explicitly removed in drivers, and the ones enabled in the ethdev layer can be explicitly added back in drives. This simplifies the driver implementation a lot. >> >> BUT, if the agreement is this patch (option 1/) I am OK with that too, I >> just want to make sure that it is discussed. >> >> >>> BTW, it seems that the ethernet port in kernel also replaces the old >>> address if we modify the one. >>> Use the test command: ifconfig eth0 hw ether new_mac >> For default MAC address it is more clear that intention is to replace >> it, but question is about what to do with the list of MAC addresses. > Hi Ferruh and Thomas, > > As mentioned above, they are actually two problems (issue /1 and issue /2). > Can we deal with them separately? > #1 For issue /1, it's really a problem. This patch is responsible for it. > #2 For issue /2, I will send a RFC to discuss as described above. > It may require the participation of all PMD maintainers. > > What do you think? > Agree to separate fixing drivers (issue /2) and ethdev (issue /1), and drivers can be fixed after ethdev clarified. Sorry that this patch is taking time because expected behavior is not clear, and we are not getting enough feedback for it. Also issue is not a major or a blocking issue.
在 2023/2/9 20:45, Ferruh Yigit 写道: > On 2/4/2023 2:57 AM, lihuisong (C) wrote: >> 在 2023/2/3 20:58, Ferruh Yigit 写道: >>> On 2/3/2023 1:56 AM, lihuisong (C) wrote: >>>> 在 2023/2/3 5:10, Thomas Monjalon 写道: >>>>> 02/02/2023 19:09, Ferruh Yigit: >>>>>> On 2/2/2023 12:36 PM, Huisong Li wrote: >>>>>>> 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() doesn't remove it from the >>>>>>> mac_addrs >>>>>>> list. As a result, one 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. >>>>>>> >>>>>>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove >>>>>>> the >>>>>>> old default MAC when set default MAC. If user continues to do >>>>>>> set_default(MAC5), and the mac_addrs list is default=MAC5, >>>>>>> filters=(MAC1, >>>>>>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the >>>>>>> list, >>>>>>> but packets with MAC3 aren't actually received by the PMD. >>>>>>> >>>>>>> So need to ensure that the new default address is removed from the >>>>>>> rest of >>>>>>> the list if the address was already in the list. >>>>>>> >>>>>> Same comment from past seems already valid, I am not looking to the >>>>>> set >>>>>> for a while, sorry if this is already discussed and decided, >>>>>> if not, I am referring to the side effect that setting MAC addresses >>>>>> cause to remove MAC addresses, think following case: >>>>>> >>>>>> add(MAC1) -> MAC1 >>>>>> add(MAC2) -> MAC1, MAC2 >>>>>> add(MAC3) -> MAC1, MAC2, MAC3 >>>>>> add(MAC4) -> MAC1, MAC2, MAC3, MAC4 >>>>>> set(MAC3) -> MAC3, MAC2, MAC4 >>>>>> set(MAC4) -> MAC4, MAC2 >>>>>> set(MAC2) -> MAC2 >>>>>> >>>>>> I am not exactly clear what is the intention with set(), >>>>> That's the problem, nobody is clear with the current behavior. >>>>> The doc says "Set the default MAC address." and nothing else. >>>> Indeed. But we can see the following information. >>>> From the ethdev layer, this set() API always replaces the old default >>>> address (index 0) without adding the old one. >>>> From the PMD layer, set() interface of some PMDs, such as i40e, ice, >>>> hns3 and so on (as far as I know), >>>> also do remove the hardware entry of the old default address. >>> If we define behavior clearly, I think we can adapt PMD implementation >>> according it, unless there is HW limitation. >> Right. I think this is another point (issue 2/) to be discussed. >> Namely, whether the old default address should be removed when set new >> default one. >> If we want to explicitly unify the behavior of all PMDs in ethdev layer >> as described above, >> there may be no problem if do the following: >> 1) In the ethdev layer, remove the old default address if the old one is >> exist. >> 2) For PMD i40e, ice and hns3, remvoe the code of deleting the old >> default address before adding the new one. >> For other PMDs, we probably don't need to do anything because they >> have supported remove_addr() API. >> (Without explicitly removing the old default address, I don't know if >> their hardware or firmware >> removes the old one when set a new address. But, we explicitly >> remove the old one in ethdev layer now, >> I'm not sure if this has an effect on these PMDs.) >>>>>> if there is >>>>>> single MAC I guess intention is to replace it with new one, but if >>>>>> there >>>>>> are multiple MACs and one of them are already in the list intention >>>>>> may >>>>>> be just to change the default MAC. >>>>> The assumption in this patch is that "Set" means "Replace", not "Swap". >>>>> So this patch takes the approach 1/ Replace and keep Unique. >>>>> >>>>>> If above assumption is correct, what about following: >>>>>> >>>>>> set(MAC) { >>>>>> if only_default_mac_exist >>>>>> replace_default_mac >>>>>> >>>>>> if MAC exists in list >>>>>> swap MAC and list[0] >>>>>> else >>>>>> replace_default_mac >>>>>> } >>>>> This approach 2/ is a mix of Swap and Replace. >>>>> The old default MAC destiny depends on whether >>>>> we have added the new MAC as "secondary" before setting as new default. >>>>> >>>>>> This swap prevents removing MAC side affect, does it make sense? >>>>> Another approach would be 3/ to do an "Always Swap" >>>>> even if the new MAC didn't exist before, >>>>> you keep the old default MAC as a secondary MAC. >>>>> >>>>> And the current approach 0/ is to Replace default MAC address >>>>> without touching the secondary addresses at all. >>>>> >>>>> So we have 4 choices. >>>>> We could vote, roll a dice, or find a strong argument? >>>> According to the implement of set() in ethdev and PMD layer, it always >>>> use "Replace", not "Swap". >>>> If we use "Swap" now, the behavior of this API will be changed. >>>> I'm not sure if the application can accept this change or has other >>>> effects. >>>> >>> This patch is also changing behavior, because of implied remove address, >>> same concern is valid with this patch. >> Indeed, it changes the behavior. >> But this patch only resolves the problem (issue 1/) that the entries of >> the MAC address list possibly are not uniques. >> Fixing it may be little impact on the application. >>> >>> As I checked again current implementation may have one more problem >>> (this from reading code, I did not test this): >>> add(MAC1) -> MAC1 >>> add(MAC2) -> MAC1, MAC2 >>> set(MAC2) -> MAC2, MAC2 >>> del(MAC2) -> FAILS >>> >>> This fails because `rte_eth_dev_mac_addr_remove()` can't remove default >>> MAC, and it only tries to remove first address it finds, it can't find >>> and remove second 'MAC2'. >>> I wasn't too much bothered with wasting one MAC address slot, so wasn't >>> sure if a change is required at all, but if above analysis is correct I >>> think this is more serious problem to justify the change. >> Your analysis is fully correct. >>> >>> I don't think always swap (option /3) is good idea, specially for single >>> MAC address exists case, and current case has (option 0/) has mentioned >>> problems. >> +1 >>> Remaining ones are mix of swap and replace (option 2/) and this patch >>> (option /1). >>> >>> I think mix of swap and replace (option 2/ above) has some benefits: >>> - It always replaces default MAC >>> - Prevents duplication MAC address in the list >>> - Doesn't implicitly remove address from list >> As far as I know, the first entry (index 0) always be the default >> address in all PMDs, >> but it's not documented. (So this patch did it, that's what was >> discussed earlier). >> The 'Swap' may be inappropriate. It may need to be discussed. > Yes, index 0 always holds the default MAC, +1 to document this. > > In option /2, MAC swap is done only if the MAC address is already in the > list. > Whether the 'swap' is required in this case depends on the assumption that the old default address needs to be 'secondary' address when set new default one, right? It is still the same issue as issue /2 to be discussed. > Another option can be to store an enabled/disabled flag for each MAC > address in the list. > In set(MAC), if MAC is already in the list, the existing one in the list > can be disabled. Next time default MAC changed, disabled MAC can be > enabled again. Like: > > (d) => disabled > > add(MAC1) -> MAC1 > add(MAC2) -> MAC1, MAC2 > add(MAC3) -> MAC1, MAC2, MAC3 > add(MAC4) -> MAC1, MAC2, MAC3, MAC4 > set(MAC3) -> MAC3, MAC2, MAC3(d), MAC4 > set(MAC4) -> MAC4, MAC2, MAC3, MAC4(d) > set(MAC2) -> MAC2, MAC2(d), MAC3, MAC4 > set(MAC5) -> MAC5, MAC2, MAC3, MAC4 > > The ones disabled in the ethdev layer can be explicitly removed in > drivers, and the ones enabled in the ethdev layer can be explicitly > added back in drives. This simplifies the driver implementation a lot. > Good idea, but it's a little complicated. If I understand correctly, all of the above are done under the condition that 'swap' is accepted. >>> BUT, if the agreement is this patch (option 1/) I am OK with that too, I >>> just want to make sure that it is discussed. >>> >>> >>>> BTW, it seems that the ethernet port in kernel also replaces the old >>>> address if we modify the one. >>>> Use the test command: ifconfig eth0 hw ether new_mac >>> For default MAC address it is more clear that intention is to replace >>> it, but question is about what to do with the list of MAC addresses. >> Hi Ferruh and Thomas, >> >> As mentioned above, they are actually two problems (issue /1 and issue /2). >> Can we deal with them separately? >> #1 For issue /1, it's really a problem. This patch is responsible for it. >> #2 For issue /2, I will send a RFC to discuss as described above. >> It may require the participation of all PMD maintainers. >> >> What do you think? >> > Agree to separate fixing drivers (issue /2) and ethdev (issue /1), and > drivers can be fixed after ethdev clarified. Yeah, we are in the same boat.😁 > > Sorry that this patch is taking time because expected behavior is not I cannot understand the behavior determined by this patch is not expected. Wouldn't it be simpler and more reasonable to make sure that the entries in the MAC list are uniques? > clear, and we are not getting enough feedback for it. Also issue is not > a major or a blocking issue. IMO, the last point to be discussed and have enough feedback is the issue /2 instead of issue /1. Whether the old default address needs to be removed or swapped when set new one is the major or a blocking issue. We can't go back and forth between them. we should break the cycle. For issue /1 (duplicate entries), please forget what to do with the old default address. I'm sure you'll think it's ok. Let's take a new discussion for the old default address in set() API to get enough feedback. what do you think, Ferruh and Thomas? > > .
On 2/10/2023 9:54 AM, lihuisong (C) wrote: > > 在 2023/2/9 20:45, Ferruh Yigit 写道: >> On 2/4/2023 2:57 AM, lihuisong (C) wrote: >>> 在 2023/2/3 20:58, Ferruh Yigit 写道: >>>> On 2/3/2023 1:56 AM, lihuisong (C) wrote: >>>>> 在 2023/2/3 5:10, Thomas Monjalon 写道: >>>>>> 02/02/2023 19:09, Ferruh Yigit: >>>>>>> On 2/2/2023 12:36 PM, Huisong Li wrote: >>>>>>>> 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() doesn't remove it from the >>>>>>>> mac_addrs >>>>>>>> list. As a result, one 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. >>>>>>>> >>>>>>>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do >>>>>>>> remove >>>>>>>> the >>>>>>>> old default MAC when set default MAC. If user continues to do >>>>>>>> set_default(MAC5), and the mac_addrs list is default=MAC5, >>>>>>>> filters=(MAC1, >>>>>>>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the >>>>>>>> list, >>>>>>>> but packets with MAC3 aren't actually received by the PMD. >>>>>>>> >>>>>>>> So need to ensure that the new default address is removed from the >>>>>>>> rest of >>>>>>>> the list if the address was already in the list. >>>>>>>> >>>>>>> Same comment from past seems already valid, I am not looking to the >>>>>>> set >>>>>>> for a while, sorry if this is already discussed and decided, >>>>>>> if not, I am referring to the side effect that setting MAC addresses >>>>>>> cause to remove MAC addresses, think following case: >>>>>>> >>>>>>> add(MAC1) -> MAC1 >>>>>>> add(MAC2) -> MAC1, MAC2 >>>>>>> add(MAC3) -> MAC1, MAC2, MAC3 >>>>>>> add(MAC4) -> MAC1, MAC2, MAC3, MAC4 >>>>>>> set(MAC3) -> MAC3, MAC2, MAC4 >>>>>>> set(MAC4) -> MAC4, MAC2 >>>>>>> set(MAC2) -> MAC2 >>>>>>> >>>>>>> I am not exactly clear what is the intention with set(), >>>>>> That's the problem, nobody is clear with the current behavior. >>>>>> The doc says "Set the default MAC address." and nothing else. >>>>> Indeed. But we can see the following information. >>>>> From the ethdev layer, this set() API always replaces the old >>>>> default >>>>> address (index 0) without adding the old one. >>>>> From the PMD layer, set() interface of some PMDs, such as i40e, ice, >>>>> hns3 and so on (as far as I know), >>>>> also do remove the hardware entry of the old default address. >>>> If we define behavior clearly, I think we can adapt PMD implementation >>>> according it, unless there is HW limitation. >>> Right. I think this is another point (issue 2/) to be discussed. >>> Namely, whether the old default address should be removed when set new >>> default one. >>> If we want to explicitly unify the behavior of all PMDs in ethdev layer >>> as described above, >>> there may be no problem if do the following: >>> 1) In the ethdev layer, remove the old default address if the old one is >>> exist. >>> 2) For PMD i40e, ice and hns3, remvoe the code of deleting the old >>> default address before adding the new one. >>> For other PMDs, we probably don't need to do anything because they >>> have supported remove_addr() API. >>> (Without explicitly removing the old default address, I don't >>> know if >>> their hardware or firmware >>> removes the old one when set a new address. But, we explicitly >>> remove the old one in ethdev layer now, >>> I'm not sure if this has an effect on these PMDs.) >>>>>>> if there is >>>>>>> single MAC I guess intention is to replace it with new one, but if >>>>>>> there >>>>>>> are multiple MACs and one of them are already in the list intention >>>>>>> may >>>>>>> be just to change the default MAC. >>>>>> The assumption in this patch is that "Set" means "Replace", not >>>>>> "Swap". >>>>>> So this patch takes the approach 1/ Replace and keep Unique. >>>>>> >>>>>>> If above assumption is correct, what about following: >>>>>>> >>>>>>> set(MAC) { >>>>>>> if only_default_mac_exist >>>>>>> replace_default_mac >>>>>>> >>>>>>> if MAC exists in list >>>>>>> swap MAC and list[0] >>>>>>> else >>>>>>> replace_default_mac >>>>>>> } >>>>>> This approach 2/ is a mix of Swap and Replace. >>>>>> The old default MAC destiny depends on whether >>>>>> we have added the new MAC as "secondary" before setting as new >>>>>> default. >>>>>> >>>>>>> This swap prevents removing MAC side affect, does it make sense? >>>>>> Another approach would be 3/ to do an "Always Swap" >>>>>> even if the new MAC didn't exist before, >>>>>> you keep the old default MAC as a secondary MAC. >>>>>> >>>>>> And the current approach 0/ is to Replace default MAC address >>>>>> without touching the secondary addresses at all. >>>>>> >>>>>> So we have 4 choices. >>>>>> We could vote, roll a dice, or find a strong argument? >>>>> According to the implement of set() in ethdev and PMD layer, it always >>>>> use "Replace", not "Swap". >>>>> If we use "Swap" now, the behavior of this API will be changed. >>>>> I'm not sure if the application can accept this change or has other >>>>> effects. >>>>> >>>> This patch is also changing behavior, because of implied remove >>>> address, >>>> same concern is valid with this patch. >>> Indeed, it changes the behavior. >>> But this patch only resolves the problem (issue 1/) that the entries of >>> the MAC address list possibly are not uniques. >>> Fixing it may be little impact on the application. >>>> >>>> As I checked again current implementation may have one more problem >>>> (this from reading code, I did not test this): >>>> add(MAC1) -> MAC1 >>>> add(MAC2) -> MAC1, MAC2 >>>> set(MAC2) -> MAC2, MAC2 >>>> del(MAC2) -> FAILS >>>> >>>> This fails because `rte_eth_dev_mac_addr_remove()` can't remove default >>>> MAC, and it only tries to remove first address it finds, it can't find >>>> and remove second 'MAC2'. >>>> I wasn't too much bothered with wasting one MAC address slot, so wasn't >>>> sure if a change is required at all, but if above analysis is correct I >>>> think this is more serious problem to justify the change. >>> Your analysis is fully correct. >>>> >>>> I don't think always swap (option /3) is good idea, specially for >>>> single >>>> MAC address exists case, and current case has (option 0/) has mentioned >>>> problems. >>> +1 >>>> Remaining ones are mix of swap and replace (option 2/) and this patch >>>> (option /1). >>>> >>>> I think mix of swap and replace (option 2/ above) has some benefits: >>>> - It always replaces default MAC >>>> - Prevents duplication MAC address in the list >>>> - Doesn't implicitly remove address from list >>> As far as I know, the first entry (index 0) always be the default >>> address in all PMDs, >>> but it's not documented. (So this patch did it, that's what was >>> discussed earlier). >>> The 'Swap' may be inappropriate. It may need to be discussed. >> Yes, index 0 always holds the default MAC, +1 to document this. >> >> In option /2, MAC swap is done only if the MAC address is already in the >> list. >> > Whether the 'swap' is required in this case depends on the assumption > that the > old default address needs to be 'secondary' address when set new default > one, right? We don't know if default address needs to be 'secondary' address or not, swap is just a way to both keep list unique and don't implicit remove any MAC address. > It is still the same issue as issue /2 to be discussed.>> Another option can be to store an enabled/disabled flag for each MAC >> address in the list. >> In set(MAC), if MAC is already in the list, the existing one in the list >> can be disabled. Next time default MAC changed, disabled MAC can be >> enabled again. Like: >> >> (d) => disabled >> >> add(MAC1) -> MAC1 >> add(MAC2) -> MAC1, MAC2 >> add(MAC3) -> MAC1, MAC2, MAC3 >> add(MAC4) -> MAC1, MAC2, MAC3, MAC4 >> set(MAC3) -> MAC3, MAC2, MAC3(d), MAC4 >> set(MAC4) -> MAC4, MAC2, MAC3, MAC4(d) >> set(MAC2) -> MAC2, MAC2(d), MAC3, MAC4 >> set(MAC5) -> MAC5, MAC2, MAC3, MAC4 >> >> The ones disabled in the ethdev layer can be explicitly removed in >> drivers, and the ones enabled in the ethdev layer can be explicitly >> added back in drives. This simplifies the driver implementation a lot. >> > Good idea, but it's a little complicated. > If I understand correctly, all of the above are done under the condition > that 'swap' is accepted. Agree it is more complicated, and no this doesn't require swap. Instead of implicitly removing duplicated MAC address it keeps in the ethdev list as disabled, and adds it back when default MAC is changed. >>>> BUT, if the agreement is this patch (option 1/) I am OK with that >>>> too, I >>>> just want to make sure that it is discussed. >>>> >>>> >>>>> BTW, it seems that the ethernet port in kernel also replaces the old >>>>> address if we modify the one. >>>>> Use the test command: ifconfig eth0 hw ether new_mac >>>> For default MAC address it is more clear that intention is to replace >>>> it, but question is about what to do with the list of MAC addresses. >>> Hi Ferruh and Thomas, >>> >>> As mentioned above, they are actually two problems (issue /1 and >>> issue /2). >>> Can we deal with them separately? >>> #1 For issue /1, it's really a problem. This patch is responsible for >>> it. >>> #2 For issue /2, I will send a RFC to discuss as described above. >>> It may require the participation of all PMD maintainers. >>> >>> What do you think? >>> >> Agree to separate fixing drivers (issue /2) and ethdev (issue /1), and >> drivers can be fixed after ethdev clarified. > Yeah, we are in the same boat.😁 >> >> Sorry that this patch is taking time because expected behavior is not > I cannot understand the behavior determined by this patch is not expected. > Wouldn't it be simpler and more reasonable to make sure that the entries > in the MAC list are uniques? Yes, above part is OK. Only problem is it may cause shrinking the MAC list by setting MAC address, that may not be the expected behavior. >> clear, and we are not getting enough feedback for it. Also issue is not >> a major or a blocking issue. > IMO, the last point to be discussed and have enough feedback is the > issue /2 instead of issue /1. > Whether the old default address needs to be removed or swapped when set > new one is the major or a blocking issue. > > We can't go back and forth between them. we should break the cycle. > For issue /1 (duplicate entries), please forget what to do with the old > default address. I'm sure you'll think it's ok. > Let's take a new discussion for the old default address in set() API to > get enough feedback. > > what do you think, Ferruh and Thomas? Does it work to present options to techboard, get a decision and proceed with it?
在 2023/2/10 20:27, Ferruh Yigit 写道: > On 2/10/2023 9:54 AM, lihuisong (C) wrote: >> 在 2023/2/9 20:45, Ferruh Yigit 写道: >>> On 2/4/2023 2:57 AM, lihuisong (C) wrote: >>>> 在 2023/2/3 20:58, Ferruh Yigit 写道: >>>>> On 2/3/2023 1:56 AM, lihuisong (C) wrote: >>>>>> 在 2023/2/3 5:10, Thomas Monjalon 写道: >>>>>>> 02/02/2023 19:09, Ferruh Yigit: >>>>>>>> On 2/2/2023 12:36 PM, Huisong Li wrote: >>>>>>>>> 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() doesn't remove it from the >>>>>>>>> mac_addrs >>>>>>>>> list. As a result, one 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. >>>>>>>>> >>>>>>>>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do >>>>>>>>> remove >>>>>>>>> the >>>>>>>>> old default MAC when set default MAC. If user continues to do >>>>>>>>> set_default(MAC5), and the mac_addrs list is default=MAC5, >>>>>>>>> filters=(MAC1, >>>>>>>>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the >>>>>>>>> list, >>>>>>>>> but packets with MAC3 aren't actually received by the PMD. >>>>>>>>> >>>>>>>>> So need to ensure that the new default address is removed from the >>>>>>>>> rest of >>>>>>>>> the list if the address was already in the list. >>>>>>>>> >>>>>>>> Same comment from past seems already valid, I am not looking to the >>>>>>>> set >>>>>>>> for a while, sorry if this is already discussed and decided, >>>>>>>> if not, I am referring to the side effect that setting MAC addresses >>>>>>>> cause to remove MAC addresses, think following case: >>>>>>>> >>>>>>>> add(MAC1) -> MAC1 >>>>>>>> add(MAC2) -> MAC1, MAC2 >>>>>>>> add(MAC3) -> MAC1, MAC2, MAC3 >>>>>>>> add(MAC4) -> MAC1, MAC2, MAC3, MAC4 >>>>>>>> set(MAC3) -> MAC3, MAC2, MAC4 >>>>>>>> set(MAC4) -> MAC4, MAC2 >>>>>>>> set(MAC2) -> MAC2 >>>>>>>> >>>>>>>> I am not exactly clear what is the intention with set(), >>>>>>> That's the problem, nobody is clear with the current behavior. >>>>>>> The doc says "Set the default MAC address." and nothing else. >>>>>> Indeed. But we can see the following information. >>>>>> From the ethdev layer, this set() API always replaces the old >>>>>> default >>>>>> address (index 0) without adding the old one. >>>>>> From the PMD layer, set() interface of some PMDs, such as i40e, ice, >>>>>> hns3 and so on (as far as I know), >>>>>> also do remove the hardware entry of the old default address. >>>>> If we define behavior clearly, I think we can adapt PMD implementation >>>>> according it, unless there is HW limitation. >>>> Right. I think this is another point (issue 2/) to be discussed. >>>> Namely, whether the old default address should be removed when set new >>>> default one. >>>> If we want to explicitly unify the behavior of all PMDs in ethdev layer >>>> as described above, >>>> there may be no problem if do the following: >>>> 1) In the ethdev layer, remove the old default address if the old one is >>>> exist. >>>> 2) For PMD i40e, ice and hns3, remvoe the code of deleting the old >>>> default address before adding the new one. >>>> For other PMDs, we probably don't need to do anything because they >>>> have supported remove_addr() API. >>>> (Without explicitly removing the old default address, I don't >>>> know if >>>> their hardware or firmware >>>> removes the old one when set a new address. But, we explicitly >>>> remove the old one in ethdev layer now, >>>> I'm not sure if this has an effect on these PMDs.) >>>>>>>> if there is >>>>>>>> single MAC I guess intention is to replace it with new one, but if >>>>>>>> there >>>>>>>> are multiple MACs and one of them are already in the list intention >>>>>>>> may >>>>>>>> be just to change the default MAC. >>>>>>> The assumption in this patch is that "Set" means "Replace", not >>>>>>> "Swap". >>>>>>> So this patch takes the approach 1/ Replace and keep Unique. >>>>>>> >>>>>>>> If above assumption is correct, what about following: >>>>>>>> >>>>>>>> set(MAC) { >>>>>>>> if only_default_mac_exist >>>>>>>> replace_default_mac >>>>>>>> >>>>>>>> if MAC exists in list >>>>>>>> swap MAC and list[0] >>>>>>>> else >>>>>>>> replace_default_mac >>>>>>>> } >>>>>>> This approach 2/ is a mix of Swap and Replace. >>>>>>> The old default MAC destiny depends on whether >>>>>>> we have added the new MAC as "secondary" before setting as new >>>>>>> default. >>>>>>> >>>>>>>> This swap prevents removing MAC side affect, does it make sense? >>>>>>> Another approach would be 3/ to do an "Always Swap" >>>>>>> even if the new MAC didn't exist before, >>>>>>> you keep the old default MAC as a secondary MAC. >>>>>>> >>>>>>> And the current approach 0/ is to Replace default MAC address >>>>>>> without touching the secondary addresses at all. >>>>>>> >>>>>>> So we have 4 choices. >>>>>>> We could vote, roll a dice, or find a strong argument? >>>>>> According to the implement of set() in ethdev and PMD layer, it always >>>>>> use "Replace", not "Swap". >>>>>> If we use "Swap" now, the behavior of this API will be changed. >>>>>> I'm not sure if the application can accept this change or has other >>>>>> effects. >>>>>> >>>>> This patch is also changing behavior, because of implied remove >>>>> address, >>>>> same concern is valid with this patch. >>>> Indeed, it changes the behavior. >>>> But this patch only resolves the problem (issue 1/) that the entries of >>>> the MAC address list possibly are not uniques. >>>> Fixing it may be little impact on the application. >>>>> As I checked again current implementation may have one more problem >>>>> (this from reading code, I did not test this): >>>>> add(MAC1) -> MAC1 >>>>> add(MAC2) -> MAC1, MAC2 >>>>> set(MAC2) -> MAC2, MAC2 >>>>> del(MAC2) -> FAILS >>>>> >>>>> This fails because `rte_eth_dev_mac_addr_remove()` can't remove default >>>>> MAC, and it only tries to remove first address it finds, it can't find >>>>> and remove second 'MAC2'. >>>>> I wasn't too much bothered with wasting one MAC address slot, so wasn't >>>>> sure if a change is required at all, but if above analysis is correct I >>>>> think this is more serious problem to justify the change. >>>> Your analysis is fully correct. >>>>> I don't think always swap (option /3) is good idea, specially for >>>>> single >>>>> MAC address exists case, and current case has (option 0/) has mentioned >>>>> problems. >>>> +1 >>>>> Remaining ones are mix of swap and replace (option 2/) and this patch >>>>> (option /1). >>>>> >>>>> I think mix of swap and replace (option 2/ above) has some benefits: >>>>> - It always replaces default MAC >>>>> - Prevents duplication MAC address in the list >>>>> - Doesn't implicitly remove address from list >>>> As far as I know, the first entry (index 0) always be the default >>>> address in all PMDs, >>>> but it's not documented. (So this patch did it, that's what was >>>> discussed earlier). >>>> The 'Swap' may be inappropriate. It may need to be discussed. >>> Yes, index 0 always holds the default MAC, +1 to document this. >>> >>> In option /2, MAC swap is done only if the MAC address is already in the >>> list. >>> >> Whether the 'swap' is required in this case depends on the assumption >> that the >> old default address needs to be 'secondary' address when set new default >> one, right? > > We don't know if default address needs to be 'secondary' address or not, > swap is just a way to both keep list unique and don't implicit remove > any MAC address. > > >> It is still the same issue as issue /2 to be discussed.>> Another option can be to store an enabled/disabled flag for each MAC >>> address in the list. >>> In set(MAC), if MAC is already in the list, the existing one in the list >>> can be disabled. Next time default MAC changed, disabled MAC can be >>> enabled again. Like: >>> >>> (d) => disabled >>> >>> add(MAC1) -> MAC1 >>> add(MAC2) -> MAC1, MAC2 >>> add(MAC3) -> MAC1, MAC2, MAC3 >>> add(MAC4) -> MAC1, MAC2, MAC3, MAC4 >>> set(MAC3) -> MAC3, MAC2, MAC3(d), MAC4 >>> set(MAC4) -> MAC4, MAC2, MAC3, MAC4(d) >>> set(MAC2) -> MAC2, MAC2(d), MAC3, MAC4 >>> set(MAC5) -> MAC5, MAC2, MAC3, MAC4 >>> >>> The ones disabled in the ethdev layer can be explicitly removed in >>> drivers, and the ones enabled in the ethdev layer can be explicitly >>> added back in drives. This simplifies the driver implementation a lot. >>> >> Good idea, but it's a little complicated. >> If I understand correctly, all of the above are done under the condition >> that 'swap' is accepted. > > Agree it is more complicated, and no this doesn't require swap. > > Instead of implicitly removing duplicated MAC address it keeps in the > ethdev list as disabled, and adds it back when default MAC is changed. > > >>>>> BUT, if the agreement is this patch (option 1/) I am OK with that >>>>> too, I >>>>> just want to make sure that it is discussed. >>>>> >>>>> >>>>>> BTW, it seems that the ethernet port in kernel also replaces the old >>>>>> address if we modify the one. >>>>>> Use the test command: ifconfig eth0 hw ether new_mac >>>>> For default MAC address it is more clear that intention is to replace >>>>> it, but question is about what to do with the list of MAC addresses. >>>> Hi Ferruh and Thomas, >>>> >>>> As mentioned above, they are actually two problems (issue /1 and >>>> issue /2). >>>> Can we deal with them separately? >>>> #1 For issue /1, it's really a problem. This patch is responsible for >>>> it. >>>> #2 For issue /2, I will send a RFC to discuss as described above. >>>> It may require the participation of all PMD maintainers. >>>> >>>> What do you think? >>>> >>> Agree to separate fixing drivers (issue /2) and ethdev (issue /1), and >>> drivers can be fixed after ethdev clarified. >> Yeah, we are in the same boat.😁 >>> Sorry that this patch is taking time because expected behavior is not >> I cannot understand the behavior determined by this patch is not expected. >> Wouldn't it be simpler and more reasonable to make sure that the entries >> in the MAC list are uniques? > > Yes, above part is OK. Only problem is it may cause shrinking the MAC > list by setting MAC address, that may not be the expected behavior. The root cause of shrinking the MAC list is that the old default address is removed when set MAC address, rather than removing the address being already in the rest of the list. > > >>> clear, and we are not getting enough feedback for it. Also issue is not >>> a major or a blocking issue. >> IMO, the last point to be discussed and have enough feedback is the >> issue /2 instead of issue /1. >> Whether the old default address needs to be removed or swapped when set >> new one is the major or a blocking issue. >> >> We can't go back and forth between them. we should break the cycle. >> For issue /1 (duplicate entries), please forget what to do with the old >> default address. I'm sure you'll think it's ok. >> Let's take a new discussion for the old default address in set() API to >> get enough feedback. >> >> what do you think, Ferruh and Thomas? > Does it work to present options to techboard, get a decision and proceed > with it? Agreed. At least, there's a decision soon. > .
Hi Ferruh,
There is no result on techboard.
How to deal with this problem next?
/Huisong
在 2023/2/2 20:36, Huisong Li 写道:
> 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() doesn't remove it from the mac_addrs
> list. As a result, one 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.
>
> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the
> old default MAC when set default MAC. If user continues to do
> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1,
> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list,
> but packets with MAC3 aren't actually received by the PMD.
>
> So need to ensure that the new default address is removed from the rest of
> the list if the address was already in the list.
>
> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
> Cc: stable@dpdk.org
>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> Acked-by: Chengwen Feng <fengchengwen@huawei.com>
> ---
> v8: fix some comments.
> v7: add announcement in the release notes and document this behavior.
> v6: fix commit log and some code comments.
> v5:
> - merge the second patch into the first patch.
> - add error log when rollback failed.
> v4:
> - fix broken in the patchwork
> v3:
> - first explicitly remove the non-default MAC, then set default one.
> - document default and non-default MAC address
> v2:
> - fixed commit log.
> ---
> doc/guides/rel_notes/release_23_03.rst | 6 +++++
> lib/ethdev/ethdev_driver.h | 6 ++++-
> lib/ethdev/rte_ethdev.c | 35 ++++++++++++++++++++++++--
> lib/ethdev/rte_ethdev.h | 3 +++
> 4 files changed, 47 insertions(+), 3 deletions(-)
>
> diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
> index 84b112a8b1..1c9b9912c2 100644
> --- a/doc/guides/rel_notes/release_23_03.rst
> +++ b/doc/guides/rel_notes/release_23_03.rst
> @@ -105,6 +105,12 @@ API Changes
> Also, make sure to start the actual text at the margin.
> =======================================================
>
> +* ethdev: ensured all entries in MAC address list are uniques.
> + When setting a default MAC address with the function
> + ``rte_eth_dev_default_mac_addr_set``,
> + the address is now removed from the rest of the address list
> + in order to ensure it is only at index 0 of the list.
> +
>
> ABI Changes
> -----------
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> index dde3ec84ef..3994c61b86 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -117,7 +117,11 @@ struct rte_eth_dev_data {
>
> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */
>
> - /** Device Ethernet link address. @see rte_eth_dev_release_port() */
> + /**
> + * Device Ethernet link addresses.
> + * All entries are unique.
> + * The first entry (index zero) is the default address.
> + */
> struct rte_ether_addr *mac_addrs;
> /** Bitmap associating MAC addresses to pools */
> uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR];
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index 86ca303ab5..de25183619 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
> int
> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
> {
> + uint64_t mac_pool_sel_bk = 0;
> struct rte_eth_dev *dev;
> + uint32_t pool;
> + int index;
> int ret;
>
> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> @@ -4517,16 +4520,44 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
> if (*dev->dev_ops->mac_addr_set == NULL)
> return -ENOTSUP;
>
> + /* Keep address unique in dev->data->mac_addrs[]. */
> + index = eth_dev_get_mac_addr_index(port_id, addr);
> + if (index > 0) {
> + /* Remove address in dev data structure */
> + mac_pool_sel_bk = dev->data->mac_pool_sel[index];
> + ret = rte_eth_dev_mac_addr_remove(port_id, addr);
> + if (ret < 0) {
> + RTE_ETHDEV_LOG(ERR, "Cannot remove the port %u address from the rest of list.\n",
> + port_id);
> + return ret;
> + }
> + }
> ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
> if (ret < 0)
> - return ret;
> + goto out;
>
> /* Update default address in NIC data structure */
> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
>
> return 0;
> -}
>
> +out:
> + if (index > 0) {
> + pool = 0;
> + do {
> + if (mac_pool_sel_bk & UINT64_C(1)) {
> + if (rte_eth_dev_mac_addr_add(port_id, addr,
> + pool) != 0)
> + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool id(%u) in port %u.\n",
> + pool, port_id);
> + }
> + mac_pool_sel_bk >>= 1;
> + pool++;
> + } while (mac_pool_sel_bk != 0);
> + }
> +
> + return ret;
> +}
>
> /*
> * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index d22de196db..2456153457 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -4356,6 +4356,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,
> + * it is removed from the rest of the list.
> *
> * @param port_id
> * The port identifier of the Ethernet device.
On 5/16/2023 12:47 PM, lihuisong (C) wrote: > Hi Ferruh, > > There is no result on techboard. > How to deal with this problem next? +techboard for comment. Btw, what was your positioning to Bruce's suggestion, when a MAC address is in the list, fail to set it as default and enforce user do the corrective action (delete MAC explicitly etc...). If you are OK with it, that is good for me too, unless techboard objects we can proceed with that one. > > /Huisong > > 在 2023/2/2 20:36, Huisong Li 写道: >> 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() doesn't remove it from the mac_addrs >> list. As a result, one 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. >> >> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the >> old default MAC when set default MAC. If user continues to do >> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, >> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, >> but packets with MAC3 aren't actually received by the PMD. >> >> So need to ensure that the new default address is removed from the >> rest of >> the list if the address was already in the list. >> >> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >> Cc: stable@dpdk.org >> >> Signed-off-by: Huisong Li <lihuisong@huawei.com> >> Acked-by: Chengwen Feng <fengchengwen@huawei.com> >> --- >> v8: fix some comments. >> v7: add announcement in the release notes and document this behavior. >> v6: fix commit log and some code comments. >> v5: >> - merge the second patch into the first patch. >> - add error log when rollback failed. >> v4: >> - fix broken in the patchwork >> v3: >> - first explicitly remove the non-default MAC, then set default one. >> - document default and non-default MAC address >> v2: >> - fixed commit log. >> --- >> doc/guides/rel_notes/release_23_03.rst | 6 +++++ >> lib/ethdev/ethdev_driver.h | 6 ++++- >> lib/ethdev/rte_ethdev.c | 35 ++++++++++++++++++++++++-- >> lib/ethdev/rte_ethdev.h | 3 +++ >> 4 files changed, 47 insertions(+), 3 deletions(-) >> >> diff --git a/doc/guides/rel_notes/release_23_03.rst >> b/doc/guides/rel_notes/release_23_03.rst >> index 84b112a8b1..1c9b9912c2 100644 >> --- a/doc/guides/rel_notes/release_23_03.rst >> +++ b/doc/guides/rel_notes/release_23_03.rst >> @@ -105,6 +105,12 @@ API Changes >> Also, make sure to start the actual text at the margin. >> ======================================================= >> +* ethdev: ensured all entries in MAC address list are uniques. >> + When setting a default MAC address with the function >> + ``rte_eth_dev_default_mac_addr_set``, >> + the address is now removed from the rest of the address list >> + in order to ensure it is only at index 0 of the list. >> + >> ABI Changes >> ----------- >> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h >> index dde3ec84ef..3994c61b86 100644 >> --- a/lib/ethdev/ethdev_driver.h >> +++ b/lib/ethdev/ethdev_driver.h >> @@ -117,7 +117,11 @@ struct rte_eth_dev_data { >> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation >> failures */ >> - /** Device Ethernet link address. @see >> rte_eth_dev_release_port() */ >> + /** >> + * Device Ethernet link addresses. >> + * All entries are unique. >> + * The first entry (index zero) is the default address. >> + */ >> struct rte_ether_addr *mac_addrs; >> /** Bitmap associating MAC addresses to pools */ >> uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; >> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >> index 86ca303ab5..de25183619 100644 >> --- a/lib/ethdev/rte_ethdev.c >> +++ b/lib/ethdev/rte_ethdev.c >> @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, >> struct rte_ether_addr *addr) >> int >> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct >> rte_ether_addr *addr) >> { >> + uint64_t mac_pool_sel_bk = 0; >> struct rte_eth_dev *dev; >> + uint32_t pool; >> + int index; >> int ret; >> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); >> @@ -4517,16 +4520,44 @@ rte_eth_dev_default_mac_addr_set(uint16_t >> port_id, struct rte_ether_addr *addr) >> if (*dev->dev_ops->mac_addr_set == NULL) >> return -ENOTSUP; >> + /* Keep address unique in dev->data->mac_addrs[]. */ >> + index = eth_dev_get_mac_addr_index(port_id, addr); >> + if (index > 0) { >> + /* Remove address in dev data structure */ >> + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; >> + ret = rte_eth_dev_mac_addr_remove(port_id, addr); >> + if (ret < 0) { >> + RTE_ETHDEV_LOG(ERR, "Cannot remove the port %u address >> from the rest of list.\n", >> + port_id); >> + return ret; >> + } >> + } >> ret = (*dev->dev_ops->mac_addr_set)(dev, addr); >> if (ret < 0) >> - return ret; >> + goto out; >> /* Update default address in NIC data structure */ >> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >> return 0; >> -} >> +out: >> + if (index > 0) { >> + pool = 0; >> + do { >> + if (mac_pool_sel_bk & UINT64_C(1)) { >> + if (rte_eth_dev_mac_addr_add(port_id, addr, >> + pool) != 0) >> + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool >> id(%u) in port %u.\n", >> + pool, port_id); >> + } >> + mac_pool_sel_bk >>= 1; >> + pool++; >> + } while (mac_pool_sel_bk != 0); >> + } >> + >> + return ret; >> +} >> /* >> * Returns index into MAC address array of addr. Use >> 00:00:00:00:00:00 to find >> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h >> index d22de196db..2456153457 100644 >> --- a/lib/ethdev/rte_ethdev.h >> +++ b/lib/ethdev/rte_ethdev.h >> @@ -4356,6 +4356,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, >> + * it is removed from the rest of the list. >> * >> * @param port_id >> * The port identifier of the Ethernet device.
在 2023/5/16 22:13, Ferruh Yigit 写道: > On 5/16/2023 12:47 PM, lihuisong (C) wrote: >> Hi Ferruh, >> >> There is no result on techboard. >> How to deal with this problem next? > +techboard for comment. > > > Btw, what was your positioning to Bruce's suggestion, > when a MAC address is in the list, fail to set it as default and enforce > user do the corrective action (delete MAC explicitly etc...). If a MAC address is in the list, rte_eth_dev_default_mac_addr_set returns failure? > If you are OK with it, that is good for me too, unless techboard objects > we can proceed with that one. > > >> /Huisong >> >> 在 2023/2/2 20:36, Huisong Li 写道: >>> 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() doesn't remove it from the mac_addrs >>> list. As a result, one 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. >>> >>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove the >>> old default MAC when set default MAC. If user continues to do >>> set_default(MAC5), and the mac_addrs list is default=MAC5, filters=(MAC1, >>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the list, >>> but packets with MAC3 aren't actually received by the PMD. >>> >>> So need to ensure that the new default address is removed from the >>> rest of >>> the list if the address was already in the list. >>> >>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>> Cc: stable@dpdk.org >>> >>> Signed-off-by: Huisong Li <lihuisong@huawei.com> >>> Acked-by: Chengwen Feng <fengchengwen@huawei.com> >>> --- >>> v8: fix some comments. >>> v7: add announcement in the release notes and document this behavior. >>> v6: fix commit log and some code comments. >>> v5: >>> - merge the second patch into the first patch. >>> - add error log when rollback failed. >>> v4: >>> - fix broken in the patchwork >>> v3: >>> - first explicitly remove the non-default MAC, then set default one. >>> - document default and non-default MAC address >>> v2: >>> - fixed commit log. >>> --- >>> doc/guides/rel_notes/release_23_03.rst | 6 +++++ >>> lib/ethdev/ethdev_driver.h | 6 ++++- >>> lib/ethdev/rte_ethdev.c | 35 ++++++++++++++++++++++++-- >>> lib/ethdev/rte_ethdev.h | 3 +++ >>> 4 files changed, 47 insertions(+), 3 deletions(-) >>> >>> diff --git a/doc/guides/rel_notes/release_23_03.rst >>> b/doc/guides/rel_notes/release_23_03.rst >>> index 84b112a8b1..1c9b9912c2 100644 >>> --- a/doc/guides/rel_notes/release_23_03.rst >>> +++ b/doc/guides/rel_notes/release_23_03.rst >>> @@ -105,6 +105,12 @@ API Changes >>> Also, make sure to start the actual text at the margin. >>> ======================================================= >>> +* ethdev: ensured all entries in MAC address list are uniques. >>> + When setting a default MAC address with the function >>> + ``rte_eth_dev_default_mac_addr_set``, >>> + the address is now removed from the rest of the address list >>> + in order to ensure it is only at index 0 of the list. >>> + >>> ABI Changes >>> ----------- >>> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h >>> index dde3ec84ef..3994c61b86 100644 >>> --- a/lib/ethdev/ethdev_driver.h >>> +++ b/lib/ethdev/ethdev_driver.h >>> @@ -117,7 +117,11 @@ struct rte_eth_dev_data { >>> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation >>> failures */ >>> - /** Device Ethernet link address. @see >>> rte_eth_dev_release_port() */ >>> + /** >>> + * Device Ethernet link addresses. >>> + * All entries are unique. >>> + * The first entry (index zero) is the default address. >>> + */ >>> struct rte_ether_addr *mac_addrs; >>> /** Bitmap associating MAC addresses to pools */ >>> uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; >>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >>> index 86ca303ab5..de25183619 100644 >>> --- a/lib/ethdev/rte_ethdev.c >>> +++ b/lib/ethdev/rte_ethdev.c >>> @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, >>> struct rte_ether_addr *addr) >>> int >>> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct >>> rte_ether_addr *addr) >>> { >>> + uint64_t mac_pool_sel_bk = 0; >>> struct rte_eth_dev *dev; >>> + uint32_t pool; >>> + int index; >>> int ret; >>> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); >>> @@ -4517,16 +4520,44 @@ rte_eth_dev_default_mac_addr_set(uint16_t >>> port_id, struct rte_ether_addr *addr) >>> if (*dev->dev_ops->mac_addr_set == NULL) >>> return -ENOTSUP; >>> + /* Keep address unique in dev->data->mac_addrs[]. */ >>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>> + if (index > 0) { >>> + /* Remove address in dev data structure */ >>> + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; >>> + ret = rte_eth_dev_mac_addr_remove(port_id, addr); >>> + if (ret < 0) { >>> + RTE_ETHDEV_LOG(ERR, "Cannot remove the port %u address >>> from the rest of list.\n", >>> + port_id); >>> + return ret; >>> + } >>> + } >>> ret = (*dev->dev_ops->mac_addr_set)(dev, addr); >>> if (ret < 0) >>> - return ret; >>> + goto out; >>> /* Update default address in NIC data structure */ >>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>> return 0; >>> -} >>> +out: >>> + if (index > 0) { >>> + pool = 0; >>> + do { >>> + if (mac_pool_sel_bk & UINT64_C(1)) { >>> + if (rte_eth_dev_mac_addr_add(port_id, addr, >>> + pool) != 0) >>> + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool >>> id(%u) in port %u.\n", >>> + pool, port_id); >>> + } >>> + mac_pool_sel_bk >>= 1; >>> + pool++; >>> + } while (mac_pool_sel_bk != 0); >>> + } >>> + >>> + return ret; >>> +} >>> /* >>> * Returns index into MAC address array of addr. Use >>> 00:00:00:00:00:00 to find >>> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h >>> index d22de196db..2456153457 100644 >>> --- a/lib/ethdev/rte_ethdev.h >>> +++ b/lib/ethdev/rte_ethdev.h >>> @@ -4356,6 +4356,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, >>> + * it is removed from the rest of the list. >>> * >>> * @param port_id >>> * The port identifier of the Ethernet device. > .
On 5/17/2023 8:45 AM, lihuisong (C) wrote: > > 在 2023/5/16 22:13, Ferruh Yigit 写道: >> On 5/16/2023 12:47 PM, lihuisong (C) wrote: >>> Hi Ferruh, >>> >>> There is no result on techboard. >>> How to deal with this problem next? >> +techboard for comment. >> >> >> Btw, what was your positioning to Bruce's suggestion, >> when a MAC address is in the list, fail to set it as default and enforce >> user do the corrective action (delete MAC explicitly etc...). > If a MAC address is in the list, rte_eth_dev_default_mac_addr_set > returns failure? Yes. In that case API can return EEXIST or similar. In this case user need to call 'rte_eth_dev_mac_addr_remove()' first and call 'rte_eth_dev_default_mac_addr_set()' again, if this is the intention. >> If you are OK with it, that is good for me too, unless techboard objects >> we can proceed with that one. >> >> >>> /Huisong >>> >>> 在 2023/2/2 20:36, Huisong Li 写道: >>>> 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() doesn't remove it from the >>>> mac_addrs >>>> list. As a result, one 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. >>>> >>>> In addition, some PMDs, such as i40e, ice, hns3 and so on, do remove >>>> the >>>> old default MAC when set default MAC. If user continues to do >>>> set_default(MAC5), and the mac_addrs list is default=MAC5, >>>> filters=(MAC1, >>>> MAC2, MAC3, MAC4). At this moment, user can still see MAC3 from the >>>> list, >>>> but packets with MAC3 aren't actually received by the PMD. >>>> >>>> So need to ensure that the new default address is removed from the >>>> rest of >>>> the list if the address was already in the list. >>>> >>>> Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier") >>>> Cc: stable@dpdk.org >>>> >>>> Signed-off-by: Huisong Li <lihuisong@huawei.com> >>>> Acked-by: Chengwen Feng <fengchengwen@huawei.com> >>>> --- >>>> v8: fix some comments. >>>> v7: add announcement in the release notes and document this behavior. >>>> v6: fix commit log and some code comments. >>>> v5: >>>> - merge the second patch into the first patch. >>>> - add error log when rollback failed. >>>> v4: >>>> - fix broken in the patchwork >>>> v3: >>>> - first explicitly remove the non-default MAC, then set default >>>> one. >>>> - document default and non-default MAC address >>>> v2: >>>> - fixed commit log. >>>> --- >>>> doc/guides/rel_notes/release_23_03.rst | 6 +++++ >>>> lib/ethdev/ethdev_driver.h | 6 ++++- >>>> lib/ethdev/rte_ethdev.c | 35 >>>> ++++++++++++++++++++++++-- >>>> lib/ethdev/rte_ethdev.h | 3 +++ >>>> 4 files changed, 47 insertions(+), 3 deletions(-) >>>> >>>> diff --git a/doc/guides/rel_notes/release_23_03.rst >>>> b/doc/guides/rel_notes/release_23_03.rst >>>> index 84b112a8b1..1c9b9912c2 100644 >>>> --- a/doc/guides/rel_notes/release_23_03.rst >>>> +++ b/doc/guides/rel_notes/release_23_03.rst >>>> @@ -105,6 +105,12 @@ API Changes >>>> Also, make sure to start the actual text at the margin. >>>> ======================================================= >>>> +* ethdev: ensured all entries in MAC address list are uniques. >>>> + When setting a default MAC address with the function >>>> + ``rte_eth_dev_default_mac_addr_set``, >>>> + the address is now removed from the rest of the address list >>>> + in order to ensure it is only at index 0 of the list. >>>> + >>>> ABI Changes >>>> ----------- >>>> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h >>>> index dde3ec84ef..3994c61b86 100644 >>>> --- a/lib/ethdev/ethdev_driver.h >>>> +++ b/lib/ethdev/ethdev_driver.h >>>> @@ -117,7 +117,11 @@ struct rte_eth_dev_data { >>>> uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation >>>> failures */ >>>> - /** Device Ethernet link address. @see >>>> rte_eth_dev_release_port() */ >>>> + /** >>>> + * Device Ethernet link addresses. >>>> + * All entries are unique. >>>> + * The first entry (index zero) is the default address. >>>> + */ >>>> struct rte_ether_addr *mac_addrs; >>>> /** Bitmap associating MAC addresses to pools */ >>>> uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; >>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c >>>> index 86ca303ab5..de25183619 100644 >>>> --- a/lib/ethdev/rte_ethdev.c >>>> +++ b/lib/ethdev/rte_ethdev.c >>>> @@ -4498,7 +4498,10 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, >>>> struct rte_ether_addr *addr) >>>> int >>>> rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct >>>> rte_ether_addr *addr) >>>> { >>>> + uint64_t mac_pool_sel_bk = 0; >>>> struct rte_eth_dev *dev; >>>> + uint32_t pool; >>>> + int index; >>>> int ret; >>>> RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); >>>> @@ -4517,16 +4520,44 @@ rte_eth_dev_default_mac_addr_set(uint16_t >>>> port_id, struct rte_ether_addr *addr) >>>> if (*dev->dev_ops->mac_addr_set == NULL) >>>> return -ENOTSUP; >>>> + /* Keep address unique in dev->data->mac_addrs[]. */ >>>> + index = eth_dev_get_mac_addr_index(port_id, addr); >>>> + if (index > 0) { >>>> + /* Remove address in dev data structure */ >>>> + mac_pool_sel_bk = dev->data->mac_pool_sel[index]; >>>> + ret = rte_eth_dev_mac_addr_remove(port_id, addr); >>>> + if (ret < 0) { >>>> + RTE_ETHDEV_LOG(ERR, "Cannot remove the port %u address >>>> from the rest of list.\n", >>>> + port_id); >>>> + return ret; >>>> + } >>>> + } >>>> ret = (*dev->dev_ops->mac_addr_set)(dev, addr); >>>> if (ret < 0) >>>> - return ret; >>>> + goto out; >>>> /* Update default address in NIC data structure */ >>>> rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); >>>> return 0; >>>> -} >>>> +out: >>>> + if (index > 0) { >>>> + pool = 0; >>>> + do { >>>> + if (mac_pool_sel_bk & UINT64_C(1)) { >>>> + if (rte_eth_dev_mac_addr_add(port_id, addr, >>>> + pool) != 0) >>>> + RTE_ETHDEV_LOG(ERR, "failed to restore MAC pool >>>> id(%u) in port %u.\n", >>>> + pool, port_id); >>>> + } >>>> + mac_pool_sel_bk >>= 1; >>>> + pool++; >>>> + } while (mac_pool_sel_bk != 0); >>>> + } >>>> + >>>> + return ret; >>>> +} >>>> /* >>>> * Returns index into MAC address array of addr. Use >>>> 00:00:00:00:00:00 to find >>>> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h >>>> index d22de196db..2456153457 100644 >>>> --- a/lib/ethdev/rte_ethdev.h >>>> +++ b/lib/ethdev/rte_ethdev.h >>>> @@ -4356,6 +4356,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, >>>> + * it is removed from the rest of the list. >>>> * >>>> * @param port_id >>>> * The port identifier of the Ethernet device. >> .
在 2023/5/17 16:53, Ferruh Yigit 写道: > On 5/17/2023 8:45 AM, lihuisong (C) wrote: >> 在 2023/5/16 22:13, Ferruh Yigit 写道: >>> On 5/16/2023 12:47 PM, lihuisong (C) wrote: >>>> Hi Ferruh, >>>> >>>> There is no result on techboard. >>>> How to deal with this problem next? >>> +techboard for comment. >>> >>> >>> Btw, what was your positioning to Bruce's suggestion, >>> when a MAC address is in the list, fail to set it as default and enforce >>> user do the corrective action (delete MAC explicitly etc...). >> If a MAC address is in the list, rte_eth_dev_default_mac_addr_set >> returns failure? > Yes. > In that case API can return EEXIST or similar. In this case user need to > call 'rte_eth_dev_mac_addr_remove()' first and call > 'rte_eth_dev_default_mac_addr_set()' again, if this is the intention. lgtm. send V9 to do this? > >>> If you are OK with it, that is good for me too, unless techboard objects >>> we can proceed with that one. >>> >>>
On 5/17/2023 12:46 PM, lihuisong (C) wrote:
>
> 在 2023/5/17 16:53, Ferruh Yigit 写道:
>> On 5/17/2023 8:45 AM, lihuisong (C) wrote:
>>> 在 2023/5/16 22:13, Ferruh Yigit 写道:
>>>> On 5/16/2023 12:47 PM, lihuisong (C) wrote:
>>>>> Hi Ferruh,
>>>>>
>>>>> There is no result on techboard.
>>>>> How to deal with this problem next?
>>>> +techboard for comment.
>>>>
>>>>
>>>> Btw, what was your positioning to Bruce's suggestion,
>>>> when a MAC address is in the list, fail to set it as default and
>>>> enforce
>>>> user do the corrective action (delete MAC explicitly etc...).
>>> If a MAC address is in the list, rte_eth_dev_default_mac_addr_set
>>> returns failure?
>> Yes.
>> In that case API can return EEXIST or similar. In this case user need to
>> call 'rte_eth_dev_mac_addr_remove()' first and call
>> 'rte_eth_dev_default_mac_addr_set()' again, if this is the intention.
>
> lgtm.
> send V9 to do this?
>
I am happy to proceed with a v9 unless there is no objection from techboard.
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. Signed-off-by: Huisong Li <lihuisong@huawei.com> Acked-by: Chengwen Feng <fengchengwen@huawei.com> Acked-by: Thomas Monjalon <thomas@monjalon.net> --- v9: request user to remove the address instead of doing it implicitly in .mac_addr_set() API. v8: fix some comments. v7: add announcement in the release notes and document this behavior. v6: fix commit log and some code comments. v5: - merge the second patch into the first patch. - add error log when rollback failed. v4: - fix broken in the patchwork v3: - first explicitly remove the non-default MAC, then set default one. - document default and non-default MAC address v2: - fixed commit log. --- doc/guides/rel_notes/release_23_07.rst | 5 +++++ lib/ethdev/ethdev_driver.h | 6 +++++- lib/ethdev/rte_ethdev.c | 10 ++++++++++ lib/ethdev/rte_ethdev.h | 3 +++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/doc/guides/rel_notes/release_23_07.rst b/doc/guides/rel_notes/release_23_07.rst index 4ffef85d74..7c624d8315 100644 --- a/doc/guides/rel_notes/release_23_07.rst +++ b/doc/guides/rel_notes/release_23_07.rst @@ -96,6 +96,11 @@ API Changes Also, make sure to start the actual text at the margin. ======================================================= + * ethdev: ensured all entries in MAC address list are uniques. + When setting a default MAC address with the function + ``rte_eth_dev_default_mac_addr_set``, + the default one needs to be removed by user if it was already in + the list. ABI Changes ----------- diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index 2c9d615fb5..367c0c4878 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -117,7 +117,11 @@ struct rte_eth_dev_data { uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ + /** + * Device Ethernet link addresses. + * All entries are unique. + * The first entry (index zero) is the default address. + */ struct rte_ether_addr *mac_addrs; /** Bitmap associating MAC addresses to pools */ uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 4d03255683..d46e74504e 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -4898,6 +4898,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); @@ -4916,6 +4917,15 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) if (*dev->dev_ops->mac_addr_set == NULL) return -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/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index 99fe9e238b..09b2ff9e5e 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -4381,6 +4381,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. -- 2.33.0
On 5/19/2023 4:00 AM, Huisong Li wrote:
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index 99fe9e238b..09b2ff9e5e 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -4381,6 +4381,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.
Can you please document last sentences under '@return' as (-EEXIST)
error type?
在 2023/5/19 16:42, Ferruh Yigit 写道: > On 5/19/2023 4:00 AM, Huisong Li wrote: >> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h >> index 99fe9e238b..09b2ff9e5e 100644 >> --- a/lib/ethdev/rte_ethdev.h >> +++ b/lib/ethdev/rte_ethdev.h >> @@ -4381,6 +4381,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. > > Can you please document last sentences under '@return' as (-EEXIST) > error type? ok, v10 send later. > .
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. Signed-off-by: Huisong Li <lihuisong@huawei.com> Acked-by: Chengwen Feng <fengchengwen@huawei.com> Acked-by: Thomas Monjalon <thomas@monjalon.net> --- v10: add '-EEXIST' error type case under @return. v9: request user to remove the address instead of doing it implicitly in .mac_addr_set() API. v8: fix some comments. v7: add announcement in the release notes and document this behavior. v6: fix commit log and some code comments. v5: - merge the second patch into the first patch. - add error log when rollback failed. v4: - fix broken in the patchwork v3: - first explicitly remove the non-default MAC, then set default one. - document default and non-default MAC address v2: - fixed commit log. --- doc/guides/rel_notes/release_23_07.rst | 5 +++++ lib/ethdev/ethdev_driver.h | 6 +++++- lib/ethdev/rte_ethdev.c | 10 ++++++++++ lib/ethdev/rte_ethdev.h | 4 ++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/doc/guides/rel_notes/release_23_07.rst b/doc/guides/rel_notes/release_23_07.rst index 4ffef85d74..7c624d8315 100644 --- a/doc/guides/rel_notes/release_23_07.rst +++ b/doc/guides/rel_notes/release_23_07.rst @@ -96,6 +96,11 @@ API Changes Also, make sure to start the actual text at the margin. ======================================================= + * ethdev: ensured all entries in MAC address list are uniques. + When setting a default MAC address with the function + ``rte_eth_dev_default_mac_addr_set``, + the default one needs to be removed by user if it was already in + the list. ABI Changes ----------- diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index 2c9d615fb5..367c0c4878 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -117,7 +117,11 @@ struct rte_eth_dev_data { uint64_t rx_mbuf_alloc_failed; /**< Rx ring mbuf allocation failures */ - /** Device Ethernet link address. @see rte_eth_dev_release_port() */ + /** + * Device Ethernet link addresses. + * All entries are unique. + * The first entry (index zero) is the default address. + */ struct rte_ether_addr *mac_addrs; /** Bitmap associating MAC addresses to pools */ uint64_t mac_pool_sel[RTE_ETH_NUM_RECEIVE_MAC_ADDR]; diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 4d03255683..d46e74504e 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -4898,6 +4898,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); @@ -4916,6 +4917,15 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr) if (*dev->dev_ops->mac_addr_set == NULL) return -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/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index 99fe9e238b..fe8f7466c8 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -4381,6 +4381,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. @@ -4391,6 +4394,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); -- 2.33.0
On 5/19/2023 10:31 AM, Huisong Li wrote:
> 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.
>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> Acked-by: Chengwen Feng <fengchengwen@huawei.com>
> Acked-by: Thomas Monjalon <thomas@monjalon.net>
Fixes: 854d8ad4ef68 ("ethdev: add default mac address modifier")
Cc: stable@dpdk.org
Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
Applied to dpdk-next-net/main, thanks.