fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / bonding / bond_sysfs.c
index 041bcc5..ced9ed8 100644 (file)
@@ -20,7 +20,6 @@
  * file called LICENSE.
  *
  */
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/sched.h>
@@ -52,6 +51,7 @@ extern struct bond_params bonding_defaults;
 extern struct bond_parm_tbl bond_mode_tbl[];
 extern struct bond_parm_tbl bond_lacp_tbl[];
 extern struct bond_parm_tbl xmit_hashtype_tbl[];
+extern struct bond_parm_tbl arp_validate_tbl[];
 
 static int expected_refcount = -1;
 static struct class *netdev_class;
@@ -424,6 +424,12 @@ static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size
                ret = -EINVAL;
                goto out;
        } else {
+               if (bond->params.mode == BOND_MODE_8023AD)
+                       bond_unset_master_3ad_flags(bond);
+
+               if (bond->params.mode == BOND_MODE_ALB)
+                       bond_unset_master_alb_flags(bond);
+
                bond->params.mode = new_value;
                bond_set_mode_ops(bond, bond->params.mode);
                printk(KERN_INFO DRV_NAME ": %s: setting mode to %s (%d).\n",
@@ -497,6 +503,53 @@ out:
 }
 static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
 
+/*
+ * Show and set arp_validate.
+ */
+static ssize_t bonding_show_arp_validate(struct class_device *cd, char *buf)
+{
+       struct bonding *bond = to_bond(cd);
+
+       return sprintf(buf, "%s %d\n",
+                      arp_validate_tbl[bond->params.arp_validate].modename,
+                      bond->params.arp_validate) + 1;
+}
+
+static ssize_t bonding_store_arp_validate(struct class_device *cd, const char *buf, size_t count)
+{
+       int new_value;
+       struct bonding *bond = to_bond(cd);
+
+       new_value = bond_parse_parm((char *)buf, arp_validate_tbl);
+       if (new_value < 0) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Ignoring invalid arp_validate value %s\n",
+                      bond->dev->name, buf);
+               return -EINVAL;
+       }
+       if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: arp_validate only supported in active-backup mode.\n",
+                      bond->dev->name);
+               return -EINVAL;
+       }
+       printk(KERN_INFO DRV_NAME ": %s: setting arp_validate to %s (%d).\n",
+              bond->dev->name, arp_validate_tbl[new_value].modename,
+              new_value);
+
+       if (!bond->params.arp_validate && new_value) {
+               bond_register_arp(bond);
+       } else if (bond->params.arp_validate && !new_value) {
+               bond_unregister_arp(bond);
+       }
+
+       bond->params.arp_validate = new_value;
+
+       return count;
+}
+
+static CLASS_DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
+
 /*
  * Show and set the arp timer interval.  There are two tricky bits
  * here.  First, if ARP monitoring is activated, then we must disable
@@ -909,6 +962,11 @@ static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, si
                               "ARP monitoring. Disabling ARP monitoring...\n",
                               bond->dev->name);
                        bond->params.arp_interval = 0;
+                       if (bond->params.arp_validate) {
+                               bond_unregister_arp(bond);
+                               bond->params.arp_validate =
+                                       BOND_ARP_VALIDATE_NONE;
+                       }
                        /* Kill ARP timer, else it brings bond's link down */
                        if (bond->mii_timer.function) {
                                printk(KERN_INFO DRV_NAME
@@ -1088,7 +1146,7 @@ static ssize_t bonding_store_active_slave(struct class_device *cd, const char *b
                             strlen(slave->dev->name)) == 0) {
                                old_active = bond->curr_active_slave;
                                new_active = slave;
-                               if (new_active && (new_active == old_active)) {
+                               if (new_active == old_active) {
                                        /* do nothing */
                                        printk(KERN_INFO DRV_NAME
                                               ": %s: %s is already the current active slave.\n",
@@ -1268,6 +1326,7 @@ static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, N
 static struct attribute *per_bond_attrs[] = {
        &class_device_attr_slaves.attr,
        &class_device_attr_mode.attr,
+       &class_device_attr_arp_validate.attr,
        &class_device_attr_arp_interval.attr,
        &class_device_attr_arp_ip_target.attr,
        &class_device_attr_downdelay.attr,