Skip to content

Commit 8ade200

Browse files
karstengrdavem330
authored andcommitted
net/smc: add v2 format of CLC decline message
The CLC decline message changed with SMC-Rv2 and supports up to 4 additional diagnosis codes. Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent e49300a commit 8ade200

File tree

2 files changed

+55
-10
lines changed

2 files changed

+55
-10
lines changed

net/smc/smc_clc.c

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,24 @@ smc_clc_msg_acc_conf_valid(struct smc_clc_msg_accept_confirm_v2 *clc_v2)
400400
return true;
401401
}
402402

403+
/* check arriving CLC decline */
404+
static bool
405+
smc_clc_msg_decl_valid(struct smc_clc_msg_decline *dclc)
406+
{
407+
struct smc_clc_msg_hdr *hdr = &dclc->hdr;
408+
409+
if (hdr->typev1 != SMC_TYPE_R && hdr->typev1 != SMC_TYPE_D)
410+
return false;
411+
if (hdr->version == SMC_V1) {
412+
if (ntohs(hdr->length) != sizeof(struct smc_clc_msg_decline))
413+
return false;
414+
} else {
415+
if (ntohs(hdr->length) != sizeof(struct smc_clc_msg_decline_v2))
416+
return false;
417+
}
418+
return true;
419+
}
420+
403421
static void smc_clc_fill_fce(struct smc_clc_first_contact_ext *fce, int *len)
404422
{
405423
memset(fce, 0, sizeof(*fce));
@@ -441,9 +459,9 @@ static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm, bool check_trl)
441459
break;
442460
case SMC_CLC_DECLINE:
443461
dclc = (struct smc_clc_msg_decline *)clcm;
444-
if (ntohs(dclc->hdr.length) != sizeof(*dclc))
462+
if (!smc_clc_msg_decl_valid(dclc))
445463
return false;
446-
trl = &dclc->trl;
464+
check_trl = false;
447465
break;
448466
default:
449467
return false;
@@ -742,15 +760,16 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
742760
/* send CLC DECLINE message across internal TCP socket */
743761
int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, u8 version)
744762
{
745-
struct smc_clc_msg_decline dclc;
763+
struct smc_clc_msg_decline *dclc_v1;
764+
struct smc_clc_msg_decline_v2 dclc;
746765
struct msghdr msg;
766+
int len, send_len;
747767
struct kvec vec;
748-
int len;
749768

769+
dclc_v1 = (struct smc_clc_msg_decline *)&dclc;
750770
memset(&dclc, 0, sizeof(dclc));
751771
memcpy(dclc.hdr.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
752772
dclc.hdr.type = SMC_CLC_DECLINE;
753-
dclc.hdr.length = htons(sizeof(struct smc_clc_msg_decline));
754773
dclc.hdr.version = version;
755774
dclc.os_type = version == SMC_V1 ? 0 : SMC_CLC_OS_LINUX;
756775
dclc.hdr.typev2 = (peer_diag_info == SMC_CLC_DECL_SYNCERR) ?
@@ -760,14 +779,22 @@ int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, u8 version)
760779
memcpy(dclc.id_for_peer, local_systemid,
761780
sizeof(local_systemid));
762781
dclc.peer_diagnosis = htonl(peer_diag_info);
763-
memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
782+
if (version == SMC_V1) {
783+
memcpy(dclc_v1->trl.eyecatcher, SMC_EYECATCHER,
784+
sizeof(SMC_EYECATCHER));
785+
send_len = sizeof(*dclc_v1);
786+
} else {
787+
memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER,
788+
sizeof(SMC_EYECATCHER));
789+
send_len = sizeof(dclc);
790+
}
791+
dclc.hdr.length = htons(send_len);
764792

765793
memset(&msg, 0, sizeof(msg));
766794
vec.iov_base = &dclc;
767-
vec.iov_len = sizeof(struct smc_clc_msg_decline);
768-
len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1,
769-
sizeof(struct smc_clc_msg_decline));
770-
if (len < 0 || len < sizeof(struct smc_clc_msg_decline))
795+
vec.iov_len = send_len;
796+
len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1, send_len);
797+
if (len < 0 || len < send_len)
771798
len = -EPROTO;
772799
return len > 0 ? 0 : len;
773800
}

net/smc/smc_clc.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,24 @@ struct smc_clc_msg_decline { /* clc decline message */
281281
struct smc_clc_msg_trail trl; /* eye catcher "SMCD" or "SMCR" EBCDIC */
282282
} __aligned(4);
283283

284+
#define SMC_DECL_DIAG_COUNT_V2 4 /* no. of additional peer diagnosis codes */
285+
286+
struct smc_clc_msg_decline_v2 { /* clc decline message */
287+
struct smc_clc_msg_hdr hdr;
288+
u8 id_for_peer[SMC_SYSTEMID_LEN]; /* sender peer_id */
289+
__be32 peer_diagnosis; /* diagnosis information */
290+
#if defined(__BIG_ENDIAN_BITFIELD)
291+
u8 os_type : 4,
292+
reserved : 4;
293+
#elif defined(__LITTLE_ENDIAN_BITFIELD)
294+
u8 reserved : 4,
295+
os_type : 4;
296+
#endif
297+
u8 reserved2[3];
298+
__be32 peer_diagnosis_v2[SMC_DECL_DIAG_COUNT_V2];
299+
struct smc_clc_msg_trail trl; /* eye catcher "SMCD" or "SMCR" EBCDIC */
300+
} __aligned(4);
301+
284302
/* determine start of the prefix area within the proposal message */
285303
static inline struct smc_clc_msg_proposal_prefix *
286304
smc_clc_proposal_get_prefix(struct smc_clc_msg_proposal *pclc)

0 commit comments

Comments
 (0)