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.
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 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
46 #include <linux/syscalls.h>
52 libcfs_sock_ioctl(int cmd, unsigned long arg)
54 mm_segment_t oldmm = get_fs();
58 struct file *sock_filp;
60 rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock);
62 CERROR ("Can't create socket: %d\n", rc);
66 #ifdef HAVE_SOCK_MAP_FD_2ARG
67 fd = sock_map_fd(sock,0);
69 fd = sock_map_fd(sock);
84 #ifdef HAVE_UNLOCKED_IOCTL
85 if (sock_filp->f_op->unlocked_ioctl)
86 rc = sock_filp->f_op->unlocked_ioctl(sock_filp, cmd, arg);
91 rc =sock_filp->f_op->ioctl(sock_filp->f_dentry->d_inode,
106 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
113 nob = strnlen(name, IFNAMSIZ);
114 if (nob == IFNAMSIZ) {
115 CERROR("Interface name %s too long\n", name);
119 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
121 strcpy(ifr.ifr_name, name);
122 rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);
125 CERROR("Can't get flags for interface %s\n", name);
129 if ((ifr.ifr_flags & IFF_UP) == 0) {
130 CDEBUG(D_NET, "Interface %s down\n", name);
138 strcpy(ifr.ifr_name, name);
139 ifr.ifr_addr.sa_family = AF_INET;
140 rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);
143 CERROR("Can't get IP address for interface %s\n", name);
147 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
150 strcpy(ifr.ifr_name, name);
151 ifr.ifr_addr.sa_family = AF_INET;
152 rc = libcfs_sock_ioctl(SIOCGIFNETMASK, (unsigned long)&ifr);
155 CERROR("Can't get netmask for interface %s\n", name);
159 val = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr;
165 EXPORT_SYMBOL(libcfs_ipif_query);
168 libcfs_ipif_enumerate (char ***namesp)
170 /* Allocate and fill in 'names', returning # interfaces/error */
182 nalloc = 16; /* first guess at max interfaces */
185 if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
187 nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
188 CWARN("Too many interfaces: only enumerating first %d\n",
192 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
194 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
199 ifc.ifc_buf = (char *)ifr;
200 ifc.ifc_len = nalloc * sizeof(*ifr);
202 rc = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
205 CERROR ("Error %d enumerating interfaces\n", rc);
211 nfound = ifc.ifc_len/sizeof(*ifr);
212 LASSERT (nfound <= nalloc);
214 if (nfound < nalloc || toobig)
217 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
224 LIBCFS_ALLOC(names, nfound * sizeof(*names));
229 /* NULL out all names[i] */
230 memset (names, 0, nfound * sizeof(*names));
232 for (i = 0; i < nfound; i++) {
234 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
235 if (nob == IFNAMSIZ) {
236 /* no space for terminating NULL */
237 CERROR("interface name %.*s too long (%d max)\n",
238 nob, ifr[i].ifr_name, IFNAMSIZ);
243 LIBCFS_ALLOC(names[i], IFNAMSIZ);
244 if (names[i] == NULL) {
249 memcpy(names[i], ifr[i].ifr_name, nob);
258 libcfs_ipif_free_enumeration(names, nfound);
260 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
265 EXPORT_SYMBOL(libcfs_ipif_enumerate);
268 libcfs_ipif_free_enumeration (char **names, int n)
274 for (i = 0; i < n && names[i] != NULL; i++)
275 LIBCFS_FREE(names[i], IFNAMSIZ);
277 LIBCFS_FREE(names, n * sizeof(*names));
280 EXPORT_SYMBOL(libcfs_ipif_free_enumeration);
283 libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout)
286 mm_segment_t oldmm = get_fs();
287 long ticks = timeout * HZ;
292 /* Caller may pass a zero timeout if she thinks the socket buffer is
293 * empty enough to take the whole message immediately */
300 struct msghdr msg = {
307 .msg_flags = (timeout == 0) ? MSG_DONTWAIT : 0
311 /* Set send timeout to remaining time */
312 tv = (struct timeval) {
313 .tv_sec = ticks / HZ,
314 .tv_usec = ((ticks % HZ) * 1000000) / HZ
317 rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
318 (char *)&tv, sizeof(tv));
321 CERROR("Can't set socket send timeout "
323 (long)tv.tv_sec, (int)tv.tv_usec, rc);
330 rc = sock_sendmsg (sock, &msg, iov.iov_len);
331 ticks -= jiffies - then;
341 CERROR ("Unexpected zero rc\n");
342 return (-ECONNABORTED);
348 buffer = ((char *)buffer) + rc;
354 EXPORT_SYMBOL(libcfs_sock_write);
357 libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout)
360 mm_segment_t oldmm = get_fs();
361 long ticks = timeout * HZ;
373 struct msghdr msg = {
383 /* Set receive timeout to remaining time */
384 tv = (struct timeval) {
385 .tv_sec = ticks / HZ,
386 .tv_usec = ((ticks % HZ) * 1000000) / HZ
389 rc = sock_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
390 (char *)&tv, sizeof(tv));
393 CERROR("Can't set socket recv timeout %ld.%06d: %d\n",
394 (long)tv.tv_sec, (int)tv.tv_usec, rc);
400 rc = sock_recvmsg(sock, &msg, iov.iov_len, 0);
401 ticks -= jiffies - then;
410 buffer = ((char *)buffer) + rc;
421 EXPORT_SYMBOL(libcfs_sock_read);
424 libcfs_sock_create (struct socket **sockp, int *fatal,
425 __u32 local_ip, int local_port)
427 struct sockaddr_in locaddr;
431 mm_segment_t oldmm = get_fs();
433 /* All errors are fatal except bind failure if the port is in use */
436 rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock);
439 CERROR ("Can't create socket: %d\n", rc);
445 rc = sock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
446 (char *)&option, sizeof (option));
449 CERROR("Can't set SO_REUSEADDR for socket: %d\n", rc);
453 if (local_ip != 0 || local_port != 0) {
454 memset(&locaddr, 0, sizeof(locaddr));
455 locaddr.sin_family = AF_INET;
456 locaddr.sin_port = htons(local_port);
457 locaddr.sin_addr.s_addr = (local_ip == 0) ?
458 INADDR_ANY : htonl(local_ip);
460 rc = sock->ops->bind(sock, (struct sockaddr *)&locaddr,
462 if (rc == -EADDRINUSE) {
463 CDEBUG(D_NET, "Port %d already in use\n", local_port);
468 CERROR("Error trying to bind to port %d: %d\n",
482 libcfs_sock_setbuf (struct socket *sock, int txbufsize, int rxbufsize)
484 mm_segment_t oldmm = get_fs();
488 if (txbufsize != 0) {
491 rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
492 (char *)&option, sizeof (option));
495 CERROR ("Can't set send buffer %d: %d\n",
501 if (rxbufsize != 0) {
504 rc = sock_setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
505 (char *)&option, sizeof (option));
508 CERROR ("Can't set receive buffer %d: %d\n",
517 EXPORT_SYMBOL(libcfs_sock_setbuf);
520 libcfs_sock_getaddr (struct socket *sock, int remote, __u32 *ip, int *port)
522 struct sockaddr_in sin;
523 int len = sizeof (sin);
526 rc = sock->ops->getname (sock, (struct sockaddr *)&sin, &len,
529 CERROR ("Error %d getting sock %s IP/port\n",
530 rc, remote ? "peer" : "local");
535 *ip = ntohl (sin.sin_addr.s_addr);
538 *port = ntohs (sin.sin_port);
543 EXPORT_SYMBOL(libcfs_sock_getaddr);
546 libcfs_sock_getbuf (struct socket *sock, int *txbufsize, int *rxbufsize)
549 if (txbufsize != NULL) {
550 *txbufsize = sock->sk->sk_sndbuf;
553 if (rxbufsize != NULL) {
554 *rxbufsize = sock->sk->sk_rcvbuf;
560 EXPORT_SYMBOL(libcfs_sock_getbuf);
563 libcfs_sock_listen (struct socket **sockp,
564 __u32 local_ip, int local_port, int backlog)
569 rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
572 CERROR("Can't create socket: port %d already in use\n",
577 rc = (*sockp)->ops->listen(*sockp, backlog);
581 CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
582 sock_release(*sockp);
586 EXPORT_SYMBOL(libcfs_sock_listen);
588 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
589 int sock_create_lite(int family, int type, int protocol, struct socket **res)
605 libcfs_sock_accept (struct socket **newsockp, struct socket *sock)
608 struct socket *newsock;
611 init_waitqueue_entry(&wait, current);
613 /* XXX this should add a ref to sock->ops->owner, if
614 * TCP could be a module */
615 rc = sock_create_lite(PF_PACKET, sock->type, IPPROTO_TCP, &newsock);
617 CERROR("Can't allocate socket\n");
621 newsock->ops = sock->ops;
623 set_current_state(TASK_INTERRUPTIBLE);
624 add_wait_queue(sock->sk->sk_sleep, &wait);
626 rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
628 /* Nothing ready, so wait for activity */
630 rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
633 remove_wait_queue(sock->sk->sk_sleep, &wait);
634 set_current_state(TASK_RUNNING);
643 sock_release(newsock);
647 EXPORT_SYMBOL(libcfs_sock_accept);
650 libcfs_sock_abort_accept (struct socket *sock)
652 wake_up_all(sock->sk->sk_sleep);
655 EXPORT_SYMBOL(libcfs_sock_abort_accept);
658 libcfs_sock_connect (struct socket **sockp, int *fatal,
659 __u32 local_ip, int local_port,
660 __u32 peer_ip, int peer_port)
662 struct sockaddr_in srvaddr;
665 rc = libcfs_sock_create(sockp, fatal, local_ip, local_port);
669 memset (&srvaddr, 0, sizeof (srvaddr));
670 srvaddr.sin_family = AF_INET;
671 srvaddr.sin_port = htons(peer_port);
672 srvaddr.sin_addr.s_addr = htonl(peer_ip);
674 rc = (*sockp)->ops->connect(*sockp,
675 (struct sockaddr *)&srvaddr, sizeof(srvaddr),
680 /* EADDRNOTAVAIL probably means we're already connected to the same
681 * peer/port on the same local port on a differently typed
682 * connection. Let our caller retry with a different local
684 *fatal = !(rc == -EADDRNOTAVAIL);
686 CDEBUG(*fatal ? D_NETERROR : D_NET,
687 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
688 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
690 sock_release(*sockp);
694 EXPORT_SYMBOL(libcfs_sock_connect);
697 libcfs_sock_release (struct socket *sock)
702 EXPORT_SYMBOL(libcfs_sock_release);