[openib-general] [PATCH][RFC] CMA automatic port number assignment
James Lentini
jlentini at netapp.com
Fri Feb 24 09:55:43 PST 2006
The RDMA CM does not automatically assign a port number to the active
consumer on IB.
My expectation was that if the active consumer called
rdma_create_id()
rdma_resolve_addr()
rdma_create_qp()
rdma_resolve_route()
rdma_connect()
analogous to the BSD sockets sequence
socket(2)
connect(2)
the consumer would automatically be assigned a local TCP/UDP/SCTP port
number.
The simple patch below solves the problem by picking a random
ephemeral port number (where ephemeral is defined as any port > 1024).
This fix is not perfect.
The choice of port number does not coordinate with the relevant
transport stack (TCP/UDP/SDP). Given that the passive side CMA code
has the same behavior, this follows an established precedent.
Also, this method needs to be reviewed for security issues. There is
no attempt to ensure that multiple (src addr, dest addr, dest port)
triplets do not simultaneously use the same src port or to ensure that
the same port is not reused before some given timeout (e.g.
TIME_WAIT). Given that the src port is chosen at random, I would
expect both of these occurrences to be extremely unlikely.
As a reference, the actual TCP code makes this assignment in
tcp_v4_hash_connect() using the sysctl_local_port_range array to
determine the range of ephemeral ports and the
secure_tcp_port_ephemeral() function to choose a secure point to start
searching for an available port. Unfortunately neither of these are
available to module code.
Signed-off-by: James Lentini <jlentini at netapp.com>
Index: core/cma.c
===================================================================
--- core/cma.c (revision 5489)
+++ core/cma.c (working copy)
@@ -1361,6 +1361,14 @@ err:
}
EXPORT_SYMBOL(rdma_bind_addr);
+static u16 cma_generate_ephemeral_port(void)
+{
+ u16 port;
+
+ get_random_bytes(&port, sizeof port);
+ return cpu_to_be16(port | 1024U);
+}
+
static void cma_format_hdr(void *hdr, enum rdma_port_space ps,
struct rdma_route *route)
{
@@ -1371,6 +1379,9 @@ static void cma_format_hdr(void *hdr, en
src4 = (struct sockaddr_in *) &route->addr.src_addr;
dst4 = (struct sockaddr_in *) &route->addr.dst_addr;
+ if (!src4->sin_port)
+ src4->sin_port = cma_generate_ephemeral_port();
+
switch (ps) {
case RDMA_PS_SDP:
sdp_hdr = hdr;
More information about the general
mailing list