[autofs/f16] - also add ipv6 interface query code.

Ian Kent iankent at fedoraproject.org
Thu Aug 9 06:14:55 UTC 2012


commit b78da1ddc6134db4a0c5d4bfda900dc1e85d4aca
Author: Ian Kent <ikent at redhat.com>
Date:   Thu Aug 9 14:14:12 2012 +0800

    - also add ipv6 interface query code.

 autofs-5.0.7-fix-ipv6-proximity-calculation.patch |  297 +++++++++++++++++++++
 autofs.spec                                       |    3 +
 2 files changed, 300 insertions(+), 0 deletions(-)
---
diff --git a/autofs-5.0.7-fix-ipv6-proximity-calculation.patch b/autofs-5.0.7-fix-ipv6-proximity-calculation.patch
new file mode 100644
index 0000000..454195c
--- /dev/null
+++ b/autofs-5.0.7-fix-ipv6-proximity-calculation.patch
@@ -0,0 +1,297 @@
+autofs-5.0.7 - fix ipv6 proximity calculation
+
+From: Ian Kent <ikent at redhat.com>
+
+The socket based ioctl used to get interface information only
+return IPv4 information. Change get_proximity() function to use
+getifaddrs(3) instead.
+---
+
+ CHANGELOG            |    1 
+ modules/replicated.c |  157 +++++++++++++--------------------------------------
+ 2 files changed, 42 insertions(+), 116 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -18,6 +18,7 @@
+ - fix ipv6 rpc calls.
+ - fix ipv6 configure check.
+ - fix nfs4 contacts portmap.
++- fix ipv6 proximity calculation.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/modules/replicated.c
++++ autofs-5.0.6/modules/replicated.c
+@@ -52,6 +52,7 @@
+ #include <net/if.h>
+ #include <netinet/in.h>
+ #include <netdb.h>
++#include <ifaddrs.h>
+ 
+ #include "rpc_subs.h"
+ #include "replicated.h"
+@@ -110,58 +111,18 @@ void seed_random(void)
+ 	return;
+ }
+ 
+-static int alloc_ifreq(struct ifconf *ifc, int sock)
+-{
+-	int ret, lastlen = ifc_last_len, len = ifc_buf_len;
+-	char err_buf[MAX_ERR_BUF], *buf;
+-
+-	while (1) {
+-		buf = malloc(len);
+-		if (!buf) {
+-			char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF);
+-			logerr("malloc: %s", estr);
+-			return 0;
+-		}
+-
+-		ifc->ifc_len = len;
+-		ifc->ifc_req = (struct ifreq *) buf;
+-
+-		ret = ioctl(sock, SIOCGIFCONF, ifc);
+-		if (ret == -1) {
+-			char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF);
+-			logerr("ioctl: %s", estr);
+-			free(buf);
+-			return 0;
+-		}
+-
+-		if (ifc->ifc_len <= lastlen)
+-			break;
+-
+-		lastlen = ifc->ifc_len;
+-		len += MAX_IFC_BUF;
+-		free(buf);
+-	}
+-
+-	if (lastlen != ifc_last_len) {
+-		ifc_last_len = lastlen;
+-		ifc_buf_len = len;
+-	}
+-
+-	return 1;
+-}
+-
+ static unsigned int get_proximity(struct sockaddr *host_addr)
+ {
++	struct ifaddrs *ifa = NULL;
++	struct ifaddrs *this;
+ 	struct sockaddr_in *addr, *msk_addr, *if_addr;
+ 	struct sockaddr_in6 *addr6, *msk6_addr, *if6_addr;
+ 	struct in_addr *hst_addr;
+ 	struct in6_addr *hst6_addr;
+ 	int addr_len;
+-	char buf[MAX_ERR_BUF], *ptr;
+-	struct ifconf ifc;
+-	struct ifreq *ifr, nmptr;
+-	int sock, ret, i;
++	char buf[MAX_ERR_BUF];
+ 	uint32_t mask, ha, ia, *mask6, *ha6, *ia6;
++	int ret;
+ 
+ 	addr = NULL;
+ 	addr6 = NULL;
+@@ -170,13 +131,14 @@ static unsigned int get_proximity(struct
+ 	mask6 = NULL;
+ 	ha6 = NULL;
+ 	ia6 = NULL;
++	ha = 0;
+ 
+ 	switch (host_addr->sa_family) {
+ 	case AF_INET:
+ 		addr = (struct sockaddr_in *) host_addr;
+ 		hst_addr = (struct in_addr *) &addr->sin_addr;
+ 		ha = ntohl((uint32_t) hst_addr->s_addr);
+-		addr_len = sizeof(hst_addr);
++		addr_len = sizeof(*hst_addr);
+ 		break;
+ 
+ 	case AF_INET6:
+@@ -186,7 +148,7 @@ static unsigned int get_proximity(struct
+ 		addr6 = (struct sockaddr_in6 *) host_addr;
+ 		hst6_addr = (struct in6_addr *) &addr6->sin6_addr;
+ 		ha6 = &hst6_addr->s6_addr32[0];
+-		addr_len = sizeof(hst6_addr);
++		addr_len = sizeof(*hst6_addr);
+ 		break;
+ #endif
+ 
+@@ -194,36 +156,27 @@ static unsigned int get_proximity(struct
+ 		return PROXIMITY_ERROR;
+ 	}
+ 
+-	sock = open_sock(AF_INET, SOCK_DGRAM, 0);
+-	if (sock < 0) {
++	ret = getifaddrs(&ifa);
++	if (ret) {
+ 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+-		logerr("socket creation failed: %s", estr);
+-		return PROXIMITY_ERROR;
+-	}
+-
+-	if (!alloc_ifreq(&ifc, sock)) {
+-		close(sock);
++		logerr("getifaddrs: %s", estr);
+ 		return PROXIMITY_ERROR;
+ 	}
+ 
+-	/* For each interface */
+-
+-	/* Is the address a local interface */
+-	i = 0;
+-	ptr = (char *) &ifc.ifc_buf[0];
+-
+-	while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) {
+-		ifr = (struct ifreq *) ptr;
++	this = ifa;
++	while (this) {
++		if (this->ifa_flags & IFF_POINTOPOINT ||
++		    this->ifa_addr->sa_data == NULL) {
++			this = this->ifa_next;
++			continue;
++		}
+ 
+-		switch (ifr->ifr_addr.sa_family) {
++		switch (this->ifa_addr->sa_family) {
+ 		case AF_INET:
+-			if (host_addr->sa_family == AF_INET6)
+-				break;
+-			if_addr = (struct sockaddr_in *) &ifr->ifr_addr;
++			if_addr = (struct sockaddr_in *) this->ifa_addr;
+ 			ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len);
+ 			if (!ret) {
+-				close(sock);
+-				free(ifc.ifc_req);
++				freeifaddrs(ifa);
+ 				return PROXIMITY_LOCAL;
+ 			}
+ 			break;
+@@ -232,57 +185,39 @@ static unsigned int get_proximity(struct
+ #ifndef WITH_LIBTIRPC
+ 			return PROXIMITY_UNSUPPORTED;
+ #else
+-			if (host_addr->sa_family == AF_INET)
+-				break;
+-
+-			if6_addr = (struct sockaddr_in6 *) &ifr->ifr_addr;
++			if6_addr = (struct sockaddr_in6 *) this->ifa_addr;
+ 			ret = memcmp(&if6_addr->sin6_addr, hst6_addr, addr_len);
+ 			if (!ret) {
+-				close(sock);
+-				free(ifc.ifc_req);
++				freeifaddrs(ifa);
+ 				return PROXIMITY_LOCAL;
+ 			}
+ #endif
+-
+ 		default:
+ 			break;
+ 		}
+-
+-		i++;
+-		ptr = (char *) &ifc.ifc_req[i];
++		this = this->ifa_next;
+ 	}
+ 
+-	i = 0;
+-	ptr = (char *) &ifc.ifc_buf[0];
+-
+-	while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) {
+-		ifr = (struct ifreq *) ptr;
+-
+-		nmptr = *ifr;
+-		ret = ioctl(sock, SIOCGIFNETMASK, &nmptr);
+-		if (ret == -1) {
+-			char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+-			logerr("ioctl: %s", estr);
+-			close(sock);
+-			free(ifc.ifc_req);
+-			return PROXIMITY_ERROR;
++	this = ifa;
++	while (this) {
++		if (this->ifa_flags & IFF_POINTOPOINT ||
++		    this->ifa_addr->sa_data == NULL) {
++			this = this->ifa_next;
++			continue;
+ 		}
+ 
+-		switch (ifr->ifr_addr.sa_family) {
++		switch (this->ifa_addr->sa_family) {
+ 		case AF_INET:
+-			if (host_addr->sa_family == AF_INET6)
+-				break;
+-			if_addr = (struct sockaddr_in *) &ifr->ifr_addr;
++			if_addr = (struct sockaddr_in *) this->ifa_addr;
+ 			ia =  ntohl((uint32_t) if_addr->sin_addr.s_addr);
+ 
+-			/* Is the address within a localiy attached subnet */
++			/* Is the address within a localy attached subnet */
+ 
+-			msk_addr = (struct sockaddr_in *) &nmptr.ifr_netmask;
++			msk_addr = (struct sockaddr_in *) this->ifa_netmask;
+ 			mask = ntohl((uint32_t) msk_addr->sin_addr.s_addr);
+ 
+ 			if ((ia & mask) == (ha & mask)) {
+-				close(sock);
+-				free(ifc.ifc_req);
++				freeifaddrs(ifa);
+ 				return PROXIMITY_SUBNET;
+ 			}
+ 
+@@ -304,8 +239,7 @@ static unsigned int get_proximity(struct
+ 				break;
+ 
+ 			if ((ia & mask) == (ha & mask)) {
+-				close(sock);
+-				free(ifc.ifc_req);
++				freeifaddrs(ifa);
+ 				return PROXIMITY_NET;
+ 			}
+ 			break;
+@@ -314,37 +248,28 @@ static unsigned int get_proximity(struct
+ #ifndef WITH_LIBTIRPC
+ 			return PROXIMITY_UNSUPPORTED;
+ #else
+-			if (host_addr->sa_family == AF_INET)
+-				break;
+-
+-			if6_addr = (struct sockaddr_in6 *) &ifr->ifr_addr;
++			if6_addr = (struct sockaddr_in6 *) this->ifa_addr;
+ 			ia6 = &if6_addr->sin6_addr.s6_addr32[0];
+ 
+ 			/* Is the address within the network of the interface */
+ 
+-			msk6_addr = (struct sockaddr_in6 *) &nmptr.ifr_netmask;
++			msk6_addr = (struct sockaddr_in6 *) this->ifa_netmask;
+ 			mask6 = &msk6_addr->sin6_addr.s6_addr32[0];
+ 
+ 			if (ipv6_mask_cmp(ha6, ia6, mask6)) {
+-				close(sock);
+-				free(ifc.ifc_req);
++				freeifaddrs(ifa);
+ 				return PROXIMITY_SUBNET;
+ 			}
+ 
+ 			/* How do we define "local network" in ipv6? */
+ #endif
+-			break;
+-
+ 		default:
+ 			break;
+ 		}
+-
+-		i++;
+-		ptr = (char *) &ifc.ifc_req[i];
++		this = this->ifa_next;
+ 	}
+ 
+-	close(sock);
+-	free(ifc.ifc_req);
++	freeifaddrs(ifa);
+ 
+ 	return PROXIMITY_OTHER;
+ }
diff --git a/autofs.spec b/autofs.spec
index b6bb095..6bcb0c8 100644
--- a/autofs.spec
+++ b/autofs.spec
@@ -29,6 +29,7 @@ Patch17: autofs-5.0.6-fix-ipv6-name-lookup-check.patch
 Patch18: autofs-5.0.6-fix-ipv6-rpc-calls.patch
 Patch19: autofs-5.0.6-fix-ipv6-configure-check.patch
 Patch20: autofs-5.0.6-fix-nfs4-contacts-portmap.patch
+Patch21: autofs-5.0.7-fix-ipv6-proximity-calculation.patch
 Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs libtirpc-devel
 Conflicts: cyrus-sasl-lib < 2.1.23-9
@@ -91,6 +92,7 @@ echo %{version}-%{release} > .version
 %patch18 -p1
 %patch19 -p1
 %patch20 -p1
+%patch21 -p1
 
 %build
 #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -150,6 +152,7 @@ fi
 - fix ipv6 rpc calls (bz711844).
 - fix ipv6 configure check (bz711844).
 - fix nfs4 contacts portmap (bz711844).
+- fix ipv6 proximity calculation (bz711844).
 
 * Mon Jan 23 2012 Ian Kent <ikent at redhat.com> - 1:5.0.6-5
 - fix fix wait for master source mutex.


More information about the scm-commits mailing list