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 <[EMAIL PROTECTED] --- 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]; _______________________________________________ openib-general mailing list openib-general@openib.org http://openib.org/mailman/listinfo/openib-general To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general