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