Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[linux-2.6-microblaze.git] / arch / um / drivers / vector_user.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4  */
5
6 #include <stdio.h>
7 #include <unistd.h>
8 #include <stdarg.h>
9 #include <errno.h>
10 #include <stddef.h>
11 #include <string.h>
12 #include <sys/ioctl.h>
13 #include <net/if.h>
14 #include <linux/if_tun.h>
15 #include <arpa/inet.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 #include <sys/socket.h>
20 #include <sys/un.h>
21 #include <netinet/ip.h>
22 #include <linux/if_ether.h>
23 #include <linux/if_packet.h>
24 #include <sys/wait.h>
25 #include <sys/uio.h>
26 #include <linux/virtio_net.h>
27 #include <netdb.h>
28 #include <stdlib.h>
29 #include <os.h>
30 #include <limits.h>
31 #include <um_malloc.h>
32 #include "vector_user.h"
33
34 #define ID_GRE 0
35 #define ID_L2TPV3 1
36 #define ID_BESS 2
37 #define ID_MAX 2
38
39 #define TOKEN_IFNAME "ifname"
40 #define TOKEN_SCRIPT "ifup"
41
42 #define TRANS_RAW "raw"
43 #define TRANS_RAW_LEN strlen(TRANS_RAW)
44
45 #define TRANS_FD "fd"
46 #define TRANS_FD_LEN strlen(TRANS_FD)
47
48 #define VNET_HDR_FAIL "could not enable vnet headers on fd %d"
49 #define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s"
50 #define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i"
51 #define UNIX_BIND_FAIL "unix_open : could not bind socket err=%i"
52 #define BPF_ATTACH_FAIL "Failed to attach filter size %d prog %px to %d, err %d\n"
53 #define BPF_DETACH_FAIL "Failed to detach filter size %d prog %px to %d, err %d\n"
54
55 #define MAX_UN_LEN 107
56
57 static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
58 static const char *template = "tapXXXXXX";
59
60 /* This is very ugly and brute force lookup, but it is done
61  * only once at initialization so not worth doing hashes or
62  * anything more intelligent
63  */
64
65 char *uml_vector_fetch_arg(struct arglist *ifspec, char *token)
66 {
67         int i;
68
69         for (i = 0; i < ifspec->numargs; i++) {
70                 if (strcmp(ifspec->tokens[i], token) == 0)
71                         return ifspec->values[i];
72         }
73         return NULL;
74
75 }
76
77 struct arglist *uml_parse_vector_ifspec(char *arg)
78 {
79         struct arglist *result;
80         int pos, len;
81         bool parsing_token = true, next_starts = true;
82
83         if (arg == NULL)
84                 return NULL;
85         result = uml_kmalloc(sizeof(struct arglist), UM_GFP_KERNEL);
86         if (result == NULL)
87                 return NULL;
88         result->numargs = 0;
89         len = strlen(arg);
90         for (pos = 0; pos < len; pos++) {
91                 if (next_starts) {
92                         if (parsing_token) {
93                                 result->tokens[result->numargs] = arg + pos;
94                         } else {
95                                 result->values[result->numargs] = arg + pos;
96                                 result->numargs++;
97                         }
98                         next_starts = false;
99                 }
100                 if (*(arg + pos) == '=') {
101                         if (parsing_token)
102                                 parsing_token = false;
103                         else
104                                 goto cleanup;
105                         next_starts = true;
106                         (*(arg + pos)) = '\0';
107                 }
108                 if (*(arg + pos) == ',') {
109                         parsing_token = true;
110                         next_starts = true;
111                         (*(arg + pos)) = '\0';
112                 }
113         }
114         return result;
115 cleanup:
116         printk(UM_KERN_ERR "vector_setup - Couldn't parse '%s'\n", arg);
117         kfree(result);
118         return NULL;
119 }
120
121 /*
122  * Socket/FD configuration functions. These return an structure
123  * of rx and tx descriptors to cover cases where these are not
124  * the same (f.e. read via raw socket and write via tap).
125  */
126
127 #define PATH_NET_TUN "/dev/net/tun"
128
129
130 static int create_tap_fd(char *iface)
131 {
132         struct ifreq ifr;
133         int fd = -1;
134         int err = -ENOMEM, offload;
135
136         fd = open(PATH_NET_TUN, O_RDWR);
137         if (fd < 0) {
138                 printk(UM_KERN_ERR "uml_tap: failed to open tun device\n");
139                 goto tap_fd_cleanup;
140         }
141         memset(&ifr, 0, sizeof(ifr));
142         ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
143         strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
144
145         err = ioctl(fd, TUNSETIFF, (void *) &ifr);
146         if (err != 0) {
147                 printk(UM_KERN_ERR "uml_tap: failed to select tap interface\n");
148                 goto tap_fd_cleanup;
149         }
150
151         offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
152         ioctl(fd, TUNSETOFFLOAD, offload);
153         return fd;
154 tap_fd_cleanup:
155         if (fd >= 0)
156                 os_close_file(fd);
157         return err;
158 }
159
160 static int create_raw_fd(char *iface, int flags, int proto)
161 {
162         struct ifreq ifr;
163         int fd = -1;
164         struct sockaddr_ll sock;
165         int err = -ENOMEM;
166
167         fd = socket(AF_PACKET, SOCK_RAW, flags);
168         if (fd == -1) {
169                 err = -errno;
170                 goto raw_fd_cleanup;
171         }
172         memset(&ifr, 0, sizeof(ifr));
173         strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
174         if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) {
175                 err = -errno;
176                 goto raw_fd_cleanup;
177         }
178
179         sock.sll_family = AF_PACKET;
180         sock.sll_protocol = htons(proto);
181         sock.sll_ifindex = ifr.ifr_ifindex;
182
183         if (bind(fd,
184                 (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) {
185                 err = -errno;
186                 goto raw_fd_cleanup;
187         }
188         return fd;
189 raw_fd_cleanup:
190         printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);
191         if (fd >= 0)
192                 os_close_file(fd);
193         return err;
194 }
195
196
197 static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
198 {
199         int fd = -1, i;
200         char *iface;
201         struct vector_fds *result = NULL;
202         bool dynamic = false;
203         char dynamic_ifname[IFNAMSIZ];
204         char *argv[] = {NULL, NULL, NULL, NULL};
205
206         iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
207         if (iface == NULL) {
208                 dynamic = true;
209                 iface = dynamic_ifname;
210                 srand(getpid());
211         }
212
213         result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
214         if (result == NULL) {
215                 printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n");
216                 goto tap_cleanup;
217         }
218         result->rx_fd = -1;
219         result->tx_fd = -1;
220         result->remote_addr = NULL;
221         result->remote_addr_size = 0;
222
223         /* TAP */
224         do {
225                 if (dynamic) {
226                         strcpy(iface, template);
227                         for (i = 0; i < strlen(iface); i++) {
228                                 if (iface[i] == 'X') {
229                                         iface[i] = padchar[rand() % strlen(padchar)];
230                                 }
231                         }
232                 }
233                 fd = create_tap_fd(iface);
234                 if ((fd < 0) && (!dynamic)) {
235                         printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n");
236                         goto tap_cleanup;
237                 }
238                 result->tx_fd = fd;
239                 result->rx_fd = fd;
240         } while (fd < 0);
241
242         argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
243         if (argv[0]) {
244                 argv[1] = iface;
245                 run_helper(NULL, NULL, argv);
246         }
247
248         return result;
249 tap_cleanup:
250         printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd);
251         kfree(result);
252         return NULL;
253 }
254
255 static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
256 {
257         char *iface;
258         struct vector_fds *result = NULL;
259         char *argv[] = {NULL, NULL, NULL, NULL};
260
261         iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
262         if (iface == NULL) {
263                 printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n");
264                 goto hybrid_cleanup;
265         }
266
267         result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
268         if (result == NULL) {
269                 printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n");
270                 goto hybrid_cleanup;
271         }
272         result->rx_fd = -1;
273         result->tx_fd = -1;
274         result->remote_addr = NULL;
275         result->remote_addr_size = 0;
276
277         /* TAP */
278
279         result->tx_fd = create_tap_fd(iface);
280         if (result->tx_fd < 0) {
281                 printk(UM_KERN_ERR "uml_tap: failed to create tun interface: %i\n", result->tx_fd);
282                 goto hybrid_cleanup;
283         }
284
285         /* RAW */
286
287         result->rx_fd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL);
288         if (result->rx_fd == -1) {
289                 printk(UM_KERN_ERR
290                         "uml_tap: failed to create paired raw socket: %i\n", result->rx_fd);
291                 goto hybrid_cleanup;
292         }
293
294         argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
295         if (argv[0]) {
296                 argv[1] = iface;
297                 run_helper(NULL, NULL, argv);
298         }
299         return result;
300 hybrid_cleanup:
301         printk(UM_KERN_ERR "user_init_hybrid: init failed");
302         kfree(result);
303         return NULL;
304 }
305
306 static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id)
307 {
308         int fd = -1;
309         int socktype;
310         char *src, *dst;
311         struct vector_fds *result = NULL;
312         struct sockaddr_un *local_addr = NULL, *remote_addr = NULL;
313
314         src = uml_vector_fetch_arg(ifspec, "src");
315         dst = uml_vector_fetch_arg(ifspec, "dst");
316         result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
317         if (result == NULL) {
318                 printk(UM_KERN_ERR "unix open:cannot allocate remote addr");
319                 goto unix_cleanup;
320         }
321         remote_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
322         if (remote_addr == NULL) {
323                 printk(UM_KERN_ERR "unix open:cannot allocate remote addr");
324                 goto unix_cleanup;
325         }
326
327         switch (id) {
328         case ID_BESS:
329                 socktype = SOCK_SEQPACKET;
330                 if ((src != NULL) && (strlen(src) <= MAX_UN_LEN)) {
331                         local_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
332                         if (local_addr == NULL) {
333                                 printk(UM_KERN_ERR "bess open:cannot allocate local addr");
334                                 goto unix_cleanup;
335                         }
336                         local_addr->sun_family = AF_UNIX;
337                         memcpy(local_addr->sun_path, src, strlen(src) + 1);
338                 }
339                 if ((dst == NULL) || (strlen(dst) > MAX_UN_LEN))
340                         goto unix_cleanup;
341                 remote_addr->sun_family = AF_UNIX;
342                 memcpy(remote_addr->sun_path, dst, strlen(dst) + 1);
343                 break;
344         default:
345                 printk(KERN_ERR "Unsupported unix socket type\n");
346                 return NULL;
347         }
348
349         fd = socket(AF_UNIX, socktype, 0);
350         if (fd == -1) {
351                 printk(UM_KERN_ERR
352                         "unix open: could not open socket, error = %d",
353                         -errno
354                 );
355                 goto unix_cleanup;
356         }
357         if (local_addr != NULL) {
358                 if (bind(fd, (struct sockaddr *) local_addr, sizeof(struct sockaddr_un))) {
359                         printk(UM_KERN_ERR UNIX_BIND_FAIL, errno);
360                         goto unix_cleanup;
361                 }
362         }
363         switch (id) {
364         case ID_BESS:
365                 if (connect(fd, (const struct sockaddr *) remote_addr, sizeof(struct sockaddr_un)) < 0) {
366                         printk(UM_KERN_ERR "bess open:cannot connect to %s %i", remote_addr->sun_path, -errno);
367                         goto unix_cleanup;
368                 }
369                 break;
370         }
371         result->rx_fd = fd;
372         result->tx_fd = fd;
373         result->remote_addr_size = sizeof(struct sockaddr_un);
374         result->remote_addr = remote_addr;
375         return result;
376 unix_cleanup:
377         if (fd >= 0)
378                 os_close_file(fd);
379         kfree(remote_addr);
380         kfree(result);
381         return NULL;
382 }
383
384 static int strtofd(const char *nptr)
385 {
386         long fd;
387         char *endptr;
388
389         if (nptr == NULL)
390                 return -1;
391
392         errno = 0;
393         fd = strtol(nptr, &endptr, 10);
394         if (nptr == endptr ||
395                 errno != 0 ||
396                 *endptr != '\0' ||
397                 fd < 0 ||
398                 fd > INT_MAX) {
399                 return -1;
400         }
401         return fd;
402 }
403
404 static struct vector_fds *user_init_fd_fds(struct arglist *ifspec)
405 {
406         int fd = -1;
407         char *fdarg = NULL;
408         struct vector_fds *result = NULL;
409
410         fdarg = uml_vector_fetch_arg(ifspec, "fd");
411         fd = strtofd(fdarg);
412         if (fd == -1) {
413                 printk(UM_KERN_ERR "fd open: bad or missing fd argument");
414                 goto fd_cleanup;
415         }
416
417         result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
418         if (result == NULL) {
419                 printk(UM_KERN_ERR "fd open: allocation failed");
420                 goto fd_cleanup;
421         }
422
423         result->rx_fd = fd;
424         result->tx_fd = fd;
425         result->remote_addr_size = 0;
426         result->remote_addr = NULL;
427         return result;
428
429 fd_cleanup:
430         if (fd >= 0)
431                 os_close_file(fd);
432         kfree(result);
433         return NULL;
434 }
435
436 static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
437 {
438         int rxfd = -1, txfd = -1;
439         int err = -ENOMEM;
440         char *iface;
441         struct vector_fds *result = NULL;
442         char *argv[] = {NULL, NULL, NULL, NULL};
443
444         iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
445         if (iface == NULL)
446                 goto raw_cleanup;
447
448         rxfd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL);
449         if (rxfd == -1) {
450                 err = -errno;
451                 goto raw_cleanup;
452         }
453         txfd = create_raw_fd(iface, 0, ETH_P_IP); /* Turn off RX on this fd */
454         if (txfd == -1) {
455                 err = -errno;
456                 goto raw_cleanup;
457         }
458         result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
459         if (result != NULL) {
460                 result->rx_fd = rxfd;
461                 result->tx_fd = txfd;
462                 result->remote_addr = NULL;
463                 result->remote_addr_size = 0;
464         }
465         argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
466         if (argv[0]) {
467                 argv[1] = iface;
468                 run_helper(NULL, NULL, argv);
469         }
470         return result;
471 raw_cleanup:
472         printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);
473         kfree(result);
474         return NULL;
475 }
476
477
478 bool uml_raw_enable_qdisc_bypass(int fd)
479 {
480         int optval = 1;
481
482         if (setsockopt(fd,
483                 SOL_PACKET, PACKET_QDISC_BYPASS,
484                 &optval, sizeof(optval)) != 0) {
485                 return false;
486         }
487         return true;
488 }
489
490 bool uml_raw_enable_vnet_headers(int fd)
491 {
492         int optval = 1;
493
494         if (setsockopt(fd,
495                 SOL_PACKET, PACKET_VNET_HDR,
496                 &optval, sizeof(optval)) != 0) {
497                 printk(UM_KERN_INFO VNET_HDR_FAIL, fd);
498                 return false;
499         }
500         return true;
501 }
502 bool uml_tap_enable_vnet_headers(int fd)
503 {
504         unsigned int features;
505         int len = sizeof(struct virtio_net_hdr);
506
507         if (ioctl(fd, TUNGETFEATURES, &features) == -1) {
508                 printk(UM_KERN_INFO TUN_GET_F_FAIL, strerror(errno));
509                 return false;
510         }
511         if ((features & IFF_VNET_HDR) == 0) {
512                 printk(UM_KERN_INFO "tapraw: No VNET HEADER support");
513                 return false;
514         }
515         ioctl(fd, TUNSETVNETHDRSZ, &len);
516         return true;
517 }
518
519 static struct vector_fds *user_init_socket_fds(struct arglist *ifspec, int id)
520 {
521         int err = -ENOMEM;
522         int fd = -1, gairet;
523         struct addrinfo srchints;
524         struct addrinfo dsthints;
525         bool v6, udp;
526         char *value;
527         char *src, *dst, *srcport, *dstport;
528         struct addrinfo *gairesult = NULL;
529         struct vector_fds *result = NULL;
530
531
532         value = uml_vector_fetch_arg(ifspec, "v6");
533         v6 = false;
534         udp = false;
535         if (value != NULL) {
536                 if (strtol((const char *) value, NULL, 10) > 0)
537                         v6 = true;
538         }
539
540         value = uml_vector_fetch_arg(ifspec, "udp");
541         if (value != NULL) {
542                 if (strtol((const char *) value, NULL, 10) > 0)
543                         udp = true;
544         }
545         src = uml_vector_fetch_arg(ifspec, "src");
546         dst = uml_vector_fetch_arg(ifspec, "dst");
547         srcport = uml_vector_fetch_arg(ifspec, "srcport");
548         dstport = uml_vector_fetch_arg(ifspec, "dstport");
549
550         memset(&dsthints, 0, sizeof(dsthints));
551
552         if (v6)
553                 dsthints.ai_family = AF_INET6;
554         else
555                 dsthints.ai_family = AF_INET;
556
557         switch (id) {
558         case ID_GRE:
559                 dsthints.ai_socktype = SOCK_RAW;
560                 dsthints.ai_protocol = IPPROTO_GRE;
561                 break;
562         case ID_L2TPV3:
563                 if (udp) {
564                         dsthints.ai_socktype = SOCK_DGRAM;
565                         dsthints.ai_protocol = 0;
566                 } else {
567                         dsthints.ai_socktype = SOCK_RAW;
568                         dsthints.ai_protocol = IPPROTO_L2TP;
569                 }
570                 break;
571         default:
572                 printk(KERN_ERR "Unsupported socket type\n");
573                 return NULL;
574         }
575         memcpy(&srchints, &dsthints, sizeof(struct addrinfo));
576
577         gairet = getaddrinfo(src, srcport, &dsthints, &gairesult);
578         if ((gairet != 0) || (gairesult == NULL)) {
579                 printk(UM_KERN_ERR
580                         "socket_open : could not resolve src, error = %s",
581                         gai_strerror(gairet)
582                 );
583                 return NULL;
584         }
585         fd = socket(gairesult->ai_family,
586                 gairesult->ai_socktype, gairesult->ai_protocol);
587         if (fd == -1) {
588                 printk(UM_KERN_ERR
589                         "socket_open : could not open socket, error = %d",
590                         -errno
591                 );
592                 goto cleanup;
593         }
594         if (bind(fd,
595                 (struct sockaddr *) gairesult->ai_addr,
596                 gairesult->ai_addrlen)) {
597                 printk(UM_KERN_ERR L2TPV3_BIND_FAIL, errno);
598                 goto cleanup;
599         }
600
601         if (gairesult != NULL)
602                 freeaddrinfo(gairesult);
603
604         gairesult = NULL;
605
606         gairet = getaddrinfo(dst, dstport, &dsthints, &gairesult);
607         if ((gairet != 0) || (gairesult == NULL)) {
608                 printk(UM_KERN_ERR
609                         "socket_open : could not resolve dst, error = %s",
610                         gai_strerror(gairet)
611                 );
612                 return NULL;
613         }
614
615         result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
616         if (result != NULL) {
617                 result->rx_fd = fd;
618                 result->tx_fd = fd;
619                 result->remote_addr = uml_kmalloc(
620                         gairesult->ai_addrlen, UM_GFP_KERNEL);
621                 if (result->remote_addr == NULL)
622                         goto cleanup;
623                 result->remote_addr_size = gairesult->ai_addrlen;
624                 memcpy(
625                         result->remote_addr,
626                         gairesult->ai_addr,
627                         gairesult->ai_addrlen
628                 );
629         }
630         freeaddrinfo(gairesult);
631         return result;
632 cleanup:
633         if (gairesult != NULL)
634                 freeaddrinfo(gairesult);
635         printk(UM_KERN_ERR "user_init_socket: init failed, error %d", err);
636         if (fd >= 0)
637                 os_close_file(fd);
638         if (result != NULL) {
639                 kfree(result->remote_addr);
640                 kfree(result);
641         }
642         return NULL;
643 }
644
645 struct vector_fds *uml_vector_user_open(
646         int unit,
647         struct arglist *parsed
648 )
649 {
650         char *transport;
651
652         if (parsed == NULL) {
653                 printk(UM_KERN_ERR "no parsed config for unit %d\n", unit);
654                 return NULL;
655         }
656         transport = uml_vector_fetch_arg(parsed, "transport");
657         if (transport == NULL) {
658                 printk(UM_KERN_ERR "missing transport for unit %d\n", unit);
659                 return NULL;
660         }
661         if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0)
662                 return user_init_raw_fds(parsed);
663         if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0)
664                 return user_init_hybrid_fds(parsed);
665         if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0)
666                 return user_init_tap_fds(parsed);
667         if (strncmp(transport, TRANS_GRE, TRANS_GRE_LEN) == 0)
668                 return user_init_socket_fds(parsed, ID_GRE);
669         if (strncmp(transport, TRANS_L2TPV3, TRANS_L2TPV3_LEN) == 0)
670                 return user_init_socket_fds(parsed, ID_L2TPV3);
671         if (strncmp(transport, TRANS_BESS, TRANS_BESS_LEN) == 0)
672                 return user_init_unix_fds(parsed, ID_BESS);
673         if (strncmp(transport, TRANS_FD, TRANS_FD_LEN) == 0)
674                 return user_init_fd_fds(parsed);
675         return NULL;
676 }
677
678
679 int uml_vector_sendmsg(int fd, void *hdr, int flags)
680 {
681         int n;
682
683         CATCH_EINTR(n = sendmsg(fd, (struct msghdr *) hdr,  flags));
684         if ((n < 0) && (errno == EAGAIN))
685                 return 0;
686         if (n >= 0)
687                 return n;
688         else
689                 return -errno;
690 }
691
692 int uml_vector_recvmsg(int fd, void *hdr, int flags)
693 {
694         int n;
695         struct msghdr *msg = (struct msghdr *) hdr;
696
697         CATCH_EINTR(n = readv(fd, msg->msg_iov, msg->msg_iovlen));
698         if ((n < 0) && (errno == EAGAIN))
699                 return 0;
700         if (n >= 0)
701                 return n;
702         else
703                 return -errno;
704 }
705
706 int uml_vector_writev(int fd, void *hdr, int iovcount)
707 {
708         int n;
709
710         CATCH_EINTR(n = writev(fd, (struct iovec *) hdr,  iovcount));
711         if ((n < 0) && ((errno == EAGAIN) || (errno == ENOBUFS)))
712                 return 0;
713         if (n >= 0)
714                 return n;
715         else
716                 return -errno;
717 }
718
719 int uml_vector_sendmmsg(
720         int fd,
721         void *msgvec,
722         unsigned int vlen,
723         unsigned int flags)
724 {
725         int n;
726
727         CATCH_EINTR(n = sendmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags));
728         if ((n < 0) && ((errno == EAGAIN) || (errno == ENOBUFS)))
729                 return 0;
730         if (n >= 0)
731                 return n;
732         else
733                 return -errno;
734 }
735
736 int uml_vector_recvmmsg(
737         int fd,
738         void *msgvec,
739         unsigned int vlen,
740         unsigned int flags)
741 {
742         int n;
743
744         CATCH_EINTR(
745                 n = recvmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags, 0));
746         if ((n < 0) && (errno == EAGAIN))
747                 return 0;
748         if (n >= 0)
749                 return n;
750         else
751                 return -errno;
752 }
753 int uml_vector_attach_bpf(int fd, void *bpf)
754 {
755         struct sock_fprog *prog = bpf;
756
757         int err = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, bpf, sizeof(struct sock_fprog));
758
759         if (err < 0)
760                 printk(KERN_ERR BPF_ATTACH_FAIL, prog->len, prog->filter, fd, -errno);
761         return err;
762 }
763
764 int uml_vector_detach_bpf(int fd, void *bpf)
765 {
766         struct sock_fprog *prog = bpf;
767
768         int err = setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, bpf, sizeof(struct sock_fprog));
769         if (err < 0)
770                 printk(KERN_ERR BPF_DETACH_FAIL, prog->len, prog->filter, fd, -errno);
771         return err;
772 }
773 void *uml_vector_default_bpf(void *mac)
774 {
775         struct sock_filter *bpf;
776         uint32_t *mac1 = (uint32_t *)(mac + 2);
777         uint16_t *mac2 = (uint16_t *) mac;
778         struct sock_fprog *bpf_prog;
779
780         bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL);
781         if (bpf_prog) {
782                 bpf_prog->len = DEFAULT_BPF_LEN;
783                 bpf_prog->filter = NULL;
784         } else {
785                 return NULL;
786         }
787         bpf = uml_kmalloc(
788                 sizeof(struct sock_filter) * DEFAULT_BPF_LEN, UM_GFP_KERNEL);
789         if (bpf) {
790                 bpf_prog->filter = bpf;
791                 /* ld   [8] */
792                 bpf[0] = (struct sock_filter){ 0x20, 0, 0, 0x00000008 };
793                 /* jeq  #0xMAC[2-6] jt 2 jf 5*/
794                 bpf[1] = (struct sock_filter){ 0x15, 0, 3, ntohl(*mac1)};
795                 /* ldh  [6] */
796                 bpf[2] = (struct sock_filter){ 0x28, 0, 0, 0x00000006 };
797                 /* jeq  #0xMAC[0-1] jt 4 jf 5 */
798                 bpf[3] = (struct sock_filter){ 0x15, 0, 1, ntohs(*mac2)};
799                 /* ret  #0 */
800                 bpf[4] = (struct sock_filter){ 0x6, 0, 0, 0x00000000 };
801                 /* ret  #0x40000 */
802                 bpf[5] = (struct sock_filter){ 0x6, 0, 0, 0x00040000 };
803         } else {
804                 kfree(bpf_prog);
805                 bpf_prog = NULL;
806         }
807         return bpf_prog;
808 }
809
810 /* Note - this function requires a valid mac being passed as an arg */
811
812 void *uml_vector_user_bpf(char *filename)
813 {
814         struct sock_filter *bpf;
815         struct sock_fprog *bpf_prog;
816         struct stat statbuf;
817         int res, ffd = -1;
818
819         if (filename == NULL)
820                 return NULL;
821
822         if (stat(filename, &statbuf) < 0) {
823                 printk(KERN_ERR "Error %d reading bpf file", -errno);
824                 return false;
825         }
826         bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL);
827         if (bpf_prog == NULL) {
828                 printk(KERN_ERR "Failed to allocate bpf prog buffer");
829                 return NULL;
830         }
831         bpf_prog->len = statbuf.st_size / sizeof(struct sock_filter);
832         bpf_prog->filter = NULL;
833         ffd = os_open_file(filename, of_read(OPENFLAGS()), 0);
834         if (ffd < 0) {
835                 printk(KERN_ERR "Error %d opening bpf file", -errno);
836                 goto bpf_failed;
837         }
838         bpf = uml_kmalloc(statbuf.st_size, UM_GFP_KERNEL);
839         if (bpf == NULL) {
840                 printk(KERN_ERR "Failed to allocate bpf buffer");
841                 goto bpf_failed;
842         }
843         bpf_prog->filter = bpf;
844         res = os_read_file(ffd, bpf, statbuf.st_size);
845         if (res < statbuf.st_size) {
846                 printk(KERN_ERR "Failed to read bpf program %s, error %d", filename, res);
847                 kfree(bpf);
848                 goto bpf_failed;
849         }
850         os_close_file(ffd);
851         return bpf_prog;
852 bpf_failed:
853         if (ffd > 0)
854                 os_close_file(ffd);
855         kfree(bpf_prog);
856         return NULL;
857 }