1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Use is subject to license terms.
32 * Copyright (c) 2012, Whamcloud, Inc.
35 * This file is part of Lustre, http://www.lustre.org/
36 * Lustre is a trademark of Sun Microsystems, Inc.
38 #define DEBUG_SUBSYSTEM S_LNET
40 #include <libcfs/libcfs.h>
41 #include <libcfs/libcfs.h>
45 #include <linux/file.h>
46 /* For sys_open & sys_close */
47 #include <linux/syscalls.h>
50 libcfs_sock_ioctl(int cmd, unsigned long arg)
52 mm_segment_t oldmm = get_fs();
56 struct file *sock_filp;
58 rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock);
60 CERROR ("Can't create socket: %d\n", rc);
64 #ifdef HAVE_SOCK_MAP_FD_2ARG
65 fd = sock_map_fd(sock,0);
67 fd = sock_map_fd(sock);
82 #ifdef HAVE_UNLOCKED_IOCTL
83 if (sock_filp->f_op->unlocked_ioctl)
84 rc = sock_filp->f_op->unlocked_ioctl(sock_filp, cmd, arg);
87 rc = sock_filp->f_op->ioctl(sock_filp->f_dentry->d_inode,
102 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
109 nob = strnlen(name, IFNAMSIZ);
110 if (nob == IFNAMSIZ) {
111 CERROR("Interface name %s too long\n", name);
115 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
117 strcpy(ifr.ifr_name, name);
118 rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);
121 CERROR("Can't get flags for interface %s\n", name);
125 if ((ifr.ifr_flags & IFF_UP) == 0) {
126 CDEBUG(D_NET, "Interface %s down\n", name);
134 strcpy(ifr.ifr_name, name);
135 ifr.ifr_addr.sa_family = AF_INET;
136 rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);
139 CERROR("Can't get IP address for interface %s\n", name);
143 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
146 strcpy(ifr.ifr_name, name);
147 ifr.ifr_addr.sa_family = AF_INET;
148 rc = libcfs_sock_ioctl(SIOCGIFNETMASK, (unsigned long)&ifr);
151 CERROR("Can't get netmask for interface %s\n", name);
155 val = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr;
161 EXPORT_SYMBOL(libcfs_ipif_query);
164 libcfs_ipif_enumerate (char ***namesp)
166 /* Allocate and fill in 'names', returning # interfaces/error */
178 nalloc = 16; /* first guess at max interfaces */
181 if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
183 nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
184 CWARN("Too many interfaces: only enumerating first %d\n",
188 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
190 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
195 ifc.ifc_buf = (char *)ifr;
196 ifc.ifc_len = nalloc * sizeof(*ifr);
198 rc = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
201 CERROR ("Error %d enumerating interfaces\n", rc);
207 nfound = ifc.ifc_len/sizeof(*ifr);
208 LASSERT (nfound <= nalloc);
210 if (nfound < nalloc || toobig)
213 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
220 LIBCFS_ALLOC(names, nfound * sizeof(*names));
225 /* NULL out all names[i] */
226 memset (names, 0, nfound * sizeof(*names));
228 for (i = 0; i < nfound; i++) {
230 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
231 if (nob == IFNAMSIZ) {
232 /* no space for terminating NULL */
233 CERROR("interface name %.*s too long (%d max)\n",
234 nob, ifr[i].ifr_name, IFNAMSIZ);
239 LIBCFS_ALLOC(names[i], IFNAMSIZ);
240 if (names[i] == NULL) {
245 memcpy(names[i], ifr[i].ifr_name, nob);
254 libcfs_ipif_free_enumeration(names, nfound);
256 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
261 EXPORT_SYMBOL(libcfs_ipif_enumerate);
264 libcfs_ipif_free_enumeration (char **names, int n)
270 for (i = 0; i < n && names[i] != NULL; i++)
271 LIBCFS_FREE(names[i], IFNAMSIZ);
273 LIBCFS_FREE(names, n * sizeof(*names));
276 EXPORT_SYMBOL(libcfs_ipif_free_enumeration);
279 libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout)
282 mm_segment_t oldmm = get_fs();
283 long ticks = timeout * HZ;
288 /* Caller may pass a zero timeout if she thinks the socket buffer is
289 * empty enough to take the whole message immediately */
296 struct msghdr msg = {
303 .msg_flags = (timeout == 0) ? MSG_DONTWAIT : 0
307 /* Set send timeout to remaining time */
308 tv = (struct timeval) {
309 .tv_sec = ticks / HZ,
310 .tv_usec = ((ticks % HZ) * 1000000) / HZ
313 rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
314 (char *)&tv, sizeof(tv));
317 CERROR("Can't set socket send timeout "
319 (long)tv.tv_sec, (int)tv.tv_usec, rc);
326 rc = sock_sendmsg (sock, &msg, iov.iov_len);
327 ticks -= jiffies - then;
337 CERROR ("Unexpected zero rc\n");
338 return (-ECONNABORTED);
344 buffer = ((char *)buffer) + rc;
350 EXPORT_SYMBOL(libcfs_sock_write);
353 libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout)
356 mm_segment_t oldmm = get_fs();
357 long ticks = timeout * HZ;
369 struct msghdr msg = {
379 /* Set receive timeout to remaining time */
380 tv = (struct timeval) {
381 .tv_sec = ticks / HZ,
382 .tv_usec = ((ticks % HZ) * 1000000) / HZ
385 rc = sock_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
386 (char *)&tv, sizeof(tv));
389 CERROR("Can't set socket recv timeout %ld.%06d: %d\n",
390 (long)tv.tv_sec, (int)tv.tv_usec, rc);
396 rc = sock_recvmsg(sock, &msg, iov.iov_len, 0);
397 ticks -= jiffies - then;
406 buffer = ((char *)buffer) + rc;
417 EXPORT_SYMBOL(libcfs_sock_read);
420 libcfs_sock_create (struct socket **sockp, int *fatal,
421 __u32 local_ip, int local_port)
423 struct sockaddr_in locaddr;
427 mm_segment_t oldmm = get_fs();
429 /* All errors are fatal except bind failure if the port is in use */
432 rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock);
435 CERROR ("Can't create socket: %d\n", rc);
441 rc = sock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
442 (char *)&option, sizeof (option));
445 CERROR("Can't set SO_REUSEADDR for socket: %d\n", rc);
449 if (local_ip != 0 || local_port != 0) {
450 memset(&locaddr, 0, sizeof(locaddr));
451 locaddr.sin_family = AF_INET;
452 locaddr.sin_port = htons(local_port);
453 locaddr.sin_addr.s_addr = (local_ip == 0) ?
454 INADDR_ANY : htonl(local_ip);
456 rc = sock->ops->bind(sock, (struct sockaddr *)&locaddr,
458 if (rc == -EADDRINUSE) {
459 CDEBUG(D_NET, "Port %d already in use\n", local_port);
464 CERROR("Error trying to bind to port %d: %d\n",
478 libcfs_sock_setbuf (struct socket *sock, int txbufsize, int rxbufsize)
480 mm_segment_t oldmm = get_fs();
484 if (txbufsize != 0) {
487 rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
488 (char *)&option, sizeof (option));
491 CERROR ("Can't set send buffer %d: %d\n",
497 if (rxbufsize != 0) {
500 rc = sock_setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
501 (char *)&option, sizeof (option));
504 CERROR ("Can't set receive buffer %d: %d\n",
513 EXPORT_SYMBOL(libcfs_sock_setbuf);
516 libcfs_sock_getaddr (struct socket *sock, int remote, __u32 *ip, int *port)
518 struct sockaddr_in sin;
519 int len = sizeof (sin);
522 rc = sock->ops->getname (sock, (struct sockaddr *)&sin, &len,
525 CERROR ("Error %d getting sock %s IP/port\n",
526 rc, remote ? "peer" : "local");
531 *ip = ntohl (sin.sin_addr.s_addr);
534 *port = ntohs (sin.sin_port);
539 EXPORT_SYMBOL(libcfs_sock_getaddr);
542 libcfs_sock_getbuf (struct socket *sock, int *txbufsize, int *rxbufsize)
545 if (txbufsize != NULL) {
546 *txbufsize = sock->sk->sk_sndbuf;
549 if (rxbufsize != NULL) {
550 *rxbufsize = sock->sk->sk_rcvbuf;
556 EXPORT_SYMBOL(libcfs_sock_getbuf);
559 libcfs_sock_listen (struct socket **sockp,
560 __u32 local_ip, int local_port, int backlog)
565 rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
568 CERROR("Can't create socket: port %d already in use\n",
573 rc = (*sockp)->ops->listen(*sockp, backlog);
577 CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
578 sock_release(*sockp);
582 EXPORT_SYMBOL(libcfs_sock_listen);
584 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
585 int sock_create_lite(int family, int type, int protocol, struct socket **res)
601 libcfs_sock_accept (struct socket **newsockp, struct socket *sock)
604 struct socket *newsock;
607 init_waitqueue_entry(&wait, current);
609 /* XXX this should add a ref to sock->ops->owner, if
610 * TCP could be a module */
611 rc = sock_create_lite(PF_PACKET, sock->type, IPPROTO_TCP, &newsock);
613 CERROR("Can't allocate socket\n");
617 newsock->ops = sock->ops;
619 set_current_state(TASK_INTERRUPTIBLE);
620 add_wait_queue(sk_sleep(sock->sk), &wait);
622 rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
624 /* Nothing ready, so wait for activity */
626 rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
629 remove_wait_queue(sk_sleep(sock->sk), &wait);
630 set_current_state(TASK_RUNNING);
639 sock_release(newsock);
643 EXPORT_SYMBOL(libcfs_sock_accept);
646 libcfs_sock_abort_accept (struct socket *sock)
648 wake_up_all(sk_sleep(sock->sk));
651 EXPORT_SYMBOL(libcfs_sock_abort_accept);
654 libcfs_sock_connect (struct socket **sockp, int *fatal,
655 __u32 local_ip, int local_port,
656 __u32 peer_ip, int peer_port)
658 struct sockaddr_in srvaddr;
661 rc = libcfs_sock_create(sockp, fatal, local_ip, local_port);
665 memset (&srvaddr, 0, sizeof (srvaddr));
666 srvaddr.sin_family = AF_INET;
667 srvaddr.sin_port = htons(peer_port);
668 srvaddr.sin_addr.s_addr = htonl(peer_ip);
670 rc = (*sockp)->ops->connect(*sockp,
671 (struct sockaddr *)&srvaddr, sizeof(srvaddr),
676 /* EADDRNOTAVAIL probably means we're already connected to the same
677 * peer/port on the same local port on a differently typed
678 * connection. Let our caller retry with a different local
680 *fatal = !(rc == -EADDRNOTAVAIL);
682 CDEBUG_LIMIT(*fatal ? D_NETERROR : D_NET,
683 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
684 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
686 sock_release(*sockp);
690 EXPORT_SYMBOL(libcfs_sock_connect);
693 libcfs_sock_release (struct socket *sock)
698 EXPORT_SYMBOL(libcfs_sock_release);