GNU Linux-libre 4.19.264-gnu1
[releases.git] / arch / um / drivers / vector_user.c
1 /*
2  * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3  * Licensed under the GPL
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/types.h>
20 #include <sys/socket.h>
21 #include <net/ethernet.h>
22 #include <netinet/ip.h>
23 #include <netinet/ether.h>
24 #include <linux/if_ether.h>
25 #include <linux/if_packet.h>
26 #include <sys/socket.h>
27 #include <sys/wait.h>
28 #include <linux/virtio_net.h>
29 #include <netdb.h>
30 #include <stdlib.h>
31 #include <os.h>
32 #include <um_malloc.h>
33 #include <sys/uio.h>
34 #include "vector_user.h"
35
36 #define ID_GRE 0
37 #define ID_L2TPV3 1
38 #define ID_MAX 1
39
40 #define TOKEN_IFNAME "ifname"
41
42 #define TRANS_RAW "raw"
43 #define TRANS_RAW_LEN strlen(TRANS_RAW)
44
45 #define VNET_HDR_FAIL "could not enable vnet headers on fd %d"
46 #define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s"
47 #define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i"
48 #define BPF_ATTACH_FAIL "Failed to attach filter size %d to %d, err %d\n"
49
50 /* This is very ugly and brute force lookup, but it is done
51  * only once at initialization so not worth doing hashes or
52  * anything more intelligent
53  */
54
55 char *uml_vector_fetch_arg(struct arglist *ifspec, char *token)
56 {
57         int i;
58
59         for (i = 0; i < ifspec->numargs; i++) {
60                 if (strcmp(ifspec->tokens[i], token) == 0)
61                         return ifspec->values[i];
62         }
63         return NULL;
64
65 }
66
67 struct arglist *uml_parse_vector_ifspec(char *arg)
68 {
69         struct arglist *result;
70         int pos, len;
71         bool parsing_token = true, next_starts = true;
72
73         if (arg == NULL)
74                 return NULL;
75         result = uml_kmalloc(sizeof(struct arglist), UM_GFP_KERNEL);
76         if (result == NULL)
77                 return NULL;
78         result->numargs = 0;
79         len = strlen(arg);
80         for (pos = 0; pos < len; pos++) {
81                 if (next_starts) {
82                         if (parsing_token) {
83                                 result->tokens[result->numargs] = arg + pos;
84                         } else {
85                                 result->values[result->numargs] = arg + pos;
86                                 result->numargs++;
87                         }
88                         next_starts = false;
89                 }
90                 if (*(arg + pos) == '=') {
91                         if (parsing_token)
92                                 parsing_token = false;
93                         else
94                                 goto cleanup;
95                         next_starts = true;
96                         (*(arg + pos)) = '\0';
97                 }
98                 if (*(arg + pos) == ',') {
99                         parsing_token = true;
100                         next_starts = true;
101                         (*(arg + pos)) = '\0';
102                 }
103         }
104         return result;
105 cleanup:
106         printk(UM_KERN_ERR "vector_setup - Couldn't parse '%s'\n", arg);
107         kfree(result);
108         return NULL;
109 }
110
111 /*
112  * Socket/FD configuration functions. These return an structure
113  * of rx and tx descriptors to cover cases where these are not
114  * the same (f.e. read via raw socket and write via tap).
115  */
116
117 #define PATH_NET_TUN "/dev/net/tun"
118
119 static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
120 {
121         struct ifreq ifr;
122         int fd = -1;
123         struct sockaddr_ll sock;
124         int err = -ENOMEM, offload;
125         char *iface;
126         struct vector_fds *result = NULL;
127
128         iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
129         if (iface == NULL) {
130                 printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n");
131                 goto tap_cleanup;
132         }
133
134         result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
135         if (result == NULL) {
136                 printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n");
137                 goto tap_cleanup;
138         }
139         result->rx_fd = -1;
140         result->tx_fd = -1;
141         result->remote_addr = NULL;
142         result->remote_addr_size = 0;
143
144         /* TAP */
145
146         fd = open(PATH_NET_TUN, O_RDWR);
147         if (fd < 0) {
148                 printk(UM_KERN_ERR "uml_tap: failed to open tun device\n");
149                 goto tap_cleanup;
150         }
151         result->tx_fd = fd;
152         memset(&ifr, 0, sizeof(ifr));
153         ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
154         strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
155
156         err = ioctl(fd, TUNSETIFF, (void *) &ifr);
157         if (err != 0) {
158                 printk(UM_KERN_ERR "uml_tap: failed to select tap interface\n");
159                 goto tap_cleanup;
160         }
161
162         offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
163         ioctl(fd, TUNSETOFFLOAD, offload);
164
165         /* RAW */
166
167         fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
168         if (fd == -1) {
169                 printk(UM_KERN_ERR
170                         "uml_tap: failed to create socket: %i\n", -errno);
171                 goto tap_cleanup;
172         }
173         result->rx_fd = fd;
174         memset(&ifr, 0, sizeof(ifr));
175         strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
176         if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) {
177                 printk(UM_KERN_ERR
178                         "uml_tap: failed to set interface: %i\n", -errno);
179                 goto tap_cleanup;
180         }
181
182         sock.sll_family = AF_PACKET;
183         sock.sll_protocol = htons(ETH_P_ALL);
184         sock.sll_ifindex = ifr.ifr_ifindex;
185
186         if (bind(fd,
187                 (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) {
188                 printk(UM_KERN_ERR
189                         "user_init_tap: failed to bind raw pair, err %d\n",
190                                 -errno);
191                 goto tap_cleanup;
192         }
193         return result;
194 tap_cleanup:
195         printk(UM_KERN_ERR "user_init_tap: init failed, error %d", err);
196         if (result != NULL) {
197                 if (result->rx_fd >= 0)
198                         os_close_file(result->rx_fd);
199                 if (result->tx_fd >= 0)
200                         os_close_file(result->tx_fd);
201                 kfree(result);
202         }
203         return NULL;
204 }
205
206
207 static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
208 {
209         struct ifreq ifr;
210         int rxfd = -1, txfd = -1;
211         struct sockaddr_ll sock;
212         int err = -ENOMEM;
213         char *iface;
214         struct vector_fds *result = NULL;
215
216         iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
217         if (iface == NULL)
218                 goto cleanup;
219
220         rxfd = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL);
221         if (rxfd == -1) {
222                 err = -errno;
223                 goto cleanup;
224         }
225         txfd = socket(AF_PACKET, SOCK_RAW, 0); /* Turn off RX on this fd */
226         if (txfd == -1) {
227                 err = -errno;
228                 goto cleanup;
229         }
230         memset(&ifr, 0, sizeof(ifr));
231         strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
232         if (ioctl(rxfd, SIOCGIFINDEX, (void *) &ifr) < 0) {
233                 err = -errno;
234                 goto cleanup;
235         }
236
237         sock.sll_family = AF_PACKET;
238         sock.sll_protocol = htons(ETH_P_ALL);
239         sock.sll_ifindex = ifr.ifr_ifindex;
240
241         if (bind(rxfd,
242                 (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) {
243                 err = -errno;
244                 goto cleanup;
245         }
246
247         sock.sll_family = AF_PACKET;
248         sock.sll_protocol = htons(ETH_P_IP);
249         sock.sll_ifindex = ifr.ifr_ifindex;
250
251         if (bind(txfd,
252                 (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) {
253                 err = -errno;
254                 goto cleanup;
255         }
256
257         result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
258         if (result != NULL) {
259                 result->rx_fd = rxfd;
260                 result->tx_fd = txfd;
261                 result->remote_addr = NULL;
262                 result->remote_addr_size = 0;
263         }
264         return result;
265 cleanup:
266         printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);
267         if (rxfd >= 0)
268                 os_close_file(rxfd);
269         if (txfd >= 0)
270                 os_close_file(txfd);
271         if (result != NULL)
272                 kfree(result);
273         return NULL;
274 }
275
276
277 bool uml_raw_enable_qdisc_bypass(int fd)
278 {
279         int optval = 1;
280
281         if (setsockopt(fd,
282                 SOL_PACKET, PACKET_QDISC_BYPASS,
283                 &optval, sizeof(optval)) != 0) {
284                 return false;
285         }
286         return true;
287 }
288
289 bool uml_raw_enable_vnet_headers(int fd)
290 {
291         int optval = 1;
292
293         if (setsockopt(fd,
294                 SOL_PACKET, PACKET_VNET_HDR,
295                 &optval, sizeof(optval)) != 0) {
296                 printk(UM_KERN_INFO VNET_HDR_FAIL, fd);
297                 return false;
298         }
299         return true;
300 }
301 bool uml_tap_enable_vnet_headers(int fd)
302 {
303         unsigned int features;
304         int len = sizeof(struct virtio_net_hdr);
305
306         if (ioctl(fd, TUNGETFEATURES, &features) == -1) {
307                 printk(UM_KERN_INFO TUN_GET_F_FAIL, strerror(errno));
308                 return false;
309         }
310         if ((features & IFF_VNET_HDR) == 0) {
311                 printk(UM_KERN_INFO "tapraw: No VNET HEADER support");
312                 return false;
313         }
314         ioctl(fd, TUNSETVNETHDRSZ, &len);
315         return true;
316 }
317
318 static struct vector_fds *user_init_socket_fds(struct arglist *ifspec, int id)
319 {
320         int err = -ENOMEM;
321         int fd = -1, gairet;
322         struct addrinfo srchints;
323         struct addrinfo dsthints;
324         bool v6, udp;
325         char *value;
326         char *src, *dst, *srcport, *dstport;
327         struct addrinfo *gairesult = NULL;
328         struct vector_fds *result = NULL;
329
330
331         value = uml_vector_fetch_arg(ifspec, "v6");
332         v6 = false;
333         udp = false;
334         if (value != NULL) {
335                 if (strtol((const char *) value, NULL, 10) > 0)
336                         v6 = true;
337         }
338
339         value = uml_vector_fetch_arg(ifspec, "udp");
340         if (value != NULL) {
341                 if (strtol((const char *) value, NULL, 10) > 0)
342                         udp = true;
343         }
344         src = uml_vector_fetch_arg(ifspec, "src");
345         dst = uml_vector_fetch_arg(ifspec, "dst");
346         srcport = uml_vector_fetch_arg(ifspec, "srcport");
347         dstport = uml_vector_fetch_arg(ifspec, "dstport");
348
349         memset(&dsthints, 0, sizeof(dsthints));
350
351         if (v6)
352                 dsthints.ai_family = AF_INET6;
353         else
354                 dsthints.ai_family = AF_INET;
355
356         switch (id) {
357         case ID_GRE:
358                 dsthints.ai_socktype = SOCK_RAW;
359                 dsthints.ai_protocol = IPPROTO_GRE;
360                 break;
361         case ID_L2TPV3:
362                 if (udp) {
363                         dsthints.ai_socktype = SOCK_DGRAM;
364                         dsthints.ai_protocol = 0;
365                 } else {
366                         dsthints.ai_socktype = SOCK_RAW;
367                         dsthints.ai_protocol = IPPROTO_L2TP;
368                 }
369                 break;
370         default:
371                 printk(KERN_ERR "Unsupported socket type\n");
372                 return NULL;
373         }
374         memcpy(&srchints, &dsthints, sizeof(struct addrinfo));
375
376         gairet = getaddrinfo(src, srcport, &dsthints, &gairesult);
377         if ((gairet != 0) || (gairesult == NULL)) {
378                 printk(UM_KERN_ERR
379                         "socket_open : could not resolve src, error = %s",
380                         gai_strerror(gairet)
381                 );
382                 return NULL;
383         }
384         fd = socket(gairesult->ai_family,
385                 gairesult->ai_socktype, gairesult->ai_protocol);
386         if (fd == -1) {
387                 printk(UM_KERN_ERR
388                         "socket_open : could not open socket, error = %d",
389                         -errno
390                 );
391                 goto cleanup;
392         }
393         if (bind(fd,
394                 (struct sockaddr *) gairesult->ai_addr,
395                 gairesult->ai_addrlen)) {
396                 printk(UM_KERN_ERR L2TPV3_BIND_FAIL, errno);
397                 goto cleanup;
398         }
399
400         if (gairesult != NULL)
401                 freeaddrinfo(gairesult);
402
403         gairesult = NULL;
404
405         gairet = getaddrinfo(dst, dstport, &dsthints, &gairesult);
406         if ((gairet != 0) || (gairesult == NULL)) {
407                 printk(UM_KERN_ERR
408                         "socket_open : could not resolve dst, error = %s",
409                         gai_strerror(gairet)
410                 );
411                 return NULL;
412         }
413
414         result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
415         if (result != NULL) {
416                 result->rx_fd = fd;
417                 result->tx_fd = fd;
418                 result->remote_addr = uml_kmalloc(
419                         gairesult->ai_addrlen, UM_GFP_KERNEL);
420                 if (result->remote_addr == NULL)
421                         goto cleanup;
422                 result->remote_addr_size = gairesult->ai_addrlen;
423                 memcpy(
424                         result->remote_addr,
425                         gairesult->ai_addr,
426                         gairesult->ai_addrlen
427                 );
428         }
429         freeaddrinfo(gairesult);
430         return result;
431 cleanup:
432         if (gairesult != NULL)
433                 freeaddrinfo(gairesult);
434         printk(UM_KERN_ERR "user_init_socket: init failed, error %d", err);
435         if (fd >= 0)
436                 os_close_file(fd);
437         if (result != NULL) {
438                 if (result->remote_addr != NULL)
439                         kfree(result->remote_addr);
440                 kfree(result);
441         }
442         return NULL;
443 }
444
445 struct vector_fds *uml_vector_user_open(
446         int unit,
447         struct arglist *parsed
448 )
449 {
450         char *transport;
451
452         if (parsed == NULL) {
453                 printk(UM_KERN_ERR "no parsed config for unit %d\n", unit);
454                 return NULL;
455         }
456         transport = uml_vector_fetch_arg(parsed, "transport");
457         if (transport == NULL) {
458                 printk(UM_KERN_ERR "missing transport for unit %d\n", unit);
459                 return NULL;
460         }
461         if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0)
462                 return user_init_raw_fds(parsed);
463         if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0)
464                 return user_init_tap_fds(parsed);
465         if (strncmp(transport, TRANS_GRE, TRANS_GRE_LEN) == 0)
466                 return user_init_socket_fds(parsed, ID_GRE);
467         if (strncmp(transport, TRANS_L2TPV3, TRANS_L2TPV3_LEN) == 0)
468                 return user_init_socket_fds(parsed, ID_L2TPV3);
469         return NULL;
470 }
471
472
473 int uml_vector_sendmsg(int fd, void *hdr, int flags)
474 {
475         int n;
476
477         CATCH_EINTR(n = sendmsg(fd, (struct msghdr *) hdr,  flags));
478         if ((n < 0) && (errno == EAGAIN))
479                 return 0;
480         if (n >= 0)
481                 return n;
482         else
483                 return -errno;
484 }
485
486 int uml_vector_recvmsg(int fd, void *hdr, int flags)
487 {
488         int n;
489
490         CATCH_EINTR(n = recvmsg(fd, (struct msghdr *) hdr,  flags));
491         if ((n < 0) && (errno == EAGAIN))
492                 return 0;
493         if (n >= 0)
494                 return n;
495         else
496                 return -errno;
497 }
498
499 int uml_vector_writev(int fd, void *hdr, int iovcount)
500 {
501         int n;
502
503         CATCH_EINTR(n = writev(fd, (struct iovec *) hdr,  iovcount));
504         if ((n < 0) && (errno == EAGAIN))
505                 return 0;
506         if (n >= 0)
507                 return n;
508         else
509                 return -errno;
510 }
511
512 int uml_vector_sendmmsg(
513         int fd,
514         void *msgvec,
515         unsigned int vlen,
516         unsigned int flags)
517 {
518         int n;
519
520         CATCH_EINTR(n = sendmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags));
521         if ((n < 0) && (errno == EAGAIN))
522                 return 0;
523         if (n >= 0)
524                 return n;
525         else
526                 return -errno;
527 }
528
529 int uml_vector_recvmmsg(
530         int fd,
531         void *msgvec,
532         unsigned int vlen,
533         unsigned int flags)
534 {
535         int n;
536
537         CATCH_EINTR(
538                 n = recvmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags, 0));
539         if ((n < 0) && (errno == EAGAIN))
540                 return 0;
541         if (n >= 0)
542                 return n;
543         else
544                 return -errno;
545 }
546 int uml_vector_attach_bpf(int fd, void *bpf, int bpf_len)
547 {
548         int err = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, bpf, bpf_len);
549
550         if (err < 0)
551                 printk(KERN_ERR BPF_ATTACH_FAIL, bpf_len, fd, -errno);
552         return err;
553 }
554
555 #define DEFAULT_BPF_LEN 6
556
557 void *uml_vector_default_bpf(int fd, void *mac)
558 {
559         struct sock_filter *bpf;
560         uint32_t *mac1 = (uint32_t *)(mac + 2);
561         uint16_t *mac2 = (uint16_t *) mac;
562         struct sock_fprog bpf_prog = {
563                 .len = 6,
564                 .filter = NULL,
565         };
566
567         bpf = uml_kmalloc(
568                 sizeof(struct sock_filter) * DEFAULT_BPF_LEN, UM_GFP_KERNEL);
569         if (bpf != NULL) {
570                 bpf_prog.filter = bpf;
571                 /* ld   [8] */
572                 bpf[0] = (struct sock_filter){ 0x20, 0, 0, 0x00000008 };
573                 /* jeq  #0xMAC[2-6] jt 2 jf 5*/
574                 bpf[1] = (struct sock_filter){ 0x15, 0, 3, ntohl(*mac1)};
575                 /* ldh  [6] */
576                 bpf[2] = (struct sock_filter){ 0x28, 0, 0, 0x00000006 };
577                 /* jeq  #0xMAC[0-1] jt 4 jf 5 */
578                 bpf[3] = (struct sock_filter){ 0x15, 0, 1, ntohs(*mac2)};
579                 /* ret  #0 */
580                 bpf[4] = (struct sock_filter){ 0x6, 0, 0, 0x00000000 };
581                 /* ret  #0x40000 */
582                 bpf[5] = (struct sock_filter){ 0x6, 0, 0, 0x00040000 };
583                 if (uml_vector_attach_bpf(
584                         fd, &bpf_prog, sizeof(struct sock_fprog)) < 0) {
585                         kfree(bpf);
586                         bpf = NULL;
587                 }
588         }
589         return bpf;
590 }
591