diff options
author | bz <bz@FreeBSD.org> | 2012-02-11 06:05:40 +0000 |
---|---|---|
committer | bz <bz@FreeBSD.org> | 2012-02-11 06:05:40 +0000 |
commit | 891142ea87ffcacbfa7af77556942c4350720c35 (patch) | |
tree | 343683357d05c431b67aeec2c8c6fab4615f0af5 | |
parent | d05091db1d58d82a2d4c3cb7c1d505fd42a0a13f (diff) | |
download | FreeBSD-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-- | UPDATING | 7 | ||||
-rw-r--r-- | lib/libc/net/getifaddrs.c | 169 |
2 files changed, 54 insertions, 122 deletions
@@ -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; |