[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#740509: ifconfig: ioctl(SIOCGIFINFO_IN6): No such device or address



Hi!

The attached patch is my best guess at how to fix this bug.  I'm still
testing it myself, but I'm sharing it now in case anyone else is able to
build glibc on kfreebsd-i386 and also help test.  (It can take many
hours to build glibc).

getifaddrs() uses a NET_RT_IFLIST sysctl to get back a struct rt_msghdr
followed by a struct sockaddr_dl.  From kfreebsd 9.0 -> 10.1, the
rt_msghdr seems to be 4 bytes larger on kfreebsd-i386 only (not on
kfreebsd-amd64, probably because there was some padding for alignment).

With the current build of glibc (based on outdated
kfreebsd-kernel-headers), ifconfig fails to get a list of interface
names on 10.1 kernels, but can still do that within a chroot on 9.0.

If glibc is rebuilt against latest kfreebsd-kernel-headers (>> 10.1~), I
think it works on 10.1 kernels, but stops working on kfreebsd-i386 9.0.

The buildds run kfreebsd 9.0, so I expect it would FTBFS when that
happens.  The attached patch uses rt_msghdr->ifm_msglen to guess the
running kernel version and accordingly, find the right place for the
struct sockaddr_dl.  I expect it will still work for the i386-on-amd64
compat case also.

Regards,
-- 
Steven Chamberlain
steven@pyro.eu.org
From: Steven Chamberlain <steven@pyro.eu.org>
Subject: getifaddrs: work around a kfreebsd 9.0 to 10.1 ABI break

--- a/ports/sysdeps/unix/bsd/bsd4.4/kfreebsd/ifaddrs.c	2014-10-21 01:19:18.000000000 +0000
+++ b/ports/sysdeps/unix/bsd/bsd4.4/kfreebsd/ifaddrs.c	2014-10-21 01:27:59.072736100 +0000
@@ -147,7 +147,13 @@
 			if (ifm->ifm_addrs & RTA_IFP) {
 				idx = ifm->ifm_index;
 				++icnt;
+				/* XXX: smooth over a kfreebsd 9.0->10.1 ABI break:
+				  sizeof(struct rt_msghdr) is correct for 10.1 kernel */
 				dl = (struct sockaddr_dl *)(void *)(ifm + 1);
+				if (rtm->rtm_msglen == 152) {
+					/* on kfreebsd-i386 9.0, struct rt_msghdr is 96 bytes */
+					dl = (struct sockaddr_dl *)((char *)ifm + 96);
+				}
 				dcnt += SA_RLEN((struct sockaddr *)(void*)dl) +
 				    ALIGNBYTES;
 #ifdef	HAVE_IFM_DATA
@@ -234,7 +240,13 @@
 			ifm = (struct if_msghdr *)(void *)rtm;
 			if (ifm->ifm_addrs & RTA_IFP) {
 				idx = ifm->ifm_index;
+				/* XXX: smooth over a kfreebsd 9.0->10.1 ABI break:
+				  sizeof(struct rt_msghdr) is correct for 10.1 kernel */
 				dl = (struct sockaddr_dl *)(void *)(ifm + 1);
+				if (rtm->rtm_msglen == 152) {
+					/* on kfreebsd-i386 9.0, struct rt_msghdr is 96 bytes */
+					dl = (struct sockaddr_dl *)((char *)ifm + 96);
+				}
 
 				cif = ift;
 				ift->ifa_name = names;

Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: