Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Jun 2004 04:06:44 +0900 (JST)
From:      HASHI Hiroaki <hashiz@tomba.cskk-sv.co.jp>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/67544: udav(4) driver does not receive multicast packets
Message-ID:  <200406031906.i53J6iJi001147@tomba.cskk-sv.co.jp>
Resent-Message-ID: <200406031910.i53JAOcE026252@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         67544
>Category:       kern
>Synopsis:       udav(4) driver does not receive multicast packets
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jun 03 12:10:23 PDT 2004
>Closed-Date:
>Last-Modified:
>Originator:     HASHI Hiroaki
>Release:        FreeBSD 5.2-CURRENT i386
>Organization:
>Environment:
System: FreeBSD tomba.cskk-sv.co.jp 5.2-CURRENT FreeBSD 5.2-CURRENT #1: Sat May 29 17:17:07 JST 2004 hashiz@tomba.cskk-sv.co.jp:/usr/obj/home/sources/src/sys/TOMBA i386


>Description:
	udav(4) driver does not receive multicast packets.
	cf. IPv6 Neighbor solicitation packet.
>How-To-Repeat:
	Enable IPv6 stack. And assign global IPv6 Address to udav interface.
	Send ping6 to udav interface address from other host.(timed out)
>Fix:
	udav driver can not receive multicast packets.
	reason:incollect multicast hash calcurate.
	`udav_ether_crc32_le' function port from NetBSD's `ether_crc32_le'.

--- if_udav.c.1.4-patch-multicast begins here ---
Index: if_udav.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/if_udav.c,v
retrieving revision 1.4
diff -u -r1.4 if_udav.c
--- if_udav.c	30 May 2004 20:08:45 -0000	1.4
+++ if_udav.c	3 Jun 2004 17:15:25 -0000
@@ -986,27 +986,30 @@
 	(ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1))
 
 #elif defined(__FreeBSD__)
+#define UDAV_CALCHASH(addr) \
+	(udav_ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1))
+
 Static uint32_t
-udav_mchash(const uint8_t *addr)
+udav_ether_crc32_le(const uint8_t *buf, size_t len)
 {
-	uint32_t crc, carry;
-	int idx, bit;
-	uint8_t data;
-
-	/* Compute CRC for the address value. */
-	crc = 0xFFFFFFFF; /* initial value */
-
-	for (idx = 0; idx < 6; idx++) {
-		for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) {
-			carry = ((crc & 0x80000000) ? 1 : 0) ^ (data & 0x01);
-			crc <<= 1;
-			if (carry)
-				crc = (crc ^ 0x04c11db6) | carry;
-		}
+	static const u_int32_t crctab[] = {
+		0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
+		0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
+		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
+		0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
+	};
+	u_int32_t crc;
+	size_t i;
+
+	crc = 0xffffffffU;      /* initial value */
+
+	for (i = 0; i < len; i++) {
+		crc ^= buf[i];
+		crc = (crc >> 4) ^ crctab[crc & 0xf];
+		crc = (crc >> 4) ^ crctab[crc & 0xf];
 	}
 
-	/* return the filter bit position */
-	return((crc >> 26) & 0x0000003F);
+	return (crc);
 }
 #endif
 
@@ -1069,8 +1072,8 @@
 	{
 		if (ifma->ifma_addr->sa_family != AF_LINK)
 			continue;
-		h = udav_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
-		hashes[h / 8] |= 1 << (h % 8);
+		h = UDAV_CALCHASH(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
+		hashes[h>>3] |= 1 << (h & 0x7);
 	}
 #endif
 
@@ -1562,6 +1565,13 @@
 #endif
 
 	switch (cmd) {
+#if defined(__FreeBSD__)
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+		udav_setmulti(sc);
+		error = 0;
+		break;
+#endif
 	case SIOCGIFMEDIA:
 	case SIOCSIFMEDIA:
 		mii = GET_MII(sc);
--- if_udav.c.1.4-patch-multicast ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



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