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