New upstream version 18.08
[deb_dpdk.git] / examples / ip_pipeline / 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 "tap.h"
21
22 #define TAP_DEV                                            "/dev/net/tun"
23
24 static struct tap_list tap_list;
25
26 int
27 tap_init(void)
28 {
29         TAILQ_INIT(&tap_list);
30
31         return 0;
32 }
33
34 struct tap *
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_LINUXAPP
50
51 struct tap *
52 tap_create(const char *name __rte_unused)
53 {
54         return NULL;
55 }
56
57 #else
58
59 struct tap *
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         snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
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