net/smc: add vendor unique experimental options area in clc handshake
authorGuangguan Wang <guangguan.wang@linux.alibaba.com>
Thu, 17 Aug 2023 13:20:28 +0000 (21:20 +0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 19 Aug 2023 11:46:52 +0000 (12:46 +0100)
Add vendor unique experimental options area in clc handshake. In clc
accept and confirm msg, vendor unique experimental options use the
16-Bytes reserved field, which defined in struct smc_clc_fce_gid_ext
in previous version. Because of the struct smc_clc_first_contact_ext
is widely used and limit the scope of modification, this patch moves
the 16-Bytes reserved field out of struct smc_clc_fce_gid_ext, and
followed with the struct smc_clc_first_contact_ext in a new struct
names struct smc_clc_first_contact_ext_v2x.

For SMC-R first connection, in previous version, the struct smc_clc_
first_contact_ext and the 16-Bytes reserved field has already been
included in clc accept and confirm msg. Thus, this patch use struct
smc_clc_first_contact_ext_v2x instead of the struct smc_clc_first_
contact_ext and the 16-Bytes reserved field in SMC-R clc accept and
confirm msg is compatible with previous version.

For SMC-D first connection, in previous version, only the struct smc_
clc_first_contact_ext is included in clc accept and confirm msg, and
the 16-Bytes reserved field is not included. Thus, when the negotiated
smc release version is the version before v2.1, we still use struct
smc_clc_first_contact_ext for compatible consideration. If the negotiated
smc release version is v2.1 or later, use struct smc_clc_first_contact_
ext_v2x instead.

Signed-off-by: Guangguan Wang <guangguan.wang@linux.alibaba.com>
Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
Reviewed-by: Jan Karcher <jaka@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/smc/af_smc.c
net/smc/smc_clc.c
net/smc/smc_clc.h

index fff196b557caaf318f30fb5d8bfcf0a92ee0320b..b80c5902f7032e77eb01a165fc8e5eaaa2bdd6d7 100644 (file)
@@ -1144,7 +1144,7 @@ static int smc_connect_ism_vlan_cleanup(struct smc_sock *smc,
 
 #define SMC_CLC_MAX_ACCEPT_LEN \
        (sizeof(struct smc_clc_msg_accept_confirm_v2) + \
-        sizeof(struct smc_clc_first_contact_ext) + \
+        sizeof(struct smc_clc_first_contact_ext_v2x) + \
         sizeof(struct smc_clc_msg_trail))
 
 /* CLC handshake during connect */
index fb0be0817e8a564a17a8431755e8c3933f5b08f1..a5b28f9c037deeaefe6c9b1fcf32dc6086553dfa 100644 (file)
@@ -391,9 +391,7 @@ smc_clc_msg_acc_conf_valid(struct smc_clc_msg_accept_confirm_v2 *clc_v2)
                        return false;
        } else {
                if (hdr->typev1 == SMC_TYPE_D &&
-                   ntohs(hdr->length) != SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 &&
-                   (ntohs(hdr->length) != SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 +
-                               sizeof(struct smc_clc_first_contact_ext)))
+                   ntohs(hdr->length) < SMCD_CLC_ACCEPT_CONFIRM_LEN_V2)
                        return false;
                if (hdr->typev1 == SMC_TYPE_R &&
                    ntohs(hdr->length) < SMCR_CLC_ACCEPT_CONFIRM_LEN_V2)
@@ -420,13 +418,19 @@ smc_clc_msg_decl_valid(struct smc_clc_msg_decline *dclc)
        return true;
 }
 
-static void smc_clc_fill_fce(struct smc_clc_first_contact_ext *fce, int *len, int release_nr)
+static int smc_clc_fill_fce(struct smc_clc_first_contact_ext_v2x *fce,
+                           struct smc_init_info *ini)
 {
+       int ret = sizeof(*fce);
+
        memset(fce, 0, sizeof(*fce));
-       fce->os_type = SMC_CLC_OS_LINUX;
-       fce->release = release_nr;
-       memcpy(fce->hostname, smc_hostname, sizeof(smc_hostname));
-       (*len) += sizeof(*fce);
+       fce->fce_v2_base.os_type = SMC_CLC_OS_LINUX;
+       fce->fce_v2_base.release = ini->release_nr;
+       memcpy(fce->fce_v2_base.hostname, smc_hostname, sizeof(smc_hostname));
+       if (ini->is_smcd && ini->release_nr < SMC_RELEASE_1)
+               ret = sizeof(struct smc_clc_first_contact_ext);
+
+       return ret;
 }
 
 /* check if received message has a correct header length and contains valid
@@ -986,13 +990,13 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
                                       u8 *eid, struct smc_init_info *ini)
 {
        struct smc_connection *conn = &smc->conn;
+       struct smc_clc_first_contact_ext_v2x fce;
        struct smc_clc_msg_accept_confirm *clc;
-       struct smc_clc_first_contact_ext fce;
        struct smc_clc_fce_gid_ext gle;
        struct smc_clc_msg_trail trl;
+       int i, len, fce_len;
        struct kvec vec[5];
        struct msghdr msg;
-       int i, len;
 
        /* send SMC Confirm CLC msg */
        clc = (struct smc_clc_msg_accept_confirm *)clc_v2;
@@ -1018,8 +1022,10 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
                        if (eid && eid[0])
                                memcpy(clc_v2->d1.eid, eid, SMC_MAX_EID_LEN);
                        len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2;
-                       if (first_contact)
-                               smc_clc_fill_fce(&fce, &len, ini->release_nr);
+                       if (first_contact) {
+                               fce_len = smc_clc_fill_fce(&fce, ini);
+                               len += fce_len;
+                       }
                        clc_v2->hdr.length = htons(len);
                }
                memcpy(trl.eyecatcher, SMCD_EYECATCHER,
@@ -1063,15 +1069,14 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
                                memcpy(clc_v2->r1.eid, eid, SMC_MAX_EID_LEN);
                        len = SMCR_CLC_ACCEPT_CONFIRM_LEN_V2;
                        if (first_contact) {
-                               smc_clc_fill_fce(&fce, &len, ini->release_nr);
-                               fce.v2_direct = !link->lgr->uses_gateway;
-                               memset(&gle, 0, sizeof(gle));
+                               fce_len = smc_clc_fill_fce(&fce, ini);
+                               len += fce_len;
+                               fce.fce_v2_base.v2_direct = !link->lgr->uses_gateway;
                                if (clc->hdr.type == SMC_CLC_CONFIRM) {
+                                       memset(&gle, 0, sizeof(gle));
                                        gle.gid_cnt = ini->smcrv2.gidlist.len;
                                        len += sizeof(gle);
                                        len += gle.gid_cnt * sizeof(gle.gid[0]);
-                               } else {
-                                       len += sizeof(gle.reserved);
                                }
                        }
                        clc_v2->hdr.length = htons(len);
@@ -1094,7 +1099,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
                                   sizeof(trl);
        if (version > SMC_V1 && first_contact) {
                vec[i].iov_base = &fce;
-               vec[i++].iov_len = sizeof(fce);
+               vec[i++].iov_len = fce_len;
                if (!conn->lgr->is_smcd) {
                        if (clc->hdr.type == SMC_CLC_CONFIRM) {
                                vec[i].iov_base = &gle;
@@ -1102,9 +1107,6 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
                                vec[i].iov_base = &ini->smcrv2.gidlist.list;
                                vec[i++].iov_len = gle.gid_cnt *
                                                   sizeof(gle.gid[0]);
-                       } else {
-                               vec[i].iov_base = &gle.reserved;
-                               vec[i++].iov_len = sizeof(gle.reserved);
                        }
                }
        }
index b923e89acafb02974a8238f4b5a01aadd52abb17..bd75382f374d55fb47658cfb21b4c506ad8dda45 100644 (file)
@@ -147,7 +147,9 @@ struct smc_clc_msg_proposal_prefix {        /* prefix part of clc proposal message*/
 struct smc_clc_msg_smcd {      /* SMC-D GID information */
        struct smc_clc_smcd_gid_chid ism; /* ISM native GID+CHID of requestor */
        __be16 v2_ext_offset;   /* SMC Version 2 Extension Offset */
-       u8 reserved[28];
+       u8 vendor_oui[3];       /* vendor organizationally unique identifier */
+       u8 vendor_exp_options[5];
+       u8 reserved[20];
 };
 
 struct smc_clc_smcd_v2_extension {
@@ -231,8 +233,17 @@ struct smc_clc_first_contact_ext {
        u8 hostname[SMC_MAX_HOSTNAME_LEN];
 };
 
+struct smc_clc_first_contact_ext_v2x {
+       struct smc_clc_first_contact_ext fce_v2_base;
+       u8 reserved3[4];
+       __be32 vendor_exp_options;
+       u8 reserved4[8];
+} __packed;            /* format defined in
+                        * IBM Shared Memory Communications Version 2 (Third Edition)
+                        * (https://www.ibm.com/support/pages/node/7009315)
+                        */
+
 struct smc_clc_fce_gid_ext {
-       u8 reserved[16];
        u8 gid_cnt;
        u8 reserved2[3];
        u8 gid[][SMC_GID_SIZE];