xref: /dpdk/examples/ip_pipeline/tap.c (revision 6491dbbecebb1e4f07fc970ef90b34119d8be2e3)
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 "tap.h"
19 
20 #define TAP_DEV                                            "/dev/net/tun"
21 
22 static struct tap_list tap_list;
23 
24 int
25 tap_init(void)
26 {
27 	TAILQ_INIT(&tap_list);
28 
29 	return 0;
30 }
31 
32 struct tap *
33 tap_find(const char *name)
34 {
35 	struct tap *tap;
36 
37 	if (name == NULL)
38 		return NULL;
39 
40 	TAILQ_FOREACH(tap, &tap_list, node)
41 		if (strcmp(tap->name, name) == 0)
42 			return tap;
43 
44 	return NULL;
45 }
46 
47 #ifndef RTE_EXEC_ENV_LINUXAPP
48 
49 struct tap *
50 tap_create(const char *name __rte_unused)
51 {
52 	return NULL;
53 }
54 
55 #else
56 
57 struct tap *
58 tap_create(const char *name)
59 {
60 	struct tap *tap;
61 	struct ifreq ifr;
62 	int fd, status;
63 
64 	/* Check input params */
65 	if ((name == NULL) ||
66 		tap_find(name))
67 		return NULL;
68 
69 	/* Resource create */
70 	fd = open(TAP_DEV, O_RDWR | O_NONBLOCK);
71 	if (fd < 0)
72 		return NULL;
73 
74 	memset(&ifr, 0, sizeof(ifr));
75 	ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */
76 	snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
77 
78 	status = ioctl(fd, TUNSETIFF, (void *) &ifr);
79 	if (status < 0)
80 		return NULL;
81 
82 	/* Node allocation */
83 	tap = calloc(1, sizeof(struct tap));
84 	if (tap == NULL)
85 		return NULL;
86 
87 	/* Node fill in */
88 	strncpy(tap->name, name, sizeof(tap->name));
89 	tap->fd = fd;
90 
91 	/* Node add to list */
92 	TAILQ_INSERT_TAIL(&tap_list, tap, node);
93 
94 	return tap;
95 }
96 
97 #endif
98