A while back the following change was made to the bonding code:

commit df49898a47061e82219c991dfbe9ac6ddf7a866b
Author: John W. Linville <[EMAIL PROTECTED]>
Date:   Tue Oct 18 21:30:58 2005 -0400

    [PATCH] bonding: cleanup comment for mode 1 IGMP xmit hack
    
    Expand comment explaining MAC address selection for replicated IGMP
    frames transmitted in bonding mode 1 (active-backup).  Also, a small
    whitespace cleanup.
    
    Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>

In general this patch is good, but this tweaks that feature by allowing
that functionality to be enabled and disabled.  This patch adds a new
module option as well as a sysfs entry.  It sets the default to be the
current behavior so existing users shouldn't notice any difference.



Signed-off-by: Andy Gospodarek <[EMAIL PROTECTED]>
---

 drivers/net/bonding/bond_main.c  |   65 +++++++++++++++++++++++++++++++--------
 drivers/net/bonding/bond_sysfs.c |   46 +++++++++++++++++++++++++++
 drivers/net/bonding/bonding.h    |    1
 include/linux/if_bonding.h       |    3 +
 4 files changed, 102 insertions(+), 13 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a7c8f98..b531d4a 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -96,6 +96,7 @@ static char *xmit_hash_policy = NULL;
 static int arp_interval = BOND_LINK_ARP_INTERV;
 static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
 static char *arp_validate = NULL;
+static char *igmp_flood = NULL;
 struct bond_params bonding_defaults;
 
 module_param(max_bonds, int, 0);
@@ -129,6 +130,8 @@ module_param_array(arp_ip_target, charp, NULL, 0);
 MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
 module_param(arp_validate, charp, 0);
 MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none 
(default), active, backup or all");
+module_param(igmp_flood, charp, 0);
+MODULE_PARM_DESC(igmp_flood, "flood IGMP control traffic on active-backup 
bonding: yes (default) or no");
 
 /*----------------------------- Global variables ----------------------------*/
 
@@ -180,6 +183,12 @@ struct bond_parm_tbl arp_validate_tbl[] = {
 {      NULL,                   -1},
 };
 
+struct bond_parm_tbl igmp_flood_tbl[] = {
+{      "no",                   BOND_IGMP_ACTIVEONLY},
+{      "yes",                  BOND_IGMP_ALLMEMBERS},
+{      NULL,                   -1},
+};
+
 /*-------------------------- Forward declarations ---------------------------*/
 
 static void bond_send_gratuitous_arp(struct bonding *bond);
@@ -3070,6 +3079,9 @@ static void bond_info_show_slave(struct seq_file *seq, 
const struct slave *slave
                   slave->perm_hwaddr[2], slave->perm_hwaddr[3],
                   slave->perm_hwaddr[4], slave->perm_hwaddr[5]);
 
+       seq_printf(seq, "IGMP Flood: %s\n", (bond->params.igmp_flood) ? 
+                                           "yes" : "no");
+                                               
        if (bond->params.mode == BOND_MODE_8023AD) {
                const struct aggregator *agg
                        = SLAVE_AD_INFO(slave).port.aggregator;
@@ -4067,19 +4079,24 @@ static int bond_xmit_activebackup(struct sk_buff *skb, 
struct net_device *bond_d
        if (!bond->curr_active_slave)
                goto out;
 
-       /* Xmit IGMP frames on all slaves to ensure rapid fail-over
-          for multicast traffic on snooping switches */
-       if (skb->protocol == __constant_htons(ETH_P_IP) &&
-           skb->nh.iph->protocol == IPPROTO_IGMP) {
-               struct slave *slave, *active_slave;
-               int i;
-
-               active_slave = bond->curr_active_slave;
-               bond_for_each_slave_from_to(bond, slave, i, active_slave->next,
-                                           active_slave->prev)
-                       if (IS_UP(slave->dev) &&
-                           (slave->link == BOND_LINK_UP))
-                               bond_activebackup_xmit_copy(skb, bond, slave);
+       /* Let's make this behavior optional since it causes problems
+          when the links are connected to different switches. */
+       if (bond->params.igmp_flood) {
+
+               /* Xmit IGMP frames on all slaves to ensure rapid fail-over
+                  for multicast traffic on snooping switches */
+               if (skb->protocol == __constant_htons(ETH_P_IP) &&
+                   skb->nh.iph->protocol == IPPROTO_IGMP) {
+                       struct slave *slave, *active_slave;
+                       int i;
+
+                       active_slave = bond->curr_active_slave;
+                       bond_for_each_slave_from_to(bond, slave, i, 
active_slave->next,
+                                                   active_slave->prev)
+                               if (IS_UP(slave->dev) &&
+                                   (slave->link == BOND_LINK_UP))
+                                       bond_activebackup_xmit_copy(skb, bond, 
slave);
+               }
        }
 
        res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
@@ -4409,6 +4426,7 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl 
*tbl)
 static int bond_check_params(struct bond_params *params)
 {
        int arp_validate_value;
+       int igmp_flood_value;
 
        /*
         * Convert string parameters.
@@ -4636,6 +4654,26 @@ static int bond_check_params(struct bond_params *params)
        } else
                arp_validate_value = 0;
 
+       if (igmp_flood) {
+               if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
+                       printk(KERN_WARNING DRV_NAME
+               ": igmp_flood only supported in active-backup mode\n");
+                       return -EINVAL;
+               }
+               igmp_flood_value = bond_parse_parm(igmp_flood,
+                                                  igmp_flood_tbl);
+
+               if (igmp_flood_value == -1) {
+                       printk(KERN_ERR DRV_NAME
+                              ": Error: invalid igmp_flood \"%s\"\n",
+                              igmp_flood == NULL ? "NULL" : igmp_flood);
+                       return -EINVAL;
+               }       
+       }
+       else
+               igmp_flood_value = 1;
+
+
        if (miimon) {
                printk(KERN_INFO DRV_NAME
                       ": MII link monitoring set to %d ms\n",
@@ -4687,6 +4725,7 @@ static int bond_check_params(struct bond_params *params)
        params->use_carrier = use_carrier;
        params->lacp_fast = lacp_fast;
        params->primary[0] = 0;
+       params->igmp_flood = igmp_flood_value;
 
        if (primary) {
                strncpy(params->primary, primary, IFNAMSIZ);
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 41aa78b..abb34d5 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -131,6 +131,7 @@ struct bond_params {
        int updelay;
        int downdelay;
        int lacp_fast;
+       int igmp_flood;
        char primary[IFNAMSIZ];
        u32 arp_targets[BOND_MAX_ARP_TARGETS];
 };
diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h
index 84598fa..3be5598 100644
--- a/include/linux/if_bonding.h
+++ b/include/linux/if_bonding.h
@@ -87,6 +87,9 @@
 #define BOND_XMIT_POLICY_LAYER2                0 /* layer 2 (MAC only), 
default */
 #define BOND_XMIT_POLICY_LAYER34       1 /* layer 3+4 (IP ^ MAC) */
 
+#define BOND_IGMP_ACTIVEONLY           0
+#define BOND_IGMP_ALLMEMBERS           1
+
 typedef struct ifbond {
        __s32 bond_mode;
        __s32 num_slaves;
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index a122baa..6a4d892 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -50,6 +50,7 @@ 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[];
+extern struct bond_parm_tbl igmp_flood_tbl[];
 
 static int expected_refcount = -1;
 static struct class *netdev_class;
@@ -563,6 +564,50 @@ static ssize_t bonding_store_arp_validate(struct device *d,
 static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, 
bonding_store_arp_validate);
 
 /*
+ * Show and set igmp_flood.
+ */
+static ssize_t bonding_show_igmp_flood(struct device *d,
+                                      struct device_attribute *attr,
+                                      char *buf)
+{
+       struct bonding *bond = to_bond(d);
+
+       return sprintf(buf, "%s %d\n",
+                      igmp_flood_tbl[bond->params.igmp_flood].modename,
+                      bond->params.igmp_flood) + 1;
+}
+
+static ssize_t bonding_store_igmp_flood(struct device *d,
+                                       struct device_attribute *attr,
+                                       const char *buf, size_t count)
+{
+       int new_value;
+       struct bonding *bond = to_bond(d);
+
+       new_value = bond_parse_parm((char *)buf, igmp_flood_tbl);
+       if (new_value < 0) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Ignoring invalid igmp_flood value %s\n",
+                      bond->dev->name, buf);
+               return -EINVAL;
+       }
+       if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: igmp_flood only supported in active-backup 
mode.\n",
+                      bond->dev->name);
+               return -EINVAL;
+       }
+       printk(KERN_INFO DRV_NAME ": %s: setting igmp_flood to %s (%d).\n",
+              bond->dev->name, igmp_flood_tbl[new_value].modename,
+              new_value);
+
+       bond->params.igmp_flood = new_value;
+
+       return count;
+}
+
+static DEVICE_ATTR(igmp_flood, S_IRUGO | S_IWUSR, bonding_show_igmp_flood, 
bonding_store_igmp_flood);
+/*
  * Show and set the arp timer interval.  There are two tricky bits
  * here.  First, if ARP monitoring is activated, then we must disable
  * MII monitoring.  Second, if the ARP timer isn't running, we must
@@ -1387,6 +1432,7 @@ static struct attribute *per_bond_attrs[] = {
        &dev_attr_slaves.attr,
        &dev_attr_mode.attr,
        &dev_attr_arp_validate.attr,
+       &dev_attr_igmp_flood.attr,
        &dev_attr_arp_interval.attr,
        &dev_attr_arp_ip_target.attr,
        &dev_attr_downdelay.attr,
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to