Browse Source

rds: Remove IPv6 dependency

This patch removes the IPv6 dependency from RDS.

Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Ka-Cheong Poon 7 years ago
parent
commit
e65d4d9633
12 changed files with 140 additions and 26 deletions
  1. 1 1
      net/rds/Kconfig
  2. 19 13
      net/rds/af_rds.c
  3. 3 1
      net/rds/bind.c
  4. 24 2
      net/rds/connection.c
  5. 26 5
      net/rds/ib.c
  6. 9 0
      net/rds/ib_cm.c
  7. 2 0
      net/rds/ib_rdma.c
  8. 10 0
      net/rds/rdma_transport.c
  9. 2 0
      net/rds/recv.c
  10. 2 0
      net/rds/send.c
  11. 25 0
      net/rds/tcp.c
  12. 17 4
      net/rds/tcp_listen.c

+ 1 - 1
net/rds/Kconfig

@@ -1,7 +1,7 @@
 
 
 config RDS
 config RDS
 	tristate "The RDS Protocol"
 	tristate "The RDS Protocol"
-	depends on INET && IPV6
+	depends on INET
 	---help---
 	---help---
 	  The RDS (Reliable Datagram Sockets) protocol provides reliable,
 	  The RDS (Reliable Datagram Sockets) protocol provides reliable,
 	  sequenced delivery of datagrams over Infiniband or TCP.
 	  sequenced delivery of datagrams over Infiniband or TCP.

+ 19 - 13
net/rds/af_rds.c

@@ -156,18 +156,20 @@ static int rds_getname(struct socket *sock, struct sockaddr *uaddr,
 				return sizeof(*sin);
 				return sizeof(*sin);
 			}
 			}
 
 
-			if (ipv6_addr_type(&rs->rs_conn_addr) &
-			    IPV6_ADDR_MAPPED) {
-				sin = (struct sockaddr_in *)uaddr;
-				memset(sin, 0, sizeof(*sin));
-				sin->sin_family = AF_INET;
-				return sizeof(*sin);
+#if IS_ENABLED(CONFIG_IPV6)
+			if (!(ipv6_addr_type(&rs->rs_conn_addr) &
+			      IPV6_ADDR_MAPPED)) {
+				sin6 = (struct sockaddr_in6 *)uaddr;
+				memset(sin6, 0, sizeof(*sin6));
+				sin6->sin6_family = AF_INET6;
+				return sizeof(*sin6);
 			}
 			}
+#endif
 
 
-			sin6 = (struct sockaddr_in6 *)uaddr;
-			memset(sin6, 0, sizeof(*sin6));
-			sin6->sin6_family = AF_INET6;
-			return sizeof(*sin6);
+			sin = (struct sockaddr_in *)uaddr;
+			memset(sin, 0, sizeof(*sin));
+			sin->sin_family = AF_INET;
+			return sizeof(*sin);
 		}
 		}
 		if (ipv6_addr_v4mapped(&rs->rs_bound_addr)) {
 		if (ipv6_addr_v4mapped(&rs->rs_bound_addr)) {
 			sin = (struct sockaddr_in *)uaddr;
 			sin = (struct sockaddr_in *)uaddr;
@@ -501,9 +503,7 @@ static int rds_connect(struct socket *sock, struct sockaddr *uaddr,
 {
 {
 	struct sock *sk = sock->sk;
 	struct sock *sk = sock->sk;
 	struct sockaddr_in *sin;
 	struct sockaddr_in *sin;
-	struct sockaddr_in6 *sin6;
 	struct rds_sock *rs = rds_sk_to_rs(sk);
 	struct rds_sock *rs = rds_sk_to_rs(sk);
-	int addr_type;
 	int ret = 0;
 	int ret = 0;
 
 
 	lock_sock(sk);
 	lock_sock(sk);
@@ -528,7 +528,11 @@ static int rds_connect(struct socket *sock, struct sockaddr *uaddr,
 		rs->rs_conn_port = sin->sin_port;
 		rs->rs_conn_port = sin->sin_port;
 		break;
 		break;
 
 
-	case AF_INET6:
+#if IS_ENABLED(CONFIG_IPV6)
+	case AF_INET6: {
+		struct sockaddr_in6 *sin6;
+		int addr_type;
+
 		sin6 = (struct sockaddr_in6 *)uaddr;
 		sin6 = (struct sockaddr_in6 *)uaddr;
 		if (addr_len < sizeof(struct sockaddr_in6)) {
 		if (addr_len < sizeof(struct sockaddr_in6)) {
 			ret = -EINVAL;
 			ret = -EINVAL;
@@ -575,6 +579,8 @@ static int rds_connect(struct socket *sock, struct sockaddr *uaddr,
 		rs->rs_conn_addr = sin6->sin6_addr;
 		rs->rs_conn_addr = sin6->sin6_addr;
 		rs->rs_conn_port = sin6->sin6_port;
 		rs->rs_conn_port = sin6->sin6_port;
 		break;
 		break;
+	}
+#endif
 
 
 	default:
 	default:
 		ret = -EAFNOSUPPORT;
 		ret = -EAFNOSUPPORT;

+ 3 - 1
net/rds/bind.c

@@ -165,7 +165,6 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 	struct in6_addr v6addr, *binding_addr;
 	struct in6_addr v6addr, *binding_addr;
 	struct rds_transport *trans;
 	struct rds_transport *trans;
 	__u32 scope_id = 0;
 	__u32 scope_id = 0;
-	int addr_type;
 	int ret = 0;
 	int ret = 0;
 	__be16 port;
 	__be16 port;
 
 
@@ -183,8 +182,10 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 		ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &v6addr);
 		ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &v6addr);
 		binding_addr = &v6addr;
 		binding_addr = &v6addr;
 		port = sin->sin_port;
 		port = sin->sin_port;
+#if IS_ENABLED(CONFIG_IPV6)
 	} else if (uaddr->sa_family == AF_INET6) {
 	} else if (uaddr->sa_family == AF_INET6) {
 		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)uaddr;
 		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)uaddr;
+		int addr_type;
 
 
 		if (addr_len < sizeof(struct sockaddr_in6))
 		if (addr_len < sizeof(struct sockaddr_in6))
 			return -EINVAL;
 			return -EINVAL;
@@ -212,6 +213,7 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 		}
 		}
 		binding_addr = &sin6->sin6_addr;
 		binding_addr = &sin6->sin6_addr;
 		port = sin6->sin6_port;
 		port = sin6->sin6_port;
+#endif
 	} else {
 	} else {
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}

+ 24 - 2
net/rds/connection.c

@@ -63,8 +63,12 @@ static struct hlist_head *rds_conn_bucket(const struct in6_addr *laddr,
 	net_get_random_once(&rds6_hash_secret, sizeof(rds6_hash_secret));
 	net_get_random_once(&rds6_hash_secret, sizeof(rds6_hash_secret));
 
 
 	lhash = (__force u32)laddr->s6_addr32[3];
 	lhash = (__force u32)laddr->s6_addr32[3];
+#if IS_ENABLED(CONFIG_IPV6)
 	fhash = __ipv6_addr_jhash(faddr, rds6_hash_secret);
 	fhash = __ipv6_addr_jhash(faddr, rds6_hash_secret);
-	hash = __inet6_ehashfn(lhash, 0, fhash, 0, rds_hash_secret);
+#else
+	fhash = (__force u32)faddr->s6_addr32[3];
+#endif
+	hash = __inet_ehashfn(lhash, 0, fhash, 0, rds_hash_secret);
 
 
 	return &rds_conn_hash[hash & RDS_CONNECTION_HASH_MASK];
 	return &rds_conn_hash[hash & RDS_CONNECTION_HASH_MASK];
 }
 }
@@ -201,6 +205,8 @@ static struct rds_connection *__rds_conn_create(struct net *net,
 	conn->c_isv6 = !ipv6_addr_v4mapped(laddr);
 	conn->c_isv6 = !ipv6_addr_v4mapped(laddr);
 	conn->c_faddr = *faddr;
 	conn->c_faddr = *faddr;
 	conn->c_dev_if = dev_if;
 	conn->c_dev_if = dev_if;
+
+#if IS_ENABLED(CONFIG_IPV6)
 	/* If the local address is link local, set c_bound_if to be the
 	/* If the local address is link local, set c_bound_if to be the
 	 * index used for this connection.  Otherwise, set it to 0 as
 	 * index used for this connection.  Otherwise, set it to 0 as
 	 * the socket is not bound to an interface.  c_bound_if is used
 	 * the socket is not bound to an interface.  c_bound_if is used
@@ -209,6 +215,7 @@ static struct rds_connection *__rds_conn_create(struct net *net,
 	if (ipv6_addr_type(laddr) & IPV6_ADDR_LINKLOCAL)
 	if (ipv6_addr_type(laddr) & IPV6_ADDR_LINKLOCAL)
 		conn->c_bound_if = dev_if;
 		conn->c_bound_if = dev_if;
 	else
 	else
+#endif
 		conn->c_bound_if = 0;
 		conn->c_bound_if = 0;
 
 
 	rds_conn_net_set(conn, net);
 	rds_conn_net_set(conn, net);
@@ -500,9 +507,11 @@ static void __rds_inc_msg_cp(struct rds_incoming *inc,
 			     struct rds_info_iterator *iter,
 			     struct rds_info_iterator *iter,
 			     void *saddr, void *daddr, int flip, bool isv6)
 			     void *saddr, void *daddr, int flip, bool isv6)
 {
 {
+#if IS_ENABLED(CONFIG_IPV6)
 	if (isv6)
 	if (isv6)
 		rds6_inc_info_copy(inc, iter, saddr, daddr, flip);
 		rds6_inc_info_copy(inc, iter, saddr, daddr, flip);
 	else
 	else
+#endif
 		rds_inc_info_copy(inc, iter, *(__be32 *)saddr,
 		rds_inc_info_copy(inc, iter, *(__be32 *)saddr,
 				  *(__be32 *)daddr, flip);
 				  *(__be32 *)daddr, flip);
 }
 }
@@ -581,6 +590,7 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len,
 	rds_conn_message_info_cmn(sock, len, iter, lens, want_send, false);
 	rds_conn_message_info_cmn(sock, len, iter, lens, want_send, false);
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 static void rds6_conn_message_info(struct socket *sock, unsigned int len,
 static void rds6_conn_message_info(struct socket *sock, unsigned int len,
 				   struct rds_info_iterator *iter,
 				   struct rds_info_iterator *iter,
 				   struct rds_info_lengths *lens,
 				   struct rds_info_lengths *lens,
@@ -588,6 +598,7 @@ static void rds6_conn_message_info(struct socket *sock, unsigned int len,
 {
 {
 	rds_conn_message_info_cmn(sock, len, iter, lens, want_send, true);
 	rds_conn_message_info_cmn(sock, len, iter, lens, want_send, true);
 }
 }
+#endif
 
 
 static void rds_conn_message_info_send(struct socket *sock, unsigned int len,
 static void rds_conn_message_info_send(struct socket *sock, unsigned int len,
 				       struct rds_info_iterator *iter,
 				       struct rds_info_iterator *iter,
@@ -596,12 +607,14 @@ static void rds_conn_message_info_send(struct socket *sock, unsigned int len,
 	rds_conn_message_info(sock, len, iter, lens, 1);
 	rds_conn_message_info(sock, len, iter, lens, 1);
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 static void rds6_conn_message_info_send(struct socket *sock, unsigned int len,
 static void rds6_conn_message_info_send(struct socket *sock, unsigned int len,
 					struct rds_info_iterator *iter,
 					struct rds_info_iterator *iter,
 					struct rds_info_lengths *lens)
 					struct rds_info_lengths *lens)
 {
 {
 	rds6_conn_message_info(sock, len, iter, lens, 1);
 	rds6_conn_message_info(sock, len, iter, lens, 1);
 }
 }
+#endif
 
 
 static void rds_conn_message_info_retrans(struct socket *sock,
 static void rds_conn_message_info_retrans(struct socket *sock,
 					  unsigned int len,
 					  unsigned int len,
@@ -611,6 +624,7 @@ static void rds_conn_message_info_retrans(struct socket *sock,
 	rds_conn_message_info(sock, len, iter, lens, 0);
 	rds_conn_message_info(sock, len, iter, lens, 0);
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 static void rds6_conn_message_info_retrans(struct socket *sock,
 static void rds6_conn_message_info_retrans(struct socket *sock,
 					   unsigned int len,
 					   unsigned int len,
 					   struct rds_info_iterator *iter,
 					   struct rds_info_iterator *iter,
@@ -618,6 +632,7 @@ static void rds6_conn_message_info_retrans(struct socket *sock,
 {
 {
 	rds6_conn_message_info(sock, len, iter, lens, 0);
 	rds6_conn_message_info(sock, len, iter, lens, 0);
 }
 }
+#endif
 
 
 void rds_for_each_conn_info(struct socket *sock, unsigned int len,
 void rds_for_each_conn_info(struct socket *sock, unsigned int len,
 			  struct rds_info_iterator *iter,
 			  struct rds_info_iterator *iter,
@@ -734,6 +749,7 @@ static int rds_conn_info_visitor(struct rds_conn_path *cp, void *buffer)
 	return 1;
 	return 1;
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 static int rds6_conn_info_visitor(struct rds_conn_path *cp, void *buffer)
 static int rds6_conn_info_visitor(struct rds_conn_path *cp, void *buffer)
 {
 {
 	struct rds6_info_connection *cinfo6 = buffer;
 	struct rds6_info_connection *cinfo6 = buffer;
@@ -761,6 +777,7 @@ static int rds6_conn_info_visitor(struct rds_conn_path *cp, void *buffer)
 	 */
 	 */
 	return 1;
 	return 1;
 }
 }
+#endif
 
 
 static void rds_conn_info(struct socket *sock, unsigned int len,
 static void rds_conn_info(struct socket *sock, unsigned int len,
 			  struct rds_info_iterator *iter,
 			  struct rds_info_iterator *iter,
@@ -774,6 +791,7 @@ static void rds_conn_info(struct socket *sock, unsigned int len,
 				sizeof(struct rds_info_connection));
 				sizeof(struct rds_info_connection));
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 static void rds6_conn_info(struct socket *sock, unsigned int len,
 static void rds6_conn_info(struct socket *sock, unsigned int len,
 			   struct rds_info_iterator *iter,
 			   struct rds_info_iterator *iter,
 			   struct rds_info_lengths *lens)
 			   struct rds_info_lengths *lens)
@@ -785,6 +803,7 @@ static void rds6_conn_info(struct socket *sock, unsigned int len,
 				buffer,
 				buffer,
 				sizeof(struct rds6_info_connection));
 				sizeof(struct rds6_info_connection));
 }
 }
+#endif
 
 
 int rds_conn_init(void)
 int rds_conn_init(void)
 {
 {
@@ -807,12 +826,13 @@ int rds_conn_init(void)
 			       rds_conn_message_info_send);
 			       rds_conn_message_info_send);
 	rds_info_register_func(RDS_INFO_RETRANS_MESSAGES,
 	rds_info_register_func(RDS_INFO_RETRANS_MESSAGES,
 			       rds_conn_message_info_retrans);
 			       rds_conn_message_info_retrans);
+#if IS_ENABLED(CONFIG_IPV6)
 	rds_info_register_func(RDS6_INFO_CONNECTIONS, rds6_conn_info);
 	rds_info_register_func(RDS6_INFO_CONNECTIONS, rds6_conn_info);
 	rds_info_register_func(RDS6_INFO_SEND_MESSAGES,
 	rds_info_register_func(RDS6_INFO_SEND_MESSAGES,
 			       rds6_conn_message_info_send);
 			       rds6_conn_message_info_send);
 	rds_info_register_func(RDS6_INFO_RETRANS_MESSAGES,
 	rds_info_register_func(RDS6_INFO_RETRANS_MESSAGES,
 			       rds6_conn_message_info_retrans);
 			       rds6_conn_message_info_retrans);
-
+#endif
 	return 0;
 	return 0;
 }
 }
 
 
@@ -830,11 +850,13 @@ void rds_conn_exit(void)
 				 rds_conn_message_info_send);
 				 rds_conn_message_info_send);
 	rds_info_deregister_func(RDS_INFO_RETRANS_MESSAGES,
 	rds_info_deregister_func(RDS_INFO_RETRANS_MESSAGES,
 				 rds_conn_message_info_retrans);
 				 rds_conn_message_info_retrans);
+#if IS_ENABLED(CONFIG_IPV6)
 	rds_info_deregister_func(RDS6_INFO_CONNECTIONS, rds6_conn_info);
 	rds_info_deregister_func(RDS6_INFO_CONNECTIONS, rds6_conn_info);
 	rds_info_deregister_func(RDS6_INFO_SEND_MESSAGES,
 	rds_info_deregister_func(RDS6_INFO_SEND_MESSAGES,
 				 rds6_conn_message_info_send);
 				 rds6_conn_message_info_send);
 	rds_info_deregister_func(RDS6_INFO_RETRANS_MESSAGES,
 	rds_info_deregister_func(RDS6_INFO_RETRANS_MESSAGES,
 				 rds6_conn_message_info_retrans);
 				 rds6_conn_message_info_retrans);
+#endif
 }
 }
 
 
 /*
 /*

+ 26 - 5
net/rds/ib.c

@@ -321,6 +321,7 @@ static int rds_ib_conn_info_visitor(struct rds_connection *conn,
 	return 1;
 	return 1;
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 /* IPv6 version of rds_ib_conn_info_visitor(). */
 /* IPv6 version of rds_ib_conn_info_visitor(). */
 static int rds6_ib_conn_info_visitor(struct rds_connection *conn,
 static int rds6_ib_conn_info_visitor(struct rds_connection *conn,
 				     void *buffer)
 				     void *buffer)
@@ -357,6 +358,7 @@ static int rds6_ib_conn_info_visitor(struct rds_connection *conn,
 	}
 	}
 	return 1;
 	return 1;
 }
 }
+#endif
 
 
 static void rds_ib_ic_info(struct socket *sock, unsigned int len,
 static void rds_ib_ic_info(struct socket *sock, unsigned int len,
 			   struct rds_info_iterator *iter,
 			   struct rds_info_iterator *iter,
@@ -370,6 +372,7 @@ static void rds_ib_ic_info(struct socket *sock, unsigned int len,
 				sizeof(struct rds_info_rdma_connection));
 				sizeof(struct rds_info_rdma_connection));
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 /* IPv6 version of rds_ib_ic_info(). */
 /* IPv6 version of rds_ib_ic_info(). */
 static void rds6_ib_ic_info(struct socket *sock, unsigned int len,
 static void rds6_ib_ic_info(struct socket *sock, unsigned int len,
 			    struct rds_info_iterator *iter,
 			    struct rds_info_iterator *iter,
@@ -382,6 +385,7 @@ static void rds6_ib_ic_info(struct socket *sock, unsigned int len,
 			       buffer,
 			       buffer,
 			       sizeof(struct rds6_info_rdma_connection));
 			       sizeof(struct rds6_info_rdma_connection));
 }
 }
+#endif
 
 
 /*
 /*
  * Early RDS/IB was built to only bind to an address if there is an IPoIB
  * Early RDS/IB was built to only bind to an address if there is an IPoIB
@@ -398,7 +402,9 @@ static int rds_ib_laddr_check(struct net *net, const struct in6_addr *addr,
 {
 {
 	int ret;
 	int ret;
 	struct rdma_cm_id *cm_id;
 	struct rdma_cm_id *cm_id;
+#if IS_ENABLED(CONFIG_IPV6)
 	struct sockaddr_in6 sin6;
 	struct sockaddr_in6 sin6;
+#endif
 	struct sockaddr_in sin;
 	struct sockaddr_in sin;
 	struct sockaddr *sa;
 	struct sockaddr *sa;
 	bool isv4;
 	bool isv4;
@@ -418,6 +424,7 @@ static int rds_ib_laddr_check(struct net *net, const struct in6_addr *addr,
 		sin.sin_addr.s_addr = addr->s6_addr32[3];
 		sin.sin_addr.s_addr = addr->s6_addr32[3];
 		sa = (struct sockaddr *)&sin;
 		sa = (struct sockaddr *)&sin;
 	} else {
 	} else {
+#if IS_ENABLED(CONFIG_IPV6)
 		memset(&sin6, 0, sizeof(sin6));
 		memset(&sin6, 0, sizeof(sin6));
 		sin6.sin6_family = AF_INET6;
 		sin6.sin6_family = AF_INET6;
 		sin6.sin6_addr = *addr;
 		sin6.sin6_addr = *addr;
@@ -432,21 +439,30 @@ static int rds_ib_laddr_check(struct net *net, const struct in6_addr *addr,
 		if (ipv6_addr_type(addr) & IPV6_ADDR_LINKLOCAL) {
 		if (ipv6_addr_type(addr) & IPV6_ADDR_LINKLOCAL) {
 			struct net_device *dev;
 			struct net_device *dev;
 
 
-			if (scope_id == 0)
-				return -EADDRNOTAVAIL;
+			if (scope_id == 0) {
+				ret = -EADDRNOTAVAIL;
+				goto out;
+			}
 
 
 			/* Use init_net for now as RDS is not network
 			/* Use init_net for now as RDS is not network
 			 * name space aware.
 			 * name space aware.
 			 */
 			 */
 			dev = dev_get_by_index(&init_net, scope_id);
 			dev = dev_get_by_index(&init_net, scope_id);
-			if (!dev)
-				return -EADDRNOTAVAIL;
+			if (!dev) {
+				ret = -EADDRNOTAVAIL;
+				goto out;
+			}
 			if (!ipv6_chk_addr(&init_net, addr, dev, 1)) {
 			if (!ipv6_chk_addr(&init_net, addr, dev, 1)) {
 				dev_put(dev);
 				dev_put(dev);
-				return -EADDRNOTAVAIL;
+				ret = -EADDRNOTAVAIL;
+				goto out;
 			}
 			}
 			dev_put(dev);
 			dev_put(dev);
 		}
 		}
+#else
+		ret = -EADDRNOTAVAIL;
+		goto out;
+#endif
 	}
 	}
 
 
 	/* rdma_bind_addr will only succeed for IB & iWARP devices */
 	/* rdma_bind_addr will only succeed for IB & iWARP devices */
@@ -461,6 +477,7 @@ static int rds_ib_laddr_check(struct net *net, const struct in6_addr *addr,
 		 addr, scope_id, ret,
 		 addr, scope_id, ret,
 		 cm_id->device ? cm_id->device->node_type : -1);
 		 cm_id->device ? cm_id->device->node_type : -1);
 
 
+out:
 	rdma_destroy_id(cm_id);
 	rdma_destroy_id(cm_id);
 
 
 	return ret;
 	return ret;
@@ -491,7 +508,9 @@ void rds_ib_exit(void)
 	rds_ib_set_unloading();
 	rds_ib_set_unloading();
 	synchronize_rcu();
 	synchronize_rcu();
 	rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
 	rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
+#if IS_ENABLED(CONFIG_IPV6)
 	rds_info_deregister_func(RDS6_INFO_IB_CONNECTIONS, rds6_ib_ic_info);
 	rds_info_deregister_func(RDS6_INFO_IB_CONNECTIONS, rds6_ib_ic_info);
+#endif
 	rds_ib_unregister_client();
 	rds_ib_unregister_client();
 	rds_ib_destroy_nodev_conns();
 	rds_ib_destroy_nodev_conns();
 	rds_ib_sysctl_exit();
 	rds_ib_sysctl_exit();
@@ -553,7 +572,9 @@ int rds_ib_init(void)
 	rds_trans_register(&rds_ib_transport);
 	rds_trans_register(&rds_ib_transport);
 
 
 	rds_info_register_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
 	rds_info_register_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
+#if IS_ENABLED(CONFIG_IPV6)
 	rds_info_register_func(RDS6_INFO_IB_CONNECTIONS, rds6_ib_ic_info);
 	rds_info_register_func(RDS6_INFO_IB_CONNECTIONS, rds6_ib_ic_info);
+#endif
 
 
 	goto out;
 	goto out;
 
 

+ 9 - 0
net/rds/ib_cm.c

@@ -678,6 +678,7 @@ static u32 rds_ib_protocol_compatible(struct rdma_cm_event *event, bool isv6)
 	return version;
 	return version;
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 /* Given an IPv6 address, find the net_device which hosts that address and
 /* Given an IPv6 address, find the net_device which hosts that address and
  * return its index.  This is used by the rds_ib_cm_handle_connect() code to
  * return its index.  This is used by the rds_ib_cm_handle_connect() code to
  * find the interface index of where an incoming request comes from when
  * find the interface index of where an incoming request comes from when
@@ -704,6 +705,7 @@ static u32 __rds_find_ifindex(struct net *net, const struct in6_addr *addr)
 
 
 	return idx;
 	return idx;
 }
 }
+#endif
 
 
 int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
 int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
 			     struct rdma_cm_event *event, bool isv6)
 			     struct rdma_cm_event *event, bool isv6)
@@ -732,6 +734,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
 
 
 	dp = event->param.conn.private_data;
 	dp = event->param.conn.private_data;
 	if (isv6) {
 	if (isv6) {
+#if IS_ENABLED(CONFIG_IPV6)
 		dp_cmn = &dp->ricp_v6.dp_cmn;
 		dp_cmn = &dp->ricp_v6.dp_cmn;
 		saddr6 = &dp->ricp_v6.dp_saddr;
 		saddr6 = &dp->ricp_v6.dp_saddr;
 		daddr6 = &dp->ricp_v6.dp_daddr;
 		daddr6 = &dp->ricp_v6.dp_daddr;
@@ -756,6 +759,10 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
 				goto out;
 				goto out;
 			}
 			}
 		}
 		}
+#else
+		err = -EOPNOTSUPP;
+		goto out;
+#endif
 	} else {
 	} else {
 		dp_cmn = &dp->ricp_v4.dp_cmn;
 		dp_cmn = &dp->ricp_v4.dp_cmn;
 		ipv6_addr_set_v4mapped(dp->ricp_v4.dp_saddr, &s_mapped_addr);
 		ipv6_addr_set_v4mapped(dp->ricp_v4.dp_saddr, &s_mapped_addr);
@@ -893,9 +900,11 @@ int rds_ib_conn_path_connect(struct rds_conn_path *cp)
 
 
 	/* XXX I wonder what affect the port space has */
 	/* XXX I wonder what affect the port space has */
 	/* delegate cm event handler to rdma_transport */
 	/* delegate cm event handler to rdma_transport */
+#if IS_ENABLED(CONFIG_IPV6)
 	if (conn->c_isv6)
 	if (conn->c_isv6)
 		handler = rds6_rdma_cm_event_handler;
 		handler = rds6_rdma_cm_event_handler;
 	else
 	else
+#endif
 		handler = rds_rdma_cm_event_handler;
 		handler = rds_rdma_cm_event_handler;
 	ic->i_cm_id = rdma_create_id(&init_net, handler, conn,
 	ic->i_cm_id = rdma_create_id(&init_net, handler, conn,
 				     RDMA_PS_TCP, IB_QPT_RC);
 				     RDMA_PS_TCP, IB_QPT_RC);

+ 2 - 0
net/rds/ib_rdma.c

@@ -180,6 +180,7 @@ void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_co
 	iinfo->rdma_mr_size = pool_1m->fmr_attr.max_pages;
 	iinfo->rdma_mr_size = pool_1m->fmr_attr.max_pages;
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 void rds6_ib_get_mr_info(struct rds_ib_device *rds_ibdev,
 void rds6_ib_get_mr_info(struct rds_ib_device *rds_ibdev,
 			 struct rds6_info_rdma_connection *iinfo6)
 			 struct rds6_info_rdma_connection *iinfo6)
 {
 {
@@ -188,6 +189,7 @@ void rds6_ib_get_mr_info(struct rds_ib_device *rds_ibdev,
 	iinfo6->rdma_mr_max = pool_1m->max_items;
 	iinfo6->rdma_mr_max = pool_1m->max_items;
 	iinfo6->rdma_mr_size = pool_1m->fmr_attr.max_pages;
 	iinfo6->rdma_mr_size = pool_1m->fmr_attr.max_pages;
 }
 }
+#endif
 
 
 struct rds_ib_mr *rds_ib_reuse_mr(struct rds_ib_mr_pool *pool)
 struct rds_ib_mr *rds_ib_reuse_mr(struct rds_ib_mr_pool *pool)
 {
 {

+ 10 - 0
net/rds/rdma_transport.c

@@ -39,7 +39,9 @@
 
 
 /* Global IPv4 and IPv6 RDS RDMA listener cm_id */
 /* Global IPv4 and IPv6 RDS RDMA listener cm_id */
 static struct rdma_cm_id *rds_rdma_listen_id;
 static struct rdma_cm_id *rds_rdma_listen_id;
+#if IS_ENABLED(CONFIG_IPV6)
 static struct rdma_cm_id *rds6_rdma_listen_id;
 static struct rdma_cm_id *rds6_rdma_listen_id;
+#endif
 
 
 static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
 static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
 					 struct rdma_cm_event *event,
 					 struct rdma_cm_event *event,
@@ -155,11 +157,13 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
 	return rds_rdma_cm_event_handler_cmn(cm_id, event, false);
 	return rds_rdma_cm_event_handler_cmn(cm_id, event, false);
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 int rds6_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
 int rds6_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
 			       struct rdma_cm_event *event)
 			       struct rdma_cm_event *event)
 {
 {
 	return rds_rdma_cm_event_handler_cmn(cm_id, event, true);
 	return rds_rdma_cm_event_handler_cmn(cm_id, event, true);
 }
 }
+#endif
 
 
 static int rds_rdma_listen_init_common(rdma_cm_event_handler handler,
 static int rds_rdma_listen_init_common(rdma_cm_event_handler handler,
 				       struct sockaddr *sa,
 				       struct sockaddr *sa,
@@ -214,7 +218,9 @@ out:
 static int rds_rdma_listen_init(void)
 static int rds_rdma_listen_init(void)
 {
 {
 	int ret;
 	int ret;
+#if IS_ENABLED(CONFIG_IPV6)
 	struct sockaddr_in6 sin6;
 	struct sockaddr_in6 sin6;
+#endif
 	struct sockaddr_in sin;
 	struct sockaddr_in sin;
 
 
 	sin.sin_family = PF_INET;
 	sin.sin_family = PF_INET;
@@ -226,6 +232,7 @@ static int rds_rdma_listen_init(void)
 	if (ret != 0)
 	if (ret != 0)
 		return ret;
 		return ret;
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 	sin6.sin6_family = PF_INET6;
 	sin6.sin6_family = PF_INET6;
 	sin6.sin6_addr = in6addr_any;
 	sin6.sin6_addr = in6addr_any;
 	sin6.sin6_port = htons(RDS_CM_PORT);
 	sin6.sin6_port = htons(RDS_CM_PORT);
@@ -237,6 +244,7 @@ static int rds_rdma_listen_init(void)
 	/* Keep going even when IPv6 is not enabled in the system. */
 	/* Keep going even when IPv6 is not enabled in the system. */
 	if (ret != 0)
 	if (ret != 0)
 		rdsdebug("Cannot set up IPv6 RDMA listener\n");
 		rdsdebug("Cannot set up IPv6 RDMA listener\n");
+#endif
 	return 0;
 	return 0;
 }
 }
 
 
@@ -247,11 +255,13 @@ static void rds_rdma_listen_stop(void)
 		rdma_destroy_id(rds_rdma_listen_id);
 		rdma_destroy_id(rds_rdma_listen_id);
 		rds_rdma_listen_id = NULL;
 		rds_rdma_listen_id = NULL;
 	}
 	}
+#if IS_ENABLED(CONFIG_IPV6)
 	if (rds6_rdma_listen_id) {
 	if (rds6_rdma_listen_id) {
 		rdsdebug("cm %p\n", rds6_rdma_listen_id);
 		rdsdebug("cm %p\n", rds6_rdma_listen_id);
 		rdma_destroy_id(rds6_rdma_listen_id);
 		rdma_destroy_id(rds6_rdma_listen_id);
 		rds6_rdma_listen_id = NULL;
 		rds6_rdma_listen_id = NULL;
 	}
 	}
+#endif
 }
 }
 
 
 static int rds_rdma_init(void)
 static int rds_rdma_init(void)

+ 2 - 0
net/rds/recv.c

@@ -793,6 +793,7 @@ void rds_inc_info_copy(struct rds_incoming *inc,
 	rds_info_copy(iter, &minfo, sizeof(minfo));
 	rds_info_copy(iter, &minfo, sizeof(minfo));
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 void rds6_inc_info_copy(struct rds_incoming *inc,
 void rds6_inc_info_copy(struct rds_incoming *inc,
 			struct rds_info_iterator *iter,
 			struct rds_info_iterator *iter,
 			struct in6_addr *saddr, struct in6_addr *daddr,
 			struct in6_addr *saddr, struct in6_addr *daddr,
@@ -817,3 +818,4 @@ void rds6_inc_info_copy(struct rds_incoming *inc,
 
 
 	rds_info_copy(iter, &minfo6, sizeof(minfo6));
 	rds_info_copy(iter, &minfo6, sizeof(minfo6));
 }
 }
+#endif

+ 2 - 0
net/rds/send.c

@@ -1103,6 +1103,7 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
 			dport = usin->sin_port;
 			dport = usin->sin_port;
 			break;
 			break;
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 		case AF_INET6: {
 		case AF_INET6: {
 			int addr_type;
 			int addr_type;
 
 
@@ -1142,6 +1143,7 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
 			dport = sin6->sin6_port;
 			dport = sin6->sin6_port;
 			break;
 			break;
 		}
 		}
+#endif
 
 
 		default:
 		default:
 			ret = -EINVAL;
 			ret = -EINVAL;

+ 25 - 0
net/rds/tcp.c

@@ -51,7 +51,9 @@ static LIST_HEAD(rds_tcp_tc_list);
  * rds6_tcp_tc_count counts both IPv4 and IPv6 connections.
  * rds6_tcp_tc_count counts both IPv4 and IPv6 connections.
  */
  */
 static unsigned int rds_tcp_tc_count;
 static unsigned int rds_tcp_tc_count;
+#if IS_ENABLED(CONFIG_IPV6)
 static unsigned int rds6_tcp_tc_count;
 static unsigned int rds6_tcp_tc_count;
+#endif
 
 
 /* Track rds_tcp_connection structs so they can be cleaned up */
 /* Track rds_tcp_connection structs so they can be cleaned up */
 static DEFINE_SPINLOCK(rds_tcp_conn_lock);
 static DEFINE_SPINLOCK(rds_tcp_conn_lock);
@@ -118,7 +120,9 @@ void rds_tcp_restore_callbacks(struct socket *sock,
 	/* done under the callback_lock to serialize with write_space */
 	/* done under the callback_lock to serialize with write_space */
 	spin_lock(&rds_tcp_tc_list_lock);
 	spin_lock(&rds_tcp_tc_list_lock);
 	list_del_init(&tc->t_list_item);
 	list_del_init(&tc->t_list_item);
+#if IS_ENABLED(CONFIG_IPV6)
 	rds6_tcp_tc_count--;
 	rds6_tcp_tc_count--;
+#endif
 	if (!tc->t_cpath->cp_conn->c_isv6)
 	if (!tc->t_cpath->cp_conn->c_isv6)
 		rds_tcp_tc_count--;
 		rds_tcp_tc_count--;
 	spin_unlock(&rds_tcp_tc_list_lock);
 	spin_unlock(&rds_tcp_tc_list_lock);
@@ -207,7 +211,9 @@ void rds_tcp_set_callbacks(struct socket *sock, struct rds_conn_path *cp)
 	/* done under the callback_lock to serialize with write_space */
 	/* done under the callback_lock to serialize with write_space */
 	spin_lock(&rds_tcp_tc_list_lock);
 	spin_lock(&rds_tcp_tc_list_lock);
 	list_add_tail(&tc->t_list_item, &rds_tcp_tc_list);
 	list_add_tail(&tc->t_list_item, &rds_tcp_tc_list);
+#if IS_ENABLED(CONFIG_IPV6)
 	rds6_tcp_tc_count++;
 	rds6_tcp_tc_count++;
+#endif
 	if (!tc->t_cpath->cp_conn->c_isv6)
 	if (!tc->t_cpath->cp_conn->c_isv6)
 		rds_tcp_tc_count++;
 		rds_tcp_tc_count++;
 	spin_unlock(&rds_tcp_tc_list_lock);
 	spin_unlock(&rds_tcp_tc_list_lock);
@@ -273,6 +279,7 @@ out:
 	spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags);
 	spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags);
 }
 }
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 /* Handle RDS6_INFO_TCP_SOCKETS socket option. It returns both IPv4 and
 /* Handle RDS6_INFO_TCP_SOCKETS socket option. It returns both IPv4 and
  * IPv6 connections. IPv4 connection address is returned in an IPv4 mapped
  * IPv6 connections. IPv4 connection address is returned in an IPv4 mapped
  * address.
  * address.
@@ -314,12 +321,15 @@ out:
 
 
 	spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags);
 	spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags);
 }
 }
+#endif
 
 
 static int rds_tcp_laddr_check(struct net *net, const struct in6_addr *addr,
 static int rds_tcp_laddr_check(struct net *net, const struct in6_addr *addr,
 			       __u32 scope_id)
 			       __u32 scope_id)
 {
 {
 	struct net_device *dev = NULL;
 	struct net_device *dev = NULL;
+#if IS_ENABLED(CONFIG_IPV6)
 	int ret;
 	int ret;
+#endif
 
 
 	if (ipv6_addr_v4mapped(addr)) {
 	if (ipv6_addr_v4mapped(addr)) {
 		if (inet_addr_type(net, addr->s6_addr32[3]) == RTN_LOCAL)
 		if (inet_addr_type(net, addr->s6_addr32[3]) == RTN_LOCAL)
@@ -340,9 +350,11 @@ static int rds_tcp_laddr_check(struct net *net, const struct in6_addr *addr,
 		}
 		}
 		rcu_read_unlock();
 		rcu_read_unlock();
 	}
 	}
+#if IS_ENABLED(CONFIG_IPV6)
 	ret = ipv6_chk_addr(net, addr, dev, 0);
 	ret = ipv6_chk_addr(net, addr, dev, 0);
 	if (ret)
 	if (ret)
 		return 0;
 		return 0;
+#endif
 	return -EADDRNOTAVAIL;
 	return -EADDRNOTAVAIL;
 }
 }
 
 
@@ -545,18 +557,27 @@ static __net_init int rds_tcp_init_net(struct net *net)
 		err = -ENOMEM;
 		err = -ENOMEM;
 		goto fail;
 		goto fail;
 	}
 	}
+
+#if IS_ENABLED(CONFIG_IPV6)
 	rtn->rds_tcp_listen_sock = rds_tcp_listen_init(net, true);
 	rtn->rds_tcp_listen_sock = rds_tcp_listen_init(net, true);
+#else
+	rtn->rds_tcp_listen_sock = rds_tcp_listen_init(net, false);
+#endif
 	if (!rtn->rds_tcp_listen_sock) {
 	if (!rtn->rds_tcp_listen_sock) {
 		pr_warn("could not set up IPv6 listen sock\n");
 		pr_warn("could not set up IPv6 listen sock\n");
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 		/* Try IPv4 as some systems disable IPv6 */
 		/* Try IPv4 as some systems disable IPv6 */
 		rtn->rds_tcp_listen_sock = rds_tcp_listen_init(net, false);
 		rtn->rds_tcp_listen_sock = rds_tcp_listen_init(net, false);
 		if (!rtn->rds_tcp_listen_sock) {
 		if (!rtn->rds_tcp_listen_sock) {
+#endif
 			unregister_net_sysctl_table(rtn->rds_tcp_sysctl);
 			unregister_net_sysctl_table(rtn->rds_tcp_sysctl);
 			rtn->rds_tcp_sysctl = NULL;
 			rtn->rds_tcp_sysctl = NULL;
 			err = -EAFNOSUPPORT;
 			err = -EAFNOSUPPORT;
 			goto fail;
 			goto fail;
+#if IS_ENABLED(CONFIG_IPV6)
 		}
 		}
+#endif
 	}
 	}
 	INIT_WORK(&rtn->rds_tcp_accept_w, rds_tcp_accept_worker);
 	INIT_WORK(&rtn->rds_tcp_accept_w, rds_tcp_accept_worker);
 	return 0;
 	return 0;
@@ -670,7 +691,9 @@ static void rds_tcp_exit(void)
 	rds_tcp_set_unloading();
 	rds_tcp_set_unloading();
 	synchronize_rcu();
 	synchronize_rcu();
 	rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
 	rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
+#if IS_ENABLED(CONFIG_IPV6)
 	rds_info_deregister_func(RDS6_INFO_TCP_SOCKETS, rds6_tcp_tc_info);
 	rds_info_deregister_func(RDS6_INFO_TCP_SOCKETS, rds6_tcp_tc_info);
+#endif
 	unregister_pernet_device(&rds_tcp_net_ops);
 	unregister_pernet_device(&rds_tcp_net_ops);
 	rds_tcp_destroy_conns();
 	rds_tcp_destroy_conns();
 	rds_trans_unregister(&rds_tcp_transport);
 	rds_trans_unregister(&rds_tcp_transport);
@@ -702,7 +725,9 @@ static int rds_tcp_init(void)
 	rds_trans_register(&rds_tcp_transport);
 	rds_trans_register(&rds_tcp_transport);
 
 
 	rds_info_register_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
 	rds_info_register_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
+#if IS_ENABLED(CONFIG_IPV6)
 	rds_info_register_func(RDS6_INFO_TCP_SOCKETS, rds6_tcp_tc_info);
 	rds_info_register_func(RDS6_INFO_TCP_SOCKETS, rds6_tcp_tc_info);
+#endif
 
 
 	goto out;
 	goto out;
 out_recv:
 out_recv:

+ 17 - 4
net/rds/tcp_listen.c

@@ -132,7 +132,10 @@ int rds_tcp_accept_one(struct socket *sock)
 	int conn_state;
 	int conn_state;
 	struct rds_conn_path *cp;
 	struct rds_conn_path *cp;
 	struct in6_addr *my_addr, *peer_addr;
 	struct in6_addr *my_addr, *peer_addr;
-	int dev_if;
+#if !IS_ENABLED(CONFIG_IPV6)
+	struct in6_addr saddr, daddr;
+#endif
+	int dev_if = 0;
 
 
 	if (!sock) /* module unload or netns delete in progress */
 	if (!sock) /* module unload or netns delete in progress */
 		return -ENETUNREACH;
 		return -ENETUNREACH;
@@ -165,12 +168,21 @@ int rds_tcp_accept_one(struct socket *sock)
 
 
 	inet = inet_sk(new_sock->sk);
 	inet = inet_sk(new_sock->sk);
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 	my_addr = &new_sock->sk->sk_v6_rcv_saddr;
 	my_addr = &new_sock->sk->sk_v6_rcv_saddr;
 	peer_addr = &new_sock->sk->sk_v6_daddr;
 	peer_addr = &new_sock->sk->sk_v6_daddr;
-	rdsdebug("accepted tcp %pI6c:%u -> %pI6c:%u\n",
+#else
+	ipv6_addr_set_v4mapped(inet->inet_saddr, &saddr);
+	ipv6_addr_set_v4mapped(inet->inet_daddr, &daddr);
+	my_addr = &saddr;
+	peer_addr = &daddr;
+#endif
+	rdsdebug("accepted family %d tcp %pI6c:%u -> %pI6c:%u\n",
+		 sock->sk->sk_family,
 		 my_addr, ntohs(inet->inet_sport),
 		 my_addr, ntohs(inet->inet_sport),
 		 peer_addr, ntohs(inet->inet_dport));
 		 peer_addr, ntohs(inet->inet_dport));
 
 
+#if IS_ENABLED(CONFIG_IPV6)
 	/* sk_bound_dev_if is not set if the peer address is not link local
 	/* sk_bound_dev_if is not set if the peer address is not link local
 	 * address.  In this case, it happens that mcast_oif is set.  So
 	 * address.  In this case, it happens that mcast_oif is set.  So
 	 * just use it.
 	 * just use it.
@@ -184,9 +196,10 @@ int rds_tcp_accept_one(struct socket *sock)
 	} else {
 	} else {
 		dev_if = new_sock->sk->sk_bound_dev_if;
 		dev_if = new_sock->sk->sk_bound_dev_if;
 	}
 	}
+#endif
+
 	conn = rds_conn_create(sock_net(sock->sk),
 	conn = rds_conn_create(sock_net(sock->sk),
-			       &new_sock->sk->sk_v6_rcv_saddr,
-			       &new_sock->sk->sk_v6_daddr,
+			       my_addr, peer_addr,
 			       &rds_tcp_transport, GFP_KERNEL, dev_if);
 			       &rds_tcp_transport, GFP_KERNEL, dev_if);
 
 
 	if (IS_ERR(conn)) {
 	if (IS_ERR(conn)) {