Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rds: rdma: add consumer reject

For legacy protocol version incompatibility with non linux RDS,
consumer reject reason being used to convey it to peer. But the
choice of reject reason value as '1' was really poor.

Anyway for interoperability reasons with shipping products,
it needs to be supported. For any future versions, properly
encoded reject reason should to be used.

Reviewed-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
[yanjun.zhu@oracle.com: Adapted original patch with ipv6 changes]
Signed-off-by: Zhu Yanjun <yanjun.zhu@oracle.com>

+22 -2
+4 -2
net/rds/ib_cm.c
··· 734 734 735 735 /* Check whether the remote protocol version matches ours. */ 736 736 version = rds_ib_protocol_compatible(event, isv6); 737 - if (!version) 737 + if (!version) { 738 + err = RDS_RDMA_REJ_INCOMPAT; 738 739 goto out; 740 + } 739 741 740 742 dp = event->param.conn.private_data; 741 743 if (isv6) { ··· 853 851 if (conn) 854 852 mutex_unlock(&conn->c_cm_lock); 855 853 if (err) 856 - rdma_reject(cm_id, NULL, 0); 854 + rdma_reject(cm_id, &err, sizeof(int)); 857 855 return destroy; 858 856 } 859 857
+12
net/rds/rdma_transport.c
··· 51 51 struct rds_connection *conn = cm_id->context; 52 52 struct rds_transport *trans; 53 53 int ret = 0; 54 + int *err; 55 + u8 len; 54 56 55 57 rdsdebug("conn %p id %p handling event %u (%s)\n", conn, cm_id, 56 58 event->event, rdma_event_msg(event->event)); ··· 108 106 break; 109 107 110 108 case RDMA_CM_EVENT_REJECTED: 109 + if (!conn) 110 + break; 111 + err = (int *)rdma_consumer_reject_data(cm_id, event, &len); 112 + if (!err || (err && ((*err) == RDS_RDMA_REJ_INCOMPAT))) { 113 + pr_warn("RDS/RDMA: conn <%pI6c, %pI6c> rejected, dropping connection\n", 114 + &conn->c_laddr, &conn->c_faddr); 115 + conn->c_proposed_version = RDS_PROTOCOL_COMPAT_VERSION; 116 + rds_conn_drop(conn); 117 + } 111 118 rdsdebug("Connection rejected: %s\n", 112 119 rdma_reject_msg(cm_id, event->status)); 120 + break; 113 121 /* FALLTHROUGH */ 114 122 case RDMA_CM_EVENT_ADDR_ERROR: 115 123 case RDMA_CM_EVENT_ROUTE_ERROR:
+6
net/rds/rdma_transport.h
··· 11 11 12 12 #define RDS_RDMA_RESOLVE_TIMEOUT_MS 5000 13 13 14 + /* Below reject reason is for legacy interoperability issue with non-linux 15 + * RDS endpoints where older version incompatibility is conveyed via value 1. 16 + * For future version(s), proper encoded reject reason should be be used. 17 + */ 18 + #define RDS_RDMA_REJ_INCOMPAT 1 19 + 14 20 int rds_rdma_conn_connect(struct rds_connection *conn); 15 21 int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, 16 22 struct rdma_cm_event *event);