1
2
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 "rte_eth_softnic_internals.h"
21
22#define TAP_DEV "/dev/net/tun"
23
24int
25softnic_tap_init(struct pmd_internals *p)
26{
27 TAILQ_INIT(&p->tap_list);
28
29 return 0;
30}
31
32void
33softnic_tap_free(struct pmd_internals *p)
34{
35 for ( ; ; ) {
36 struct softnic_tap *tap;
37
38 tap = TAILQ_FIRST(&p->tap_list);
39 if (tap == NULL)
40 break;
41
42 TAILQ_REMOVE(&p->tap_list, tap, node);
43 free(tap);
44 }
45}
46
47struct softnic_tap *
48softnic_tap_find(struct pmd_internals *p,
49 const char *name)
50{
51 struct softnic_tap *tap;
52
53 if (name == NULL)
54 return NULL;
55
56 TAILQ_FOREACH(tap, &p->tap_list, node)
57 if (strcmp(tap->name, name) == 0)
58 return tap;
59
60 return NULL;
61}
62
63#ifndef RTE_EXEC_ENV_LINUX
64
65struct softnic_tap *
66softnic_tap_create(struct pmd_internals *p __rte_unused,
67 const char *name __rte_unused)
68{
69 return NULL;
70}
71
72#else
73
74struct softnic_tap *
75softnic_tap_create(struct pmd_internals *p,
76 const char *name)
77{
78 struct softnic_tap *tap;
79 struct ifreq ifr;
80 int fd, status;
81
82
83 if (name == NULL ||
84 softnic_tap_find(p, name))
85 return NULL;
86
87
88 fd = open(TAP_DEV, O_RDWR | O_NONBLOCK);
89 if (fd < 0)
90 return NULL;
91
92 memset(&ifr, 0, sizeof(ifr));
93 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
94 strlcpy(ifr.ifr_name, name, IFNAMSIZ);
95
96 status = ioctl(fd, TUNSETIFF, (void *)&ifr);
97 if (status < 0) {
98 close(fd);
99 return NULL;
100 }
101
102
103 tap = calloc(1, sizeof(struct softnic_tap));
104 if (tap == NULL) {
105 close(fd);
106 return NULL;
107 }
108
109 strlcpy(tap->name, name, sizeof(tap->name));
110 tap->fd = fd;
111
112
113 TAILQ_INSERT_TAIL(&p->tap_list, tap, node);
114
115 return tap;
116}
117
118#endif
119