netdev
[Top] [All Lists]

[PATCH 5/10] [bonding 2.6] Add support for changing HW address and MTU

To: bonding-devel@xxxxxxxxxxxxxxxxxxxxx, netdev@xxxxxxxxxxx
Subject: [PATCH 5/10] [bonding 2.6] Add support for changing HW address and MTU
From: Amir Noam <amir.noam@xxxxxxxxx>
Date: Thu, 11 Sep 2003 17:40:58 +0300
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: KMail/1.4.3
diff -Nuarp a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c   Thu Sep 11 16:48:26 2003
+++ b/drivers/net/bonding/bond_main.c   Thu Sep 11 16:48:27 2003
@@ -592,6 +592,11 @@ static struct slave *find_best_interface
 
 
 /* #define BONDING_DEBUG 1 */
+#ifdef BONDING_DEBUG
+#define dprintk(x...) printk(x...)
+#else /* BONDING_DEBUG */
+#define dprintk(x...) do {} while (0)
+#endif /* BONDING_DEBUG */
 
 /* several macros */
 
@@ -3021,10 +3026,6 @@ static int bond_ioctl(struct net_device 
                case SIOCBONDRELEASE:   
                        ret = bond_release(master_dev, slave_dev); 
                        break;
-               case BOND_SETHWADDR_OLD:
-               case SIOCBONDSETHWADDR: 
-                       ret = bond_sethwaddr(master_dev, slave_dev);
-                       break;
                case BOND_CHANGE_ACTIVE_OLD:
                case SIOCBONDCHANGEACTIVE:
                        if (USES_PRIMARY(bond_mode)) {
@@ -3464,6 +3465,132 @@ static int bond_read_proc(char *buf, cha
 }
 #endif /* CONFIG_PROC_FS */
 
+
+/*
+ * Change HW address
+ *
+ * Note that many devices must be down to change the HW address, and
+ * downing the master releases all slaves.  We can make bonds full of
+ * bonding devices to test this, however.
+ */
+static inline int
+bond_set_mac_address(struct net_device *dev, void *addr)
+{
+       struct bonding *bond = dev->priv;
+       struct sockaddr *sa = addr, tmp_sa;
+       struct slave *slave;
+       int error;
+
+       dprintk(KERN_INFO "bond_set_mac_address %p %s\n", dev,
+              dev->name);
+
+       if (!is_valid_ether_addr(sa->sa_data)) {
+               return -EADDRNOTAVAIL;
+       }
+
+       for (slave = bond->prev; slave != (struct slave *)bond;
+            slave = slave->prev) {
+               dprintk(KERN_INFO "bond_set_mac: slave %p %s\n", slave,
+                       slave->dev->name);
+               if (slave->dev->set_mac_address == NULL) {
+                       error = -EOPNOTSUPP;
+                       dprintk(KERN_INFO "bond_set_mac EOPNOTSUPP %s\n",
+                               slave->dev->name);
+                       goto unwind;
+               }
+
+               error = slave->dev->set_mac_address(slave->dev, addr);
+               if (error) {
+                       /* TODO: consider downing the slave 
+                        * and retry ?
+                        * User should expect communications
+                        * breakage anyway until ARP finish
+                        * updating, so...
+                        */
+                       dprintk(KERN_INFO "bond_set_mac err %d %s\n",
+                               error, slave->dev->name);
+                       goto unwind;
+               }
+       }
+
+       /* success */
+       memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
+       return 0;
+
+unwind:
+       memcpy(tmp_sa.sa_data, dev->dev_addr, dev->addr_len);
+       tmp_sa.sa_family = dev->type;
+
+       for (slave = slave->next; slave != bond->next;
+            slave = slave->next) {
+               int tmp_error;
+
+               tmp_error = slave->dev->set_mac_address(slave->dev, &tmp_sa);
+               if (tmp_error) {
+                       dprintk(KERN_INFO "bond_set_mac_address: "
+                               "unwind err %d dev %s\n",
+                               tmp_error, slave->dev->name);
+               }
+       }
+
+       return error;
+}
+
+/*
+ * Change the MTU of all of a master's slaves to match the master
+ */
+static inline int
+bond_change_mtu(struct net_device *dev, int newmtu)
+{
+       bonding_t *bond = dev->priv;
+       slave_t *slave;
+       int error;
+
+       dprintk(KERN_INFO "CM: b %p nm %d\n", bond, newmtu);
+       for (slave = bond->prev; slave != (slave_t *)bond;
+            slave = slave->prev) {
+               dprintk(KERN_INFO "CM: s %p s->p %p c_m %p\n", slave,
+                       slave->prev, slave->dev->change_mtu);
+               if (slave->dev->change_mtu) {
+                       error = slave->dev->change_mtu(slave->dev, newmtu);
+               } else {
+                       slave->dev->mtu = newmtu;
+                       error = 0;
+               }
+
+               if (error) {
+                       /* If we failed to set the slave's mtu to the new value
+                        * we must abort the operation even in ACTIVE_BACKUP
+                        * mode, because if we allow the backup slaves to have
+                        * different mtu values than the active slave we'll
+                        * need to change their mtu when doing a failover. That
+                        * means changing their mtu from timer context, which
+                        * is probably not a good idea.
+                        */
+                       dprintk(KERN_INFO "bond_change_mtu err %d %s\n",
+                              error, slave->dev->name);
+                       goto unwind;
+               }
+       }
+
+       dev->mtu = newmtu;
+       return 0;
+
+
+unwind:
+       for (slave = slave->next; slave != bond->next;
+            slave = slave->next) {
+
+               if (slave->dev->change_mtu) {
+                       slave->dev->change_mtu(slave->dev, dev->mtu);
+               } else {
+                       slave->dev->mtu = dev->mtu;
+               }
+       }
+
+       return error;
+}
+
 static int bond_event(struct notifier_block *this, unsigned long event, 
                        void *ptr)
 {
@@ -3556,7 +3683,8 @@ static int __init bond_init(struct net_d
        dev->stop = bond_close;
        dev->set_multicast_list = set_multicast_list;
        dev->do_ioctl = bond_ioctl;
-
+       dev->change_mtu = bond_change_mtu;
+       dev->set_mac_address = bond_set_mac_address;
        dev->tx_queue_len = 0;
        dev->flags |= IFF_MASTER|IFF_MULTICAST;
 #ifdef CONFIG_NET_FASTROUTE



<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH 5/10] [bonding 2.6] Add support for changing HW address and MTU, Amir Noam <=