1 /* 2 * Copyright (c) International Business Machines Corp., 2008 3 * Copyright (c) Linux Test Project, 2017 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 /* 20 * File: ioctl03.c 21 * 22 * Description: This program tests whether all the valid IFF flags are 23 * returned properly by implementation of TUNGETFEATURES ioctl 24 * on kernel 2.6.27 25 * 26 * Test Name: ioctl03 27 * 28 * Author: Rusty Russell <rusty (at) rustcorp.com.au> 29 * 30 * history: created - nov 28 2008 - rusty russell <rusty (at) rustcorp.com.au> 31 * ported to ltp 32 * - nov 28 2008 - subrata <subrata (at) linux.vnet.ibm.com> 33 */ 34 35 #include <sys/types.h> 36 #include <sys/ioctl.h> 37 #include <sys/stat.h> 38 #include <fcntl.h> 39 #include <errno.h> 40 #include <linux/if_tun.h> 41 #include "tst_test.h" 42 43 #ifndef TUNGETFEATURES 44 #define TUNGETFEATURES _IOR('T', 207, unsigned int) 45 #endif 46 47 #ifndef IFF_VNET_HDR 48 #define IFF_VNET_HDR 0x4000 49 #endif 50 51 #ifndef IFF_MULTI_QUEUE 52 #define IFF_MULTI_QUEUE 0x0100 53 #endif 54 55 #ifndef IFF_NAPI 56 #define IFF_NAPI 0x0010 57 #endif 58 59 #ifndef IFF_NAPI_FRAGS 60 #define IFF_NAPI_FRAGS 0x0020 61 #endif 62 63 static struct { 64 unsigned int flag; 65 const char *name; 66 } known_flags[] = { 67 {IFF_TUN, "TUN"}, 68 {IFF_TAP, "TAP"}, 69 {IFF_NO_PI, "NO_PI"}, 70 {IFF_ONE_QUEUE, "ONE_QUEUE"}, 71 {IFF_VNET_HDR, "VNET_HDR"}, 72 {IFF_MULTI_QUEUE, "MULTI_QUEUE"}, 73 {IFF_NAPI, "IFF_NAPI"}, 74 {IFF_NAPI_FRAGS, "IFF_NAPI_FRAGS"} 75 }; 76 77 static void verify_features(void) 78 { 79 unsigned int features, i; 80 81 int netfd = open("/dev/net/tun", O_RDWR); 82 if (netfd == -1) { 83 if (errno == ENODEV || errno == ENOENT) 84 tst_brk(TCONF, "TUN support is missing?"); 85 86 tst_brk(TBROK | TERRNO, "opening /dev/net/tun failed"); 87 } 88 89 SAFE_IOCTL(netfd, TUNGETFEATURES, &features); 90 91 tst_res(TINFO, "Available features are: %#x", features); 92 for (i = 0; i < ARRAY_SIZE(known_flags); i++) { 93 if (features & known_flags[i].flag) { 94 features &= ~known_flags[i].flag; 95 tst_res(TPASS, "%s %#x", known_flags[i].name, 96 known_flags[i].flag); 97 } 98 } 99 if (features) 100 tst_res(TFAIL, "(UNKNOWN %#x)", features); 101 102 SAFE_CLOSE(netfd); 103 } 104 105 static struct tst_test test = { 106 .test_all = verify_features, 107 .needs_root = 1, 108 }; 109