[openib-general] [PATCH] rdma cm: add sdp version checks

Sean Hefty sean.hefty at intel.com
Fri Apr 28 13:58:49 PDT 2006


Let SDP determine which version of the SDP headers to use.  The
CMA will check that it can support that version, and set the
address fields appropriately.

The CMA will also verify that the major SDP and IP versions are
supported on received REQ and REP messages.  If an unsupported
version is received, the connection will be aborted.  This will
result in sending a consumer REJ message when the cm_id is
destroyed.

Signed-off-by: Sean Hefty <sean.hefty at intel.com
---
Michael, can you test this against SDP?  This patch should address
CA4-15, 17, and 22.  CA4-43 is handled automatically by the IB CM
when the cm_id is destroyed.

Index: cma.c
===================================================================
--- cma.c	(revision 6627)
+++ cma.c	(working copy)
@@ -153,7 +153,7 @@ struct cma_hdr {
 
 struct sdp_hh {
 	u8 bsdh[16];
-	u8 sdp_version;
+	u8 sdp_version; /* Major version: 7:4 */
 	u8 ip_version;	/* IP version: 7:4 */
 	u8 sdp_specific1[10];
 	__u16 port;
@@ -162,8 +162,13 @@ struct sdp_hh {
 	union cma_ip_addr dst_addr;
 };
 
+struct sdp_hah {
+	u8 bsdh[16];
+	u8 sdp_version;
+};
+
 #define CMA_VERSION 0x00
-#define SDP_VERSION 0x22
+#define SDP_MAJ_VERSION 0x2
 
 static int cma_comp(struct rdma_id_private *id_priv, enum cma_state comp)
 {
@@ -212,6 +217,11 @@ static inline void cma_set_ip_ver(struct
 	hdr->ip_version = (ip_ver << 4) | (hdr->ip_version & 0xF);
 }
 
+static inline u8 sdp_get_majv(u8 sdp_version)
+{
+	return sdp_version >> 4;
+}
+
 static inline u8 sdp_get_ip_ver(struct sdp_hh *hh)
 {
 	return hh->ip_version >> 4;
@@ -483,7 +493,8 @@ static int cma_get_net_info(void *hdr, e
 {
 	switch (ps) {
 	case RDMA_PS_SDP:
-		if (((struct sdp_hh *) hdr)->sdp_version != SDP_VERSION)
+		if (sdp_get_majv(((struct sdp_hh *) hdr)->sdp_version) !=
+		    SDP_MAJ_VERSION)
 			return -EINVAL;
 
 		*ip_ver	= sdp_get_ip_ver(hdr);
@@ -501,6 +512,9 @@ static int cma_get_net_info(void *hdr, e
 		*dst	= &((struct cma_hdr *) hdr)->dst_addr;
 		break;
 	}
+
+	if (*ip_ver != 4 && *ip_ver != 6)
+		return -EINVAL;
 	return 0;
 }
 
@@ -714,6 +728,16 @@ reject:
 	return ret;
 }
 
+static int cma_verify_rep(struct rdma_id_private *id_priv, void *data)
+{
+	if (id_priv->id.ps == RDMA_PS_SDP &&
+	    sdp_get_majv(((struct sdp_hah *) data)->sdp_version) !=
+	    SDP_MAJ_VERSION)
+		return -EINVAL;
+
+	return 0;
+}
+
 static int cma_rtu_recv(struct rdma_id_private *id_priv)
 {
 	int ret;
@@ -748,7 +772,10 @@ static int cma_ib_handler(struct ib_cm_i
 		status = -ETIMEDOUT;
 		break;
 	case IB_CM_REP_RECEIVED:
-		if (id_priv->id.qp) {
+		status = cma_verify_rep(id_priv, ib_event->private_data);
+		if (status)
+			event = RDMA_CM_EVENT_CONNECT_ERROR;
+		else if (id_priv->id.qp) {
 			status = cma_rep_recv(id_priv);
 			event = status ? RDMA_CM_EVENT_CONNECT_ERROR :
 					 RDMA_CM_EVENT_ESTABLISHED;
@@ -1473,8 +1500,8 @@ err:
 }
 EXPORT_SYMBOL(rdma_bind_addr);
 
-static void cma_format_hdr(void *hdr, enum rdma_port_space ps,
-			   struct rdma_route *route)
+static int cma_format_hdr(void *hdr, enum rdma_port_space ps,
+			  struct rdma_route *route)
 {
 	struct sockaddr_in *src4, *dst4;
 	struct cma_hdr *cma_hdr;
@@ -1486,7 +1513,8 @@ static void cma_format_hdr(void *hdr, en
 	switch (ps) {
 	case RDMA_PS_SDP:
 		sdp_hdr = hdr;
-		sdp_hdr->sdp_version = SDP_VERSION;
+		if (sdp_get_majv(sdp_hdr->sdp_version) != SDP_MAJ_VERSION)
+			return -EINVAL;
 		sdp_set_ip_ver(sdp_hdr, 4);
 		sdp_hdr->src_addr.ip4.addr = src4->sin_addr.s_addr;
 		sdp_hdr->dst_addr.ip4.addr = dst4->sin_addr.s_addr;
@@ -1501,6 +1529,7 @@ static void cma_format_hdr(void *hdr, en
 		cma_hdr->port = src4->sin_port;
 		break;
 	}
+	return 0;
 }
 
 static int cma_connect_ib(struct rdma_id_private *id_priv,
@@ -1530,7 +1559,9 @@ static int cma_connect_ib(struct rdma_id
 	}
 
 	route = &id_priv->id.route;
-	cma_format_hdr(private_data, id_priv->id.ps, route);
+	ret = cma_format_hdr(private_data, id_priv->id.ps, route);
+	if (ret)
+		goto out;
 	req.private_data = private_data;
 
 	req.primary_path = &route->path_rec[0];




More information about the general mailing list