Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 09 Sep 2009 03:37:35 -0000
From:      Stef Walter <stef-list@memberwebs.com>
To:        "freebsd-net@FreeBSD.org" <freebsd-net@freebsd.org>
Subject:   [patch] Multicast: IP_DROP_MEMBERSHIP should return EADDRNOTAVAIL for invalid address
Resent-Message-ID: <none>

| raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------040206040408060908060700
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

After an interface goes down and its addresses go away, if a caller
calls setsockopt/IP_DROP_MEMBERSHIP with a simple in_mreq input
containing the address that no longer exists, the kernel should return
EADDRNOTAVAIL.

However the current behavior in 8.0-BETA3 is to remove a membership to
the same multicast group from the 'first' interface instead. You can see
the results below in the ifmcstat output below.

Before northstar1 (tunnel) interface goes away, both bge0 and northstar1
 are on the 224.0.0.5 (ie: OSPF-ALL.MCAST.NET) group.

> bge0:
> 	inet 172.27.5.18
> 	igmpv3 flags=0<> rv 2 qi 125 qri 10 uri 3
> 		group 224.0.0.5 mode exclude
> 			mcast-macaddr 01:00:5e:00:00:05
> 		group 224.0.0.1 mode exclude
> 			mcast-macaddr 01:00:5e:00:00:01
> rl0:
> 	inet 192.168.1.70
> 	igmpv3 flags=0<> rv 2 qi 125 qri 10 uri 3
> 		group 224.0.0.1 mode exclude
> 			mcast-macaddr 01:00:5e:00:00:01
> lo0:
> 	inet 127.0.0.1
> 	igmpv3 flags=0<> rv 2 qi 125 qri 10 uri 3
> 		group 224.0.0.1 mode exclude
> 	inet6 fe80::1%lo0
> 	mldv2 flags=0<> rv 2 qi 125 qri 10 uri 3
> 		group ff01::1%lo0 mode exclude
> 		group ff02::2:e78c:f513%lo0 mode exclude
> 		group ff02::1%lo0 mode exclude
> 		group ff02::1:ff00:1%lo0 mode exclude
> northstar1:
> 	inet 172.28.1.66
> 	igmpv3 flags=0<> rv 2 qi 125 qri 10 uri 3
> 		group 224.0.0.5 mode exclude
> 		group 224.0.0.1 mode exclude

After northstar1 goes down, and setsockopt(..., IP_DROP_MEMBERSHIP, ...)
is called for the 172.28.1.66 address, we see that the group has been
dropped from bge0 instead. No error was returned from setsockopt.

> bge0:
> 	inet 172.27.5.18
> 	igmpv3 flags=0<> rv 2 qi 125 qri 10 uri 3
> 		group 224.0.0.1 mode exclude
> 			mcast-macaddr 01:00:5e:00:00:01
> rl0:
> 	inet 192.168.1.70
> 	igmpv3 flags=0<> rv 2 qi 125 qri 10 uri 3
> 		group 224.0.0.1 mode exclude
> 			mcast-macaddr 01:00:5e:00:00:01
> lo0:
> 	inet 127.0.0.1
> 	igmpv3 flags=0<> rv 2 qi 125 qri 10 uri 3
> 		group 224.0.0.1 mode exclude
> 	inet6 fe80::1%lo0
> 	mldv2 flags=0<> rv 2 qi 125 qri 10 uri 3
> 		group ff01::1%lo0 mode exclude
> 		group ff02::2:e78c:f513%lo0 mode exclude
> 		group ff02::1%lo0 mode exclude
> 		group ff02::1:ff00:1%lo0 mode exclude
> northstar1:

UNAME: FreeBSD portillo-gate.ws.local 8.0-BETA3 FreeBSD 8.0-BETA3 #19:
Wed Sep  9 01:27:39 UTC 2009
root@portillo-gate.ws.local:/usr/src/sys/i386/compile/PORTILLO  i386

Patch is attached which fixes the problem. Is this the right approach?

BTW, the behavior of FreeBSD has always been that after northstar1 comes
back up with the same address, it is a member of 224.0.0.5 group.
Memberships are retained across interfaces and addresses going away. Not
sure if this is the best behavior, but it has been the historical
behavior. One can see people coding against this in routing software [2].

Besides fixing the problem of dropping membership on the first
interface, the effect of this patch is to restore the previous freebsd
behavior.

Cheers,

Stef

PS: BTW, I've been using the patch [1] for the imo_match_source panic,
that Shteryana posted. That fixes problems calling IP_ADD_MEMBERSHIP
twice with the same info.

[1] http://people.freebsd.org/~syrinx/mcast/in_mcast.c-20090908-01.diff

[2]
http://code.quagga.net/cgi-bin/gitweb.cgi?p=quagga.git;a=blob;f=lib/sockopt.c;h=55c6226b711e6386ef0378eb6def992af281082e;hb=HEAD#l196



--------------040206040408060908060700
Content-Type: text/x-diff;
 name="freebsd-mcast-drop-eaddrnotavail.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="freebsd-mcast-drop-eaddrnotavail.patch"

--- sys/netinet/in_mcast.c.orig	2009-08-03 08:13:06.000000000 +0000
+++ sys/netinet/in_mcast.c	2009-09-09 01:35:06.000000000 +0000
@@ -2139,6 +2143,9 @@
 		}
 
-		if (!in_nullhost(gsa->sin.sin_addr))
+		if (!in_nullhost(gsa->sin.sin_addr)) {
 			INADDR_TO_IFP(mreqs.imr_interface, ifp);
+			if (ifp == NULL)
+				return (EADDRNOTAVAIL);
+		}
 
 		CTR3(KTR_IGMPV3, "%s: imr_interface = %s, ifp = %p",


--------------040206040408060908060700--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?>