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