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 "rte_eth_softnic_internals.h"
21
22 #define TAP_DEV "/dev/net/tun"
23
24 int
softnic_tap_init(struct pmd_internals * p)25 softnic_tap_init(struct pmd_internals *p)
26 {
27 TAILQ_INIT(&p->tap_list);
28
29 return 0;
30 }
31
32 void
softnic_tap_free(struct pmd_internals * p)33 softnic_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
47 struct softnic_tap *
softnic_tap_find(struct pmd_internals * p,const char * name)48 softnic_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
65 struct softnic_tap *
softnic_tap_create(struct pmd_internals * p __rte_unused,const char * name __rte_unused)66 softnic_tap_create(struct pmd_internals *p __rte_unused,
67 const char *name __rte_unused)
68 {
69 return NULL;
70 }
71
72 #else
73
74 struct softnic_tap *
softnic_tap_create(struct pmd_internals * p,const char * name)75 softnic_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 /* Check input params */
83 if (name == NULL ||
84 softnic_tap_find(p, name))
85 return NULL;
86
87 /* Resource create */
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; /* No packet information */
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 /* Node allocation */
103 tap = calloc(1, sizeof(struct softnic_tap));
104 if (tap == NULL) {
105 close(fd);
106 return NULL;
107 }
108 /* Node fill in */
109 strlcpy(tap->name, name, sizeof(tap->name));
110 tap->fd = fd;
111
112 /* Node add to list */
113 TAILQ_INSERT_TAIL(&p->tap_list, tap, node);
114
115 return tap;
116 }
117
118 #endif
119