[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