]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: hsr: sync hw addr of slave2 according to slave1 hw addr on PRP
authorFernando Fernandez Mancera <ffmancera@riseup.net>
Wed, 9 Apr 2025 10:19:11 +0000 (12:19 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 14 Apr 2025 11:40:06 +0000 (12:40 +0100)
In order to work properly PRP requires slave1 and slave2 to share the
same MAC address. To ease the configuration process on userspace tools,
sync the slave2 MAC address with slave1. In addition, when deleting the
port from the list, restore the original MAC address.

Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/hsr/hsr_device.c
net/hsr/hsr_main.c
net/hsr/hsr_main.h
net/hsr/hsr_slave.c

index 1b1b700ec05eac49efdc71f8fe4df41497634196..0d1e56965af0aca9a359cc38115c23a555ee26cc 100644 (file)
@@ -761,6 +761,11 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
        if (res)
                goto err_unregister;
 
+       if (protocol_version == PRP_V1) {
+               eth_hw_addr_set(slave[1], slave[0]->dev_addr);
+               call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
+       }
+
        if (interlink) {
                res = hsr_add_port(hsr, interlink, HSR_PT_INTERLINK, extack);
                if (res)
index d7ae32473c41a641bff1c0783ca5867d8acae052..192893c3f2ec7360695b178970cc4870002f702b 100644 (file)
@@ -78,6 +78,15 @@ static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,
                        eth_hw_addr_set(master->dev, dev->dev_addr);
                        call_netdevice_notifiers(NETDEV_CHANGEADDR,
                                                 master->dev);
+
+                       if (hsr->prot_version == PRP_V1) {
+                               port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
+                               if (port) {
+                                       eth_hw_addr_set(port->dev, dev->dev_addr);
+                                       call_netdevice_notifiers(NETDEV_CHANGEADDR,
+                                                                port->dev);
+                               }
+                       }
                }
 
                /* Make sure we recognize frames from ourselves in hsr_rcv() */
index 1bc47b17a2968c6af390c2b9dc7d993198122881..135ec5fce0196741f4035a74a4f965e7fa015504 100644 (file)
@@ -155,6 +155,7 @@ struct hsr_port {
        struct hsr_priv         *hsr;
        enum hsr_port_type      type;
        struct rcu_head         rcu;
+       unsigned char           original_macaddress[ETH_ALEN];
 };
 
 struct hsr_frame_info;
index 2a802a5de2acca1d87ad475b3c96d2464a1faad0..b87b6a6fe07000e77011b6c0ab408ee8263a3171 100644 (file)
@@ -196,6 +196,7 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev,
        port->hsr = hsr;
        port->dev = dev;
        port->type = type;
+       ether_addr_copy(port->original_macaddress, dev->dev_addr);
 
        if (type != HSR_PT_MASTER) {
                res = hsr_portdev_setup(hsr, dev, port, extack);
@@ -232,6 +233,7 @@ void hsr_del_port(struct hsr_port *port)
                if (!port->hsr->fwd_offloaded)
                        dev_set_promiscuity(port->dev, -1);
                netdev_upper_dev_unlink(port->dev, master->dev);
+               eth_hw_addr_set(port->dev, port->original_macaddress);
        }
 
        kfree_rcu(port, rcu);