summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2012-02-11 06:05:40 +0000
committerbz <bz@FreeBSD.org>2012-02-11 06:05:40 +0000
commit891142ea87ffcacbfa7af77556942c4350720c35 (patch)
tree343683357d05c431b67aeec2c8c6fab4615f0af5
parentd05091db1d58d82a2d4c3cb7c1d505fd42a0a13f (diff)
downloadFreeBSD-src-891142ea87ffcacbfa7af77556942c4350720c35.zip
FreeBSD-src-891142ea87ffcacbfa7af77556942c4350720c35.tar.gz
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
-rw-r--r--UPDATING7
-rw-r--r--lib/libc/net/getifaddrs.c169
2 files changed, 54 insertions, 122 deletions
diff --git a/UPDATING b/UPDATING
index 9a7699b..9da1e29 100644
--- a/UPDATING
+++ b/UPDATING
@@ -22,6 +22,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
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
diff --git a/lib/libc/net/getifaddrs.c b/lib/libc/net/getifaddrs.c
index 41ef3f4..f8633d5 100644
--- a/lib/libc/net/getifaddrs.c
+++ b/lib/libc/net/getifaddrs.c
@@ -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);
-
- 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 */
-
- ift = (ift->ifa_next = ift + 1);
- } else
+ ifm = (struct if_msghdrl *)(void *)rtm;
+ if ((ifm->ifm_addrs & RTA_IFP) == 0) {
idx = 0;
+ break;
+ }
+
+ idx = ifm->ifm_index;
+ dl = (struct sockaddr_dl *)IF_MSGHDRL_RTA(ifm);
+
+ 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;
OpenPOWER on IntegriCloud