New upstream version 18.08
[deb_dpdk.git] / drivers / net / softnic / rte_eth_softnic_tap.c
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_LINUXAPP
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
25 softnic_tap_init(struct pmd_internals *p)
26 {
27         TAILQ_INIT(&p->tap_list);
28
29         return 0;
30 }
31
32 void
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 *
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_LINUXAPP
64
65 struct softnic_tap *
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 *
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         snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
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