]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/lustre/lnet/lnet/lib-socket.c
53dd0bdcd07f40c1c170019616501ef1b031d5a4
[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         strcpy(ifr.ifr_name, name);
103         rc = lnet_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);
104         if (rc) {
105                 CERROR("Can't get flags for interface %s\n", name);
106                 return rc;
107         }
108
109         if (!(ifr.ifr_flags & IFF_UP)) {
110                 CDEBUG(D_NET, "Interface %s down\n", name);
111                 *up = 0;
112                 *ip = *mask = 0;
113                 return 0;
114         }
115         *up = 1;
116
117         strcpy(ifr.ifr_name, name);
118         ifr.ifr_addr.sa_family = AF_INET;
119         rc = lnet_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);
120         if (rc) {
121                 CERROR("Can't get IP address for interface %s\n", name);
122                 return rc;
123         }
124
125         val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
126         *ip = ntohl(val);
127
128         strcpy(ifr.ifr_name, name);
129         ifr.ifr_addr.sa_family = AF_INET;
130         rc = lnet_sock_ioctl(SIOCGIFNETMASK, (unsigned long)&ifr);
131         if (rc) {
132                 CERROR("Can't get netmask for interface %s\n", name);
133                 return rc;
134         }
135
136         val = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr;
137         *mask = ntohl(val);
138
139         return 0;
140 }
141 EXPORT_SYMBOL(lnet_ipif_query);
142
143 int
144 lnet_ipif_enumerate(char ***namesp)
145 {
146         /* Allocate and fill in 'names', returning # interfaces/error */
147         char **names;
148         int toobig;
149         int nalloc;
150         int nfound;
151         struct ifreq *ifr;
152         struct ifconf ifc;
153         int rc;
154         int nob;
155         int i;
156
157         nalloc = 16;    /* first guess at max interfaces */
158         toobig = 0;
159         for (;;) {
160                 if (nalloc * sizeof(*ifr) > PAGE_CACHE_SIZE) {
161                         toobig = 1;
162                         nalloc = PAGE_CACHE_SIZE / sizeof(*ifr);
163                         CWARN("Too many interfaces: only enumerating first %d\n",
164                               nalloc);
165                 }
166
167                 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
168                 if (!ifr) {
169                         CERROR("ENOMEM enumerating up to %d interfaces\n",
170                                nalloc);
171                         rc = -ENOMEM;
172                         goto out0;
173                 }
174
175                 ifc.ifc_buf = (char *)ifr;
176                 ifc.ifc_len = nalloc * sizeof(*ifr);
177
178                 rc = lnet_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
179                 if (rc < 0) {
180                         CERROR("Error %d enumerating interfaces\n", rc);
181                         goto out1;
182                 }
183
184                 LASSERT(!rc);
185
186                 nfound = ifc.ifc_len / sizeof(*ifr);
187                 LASSERT(nfound <= nalloc);
188
189                 if (nfound < nalloc || toobig)
190                         break;
191
192                 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
193                 nalloc *= 2;
194         }
195
196         if (!nfound)
197                 goto out1;
198
199         LIBCFS_ALLOC(names, nfound * sizeof(*names));
200         if (!names) {
201                 rc = -ENOMEM;
202                 goto out1;
203         }
204
205         for (i = 0; i < nfound; i++) {
206                 nob = strnlen(ifr[i].ifr_name, IFNAMSIZ);
207                 if (nob == IFNAMSIZ) {
208                         /* no space for terminating NULL */
209                         CERROR("interface name %.*s too long (%d max)\n",
210                                nob, ifr[i].ifr_name, IFNAMSIZ);
211                         rc = -ENAMETOOLONG;
212                         goto out2;
213                 }
214
215                 LIBCFS_ALLOC(names[i], IFNAMSIZ);
216                 if (!names[i]) {
217                         rc = -ENOMEM;
218                         goto out2;
219                 }
220
221                 memcpy(names[i], ifr[i].ifr_name, nob);
222                 names[i][nob] = 0;
223         }
224
225         *namesp = names;
226         rc = nfound;
227
228 out2:
229         if (rc < 0)
230                 lnet_ipif_free_enumeration(names, nfound);
231 out1:
232         LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
233 out0:
234         return rc;
235 }
236 EXPORT_SYMBOL(lnet_ipif_enumerate);
237
238 void
239 lnet_ipif_free_enumeration(char **names, int n)
240 {
241         int i;
242
243         LASSERT(n > 0);
244
245         for (i = 0; i < n && names[i]; i++)
246                 LIBCFS_FREE(names[i], IFNAMSIZ);
247
248         LIBCFS_FREE(names, n * sizeof(*names));
249 }
250 EXPORT_SYMBOL(lnet_ipif_free_enumeration);
251
252 int
253 lnet_sock_write(struct socket *sock, void *buffer, int nob, int timeout)
254 {
255         int rc;
256         long ticks = timeout * HZ;
257         unsigned long then;
258         struct timeval tv;
259
260         LASSERT(nob > 0);
261         /*
262          * Caller may pass a zero timeout if she thinks the socket buffer is
263          * empty enough to take the whole message immediately
264          */
265         for (;;) {
266                 struct kvec  iov = {
267                         .iov_base = buffer,
268                         .iov_len  = nob
269                 };
270                 struct msghdr msg = {
271                         .msg_flags      = !timeout ? MSG_DONTWAIT : 0
272                 };
273
274                 if (timeout) {
275                         /* Set send timeout to remaining time */
276                         tv = (struct timeval) {
277                                 .tv_sec = ticks / HZ,
278                                 .tv_usec = ((ticks % HZ) * 1000000) / HZ
279                         };
280                         rc = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
281                                                (char *)&tv, sizeof(tv));
282                         if (rc) {
283                                 CERROR("Can't set socket send timeout %ld.%06d: %d\n",
284                                        (long)tv.tv_sec, (int)tv.tv_usec, rc);
285                                 return rc;
286                         }
287                 }
288
289                 then = jiffies;
290                 rc = kernel_sendmsg(sock, &msg, &iov, 1, nob);
291                 ticks -= jiffies - then;
292
293                 if (rc == nob)
294                         return 0;
295
296                 if (rc < 0)
297                         return rc;
298
299                 if (!rc) {
300                         CERROR("Unexpected zero rc\n");
301                         return -ECONNABORTED;
302                 }
303
304                 if (ticks <= 0)
305                         return -EAGAIN;
306
307                 buffer = ((char *)buffer) + rc;
308                 nob -= rc;
309         }
310         return 0;
311 }
312 EXPORT_SYMBOL(lnet_sock_write);
313
314 int
315 lnet_sock_read(struct socket *sock, void *buffer, int nob, int timeout)
316 {
317         int rc;
318         long ticks = timeout * HZ;
319         unsigned long then;
320         struct timeval tv;
321
322         LASSERT(nob > 0);
323         LASSERT(ticks > 0);
324
325         for (;;) {
326                 struct kvec  iov = {
327                         .iov_base = buffer,
328                         .iov_len  = nob
329                 };
330                 struct msghdr msg = {
331                         .msg_flags = 0
332                 };
333
334                 /* Set receive timeout to remaining time */
335                 tv = (struct timeval) {
336                         .tv_sec = ticks / HZ,
337                         .tv_usec = ((ticks % HZ) * 1000000) / HZ
338                 };
339                 rc = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
340                                        (char *)&tv, sizeof(tv));
341                 if (rc) {
342                         CERROR("Can't set socket recv timeout %ld.%06d: %d\n",
343                                (long)tv.tv_sec, (int)tv.tv_usec, rc);
344                         return rc;
345                 }
346
347                 then = jiffies;
348                 rc = kernel_recvmsg(sock, &msg, &iov, 1, nob, 0);
349                 ticks -= jiffies - then;
350
351                 if (rc < 0)
352                         return rc;
353
354                 if (!rc)
355                         return -ECONNRESET;
356
357                 buffer = ((char *)buffer) + rc;
358                 nob -= rc;
359
360                 if (!nob)
361                         return 0;
362
363                 if (ticks <= 0)
364                         return -ETIMEDOUT;
365         }
366 }
367 EXPORT_SYMBOL(lnet_sock_read);
368
369 static int
370 lnet_sock_create(struct socket **sockp, int *fatal, __u32 local_ip,
371                  int local_port)
372 {
373         struct sockaddr_in locaddr;
374         struct socket *sock;
375         int rc;
376         int option;
377
378         /* All errors are fatal except bind failure if the port is in use */
379         *fatal = 1;
380
381         rc = sock_create(PF_INET, SOCK_STREAM, 0, &sock);
382         *sockp = sock;
383         if (rc) {
384                 CERROR("Can't create socket: %d\n", rc);
385                 return rc;
386         }
387
388         option = 1;
389         rc = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
390                                (char *)&option, sizeof(option));
391         if (rc) {
392                 CERROR("Can't set SO_REUSEADDR for socket: %d\n", rc);
393                 goto failed;
394         }
395
396         if (local_ip || local_port) {
397                 memset(&locaddr, 0, sizeof(locaddr));
398                 locaddr.sin_family = AF_INET;
399                 locaddr.sin_port = htons(local_port);
400                 locaddr.sin_addr.s_addr = !local_ip ?
401                                           INADDR_ANY : htonl(local_ip);
402
403                 rc = kernel_bind(sock, (struct sockaddr *)&locaddr,
404                                  sizeof(locaddr));
405                 if (rc == -EADDRINUSE) {
406                         CDEBUG(D_NET, "Port %d already in use\n", local_port);
407                         *fatal = 0;
408                         goto failed;
409                 }
410                 if (rc) {
411                         CERROR("Error trying to bind to port %d: %d\n",
412                                local_port, rc);
413                         goto failed;
414                 }
415         }
416         return 0;
417
418 failed:
419         sock_release(sock);
420         return rc;
421 }
422
423 int
424 lnet_sock_setbuf(struct socket *sock, int txbufsize, int rxbufsize)
425 {
426         int option;
427         int rc;
428
429         if (txbufsize) {
430                 option = txbufsize;
431                 rc = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
432                                        (char *)&option, sizeof(option));
433                 if (rc) {
434                         CERROR("Can't set send buffer %d: %d\n",
435                                option, rc);
436                         return rc;
437                 }
438         }
439
440         if (rxbufsize) {
441                 option = rxbufsize;
442                 rc = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
443                                        (char *)&option, sizeof(option));
444                 if (rc) {
445                         CERROR("Can't set receive buffer %d: %d\n",
446                                option, rc);
447                         return rc;
448                 }
449         }
450         return 0;
451 }
452 EXPORT_SYMBOL(lnet_sock_setbuf);
453
454 int
455 lnet_sock_getaddr(struct socket *sock, bool remote, __u32 *ip, int *port)
456 {
457         struct sockaddr_in sin;
458         int len = sizeof(sin);
459         int rc;
460
461         if (remote)
462                 rc = kernel_getpeername(sock, (struct sockaddr *)&sin, &len);
463         else
464                 rc = kernel_getsockname(sock, (struct sockaddr *)&sin, &len);
465         if (rc) {
466                 CERROR("Error %d getting sock %s IP/port\n",
467                        rc, remote ? "peer" : "local");
468                 return rc;
469         }
470
471         if (ip)
472                 *ip = ntohl(sin.sin_addr.s_addr);
473
474         if (port)
475                 *port = ntohs(sin.sin_port);
476
477         return 0;
478 }
479 EXPORT_SYMBOL(lnet_sock_getaddr);
480
481 int
482 lnet_sock_getbuf(struct socket *sock, int *txbufsize, int *rxbufsize)
483 {
484         if (txbufsize)
485                 *txbufsize = sock->sk->sk_sndbuf;
486
487         if (rxbufsize)
488                 *rxbufsize = sock->sk->sk_rcvbuf;
489
490         return 0;
491 }
492 EXPORT_SYMBOL(lnet_sock_getbuf);
493
494 int
495 lnet_sock_listen(struct socket **sockp, __u32 local_ip, int local_port,
496                  int backlog)
497 {
498         int fatal;
499         int rc;
500
501         rc = lnet_sock_create(sockp, &fatal, local_ip, local_port);
502         if (rc) {
503                 if (!fatal)
504                         CERROR("Can't create socket: port %d already in use\n",
505                                local_port);
506                 return rc;
507         }
508
509         rc = kernel_listen(*sockp, backlog);
510         if (!rc)
511                 return 0;
512
513         CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
514         sock_release(*sockp);
515         return rc;
516 }
517 EXPORT_SYMBOL(lnet_sock_listen);
518
519 int
520 lnet_sock_accept(struct socket **newsockp, struct socket *sock)
521 {
522         wait_queue_t wait;
523         struct socket *newsock;
524         int rc;
525
526         init_waitqueue_entry(&wait, current);
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                 set_current_state(TASK_INTERRUPTIBLE);
544                 add_wait_queue(sk_sleep(sock->sk), &wait);
545                 schedule();
546                 remove_wait_queue(sk_sleep(sock->sk), &wait);
547                 set_current_state(TASK_RUNNING);
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 EXPORT_SYMBOL(lnet_sock_accept);
562
563 int
564 lnet_sock_connect(struct socket **sockp, int *fatal, __u32 local_ip,
565                   int local_port, __u32 peer_ip, int peer_port)
566 {
567         struct sockaddr_in srvaddr;
568         int rc;
569
570         rc = lnet_sock_create(sockp, fatal, local_ip, local_port);
571         if (rc)
572                 return rc;
573
574         memset(&srvaddr, 0, sizeof(srvaddr));
575         srvaddr.sin_family = AF_INET;
576         srvaddr.sin_port = htons(peer_port);
577         srvaddr.sin_addr.s_addr = htonl(peer_ip);
578
579         rc = kernel_connect(*sockp, (struct sockaddr *)&srvaddr,
580                             sizeof(srvaddr), 0);
581         if (!rc)
582                 return 0;
583
584         /*
585          * EADDRNOTAVAIL probably means we're already connected to the same
586          * peer/port on the same local port on a differently typed
587          * connection.  Let our caller retry with a different local
588          * port...
589          */
590         *fatal = !(rc == -EADDRNOTAVAIL);
591
592         CDEBUG_LIMIT(*fatal ? D_NETERROR : D_NET,
593                      "Error %d connecting %pI4h/%d -> %pI4h/%d\n", rc,
594                      &local_ip, local_port, &peer_ip, peer_port);
595
596         sock_release(*sockp);
597         return rc;
598 }
599 EXPORT_SYMBOL(lnet_sock_connect);