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, Whamcloud, Inc.
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 <libcfs/libcfs.h>
39 #include <libcfs/libcfs.h>
43 #include <linux/file.h>
44 /* For sys_open & sys_close */
45 #include <linux/syscalls.h>
48 libcfs_sock_ioctl(int cmd, unsigned long arg)
50 mm_segment_t oldmm = get_fs();
54 struct file *sock_filp;
56 rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock);
58 CERROR ("Can't create socket: %d\n", rc);
62 #ifdef HAVE_SOCK_MAP_FD_2ARG
63 fd = sock_map_fd(sock,0);
65 fd = sock_map_fd(sock);
80 if (sock_filp->f_op->unlocked_ioctl)
81 rc = sock_filp->f_op->unlocked_ioctl(sock_filp, cmd, arg);
93 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
100 nob = strnlen(name, IFNAMSIZ);
101 if (nob == IFNAMSIZ) {
102 CERROR("Interface name %s too long\n", name);
106 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
108 strcpy(ifr.ifr_name, name);
109 rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);
112 CERROR("Can't get flags for interface %s\n", name);
116 if ((ifr.ifr_flags & IFF_UP) == 0) {
117 CDEBUG(D_NET, "Interface %s down\n", name);
125 strcpy(ifr.ifr_name, name);
126 ifr.ifr_addr.sa_family = AF_INET;
127 rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);
130 CERROR("Can't get IP address for interface %s\n", name);
134 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
137 strcpy(ifr.ifr_name, name);
138 ifr.ifr_addr.sa_family = AF_INET;
139 rc = libcfs_sock_ioctl(SIOCGIFNETMASK, (unsigned long)&ifr);
142 CERROR("Can't get netmask for interface %s\n", name);
146 val = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr;
152 EXPORT_SYMBOL(libcfs_ipif_query);
155 libcfs_ipif_enumerate (char ***namesp)
157 /* Allocate and fill in 'names', returning # interfaces/error */
169 nalloc = 16; /* first guess at max interfaces */
172 if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
174 nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
175 CWARN("Too many interfaces: only enumerating first %d\n",
179 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
181 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
186 ifc.ifc_buf = (char *)ifr;
187 ifc.ifc_len = nalloc * sizeof(*ifr);
189 rc = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
192 CERROR ("Error %d enumerating interfaces\n", rc);
198 nfound = ifc.ifc_len/sizeof(*ifr);
199 LASSERT (nfound <= nalloc);
201 if (nfound < nalloc || toobig)
204 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
211 LIBCFS_ALLOC(names, nfound * sizeof(*names));
216 /* NULL out all names[i] */
217 memset (names, 0, nfound * sizeof(*names));
219 for (i = 0; i < nfound; i++) {
221 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
222 if (nob == IFNAMSIZ) {
223 /* no space for terminating NULL */
224 CERROR("interface name %.*s too long (%d max)\n",
225 nob, ifr[i].ifr_name, IFNAMSIZ);
230 LIBCFS_ALLOC(names[i], IFNAMSIZ);
231 if (names[i] == NULL) {
236 memcpy(names[i], ifr[i].ifr_name, nob);
245 libcfs_ipif_free_enumeration(names, nfound);
247 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
252 EXPORT_SYMBOL(libcfs_ipif_enumerate);
255 libcfs_ipif_free_enumeration (char **names, int n)
261 for (i = 0; i < n && names[i] != NULL; i++)
262 LIBCFS_FREE(names[i], IFNAMSIZ);
264 LIBCFS_FREE(names, n * sizeof(*names));
267 EXPORT_SYMBOL(libcfs_ipif_free_enumeration);
270 libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout)
273 mm_segment_t oldmm = get_fs();
274 long ticks = timeout * HZ;
279 /* Caller may pass a zero timeout if she thinks the socket buffer is
280 * empty enough to take the whole message immediately */
287 struct msghdr msg = {
294 .msg_flags = (timeout == 0) ? MSG_DONTWAIT : 0
298 /* Set send timeout to remaining time */
299 tv = (struct timeval) {
300 .tv_sec = ticks / HZ,
301 .tv_usec = ((ticks % HZ) * 1000000) / HZ
304 rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
305 (char *)&tv, sizeof(tv));
308 CERROR("Can't set socket send timeout "
310 (long)tv.tv_sec, (int)tv.tv_usec, rc);
317 rc = sock_sendmsg (sock, &msg, iov.iov_len);
318 ticks -= jiffies - then;
328 CERROR ("Unexpected zero rc\n");
329 return (-ECONNABORTED);
335 buffer = ((char *)buffer) + rc;
341 EXPORT_SYMBOL(libcfs_sock_write);
344 libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout)
347 mm_segment_t oldmm = get_fs();
348 long ticks = timeout * HZ;
360 struct msghdr msg = {
370 /* Set receive timeout to remaining time */
371 tv = (struct timeval) {
372 .tv_sec = ticks / HZ,
373 .tv_usec = ((ticks % HZ) * 1000000) / HZ
376 rc = sock_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
377 (char *)&tv, sizeof(tv));
380 CERROR("Can't set socket recv timeout %ld.%06d: %d\n",
381 (long)tv.tv_sec, (int)tv.tv_usec, rc);
387 rc = sock_recvmsg(sock, &msg, iov.iov_len, 0);
388 ticks -= jiffies - then;
397 buffer = ((char *)buffer) + rc;
408 EXPORT_SYMBOL(libcfs_sock_read);
411 libcfs_sock_create (struct socket **sockp, int *fatal,
412 __u32 local_ip, int local_port)
414 struct sockaddr_in locaddr;
418 mm_segment_t oldmm = get_fs();
420 /* All errors are fatal except bind failure if the port is in use */
423 rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock);
426 CERROR ("Can't create socket: %d\n", rc);
432 rc = sock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
433 (char *)&option, sizeof (option));
436 CERROR("Can't set SO_REUSEADDR for socket: %d\n", rc);
440 if (local_ip != 0 || local_port != 0) {
441 memset(&locaddr, 0, sizeof(locaddr));
442 locaddr.sin_family = AF_INET;
443 locaddr.sin_port = htons(local_port);
444 locaddr.sin_addr.s_addr = (local_ip == 0) ?
445 INADDR_ANY : htonl(local_ip);
447 rc = sock->ops->bind(sock, (struct sockaddr *)&locaddr,
449 if (rc == -EADDRINUSE) {
450 CDEBUG(D_NET, "Port %d already in use\n", local_port);
455 CERROR("Error trying to bind to port %d: %d\n",
469 libcfs_sock_setbuf (struct socket *sock, int txbufsize, int rxbufsize)
471 mm_segment_t oldmm = get_fs();
475 if (txbufsize != 0) {
478 rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
479 (char *)&option, sizeof (option));
482 CERROR ("Can't set send buffer %d: %d\n",
488 if (rxbufsize != 0) {
491 rc = sock_setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
492 (char *)&option, sizeof (option));
495 CERROR ("Can't set receive buffer %d: %d\n",
504 EXPORT_SYMBOL(libcfs_sock_setbuf);
507 libcfs_sock_getaddr (struct socket *sock, int remote, __u32 *ip, int *port)
509 struct sockaddr_in sin;
510 int len = sizeof (sin);
513 rc = sock->ops->getname (sock, (struct sockaddr *)&sin, &len,
516 CERROR ("Error %d getting sock %s IP/port\n",
517 rc, remote ? "peer" : "local");
522 *ip = ntohl (sin.sin_addr.s_addr);
525 *port = ntohs (sin.sin_port);
530 EXPORT_SYMBOL(libcfs_sock_getaddr);
533 libcfs_sock_getbuf (struct socket *sock, int *txbufsize, int *rxbufsize)
536 if (txbufsize != NULL) {
537 *txbufsize = sock->sk->sk_sndbuf;
540 if (rxbufsize != NULL) {
541 *rxbufsize = sock->sk->sk_rcvbuf;
547 EXPORT_SYMBOL(libcfs_sock_getbuf);
550 libcfs_sock_listen (struct socket **sockp,
551 __u32 local_ip, int local_port, int backlog)
556 rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
559 CERROR("Can't create socket: port %d already in use\n",
564 rc = (*sockp)->ops->listen(*sockp, backlog);
568 CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
569 sock_release(*sockp);
573 EXPORT_SYMBOL(libcfs_sock_listen);
575 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
576 int sock_create_lite(int family, int type, int protocol, struct socket **res)
592 libcfs_sock_accept (struct socket **newsockp, struct socket *sock)
595 struct socket *newsock;
598 init_waitqueue_entry(&wait, current);
600 /* XXX this should add a ref to sock->ops->owner, if
601 * TCP could be a module */
602 rc = sock_create_lite(PF_PACKET, sock->type, IPPROTO_TCP, &newsock);
604 CERROR("Can't allocate socket\n");
608 newsock->ops = sock->ops;
610 set_current_state(TASK_INTERRUPTIBLE);
611 add_wait_queue(sk_sleep(sock->sk), &wait);
613 rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
615 /* Nothing ready, so wait for activity */
617 rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
620 remove_wait_queue(sk_sleep(sock->sk), &wait);
621 set_current_state(TASK_RUNNING);
630 sock_release(newsock);
634 EXPORT_SYMBOL(libcfs_sock_accept);
637 libcfs_sock_abort_accept (struct socket *sock)
639 wake_up_all(sk_sleep(sock->sk));
642 EXPORT_SYMBOL(libcfs_sock_abort_accept);
645 libcfs_sock_connect (struct socket **sockp, int *fatal,
646 __u32 local_ip, int local_port,
647 __u32 peer_ip, int peer_port)
649 struct sockaddr_in srvaddr;
652 rc = libcfs_sock_create(sockp, fatal, local_ip, local_port);
656 memset (&srvaddr, 0, sizeof (srvaddr));
657 srvaddr.sin_family = AF_INET;
658 srvaddr.sin_port = htons(peer_port);
659 srvaddr.sin_addr.s_addr = htonl(peer_ip);
661 rc = (*sockp)->ops->connect(*sockp,
662 (struct sockaddr *)&srvaddr, sizeof(srvaddr),
667 /* EADDRNOTAVAIL probably means we're already connected to the same
668 * peer/port on the same local port on a differently typed
669 * connection. Let our caller retry with a different local
671 *fatal = !(rc == -EADDRNOTAVAIL);
673 CDEBUG_LIMIT(*fatal ? D_NETERROR : D_NET,
674 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
675 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
677 sock_release(*sockp);
681 EXPORT_SYMBOL(libcfs_sock_connect);
684 libcfs_sock_release (struct socket *sock)
689 EXPORT_SYMBOL(libcfs_sock_release);