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>
This commit is contained in:
Ka-Cheong Poon 2018-07-30 22:48:42 -07:00 committed by David S. Miller
parent f394ad28fe
commit e65d4d9633
12 changed files with 140 additions and 26 deletions

View File

@ -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.

View File

@ -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) & #if IS_ENABLED(CONFIG_IPV6)
IPV6_ADDR_MAPPED) { if (!(ipv6_addr_type(&rs->rs_conn_addr) &
sin = (struct sockaddr_in *)uaddr; IPV6_ADDR_MAPPED)) {
memset(sin, 0, sizeof(*sin)); sin6 = (struct sockaddr_in6 *)uaddr;
sin->sin_family = AF_INET; memset(sin6, 0, sizeof(*sin6));
return sizeof(*sin); sin6->sin6_family = AF_INET6;
return sizeof(*sin6);
} }
#endif
sin6 = (struct sockaddr_in6 *)uaddr; sin = (struct sockaddr_in *)uaddr;
memset(sin6, 0, sizeof(*sin6)); memset(sin, 0, sizeof(*sin));
sin6->sin6_family = AF_INET6; sin->sin_family = AF_INET;
return sizeof(*sin6); 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;

View File

@ -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;
} }

View File

@ -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
} }
/* /*

View File

@ -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) if (scope_id == 0) {
return -EADDRNOTAVAIL; 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) if (!dev) {
return -EADDRNOTAVAIL; 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;

View File

@ -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);

View File

@ -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)
{ {

View File

@ -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 @@ static int rds_rdma_listen_init_common(rdma_cm_event_handler handler,
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)

View File

@ -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

View File

@ -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;

View File

@ -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 @@ static void rds_tcp_tc_info(struct socket *rds_sock, unsigned int len,
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 @@ static void rds6_tcp_tc_info(struct socket *sock, unsigned int len,
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:

View File

@ -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, my_addr, peer_addr,
&new_sock->sk->sk_v6_daddr,
&rds_tcp_transport, GFP_KERNEL, dev_if); &rds_tcp_transport, GFP_KERNEL, dev_if);
if (IS_ERR(conn)) { if (IS_ERR(conn)) {