@@ -439,6 +439,47 @@ static int smcr_clnt_conf_first_link(struct smc_sock *smc)
439439 return 0 ;
440440}
441441
442+ static bool smc_isascii (char * hostname )
443+ {
444+ int i ;
445+
446+ for (i = 0 ; i < SMC_MAX_HOSTNAME_LEN ; i ++ )
447+ if (!isascii (hostname [i ]))
448+ return false;
449+ return true;
450+ }
451+
452+ static void smc_conn_save_peer_info_fce (struct smc_sock * smc ,
453+ struct smc_clc_msg_accept_confirm * clc )
454+ {
455+ struct smc_clc_msg_accept_confirm_v2 * clc_v2 =
456+ (struct smc_clc_msg_accept_confirm_v2 * )clc ;
457+ struct smc_clc_first_contact_ext * fce ;
458+ int clc_v2_len ;
459+
460+ if (clc -> hdr .version == SMC_V1 ||
461+ !(clc -> hdr .typev2 & SMC_FIRST_CONTACT_MASK ))
462+ return ;
463+
464+ if (smc -> conn .lgr -> is_smcd ) {
465+ memcpy (smc -> conn .lgr -> negotiated_eid , clc_v2 -> d1 .eid ,
466+ SMC_MAX_EID_LEN );
467+ clc_v2_len = offsetofend (struct smc_clc_msg_accept_confirm_v2 ,
468+ d1 );
469+ } else {
470+ memcpy (smc -> conn .lgr -> negotiated_eid , clc_v2 -> r1 .eid ,
471+ SMC_MAX_EID_LEN );
472+ clc_v2_len = offsetofend (struct smc_clc_msg_accept_confirm_v2 ,
473+ r1 );
474+ }
475+ fce = (struct smc_clc_first_contact_ext * )(((u8 * )clc_v2 ) + clc_v2_len );
476+ smc -> conn .lgr -> peer_os = fce -> os_type ;
477+ smc -> conn .lgr -> peer_smc_release = fce -> release ;
478+ if (smc_isascii (fce -> hostname ))
479+ memcpy (smc -> conn .lgr -> peer_hostname , fce -> hostname ,
480+ SMC_MAX_HOSTNAME_LEN );
481+ }
482+
442483static void smcr_conn_save_peer_info (struct smc_sock * smc ,
443484 struct smc_clc_msg_accept_confirm * clc )
444485{
@@ -451,16 +492,6 @@ static void smcr_conn_save_peer_info(struct smc_sock *smc,
451492 smc -> conn .tx_off = bufsize * (smc -> conn .peer_rmbe_idx - 1 );
452493}
453494
454- static bool smc_isascii (char * hostname )
455- {
456- int i ;
457-
458- for (i = 0 ; i < SMC_MAX_HOSTNAME_LEN ; i ++ )
459- if (!isascii (hostname [i ]))
460- return false;
461- return true;
462- }
463-
464495static void smcd_conn_save_peer_info (struct smc_sock * smc ,
465496 struct smc_clc_msg_accept_confirm * clc )
466497{
@@ -472,22 +503,6 @@ static void smcd_conn_save_peer_info(struct smc_sock *smc,
472503 smc -> conn .peer_rmbe_size = bufsize - sizeof (struct smcd_cdc_msg );
473504 atomic_set (& smc -> conn .peer_rmbe_space , smc -> conn .peer_rmbe_size );
474505 smc -> conn .tx_off = bufsize * smc -> conn .peer_rmbe_idx ;
475- if (clc -> hdr .version > SMC_V1 &&
476- (clc -> hdr .typev2 & SMC_FIRST_CONTACT_MASK )) {
477- struct smc_clc_msg_accept_confirm_v2 * clc_v2 =
478- (struct smc_clc_msg_accept_confirm_v2 * )clc ;
479- struct smc_clc_first_contact_ext * fce =
480- (struct smc_clc_first_contact_ext * )
481- (((u8 * )clc_v2 ) + sizeof (* clc_v2 ));
482-
483- memcpy (smc -> conn .lgr -> negotiated_eid , clc_v2 -> eid ,
484- SMC_MAX_EID_LEN );
485- smc -> conn .lgr -> peer_os = fce -> os_type ;
486- smc -> conn .lgr -> peer_smc_release = fce -> release ;
487- if (smc_isascii (fce -> hostname ))
488- memcpy (smc -> conn .lgr -> peer_hostname , fce -> hostname ,
489- SMC_MAX_HOSTNAME_LEN );
490- }
491506}
492507
493508static void smc_conn_save_peer_info (struct smc_sock * smc ,
@@ -497,14 +512,16 @@ static void smc_conn_save_peer_info(struct smc_sock *smc,
497512 smcd_conn_save_peer_info (smc , clc );
498513 else
499514 smcr_conn_save_peer_info (smc , clc );
515+ smc_conn_save_peer_info_fce (smc , clc );
500516}
501517
502518static void smc_link_save_peer_info (struct smc_link * link ,
503- struct smc_clc_msg_accept_confirm * clc )
519+ struct smc_clc_msg_accept_confirm * clc ,
520+ struct smc_init_info * ini )
504521{
505522 link -> peer_qpn = ntoh24 (clc -> r0 .qpn );
506- memcpy (link -> peer_gid , clc -> r0 . lcl . gid , SMC_GID_SIZE );
507- memcpy (link -> peer_mac , clc -> r0 . lcl . mac , sizeof (link -> peer_mac ));
523+ memcpy (link -> peer_gid , ini -> peer_gid , SMC_GID_SIZE );
524+ memcpy (link -> peer_mac , ini -> peer_mac , sizeof (link -> peer_mac ));
508525 link -> peer_psn = ntoh24 (clc -> r0 .psn );
509526 link -> peer_mtu = clc -> r0 .qp_mtu ;
510527}
@@ -769,18 +786,83 @@ static int smc_connect_clc(struct smc_sock *smc,
769786 SMC_CLC_ACCEPT , CLC_WAIT_TIME );
770787}
771788
789+ static void smc_fill_gid_list (struct smc_link_group * lgr ,
790+ struct smc_gidlist * gidlist ,
791+ struct smc_ib_device * known_dev , u8 * known_gid )
792+ {
793+ struct smc_init_info * alt_ini = NULL ;
794+
795+ memset (gidlist , 0 , sizeof (* gidlist ));
796+ memcpy (gidlist -> list [gidlist -> len ++ ], known_gid , SMC_GID_SIZE );
797+
798+ alt_ini = kzalloc (sizeof (* alt_ini ), GFP_KERNEL );
799+ if (!alt_ini )
800+ goto out ;
801+
802+ alt_ini -> vlan_id = lgr -> vlan_id ;
803+ alt_ini -> check_smcrv2 = true;
804+ alt_ini -> smcrv2 .saddr = lgr -> saddr ;
805+ smc_pnet_find_alt_roce (lgr , alt_ini , known_dev );
806+
807+ if (!alt_ini -> smcrv2 .ib_dev_v2 )
808+ goto out ;
809+
810+ memcpy (gidlist -> list [gidlist -> len ++ ], alt_ini -> smcrv2 .ib_gid_v2 ,
811+ SMC_GID_SIZE );
812+
813+ out :
814+ kfree (alt_ini );
815+ }
816+
817+ static int smc_connect_rdma_v2_prepare (struct smc_sock * smc ,
818+ struct smc_clc_msg_accept_confirm * aclc ,
819+ struct smc_init_info * ini )
820+ {
821+ struct smc_clc_msg_accept_confirm_v2 * clc_v2 =
822+ (struct smc_clc_msg_accept_confirm_v2 * )aclc ;
823+ struct smc_clc_first_contact_ext * fce =
824+ (struct smc_clc_first_contact_ext * )
825+ (((u8 * )clc_v2 ) + sizeof (* clc_v2 ));
826+
827+ if (!ini -> first_contact_peer || aclc -> hdr .version == SMC_V1 )
828+ return 0 ;
829+
830+ if (fce -> v2_direct ) {
831+ memcpy (ini -> smcrv2 .nexthop_mac , & aclc -> r0 .lcl .mac , ETH_ALEN );
832+ ini -> smcrv2 .uses_gateway = false;
833+ } else {
834+ if (smc_ib_find_route (smc -> clcsock -> sk -> sk_rcv_saddr ,
835+ smc_ib_gid_to_ipv4 (aclc -> r0 .lcl .gid ),
836+ ini -> smcrv2 .nexthop_mac ,
837+ & ini -> smcrv2 .uses_gateway ))
838+ return SMC_CLC_DECL_NOROUTE ;
839+ if (!ini -> smcrv2 .uses_gateway ) {
840+ /* mismatch: peer claims indirect, but its direct */
841+ return SMC_CLC_DECL_NOINDIRECT ;
842+ }
843+ }
844+ return 0 ;
845+ }
846+
772847/* setup for RDMA connection of client */
773848static int smc_connect_rdma (struct smc_sock * smc ,
774849 struct smc_clc_msg_accept_confirm * aclc ,
775850 struct smc_init_info * ini )
776851{
777852 int i , reason_code = 0 ;
778853 struct smc_link * link ;
854+ u8 * eid = NULL ;
779855
780856 ini -> is_smcd = false;
781- ini -> ib_lcl = & aclc -> r0 .lcl ;
782857 ini -> ib_clcqpn = ntoh24 (aclc -> r0 .qpn );
783858 ini -> first_contact_peer = aclc -> hdr .typev2 & SMC_FIRST_CONTACT_MASK ;
859+ memcpy (ini -> peer_systemid , aclc -> r0 .lcl .id_for_peer , SMC_SYSTEMID_LEN );
860+ memcpy (ini -> peer_gid , aclc -> r0 .lcl .gid , SMC_GID_SIZE );
861+ memcpy (ini -> peer_mac , aclc -> r0 .lcl .mac , ETH_ALEN );
862+
863+ reason_code = smc_connect_rdma_v2_prepare (smc , aclc , ini );
864+ if (reason_code )
865+ return reason_code ;
784866
785867 mutex_lock (& smc_client_lgr_pending );
786868 reason_code = smc_conn_create (smc , ini );
@@ -802,8 +884,9 @@ static int smc_connect_rdma(struct smc_sock *smc,
802884 if (l -> peer_qpn == ntoh24 (aclc -> r0 .qpn ) &&
803885 !memcmp (l -> peer_gid , & aclc -> r0 .lcl .gid ,
804886 SMC_GID_SIZE ) &&
805- !memcmp (l -> peer_mac , & aclc -> r0 .lcl .mac ,
806- sizeof (l -> peer_mac ))) {
887+ (aclc -> hdr .version > SMC_V1 ||
888+ !memcmp (l -> peer_mac , & aclc -> r0 .lcl .mac ,
889+ sizeof (l -> peer_mac )))) {
807890 link = l ;
808891 break ;
809892 }
@@ -822,7 +905,7 @@ static int smc_connect_rdma(struct smc_sock *smc,
822905 }
823906
824907 if (ini -> first_contact_local )
825- smc_link_save_peer_info (link , aclc );
908+ smc_link_save_peer_info (link , aclc , ini );
826909
827910 if (smc_rmb_rtoken_handling (& smc -> conn , link , aclc )) {
828911 reason_code = SMC_CLC_DECL_ERR_RTOK ;
@@ -845,8 +928,18 @@ static int smc_connect_rdma(struct smc_sock *smc,
845928 }
846929 smc_rmb_sync_sg_for_device (& smc -> conn );
847930
931+ if (aclc -> hdr .version > SMC_V1 ) {
932+ struct smc_clc_msg_accept_confirm_v2 * clc_v2 =
933+ (struct smc_clc_msg_accept_confirm_v2 * )aclc ;
934+
935+ eid = clc_v2 -> r1 .eid ;
936+ if (ini -> first_contact_local )
937+ smc_fill_gid_list (link -> lgr , & ini -> smcrv2 .gidlist ,
938+ link -> smcibdev , link -> gid );
939+ }
940+
848941 reason_code = smc_clc_send_confirm (smc , ini -> first_contact_local ,
849- SMC_V1 , NULL );
942+ aclc -> hdr . version , eid , ini );
850943 if (reason_code )
851944 goto connect_abort ;
852945
@@ -886,7 +979,7 @@ smc_v2_determine_accepted_chid(struct smc_clc_msg_accept_confirm_v2 *aclc,
886979 int i ;
887980
888981 for (i = 0 ; i < ini -> ism_offered_cnt + 1 ; i ++ ) {
889- if (ini -> ism_chid [i ] == ntohs (aclc -> chid )) {
982+ if (ini -> ism_chid [i ] == ntohs (aclc -> d1 . chid )) {
890983 ini -> ism_selected = i ;
891984 return 0 ;
892985 }
@@ -940,11 +1033,11 @@ static int smc_connect_ism(struct smc_sock *smc,
9401033 struct smc_clc_msg_accept_confirm_v2 * clc_v2 =
9411034 (struct smc_clc_msg_accept_confirm_v2 * )aclc ;
9421035
943- eid = clc_v2 -> eid ;
1036+ eid = clc_v2 -> d1 . eid ;
9441037 }
9451038
9461039 rc = smc_clc_send_confirm (smc , ini -> first_contact_local ,
947- aclc -> hdr .version , eid );
1040+ aclc -> hdr .version , eid , NULL );
9481041 if (rc )
9491042 goto connect_abort ;
9501043 mutex_unlock (& smc_server_lgr_pending );
@@ -1735,7 +1828,7 @@ static int smc_listen_rdma_finish(struct smc_sock *new_smc,
17351828 int reason_code = 0 ;
17361829
17371830 if (local_first )
1738- smc_link_save_peer_info (link , cclc );
1831+ smc_link_save_peer_info (link , cclc , NULL );
17391832
17401833 if (smc_rmb_rtoken_handling (& new_smc -> conn , link , cclc ))
17411834 return SMC_CLC_DECL_ERR_RTOK ;
0 commit comments