Support smc v2.x features validate for smc v2.1.
Signed-off-by: Guangguan Wang <guangguan.wang@linux.alibaba.com>
Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
---
net/smc/af_smc.c | 18 ++++++++++++++++++
net/smc/smc_clc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
net/smc/smc_clc.h | 7 +++++++
3 files changed, 71 insertions(+)
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 52279bdc100a..fd58e25beddf 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1169,6 +1169,7 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc,
struct smc_clc_first_contact_ext *fce =
(struct smc_clc_first_contact_ext *)
(((u8 *)clc_v2) + sizeof(*clc_v2));
+ int rc;
if (!ini->first_contact_peer || aclc->hdr.version == SMC_V1)
return 0;
@@ -1191,6 +1192,9 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc,
if (fce->release > SMC_RELEASE)
return SMC_CLC_DECL_VERSMISMAT;
ini->release_ver = fce->release;
+ rc = smc_clc_cli_v2x_features_validate(fce, ini);
+ if (rc)
+ return rc;
return 0;
}
@@ -1367,6 +1371,9 @@ static int smc_connect_ism(struct smc_sock *smc,
if (fce->release > SMC_RELEASE)
return SMC_CLC_DECL_VERSMISMAT;
ini->release_ver = fce->release;
+ rc = smc_clc_cli_v2x_features_validate(fce, ini);
+ if (rc)
+ return rc;
}
rc = smc_v2_determine_accepted_chid(aclc_v2, ini);
@@ -2417,6 +2424,10 @@ static void smc_listen_work(struct work_struct *work)
if (rc)
goto out_decl;
+ rc = smc_clc_srv_v2x_features_validate(pclc, ini);
+ if (rc)
+ goto out_decl;
+
mutex_lock(&smc_server_lgr_pending);
smc_close_init(new_smc);
smc_rx_init(new_smc);
@@ -2449,6 +2460,13 @@ static void smc_listen_work(struct work_struct *work)
goto out_decl;
}
+ rc = smc_clc_v2x_features_confirm_check(cclc, ini);
+ if (rc) {
+ if (!ini->is_smcd)
+ goto out_unlock;
+ goto out_decl;
+ }
+
/* finish worker */
if (!ini->is_smcd) {
rc = smc_listen_rdma_finish(new_smc, cclc,
diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
index ae80c191a834..4f6b69af2b80 100644
--- a/net/smc/smc_clc.c
+++ b/net/smc/smc_clc.c
@@ -1158,6 +1158,52 @@ int smc_clc_send_accept(struct smc_sock *new_smc, bool srv_first_contact,
return len > 0 ? 0 : len;
}
+int smc_clc_srv_v2x_features_validate(struct smc_clc_msg_proposal *pclc,
+ struct smc_init_info *ini)
+{
+ struct smc_clc_v2_extension *pclc_v2_ext;
+
+ if ((!(ini->smcd_version & SMC_V2) && !(ini->smcr_version & SMC_V2)) ||
+ ini->release_ver < SMC_RELEASE_1)
+ return 0;
+
+ pclc_v2_ext = smc_get_clc_v2_ext(pclc);
+ if (!pclc_v2_ext)
+ return SMC_CLC_DECL_NOV2EXT;
+
+ return 0;
+}
+
+int smc_clc_cli_v2x_features_validate(struct smc_clc_first_contact_ext *fce,
+ struct smc_init_info *ini)
+{
+ if (ini->release_ver < SMC_RELEASE_1)
+ return 0;
+
+ return 0;
+}
+
+int smc_clc_v2x_features_confirm_check(struct smc_clc_msg_accept_confirm *cclc,
+ struct smc_init_info *ini)
+{
+ struct smc_clc_msg_accept_confirm_v2 *clc_v2 =
+ (struct smc_clc_msg_accept_confirm_v2 *)cclc;
+ struct smc_clc_first_contact_ext *fce =
+ smc_get_clc_first_contact_ext(clc_v2, ini->is_smcd);
+
+ if (cclc->hdr.version == SMC_V1 ||
+ !(cclc->hdr.typev2 & SMC_FIRST_CONTACT_MASK))
+ return 0;
+
+ if (ini->release_ver != fce->release)
+ return SMC_CLC_DECL_RELEASEERR;
+
+ if (fce->release < SMC_RELEASE_1)
+ return 0;
+
+ return 0;
+}
+
void smc_clc_get_hostname(u8 **host)
{
*host = &smc_hostname[0];
diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h
index 6133276a8839..66932bfdc6d0 100644
--- a/net/smc/smc_clc.h
+++ b/net/smc/smc_clc.h
@@ -45,6 +45,7 @@
#define SMC_CLC_DECL_NOSEID 0x03030006 /* peer sent no SEID */
#define SMC_CLC_DECL_NOSMCD2DEV 0x03030007 /* no SMC-Dv2 device found */
#define SMC_CLC_DECL_NOUEID 0x03030008 /* peer sent no UEID */
+#define SMC_CLC_DECL_RELEASEERR 0x03030009 /* release version negotiate failed */
#define SMC_CLC_DECL_MODEUNSUPP 0x03040000 /* smc modes do not match (R or D)*/
#define SMC_CLC_DECL_RMBE_EC 0x03050000 /* peer has eyecatcher in RMBE */
#define SMC_CLC_DECL_OPTUNSUPP 0x03060000 /* fastopen sockopt not supported */
@@ -415,6 +416,12 @@ int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
u8 version, u8 *eid, struct smc_init_info *ini);
int smc_clc_send_accept(struct smc_sock *smc, bool srv_first_contact,
u8 version, u8 *negotiated_eid, struct smc_init_info *ini);
+int smc_clc_srv_v2x_features_validate(struct smc_clc_msg_proposal *pclc,
+ struct smc_init_info *ini);
+int smc_clc_cli_v2x_features_validate(struct smc_clc_first_contact_ext *fce,
+ struct smc_init_info *ini);
+int smc_clc_v2x_features_confirm_check(struct smc_clc_msg_accept_confirm *cclc,
+ struct smc_init_info *ini);
void smc_clc_init(void) __init;
void smc_clc_exit(void);
void smc_clc_get_hostname(u8 **host);
--
2.24.3 (Apple Git-128)
On 07.08.23 08:27, Guangguan Wang wrote: > Support smc v2.x features validate for smc v2.1. > a bit more description? > Signed-off-by: Guangguan Wang <guangguan.wang@linux.alibaba.com> > Reviewed-by: Tony Lu <tonylu@linux.alibaba.com> > --- > net/smc/af_smc.c | 18 ++++++++++++++++++ > net/smc/smc_clc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ > net/smc/smc_clc.h | 7 +++++++ > 3 files changed, 71 insertions(+) > > diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c > index 52279bdc100a..fd58e25beddf 100644 > --- a/net/smc/af_smc.c > +++ b/net/smc/af_smc.c > @@ -1169,6 +1169,7 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc, > struct smc_clc_first_contact_ext *fce = > (struct smc_clc_first_contact_ext *) > (((u8 *)clc_v2) + sizeof(*clc_v2)); > + int rc; > > if (!ini->first_contact_peer || aclc->hdr.version == SMC_V1) > return 0; > @@ -1191,6 +1192,9 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc, > if (fce->release > SMC_RELEASE) > return SMC_CLC_DECL_VERSMISMAT; > ini->release_ver = fce->release; > + rc = smc_clc_cli_v2x_features_validate(fce, ini); > + if (rc) > + return rc; > > return 0; > } > @@ -1367,6 +1371,9 @@ static int smc_connect_ism(struct smc_sock *smc, > if (fce->release > SMC_RELEASE) > return SMC_CLC_DECL_VERSMISMAT; > ini->release_ver = fce->release; > + rc = smc_clc_cli_v2x_features_validate(fce, ini); > + if (rc) > + return rc; > } > > rc = smc_v2_determine_accepted_chid(aclc_v2, ini); > @@ -2417,6 +2424,10 @@ static void smc_listen_work(struct work_struct *work) > if (rc) > goto out_decl; > > + rc = smc_clc_srv_v2x_features_validate(pclc, ini); > + if (rc) > + goto out_decl; > + > mutex_lock(&smc_server_lgr_pending); > smc_close_init(new_smc); > smc_rx_init(new_smc); > @@ -2449,6 +2460,13 @@ static void smc_listen_work(struct work_struct *work) > goto out_decl; > } > > + rc = smc_clc_v2x_features_confirm_check(cclc, ini); > + if (rc) { > + if (!ini->is_smcd) > + goto out_unlock; > + goto out_decl; > + } > + > /* finish worker */ > if (!ini->is_smcd) { > rc = smc_listen_rdma_finish(new_smc, cclc, > diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c > index ae80c191a834..4f6b69af2b80 100644 > --- a/net/smc/smc_clc.c > +++ b/net/smc/smc_clc.c > @@ -1158,6 +1158,52 @@ int smc_clc_send_accept(struct smc_sock *new_smc, bool srv_first_contact, > return len > 0 ? 0 : len; > } > > +int smc_clc_srv_v2x_features_validate(struct smc_clc_msg_proposal *pclc, > + struct smc_init_info *ini) > +{ > + struct smc_clc_v2_extension *pclc_v2_ext; > + > + if ((!(ini->smcd_version & SMC_V2) && !(ini->smcr_version & SMC_V2)) || > + ini->release_ver < SMC_RELEASE_1) > + return 0; > + > + pclc_v2_ext = smc_get_clc_v2_ext(pclc); > + if (!pclc_v2_ext) > + return SMC_CLC_DECL_NOV2EXT; > + > + return 0; > +} > + > +int smc_clc_cli_v2x_features_validate(struct smc_clc_first_contact_ext *fce, > + struct smc_init_info *ini) > +{ > + if (ini->release_ver < SMC_RELEASE_1) > + return 0; > + > + return 0; > +} Why need the function? Since it returns 0 anyway. > + > +int smc_clc_v2x_features_confirm_check(struct smc_clc_msg_accept_confirm *cclc, > + struct smc_init_info *ini) > +{ > + struct smc_clc_msg_accept_confirm_v2 *clc_v2 = > + (struct smc_clc_msg_accept_confirm_v2 *)cclc; > + struct smc_clc_first_contact_ext *fce = > + smc_get_clc_first_contact_ext(clc_v2, ini->is_smcd); > + > + if (cclc->hdr.version == SMC_V1 || > + !(cclc->hdr.typev2 & SMC_FIRST_CONTACT_MASK)) > + return 0; > + > + if (ini->release_ver != fce->release) > + return SMC_CLC_DECL_RELEASEERR; > + > + if (fce->release < SMC_RELEASE_1) > + return 0; > + > + return 0; > +} > + > void smc_clc_get_hostname(u8 **host) > { > *host = &smc_hostname[0]; > diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h > index 6133276a8839..66932bfdc6d0 100644 > --- a/net/smc/smc_clc.h > +++ b/net/smc/smc_clc.h > @@ -45,6 +45,7 @@ > #define SMC_CLC_DECL_NOSEID 0x03030006 /* peer sent no SEID */ > #define SMC_CLC_DECL_NOSMCD2DEV 0x03030007 /* no SMC-Dv2 device found */ > #define SMC_CLC_DECL_NOUEID 0x03030008 /* peer sent no UEID */ > +#define SMC_CLC_DECL_RELEASEERR 0x03030009 /* release version negotiate failed */ > #define SMC_CLC_DECL_MODEUNSUPP 0x03040000 /* smc modes do not match (R or D)*/ > #define SMC_CLC_DECL_RMBE_EC 0x03050000 /* peer has eyecatcher in RMBE */ > #define SMC_CLC_DECL_OPTUNSUPP 0x03060000 /* fastopen sockopt not supported */ > @@ -415,6 +416,12 @@ int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact, > u8 version, u8 *eid, struct smc_init_info *ini); > int smc_clc_send_accept(struct smc_sock *smc, bool srv_first_contact, > u8 version, u8 *negotiated_eid, struct smc_init_info *ini); > +int smc_clc_srv_v2x_features_validate(struct smc_clc_msg_proposal *pclc, > + struct smc_init_info *ini); > +int smc_clc_cli_v2x_features_validate(struct smc_clc_first_contact_ext *fce, > + struct smc_init_info *ini); > +int smc_clc_v2x_features_confirm_check(struct smc_clc_msg_accept_confirm *cclc, > + struct smc_init_info *ini); > void smc_clc_init(void) __init; > void smc_clc_exit(void); > void smc_clc_get_hostname(u8 **host);
On 2023/8/10 00:03, Wenjia Zhang wrote: > > > On 07.08.23 08:27, Guangguan Wang wrote: >> Support smc v2.x features validate for smc v2.1. >> > a bit more description? > OK, more descriptions will be added in the next version. >> Signed-off-by: Guangguan Wang <guangguan.wang@linux.alibaba.com> >> Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
© 2016 - 2025 Red Hat, Inc.