@@ -143,6 +143,13 @@ struct dlm_node_addr {
143143};
144144
145145struct dlm_proto_ops {
146+ const char * name ;
147+ int proto ;
148+
149+ int (* listen_validate )(void );
150+ void (* listen_sockopts )(struct socket * sock );
151+ int (* listen_bind )(struct socket * sock );
152+
146153 /* What to do to connect */
147154 void (* connect_action )(struct connection * con );
148155 /* What to do to shutdown */
@@ -1327,59 +1334,6 @@ static void tcp_connect_to_sock(struct connection *con)
13271334 return ;
13281335}
13291336
1330- /* On error caller must run dlm_close_sock() for the
1331- * listen connection socket.
1332- */
1333- static int tcp_create_listen_sock (struct listen_connection * con ,
1334- struct sockaddr_storage * saddr )
1335- {
1336- struct socket * sock = NULL ;
1337- int result = 0 ;
1338- int addr_len ;
1339-
1340- if (dlm_local_addr [0 ]-> ss_family == AF_INET )
1341- addr_len = sizeof (struct sockaddr_in );
1342- else
1343- addr_len = sizeof (struct sockaddr_in6 );
1344-
1345- /* Create a socket to communicate with */
1346- result = sock_create_kern (& init_net , dlm_local_addr [0 ]-> ss_family ,
1347- SOCK_STREAM , IPPROTO_TCP , & sock );
1348- if (result < 0 ) {
1349- log_print ("Can't create listening comms socket" );
1350- goto create_out ;
1351- }
1352-
1353- sock_set_mark (sock -> sk , dlm_config .ci_mark );
1354-
1355- /* Turn off Nagle's algorithm */
1356- tcp_sock_set_nodelay (sock -> sk );
1357-
1358- sock_set_reuseaddr (sock -> sk );
1359-
1360- add_listen_sock (sock , con );
1361-
1362- /* Bind to our port */
1363- make_sockaddr (saddr , dlm_config .ci_tcp_port , & addr_len );
1364- result = sock -> ops -> bind (sock , (struct sockaddr * ) saddr , addr_len );
1365- if (result < 0 ) {
1366- log_print ("Can't bind to port %d" , dlm_config .ci_tcp_port );
1367- goto create_out ;
1368- }
1369- sock_set_keepalive (sock -> sk );
1370-
1371- result = sock -> ops -> listen (sock , 5 );
1372- if (result < 0 ) {
1373- log_print ("Can't listen on port %d" , dlm_config .ci_tcp_port );
1374- goto create_out ;
1375- }
1376-
1377- return 0 ;
1378-
1379- create_out :
1380- return result ;
1381- }
1382-
13831337/* Get local addresses */
13841338static void init_local (void )
13851339{
@@ -1406,63 +1360,6 @@ static void deinit_local(void)
14061360 kfree (dlm_local_addr [i ]);
14071361}
14081362
1409- /* Initialise SCTP socket and bind to all interfaces
1410- * On error caller must run dlm_close_sock() for the
1411- * listen connection socket.
1412- */
1413- static int sctp_listen_for_all (struct listen_connection * con )
1414- {
1415- struct socket * sock = NULL ;
1416- int result = - EINVAL ;
1417-
1418- log_print ("Using SCTP for communications" );
1419-
1420- result = sock_create_kern (& init_net , dlm_local_addr [0 ]-> ss_family ,
1421- SOCK_STREAM , IPPROTO_SCTP , & sock );
1422- if (result < 0 ) {
1423- log_print ("Can't create comms socket, check SCTP is loaded" );
1424- goto out ;
1425- }
1426-
1427- sock_set_rcvbuf (sock -> sk , NEEDED_RMEM );
1428- sock_set_mark (sock -> sk , dlm_config .ci_mark );
1429- sctp_sock_set_nodelay (sock -> sk );
1430-
1431- add_listen_sock (sock , con );
1432-
1433- /* Bind to all addresses. */
1434- result = sctp_bind_addrs (con -> sock , dlm_config .ci_tcp_port );
1435- if (result < 0 )
1436- goto out ;
1437-
1438- result = sock -> ops -> listen (sock , 5 );
1439- if (result < 0 ) {
1440- log_print ("Can't set socket listening" );
1441- goto out ;
1442- }
1443-
1444- return 0 ;
1445-
1446- out :
1447- return result ;
1448- }
1449-
1450- static int tcp_listen_for_all (void )
1451- {
1452- /* We don't support multi-homed hosts */
1453- if (dlm_local_count > 1 ) {
1454- log_print ("TCP protocol can't handle multi-homed hosts, "
1455- "try SCTP" );
1456- return - EINVAL ;
1457- }
1458-
1459- log_print ("Using TCP for communications" );
1460-
1461- return tcp_create_listen_sock (& listen_con , dlm_local_addr [0 ]);
1462- }
1463-
1464-
1465-
14661363static struct writequeue_entry * new_writequeue_entry (struct connection * con ,
14671364 gfp_t allocation )
14681365{
@@ -1959,13 +1856,112 @@ void dlm_lowcomms_stop(void)
19591856 dlm_proto_ops = NULL ;
19601857}
19611858
1859+ static int dlm_listen_for_all (void )
1860+ {
1861+ struct socket * sock ;
1862+ int result ;
1863+
1864+ log_print ("Using %s for communications" ,
1865+ dlm_proto_ops -> name );
1866+
1867+ if (dlm_proto_ops -> listen_validate ) {
1868+ result = dlm_proto_ops -> listen_validate ();
1869+ if (result < 0 )
1870+ return result ;
1871+ }
1872+
1873+ result = sock_create_kern (& init_net , dlm_local_addr [0 ]-> ss_family ,
1874+ SOCK_STREAM , dlm_proto_ops -> proto , & sock );
1875+ if (result < 0 ) {
1876+ log_print ("Can't create comms socket, check SCTP is loaded" );
1877+ goto out ;
1878+ }
1879+
1880+ sock_set_mark (sock -> sk , dlm_config .ci_mark );
1881+ dlm_proto_ops -> listen_sockopts (sock );
1882+
1883+ result = dlm_proto_ops -> listen_bind (sock );
1884+ if (result < 0 )
1885+ goto out ;
1886+
1887+ save_listen_callbacks (sock );
1888+ add_listen_sock (sock , & listen_con );
1889+
1890+ INIT_WORK (& listen_con .rwork , process_listen_recv_socket );
1891+ result = sock -> ops -> listen (sock , 5 );
1892+ if (result < 0 ) {
1893+ dlm_close_sock (& listen_con .sock );
1894+ goto out ;
1895+ }
1896+
1897+ return 0 ;
1898+
1899+ out :
1900+ sock_release (sock );
1901+ return result ;
1902+ }
1903+
1904+ static int dlm_tcp_listen_validate (void )
1905+ {
1906+ /* We don't support multi-homed hosts */
1907+ if (dlm_local_count > 1 ) {
1908+ log_print ("TCP protocol can't handle multi-homed hosts, try SCTP" );
1909+ return - EINVAL ;
1910+ }
1911+
1912+ return 0 ;
1913+ }
1914+
1915+ static void dlm_tcp_sockopts (struct socket * sock )
1916+ {
1917+ /* Turn off Nagle's algorithm */
1918+ tcp_sock_set_nodelay (sock -> sk );
1919+ }
1920+
1921+ static void dlm_tcp_listen_sockopts (struct socket * sock )
1922+ {
1923+ dlm_tcp_sockopts (sock );
1924+ sock_set_reuseaddr (sock -> sk );
1925+ }
1926+
1927+ static int dlm_tcp_listen_bind (struct socket * sock )
1928+ {
1929+ int addr_len ;
1930+
1931+ /* Bind to our port */
1932+ make_sockaddr (dlm_local_addr [0 ], dlm_config .ci_tcp_port , & addr_len );
1933+ return sock -> ops -> bind (sock , (struct sockaddr * )dlm_local_addr [0 ],
1934+ addr_len );
1935+ }
1936+
19621937static const struct dlm_proto_ops dlm_tcp_ops = {
1938+ .name = "TCP" ,
1939+ .proto = IPPROTO_TCP ,
1940+ .listen_validate = dlm_tcp_listen_validate ,
1941+ .listen_sockopts = dlm_tcp_listen_sockopts ,
1942+ .listen_bind = dlm_tcp_listen_bind ,
19631943 .connect_action = tcp_connect_to_sock ,
19641944 .shutdown_action = dlm_tcp_shutdown ,
19651945 .eof_condition = tcp_eof_condition ,
19661946};
19671947
1948+ static int dlm_sctp_bind_listen (struct socket * sock )
1949+ {
1950+ return sctp_bind_addrs (sock , dlm_config .ci_tcp_port );
1951+ }
1952+
1953+ static void dlm_sctp_sockopts (struct socket * sock )
1954+ {
1955+ /* Turn off Nagle's algorithm */
1956+ sctp_sock_set_nodelay (sock -> sk );
1957+ sock_set_rcvbuf (sock -> sk , NEEDED_RMEM );
1958+ }
1959+
19681960static const struct dlm_proto_ops dlm_sctp_ops = {
1961+ .name = "SCTP" ,
1962+ .proto = IPPROTO_SCTP ,
1963+ .listen_sockopts = dlm_sctp_sockopts ,
1964+ .listen_bind = dlm_sctp_bind_listen ,
19691965 .connect_action = sctp_connect_to_sock ,
19701966};
19711967
@@ -1996,24 +1992,26 @@ int dlm_lowcomms_start(void)
19961992 switch (dlm_config .ci_protocol ) {
19971993 case DLM_PROTO_TCP :
19981994 dlm_proto_ops = & dlm_tcp_ops ;
1999- error = tcp_listen_for_all ();
20001995 break ;
20011996 case DLM_PROTO_SCTP :
20021997 dlm_proto_ops = & dlm_sctp_ops ;
2003- error = sctp_listen_for_all (& listen_con );
20041998 break ;
20051999 default :
20062000 log_print ("Invalid protocol identifier %d set" ,
20072001 dlm_config .ci_protocol );
20082002 error = - EINVAL ;
2009- break ;
2003+ goto fail_proto_ops ;
20102004 }
2005+
2006+ error = dlm_listen_for_all ();
20112007 if (error )
2012- goto fail_unlisten ;
2008+ goto fail_listen ;
20132009
20142010 return 0 ;
20152011
2016- fail_unlisten :
2012+ fail_listen :
2013+ dlm_proto_ops = NULL ;
2014+ fail_proto_ops :
20172015 dlm_allow_conn = 0 ;
20182016 dlm_close_sock (& listen_con .sock );
20192017 work_stop ();
0 commit comments