Browse Source

Really ripngd should either leave groups on down interfaces, or keep
track of on which interfaces joins have occurred. This is complicated
by the possible lack of a clear behavior spec on whether interfaces
keep their joined group lists across a down/up/down transition. (On
NetBSD, they do.)

2004-01-03 Greg Troxel <gdt@ahi.ir.bbn.com>

* ripng_interface.c (ripng_multicast_join): If IPV6_JOIN_GROUP
returns EADDRINUSE, consider the join successful. This happens
when an interface goes down and comes back because
ripng_multicast_leave does not invoke the LEAVE_GROUP operation if
the interface is down. Solves problem of ripng stopping working
on an interface which goes down and then comes back up (on NetBSD).

gdt 18 years ago
parent
commit
ddf1c26ca3
2 changed files with 21 additions and 0 deletions
  1. 9 0
      ripngd/ChangeLog
  2. 12 0
      ripngd/ripng_interface.c

+ 9 - 0
ripngd/ChangeLog

@@ -1,3 +1,12 @@
+2004-01-03  Greg Troxel  <gdt@ahi.ir.bbn.com>
+
+	* ripng_interface.c (ripng_multicast_join): If IPV6_JOIN_GROUP
+	returns EADDRINUSE, consider the join successful.  This happens
+	when an interface goes down and comes back because
+	ripng_multicast_leave does not invoke the LEAVE_GROUP operation if
+	the interface is down.  Solves problem of ripng stopping working
+	on an interface which goes down and then comes back up (on NetBSD).
+
 2003-05-25 Hasso Tepper <hasso@estpak.ee>
   
   * Revert ripng_ifrmap stuff because ripd uses it now as well.

+ 12 - 0
ripngd/ripng_interface.c

@@ -67,6 +67,18 @@ ripng_multicast_join (struct interface *ifp)
 
     ret = setsockopt (ripng->sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
 		      (char *) &mreq, sizeof (mreq));
+
+    if (ret < 0 && errno == EADDRINUSE)
+      {
+	/*
+	 * Group is already joined.  This occurs due to sloppy group
+	 * management, in particular declining to leave the group on
+	 * an interface that has just gone down.
+	 */
+	zlog_warn ("ripng join on %s EADDRINUSE (ignoring)\n", ifp->name);
+	return 0;		/* not an error */
+      }
+
     if (ret < 0)
       zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", strerror (errno));