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?>