]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/lustre/lnet/lnet/lib-socket.c
Merge remote-tracking branch 'asoc/topic/sti' into asoc-next
[karo-tx-linux.git] / drivers / staging / lustre / lnet / lnet / lib-socket.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.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2015, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Seagate, Inc.
31  */
32 #define DEBUG_SUBSYSTEM S_LNET
33
34 #include <linux/if.h>
35 #include <linux/in.h>
36 #include <linux/net.h>
37 #include <linux/file.h>
38 #include <linux/pagemap.h>
39 /* For sys_open & sys_close */
40 #include <linux/syscalls.h>
41 #include <net/sock.h>
42
43 #include "../../include/linux/libcfs/libcfs.h"
44 #include "../../include/linux/lnet/lib-lnet.h"
45
46 static int
47 kernel_sock_unlocked_ioctl(struct file *filp, int cmd, unsigned long arg)
48 {
49         mm_segment_t oldfs = get_fs();
50         int err;
51
52         set_fs(KERNEL_DS);
53         err = filp->f_op->unlocked_ioctl(filp, cmd, arg);
54         set_fs(oldfs);
55
56         return err;
57 }
58
59 static int
60 lnet_sock_ioctl(int cmd, unsigned long arg)
61 {
62         struct file *sock_filp;
63         struct socket *sock;
64         int rc;
65
66         rc = sock_create(PF_INET, SOCK_STREAM, 0, &sock);
67         if (rc) {
68                 CERROR("Can't create socket: %d\n", rc);
69                 return rc;
70         }
71
72         sock_filp = sock_alloc_file(sock, 0, NULL);
73         if (IS_ERR(sock_filp)) {
74                 sock_release(sock);
75                 rc = PTR_ERR(sock_filp);
76                 goto out;
77         }
78
79         rc = kernel_sock_unlocked_ioctl(sock_filp, cmd, arg);
80
81         fput(sock_filp);
82 out:
83         return rc;
84 }
85
86 int
87 lnet_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask)
88 {
89         struct ifreq ifr;
90         int nob;
91         int rc;
92         __u32 val;
93
94         nob = strnlen(name, IFNAMSIZ);
95         if (nob == IFNAMSIZ) {
96                 CERROR("Interface name %s too long\n", name);
97                 return -EINVAL;
98         }
99
100         CLASSERT(sizeof(ifr.ifr_name) >= IFNAMSIZ);
101
102         if (strlen(name) > sizeof(ifr.ifr_name) - 1)
103                 return -E2BIG;
104         strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
105
106         rc = lnet_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);
107         if (rc) {
108                 CERROR("Can't get flags for interface %s\n", name);
109                 return rc;
110         }
111
112         if (!(ifr.ifr_flags & IFF_UP)) {
113                 CDEBUG(D_NET, "Interface %s down\n", name);
114                 *up = 0;
115                 *ip = *mask = 0;
116                 return 0;
117         }
118         *up = 1;
119
120         if (strlen(name) > sizeof(ifr.ifr_name) - 1)
121                 return -E2BIG;
122         strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
123
124         ifr.ifr_addr.sa_family = AF_INET;
125         rc = lnet_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);
126         if (rc) {
127                 CERROR("Can't get IP address for interface %s\n", name);
128                 return rc;
129         }
130
131         val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
132         *ip = ntohl(val);
133
134         if (strlen(name) > sizeof(ifr.ifr_name) - 1)
135                 return -E2BIG;
136         strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
137
138         ifr.ifr_addr.sa_family = AF_INET;
139         rc = lnet_sock_ioctl(SIOCGIFNETMASK, (unsigned long)&ifr);
140         if (rc) {
141                 CERROR("Can't get netmask for interface %s\n", name);
142                 return rc;
143         }
144
145         val = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr;
146         *mask = ntohl(val);
147
148         return 0;
149 }
150 EXPORT_SYMBOL(lnet_ipif_query);
151
152 int
153 lnet_ipif_enumerate(char ***namesp)
154 {
155         /* Allocate and fill in 'names', returning # interfaces/error */
156         char **names;
157         int toobig;
158         int nalloc;
159         int nfound;
160         struct ifreq *ifr;
161         struct ifconf ifc;
162         int rc;
163         int nob;
164         int i;
165
166         nalloc = 16;    /* first guess at max interfaces */
167         toobig = 0;
168         for (;;) {
169                 if (nalloc * sizeof(*ifr) > PAGE_SIZE) {
170                         toobig = 1;
171                         nalloc = PAGE_SIZE / sizeof(*ifr);
172                         CWARN("Too many interfaces: only enumerating first %d\n",
173                               nalloc);
174                 }
175
176                 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
177                 if (!ifr) {
178                         CERROR("ENOMEM enumerating up to %d interfaces\n",
179                                nalloc);
180                         rc = -ENOMEM;
181                         goto out0;
182                 }
183
184                 ifc.ifc_buf = (char *)ifr;
185                 ifc.ifc_len = nalloc * sizeof(*ifr);
186
187                 rc = lnet_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
188                 if (rc < 0) {
189                         CERROR("Error %d enumerating interfaces\n", rc);
190                         goto out1;
191                 }
192
193                 LASSERT(!rc);
194
195                 nfound = ifc.ifc_len / sizeof(*ifr);
196                 LASSERT(nfound <= nalloc);
197
198                 if (nfound < nalloc || toobig)
199                         break;
200
201                 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
202                 nalloc *= 2;
203         }
204
205         if (!nfound)
206                 goto out1;
207
208         LIBCFS_ALLOC(names, nfound * sizeof(*names));
209         if (!names) {
210                 rc = -ENOMEM;
211                 goto out1;
212         }
213
214         for (i = 0; i < nfound; i++) {
215                 nob = strnlen(ifr[i].ifr_name, IFNAMSIZ);
216                 if (nob == IFNAMSIZ) {
217                         /* no space for terminating NULL */
218                         CERROR("interface name %.*s too long (%d max)\n",
219                                nob, ifr[i].ifr_name, IFNAMSIZ);
220                         rc = -ENAMETOOLONG;
221                         goto out2;
222                 }
223
224                 LIBCFS_ALLOC(names[i], IFNAMSIZ);
225                 if (!names[i]) {
226                         rc = -ENOMEM;
227                         goto out2;
228                 }
229
230                 memcpy(names[i], ifr[i].ifr_name, nob);
231                 names[i][nob] = 0;
232         }
233
234         *namesp = names;
235         rc = nfound;
236
237 out2:
238         if (rc < 0)
239                 lnet_ipif_free_enumeration(names, nfound);
240 out1:
241         LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
242 out0:
243         return rc;
244 }
245 EXPORT_SYMBOL(lnet_ipif_enumerate);
246
247 void
248 lnet_ipif_free_enumeration(char **names, int n)
249 {
250         int i;
251
252         LASSERT(n > 0);
253
254         for (i = 0; i < n && names[i]; i++)
255                 LIBCFS_FREE(names[i], IFNAMSIZ);
256
257         LIBCFS_FREE(names, n * sizeof(*names));
258 }
259 EXPORT_SYMBOL(lnet_ipif_free_enumeration);
260
261 int
262 lnet_sock_write(struct socket *sock, void *buffer, int nob, int timeout)
263 {
264         int rc;
265         long jiffies_left = timeout * msecs_to_jiffies(MSEC_PER_SEC);
266         unsigned long then;
267         struct timeval tv;
268
269         LASSERT(nob > 0);
270         /*
271          * Caller may pass a zero timeout if she thinks the socket buffer is
272          * empty enough to take the whole message immediately
273          */
274         for (;;) {
275                 struct kvec  iov = {
276                         .iov_base = buffer,
277                         .iov_len  = nob
278                 };
279                 struct msghdr msg = {
280                         .msg_flags      = !timeout ? MSG_DONTWAIT : 0
281                 };
282
283                 if (timeout) {
284                         /* Set send timeout to remaining time */
285                         jiffies_to_timeval(jiffies_left, &tv);
286                         rc = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
287                                                (char *)&tv, sizeof(tv));
288                         if (rc) {
289                                 CERROR("Can't set socket send timeout %ld.%06d: %d\n",
290                                        (long)tv.tv_sec, (int)tv.tv_usec, rc);
291                                 return rc;
292                         }
293                 }
294
295                 then = jiffies;
296                 rc = kernel_sendmsg(sock, &msg, &iov, 1, nob);
297                 jiffies_left -= jiffies - then;
298
299                 if (rc == nob)
300                         return 0;
301
302                 if (rc < 0)
303                         return rc;
304
305                 if (!rc) {
306                         CERROR("Unexpected zero rc\n");
307                         return -ECONNABORTED;
308                 }
309
310                 if (jiffies_left <= 0)
311                         return -EAGAIN;
312
313                 buffer = ((char *)buffer) + rc;
314                 nob -= rc;
315         }
316         return 0;
317 }
318 EXPORT_SYMBOL(lnet_sock_write);
319
320 int
321 lnet_sock_read(struct socket *sock, void *buffer, int nob, int timeout)
322 {
323         int rc;
324         long jiffies_left = timeout * msecs_to_jiffies(MSEC_PER_SEC);
325         unsigned long then;
326         struct timeval tv;
327
328         LASSERT(nob > 0);
329         LASSERT(jiffies_left > 0);
330
331         for (;;) {
332                 struct kvec  iov = {
333                         .iov_base = buffer,
334                         .iov_len  = nob
335                 };
336                 struct msghdr msg = {
337                         .msg_flags = 0
338                 };
339
340                 /* Set receive timeout to remaining time */
341                 jiffies_to_timeval(jiffies_left, &tv);
342                 rc = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
343                                        (char *)&tv, sizeof(tv));
344                 if (rc) {
345                         CERROR("Can't set socket recv timeout %ld.%06d: %d\n",
346                                (long)tv.tv_sec, (int)tv.tv_usec, rc);
347                         return rc;
348                 }
349
350                 then = jiffies;
351                 rc = kernel_recvmsg(sock, &msg, &iov, 1, nob, 0);
352                 jiffies_left -= jiffies - then;
353
354                 if (rc < 0)
355                         return rc;
356
357                 if (!rc)
358                         return -ECONNRESET;
359
360                 buffer = ((char *)buffer) + rc;
361                 nob -= rc;
362
363                 if (!nob)
364                         return 0;
365
366                 if (jiffies_left <= 0)
367                         return -ETIMEDOUT;
368         }
369 }
370 EXPORT_SYMBOL(lnet_sock_read);
371
372 static int
373 lnet_sock_create(struct socket **sockp, int *fatal, __u32 local_ip,
374                  int local_port)
375 {
376         struct sockaddr_in locaddr;
377         struct socket *sock;
378         int rc;
379         int option;
380
381         /* All errors are fatal except bind failure if the port is in use */
382         *fatal = 1;
383
384         rc = sock_create(PF_INET, SOCK_STREAM, 0, &sock);
385         *sockp = sock;
386         if (rc) {
387                 CERROR("Can't create socket: %d\n", rc);
388                 return rc;
389         }
390
391         option = 1;
392         rc = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
393                                (char *)&option, sizeof(option));
394         if (rc) {
395                 CERROR("Can't set SO_REUSEADDR for socket: %d\n", rc);
396                 goto failed;
397         }
398
399         if (local_ip || local_port) {
400                 memset(&locaddr, 0, sizeof(locaddr));
401                 locaddr.sin_family = AF_INET;
402                 locaddr.sin_port = htons(local_port);
403                 locaddr.sin_addr.s_addr = !local_ip ?
404                                           INADDR_ANY : htonl(local_ip);
405
406                 rc = kernel_bind(sock, (struct sockaddr *)&locaddr,
407                                  sizeof(locaddr));
408                 if (rc == -EADDRINUSE) {
409                         CDEBUG(D_NET, "Port %d already in use\n", local_port);
410                         *fatal = 0;
411                         goto failed;
412                 }
413                 if (rc) {
414                         CERROR("Error trying to bind to port %d: %d\n",
415                                local_port, rc);
416                         goto failed;
417                 }
418         }
419         return 0;
420
421 failed:
422         sock_release(sock);
423         return rc;
424 }
425
426 int
427 lnet_sock_setbuf(struct socket *sock, int txbufsize, int rxbufsize)
428 {
429         int option;
430         int rc;
431
432         if (txbufsize) {
433                 option = txbufsize;
434                 rc = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
435                                        (char *)&option, sizeof(option));
436                 if (rc) {
437                         CERROR("Can't set send buffer %d: %d\n",
438                                option, rc);
439                         return rc;
440                 }
441         }
442
443         if (rxbufsize) {
444                 option = rxbufsize;
445                 rc = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
446                                        (char *)&option, sizeof(option));
447                 if (rc) {
448                         CERROR("Can't set receive buffer %d: %d\n",
449                                option, rc);
450                         return rc;
451                 }
452         }
453         return 0;
454 }
455 EXPORT_SYMBOL(lnet_sock_setbuf);
456
457 int
458 lnet_sock_getaddr(struct socket *sock, bool remote, __u32 *ip, int *port)
459 {
460         struct sockaddr_in sin;
461         int len = sizeof(sin);
462         int rc;
463
464         if (remote)
465                 rc = kernel_getpeername(sock, (struct sockaddr *)&sin, &len);
466         else
467                 rc = kernel_getsockname(sock, (struct sockaddr *)&sin, &len);
468         if (rc) {
469                 CERROR("Error %d getting sock %s IP/port\n",
470                        rc, remote ? "peer" : "local");
471                 return rc;
472         }
473
474         if (ip)
475                 *ip = ntohl(sin.sin_addr.s_addr);
476
477         if (port)
478                 *port = ntohs(sin.sin_port);
479
480         return 0;
481 }
482 EXPORT_SYMBOL(lnet_sock_getaddr);
483
484 int
485 lnet_sock_getbuf(struct socket *sock, int *txbufsize, int *rxbufsize)
486 {
487         if (txbufsize)
488                 *txbufsize = sock->sk->sk_sndbuf;
489
490         if (rxbufsize)
491                 *rxbufsize = sock->sk->sk_rcvbuf;
492
493         return 0;
494 }
495 EXPORT_SYMBOL(lnet_sock_getbuf);
496
497 int
498 lnet_sock_listen(struct socket **sockp, __u32 local_ip, int local_port,
499                  int backlog)
500 {
501         int fatal;
502         int rc;
503
504         rc = lnet_sock_create(sockp, &fatal, local_ip, local_port);
505         if (rc) {
506                 if (!fatal)
507                         CERROR("Can't create socket: port %d already in use\n",
508                                local_port);
509                 return rc;
510         }
511
512         rc = kernel_listen(*sockp, backlog);
513         if (!rc)
514                 return 0;
515
516         CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
517         sock_release(*sockp);
518         return rc;
519 }
520
521 int
522 lnet_sock_accept(struct socket **newsockp, struct socket *sock)
523 {
524         wait_queue_t wait;
525         struct socket *newsock;
526         int rc;
527
528         /*
529          * XXX this should add a ref to sock->ops->owner, if
530          * TCP could be a module
531          */
532         rc = sock_create_lite(PF_PACKET, sock->type, IPPROTO_TCP, &newsock);
533         if (rc) {
534                 CERROR("Can't allocate socket\n");
535                 return rc;
536         }
537
538         newsock->ops = sock->ops;
539
540         rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
541         if (rc == -EAGAIN) {
542                 /* Nothing ready, so wait for activity */
543                 init_waitqueue_entry(&wait, current);
544                 add_wait_queue(sk_sleep(sock->sk), &wait);
545                 set_current_state(TASK_INTERRUPTIBLE);
546                 schedule();
547                 remove_wait_queue(sk_sleep(sock->sk), &wait);
548                 rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
549         }
550
551         if (rc)
552                 goto failed;
553
554         *newsockp = newsock;
555         return 0;
556
557 failed:
558         sock_release(newsock);
559         return rc;
560 }
561
562 int
563 lnet_sock_connect(struct socket **sockp, int *fatal, __u32 local_ip,
564                   int local_port, __u32 peer_ip, int peer_port)
565 {
566         struct sockaddr_in srvaddr;
567         int rc;
568
569         rc = lnet_sock_create(sockp, fatal, local_ip, local_port);
570         if (rc)
571                 return rc;
572
573         memset(&srvaddr, 0, sizeof(srvaddr));
574         srvaddr.sin_family = AF_INET;
575         srvaddr.sin_port = htons(peer_port);
576         srvaddr.sin_addr.s_addr = htonl(peer_ip);
577
578         rc = kernel_connect(*sockp, (struct sockaddr *)&srvaddr,
579                             sizeof(srvaddr), 0);
580         if (!rc)
581                 return 0;
582
583         /*
584          * EADDRNOTAVAIL probably means we're already connected to the same
585          * peer/port on the same local port on a differently typed
586          * connection.  Let our caller retry with a different local
587          * port...
588          */
589         *fatal = !(rc == -EADDRNOTAVAIL);
590
591         CDEBUG_LIMIT(*fatal ? D_NETERROR : D_NET,
592                      "Error %d connecting %pI4h/%d -> %pI4h/%d\n", rc,
593                      &local_ip, local_port, &peer_ip, peer_port);
594
595         sock_release(*sockp);
596         return rc;
597 }