diff mbox series

[net-next] net: add check for current MAC address in dev_set_mac_address

Message ID 20230609165241.827338-1-piotrx.gardocki@intel.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series [net-next] net: add check for current MAC address in dev_set_mac_address | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 16 this patch: 16
netdev/cc_maintainers warning 3 maintainers not CCed: pabeni@redhat.com edumazet@google.com davem@davemloft.net
netdev/build_clang success Errors and warnings before: 8 this patch: 8
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 16 this patch: 16
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Piotr Gardocki June 9, 2023, 4:52 p.m. UTC
In some cases it is possible for kernel to come with request
to change primary MAC address to the address that is already
set on the given interface.

This patch adds proper check to return fast from the function
in these cases.

An example of such case is adding an interface to bonding
channel in balance-alb mode:
modprobe bonding mode=balance-alb miimon=100 max_bonds=1
ip link set bond0 up
ifenslave bond0 <eth>

Signed-off-by: Piotr Gardocki <piotrx.gardocki@intel.com>
---
 net/core/dev.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Maciej Fijalkowski June 9, 2023, 5 p.m. UTC | #1
On Fri, Jun 09, 2023 at 06:52:41PM +0200, Piotr Gardocki wrote:

Hey Piotr,

> In some cases it is possible for kernel to come with request
> to change primary MAC address to the address that is already
> set on the given interface.
> 
> This patch adds proper check to return fast from the function
> in these cases.
> 
> An example of such case is adding an interface to bonding
> channel in balance-alb mode:
> modprobe bonding mode=balance-alb miimon=100 max_bonds=1
> ip link set bond0 up
> ifenslave bond0 <eth>
> 
> Signed-off-by: Piotr Gardocki <piotrx.gardocki@intel.com>
> ---
>  net/core/dev.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 99d99b247bc9..c2c3ec61397b 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -8820,6 +8820,8 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
>  		return -EINVAL;
>  	if (!netif_device_present(dev))
>  		return -ENODEV;
> +	if (ether_addr_equal(dev->dev_addr, sa->sa_data))
> +		return 0;

Now this check being in makes calls to ether_addr_equal() within driver's
ndo callbacks redundant.

I would rather see this as patchset send directly to netdev where you have
this patch followed by addressing driver's callbacks.

Moar commitz == moar glory ;)

>  	err = dev_pre_changeaddr_notify(dev, sa->sa_data, extack);
>  	if (err)
>  		return err;
> -- 
> 2.34.1
>
Piotr Gardocki June 9, 2023, 5:11 p.m. UTC | #2
On 09.06.2023 19:00, Maciej Fijalkowski wrote:
> On Fri, Jun 09, 2023 at 06:52:41PM +0200, Piotr Gardocki wrote:
>> @@ -8820,6 +8820,8 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
>>  		return -EINVAL;
>>  	if (!netif_device_present(dev))
>>  		return -ENODEV;
>> +	if (ether_addr_equal(dev->dev_addr, sa->sa_data))
>> +		return 0;
> 
> Now this check being in makes calls to ether_addr_equal() within driver's
> ndo callbacks redundant.
> 
> I would rather see this as patchset send directly to netdev where you have
> this patch followed by addressing driver's callbacks.

Sure, will do :)
I will remove this check in all drivers in drivers/net/ethernet/intel/,
I don't have time to review all usages of this callback in kernel,
there are too many of them. Will resend as a patchset next week.

> Moar commitz == moar glory ;)
> 
>>  	err = dev_pre_changeaddr_notify(dev, sa->sa_data, extack);
>>  	if (err)
>>  		return err;
>> -- 
>> 2.34.1
>>
Jakub Kicinski June 10, 2023, 6:44 a.m. UTC | #3
On Fri,  9 Jun 2023 18:52:41 +0200 Piotr Gardocki wrote:
> +	if (ether_addr_equal(dev->dev_addr, sa->sa_data))
> +		return 0;

not every device is ethernet, you need to use dev->addr_len for
the comparison.
Piotr Gardocki June 12, 2023, 2:49 p.m. UTC | #4
On 10.06.2023 08:44, Jakub Kicinski wrote:
> On Fri,  9 Jun 2023 18:52:41 +0200 Piotr Gardocki wrote:
>> +	if (ether_addr_equal(dev->dev_addr, sa->sa_data))
>> +		return 0;
> 
> not every device is ethernet, you need to use dev->addr_len for
> the comparison.

Before re-sending I just want to double check.
Did you mean checking if sa->sa_family == AF_LOCAL ?
There's no length in sockaddr.

It would like this:
	if (sa->sa_family == AF_LOCAL &&
	    ether_addr_equal(dev->dev_addr, sa->sa_data))
		return 0;
Maciej Fijalkowski June 12, 2023, 3:37 p.m. UTC | #5
On Mon, Jun 12, 2023 at 04:49:47PM +0200, Piotr Gardocki wrote:
> On 10.06.2023 08:44, Jakub Kicinski wrote:
> > On Fri,  9 Jun 2023 18:52:41 +0200 Piotr Gardocki wrote:
> >> +	if (ether_addr_equal(dev->dev_addr, sa->sa_data))
> >> +		return 0;
> > 
> > not every device is ethernet, you need to use dev->addr_len for
> > the comparison.
> 
> Before re-sending I just want to double check.
> Did you mean checking if sa->sa_family == AF_LOCAL ?
> There's no length in sockaddr.
> 
> It would like this:
> 	if (sa->sa_family == AF_LOCAL &&
> 	    ether_addr_equal(dev->dev_addr, sa->sa_data))
> 		return 0;

I believe Jakub just wanted this:

	if (dev->addr_len)
		if (ether_addr_equal(dev->dev_addr, sa->sa_data))
			return 0;

so no clue why you want anything from sockaddr?
Piotr Gardocki June 12, 2023, 4:43 p.m. UTC | #6
On 12.06.2023 17:37, Maciej Fijalkowski wrote:
> On Mon, Jun 12, 2023 at 04:49:47PM +0200, Piotr Gardocki wrote:
>> On 10.06.2023 08:44, Jakub Kicinski wrote:
>>> On Fri,  9 Jun 2023 18:52:41 +0200 Piotr Gardocki wrote:
>>>> +	if (ether_addr_equal(dev->dev_addr, sa->sa_data))
>>>> +		return 0;
>>>
>>> not every device is ethernet, you need to use dev->addr_len for
>>> the comparison.
>>
>> Before re-sending I just want to double check.
>> Did you mean checking if sa->sa_family == AF_LOCAL ?
>> There's no length in sockaddr.
>>
>> It would like this:
>> 	if (sa->sa_family == AF_LOCAL &&
>> 	    ether_addr_equal(dev->dev_addr, sa->sa_data))
>> 		return 0;
> 
> I believe Jakub just wanted this:
> 
> 	if (dev->addr_len)
> 		if (ether_addr_equal(dev->dev_addr, sa->sa_data))
> 			return 0;
> 
> so no clue why you want anything from sockaddr?

I understood that dev->type and dev->addr_len can just be different
than AF_LOCAL and 48 bits in this function.
Your version does not convince me, let's wait for Jakub's judgement.
Jakub Kicinski June 12, 2023, 5:39 p.m. UTC | #7
On Mon, 12 Jun 2023 18:43:01 +0200 Piotr Gardocki wrote:
> On 12.06.2023 17:37, Maciej Fijalkowski wrote:
> > On Mon, Jun 12, 2023 at 04:49:47PM +0200, Piotr Gardocki wrote:  
> >> Before re-sending I just want to double check.
> >> Did you mean checking if sa->sa_family == AF_LOCAL ?
> >> There's no length in sockaddr.
> >>
> >> It would like this:
> >> 	if (sa->sa_family == AF_LOCAL &&
> >> 	    ether_addr_equal(dev->dev_addr, sa->sa_data))
> >> 		return 0;  
> > 
> > I believe Jakub just wanted this:
> > 
> > 	if (dev->addr_len)
> > 		if (ether_addr_equal(dev->dev_addr, sa->sa_data))
> > 			return 0;
> > 
> > so no clue why you want anything from sockaddr?  
> 
> I understood that dev->type and dev->addr_len can just be different
> than AF_LOCAL and 48 bits in this function.
> Your version does not convince me, let's wait for Jakub's judgement.

I'm probably missing something because I'm not sure where 
the discussion about AF_LOCAL came from. All I meant is:

	if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
		return 0;
diff mbox series

Patch

diff --git a/net/core/dev.c b/net/core/dev.c
index 99d99b247bc9..c2c3ec61397b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -8820,6 +8820,8 @@  int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
 		return -EINVAL;
 	if (!netif_device_present(dev))
 		return -ENODEV;
+	if (ether_addr_equal(dev->dev_addr, sa->sa_data))
+		return 0;
 	err = dev_pre_changeaddr_notify(dev, sa->sa_data, extack);
 	if (err)
 		return err;