@@ -153,7 +153,6 @@ static int smc_clc_prfx_set(struct socket *clcsock,
153153 struct sockaddr_in * addr ;
154154 int rc = - ENOENT ;
155155
156- memset (prop , 0 , sizeof (* prop ));
157156 if (!dst ) {
158157 rc = - ENOTCONN ;
159158 goto out ;
@@ -412,76 +411,89 @@ int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info)
412411int smc_clc_send_proposal (struct smc_sock * smc , int smc_type ,
413412 struct smc_init_info * ini )
414413{
415- struct smc_clc_ipv6_prefix ipv6_prfx [SMC_CLC_MAX_V6_PREFIX ];
416- struct smc_clc_msg_proposal_prefix pclc_prfx ;
417- struct smc_clc_msg_smcd pclc_smcd ;
418- struct smc_clc_msg_proposal pclc ;
419- struct smc_clc_msg_trail trl ;
414+ struct smc_clc_msg_proposal_prefix * pclc_prfx ;
415+ struct smc_clc_msg_proposal * pclc_base ;
416+ struct smc_clc_msg_proposal_area * pclc ;
417+ struct smc_clc_ipv6_prefix * ipv6_prfx ;
418+ struct smc_clc_msg_smcd * pclc_smcd ;
419+ struct smc_clc_msg_trail * trl ;
420420 int len , i , plen , rc ;
421421 int reason_code = 0 ;
422422 struct kvec vec [5 ];
423423 struct msghdr msg ;
424424
425+ pclc = kzalloc (sizeof (* pclc ), GFP_KERNEL );
426+ if (!pclc )
427+ return - ENOMEM ;
428+
429+ pclc_base = & pclc -> pclc_base ;
430+ pclc_smcd = & pclc -> pclc_smcd ;
431+ pclc_prfx = & pclc -> pclc_prfx ;
432+ ipv6_prfx = pclc -> pclc_prfx_ipv6 ;
433+ trl = & pclc -> pclc_trl ;
434+
425435 /* retrieve ip prefixes for CLC proposal msg */
426- rc = smc_clc_prfx_set (smc -> clcsock , & pclc_prfx , ipv6_prfx );
427- if (rc )
436+ rc = smc_clc_prfx_set (smc -> clcsock , pclc_prfx , ipv6_prfx );
437+ if (rc ) {
438+ kfree (pclc );
428439 return SMC_CLC_DECL_CNFERR ; /* configuration error */
440+ }
429441
430442 /* send SMC Proposal CLC message */
431- plen = sizeof (pclc ) + sizeof (pclc_prfx ) +
432- (pclc_prfx . ipv6_prefixes_cnt * sizeof (ipv6_prfx [0 ])) +
433- sizeof (trl );
434- memset ( & pclc , 0 , sizeof ( pclc ));
435- memcpy ( pclc . hdr . eyecatcher , SMC_EYECATCHER , sizeof (SMC_EYECATCHER ));
436- pclc . hdr .type = SMC_CLC_PROPOSAL ;
437- pclc . hdr .version = SMC_V1 ; /* SMC version */
438- pclc . hdr .path = smc_type ;
443+ plen = sizeof (* pclc_base ) + sizeof (* pclc_prfx ) +
444+ (pclc_prfx -> ipv6_prefixes_cnt * sizeof (ipv6_prfx [0 ])) +
445+ sizeof (* trl );
446+ memcpy ( pclc_base -> hdr . eyecatcher , SMC_EYECATCHER ,
447+ sizeof (SMC_EYECATCHER ));
448+ pclc_base -> hdr .type = SMC_CLC_PROPOSAL ;
449+ pclc_base -> hdr .version = SMC_V1 ; /* SMC version */
450+ pclc_base -> hdr .path = smc_type ;
439451 if (smc_type == SMC_TYPE_R || smc_type == SMC_TYPE_B ) {
440452 /* add SMC-R specifics */
441- memcpy (pclc . lcl .id_for_peer , local_systemid ,
453+ memcpy (pclc_base -> lcl .id_for_peer , local_systemid ,
442454 sizeof (local_systemid ));
443- memcpy (& pclc . lcl .gid , ini -> ib_gid , SMC_GID_SIZE );
444- memcpy (& pclc . lcl .mac , & ini -> ib_dev -> mac [ini -> ib_port - 1 ],
455+ memcpy (pclc_base -> lcl .gid , ini -> ib_gid , SMC_GID_SIZE );
456+ memcpy (pclc_base -> lcl .mac , & ini -> ib_dev -> mac [ini -> ib_port - 1 ],
445457 ETH_ALEN );
446- pclc . iparea_offset = htons (0 );
458+ pclc_base -> iparea_offset = htons (0 );
447459 }
448460 if (smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B ) {
449461 /* add SMC-D specifics */
450- memset (& pclc_smcd , 0 , sizeof (pclc_smcd ));
451- plen += sizeof (pclc_smcd );
452- pclc .iparea_offset = htons (SMC_CLC_PROPOSAL_MAX_OFFSET );
453- pclc_smcd .gid = ini -> ism_dev -> local_gid ;
462+ plen += sizeof (* pclc_smcd );
463+ pclc_base -> iparea_offset = htons (sizeof (* pclc_smcd ));
464+ pclc_smcd -> gid = ini -> ism_dev -> local_gid ;
454465 }
455- pclc . hdr .length = htons (plen );
466+ pclc_base -> hdr .length = htons (plen );
456467
457- memcpy (trl . eyecatcher , SMC_EYECATCHER , sizeof (SMC_EYECATCHER ));
468+ memcpy (trl -> eyecatcher , SMC_EYECATCHER , sizeof (SMC_EYECATCHER ));
458469 memset (& msg , 0 , sizeof (msg ));
459470 i = 0 ;
460- vec [i ].iov_base = & pclc ;
461- vec [i ++ ].iov_len = sizeof (pclc );
471+ vec [i ].iov_base = pclc_base ;
472+ vec [i ++ ].iov_len = sizeof (* pclc_base );
462473 if (smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B ) {
463- vec [i ].iov_base = & pclc_smcd ;
464- vec [i ++ ].iov_len = sizeof (pclc_smcd );
474+ vec [i ].iov_base = pclc_smcd ;
475+ vec [i ++ ].iov_len = sizeof (* pclc_smcd );
465476 }
466- vec [i ].iov_base = & pclc_prfx ;
467- vec [i ++ ].iov_len = sizeof (pclc_prfx );
468- if (pclc_prfx . ipv6_prefixes_cnt > 0 ) {
469- vec [i ].iov_base = & ipv6_prfx [ 0 ] ;
470- vec [i ++ ].iov_len = pclc_prfx . ipv6_prefixes_cnt *
477+ vec [i ].iov_base = pclc_prfx ;
478+ vec [i ++ ].iov_len = sizeof (* pclc_prfx );
479+ if (pclc_prfx -> ipv6_prefixes_cnt > 0 ) {
480+ vec [i ].iov_base = ipv6_prfx ;
481+ vec [i ++ ].iov_len = pclc_prfx -> ipv6_prefixes_cnt *
471482 sizeof (ipv6_prfx [0 ]);
472483 }
473- vec [i ].iov_base = & trl ;
474- vec [i ++ ].iov_len = sizeof (trl );
484+ vec [i ].iov_base = trl ;
485+ vec [i ++ ].iov_len = sizeof (* trl );
475486 /* due to the few bytes needed for clc-handshake this cannot block */
476487 len = kernel_sendmsg (smc -> clcsock , & msg , vec , i , plen );
477488 if (len < 0 ) {
478489 smc -> sk .sk_err = smc -> clcsock -> sk -> sk_err ;
479490 reason_code = - smc -> sk .sk_err ;
480- } else if (len < ( int ) sizeof ( pclc )) {
491+ } else if (len < ntohs ( pclc_base -> hdr . length )) {
481492 reason_code = - ENETUNREACH ;
482493 smc -> sk .sk_err = - reason_code ;
483494 }
484495
496+ kfree (pclc );
485497 return reason_code ;
486498}
487499
0 commit comments