netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] fix IGMPv3 timer initialization when device not "upped"
@ 2004-03-31  0:13 David Stevens
  2004-03-31  3:25 ` David S. Miller
  0 siblings, 1 reply; 4+ messages in thread
From: David Stevens @ 2004-03-31  0:13 UTC (permalink / raw)
  To: davem, netdev


[-- Attachment #1.1: Type: text/plain, Size: 3318 bytes --]





The patch below creates a new "ip_mc_init_dev()" that has complementary
function to "ip_mc_destroy_dev()", and moves timer and lock initialization
to
it rather than trying to determine when a device is up, coming up, down or
going down based on idev->dead (not set before device up, but set on
device going down) or IFF_UP (not set on mc_down).

With this patch, multicast initialization is always done at device
initialization
and has nothing to do with up/down state. This should eliminate the timer
queue corruption and (I think) make the code easier to understand. This
patch also removes the "mc_initted" flag, which is no longer needed. Patch
is relative to 2.6.5-rc3 ; 2.4.x version to follow.

Thanks to Karlis Peisenieks, who original reported the problem and pointed
out flaws in the original fix.

                                    +-DLS

diff -ruN linux-2.6.5-rc3/include/linux/inetdevice.h linux-2.6.5-rc3F1/include/linux/inetdevice.h
--- linux-2.6.5-rc3/include/linux/inetdevice.h  2004-03-30 12:27:29.000000000 -0800
+++ linux-2.6.5-rc3F1/include/linux/inetdevice.h      2004-03-30 14:08:50.000000000 -0800
@@ -36,8 +36,6 @@
      rwlock_t          lock;
      int               dead;
      struct in_ifaddr  *ifa_list;  /* IP ifaddr chain            */
-     int               mc_initted;
-
      struct ip_mc_list *mc_list;   /* IP multicast filter chain    */
      rwlock_t          mc_lock;    /* for mc_tomb */
      struct ip_mc_list *mc_tomb;
diff -ruN linux-2.6.5-rc3/net/ipv4/devinet.c linux-2.6.5-rc3F1/net/ipv4/devinet.c
--- linux-2.6.5-rc3/net/ipv4/devinet.c    2004-03-10 18:55:23.000000000 -0800
+++ linux-2.6.5-rc3F1/net/ipv4/devinet.c  2004-03-30 14:09:46.000000000 -0800
@@ -165,6 +165,7 @@
 #ifdef CONFIG_SYSCTL
      devinet_sysctl_register(in_dev, &in_dev->cnf);
 #endif
+     ip_mc_init_dev(in_dev);
      if (dev->flags & IFF_UP)
            ip_mc_up(in_dev);
 out:
diff -ruN linux-2.6.5-rc3/net/ipv4/igmp.c linux-2.6.5-rc3F1/net/ipv4/igmp.c
--- linux-2.6.5-rc3/net/ipv4/igmp.c 2004-03-30 12:27:30.000000000 -0800
+++ linux-2.6.5-rc3F1/net/ipv4/igmp.c     2004-03-30 15:53:28.000000000 -0800
@@ -1217,8 +1217,8 @@

      ASSERT_RTNL();

-     if (!in_dev->mc_initted)
-           return;
+     for (i=in_dev->mc_list; i; i=i->next)
+           igmp_group_dropped(i);

 #ifdef CONFIG_IP_MULTICAST
      in_dev->mr_ifc_count = 0;
@@ -1227,24 +1227,14 @@
      in_dev->mr_gq_running = 0;
      if (del_timer(&in_dev->mr_gq_timer))
            __in_dev_put(in_dev);
-#endif
-
-     for (i=in_dev->mc_list; i; i=i->next)
-           igmp_group_dropped(i);
-
-#ifdef CONFIG_IP_MULTICAST
      igmpv3_clear_delrec(in_dev);
 #endif

      ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS);
 }

-/* Device going up */
-
-void ip_mc_up(struct in_device *in_dev)
+void ip_mc_init_dev(struct in_device *in_dev)
 {
-     struct ip_mc_list *i;
-
      ASSERT_RTNL();

      in_dev->mc_tomb = 0;
@@ -1261,12 +1251,20 @@
 #endif

      in_dev->mc_lock = RW_LOCK_UNLOCKED;
+}
+
+/* Device going up */
+
+void ip_mc_up(struct in_device *in_dev)
+{
+     struct ip_mc_list *i;
+
+     ASSERT_RTNL();
+
      ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);

      for (i=in_dev->mc_list; i; i=i->next)
            igmp_group_added(i);
-
-     in_dev->mc_initted = 1;
 }

 /*

(See attached file: igmpinit.patch)

[-- Attachment #1.2: Type: text/html, Size: 3600 bytes --]

[-- Attachment #2: igmpinit.patch --]
[-- Type: application/octet-stream, Size: 2198 bytes --]

diff -ruN linux-2.6.5-rc3/include/linux/inetdevice.h linux-2.6.5-rc3F1/include/linux/inetdevice.h
--- linux-2.6.5-rc3/include/linux/inetdevice.h	2004-03-30 12:27:29.000000000 -0800
+++ linux-2.6.5-rc3F1/include/linux/inetdevice.h	2004-03-30 14:08:50.000000000 -0800
@@ -36,8 +36,6 @@
 	rwlock_t		lock;
 	int			dead;
 	struct in_ifaddr	*ifa_list;	/* IP ifaddr chain		*/
-	int			mc_initted;
-
 	struct ip_mc_list	*mc_list;	/* IP multicast filter chain    */
 	rwlock_t		mc_lock;	/* for mc_tomb */
 	struct ip_mc_list	*mc_tomb;
diff -ruN linux-2.6.5-rc3/net/ipv4/devinet.c linux-2.6.5-rc3F1/net/ipv4/devinet.c
--- linux-2.6.5-rc3/net/ipv4/devinet.c	2004-03-10 18:55:23.000000000 -0800
+++ linux-2.6.5-rc3F1/net/ipv4/devinet.c	2004-03-30 14:09:46.000000000 -0800
@@ -165,6 +165,7 @@
 #ifdef CONFIG_SYSCTL
 	devinet_sysctl_register(in_dev, &in_dev->cnf);
 #endif
+	ip_mc_init_dev(in_dev);
 	if (dev->flags & IFF_UP)
 		ip_mc_up(in_dev);
 out:
diff -ruN linux-2.6.5-rc3/net/ipv4/igmp.c linux-2.6.5-rc3F1/net/ipv4/igmp.c
--- linux-2.6.5-rc3/net/ipv4/igmp.c	2004-03-30 12:27:30.000000000 -0800
+++ linux-2.6.5-rc3F1/net/ipv4/igmp.c	2004-03-30 15:53:28.000000000 -0800
@@ -1217,8 +1217,8 @@
 
 	ASSERT_RTNL();
 
-	if (!in_dev->mc_initted)
-		return;
+	for (i=in_dev->mc_list; i; i=i->next)
+		igmp_group_dropped(i);
 
 #ifdef CONFIG_IP_MULTICAST
 	in_dev->mr_ifc_count = 0;
@@ -1227,24 +1227,14 @@
 	in_dev->mr_gq_running = 0;
 	if (del_timer(&in_dev->mr_gq_timer))
 		__in_dev_put(in_dev);
-#endif
-
-	for (i=in_dev->mc_list; i; i=i->next)
-		igmp_group_dropped(i);
-
-#ifdef CONFIG_IP_MULTICAST
 	igmpv3_clear_delrec(in_dev);
 #endif
 
 	ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS);
 }
 
-/* Device going up */
-
-void ip_mc_up(struct in_device *in_dev)
+void ip_mc_init_dev(struct in_device *in_dev)
 {
-	struct ip_mc_list *i;
-
 	ASSERT_RTNL();
 
 	in_dev->mc_tomb = 0;
@@ -1261,12 +1251,20 @@
 #endif
 
 	in_dev->mc_lock = RW_LOCK_UNLOCKED;
+}
+
+/* Device going up */
+
+void ip_mc_up(struct in_device *in_dev)
+{
+	struct ip_mc_list *i;
+
+	ASSERT_RTNL();
+
 	ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);
 
 	for (i=in_dev->mc_list; i; i=i->next)
 		igmp_group_added(i);
-
-	in_dev->mc_initted = 1;
 }
 
 /*

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] fix IGMPv3 timer initialization when device not "upped"
  2004-03-31  0:13 [PATCH] fix IGMPv3 timer initialization when device not "upped" David Stevens
@ 2004-03-31  3:25 ` David S. Miller
  2004-04-01  6:10   ` David Stevens
  0 siblings, 1 reply; 4+ messages in thread
From: David S. Miller @ 2004-03-31  3:25 UTC (permalink / raw)
  To: David Stevens; +Cc: netdev


Applied, thanks David.  Can I have a 2.4.x variant under seperate
cover please?  I did the "mc_initted" thing there too.

Thanks again.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] fix IGMPv3 timer initialization when device not "upped"
  2004-03-31  3:25 ` David S. Miller
@ 2004-04-01  6:10   ` David Stevens
  2004-04-01  7:02     ` David S. Miller
  0 siblings, 1 reply; 4+ messages in thread
From: David Stevens @ 2004-04-01  6:10 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev


[-- Attachment #1.1: Type: text/plain, Size: 2804 bytes --]







netdev-bounce@oss.sgi.com wrote on 03/30/2004 07:25:58 PM:

> Applied, thanks David.  Can I have a 2.4.x variant under seperate
> cover please?  I did the "mc_initted" thing there too.

Dave,
      Here's a 2.4.x version of the patch.

                        +-DLS

diff -ruN linux-2.4.26-rc1/include/linux/inetdevice.h
linux-2.4.26-rc1F1/include/linux/inetdevice.h
--- linux-2.4.26-rc1/include/linux/inetdevice.h 2004-03-30
16:28:38.000000000 -0800
+++ linux-2.4.26-rc1F1/include/linux/inetdevice.h     2004-03-31
19:33:34.000000000 -0800
@@ -34,8 +34,6 @@
      rwlock_t          lock;
      int               dead;
      struct in_ifaddr  *ifa_list;  /* IP ifaddr chain            */
-     int               mc_initted;
-
      struct ip_mc_list *mc_list;   /* IP multicast filter chain    */
      rwlock_t          mc_lock;    /* for mc_tomb */
      struct ip_mc_list *mc_tomb;
diff -ruN linux-2.4.26-rc1/net/ipv4/devinet.c
linux-2.4.26-rc1F1/net/ipv4/devinet.c
--- linux-2.4.26-rc1/net/ipv4/devinet.c   2004-03-30 16:28:39.000000000
-0800
+++ linux-2.4.26-rc1F1/net/ipv4/devinet.c 2004-03-31 19:35:38.000000000
-0800
@@ -151,7 +151,8 @@
 #ifdef CONFIG_SYSCTL
      devinet_sysctl_register(in_dev, &in_dev->cnf);
 #endif
-     if (dev->flags&IFF_UP)
+     ip_mc_init_dev(in_dev);
+     if (dev->flags & IFF_UP)
            ip_mc_up(in_dev);
      return in_dev;
 }
diff -ruN linux-2.4.26-rc1/net/ipv4/igmp.c
linux-2.4.26-rc1F1/net/ipv4/igmp.c
--- linux-2.4.26-rc1/net/ipv4/igmp.c      2004-03-30 16:28:39.000000000 -0800
+++ linux-2.4.26-rc1F1/net/ipv4/igmp.c    2004-03-31 19:33:34.000000000 -0800
@@ -1205,8 +1205,8 @@

      ASSERT_RTNL();

-     if (!in_dev->mc_initted)
-           return;
+     for (i=in_dev->mc_list; i; i=i->next)
+           igmp_group_dropped(i);

 #ifdef CONFIG_IP_MULTICAST
      in_dev->mr_ifc_count = 0;
@@ -1215,24 +1215,14 @@
      in_dev->mr_gq_running = 0;
      if (del_timer(&in_dev->mr_gq_timer))
            __in_dev_put(in_dev);
-#endif
-
-     for (i=in_dev->mc_list; i; i=i->next)
-           igmp_group_dropped(i);
-
-#ifdef CONFIG_IP_MULTICAST
      igmpv3_clear_delrec(in_dev);
 #endif

      ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS);
 }

-/* Device going up */
-
-void ip_mc_up(struct in_device *in_dev)
+void ip_mc_init_dev(struct in_device *in_dev)
 {
-     struct ip_mc_list *i;
-
      ASSERT_RTNL();

      in_dev->mc_tomb = 0;
@@ -1249,12 +1239,20 @@
 #endif

      in_dev->mc_lock = RW_LOCK_UNLOCKED;
+}
+
+/* Device going up */
+
+void ip_mc_up(struct in_device *in_dev)
+{
+     struct ip_mc_list *i;
+
+     ASSERT_RTNL();
+
      ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);

      for (i=in_dev->mc_list; i; i=i->next)
            igmp_group_added(i);
-
-     in_dev->mc_initted = 1;
 }

 /*
(See attached file: 2.4.26-rc1-igmpinit.patch)

[-- Attachment #1.2: Type: text/html, Size: 3144 bytes --]

[-- Attachment #2: 2.4.26-rc1-igmpinit.patch --]
[-- Type: application/octet-stream, Size: 2249 bytes --]

diff -ruN linux-2.4.26-rc1/include/linux/inetdevice.h linux-2.4.26-rc1F1/include/linux/inetdevice.h
--- linux-2.4.26-rc1/include/linux/inetdevice.h	2004-03-30 16:28:38.000000000 -0800
+++ linux-2.4.26-rc1F1/include/linux/inetdevice.h	2004-03-31 19:33:34.000000000 -0800
@@ -34,8 +34,6 @@
 	rwlock_t		lock;
 	int			dead;
 	struct in_ifaddr	*ifa_list;	/* IP ifaddr chain		*/
-	int			mc_initted;
-
 	struct ip_mc_list	*mc_list;	/* IP multicast filter chain    */
 	rwlock_t		mc_lock;	/* for mc_tomb */
 	struct ip_mc_list	*mc_tomb;
diff -ruN linux-2.4.26-rc1/net/ipv4/devinet.c linux-2.4.26-rc1F1/net/ipv4/devinet.c
--- linux-2.4.26-rc1/net/ipv4/devinet.c	2004-03-30 16:28:39.000000000 -0800
+++ linux-2.4.26-rc1F1/net/ipv4/devinet.c	2004-03-31 19:35:38.000000000 -0800
@@ -151,7 +151,8 @@
 #ifdef CONFIG_SYSCTL
 	devinet_sysctl_register(in_dev, &in_dev->cnf);
 #endif
-	if (dev->flags&IFF_UP)
+	ip_mc_init_dev(in_dev);
+	if (dev->flags & IFF_UP)
 		ip_mc_up(in_dev);
 	return in_dev;
 }
diff -ruN linux-2.4.26-rc1/net/ipv4/igmp.c linux-2.4.26-rc1F1/net/ipv4/igmp.c
--- linux-2.4.26-rc1/net/ipv4/igmp.c	2004-03-30 16:28:39.000000000 -0800
+++ linux-2.4.26-rc1F1/net/ipv4/igmp.c	2004-03-31 19:33:34.000000000 -0800
@@ -1205,8 +1205,8 @@
 
 	ASSERT_RTNL();
 
-	if (!in_dev->mc_initted)
-		return;
+	for (i=in_dev->mc_list; i; i=i->next)
+		igmp_group_dropped(i);
 
 #ifdef CONFIG_IP_MULTICAST
 	in_dev->mr_ifc_count = 0;
@@ -1215,24 +1215,14 @@
 	in_dev->mr_gq_running = 0;
 	if (del_timer(&in_dev->mr_gq_timer))
 		__in_dev_put(in_dev);
-#endif
-
-	for (i=in_dev->mc_list; i; i=i->next)
-		igmp_group_dropped(i);
-
-#ifdef CONFIG_IP_MULTICAST
 	igmpv3_clear_delrec(in_dev);
 #endif
 
 	ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS);
 }
 
-/* Device going up */
-
-void ip_mc_up(struct in_device *in_dev)
+void ip_mc_init_dev(struct in_device *in_dev)
 {
-	struct ip_mc_list *i;
-
 	ASSERT_RTNL();
 
 	in_dev->mc_tomb = 0;
@@ -1249,12 +1239,20 @@
 #endif
 
 	in_dev->mc_lock = RW_LOCK_UNLOCKED;
+}
+
+/* Device going up */
+
+void ip_mc_up(struct in_device *in_dev)
+{
+	struct ip_mc_list *i;
+
+	ASSERT_RTNL();
+
 	ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);
 
 	for (i=in_dev->mc_list; i; i=i->next)
 		igmp_group_added(i);
-
-	in_dev->mc_initted = 1;
 }
 
 /*

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] fix IGMPv3 timer initialization when device not "upped"
  2004-04-01  6:10   ` David Stevens
@ 2004-04-01  7:02     ` David S. Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David S. Miller @ 2004-04-01  7:02 UTC (permalink / raw)
  To: David Stevens; +Cc: netdev

On Wed, 31 Mar 2004 23:10:22 -0700
David Stevens <dlstevens@us.ibm.com> wrote:

> netdev-bounce@oss.sgi.com wrote on 03/30/2004 07:25:58 PM:
> 
> > Applied, thanks David.  Can I have a 2.4.x variant under seperate
> > cover please?  I did the "mc_initted" thing there too.
> 
> Dave,
>       Here's a 2.4.x version of the patch.

Applied, thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-04-01  7:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-31  0:13 [PATCH] fix IGMPv3 timer initialization when device not "upped" David Stevens
2004-03-31  3:25 ` David S. Miller
2004-04-01  6:10   ` David Stevens
2004-04-01  7:02     ` David S. Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).