xref: /openbmc/linux/arch/um/drivers/vector_user.c (revision d9fd5a71)
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 }
858