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