Hi,

>>>>> On Thu, 10 Mar 2011 21:19:00 -0800
>>>>> Carl Johnson <ca...@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,

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);
 }
--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
u...@mahoroba.org  ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/
_______________________________________________
freebsd-stable@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "freebsd-stable-unsubscr...@freebsd.org"

Reply via email to