All of lore.kernel.org
 help / color / mirror / Atom feed
From: Flavio Leitner <fleitner@redhat.com>
To: <netdev@vger.kernel.org>
Cc: Flavio Leitner <fleitner@redhat.com>
Subject: [PATCH] bonding: rejoin multicast groups on VLANs
Date: Wed, 29 Sep 2010 04:12:24 -0300	[thread overview]
Message-ID: <1285744344-1231-1-git-send-email-fleitner@redhat.com> (raw)

It fixes bonding to rejoin multicast groups added
to VLAN devices on top of bonding when a failover
happens.

The first packet may be discarded, so the timer
assure that at least 3 Reports are sent.

Signed-off-by: Flavio Leitner <fleitner@redhat.com>
---
 drivers/net/bonding/bond_main.c |   59 +++++++++++++++++++++++++++++++++-----
 drivers/net/bonding/bonding.h   |    2 +
 2 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 3b16f62..a23a5fa 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -865,18 +865,14 @@ static void bond_mc_del(struct bonding *bond, void *addr)
 }
 
 
-/*
- * Retrieve the list of registered multicast addresses for the bonding
- * device and retransmit an IGMP JOIN request to the current active
- * slave.
- */
-static void bond_resend_igmp_join_requests(struct bonding *bond)
+static void __bond_resend_igmp_join_requests(struct net_device *dev)
 {
 	struct in_device *in_dev;
 	struct ip_mc_list *im;
 
 	rcu_read_lock();
-	in_dev = __in_dev_get_rcu(bond->dev);
+
+	in_dev = __in_dev_get_rcu(dev);
 	if (in_dev) {
 		for (im = in_dev->mc_list; im; im = im->next)
 			ip_mc_rejoin_group(im);
@@ -885,6 +881,42 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
 	rcu_read_unlock();
 }
 
+
+/*
+ * Retrieve the list of registered multicast addresses for the bonding
+ * device and retransmit an IGMP JOIN request to the current active
+ * slave.
+ */
+static void bond_resend_igmp_join_requests(struct bonding *bond)
+{
+	struct net_device *vlan_dev;
+	struct vlan_entry *vlan;
+
+	read_lock(&bond->lock);
+	if (bond->kill_timers)
+		goto out;
+
+	/* rejoin all groups on bond device */
+	__bond_resend_igmp_join_requests(bond->dev);
+
+	if (!bond->vlgrp)
+		goto reschedule;
+
+	/* rejoin all groups on vlan devices */
+	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
+		vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
+		if (vlan_dev)
+			__bond_resend_igmp_join_requests(vlan_dev);
+	}
+
+reschedule:
+	if (--bond->resend_igmp > 0)
+		mod_timer(&bond->mc_timer, jiffies + HZ/5);
+
+out:
+	read_unlock(&bond->lock);
+}
+
 /*
  * flush all members of flush->mc_list from device dev->mc_list
  */
@@ -944,7 +976,10 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
 
 		netdev_for_each_mc_addr(ha, bond->dev)
 			dev_mc_add(new_active->dev, ha->addr);
-		bond_resend_igmp_join_requests(bond);
+
+		/* rejoin multicast groups */
+		bond->resend_igmp = 3;
+		mod_timer(&bond->mc_timer, jiffies + 1);
 	}
 }
 
@@ -3741,9 +3776,15 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count)
 static int bond_open(struct net_device *bond_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
+	struct timer_list *mc_timer = &bond->mc_timer;
 
 	bond->kill_timers = 0;
 
+	/* multicast */
+	init_timer(mc_timer);
+	mc_timer->data = (unsigned long)bond;
+	mc_timer->function = (void *)&bond_resend_igmp_join_requests;
+
 	if (bond_is_lb(bond)) {
 		/* bond_alb_initialize must be called before the timer
 		 * is started.
@@ -3808,6 +3849,8 @@ static int bond_close(struct net_device *bond_dev)
 
 	write_unlock_bh(&bond->lock);
 
+	del_timer_sync(&bond->mc_timer);
+
 	if (bond->params.miimon) {  /* link check interval, in milliseconds. */
 		cancel_delayed_work(&bond->mii_work);
 	}
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index c6fdd85..5fd4164 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -198,6 +198,8 @@ struct bonding {
 	s32      slave_cnt; /* never change this value outside the attach/detach wrappers */
 	rwlock_t lock;
 	rwlock_t curr_slave_lock;
+	struct   timer_list mc_timer;
+	s8       resend_igmp;
 	s8       kill_timers;
 	s8	 send_grat_arp;
 	s8	 send_unsol_na;
-- 
1.7.2.3


             reply	other threads:[~2010-09-29  7:12 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-29  7:12 Flavio Leitner [this message]
2010-09-29 13:17 ` [PATCH] bonding: rejoin multicast groups on VLANs Flavio Leitner
2010-09-30 20:45   ` [PATCH v2] " Flavio Leitner
2010-10-04 13:24     ` Andy Gospodarek
2010-10-05 22:07       ` Flavio Leitner
2010-10-06  0:23         ` [PATCH 1/3] " Flavio Leitner
2010-10-06  3:28           ` David Miller
2010-10-06 12:12             ` Andy Gospodarek
2010-10-06  0:23         ` [PATCH 2/3] bonding: fix to rejoin multicast groups immediately Flavio Leitner
2010-10-06  3:28           ` David Miller
2010-10-06  0:23         ` [PATCH 3/3] bonding: add retransmit membership reports tunable Flavio Leitner
2010-10-06  3:29           ` David Miller
2010-09-30 20:46   ` [PATCH] " Flavio Leitner
2010-09-29 18:44 ` [PATCH] bonding: rejoin multicast groups on VLANs Andy Gospodarek
2010-09-29 19:35   ` Flavio Leitner
2010-09-29 19:54     ` Andy Gospodarek
2010-09-29 20:38       ` Flavio Leitner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1285744344-1231-1-git-send-email-fleitner@redhat.com \
    --to=fleitner@redhat.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.