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@rustcorp.com.au>
29 *
30 * history: created - nov 28 2008 - rusty russell <rusty@rustcorp.com.au>
31 * ported to ltp
32 * - nov 28 2008 - subrata <subrata@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
verify_features(void)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