@@ -1515,33 +1515,48 @@ static int smc_listen_v2_check(struct smc_sock *new_smc,
1515
1515
1516
1516
ini -> smc_type_v1 = pclc -> hdr .typev1 ;
1517
1517
ini -> smc_type_v2 = pclc -> hdr .typev2 ;
1518
- ini -> smcd_version = ini -> smc_type_v1 != SMC_TYPE_N ? SMC_V1 : 0 ;
1519
- if (pclc -> hdr .version > SMC_V1 )
1520
- ini -> smcd_version |=
1521
- ini -> smc_type_v2 != SMC_TYPE_N ? SMC_V2 : 0 ;
1522
- if (!(ini -> smcd_version & SMC_V2 )) {
1518
+ ini -> smcd_version = smcd_indicated (ini -> smc_type_v1 ) ? SMC_V1 : 0 ;
1519
+ ini -> smcr_version = smcr_indicated (ini -> smc_type_v1 ) ? SMC_V1 : 0 ;
1520
+ if (pclc -> hdr .version > SMC_V1 ) {
1521
+ if (smcd_indicated (ini -> smc_type_v2 ))
1522
+ ini -> smcd_version |= SMC_V2 ;
1523
+ if (smcr_indicated (ini -> smc_type_v2 ))
1524
+ ini -> smcr_version |= SMC_V2 ;
1525
+ }
1526
+ if (!(ini -> smcd_version & SMC_V2 ) && !(ini -> smcr_version & SMC_V2 )) {
1523
1527
rc = SMC_CLC_DECL_PEERNOSMC ;
1524
1528
goto out ;
1525
1529
}
1526
- if (!smc_ism_is_v2_capable ()) {
1527
- ini -> smcd_version &= ~SMC_V2 ;
1528
- rc = SMC_CLC_DECL_NOISM2SUPP ;
1529
- goto out ;
1530
- }
1531
1530
pclc_v2_ext = smc_get_clc_v2_ext (pclc );
1532
1531
if (!pclc_v2_ext ) {
1533
1532
ini -> smcd_version &= ~SMC_V2 ;
1533
+ ini -> smcr_version &= ~SMC_V2 ;
1534
1534
rc = SMC_CLC_DECL_NOV2EXT ;
1535
1535
goto out ;
1536
1536
}
1537
1537
pclc_smcd_v2_ext = smc_get_clc_smcd_v2_ext (pclc_v2_ext );
1538
- if (!pclc_smcd_v2_ext ) {
1539
- ini -> smcd_version &= ~SMC_V2 ;
1540
- rc = SMC_CLC_DECL_NOV2DEXT ;
1538
+ if (ini -> smcd_version & SMC_V2 ) {
1539
+ if (!smc_ism_is_v2_capable ()) {
1540
+ ini -> smcd_version &= ~SMC_V2 ;
1541
+ rc = SMC_CLC_DECL_NOISM2SUPP ;
1542
+ } else if (!pclc_smcd_v2_ext ) {
1543
+ ini -> smcd_version &= ~SMC_V2 ;
1544
+ rc = SMC_CLC_DECL_NOV2DEXT ;
1545
+ } else if (!pclc_v2_ext -> hdr .eid_cnt &&
1546
+ !pclc_v2_ext -> hdr .flag .seid ) {
1547
+ ini -> smcd_version &= ~SMC_V2 ;
1548
+ rc = SMC_CLC_DECL_NOUEID ;
1549
+ }
1550
+ }
1551
+ if (ini -> smcr_version & SMC_V2 ) {
1552
+ if (!pclc_v2_ext -> hdr .eid_cnt ) {
1553
+ ini -> smcr_version &= ~SMC_V2 ;
1554
+ rc = SMC_CLC_DECL_NOUEID ;
1555
+ }
1541
1556
}
1542
1557
1543
1558
out :
1544
- if (!ini -> smcd_version )
1559
+ if (!ini -> smcd_version && ! ini -> smcr_version )
1545
1560
return rc ;
1546
1561
1547
1562
return 0 ;
@@ -1661,10 +1676,6 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
1661
1676
pclc_smcd = smc_get_clc_msg_smcd (pclc );
1662
1677
smc_v2_ext = smc_get_clc_v2_ext (pclc );
1663
1678
smcd_v2_ext = smc_get_clc_smcd_v2_ext (smc_v2_ext );
1664
- if (!smcd_v2_ext ) {
1665
- smc_find_ism_store_rc (SMC_CLC_DECL_NOV2DEXT , ini );
1666
- goto not_found ;
1667
- }
1668
1679
1669
1680
mutex_lock (& smcd_dev_list .mutex );
1670
1681
if (pclc_smcd -> ism .chid )
@@ -1682,8 +1693,10 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
1682
1693
}
1683
1694
mutex_unlock (& smcd_dev_list .mutex );
1684
1695
1685
- if (!ini -> ism_dev [0 ])
1696
+ if (!ini -> ism_dev [0 ]) {
1697
+ smc_find_ism_store_rc (SMC_CLC_DECL_NOSMCD2DEV , ini );
1686
1698
goto not_found ;
1699
+ }
1687
1700
1688
1701
smc_ism_get_system_eid (& eid );
1689
1702
if (!smc_clc_match_eid (ini -> negotiated_eid , smc_v2_ext ,
@@ -1736,6 +1749,7 @@ static void smc_find_ism_v1_device_serv(struct smc_sock *new_smc,
1736
1749
1737
1750
not_found :
1738
1751
smc_find_ism_store_rc (rc , ini );
1752
+ ini -> smcd_version &= ~SMC_V1 ;
1739
1753
ini -> ism_dev [0 ] = NULL ;
1740
1754
ini -> is_smcd = false;
1741
1755
}
@@ -1754,24 +1768,69 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, bool local_first)
1754
1768
return 0 ;
1755
1769
}
1756
1770
1771
+ static void smc_find_rdma_v2_device_serv (struct smc_sock * new_smc ,
1772
+ struct smc_clc_msg_proposal * pclc ,
1773
+ struct smc_init_info * ini )
1774
+ {
1775
+ struct smc_clc_v2_extension * smc_v2_ext ;
1776
+ u8 smcr_version ;
1777
+ int rc ;
1778
+
1779
+ if (!(ini -> smcr_version & SMC_V2 ) || !smcr_indicated (ini -> smc_type_v2 ))
1780
+ goto not_found ;
1781
+
1782
+ smc_v2_ext = smc_get_clc_v2_ext (pclc );
1783
+ if (!smc_clc_match_eid (ini -> negotiated_eid , smc_v2_ext , NULL , NULL ))
1784
+ goto not_found ;
1785
+
1786
+ /* prepare RDMA check */
1787
+ memcpy (ini -> peer_systemid , pclc -> lcl .id_for_peer , SMC_SYSTEMID_LEN );
1788
+ memcpy (ini -> peer_gid , smc_v2_ext -> roce , SMC_GID_SIZE );
1789
+ memcpy (ini -> peer_mac , pclc -> lcl .mac , ETH_ALEN );
1790
+ ini -> check_smcrv2 = true;
1791
+ ini -> smcrv2 .clc_sk = new_smc -> clcsock -> sk ;
1792
+ ini -> smcrv2 .saddr = new_smc -> clcsock -> sk -> sk_rcv_saddr ;
1793
+ ini -> smcrv2 .daddr = smc_ib_gid_to_ipv4 (smc_v2_ext -> roce );
1794
+ rc = smc_find_rdma_device (new_smc , ini );
1795
+ if (rc ) {
1796
+ smc_find_ism_store_rc (rc , ini );
1797
+ goto not_found ;
1798
+ }
1799
+ if (!ini -> smcrv2 .uses_gateway )
1800
+ memcpy (ini -> smcrv2 .nexthop_mac , pclc -> lcl .mac , ETH_ALEN );
1801
+
1802
+ smcr_version = ini -> smcr_version ;
1803
+ ini -> smcr_version = SMC_V2 ;
1804
+ rc = smc_listen_rdma_init (new_smc , ini );
1805
+ if (!rc )
1806
+ rc = smc_listen_rdma_reg (new_smc , ini -> first_contact_local );
1807
+ if (!rc )
1808
+ return ;
1809
+ ini -> smcr_version = smcr_version ;
1810
+ smc_find_ism_store_rc (rc , ini );
1811
+
1812
+ not_found :
1813
+ ini -> smcr_version &= ~SMC_V2 ;
1814
+ ini -> check_smcrv2 = false;
1815
+ }
1816
+
1757
1817
static int smc_find_rdma_v1_device_serv (struct smc_sock * new_smc ,
1758
1818
struct smc_clc_msg_proposal * pclc ,
1759
1819
struct smc_init_info * ini )
1760
1820
{
1761
1821
int rc ;
1762
1822
1763
- if (!smcr_indicated (ini -> smc_type_v1 ))
1823
+ if (!( ini -> smcr_version & SMC_V1 ) || ! smcr_indicated (ini -> smc_type_v1 ))
1764
1824
return SMC_CLC_DECL_NOSMCDEV ;
1765
1825
1766
1826
/* prepare RDMA check */
1767
- ini -> ib_lcl = & pclc -> lcl ;
1827
+ memcpy (ini -> peer_systemid , pclc -> lcl .id_for_peer , SMC_SYSTEMID_LEN );
1828
+ memcpy (ini -> peer_gid , pclc -> lcl .gid , SMC_GID_SIZE );
1829
+ memcpy (ini -> peer_mac , pclc -> lcl .mac , ETH_ALEN );
1768
1830
rc = smc_find_rdma_device (new_smc , ini );
1769
1831
if (rc ) {
1770
1832
/* no RDMA device found */
1771
- if (ini -> smc_type_v1 == SMC_TYPE_B )
1772
- /* neither ISM nor RDMA device found */
1773
- rc = SMC_CLC_DECL_NOSMCDEV ;
1774
- return rc ;
1833
+ return SMC_CLC_DECL_NOSMCDEV ;
1775
1834
}
1776
1835
rc = smc_listen_rdma_init (new_smc , ini );
1777
1836
if (rc )
@@ -1784,51 +1843,60 @@ static int smc_listen_find_device(struct smc_sock *new_smc,
1784
1843
struct smc_clc_msg_proposal * pclc ,
1785
1844
struct smc_init_info * ini )
1786
1845
{
1787
- int rc ;
1846
+ int prfx_rc ;
1788
1847
1789
1848
/* check for ISM device matching V2 proposed device */
1790
1849
smc_find_ism_v2_device_serv (new_smc , pclc , ini );
1791
1850
if (ini -> ism_dev [0 ])
1792
1851
return 0 ;
1793
1852
1794
- if (!(ini -> smcd_version & SMC_V1 ))
1795
- return ini -> rc ?: SMC_CLC_DECL_NOSMCD2DEV ;
1796
-
1797
- /* check for matching IP prefix and subnet length */
1798
- rc = smc_listen_prfx_check (new_smc , pclc );
1799
- if (rc )
1800
- return ini -> rc ?: rc ;
1853
+ /* check for matching IP prefix and subnet length (V1) */
1854
+ prfx_rc = smc_listen_prfx_check (new_smc , pclc );
1855
+ if (prfx_rc )
1856
+ smc_find_ism_store_rc (prfx_rc , ini );
1801
1857
1802
1858
/* get vlan id from IP device */
1803
1859
if (smc_vlan_by_tcpsk (new_smc -> clcsock , ini ))
1804
1860
return ini -> rc ?: SMC_CLC_DECL_GETVLANERR ;
1805
1861
1806
1862
/* check for ISM device matching V1 proposed device */
1807
- smc_find_ism_v1_device_serv (new_smc , pclc , ini );
1863
+ if (!prfx_rc )
1864
+ smc_find_ism_v1_device_serv (new_smc , pclc , ini );
1808
1865
if (ini -> ism_dev [0 ])
1809
1866
return 0 ;
1810
1867
1811
- if (pclc -> hdr .typev1 == SMC_TYPE_D )
1868
+ if (!smcr_indicated (pclc -> hdr .typev1 ) &&
1869
+ !smcr_indicated (pclc -> hdr .typev2 ))
1812
1870
/* skip RDMA and decline */
1813
1871
return ini -> rc ?: SMC_CLC_DECL_NOSMCDDEV ;
1814
1872
1815
- /* check if RDMA is available */
1816
- rc = smc_find_rdma_v1_device_serv (new_smc , pclc , ini );
1817
- smc_find_ism_store_rc (rc , ini );
1873
+ /* check if RDMA V2 is available */
1874
+ smc_find_rdma_v2_device_serv (new_smc , pclc , ini );
1875
+ if (ini -> smcrv2 .ib_dev_v2 )
1876
+ return 0 ;
1818
1877
1819
- return (!rc ) ? 0 : ini -> rc ;
1878
+ /* check if RDMA V1 is available */
1879
+ if (!prfx_rc ) {
1880
+ int rc ;
1881
+
1882
+ rc = smc_find_rdma_v1_device_serv (new_smc , pclc , ini );
1883
+ smc_find_ism_store_rc (rc , ini );
1884
+ return (!rc ) ? 0 : ini -> rc ;
1885
+ }
1886
+ return SMC_CLC_DECL_NOSMCDEV ;
1820
1887
}
1821
1888
1822
1889
/* listen worker: finish RDMA setup */
1823
1890
static int smc_listen_rdma_finish (struct smc_sock * new_smc ,
1824
1891
struct smc_clc_msg_accept_confirm * cclc ,
1825
- bool local_first )
1892
+ bool local_first ,
1893
+ struct smc_init_info * ini )
1826
1894
{
1827
1895
struct smc_link * link = new_smc -> conn .lnk ;
1828
1896
int reason_code = 0 ;
1829
1897
1830
1898
if (local_first )
1831
- smc_link_save_peer_info (link , cclc , NULL );
1899
+ smc_link_save_peer_info (link , cclc , ini );
1832
1900
1833
1901
if (smc_rmb_rtoken_handling (& new_smc -> conn , link , cclc ))
1834
1902
return SMC_CLC_DECL_ERR_RTOK ;
@@ -1849,12 +1917,13 @@ static void smc_listen_work(struct work_struct *work)
1849
1917
{
1850
1918
struct smc_sock * new_smc = container_of (work , struct smc_sock ,
1851
1919
smc_listen_work );
1852
- u8 version = smc_ism_is_v2_capable () ? SMC_V2 : SMC_V1 ;
1853
1920
struct socket * newclcsock = new_smc -> clcsock ;
1854
1921
struct smc_clc_msg_accept_confirm * cclc ;
1855
1922
struct smc_clc_msg_proposal_area * buf ;
1856
1923
struct smc_clc_msg_proposal * pclc ;
1857
1924
struct smc_init_info * ini = NULL ;
1925
+ u8 proposal_version = SMC_V1 ;
1926
+ u8 accept_version ;
1858
1927
int rc = 0 ;
1859
1928
1860
1929
if (new_smc -> listen_smc -> sk .sk_state != SMC_LISTEN )
@@ -1885,7 +1954,9 @@ static void smc_listen_work(struct work_struct *work)
1885
1954
SMC_CLC_PROPOSAL , CLC_WAIT_TIME );
1886
1955
if (rc )
1887
1956
goto out_decl ;
1888
- version = pclc -> hdr .version == SMC_V1 ? SMC_V1 : version ;
1957
+
1958
+ if (pclc -> hdr .version > SMC_V1 )
1959
+ proposal_version = SMC_V2 ;
1889
1960
1890
1961
/* IPSec connections opt out of SMC optimizations */
1891
1962
if (using_ipsec (new_smc )) {
@@ -1915,9 +1986,9 @@ static void smc_listen_work(struct work_struct *work)
1915
1986
goto out_unlock ;
1916
1987
1917
1988
/* send SMC Accept CLC message */
1989
+ accept_version = ini -> is_smcd ? ini -> smcd_version : ini -> smcr_version ;
1918
1990
rc = smc_clc_send_accept (new_smc , ini -> first_contact_local ,
1919
- ini -> smcd_version == SMC_V2 ? SMC_V2 : SMC_V1 ,
1920
- ini -> negotiated_eid );
1991
+ accept_version , ini -> negotiated_eid );
1921
1992
if (rc )
1922
1993
goto out_unlock ;
1923
1994
@@ -1939,7 +2010,7 @@ static void smc_listen_work(struct work_struct *work)
1939
2010
/* finish worker */
1940
2011
if (!ini -> is_smcd ) {
1941
2012
rc = smc_listen_rdma_finish (new_smc , cclc ,
1942
- ini -> first_contact_local );
2013
+ ini -> first_contact_local , ini );
1943
2014
if (rc )
1944
2015
goto out_unlock ;
1945
2016
mutex_unlock (& smc_server_lgr_pending );
@@ -1953,7 +2024,7 @@ static void smc_listen_work(struct work_struct *work)
1953
2024
mutex_unlock (& smc_server_lgr_pending );
1954
2025
out_decl :
1955
2026
smc_listen_decline (new_smc , rc , ini ? ini -> first_contact_local : 0 ,
1956
- version );
2027
+ proposal_version );
1957
2028
out_free :
1958
2029
kfree (ini );
1959
2030
kfree (buf );
0 commit comments