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