Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Mar 2011 14:38:31 +0900
From:      Hajimu UMEMOTO <ume@mahoroba.org>
To:        Carl Johnson <carlj@peak.org>
Cc:        freebsd-stable@freebsd.org
Subject:   Re: if_bridge and IPv6
Message-ID:  <yge4o7afc88.wl%ume@mahoroba.org>
In-Reply-To: <87oc5i5j5n.fsf@oak.localnet>
References:  <FAF0B5E9-029E-4345-BFC4-98C0DFF505CC@gsoft.com.au>	<87oc5i5j5n.fsf@oak.localnet>

next in thread | previous in thread | raw e-mail | index | archive | help
--Multipart_Fri_Mar_11_14:38:28_2011-1
Content-Type: text/plain; charset=US-ASCII

Hi,

>>>>> On Thu, 10 Mar 2011 21:19:00 -0800
>>>>> Carl Johnson <carlj@peak.org> said:

carlj> You should be able to do something like the following:

carlj>   ifconfig bridge0 inet6 fe80:: eui64 add

carlj> That assumes that it has a MAC address already assigned.  I can't help
carlj> if it doesn't have one yet.

Unfortunately, eui64 option doesn't support link-local address.
You need to specify link-local address, explicitly.
Here is a patch to support it.

Sincerely,


--Multipart_Fri_Mar_11_14:38:28_2011-1
Content-Type: text/x-patch; type=patch; charset=US-ASCII
Content-Disposition: attachment; filename="ifconfig-af_inet6.c-linklocal.diff"
Content-Transfer-Encoding: 7bit

Index: sbin/ifconfig/af_inet6.c
diff -u -p sbin/ifconfig/af_inet6.c.orig sbin/ifconfig/af_inet6.c
--- sbin/ifconfig/af_inet6.c.orig	2009-11-21 20:28:57.783110487 +0900
+++ sbin/ifconfig/af_inet6.c	2009-11-23 21:00:02.212252557 +0900
@@ -36,6 +36,9 @@ static const char rcsid[] =
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/ethernet.h>
 
 #include <err.h>
 #include <stdio.h>
@@ -130,6 +133,56 @@ setip6vltime(const char *seconds, int du
 	setip6lifetime("vltime", seconds, s, afp);
 }
 
+static struct sockaddr_dl *
+getsdl(struct ifaddrs *ifap, char *ifname)
+{
+	struct ifaddrs *ifa;
+	struct sockaddr_dl *sdl = NULL;
+
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+		if (ifname != NULL && strcmp(ifa->ifa_name, ifname) != 0)
+			continue;
+		if (ifa->ifa_addr == NULL)
+			continue;
+		if (ifa->ifa_addr->sa_family != AF_LINK)
+			continue;
+		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+		if (sdl == NULL)
+			continue;
+		if (sdl->sdl_type != IFT_ETHER ||
+		    sdl->sdl_alen != ETHER_ADDR_LEN) {
+			sdl = NULL;
+			continue;
+		}
+		break;
+	}
+	return (sdl);
+}
+
+static void
+link2eui64(struct ifaddrs *ifap, struct in6_addr *in6)
+{
+	struct sockaddr_dl *sdl;
+	char *cp;
+
+	sdl = getsdl(ifap, name);
+	if (sdl == NULL) {
+		sdl = getsdl(ifap, NULL);
+		if (sdl == NULL)
+			errx(EXIT_FAILURE, "cannot find interface information");
+	}
+	cp = (char *)(sdl->sdl_data + sdl->sdl_nlen);
+	in6->s6_addr[8] = cp[0];
+	in6->s6_addr[8] ^= 0x02;		/* reverse the u/l bit*/
+	in6->s6_addr[9] = cp[1];
+	in6->s6_addr[10] = cp[2];
+	in6->s6_addr[11] = 0xff;
+	in6->s6_addr[12] = 0xfe;
+	in6->s6_addr[13] = cp[3];
+	in6->s6_addr[14] = cp[4];
+	in6->s6_addr[15] = cp[5];
+}
+
 static void
 setip6eui64(const char *cmd, int dummy __unused, int s,
     const struct afswtch *afp)
@@ -156,10 +209,13 @@ setip6eui64(const char *cmd, int dummy _
 			}
 		}
 	}
-	if (!lladdr)
-		errx(EXIT_FAILURE, "could not determine link local address"); 
-
- 	memcpy(&in6->s6_addr[8], &lladdr->s6_addr[8], 8);
+	if (!lladdr) {
+		if (!IN6_IS_ADDR_LINKLOCAL(in6))
+			errx(EXIT_FAILURE,
+			    "could not determine link local address");
+		link2eui64(ifap, in6);
+	} else
+		memcpy(&in6->s6_addr[8], &lladdr->s6_addr[8], 8);
 
 	freeifaddrs(ifap);
 }

--Multipart_Fri_Mar_11_14:38:28_2011-1
Content-Type: text/plain; charset=US-ASCII


--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume@mahoroba.org  ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/

--Multipart_Fri_Mar_11_14:38:28_2011-1--



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