[PATCH v3 3/6] nfs-utils: Implement srcaddr binding in rpc_socket

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

 



From: Ben Greear <greearb@xxxxxxxxxxxxxxx>

This implements the actual binding, if we are passed
a non-null local_ip structure.

Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx>
---
:100644 100644 5652f6c... 4bcbdf0... M	support/nfs/rpc_socket.c
 support/nfs/rpc_socket.c |   59 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/support/nfs/rpc_socket.c b/support/nfs/rpc_socket.c
index 5652f6c..4bcbdf0 100644
--- a/support/nfs/rpc_socket.c
+++ b/support/nfs/rpc_socket.c
@@ -115,6 +115,8 @@ static CLIENT *nfs_get_localclient(const struct sockaddr *sap,
 static int nfs_bind(const int sock, const sa_family_t family,
 		    struct local_bind_info *local_ip)
 {
+	struct sockaddr *sa = NULL;
+	socklen_t salen = 0;
 	struct sockaddr_in sin = {
 		.sin_family		= AF_INET,
 		.sin_addr.s_addr	= htonl(INADDR_ANY),
@@ -124,15 +126,26 @@ static int nfs_bind(const int sock, const sa_family_t family,
 		.sin6_addr		= IN6ADDR_ANY_INIT,
 	};
 
-	switch (family) {
-	case AF_INET:
-		return bind(sock, (struct sockaddr *)(char *)&sin,
-					(socklen_t)sizeof(sin));
-	case AF_INET6:
-		return bind(sock, (struct sockaddr *)(char *)&sin6,
-					(socklen_t)sizeof(sin6));
+	if (local_ip && local_ip->is_set) {
+		sa = &local_ip->addr.sa;
+		salen = local_ip->addrlen;
+	} else {
+		switch (family) {
+		case AF_INET:
+			sa = (struct sockaddr *)&sin;
+			salen = sizeof(sin);
+			break;
+		case AF_INET6:
+			sa = (struct sockaddr *)&sin6;
+			salen = sizeof(sin6);
+		default:
+			break;
+		}
 	}
 
+	if (sa)
+		return bind(sock, sa, salen);
+
 	errno = EAFNOSUPPORT;
 	return -1;
 }
@@ -148,6 +161,7 @@ static int nfs_bind(const int sock, const sa_family_t family,
 static int nfs_bindresvport(const int sock, const sa_family_t family,
 			    struct local_bind_info *local_ip)
 {
+	struct sockaddr *sa = NULL;
 	struct sockaddr_in sin = {
 		.sin_family		= AF_INET,
 		.sin_addr.s_addr	= htonl(INADDR_ANY),
@@ -157,13 +171,23 @@ static int nfs_bindresvport(const int sock, const sa_family_t family,
 		.sin6_addr		= IN6ADDR_ANY_INIT,
 	};
 
-	switch (family) {
-	case AF_INET:
-		return bindresvport_sa(sock, (struct sockaddr *)(char *)&sin);
-	case AF_INET6:
-		return bindresvport_sa(sock, (struct sockaddr *)(char *)&sin6);
+	if (local_ip && local_ip->is_set) {
+		sa = &local_ip->addr.sa;
+	} else {
+		switch (family) {
+		case AF_INET:
+			sa = (struct sockaddr *)&sin;
+			break;
+		case AF_INET6:
+			sa = (struct sockaddr *)&sin6;
+		default:
+			break;
+		}
 	}
 
+	if (sa)
+		return bindresvport_sa(sock, sa);
+
 	errno = EAFNOSUPPORT;
 	return -1;
 }
@@ -179,12 +203,21 @@ static int nfs_bindresvport(const int sock, const sa_family_t family,
 static int nfs_bindresvport(const int sock, const sa_family_t family,
 			    struct local_bind_info *local_ip)
 {
+	struct sockaddr_in laddr;
 	if (family != AF_INET) {
 		errno = EAFNOSUPPORT;
 		return -1;
 	}
 
-	return bindresvport(sock, NULL);
+	laddr.sin_family = family;
+	laddr.sin_port = 0;
+	if (local_ip && local_ip->is_set) {
+		struct sockaddr_in *si = &local_ip->addr.s4;
+		laddr.sin_addr.s_addr = si->sin_addr.s_addr;
+	} else {
+		laddr.sin_addr.s_addr = htonl(INADDR_ANY);
+	}
+	return bindresvport(sock, &laddr);
 }
 
 #endif	/* !HAVE_LIBTIRPC */
-- 
1.7.3.4

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux