2727
2828#define SMCR_CLC_ACCEPT_CONFIRM_LEN 68
2929#define SMCD_CLC_ACCEPT_CONFIRM_LEN 48
30+ #define SMC_CLC_RECV_BUF_LEN 100
3031
3132/* eye catcher "SMCR" EBCDIC for CLC messages */
3233static const char SMC_EYECATCHER [4 ] = {'\xe2' , '\xd4' , '\xc3' , '\xd9' };
@@ -36,7 +37,7 @@ static const char SMCD_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xc4'};
3637/* check if received message has a correct header length and contains valid
3738 * heading and trailing eyecatchers
3839 */
39- static bool smc_clc_msg_hdr_valid (struct smc_clc_msg_hdr * clcm )
40+ static bool smc_clc_msg_hdr_valid (struct smc_clc_msg_hdr * clcm , bool check_trl )
4041{
4142 struct smc_clc_msg_proposal_prefix * pclc_prfx ;
4243 struct smc_clc_msg_accept_confirm * clc ;
@@ -49,12 +50,9 @@ static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)
4950 return false;
5051 switch (clcm -> type ) {
5152 case SMC_CLC_PROPOSAL :
52- if (clcm -> path != SMC_TYPE_R && clcm -> path != SMC_TYPE_D &&
53- clcm -> path != SMC_TYPE_B )
54- return false;
5553 pclc = (struct smc_clc_msg_proposal * )clcm ;
5654 pclc_prfx = smc_clc_proposal_get_prefix (pclc );
57- if (ntohs (pclc -> hdr .length ) !=
55+ if (ntohs (pclc -> hdr .length ) <
5856 sizeof (* pclc ) + ntohs (pclc -> iparea_offset ) +
5957 sizeof (* pclc_prfx ) +
6058 pclc_prfx -> ipv6_prefixes_cnt *
@@ -86,7 +84,8 @@ static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)
8684 default :
8785 return false;
8886 }
89- if (memcmp (trl -> eyecatcher , SMC_EYECATCHER , sizeof (SMC_EYECATCHER )) &&
87+ if (check_trl &&
88+ memcmp (trl -> eyecatcher , SMC_EYECATCHER , sizeof (SMC_EYECATCHER )) &&
9089 memcmp (trl -> eyecatcher , SMCD_EYECATCHER , sizeof (SMCD_EYECATCHER )))
9190 return false;
9291 return true;
@@ -276,7 +275,8 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
276275 struct msghdr msg = {NULL , 0 };
277276 int reason_code = 0 ;
278277 struct kvec vec = {buf , buflen };
279- int len , datlen ;
278+ int len , datlen , recvlen ;
279+ bool check_trl = true;
280280 int krflags ;
281281
282282 /* peek the first few bytes to determine length of data to receive
@@ -320,27 +320,46 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
320320 }
321321 datlen = ntohs (clcm -> length );
322322 if ((len < sizeof (struct smc_clc_msg_hdr )) ||
323- (datlen > buflen ) ||
324- (clcm -> version != SMC_CLC_V1 ) ||
325- (clcm -> path != SMC_TYPE_R && clcm -> path != SMC_TYPE_D &&
326- clcm -> path != SMC_TYPE_B ) ||
323+ (clcm -> version < SMC_CLC_V1 ) ||
327324 ((clcm -> type != SMC_CLC_DECLINE ) &&
328325 (clcm -> type != expected_type ))) {
329326 smc -> sk .sk_err = EPROTO ;
330327 reason_code = - EPROTO ;
331328 goto out ;
332329 }
333330
331+ if (clcm -> type == SMC_CLC_PROPOSAL && clcm -> path == SMC_TYPE_N )
332+ reason_code = SMC_CLC_DECL_VERSMISMAT ; /* just V2 offered */
333+
334334 /* receive the complete CLC message */
335335 memset (& msg , 0 , sizeof (struct msghdr ));
336- iov_iter_kvec (& msg .msg_iter , READ , & vec , 1 , datlen );
336+ if (datlen > buflen ) {
337+ check_trl = false;
338+ recvlen = buflen ;
339+ } else {
340+ recvlen = datlen ;
341+ }
342+ iov_iter_kvec (& msg .msg_iter , READ , & vec , 1 , recvlen );
337343 krflags = MSG_WAITALL ;
338344 len = sock_recvmsg (smc -> clcsock , & msg , krflags );
339- if (len < datlen || !smc_clc_msg_hdr_valid (clcm )) {
345+ if (len < recvlen || !smc_clc_msg_hdr_valid (clcm , check_trl )) {
340346 smc -> sk .sk_err = EPROTO ;
341347 reason_code = - EPROTO ;
342348 goto out ;
343349 }
350+ datlen -= len ;
351+ while (datlen ) {
352+ u8 tmp [SMC_CLC_RECV_BUF_LEN ];
353+
354+ vec .iov_base = & tmp ;
355+ vec .iov_len = SMC_CLC_RECV_BUF_LEN ;
356+ /* receive remaining proposal message */
357+ recvlen = datlen > SMC_CLC_RECV_BUF_LEN ?
358+ SMC_CLC_RECV_BUF_LEN : datlen ;
359+ iov_iter_kvec (& msg .msg_iter , READ , & vec , 1 , recvlen );
360+ len = sock_recvmsg (smc -> clcsock , & msg , krflags );
361+ datlen -= len ;
362+ }
344363 if (clcm -> type == SMC_CLC_DECLINE ) {
345364 struct smc_clc_msg_decline * dclc ;
346365
0 commit comments