Home | History | Annotate | Download | only in ioctl
      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