xref: /f-stack/dpdk/examples/ip_pipeline/tap.c (revision d30ea906)
1*d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*d30ea906Sjfb8856606  * Copyright(c) 2010-2018 Intel Corporation
3*d30ea906Sjfb8856606  */
4*d30ea906Sjfb8856606 
5*d30ea906Sjfb8856606 #include <netinet/in.h>
6*d30ea906Sjfb8856606 #ifdef RTE_EXEC_ENV_LINUXAPP
7*d30ea906Sjfb8856606 #include <linux/if.h>
8*d30ea906Sjfb8856606 #include <linux/if_tun.h>
9*d30ea906Sjfb8856606 #endif
10*d30ea906Sjfb8856606 #include <sys/ioctl.h>
11*d30ea906Sjfb8856606 
12*d30ea906Sjfb8856606 #include <fcntl.h>
13*d30ea906Sjfb8856606 #include <stdio.h>
14*d30ea906Sjfb8856606 #include <stdlib.h>
15*d30ea906Sjfb8856606 #include <string.h>
16*d30ea906Sjfb8856606 #include <unistd.h>
17*d30ea906Sjfb8856606 
18*d30ea906Sjfb8856606 #include <rte_string_fns.h>
19*d30ea906Sjfb8856606 
20*d30ea906Sjfb8856606 #include "tap.h"
21*d30ea906Sjfb8856606 
22*d30ea906Sjfb8856606 #define TAP_DEV                                            "/dev/net/tun"
23*d30ea906Sjfb8856606 
24*d30ea906Sjfb8856606 static struct tap_list tap_list;
25*d30ea906Sjfb8856606 
26*d30ea906Sjfb8856606 int
27*d30ea906Sjfb8856606 tap_init(void)
28*d30ea906Sjfb8856606 {
29*d30ea906Sjfb8856606 	TAILQ_INIT(&tap_list);
30*d30ea906Sjfb8856606 
31*d30ea906Sjfb8856606 	return 0;
32*d30ea906Sjfb8856606 }
33*d30ea906Sjfb8856606 
34*d30ea906Sjfb8856606 struct tap *
35*d30ea906Sjfb8856606 tap_find(const char *name)
36*d30ea906Sjfb8856606 {
37*d30ea906Sjfb8856606 	struct tap *tap;
38*d30ea906Sjfb8856606 
39*d30ea906Sjfb8856606 	if (name == NULL)
40*d30ea906Sjfb8856606 		return NULL;
41*d30ea906Sjfb8856606 
42*d30ea906Sjfb8856606 	TAILQ_FOREACH(tap, &tap_list, node)
43*d30ea906Sjfb8856606 		if (strcmp(tap->name, name) == 0)
44*d30ea906Sjfb8856606 			return tap;
45*d30ea906Sjfb8856606 
46*d30ea906Sjfb8856606 	return NULL;
47*d30ea906Sjfb8856606 }
48*d30ea906Sjfb8856606 
49*d30ea906Sjfb8856606 #ifndef RTE_EXEC_ENV_LINUXAPP
50*d30ea906Sjfb8856606 
51*d30ea906Sjfb8856606 struct tap *
52*d30ea906Sjfb8856606 tap_create(const char *name __rte_unused)
53*d30ea906Sjfb8856606 {
54*d30ea906Sjfb8856606 	return NULL;
55*d30ea906Sjfb8856606 }
56*d30ea906Sjfb8856606 
57*d30ea906Sjfb8856606 #else
58*d30ea906Sjfb8856606 
59*d30ea906Sjfb8856606 struct tap *
60*d30ea906Sjfb8856606 tap_create(const char *name)
61*d30ea906Sjfb8856606 {
62*d30ea906Sjfb8856606 	struct tap *tap;
63*d30ea906Sjfb8856606 	struct ifreq ifr;
64*d30ea906Sjfb8856606 	int fd, status;
65*d30ea906Sjfb8856606 
66*d30ea906Sjfb8856606 	/* Check input params */
67*d30ea906Sjfb8856606 	if ((name == NULL) ||
68*d30ea906Sjfb8856606 		tap_find(name))
69*d30ea906Sjfb8856606 		return NULL;
70*d30ea906Sjfb8856606 
71*d30ea906Sjfb8856606 	/* Resource create */
72*d30ea906Sjfb8856606 	fd = open(TAP_DEV, O_RDWR | O_NONBLOCK);
73*d30ea906Sjfb8856606 	if (fd < 0)
74*d30ea906Sjfb8856606 		return NULL;
75*d30ea906Sjfb8856606 
76*d30ea906Sjfb8856606 	memset(&ifr, 0, sizeof(ifr));
77*d30ea906Sjfb8856606 	ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */
78*d30ea906Sjfb8856606 	snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
79*d30ea906Sjfb8856606 
80*d30ea906Sjfb8856606 	status = ioctl(fd, TUNSETIFF, (void *) &ifr);
81*d30ea906Sjfb8856606 	if (status < 0) {
82*d30ea906Sjfb8856606 		close(fd);
83*d30ea906Sjfb8856606 		return NULL;
84*d30ea906Sjfb8856606 	}
85*d30ea906Sjfb8856606 
86*d30ea906Sjfb8856606 	/* Node allocation */
87*d30ea906Sjfb8856606 	tap = calloc(1, sizeof(struct tap));
88*d30ea906Sjfb8856606 	if (tap == NULL) {
89*d30ea906Sjfb8856606 		close(fd);
90*d30ea906Sjfb8856606 		return NULL;
91*d30ea906Sjfb8856606 	}
92*d30ea906Sjfb8856606 	/* Node fill in */
93*d30ea906Sjfb8856606 	strlcpy(tap->name, name, sizeof(tap->name));
94*d30ea906Sjfb8856606 	tap->fd = fd;
95*d30ea906Sjfb8856606 
96*d30ea906Sjfb8856606 	/* Node add to list */
97*d30ea906Sjfb8856606 	TAILQ_INSERT_TAIL(&tap_list, tap, node);
98*d30ea906Sjfb8856606 
99*d30ea906Sjfb8856606 	return tap;
100*d30ea906Sjfb8856606 }
101*d30ea906Sjfb8856606 
102*d30ea906Sjfb8856606 #endif
103