4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2012, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 #define DEBUG_SUBSYSTEM S_LNET
38 #include "../../../include/linux/libcfs/libcfs.h"
42 #include <linux/file.h>
43 /* For sys_open & sys_close */
44 #include <linux/syscalls.h>
47 libcfs_sock_ioctl(int cmd
, unsigned long arg
)
49 mm_segment_t oldmm
= get_fs();
52 struct file
*sock_filp
;
54 rc
= sock_create (PF_INET
, SOCK_STREAM
, 0, &sock
);
56 CERROR ("Can't create socket: %d\n", rc
);
60 sock_filp
= sock_alloc_file(sock
, 0, NULL
);
61 if (IS_ERR(sock_filp
)) {
63 rc
= PTR_ERR(sock_filp
);
68 if (sock_filp
->f_op
->unlocked_ioctl
)
69 rc
= sock_filp
->f_op
->unlocked_ioctl(sock_filp
, cmd
, arg
);
78 libcfs_ipif_query (char *name
, int *up
, __u32
*ip
, __u32
*mask
)
85 nob
= strnlen(name
, IFNAMSIZ
);
86 if (nob
== IFNAMSIZ
) {
87 CERROR("Interface name %s too long\n", name
);
91 CLASSERT (sizeof(ifr
.ifr_name
) >= IFNAMSIZ
);
93 strcpy(ifr
.ifr_name
, name
);
94 rc
= libcfs_sock_ioctl(SIOCGIFFLAGS
, (unsigned long)&ifr
);
97 CERROR("Can't get flags for interface %s\n", name
);
101 if ((ifr
.ifr_flags
& IFF_UP
) == 0) {
102 CDEBUG(D_NET
, "Interface %s down\n", name
);
110 strcpy(ifr
.ifr_name
, name
);
111 ifr
.ifr_addr
.sa_family
= AF_INET
;
112 rc
= libcfs_sock_ioctl(SIOCGIFADDR
, (unsigned long)&ifr
);
115 CERROR("Can't get IP address for interface %s\n", name
);
119 val
= ((struct sockaddr_in
*)&ifr
.ifr_addr
)->sin_addr
.s_addr
;
122 strcpy(ifr
.ifr_name
, name
);
123 ifr
.ifr_addr
.sa_family
= AF_INET
;
124 rc
= libcfs_sock_ioctl(SIOCGIFNETMASK
, (unsigned long)&ifr
);
127 CERROR("Can't get netmask for interface %s\n", name
);
131 val
= ((struct sockaddr_in
*)&ifr
.ifr_netmask
)->sin_addr
.s_addr
;
137 EXPORT_SYMBOL(libcfs_ipif_query
);
140 libcfs_ipif_enumerate (char ***namesp
)
142 /* Allocate and fill in 'names', returning # interfaces/error */
154 nalloc
= 16; /* first guess at max interfaces */
157 if (nalloc
* sizeof(*ifr
) > PAGE_CACHE_SIZE
) {
159 nalloc
= PAGE_CACHE_SIZE
/sizeof(*ifr
);
160 CWARN("Too many interfaces: only enumerating first %d\n",
164 LIBCFS_ALLOC(ifr
, nalloc
* sizeof(*ifr
));
166 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc
);
171 ifc
.ifc_buf
= (char *)ifr
;
172 ifc
.ifc_len
= nalloc
* sizeof(*ifr
);
174 rc
= libcfs_sock_ioctl(SIOCGIFCONF
, (unsigned long)&ifc
);
177 CERROR ("Error %d enumerating interfaces\n", rc
);
183 nfound
= ifc
.ifc_len
/sizeof(*ifr
);
184 LASSERT (nfound
<= nalloc
);
186 if (nfound
< nalloc
|| toobig
)
189 LIBCFS_FREE(ifr
, nalloc
* sizeof(*ifr
));
196 LIBCFS_ALLOC(names
, nfound
* sizeof(*names
));
202 for (i
= 0; i
< nfound
; i
++) {
204 nob
= strnlen (ifr
[i
].ifr_name
, IFNAMSIZ
);
205 if (nob
== IFNAMSIZ
) {
206 /* no space for terminating NULL */
207 CERROR("interface name %.*s too long (%d max)\n",
208 nob
, ifr
[i
].ifr_name
, IFNAMSIZ
);
213 LIBCFS_ALLOC(names
[i
], IFNAMSIZ
);
214 if (names
[i
] == NULL
) {
219 memcpy(names
[i
], ifr
[i
].ifr_name
, nob
);
228 libcfs_ipif_free_enumeration(names
, nfound
);
230 LIBCFS_FREE(ifr
, nalloc
* sizeof(*ifr
));
235 EXPORT_SYMBOL(libcfs_ipif_enumerate
);
238 libcfs_ipif_free_enumeration (char **names
, int n
)
244 for (i
= 0; i
< n
&& names
[i
] != NULL
; i
++)
245 LIBCFS_FREE(names
[i
], IFNAMSIZ
);
247 LIBCFS_FREE(names
, n
* sizeof(*names
));
250 EXPORT_SYMBOL(libcfs_ipif_free_enumeration
);
253 libcfs_sock_write (struct socket
*sock
, void *buffer
, int nob
, int timeout
)
256 long ticks
= timeout
* HZ
;
261 /* Caller may pass a zero timeout if she thinks the socket buffer is
262 * empty enough to take the whole message immediately */
269 struct msghdr msg
= {
270 .msg_flags
= (timeout
== 0) ? MSG_DONTWAIT
: 0
274 /* Set send timeout to remaining time */
275 tv
= (struct timeval
) {
276 .tv_sec
= ticks
/ HZ
,
277 .tv_usec
= ((ticks
% HZ
) * 1000000) / HZ
279 rc
= kernel_setsockopt(sock
, SOL_SOCKET
, SO_SNDTIMEO
,
280 (char *)&tv
, sizeof(tv
));
282 CERROR("Can't set socket send timeout "
284 (long)tv
.tv_sec
, (int)tv
.tv_usec
, rc
);
290 rc
= kernel_sendmsg(sock
, &msg
, &iov
, 1, nob
);
291 ticks
-= jiffies
- then
;
300 CERROR ("Unexpected zero rc\n");
301 return (-ECONNABORTED
);
307 buffer
= ((char *)buffer
) + rc
;
313 EXPORT_SYMBOL(libcfs_sock_write
);
316 libcfs_sock_read (struct socket
*sock
, void *buffer
, int nob
, int timeout
)
319 long ticks
= timeout
* HZ
;
331 struct msghdr msg
= {
335 /* Set receive timeout to remaining time */
336 tv
= (struct timeval
) {
337 .tv_sec
= ticks
/ HZ
,
338 .tv_usec
= ((ticks
% HZ
) * 1000000) / HZ
340 rc
= kernel_setsockopt(sock
, SOL_SOCKET
, SO_RCVTIMEO
,
341 (char *)&tv
, sizeof(tv
));
343 CERROR("Can't set socket recv timeout %ld.%06d: %d\n",
344 (long)tv
.tv_sec
, (int)tv
.tv_usec
, rc
);
349 rc
= kernel_recvmsg(sock
, &msg
, &iov
, 1, nob
, 0);
350 ticks
-= jiffies
- then
;
358 buffer
= ((char *)buffer
) + rc
;
369 EXPORT_SYMBOL(libcfs_sock_read
);
372 libcfs_sock_create (struct socket
**sockp
, int *fatal
,
373 __u32 local_ip
, int local_port
)
375 struct sockaddr_in locaddr
;
380 /* All errors are fatal except bind failure if the port is in use */
383 rc
= sock_create (PF_INET
, SOCK_STREAM
, 0, &sock
);
386 CERROR ("Can't create socket: %d\n", rc
);
391 rc
= kernel_setsockopt(sock
, SOL_SOCKET
, SO_REUSEADDR
,
392 (char *)&option
, sizeof (option
));
394 CERROR("Can't set SO_REUSEADDR for socket: %d\n", rc
);
398 if (local_ip
!= 0 || local_port
!= 0) {
399 memset(&locaddr
, 0, sizeof(locaddr
));
400 locaddr
.sin_family
= AF_INET
;
401 locaddr
.sin_port
= htons(local_port
);
402 locaddr
.sin_addr
.s_addr
= (local_ip
== 0) ?
403 INADDR_ANY
: htonl(local_ip
);
405 rc
= sock
->ops
->bind(sock
, (struct sockaddr
*)&locaddr
,
407 if (rc
== -EADDRINUSE
) {
408 CDEBUG(D_NET
, "Port %d already in use\n", local_port
);
413 CERROR("Error trying to bind to port %d: %d\n",
427 libcfs_sock_setbuf (struct socket
*sock
, int txbufsize
, int rxbufsize
)
432 if (txbufsize
!= 0) {
434 rc
= kernel_setsockopt(sock
, SOL_SOCKET
, SO_SNDBUF
,
435 (char *)&option
, sizeof (option
));
437 CERROR ("Can't set send buffer %d: %d\n",
443 if (rxbufsize
!= 0) {
445 rc
= kernel_setsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
,
446 (char *)&option
, sizeof (option
));
448 CERROR ("Can't set receive buffer %d: %d\n",
457 EXPORT_SYMBOL(libcfs_sock_setbuf
);
460 libcfs_sock_getaddr (struct socket
*sock
, int remote
, __u32
*ip
, int *port
)
462 struct sockaddr_in sin
;
463 int len
= sizeof (sin
);
466 rc
= sock
->ops
->getname (sock
, (struct sockaddr
*)&sin
, &len
,
469 CERROR ("Error %d getting sock %s IP/port\n",
470 rc
, remote
? "peer" : "local");
475 *ip
= ntohl (sin
.sin_addr
.s_addr
);
478 *port
= ntohs (sin
.sin_port
);
483 EXPORT_SYMBOL(libcfs_sock_getaddr
);
486 libcfs_sock_getbuf (struct socket
*sock
, int *txbufsize
, int *rxbufsize
)
489 if (txbufsize
!= NULL
) {
490 *txbufsize
= sock
->sk
->sk_sndbuf
;
493 if (rxbufsize
!= NULL
) {
494 *rxbufsize
= sock
->sk
->sk_rcvbuf
;
500 EXPORT_SYMBOL(libcfs_sock_getbuf
);
503 libcfs_sock_listen (struct socket
**sockp
,
504 __u32 local_ip
, int local_port
, int backlog
)
509 rc
= libcfs_sock_create(sockp
, &fatal
, local_ip
, local_port
);
512 CERROR("Can't create socket: port %d already in use\n",
517 rc
= (*sockp
)->ops
->listen(*sockp
, backlog
);
521 CERROR("Can't set listen backlog %d: %d\n", backlog
, rc
);
522 sock_release(*sockp
);
526 EXPORT_SYMBOL(libcfs_sock_listen
);
529 libcfs_sock_accept (struct socket
**newsockp
, struct socket
*sock
)
532 struct socket
*newsock
;
535 init_waitqueue_entry(&wait
, current
);
537 /* XXX this should add a ref to sock->ops->owner, if
538 * TCP could be a module */
539 rc
= sock_create_lite(PF_PACKET
, sock
->type
, IPPROTO_TCP
, &newsock
);
541 CERROR("Can't allocate socket\n");
545 newsock
->ops
= sock
->ops
;
547 set_current_state(TASK_INTERRUPTIBLE
);
548 add_wait_queue(cfs_sk_sleep(sock
->sk
), &wait
);
550 rc
= sock
->ops
->accept(sock
, newsock
, O_NONBLOCK
);
552 /* Nothing ready, so wait for activity */
554 rc
= sock
->ops
->accept(sock
, newsock
, O_NONBLOCK
);
557 remove_wait_queue(cfs_sk_sleep(sock
->sk
), &wait
);
558 set_current_state(TASK_RUNNING
);
567 sock_release(newsock
);
571 EXPORT_SYMBOL(libcfs_sock_accept
);
574 libcfs_sock_abort_accept (struct socket
*sock
)
576 wake_up_all(cfs_sk_sleep(sock
->sk
));
579 EXPORT_SYMBOL(libcfs_sock_abort_accept
);
582 libcfs_sock_connect (struct socket
**sockp
, int *fatal
,
583 __u32 local_ip
, int local_port
,
584 __u32 peer_ip
, int peer_port
)
586 struct sockaddr_in srvaddr
;
589 rc
= libcfs_sock_create(sockp
, fatal
, local_ip
, local_port
);
593 memset (&srvaddr
, 0, sizeof (srvaddr
));
594 srvaddr
.sin_family
= AF_INET
;
595 srvaddr
.sin_port
= htons(peer_port
);
596 srvaddr
.sin_addr
.s_addr
= htonl(peer_ip
);
598 rc
= (*sockp
)->ops
->connect(*sockp
,
599 (struct sockaddr
*)&srvaddr
, sizeof(srvaddr
),
604 /* EADDRNOTAVAIL probably means we're already connected to the same
605 * peer/port on the same local port on a differently typed
606 * connection. Let our caller retry with a different local
608 *fatal
= !(rc
== -EADDRNOTAVAIL
);
610 CDEBUG_LIMIT(*fatal
? D_NETERROR
: D_NET
,
611 "Error %d connecting %pI4h/%d -> %pI4h/%d\n", rc
,
612 &local_ip
, local_port
, &peer_ip
, peer_port
);
614 sock_release(*sockp
);
618 EXPORT_SYMBOL(libcfs_sock_connect
);
621 libcfs_sock_release (struct socket
*sock
)
626 EXPORT_SYMBOL(libcfs_sock_release
);