[SRU][F][G][PATCH 1/1] net/smc: tolerate future SMCD versions
seth.forshee at canonical.com
seth.forshee at canonical.com
Fri Jul 17 22:33:31 UTC 2020
On Fri, Jul 10, 2020 at 09:21:45PM +0200, frank.heimes at canonical.com wrote:
> From: Ursula Braun <ubraun at linux.ibm.com>
>
> BugLink: https://bugs.launchpad.net/bugs/1882088
>
> CLC proposal messages of future SMCD versions could be larger than SMCD
> V1 CLC proposal messages.
> To enable toleration in SMC V1 the receival of CLC proposal messages
> is adapted:
> * accept larger length values in CLC proposal
> * check trailing eye catcher for incoming CLC proposal with V1 length only
> * receive the whole CLC proposal even in cases it does not fit into the
> V1 buffer
>
> Fixes: e7b7a64a8493d ("smc: support variable CLC proposal messages")
> Signed-off-by: Ursula Braun <ubraun at linux.ibm.com>
> Signed-off-by: Karsten Graul <kgraul at linux.ibm.com>
> Signed-off-by: David S. Miller <davem at davemloft.net>
> (cherry picked from commit fb4f79264c0fc6fd5a68ffe3e31bfff97311e1f1i linux-next)
One note, there is an 'i' appended to the end of the sha1 which should
be removed when applying.
> Signed-off-by: Frank Heimes <frank.heimes at canonical.com>
> ---
> net/smc/smc_clc.c | 45 ++++++++++++++++++++++++++++++++-------------
> net/smc/smc_clc.h | 4 ++++
> 2 files changed, 36 insertions(+), 13 deletions(-)
>
> diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
> index aee9ccfa99c2..640cce262015 100644
> --- a/net/smc/smc_clc.c
> +++ b/net/smc/smc_clc.c
> @@ -27,6 +27,7 @@
>
> #define SMCR_CLC_ACCEPT_CONFIRM_LEN 68
> #define SMCD_CLC_ACCEPT_CONFIRM_LEN 48
> +#define SMC_CLC_RECV_BUF_LEN 100
>
> /* eye catcher "SMCR" EBCDIC for CLC messages */
> static const char SMC_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xd9'};
> @@ -36,7 +37,7 @@ static const char SMCD_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xc4'};
> /* check if received message has a correct header length and contains valid
> * heading and trailing eyecatchers
> */
> -static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)
> +static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm, bool check_trl)
> {
> struct smc_clc_msg_proposal_prefix *pclc_prfx;
> struct smc_clc_msg_accept_confirm *clc;
> @@ -49,12 +50,9 @@ static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)
> return false;
> switch (clcm->type) {
> case SMC_CLC_PROPOSAL:
> - if (clcm->path != SMC_TYPE_R && clcm->path != SMC_TYPE_D &&
> - clcm->path != SMC_TYPE_B)
> - return false;
> pclc = (struct smc_clc_msg_proposal *)clcm;
> pclc_prfx = smc_clc_proposal_get_prefix(pclc);
> - if (ntohs(pclc->hdr.length) !=
> + if (ntohs(pclc->hdr.length) <
> sizeof(*pclc) + ntohs(pclc->iparea_offset) +
> sizeof(*pclc_prfx) +
> pclc_prfx->ipv6_prefixes_cnt *
> @@ -86,7 +84,8 @@ static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)
> default:
> return false;
> }
> - if (memcmp(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
> + if (check_trl &&
> + memcmp(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
> memcmp(trl->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))
> return false;
> return true;
> @@ -276,7 +275,8 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
> struct msghdr msg = {NULL, 0};
> int reason_code = 0;
> struct kvec vec = {buf, buflen};
> - int len, datlen;
> + int len, datlen, recvlen;
> + bool check_trl = true;
> int krflags;
>
> /* peek the first few bytes to determine length of data to receive
> @@ -320,10 +320,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
> }
> datlen = ntohs(clcm->length);
> if ((len < sizeof(struct smc_clc_msg_hdr)) ||
> - (datlen > buflen) ||
> - (clcm->version != SMC_CLC_V1) ||
> - (clcm->path != SMC_TYPE_R && clcm->path != SMC_TYPE_D &&
> - clcm->path != SMC_TYPE_B) ||
> + (clcm->version < SMC_CLC_V1) ||
> ((clcm->type != SMC_CLC_DECLINE) &&
> (clcm->type != expected_type))) {
> smc->sk.sk_err = EPROTO;
> @@ -331,16 +328,38 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
> goto out;
> }
>
> + if (clcm->type == SMC_CLC_PROPOSAL && clcm->path == SMC_TYPE_N)
> + reason_code = SMC_CLC_DECL_VERSMISMAT; /* just V2 offered */
> +
> /* receive the complete CLC message */
> memset(&msg, 0, sizeof(struct msghdr));
> - iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, datlen);
> + if (datlen > buflen) {
> + check_trl = false;
> + recvlen = buflen;
> + } else {
> + recvlen = datlen;
> + }
> + iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, recvlen);
> krflags = MSG_WAITALL;
> len = sock_recvmsg(smc->clcsock, &msg, krflags);
> - if (len < datlen || !smc_clc_msg_hdr_valid(clcm)) {
> + if (len < recvlen || !smc_clc_msg_hdr_valid(clcm, check_trl)) {
> smc->sk.sk_err = EPROTO;
> reason_code = -EPROTO;
> goto out;
> }
> + datlen -= len;
> + while (datlen) {
> + u8 tmp[SMC_CLC_RECV_BUF_LEN];
> +
> + vec.iov_base = &tmp;
> + vec.iov_len = SMC_CLC_RECV_BUF_LEN;
> + /* receive remaining proposal message */
> + recvlen = datlen > SMC_CLC_RECV_BUF_LEN ?
> + SMC_CLC_RECV_BUF_LEN : datlen;
> + iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, recvlen);
> + len = sock_recvmsg(smc->clcsock, &msg, krflags);
> + datlen -= len;
> + }
> if (clcm->type == SMC_CLC_DECLINE) {
> struct smc_clc_msg_decline *dclc;
>
> diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h
> index ca209272e5fa..76c2b150d040 100644
> --- a/net/smc/smc_clc.h
> +++ b/net/smc/smc_clc.h
> @@ -25,6 +25,7 @@
> #define SMC_CLC_V1 0x1 /* SMC version */
> #define SMC_TYPE_R 0 /* SMC-R only */
> #define SMC_TYPE_D 1 /* SMC-D only */
> +#define SMC_TYPE_N 2 /* neither SMC-R nor SMC-D */
> #define SMC_TYPE_B 3 /* SMC-R and SMC-D */
> #define CLC_WAIT_TIME (6 * HZ) /* max. wait time on clcsock */
> #define CLC_WAIT_TIME_SHORT HZ /* short wait time on clcsock */
> @@ -44,6 +45,9 @@
> #define SMC_CLC_DECL_DIFFPREFIX 0x03070000 /* IP prefix / subnet mismatch */
> #define SMC_CLC_DECL_GETVLANERR 0x03080000 /* err to get vlan id of ip device*/
> #define SMC_CLC_DECL_ISMVLANERR 0x03090000 /* err to reg vlan id on ism dev */
> +#define SMC_CLC_DECL_NOACTLINK 0x030a0000 /* no active smc-r link in lgr */
> +#define SMC_CLC_DECL_NOSRVLINK 0x030b0000 /* SMC-R link from srv not found */
> +#define SMC_CLC_DECL_VERSMISMAT 0x030c0000 /* SMC version mismatch */
> #define SMC_CLC_DECL_SYNCERR 0x04000000 /* synchronization error */
> #define SMC_CLC_DECL_PEERDECL 0x05000000 /* peer declined during handshake */
> #define SMC_CLC_DECL_INTERR 0x09990000 /* internal error */
> --
> 2.25.1
>
>
> --
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
More information about the kernel-team
mailing list