Whamcloud - gitweb
480b9a5f72e5ce8d25df44cea916fb492e90dbcf
[fs/lustre-release.git] / libcfs / libcfs / linux / linux-tcpip.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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
19  *
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
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36 #define DEBUG_SUBSYSTEM S_LNET
37
38 #include <libcfs/libcfs.h>
39 #include <libcfs/libcfs.h>
40
41 #include <linux/if.h>
42 #include <linux/in.h>
43 #include <linux/file.h>
44 /* For sys_open & sys_close */
45 #include <linux/syscalls.h>
46
47 #ifndef HAVE_SK_SLEEP
48 static inline wait_queue_head_t *sk_sleep(struct sock *sk)
49 {
50         return sk->sk_sleep;
51 }
52 #endif
53
54 int
55 libcfs_sock_ioctl(int cmd, unsigned long arg)
56 {
57         mm_segment_t    oldmm = get_fs();
58         struct socket  *sock;
59         int             fd = -1;
60         int             rc;
61         struct file    *sock_filp;
62
63         rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock);
64         if (rc != 0) {
65                 CERROR ("Can't create socket: %d\n", rc);
66                 return rc;
67         }
68
69 #if !defined(HAVE_SOCK_ALLOC_FILE) && !defined(HAVE_SOCK_ALLOC_FILE_3ARGS)
70 # ifdef HAVE_SOCK_MAP_FD_2ARG
71         fd = sock_map_fd(sock,0);
72 # else
73         fd = sock_map_fd(sock);
74 # endif
75         if (fd < 0) {
76                 rc = fd;
77                 sock_release(sock);
78                 goto out;
79         }
80         sock_filp = fget(fd);
81 #else
82 # ifdef HAVE_SOCK_ALLOC_FILE_3ARGS
83         sock_filp = sock_alloc_file(sock, 0, NULL);
84 # else
85         sock_filp = sock_alloc_file(sock, 0);
86 # endif
87 #endif
88         if (!sock_filp) {
89                 rc = -ENOMEM;
90                 sock_release(sock);
91                 goto out;
92         }
93
94         set_fs(KERNEL_DS);
95         if (sock_filp->f_op->unlocked_ioctl)
96                 rc = sock_filp->f_op->unlocked_ioctl(sock_filp, cmd, arg);
97         set_fs(oldmm);
98
99         fput(sock_filp);
100
101  out:
102         if (fd >= 0)
103                 sys_close(fd);
104
105         return rc;
106 }
107
108 int
109 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
110 {
111         struct ifreq   ifr;
112         int            nob;
113         int            rc;
114         __u32          val;
115
116         nob = strnlen(name, IFNAMSIZ);
117         if (nob == IFNAMSIZ) {
118                 CERROR("Interface name %s too long\n", name);
119                 return -EINVAL;
120         }
121
122         CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
123
124         strcpy(ifr.ifr_name, name);
125         rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);
126
127         if (rc != 0) {
128                 CERROR("Can't get flags for interface %s\n", name);
129                 return rc;
130         }
131
132         if ((ifr.ifr_flags & IFF_UP) == 0) {
133                 CDEBUG(D_NET, "Interface %s down\n", name);
134                 *up = 0;
135                 *ip = *mask = 0;
136                 return 0;
137         }
138
139         *up = 1;
140
141         strcpy(ifr.ifr_name, name);
142         ifr.ifr_addr.sa_family = AF_INET;
143         rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);
144
145         if (rc != 0) {
146                 CERROR("Can't get IP address for interface %s\n", name);
147                 return rc;
148         }
149
150         val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
151         *ip = ntohl(val);
152
153         strcpy(ifr.ifr_name, name);
154         ifr.ifr_addr.sa_family = AF_INET;
155         rc = libcfs_sock_ioctl(SIOCGIFNETMASK, (unsigned long)&ifr);
156
157         if (rc != 0) {
158                 CERROR("Can't get netmask for interface %s\n", name);
159                 return rc;
160         }
161
162         val = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr;
163         *mask = ntohl(val);
164
165         return 0;
166 }
167
168 EXPORT_SYMBOL(libcfs_ipif_query);
169
170 int
171 libcfs_ipif_enumerate (char ***namesp)
172 {
173         /* Allocate and fill in 'names', returning # interfaces/error */
174         char           **names;
175         int             toobig;
176         int             nalloc;
177         int             nfound;
178         struct ifreq   *ifr;
179         struct ifconf   ifc;
180         int             rc;
181         int             nob;
182         int             i;
183
184
185         nalloc = 16;        /* first guess at max interfaces */
186         toobig = 0;
187         for (;;) {
188                 if (nalloc * sizeof(*ifr) > PAGE_CACHE_SIZE) {
189                         toobig = 1;
190                         nalloc = PAGE_CACHE_SIZE/sizeof(*ifr);
191                         CWARN("Too many interfaces: only enumerating first %d\n",
192                               nalloc);
193                 }
194
195                 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
196                 if (ifr == NULL) {
197                         CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
198                         rc = -ENOMEM;
199                         goto out0;
200                 }
201
202                 ifc.ifc_buf = (char *)ifr;
203                 ifc.ifc_len = nalloc * sizeof(*ifr);
204
205                 rc = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
206
207                 if (rc < 0) {
208                         CERROR ("Error %d enumerating interfaces\n", rc);
209                         goto out1;
210                 }
211
212                 LASSERT (rc == 0);
213
214                 nfound = ifc.ifc_len/sizeof(*ifr);
215                 LASSERT (nfound <= nalloc);
216
217                 if (nfound < nalloc || toobig)
218                         break;
219
220                 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
221                 nalloc *= 2;
222         }
223
224         if (nfound == 0)
225                 goto out1;
226
227         LIBCFS_ALLOC(names, nfound * sizeof(*names));
228         if (names == NULL) {
229                 rc = -ENOMEM;
230                 goto out1;
231         }
232         /* NULL out all names[i] */
233         memset (names, 0, nfound * sizeof(*names));
234
235         for (i = 0; i < nfound; i++) {
236
237                 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
238                 if (nob == IFNAMSIZ) {
239                         /* no space for terminating NULL */
240                         CERROR("interface name %.*s too long (%d max)\n",
241                                nob, ifr[i].ifr_name, IFNAMSIZ);
242                         rc = -ENAMETOOLONG;
243                         goto out2;
244                 }
245
246                 LIBCFS_ALLOC(names[i], IFNAMSIZ);
247                 if (names[i] == NULL) {
248                         rc = -ENOMEM;
249                         goto out2;
250                 }
251
252                 memcpy(names[i], ifr[i].ifr_name, nob);
253                 names[i][nob] = 0;
254         }
255
256         *namesp = names;
257         rc = nfound;
258
259  out2:
260         if (rc < 0)
261                 libcfs_ipif_free_enumeration(names, nfound);
262  out1:
263         LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
264  out0:
265         return rc;
266 }
267
268 EXPORT_SYMBOL(libcfs_ipif_enumerate);
269
270 void
271 libcfs_ipif_free_enumeration (char **names, int n)
272 {
273         int      i;
274
275         LASSERT (n > 0);
276
277         for (i = 0; i < n && names[i] != NULL; i++)
278                 LIBCFS_FREE(names[i], IFNAMSIZ);
279
280         LIBCFS_FREE(names, n * sizeof(*names));
281 }
282
283 EXPORT_SYMBOL(libcfs_ipif_free_enumeration);
284
285 int
286 libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout)
287 {
288         int            rc;
289         mm_segment_t   oldmm = get_fs();
290         long           ticks = timeout * HZ;
291         unsigned long  then;
292         struct timeval tv;
293
294         LASSERT (nob > 0);
295         /* Caller may pass a zero timeout if she thinks the socket buffer is
296          * empty enough to take the whole message immediately */
297
298         for (;;) {
299                 struct iovec  iov = {
300                         .iov_base = buffer,
301                         .iov_len  = nob
302                 };
303                 struct msghdr msg = {
304                         .msg_name       = NULL,
305                         .msg_namelen    = 0,
306                         .msg_iov        = &iov,
307                         .msg_iovlen     = 1,
308                         .msg_control    = NULL,
309                         .msg_controllen = 0,
310                         .msg_flags      = (timeout == 0) ? MSG_DONTWAIT : 0
311                 };
312
313                 if (timeout != 0) {
314                         /* Set send timeout to remaining time */
315                         tv = (struct timeval) {
316                                 .tv_sec = ticks / HZ,
317                                 .tv_usec = ((ticks % HZ) * 1000000) / HZ
318                         };
319                         set_fs(KERNEL_DS);
320                         rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
321                                              (char *)&tv, sizeof(tv));
322                         set_fs(oldmm);
323                         if (rc != 0) {
324                                 CERROR("Can't set socket send timeout "
325                                        "%ld.%06d: %d\n",
326                                        (long)tv.tv_sec, (int)tv.tv_usec, rc);
327                                 return rc;
328                         }
329                 }
330
331                 set_fs (KERNEL_DS);
332                 then = jiffies;
333                 rc = sock_sendmsg (sock, &msg, iov.iov_len);
334                 ticks -= jiffies - then;
335                 set_fs (oldmm);
336
337                 if (rc == nob)
338                         return 0;
339
340                 if (rc < 0)
341                         return rc;
342
343                 if (rc == 0) {
344                         CERROR ("Unexpected zero rc\n");
345                         return (-ECONNABORTED);
346                 }
347
348                 if (ticks <= 0)
349                         return -EAGAIN;
350
351                 buffer = ((char *)buffer) + rc;
352                 nob -= rc;
353         }
354
355         return (0);
356 }
357 EXPORT_SYMBOL(libcfs_sock_write);
358
359 int
360 libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout)
361 {
362         int            rc;
363         mm_segment_t   oldmm = get_fs();
364         long           ticks = timeout * HZ;
365         unsigned long  then;
366         struct timeval tv;
367
368         LASSERT (nob > 0);
369         LASSERT (ticks > 0);
370
371         for (;;) {
372                 struct iovec  iov = {
373                         .iov_base = buffer,
374                         .iov_len  = nob
375                 };
376                 struct msghdr msg = {
377                         .msg_name       = NULL,
378                         .msg_namelen    = 0,
379                         .msg_iov        = &iov,
380                         .msg_iovlen     = 1,
381                         .msg_control    = NULL,
382                         .msg_controllen = 0,
383                         .msg_flags      = 0
384                 };
385
386                 /* Set receive timeout to remaining time */
387                 tv = (struct timeval) {
388                         .tv_sec = ticks / HZ,
389                         .tv_usec = ((ticks % HZ) * 1000000) / HZ
390                 };
391                 set_fs(KERNEL_DS);
392                 rc = sock_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
393                                      (char *)&tv, sizeof(tv));
394                 set_fs(oldmm);
395                 if (rc != 0) {
396                         CERROR("Can't set socket recv timeout %ld.%06d: %d\n",
397                                (long)tv.tv_sec, (int)tv.tv_usec, rc);
398                         return rc;
399                 }
400
401                 set_fs(KERNEL_DS);
402                 then = jiffies;
403                 rc = sock_recvmsg(sock, &msg, iov.iov_len, 0);
404                 ticks -= jiffies - then;
405                 set_fs(oldmm);
406
407                 if (rc < 0)
408                         return rc;
409
410                 if (rc == 0)
411                         return -ECONNRESET;
412
413                 buffer = ((char *)buffer) + rc;
414                 nob -= rc;
415
416                 if (nob == 0)
417                         return 0;
418
419                 if (ticks <= 0)
420                         return -ETIMEDOUT;
421         }
422 }
423
424 EXPORT_SYMBOL(libcfs_sock_read);
425
426 static int
427 libcfs_sock_create (struct socket **sockp, int *fatal,
428                     __u32 local_ip, int local_port)
429 {
430         struct sockaddr_in  locaddr;
431         struct socket      *sock;
432         int                 rc;
433         int                 option;
434         mm_segment_t        oldmm = get_fs();
435
436         /* All errors are fatal except bind failure if the port is in use */
437         *fatal = 1;
438
439         rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock);
440         *sockp = sock;
441         if (rc != 0) {
442                 CERROR ("Can't create socket: %d\n", rc);
443                 return (rc);
444         }
445
446         set_fs (KERNEL_DS);
447         option = 1;
448         rc = sock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
449                              (char *)&option, sizeof (option));
450         set_fs (oldmm);
451         if (rc != 0) {
452                 CERROR("Can't set SO_REUSEADDR for socket: %d\n", rc);
453                 goto failed;
454         }
455
456         if (local_ip != 0 || local_port != 0) {
457                 memset(&locaddr, 0, sizeof(locaddr));
458                 locaddr.sin_family = AF_INET;
459                 locaddr.sin_port = htons(local_port);
460                 locaddr.sin_addr.s_addr = (local_ip == 0) ?
461                                           INADDR_ANY : htonl(local_ip);
462
463                 rc = sock->ops->bind(sock, (struct sockaddr *)&locaddr,
464                                      sizeof(locaddr));
465                 if (rc == -EADDRINUSE) {
466                         CDEBUG(D_NET, "Port %d already in use\n", local_port);
467                         *fatal = 0;
468                         goto failed;
469                 }
470                 if (rc != 0) {
471                         CERROR("Error trying to bind to port %d: %d\n",
472                                local_port, rc);
473                         goto failed;
474                 }
475         }
476
477         return 0;
478
479  failed:
480         sock_release(sock);
481         return rc;
482 }
483
484 int
485 libcfs_sock_setbuf (struct socket *sock, int txbufsize, int rxbufsize)
486 {
487         mm_segment_t        oldmm = get_fs();
488         int                 option;
489         int                 rc;
490
491         if (txbufsize != 0) {
492                 option = txbufsize;
493                 set_fs (KERNEL_DS);
494                 rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
495                                      (char *)&option, sizeof (option));
496                 set_fs (oldmm);
497                 if (rc != 0) {
498                         CERROR ("Can't set send buffer %d: %d\n",
499                                 option, rc);
500                         return (rc);
501                 }
502         }
503
504         if (rxbufsize != 0) {
505                 option = rxbufsize;
506                 set_fs (KERNEL_DS);
507                 rc = sock_setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
508                                       (char *)&option, sizeof (option));
509                 set_fs (oldmm);
510                 if (rc != 0) {
511                         CERROR ("Can't set receive buffer %d: %d\n",
512                                 option, rc);
513                         return (rc);
514                 }
515         }
516
517         return 0;
518 }
519
520 EXPORT_SYMBOL(libcfs_sock_setbuf);
521
522 int
523 libcfs_sock_getaddr (struct socket *sock, int remote, __u32 *ip, int *port)
524 {
525         struct sockaddr_in sin;
526         int                len = sizeof (sin);
527         int                rc;
528
529         rc = sock->ops->getname (sock, (struct sockaddr *)&sin, &len,
530                                  remote ? 2 : 0);
531         if (rc != 0) {
532                 CERROR ("Error %d getting sock %s IP/port\n",
533                         rc, remote ? "peer" : "local");
534                 return rc;
535         }
536
537         if (ip != NULL)
538                 *ip = ntohl (sin.sin_addr.s_addr);
539
540         if (port != NULL)
541                 *port = ntohs (sin.sin_port);
542
543         return 0;
544 }
545
546 EXPORT_SYMBOL(libcfs_sock_getaddr);
547
548 int
549 libcfs_sock_getbuf (struct socket *sock, int *txbufsize, int *rxbufsize)
550 {
551
552         if (txbufsize != NULL) {
553                 *txbufsize = sock->sk->sk_sndbuf;
554         }
555
556         if (rxbufsize != NULL) {
557                 *rxbufsize = sock->sk->sk_rcvbuf;
558         }
559
560         return 0;
561 }
562
563 EXPORT_SYMBOL(libcfs_sock_getbuf);
564
565 int
566 libcfs_sock_listen (struct socket **sockp,
567                     __u32 local_ip, int local_port, int backlog)
568 {
569         int      fatal;
570         int      rc;
571
572         rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
573         if (rc != 0) {
574                 if (!fatal)
575                         CERROR("Can't create socket: port %d already in use\n",
576                                local_port);
577                 return rc;
578         }
579
580         rc = (*sockp)->ops->listen(*sockp, backlog);
581         if (rc == 0)
582                 return 0;
583
584         CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
585         sock_release(*sockp);
586         return rc;
587 }
588
589 EXPORT_SYMBOL(libcfs_sock_listen);
590
591 int
592 libcfs_sock_accept (struct socket **newsockp, struct socket *sock)
593 {
594         wait_queue_t   wait;
595         struct socket *newsock;
596         int            rc;
597
598         init_waitqueue_entry(&wait, current);
599
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);
603         if (rc) {
604                 CERROR("Can't allocate socket\n");
605                 return rc;
606         }
607
608         newsock->ops = sock->ops;
609
610         set_current_state(TASK_INTERRUPTIBLE);
611         add_wait_queue(sk_sleep(sock->sk), &wait);
612
613         rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
614         if (rc == -EAGAIN) {
615                 /* Nothing ready, so wait for activity */
616                 schedule();
617                 rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
618         }
619
620         remove_wait_queue(sk_sleep(sock->sk), &wait);
621         set_current_state(TASK_RUNNING);
622
623         if (rc != 0)
624                 goto failed;
625
626         *newsockp = newsock;
627         return 0;
628
629  failed:
630         sock_release(newsock);
631         return rc;
632 }
633
634 EXPORT_SYMBOL(libcfs_sock_accept);
635
636 void
637 libcfs_sock_abort_accept (struct socket *sock)
638 {
639         wake_up_all(sk_sleep(sock->sk));
640 }
641
642 EXPORT_SYMBOL(libcfs_sock_abort_accept);
643
644 int
645 libcfs_sock_connect (struct socket **sockp, int *fatal,
646                      __u32 local_ip, int local_port,
647                      __u32 peer_ip, int peer_port)
648 {
649         struct sockaddr_in  srvaddr;
650         int                 rc;
651
652         rc = libcfs_sock_create(sockp, fatal, local_ip, local_port);
653         if (rc != 0)
654                 return rc;
655
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);
660
661         rc = (*sockp)->ops->connect(*sockp,
662                                     (struct sockaddr *)&srvaddr, sizeof(srvaddr),
663                                     0);
664         if (rc == 0)
665                 return 0;
666
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
670          * port... */
671         *fatal = !(rc == -EADDRNOTAVAIL);
672
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);
676
677         sock_release(*sockp);
678         return rc;
679 }
680
681 EXPORT_SYMBOL(libcfs_sock_connect);
682
683 void
684 libcfs_sock_release (struct socket *sock)
685 {
686         sock_release(sock);
687 }
688
689 EXPORT_SYMBOL(libcfs_sock_release);