Skip to content

Commit b7ff8b1

Browse files
kcp-gitdavem330
authored andcommitted
rds: Extend RDS API for IPv6 support
There are many data structures (RDS socket options) used by RDS apps which use a 32 bit integer to store IP address. To support IPv6, struct in6_addr needs to be used. To ensure backward compatibility, a new data structure is introduced for each of those data structures which use a 32 bit integer to represent an IP address. And new socket options are introduced to use those new structures. This means that existing apps should work without a problem with the new RDS module. For apps which want to use IPv6, those new data structures and socket options can be used. IPv4 mapped address is used to represent IPv4 address in the new data structures. v4: Revert changes to SO_RDS_TRANSPORT Signed-off-by: Ka-Cheong Poon <[email protected]> Acked-by: Santosh Shilimkar <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1e2b44e commit b7ff8b1

File tree

7 files changed

+293
-11
lines changed

7 files changed

+293
-11
lines changed

include/uapi/linux/rds.h

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */
22
/*
3-
* Copyright (c) 2008 Oracle. All rights reserved.
3+
* Copyright (c) 2008, 2018 Oracle and/or its affiliates. All rights reserved.
44
*
55
* This software is available to you under a choice of one of two
66
* licenses. You may choose to be licensed under the terms of the GNU
@@ -118,7 +118,17 @@
118118
#define RDS_INFO_IB_CONNECTIONS 10008
119119
#define RDS_INFO_CONNECTION_STATS 10009
120120
#define RDS_INFO_IWARP_CONNECTIONS 10010
121-
#define RDS_INFO_LAST 10010
121+
122+
/* PF_RDS6 options */
123+
#define RDS6_INFO_CONNECTIONS 10011
124+
#define RDS6_INFO_SEND_MESSAGES 10012
125+
#define RDS6_INFO_RETRANS_MESSAGES 10013
126+
#define RDS6_INFO_RECV_MESSAGES 10014
127+
#define RDS6_INFO_SOCKETS 10015
128+
#define RDS6_INFO_TCP_SOCKETS 10016
129+
#define RDS6_INFO_IB_CONNECTIONS 10017
130+
131+
#define RDS_INFO_LAST 10017
122132

123133
struct rds_info_counter {
124134
__u8 name[32];
@@ -140,6 +150,15 @@ struct rds_info_connection {
140150
__u8 flags;
141151
} __attribute__((packed));
142152

153+
struct rds6_info_connection {
154+
__u64 next_tx_seq;
155+
__u64 next_rx_seq;
156+
struct in6_addr laddr;
157+
struct in6_addr faddr;
158+
__u8 transport[TRANSNAMSIZ]; /* null term ascii */
159+
__u8 flags;
160+
} __attribute__((packed));
161+
143162
#define RDS_INFO_MESSAGE_FLAG_ACK 0x01
144163
#define RDS_INFO_MESSAGE_FLAG_FAST_ACK 0x02
145164

@@ -153,6 +172,17 @@ struct rds_info_message {
153172
__u8 flags;
154173
} __attribute__((packed));
155174

175+
struct rds6_info_message {
176+
__u64 seq;
177+
__u32 len;
178+
struct in6_addr laddr;
179+
struct in6_addr faddr;
180+
__be16 lport;
181+
__be16 fport;
182+
__u8 flags;
183+
__u8 tos;
184+
} __attribute__((packed));
185+
156186
struct rds_info_socket {
157187
__u32 sndbuf;
158188
__be32 bound_addr;
@@ -163,6 +193,16 @@ struct rds_info_socket {
163193
__u64 inum;
164194
} __attribute__((packed));
165195

196+
struct rds6_info_socket {
197+
__u32 sndbuf;
198+
struct in6_addr bound_addr;
199+
struct in6_addr connected_addr;
200+
__be16 bound_port;
201+
__be16 connected_port;
202+
__u32 rcvbuf;
203+
__u64 inum;
204+
} __attribute__((packed));
205+
166206
struct rds_info_tcp_socket {
167207
__be32 local_addr;
168208
__be16 local_port;
@@ -175,6 +215,18 @@ struct rds_info_tcp_socket {
175215
__u32 last_seen_una;
176216
} __attribute__((packed));
177217

218+
struct rds6_info_tcp_socket {
219+
struct in6_addr local_addr;
220+
__be16 local_port;
221+
struct in6_addr peer_addr;
222+
__be16 peer_port;
223+
__u64 hdr_rem;
224+
__u64 data_rem;
225+
__u32 last_sent_nxt;
226+
__u32 last_expected_una;
227+
__u32 last_seen_una;
228+
} __attribute__((packed));
229+
178230
#define RDS_IB_GID_LEN 16
179231
struct rds_info_rdma_connection {
180232
__be32 src_addr;
@@ -189,6 +241,19 @@ struct rds_info_rdma_connection {
189241
__u32 rdma_mr_size;
190242
};
191243

244+
struct rds6_info_rdma_connection {
245+
struct in6_addr src_addr;
246+
struct in6_addr dst_addr;
247+
__u8 src_gid[RDS_IB_GID_LEN];
248+
__u8 dst_gid[RDS_IB_GID_LEN];
249+
250+
__u32 max_send_wr;
251+
__u32 max_recv_wr;
252+
__u32 max_send_sge;
253+
__u32 rdma_mr_max;
254+
__u32 rdma_mr_size;
255+
};
256+
192257
/* RDS message Receive Path Latency points */
193258
enum rds_message_rxpath_latency {
194259
RDS_MSG_RX_HDR_TO_DGRAM_START = 0,

net/rds/connection.c

Lines changed: 93 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -498,16 +498,19 @@ EXPORT_SYMBOL_GPL(rds_conn_destroy);
498498

499499
static void __rds_inc_msg_cp(struct rds_incoming *inc,
500500
struct rds_info_iterator *iter,
501-
void *saddr, void *daddr, int flip)
501+
void *saddr, void *daddr, int flip, bool isv6)
502502
{
503-
rds_inc_info_copy(inc, iter, *(__be32 *)saddr,
504-
*(__be32 *)daddr, flip);
503+
if (isv6)
504+
rds6_inc_info_copy(inc, iter, saddr, daddr, flip);
505+
else
506+
rds_inc_info_copy(inc, iter, *(__be32 *)saddr,
507+
*(__be32 *)daddr, flip);
505508
}
506509

507510
static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
508511
struct rds_info_iterator *iter,
509512
struct rds_info_lengths *lens,
510-
int want_send)
513+
int want_send, bool isv6)
511514
{
512515
struct hlist_head *head;
513516
struct list_head *list;
@@ -518,7 +521,10 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
518521
size_t i;
519522
int j;
520523

521-
len /= sizeof(struct rds_info_message);
524+
if (isv6)
525+
len /= sizeof(struct rds6_info_message);
526+
else
527+
len /= sizeof(struct rds_info_message);
522528

523529
rcu_read_lock();
524530

@@ -528,6 +534,9 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
528534
struct rds_conn_path *cp;
529535
int npaths;
530536

537+
if (!isv6 && conn->c_isv6)
538+
continue;
539+
531540
npaths = (conn->c_trans->t_mp_capable ?
532541
RDS_MPATH_WORKERS : 1);
533542

@@ -548,7 +557,7 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
548557
iter,
549558
&conn->c_laddr,
550559
&conn->c_faddr,
551-
0);
560+
0, isv6);
552561
}
553562

554563
spin_unlock_irqrestore(&cp->cp_lock, flags);
@@ -558,15 +567,26 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
558567
rcu_read_unlock();
559568

560569
lens->nr = total;
561-
lens->each = sizeof(struct rds_info_message);
570+
if (isv6)
571+
lens->each = sizeof(struct rds6_info_message);
572+
else
573+
lens->each = sizeof(struct rds_info_message);
562574
}
563575

564576
static void rds_conn_message_info(struct socket *sock, unsigned int len,
565577
struct rds_info_iterator *iter,
566578
struct rds_info_lengths *lens,
567579
int want_send)
568580
{
569-
rds_conn_message_info_cmn(sock, len, iter, lens, want_send);
581+
rds_conn_message_info_cmn(sock, len, iter, lens, want_send, false);
582+
}
583+
584+
static void rds6_conn_message_info(struct socket *sock, unsigned int len,
585+
struct rds_info_iterator *iter,
586+
struct rds_info_lengths *lens,
587+
int want_send)
588+
{
589+
rds_conn_message_info_cmn(sock, len, iter, lens, want_send, true);
570590
}
571591

572592
static void rds_conn_message_info_send(struct socket *sock, unsigned int len,
@@ -576,6 +596,13 @@ static void rds_conn_message_info_send(struct socket *sock, unsigned int len,
576596
rds_conn_message_info(sock, len, iter, lens, 1);
577597
}
578598

599+
static void rds6_conn_message_info_send(struct socket *sock, unsigned int len,
600+
struct rds_info_iterator *iter,
601+
struct rds_info_lengths *lens)
602+
{
603+
rds6_conn_message_info(sock, len, iter, lens, 1);
604+
}
605+
579606
static void rds_conn_message_info_retrans(struct socket *sock,
580607
unsigned int len,
581608
struct rds_info_iterator *iter,
@@ -584,6 +611,14 @@ static void rds_conn_message_info_retrans(struct socket *sock,
584611
rds_conn_message_info(sock, len, iter, lens, 0);
585612
}
586613

614+
static void rds6_conn_message_info_retrans(struct socket *sock,
615+
unsigned int len,
616+
struct rds_info_iterator *iter,
617+
struct rds_info_lengths *lens)
618+
{
619+
rds6_conn_message_info(sock, len, iter, lens, 0);
620+
}
621+
587622
void rds_for_each_conn_info(struct socket *sock, unsigned int len,
588623
struct rds_info_iterator *iter,
589624
struct rds_info_lengths *lens,
@@ -699,6 +734,34 @@ static int rds_conn_info_visitor(struct rds_conn_path *cp, void *buffer)
699734
return 1;
700735
}
701736

737+
static int rds6_conn_info_visitor(struct rds_conn_path *cp, void *buffer)
738+
{
739+
struct rds6_info_connection *cinfo6 = buffer;
740+
struct rds_connection *conn = cp->cp_conn;
741+
742+
cinfo6->next_tx_seq = cp->cp_next_tx_seq;
743+
cinfo6->next_rx_seq = cp->cp_next_rx_seq;
744+
cinfo6->laddr = conn->c_laddr;
745+
cinfo6->faddr = conn->c_faddr;
746+
strncpy(cinfo6->transport, conn->c_trans->t_name,
747+
sizeof(cinfo6->transport));
748+
cinfo6->flags = 0;
749+
750+
rds_conn_info_set(cinfo6->flags, test_bit(RDS_IN_XMIT, &cp->cp_flags),
751+
SENDING);
752+
/* XXX Future: return the state rather than these funky bits */
753+
rds_conn_info_set(cinfo6->flags,
754+
atomic_read(&cp->cp_state) == RDS_CONN_CONNECTING,
755+
CONNECTING);
756+
rds_conn_info_set(cinfo6->flags,
757+
atomic_read(&cp->cp_state) == RDS_CONN_UP,
758+
CONNECTED);
759+
/* Just return 1 as there is no error case. This is a helper function
760+
* for rds_walk_conn_path_info() and it wants a return value.
761+
*/
762+
return 1;
763+
}
764+
702765
static void rds_conn_info(struct socket *sock, unsigned int len,
703766
struct rds_info_iterator *iter,
704767
struct rds_info_lengths *lens)
@@ -711,6 +774,18 @@ static void rds_conn_info(struct socket *sock, unsigned int len,
711774
sizeof(struct rds_info_connection));
712775
}
713776

777+
static void rds6_conn_info(struct socket *sock, unsigned int len,
778+
struct rds_info_iterator *iter,
779+
struct rds_info_lengths *lens)
780+
{
781+
u64 buffer[(sizeof(struct rds6_info_connection) + 7) / 8];
782+
783+
rds_walk_conn_path_info(sock, len, iter, lens,
784+
rds6_conn_info_visitor,
785+
buffer,
786+
sizeof(struct rds6_info_connection));
787+
}
788+
714789
int rds_conn_init(void)
715790
{
716791
int ret;
@@ -732,6 +807,11 @@ int rds_conn_init(void)
732807
rds_conn_message_info_send);
733808
rds_info_register_func(RDS_INFO_RETRANS_MESSAGES,
734809
rds_conn_message_info_retrans);
810+
rds_info_register_func(RDS6_INFO_CONNECTIONS, rds6_conn_info);
811+
rds_info_register_func(RDS6_INFO_SEND_MESSAGES,
812+
rds6_conn_message_info_send);
813+
rds_info_register_func(RDS6_INFO_RETRANS_MESSAGES,
814+
rds6_conn_message_info_retrans);
735815

736816
return 0;
737817
}
@@ -750,6 +830,11 @@ void rds_conn_exit(void)
750830
rds_conn_message_info_send);
751831
rds_info_deregister_func(RDS_INFO_RETRANS_MESSAGES,
752832
rds_conn_message_info_retrans);
833+
rds_info_deregister_func(RDS6_INFO_CONNECTIONS, rds6_conn_info);
834+
rds_info_deregister_func(RDS6_INFO_SEND_MESSAGES,
835+
rds6_conn_message_info_send);
836+
rds_info_deregister_func(RDS6_INFO_RETRANS_MESSAGES,
837+
rds6_conn_message_info_retrans);
753838
}
754839

755840
/*

net/rds/ib.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,43 @@ static int rds_ib_conn_info_visitor(struct rds_connection *conn,
321321
return 1;
322322
}
323323

324+
/* IPv6 version of rds_ib_conn_info_visitor(). */
325+
static int rds6_ib_conn_info_visitor(struct rds_connection *conn,
326+
void *buffer)
327+
{
328+
struct rds6_info_rdma_connection *iinfo6 = buffer;
329+
struct rds_ib_connection *ic;
330+
331+
/* We will only ever look at IB transports */
332+
if (conn->c_trans != &rds_ib_transport)
333+
return 0;
334+
335+
iinfo6->src_addr = conn->c_laddr;
336+
iinfo6->dst_addr = conn->c_faddr;
337+
338+
memset(&iinfo6->src_gid, 0, sizeof(iinfo6->src_gid));
339+
memset(&iinfo6->dst_gid, 0, sizeof(iinfo6->dst_gid));
340+
341+
if (rds_conn_state(conn) == RDS_CONN_UP) {
342+
struct rds_ib_device *rds_ibdev;
343+
struct rdma_dev_addr *dev_addr;
344+
345+
ic = conn->c_transport_data;
346+
dev_addr = &ic->i_cm_id->route.addr.dev_addr;
347+
rdma_addr_get_sgid(dev_addr,
348+
(union ib_gid *)&iinfo6->src_gid);
349+
rdma_addr_get_dgid(dev_addr,
350+
(union ib_gid *)&iinfo6->dst_gid);
351+
352+
rds_ibdev = ic->rds_ibdev;
353+
iinfo6->max_send_wr = ic->i_send_ring.w_nr;
354+
iinfo6->max_recv_wr = ic->i_recv_ring.w_nr;
355+
iinfo6->max_send_sge = rds_ibdev->max_sge;
356+
rds6_ib_get_mr_info(rds_ibdev, iinfo6);
357+
}
358+
return 1;
359+
}
360+
324361
static void rds_ib_ic_info(struct socket *sock, unsigned int len,
325362
struct rds_info_iterator *iter,
326363
struct rds_info_lengths *lens)
@@ -333,6 +370,19 @@ static void rds_ib_ic_info(struct socket *sock, unsigned int len,
333370
sizeof(struct rds_info_rdma_connection));
334371
}
335372

373+
/* IPv6 version of rds_ib_ic_info(). */
374+
static void rds6_ib_ic_info(struct socket *sock, unsigned int len,
375+
struct rds_info_iterator *iter,
376+
struct rds_info_lengths *lens)
377+
{
378+
u64 buffer[(sizeof(struct rds6_info_rdma_connection) + 7) / 8];
379+
380+
rds_for_each_conn_info(sock, len, iter, lens,
381+
rds6_ib_conn_info_visitor,
382+
buffer,
383+
sizeof(struct rds6_info_rdma_connection));
384+
}
385+
336386
/*
337387
* Early RDS/IB was built to only bind to an address if there is an IPoIB
338388
* device with that address set.
@@ -441,6 +491,7 @@ void rds_ib_exit(void)
441491
rds_ib_set_unloading();
442492
synchronize_rcu();
443493
rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
494+
rds_info_deregister_func(RDS6_INFO_IB_CONNECTIONS, rds6_ib_ic_info);
444495
rds_ib_unregister_client();
445496
rds_ib_destroy_nodev_conns();
446497
rds_ib_sysctl_exit();
@@ -502,6 +553,7 @@ int rds_ib_init(void)
502553
rds_trans_register(&rds_ib_transport);
503554

504555
rds_info_register_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
556+
rds_info_register_func(RDS6_INFO_IB_CONNECTIONS, rds6_ib_ic_info);
505557

506558
goto out;
507559

net/rds/ib_mr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *rds_dev,
113113
int npages);
114114
void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev,
115115
struct rds_info_rdma_connection *iinfo);
116+
void rds6_ib_get_mr_info(struct rds_ib_device *rds_ibdev,
117+
struct rds6_info_rdma_connection *iinfo6);
116118
void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *);
117119
void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents,
118120
struct rds_sock *rs, u32 *key_ret);

0 commit comments

Comments
 (0)