svn commit: r231506 - in head: . lib/libc/net

Bjoern A. Zeeb bz at FreeBSD.org
Sat Feb 11 06:05:41 UTC 2012


Author: bz
Date: Sat Feb 11 06:05:40 2012
New Revision: 231506
URL: http://svn.freebsd.org/changeset/base/231506

Log:
  Switch getifaddrs(3) to the new API introduced in r231505.  Also remove
  conditional code parts not used by or applicable to FreeBSD.
  
  The new implementation is supposed to be able to cope with changes to
  the 'l' versions of the msghdr structs now used as well as to if_data
  allowing future changes without breaking things.
  
  This restores carp(4) config support in HEAD after r231504.
  
  Reviewed by:	glebius, brooks
  MFC After:	3 months

Modified:
  head/UPDATING
  head/lib/libc/net/getifaddrs.c

Modified: head/UPDATING
==============================================================================
--- head/UPDATING	Sat Feb 11 06:02:16 2012	(r231505)
+++ head/UPDATING	Sat Feb 11 06:05:40 2012	(r231506)
@@ -22,6 +22,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10
 	machines to maximize performance.  (To disable malloc debugging, run
 	ln -s aj /etc/malloc.conf.)
 
+20120211:
+	The getifaddrs upgrade path broken with 20111215 has been restored.
+	If you have upgraded in between 20111215 and 20120209 you need to
+	recompile libc again with your kernel.  You still need to recompile
+	world to be able to configure CARP but this restriction already
+	comes from 20111215.
+
 20120114:
 	The set_rcvar() function has been removed from /etc/rc.subr.  All
 	base and ports rc.d scripts have been updated, so if you have a

Modified: head/lib/libc/net/getifaddrs.c
==============================================================================
--- head/lib/libc/net/getifaddrs.c	Sat Feb 11 06:02:16 2012	(r231505)
+++ head/lib/libc/net/getifaddrs.c	Sat Feb 11 06:05:40 2012	(r231506)
@@ -72,19 +72,6 @@ __FBSDID("$FreeBSD$");
 #define	ALIGN(p)	(((u_long)(p) + ALIGNBYTES) &~ ALIGNBYTES)
 #endif
 
-#if	_BSDI_VERSION >= 199701
-#define	HAVE_IFM_DATA
-#endif
-
-#if	_BSDI_VERSION >= 199802
-/* ifam_data is very specific to recent versions of bsdi */
-#define	HAVE_IFAM_DATA
-#endif
-
-#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
-#define	HAVE_IFM_DATA
-#endif
-
 #define MAX_SYSCTL_TRY 5
 
 int
@@ -93,7 +80,6 @@ getifaddrs(struct ifaddrs **pif)
 	int icnt = 1;
 	int dcnt = 0;
 	int ncnt = 0;
-#ifdef	NET_RT_IFLIST
 	int ntry = 0;
 	int mib[6];
 	size_t needed;
@@ -102,30 +88,23 @@ getifaddrs(struct ifaddrs **pif)
 	struct ifaddrs *cif = 0;
 	char *p, *p0;
 	struct rt_msghdr *rtm;
-	struct if_msghdr *ifm;
-	struct ifa_msghdr *ifam;
+	struct if_msghdrl *ifm;
+	struct ifa_msghdrl *ifam;
 	struct sockaddr_dl *dl;
 	struct sockaddr *sa;
 	struct ifaddrs *ifa, *ift;
+	struct if_data *if_data;
 	u_short idx = 0;
-#else	/* NET_RT_IFLIST */
-	char buf[1024];
-	int m, sock;
-	struct ifconf ifc;
-	struct ifreq *ifr;
-	struct ifreq *lifr;
-#endif	/* NET_RT_IFLIST */
 	int i;
 	size_t len, alen;
 	char *data;
 	char *names;
 
-#ifdef	NET_RT_IFLIST
 	mib[0] = CTL_NET;
 	mib[1] = PF_ROUTE;
 	mib[2] = 0;             /* protocol */
 	mib[3] = 0;             /* wildcard address family */
-	mib[4] = NET_RT_IFLIST;
+	mib[4] = NET_RT_IFLISTL;/* extra fields for extensible msghdr structs */
 	mib[5] = 0;             /* no flags */
 	do {
 		/*
@@ -159,34 +138,33 @@ getifaddrs(struct ifaddrs **pif)
 			continue;
 		switch (rtm->rtm_type) {
 		case RTM_IFINFO:
-			ifm = (struct if_msghdr *)(void *)rtm;
+			ifm = (struct if_msghdrl *)(void *)rtm;
 			if (ifm->ifm_addrs & RTA_IFP) {
 				idx = ifm->ifm_index;
 				++icnt;
-				dl = (struct sockaddr_dl *)(void *)(ifm + 1);
+				if_data = IF_MSGHDRL_IFM_DATA(ifm);
+				dcnt += if_data->ifi_datalen;
+				dl = (struct sockaddr_dl *)IF_MSGHDRL_RTA(ifm);
 				dcnt += SA_RLEN((struct sockaddr *)(void*)dl) +
 				    ALIGNBYTES;
-#ifdef	HAVE_IFM_DATA
-				dcnt += sizeof(ifm->ifm_data);
-#endif	/* HAVE_IFM_DATA */
 				ncnt += dl->sdl_nlen + 1;
 			} else
 				idx = 0;
 			break;
 
 		case RTM_NEWADDR:
-			ifam = (struct ifa_msghdr *)(void *)rtm;
+			ifam = (struct ifa_msghdrl *)(void *)rtm;
 			if (idx && ifam->ifam_index != idx)
 				abort();	/* this cannot happen */
 
 #define	RTA_MASKS	(RTA_NETMASK | RTA_IFA | RTA_BRD)
 			if (idx == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
 				break;
-			p = (char *)(void *)(ifam + 1);
+			p = (char *)IFA_MSGHDRL_RTA(ifam);
 			++icnt;
-#ifdef	HAVE_IFAM_DATA
-			dcnt += sizeof(ifam->ifam_data) + ALIGNBYTES;
-#endif	/* HAVE_IFAM_DATA */
+			if_data = IFA_MSGHDRL_IFAM_DATA(ifam);
+			dcnt += if_data->ifi_datalen + ALIGNBYTES;
+
 			/* Scan to look for length of address */
 			alen = 0;
 			for (p0 = p, i = 0; i < RTAX_MAX; i++) {
@@ -216,34 +194,6 @@ getifaddrs(struct ifaddrs **pif)
 			break;
 		}
 	}
-#else	/* NET_RT_IFLIST */
-	ifc.ifc_buf = buf;
-	ifc.ifc_len = sizeof(buf);
-
-	if ((sock = _socket(AF_INET, SOCK_STREAM, 0)) < 0)
-		return (-1);
-	i =  _ioctl(sock, SIOCGIFCONF, (char *)&ifc);
-	_close(sock);
-	if (i < 0)
-		return (-1);
-
-	ifr = ifc.ifc_req;
-	lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
-
-	while (ifr < lifr) {
-		struct sockaddr *sa;
-
-		sa = &ifr->ifr_addr;
-		++icnt;
-		dcnt += SA_RLEN(sa);
-		ncnt += sizeof(ifr->ifr_name) + 1;
-		
-		if (SA_LEN(sa) < sizeof(*sa))
-			ifr = (struct ifreq *)(((char *)sa) + sizeof(*sa));
-		else
-			ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa));
-	}
-#endif	/* NET_RT_IFLIST */
 
 	if (icnt + dcnt + ncnt == 1) {
 		*pif = NULL;
@@ -263,7 +213,6 @@ getifaddrs(struct ifaddrs **pif)
 	memset(ifa, 0, sizeof(struct ifaddrs) * icnt);
 	ift = ifa;
 
-#ifdef	NET_RT_IFLIST
 	idx = 0;
 	for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
 		rtm = (struct rt_msghdr *)(void *)next;
@@ -271,41 +220,38 @@ getifaddrs(struct ifaddrs **pif)
 			continue;
 		switch (rtm->rtm_type) {
 		case RTM_IFINFO:
-			ifm = (struct if_msghdr *)(void *)rtm;
-			if (ifm->ifm_addrs & RTA_IFP) {
-				idx = ifm->ifm_index;
-				dl = (struct sockaddr_dl *)(void *)(ifm + 1);
+			ifm = (struct if_msghdrl *)(void *)rtm;
+			if ((ifm->ifm_addrs & RTA_IFP) == 0) {
+				idx = 0;
+				break;
+			}
 
-				cif = ift;
-				ift->ifa_name = names;
-				ift->ifa_flags = (int)ifm->ifm_flags;
-				memcpy(names, dl->sdl_data,
-				    (size_t)dl->sdl_nlen);
-				names[dl->sdl_nlen] = 0;
-				names += dl->sdl_nlen + 1;
-
-				ift->ifa_addr = (struct sockaddr *)(void *)data;
-				memcpy(data, dl,
-				    (size_t)SA_LEN((struct sockaddr *)
-				    (void *)dl));
-				data += SA_RLEN((struct sockaddr *)(void *)dl);
-
-#ifdef	HAVE_IFM_DATA
-				/* ifm_data needs to be aligned */
-				ift->ifa_data = data = (void *)ALIGN(data);
-				memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data));
- 				data += sizeof(ifm->ifm_data);
-#else	/* HAVE_IFM_DATA */
-				ift->ifa_data = NULL;
-#endif	/* HAVE_IFM_DATA */
+			idx = ifm->ifm_index;
+			dl = (struct sockaddr_dl *)IF_MSGHDRL_RTA(ifm);
 
-				ift = (ift->ifa_next = ift + 1);
-			} else
-				idx = 0;
+			cif = ift;
+			ift->ifa_name = names;
+			ift->ifa_flags = (int)ifm->ifm_flags;
+			memcpy(names, dl->sdl_data, (size_t)dl->sdl_nlen);
+			names[dl->sdl_nlen] = 0;
+			names += dl->sdl_nlen + 1;
+
+			ift->ifa_addr = (struct sockaddr *)(void *)data;
+			memcpy(data, dl, (size_t)SA_LEN((struct sockaddr *)
+			    (void *)dl));
+			data += SA_RLEN((struct sockaddr *)(void *)dl);
+
+			if_data = IF_MSGHDRL_IFM_DATA(ifm);
+			/* ifm_data needs to be aligned */
+			ift->ifa_data = data = (void *)ALIGN(data);
+			memcpy(data, if_data, if_data->ifi_datalen);
+			data += if_data->ifi_datalen;
+
+			ift = (ift->ifa_next = ift + 1);
 			break;
 
 		case RTM_NEWADDR:
-			ifam = (struct ifa_msghdr *)(void *)rtm;
+			ifam = (struct ifa_msghdrl *)(void *)rtm;
 			if (idx && ifam->ifam_index != idx)
 				abort();	/* this cannot happen */
 
@@ -314,7 +260,8 @@ getifaddrs(struct ifaddrs **pif)
 			ift->ifa_name = cif->ifa_name;
 			ift->ifa_flags = cif->ifa_flags;
 			ift->ifa_data = NULL;
-			p = (char *)(void *)(ifam + 1);
+
+			p = (char *)IFA_MSGHDRL_RTA(ifam);
 			/* Scan to look for length of address */
 			alen = 0;
 			for (p0 = p, i = 0; i < RTAX_MAX; i++) {
@@ -365,12 +312,11 @@ getifaddrs(struct ifaddrs **pif)
 				p += len;
 			}
 
-#ifdef	HAVE_IFAM_DATA
+			if_data = IFA_MSGHDRL_IFAM_DATA(ifam);
 			/* ifam_data needs to be aligned */
 			ift->ifa_data = data = (void *)ALIGN(data);
-			memcpy(data, &ifam->ifam_data, sizeof(ifam->ifam_data));
-			data += sizeof(ifam->ifam_data);
-#endif	/* HAVE_IFAM_DATA */
+			memcpy(data, if_data, if_data->ifi_datalen);
+			data += if_data->ifi_datalen;
 
 			ift = (ift->ifa_next = ift + 1);
 			break;
@@ -378,28 +324,7 @@ getifaddrs(struct ifaddrs **pif)
 	}
 
 	free(buf);
-#else	/* NET_RT_IFLIST */
-	ifr = ifc.ifc_req;
-	lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
-
-	while (ifr < lifr) {
-		struct sockaddr *sa;
-
-		ift->ifa_name = names;
-		names[sizeof(ifr->ifr_name)] = 0;
-		strncpy(names, ifr->ifr_name, sizeof(ifr->ifr_name));
-		while (*names++)
-			;
-
-		ift->ifa_addr = (struct sockaddr *)data;
-		sa = &ifr->ifr_addr;
-		memcpy(data, sa, SA_LEN(sa));
-		data += SA_RLEN(sa);
-		
-		ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa));
-		ift = (ift->ifa_next = ift + 1);
-	}
-#endif	/* NET_RT_IFLIST */
+
 	if (--ift >= ifa) {
 		ift->ifa_next = NULL;
 		*pif = ifa;


More information about the svn-src-head mailing list