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