Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 Feb 2007 00:34:54 +0000
From:      "Bruce M. Simpson" <bms@FreeBSD.org>
To:        Jouke Witteveen <j.witteveen@gmail.com>
Cc:        freebsd-net@freebsd.org
Subject:   Re: ioctl: SIOCADDMULTI (howto?)
Message-ID:  <45DB93AE.7030804@FreeBSD.org>
In-Reply-To: <3993a4980702170546t7f9384eaq358986a4cc734582@mail.gmail.com>
References:  <3993a4980702051233u10c30575kd1f6d27fcd600110@mail.gmail.com>	<45C7A1F9.20306@FreeBSD.org> <3993a4980702170546t7f9384eaq358986a4cc734582@mail.gmail.com>

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

Jouke Witteveen wrote:
>
> I hope someone can find a spare minute to look at if_findmulti. It
> would help me quite much.
I verified with mtest that FreeBSD cannot delete an AF_LINK multicast 
membership, reproduced with both 7-CURRENT and 6.2-RELEASE.

if_findmulti() appears to be doing a possibly incorrect comparison.
sa_equal() is not valid for use with AF_LINK in some cases, as 
sockaddr_dl has deeper structure than a simple array of bytes.

Thanks for finding this bug -- it would have affected XORP's IS-IS 
implementation further on in time.

Further testing would be appreciated. If the fix is good I will merge, 
though it should perhaps be a more general fix for sa_equal().

BMS

--------------000101000609080301020806
Content-Type: text/x-patch;
 name="ethermcast.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="ethermcast.diff"

Index: src/sys/net/if.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if.c,v
retrieving revision 1.265
diff -u -p -r1.265 if.c
--- src/sys/net/if.c	30 Nov 2006 15:02:01 -0000	1.265
+++ src/sys/net/if.c	21 Feb 2007 00:34:12 -0000
@@ -2123,8 +2123,16 @@ if_findmulti(struct ifnet *ifp, struct s
 	IF_ADDR_LOCK_ASSERT(ifp);
 
 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
-		if (sa_equal(ifma->ifma_addr, sa))
-			break;
+		if (sa->sa_family == AF_LINK) {
+			struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
+
+			if (bcmp(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
+			    LLADDR(sdl), sdl->sdl_alen) == 0)
+				break;
+		} else {
+			if (sa_equal(ifma->ifma_addr, sa))
+				break;
+		}
 	}
 
 	return ifma;

--------------000101000609080301020806--



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