xref: /dpdk/examples/ip_pipeline/tap.c (revision f9acaf84e923066344bd3467e4703da66f1f23a8)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2018 Intel Corporation
3  */
4 
5 #include <netinet/in.h>
6 #ifdef RTE_EXEC_ENV_LINUX
7 #include <linux/if.h>
8 #include <linux/if_tun.h>
9 #endif
10 #include <sys/ioctl.h>
11 
12 #include <fcntl.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17 
18 #include <rte_string_fns.h>
19 
20 #include "tap.h"
21 
22 #define TAP_DEV                                            "/dev/net/tun"
23 
24 static struct tap_list tap_list;
25 
26 int
tap_init(void)27 tap_init(void)
28 {
29 	TAILQ_INIT(&tap_list);
30 
31 	return 0;
32 }
33 
34 struct tap *
tap_find(const char * name)35 tap_find(const char *name)
36 {
37 	struct tap *tap;
38 
39 	if (name == NULL)
40 		return NULL;
41 
42 	TAILQ_FOREACH(tap, &tap_list, node)
43 		if (strcmp(tap->name, name) == 0)
44 			return tap;
45 
46 	return NULL;
47 }
48 
49 #ifndef RTE_EXEC_ENV_LINUX
50 
51 struct tap *
tap_create(const char * name __rte_unused)52 tap_create(const char *name __rte_unused)
53 {
54 	return NULL;
55 }
56 
57 #else
58 
59 struct tap *
tap_create(const char * name)60 tap_create(const char *name)
61 {
62 	struct tap *tap;
63 	struct ifreq ifr;
64 	int fd, status;
65 
66 	/* Check input params */
67 	if ((name == NULL) ||
68 		tap_find(name))
69 		return NULL;
70 
71 	/* Resource create */
72 	fd = open(TAP_DEV, O_RDWR | O_NONBLOCK);
73 	if (fd < 0)
74 		return NULL;
75 
76 	memset(&ifr, 0, sizeof(ifr));
77 	ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */
78 	strlcpy(ifr.ifr_name, name, IFNAMSIZ);
79 
80 	status = ioctl(fd, TUNSETIFF, (void *) &ifr);
81 	if (status < 0) {
82 		close(fd);
83 		return NULL;
84 	}
85 
86 	/* Node allocation */
87 	tap = calloc(1, sizeof(struct tap));
88 	if (tap == NULL) {
89 		close(fd);
90 		return NULL;
91 	}
92 	/* Node fill in */
93 	strlcpy(tap->name, name, sizeof(tap->name));
94 	tap->fd = fd;
95 
96 	/* Node add to list */
97 	TAILQ_INSERT_TAIL(&tap_list, tap, node);
98 
99 	return tap;
100 }
101 
102 #endif
103