Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  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 <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/wait.h>
 27#include <sys/uio.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 "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
 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 UNIX_BIND_FAIL "unix_open : could not bind socket err=%i"
 49#define BPF_ATTACH_FAIL "Failed to attach filter size %d to %d, err %d\n"
 50
 51#define MAX_UN_LEN 107
 52
 53/* This is very ugly and brute force lookup, but it is done
 54 * only once at initialization so not worth doing hashes or
 55 * anything more intelligent
 56 */
 57
 58char *uml_vector_fetch_arg(struct arglist *ifspec, char *token)
 59{
 60	int i;
 61
 62	for (i = 0; i < ifspec->numargs; i++) {
 63		if (strcmp(ifspec->tokens[i], token) == 0)
 64			return ifspec->values[i];
 65	}
 66	return NULL;
 67
 68}
 69
 70struct arglist *uml_parse_vector_ifspec(char *arg)
 71{
 72	struct arglist *result;
 73	int pos, len;
 74	bool parsing_token = true, next_starts = true;
 75
 76	if (arg == NULL)
 77		return NULL;
 78	result = uml_kmalloc(sizeof(struct arglist), UM_GFP_KERNEL);
 79	if (result == NULL)
 80		return NULL;
 81	result->numargs = 0;
 82	len = strlen(arg);
 83	for (pos = 0; pos < len; pos++) {
 84		if (next_starts) {
 85			if (parsing_token) {
 86				result->tokens[result->numargs] = arg + pos;
 87			} else {
 88				result->values[result->numargs] = arg + pos;
 89				result->numargs++;
 90			}
 91			next_starts = false;
 92		}
 93		if (*(arg + pos) == '=') {
 94			if (parsing_token)
 95				parsing_token = false;
 96			else
 97				goto cleanup;
 98			next_starts = true;
 99			(*(arg + pos)) = '\0';
100		}
101		if (*(arg + pos) == ',') {
102			parsing_token = true;
103			next_starts = true;
104			(*(arg + pos)) = '\0';
105		}
106	}
107	return result;
108cleanup:
109	printk(UM_KERN_ERR "vector_setup - Couldn't parse '%s'\n", arg);
110	kfree(result);
111	return NULL;
112}
113
114/*
115 * Socket/FD configuration functions. These return an structure
116 * of rx and tx descriptors to cover cases where these are not
117 * the same (f.e. read via raw socket and write via tap).
118 */
119
120#define PATH_NET_TUN "/dev/net/tun"
121
122
123static int create_tap_fd(char *iface)
124{
125	struct ifreq ifr;
126	int fd = -1;
127	int err = -ENOMEM, offload;
128
129	fd = open(PATH_NET_TUN, O_RDWR);
130	if (fd < 0) {
131		printk(UM_KERN_ERR "uml_tap: failed to open tun device\n");
132		goto tap_fd_cleanup;
133	}
134	memset(&ifr, 0, sizeof(ifr));
135	ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
136	strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
137
138	err = ioctl(fd, TUNSETIFF, (void *) &ifr);
139	if (err != 0) {
140		printk(UM_KERN_ERR "uml_tap: failed to select tap interface\n");
141		goto tap_fd_cleanup;
142	}
143
144	offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
145	ioctl(fd, TUNSETOFFLOAD, offload);
146	return fd;
147tap_fd_cleanup:
148	if (fd >= 0)
149		os_close_file(fd);
150	return err;
151}
152
153static int create_raw_fd(char *iface, int flags, int proto)
154{
155	struct ifreq ifr;
156	int fd = -1;
157	struct sockaddr_ll sock;
158	int err = -ENOMEM;
159
160	fd = socket(AF_PACKET, SOCK_RAW, flags);
161	if (fd == -1) {
162		err = -errno;
163		goto raw_fd_cleanup;
164	}
165	memset(&ifr, 0, sizeof(ifr));
166	strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
167	if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) {
168		err = -errno;
169		goto raw_fd_cleanup;
170	}
171
172	sock.sll_family = AF_PACKET;
173	sock.sll_protocol = htons(proto);
174	sock.sll_ifindex = ifr.ifr_ifindex;
175
176	if (bind(fd,
177		(struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) {
178		err = -errno;
179		goto raw_fd_cleanup;
180	}
181	return fd;
182raw_fd_cleanup:
183	printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);
184	if (fd >= 0)
185		os_close_file(fd);
186	return err;
187}
188
189static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
190{
191	int fd = -1;
192	char *iface;
193	struct vector_fds *result = NULL;
194
195	iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
196	if (iface == NULL) {
197		printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n");
198		goto tap_cleanup;
199	}
200
201	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
202	if (result == NULL) {
203		printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n");
204		goto tap_cleanup;
205	}
206	result->rx_fd = -1;
207	result->tx_fd = -1;
208	result->remote_addr = NULL;
209	result->remote_addr_size = 0;
210
211	/* TAP */
212
213	fd = create_tap_fd(iface);
214	if (fd < 0) {
215		printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n");
216		goto tap_cleanup;
217	}
218	result->tx_fd = fd;
219	result->rx_fd = fd;
220	return result;
221tap_cleanup:
222	printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd);
223	if (result != NULL)
224		kfree(result);
225	return NULL;
226}
227
228static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
229{
230	char *iface;
231	struct vector_fds *result = NULL;
232
233	iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
234	if (iface == NULL) {
235		printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n");
236		goto hybrid_cleanup;
237	}
238
239	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
240	if (result == NULL) {
241		printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n");
242		goto hybrid_cleanup;
243	}
244	result->rx_fd = -1;
245	result->tx_fd = -1;
246	result->remote_addr = NULL;
247	result->remote_addr_size = 0;
248
249	/* TAP */
250
251	result->tx_fd = create_tap_fd(iface);
252	if (result->tx_fd < 0) {
253		printk(UM_KERN_ERR "uml_tap: failed to create tun interface: %i\n", result->tx_fd);
254		goto hybrid_cleanup;
255	}
256
257	/* RAW */
258
259	result->rx_fd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL);
260	if (result->rx_fd == -1) {
261		printk(UM_KERN_ERR
262			"uml_tap: failed to create paired raw socket: %i\n", result->rx_fd);
263		goto hybrid_cleanup;
264	}
265	return result;
266hybrid_cleanup:
267	printk(UM_KERN_ERR "user_init_hybrid: init failed");
268	if (result != NULL)
269		kfree(result);
270	return NULL;
271}
272
273static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id)
274{
275	int fd = -1;
276	int socktype;
277	char *src, *dst;
278	struct vector_fds *result = NULL;
279	struct sockaddr_un *local_addr = NULL, *remote_addr = NULL;
280
281	src = uml_vector_fetch_arg(ifspec, "src");
282	dst = uml_vector_fetch_arg(ifspec, "dst");
283	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
284	if (result == NULL) {
285		printk(UM_KERN_ERR "unix open:cannot allocate remote addr");
286		goto unix_cleanup;
287	}
288	remote_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
289	if (remote_addr == NULL) {
290		printk(UM_KERN_ERR "unix open:cannot allocate remote addr");
291		goto unix_cleanup;
292	}
293
294	switch (id) {
295	case ID_BESS:
296		socktype = SOCK_SEQPACKET;
297		if ((src != NULL) && (strlen(src) <= MAX_UN_LEN)) {
298			local_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
299			if (local_addr == NULL) {
300				printk(UM_KERN_ERR "bess open:cannot allocate local addr");
301				goto unix_cleanup;
302			}
303			local_addr->sun_family = AF_UNIX;
304			memcpy(local_addr->sun_path, src, strlen(src) + 1);
305		}
306		if ((dst == NULL) || (strlen(dst) > MAX_UN_LEN))
307			goto unix_cleanup;
308		remote_addr->sun_family = AF_UNIX;
309		memcpy(remote_addr->sun_path, dst, strlen(dst) + 1);
310		break;
311	default:
312		printk(KERN_ERR "Unsupported unix socket type\n");
313		return NULL;
314	}
315
316	fd = socket(AF_UNIX, socktype, 0);
317	if (fd == -1) {
318		printk(UM_KERN_ERR
319			"unix open: could not open socket, error = %d",
320			-errno
321		);
322		goto unix_cleanup;
323	}
324	if (local_addr != NULL) {
325		if (bind(fd, (struct sockaddr *) local_addr, sizeof(struct sockaddr_un))) {
326			printk(UM_KERN_ERR UNIX_BIND_FAIL, errno);
327			goto unix_cleanup;
328		}
329	}
330	switch (id) {
331	case ID_BESS:
332		if (connect(fd, remote_addr, sizeof(struct sockaddr_un)) < 0) {
333			printk(UM_KERN_ERR "bess open:cannot connect to %s %i", remote_addr->sun_path, -errno);
334			goto unix_cleanup;
335		}
336		break;
337	}
338	result->rx_fd = fd;
339	result->tx_fd = fd;
340	result->remote_addr_size = sizeof(struct sockaddr_un);
341	result->remote_addr = remote_addr;
342	return result;
343unix_cleanup:
344	if (fd >= 0)
345		os_close_file(fd);
346	if (remote_addr != NULL)
347		kfree(remote_addr);
348	if (result != NULL)
349		kfree(result);
350	return NULL;
351}
352
353static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
354{
355	int rxfd = -1, txfd = -1;
356	int err = -ENOMEM;
357	char *iface;
358	struct vector_fds *result = NULL;
359
360	iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
361	if (iface == NULL)
362		goto raw_cleanup;
363
364	rxfd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL);
365	if (rxfd == -1) {
366		err = -errno;
367		goto raw_cleanup;
368	}
369	txfd = create_raw_fd(iface, 0, ETH_P_IP); /* Turn off RX on this fd */
370	if (txfd == -1) {
371		err = -errno;
372		goto raw_cleanup;
373	}
374	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
375	if (result != NULL) {
376		result->rx_fd = rxfd;
377		result->tx_fd = txfd;
378		result->remote_addr = NULL;
379		result->remote_addr_size = 0;
380	}
381	return result;
382raw_cleanup:
383	printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);
384	if (result != NULL)
385		kfree(result);
386	return NULL;
387}
388
389
390bool uml_raw_enable_qdisc_bypass(int fd)
391{
392	int optval = 1;
393
394	if (setsockopt(fd,
395		SOL_PACKET, PACKET_QDISC_BYPASS,
396		&optval, sizeof(optval)) != 0) {
397		return false;
398	}
399	return true;
400}
401
402bool uml_raw_enable_vnet_headers(int fd)
403{
404	int optval = 1;
405
406	if (setsockopt(fd,
407		SOL_PACKET, PACKET_VNET_HDR,
408		&optval, sizeof(optval)) != 0) {
409		printk(UM_KERN_INFO VNET_HDR_FAIL, fd);
410		return false;
411	}
412	return true;
413}
414bool uml_tap_enable_vnet_headers(int fd)
415{
416	unsigned int features;
417	int len = sizeof(struct virtio_net_hdr);
418
419	if (ioctl(fd, TUNGETFEATURES, &features) == -1) {
420		printk(UM_KERN_INFO TUN_GET_F_FAIL, strerror(errno));
421		return false;
422	}
423	if ((features & IFF_VNET_HDR) == 0) {
424		printk(UM_KERN_INFO "tapraw: No VNET HEADER support");
425		return false;
426	}
427	ioctl(fd, TUNSETVNETHDRSZ, &len);
428	return true;
429}
430
431static struct vector_fds *user_init_socket_fds(struct arglist *ifspec, int id)
432{
433	int err = -ENOMEM;
434	int fd = -1, gairet;
435	struct addrinfo srchints;
436	struct addrinfo dsthints;
437	bool v6, udp;
438	char *value;
439	char *src, *dst, *srcport, *dstport;
440	struct addrinfo *gairesult = NULL;
441	struct vector_fds *result = NULL;
442
443
444	value = uml_vector_fetch_arg(ifspec, "v6");
445	v6 = false;
446	udp = false;
447	if (value != NULL) {
448		if (strtol((const char *) value, NULL, 10) > 0)
449			v6 = true;
450	}
451
452	value = uml_vector_fetch_arg(ifspec, "udp");
453	if (value != NULL) {
454		if (strtol((const char *) value, NULL, 10) > 0)
455			udp = true;
456	}
457	src = uml_vector_fetch_arg(ifspec, "src");
458	dst = uml_vector_fetch_arg(ifspec, "dst");
459	srcport = uml_vector_fetch_arg(ifspec, "srcport");
460	dstport = uml_vector_fetch_arg(ifspec, "dstport");
461
462	memset(&dsthints, 0, sizeof(dsthints));
463
464	if (v6)
465		dsthints.ai_family = AF_INET6;
466	else
467		dsthints.ai_family = AF_INET;
468
469	switch (id) {
470	case ID_GRE:
471		dsthints.ai_socktype = SOCK_RAW;
472		dsthints.ai_protocol = IPPROTO_GRE;
473		break;
474	case ID_L2TPV3:
475		if (udp) {
476			dsthints.ai_socktype = SOCK_DGRAM;
477			dsthints.ai_protocol = 0;
478		} else {
479			dsthints.ai_socktype = SOCK_RAW;
480			dsthints.ai_protocol = IPPROTO_L2TP;
481		}
482		break;
483	default:
484		printk(KERN_ERR "Unsupported socket type\n");
485		return NULL;
486	}
487	memcpy(&srchints, &dsthints, sizeof(struct addrinfo));
488
489	gairet = getaddrinfo(src, srcport, &dsthints, &gairesult);
490	if ((gairet != 0) || (gairesult == NULL)) {
491		printk(UM_KERN_ERR
492			"socket_open : could not resolve src, error = %s",
493			gai_strerror(gairet)
494		);
495		return NULL;
496	}
497	fd = socket(gairesult->ai_family,
498		gairesult->ai_socktype, gairesult->ai_protocol);
499	if (fd == -1) {
500		printk(UM_KERN_ERR
501			"socket_open : could not open socket, error = %d",
502			-errno
503		);
504		goto cleanup;
505	}
506	if (bind(fd,
507		(struct sockaddr *) gairesult->ai_addr,
508		gairesult->ai_addrlen)) {
509		printk(UM_KERN_ERR L2TPV3_BIND_FAIL, errno);
510		goto cleanup;
511	}
512
513	if (gairesult != NULL)
514		freeaddrinfo(gairesult);
515
516	gairesult = NULL;
517
518	gairet = getaddrinfo(dst, dstport, &dsthints, &gairesult);
519	if ((gairet != 0) || (gairesult == NULL)) {
520		printk(UM_KERN_ERR
521			"socket_open : could not resolve dst, error = %s",
522			gai_strerror(gairet)
523		);
524		return NULL;
525	}
526
527	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
528	if (result != NULL) {
529		result->rx_fd = fd;
530		result->tx_fd = fd;
531		result->remote_addr = uml_kmalloc(
532			gairesult->ai_addrlen, UM_GFP_KERNEL);
533		if (result->remote_addr == NULL)
534			goto cleanup;
535		result->remote_addr_size = gairesult->ai_addrlen;
536		memcpy(
537			result->remote_addr,
538			gairesult->ai_addr,
539			gairesult->ai_addrlen
540		);
541	}
542	freeaddrinfo(gairesult);
543	return result;
544cleanup:
545	if (gairesult != NULL)
546		freeaddrinfo(gairesult);
547	printk(UM_KERN_ERR "user_init_socket: init failed, error %d", err);
548	if (fd >= 0)
549		os_close_file(fd);
550	if (result != NULL) {
551		kfree(result->remote_addr);
552		kfree(result);
553	}
554	return NULL;
555}
556
557struct vector_fds *uml_vector_user_open(
558	int unit,
559	struct arglist *parsed
560)
561{
562	char *transport;
563
564	if (parsed == NULL) {
565		printk(UM_KERN_ERR "no parsed config for unit %d\n", unit);
566		return NULL;
567	}
568	transport = uml_vector_fetch_arg(parsed, "transport");
569	if (transport == NULL) {
570		printk(UM_KERN_ERR "missing transport for unit %d\n", unit);
571		return NULL;
572	}
573	if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0)
574		return user_init_raw_fds(parsed);
575	if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0)
576		return user_init_hybrid_fds(parsed);
577	if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0)
578		return user_init_tap_fds(parsed);
579	if (strncmp(transport, TRANS_GRE, TRANS_GRE_LEN) == 0)
580		return user_init_socket_fds(parsed, ID_GRE);
581	if (strncmp(transport, TRANS_L2TPV3, TRANS_L2TPV3_LEN) == 0)
582		return user_init_socket_fds(parsed, ID_L2TPV3);
583	if (strncmp(transport, TRANS_BESS, TRANS_BESS_LEN) == 0)
584		return user_init_unix_fds(parsed, ID_BESS);
585	return NULL;
586}
587
588
589int uml_vector_sendmsg(int fd, void *hdr, int flags)
590{
591	int n;
592
593	CATCH_EINTR(n = sendmsg(fd, (struct msghdr *) hdr,  flags));
594	if ((n < 0) && (errno == EAGAIN))
595		return 0;
596	if (n >= 0)
597		return n;
598	else
599		return -errno;
600}
601
602int uml_vector_recvmsg(int fd, void *hdr, int flags)
603{
604	int n;
605	struct msghdr *msg = (struct msghdr *) hdr;
606
607	CATCH_EINTR(n = readv(fd, msg->msg_iov, msg->msg_iovlen));
608	if ((n < 0) && (errno == EAGAIN))
609		return 0;
610	if (n >= 0)
611		return n;
612	else
613		return -errno;
614}
615
616int uml_vector_writev(int fd, void *hdr, int iovcount)
617{
618	int n;
619
620	CATCH_EINTR(n = writev(fd, (struct iovec *) hdr,  iovcount));
621	if ((n < 0) && ((errno == EAGAIN) || (errno == ENOBUFS)))
622		return 0;
623	if (n >= 0)
624		return n;
625	else
626		return -errno;
627}
628
629int uml_vector_sendmmsg(
630	int fd,
631	void *msgvec,
632	unsigned int vlen,
633	unsigned int flags)
634{
635	int n;
636
637	CATCH_EINTR(n = sendmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags));
638	if ((n < 0) && ((errno == EAGAIN) || (errno == ENOBUFS)))
639		return 0;
640	if (n >= 0)
641		return n;
642	else
643		return -errno;
644}
645
646int uml_vector_recvmmsg(
647	int fd,
648	void *msgvec,
649	unsigned int vlen,
650	unsigned int flags)
651{
652	int n;
653
654	CATCH_EINTR(
655		n = recvmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags, 0));
656	if ((n < 0) && (errno == EAGAIN))
657		return 0;
658	if (n >= 0)
659		return n;
660	else
661		return -errno;
662}
663int uml_vector_attach_bpf(int fd, void *bpf, int bpf_len)
664{
665	int err = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, bpf, bpf_len);
666
667	if (err < 0)
668		printk(KERN_ERR BPF_ATTACH_FAIL, bpf_len, fd, -errno);
669	return err;
670}
671
672#define DEFAULT_BPF_LEN 6
673
674void *uml_vector_default_bpf(int fd, void *mac)
675{
676	struct sock_filter *bpf;
677	uint32_t *mac1 = (uint32_t *)(mac + 2);
678	uint16_t *mac2 = (uint16_t *) mac;
679	struct sock_fprog bpf_prog = {
680		.len = 6,
681		.filter = NULL,
682	};
683
684	bpf = uml_kmalloc(
685		sizeof(struct sock_filter) * DEFAULT_BPF_LEN, UM_GFP_KERNEL);
686	if (bpf != NULL) {
687		bpf_prog.filter = bpf;
688		/* ld	[8] */
689		bpf[0] = (struct sock_filter){ 0x20, 0, 0, 0x00000008 };
690		/* jeq	#0xMAC[2-6] jt 2 jf 5*/
691		bpf[1] = (struct sock_filter){ 0x15, 0, 3, ntohl(*mac1)};
692		/* ldh	[6] */
693		bpf[2] = (struct sock_filter){ 0x28, 0, 0, 0x00000006 };
694		/* jeq	#0xMAC[0-1] jt 4 jf 5 */
695		bpf[3] = (struct sock_filter){ 0x15, 0, 1, ntohs(*mac2)};
696		/* ret	#0 */
697		bpf[4] = (struct sock_filter){ 0x6, 0, 0, 0x00000000 };
698		/* ret	#0x40000 */
699		bpf[5] = (struct sock_filter){ 0x6, 0, 0, 0x00040000 };
700		if (uml_vector_attach_bpf(
701			fd, &bpf_prog, sizeof(struct sock_fprog)) < 0) {
702			kfree(bpf);
703			bpf = NULL;
704		}
705	}
706	return bpf;
707}
708