1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2008 4f08c3bdfSopenharmony_ci * Copyright (c) Linux Test Project, 2017-2019 5f08c3bdfSopenharmony_ci * Author: Rusty Russell <rusty@rustcorp.com.au> 6f08c3bdfSopenharmony_ci * Ported to LTP: subrata <subrata@linux.vnet.ibm.com> 7f08c3bdfSopenharmony_ci */ 8f08c3bdfSopenharmony_ci 9f08c3bdfSopenharmony_ci/* 10f08c3bdfSopenharmony_ci * This program tests whether all the valid IFF flags are 11f08c3bdfSopenharmony_ci * returned properly by implementation of TUNGETFEATURES ioctl 12f08c3bdfSopenharmony_ci * on kernel 2.6.27 13f08c3bdfSopenharmony_ci */ 14f08c3bdfSopenharmony_ci 15f08c3bdfSopenharmony_ci#include <sys/types.h> 16f08c3bdfSopenharmony_ci#include <sys/ioctl.h> 17f08c3bdfSopenharmony_ci#include <sys/stat.h> 18f08c3bdfSopenharmony_ci#include <fcntl.h> 19f08c3bdfSopenharmony_ci#include <errno.h> 20f08c3bdfSopenharmony_ci#include <linux/if_tun.h> 21f08c3bdfSopenharmony_ci#include "tst_test.h" 22f08c3bdfSopenharmony_ci 23f08c3bdfSopenharmony_ci#ifndef TUNGETFEATURES 24f08c3bdfSopenharmony_ci#define TUNGETFEATURES _IOR('T', 207, unsigned int) 25f08c3bdfSopenharmony_ci#endif 26f08c3bdfSopenharmony_ci 27f08c3bdfSopenharmony_ci#ifndef IFF_VNET_HDR 28f08c3bdfSopenharmony_ci#define IFF_VNET_HDR 0x4000 29f08c3bdfSopenharmony_ci#endif 30f08c3bdfSopenharmony_ci 31f08c3bdfSopenharmony_ci#ifndef IFF_MULTI_QUEUE 32f08c3bdfSopenharmony_ci#define IFF_MULTI_QUEUE 0x0100 33f08c3bdfSopenharmony_ci#endif 34f08c3bdfSopenharmony_ci 35f08c3bdfSopenharmony_ci#ifndef IFF_NAPI 36f08c3bdfSopenharmony_ci#define IFF_NAPI 0x0010 37f08c3bdfSopenharmony_ci#endif 38f08c3bdfSopenharmony_ci 39f08c3bdfSopenharmony_ci#ifndef IFF_NAPI_FRAGS 40f08c3bdfSopenharmony_ci#define IFF_NAPI_FRAGS 0x0020 41f08c3bdfSopenharmony_ci#endif 42f08c3bdfSopenharmony_ci 43f08c3bdfSopenharmony_ci#ifndef IFF_NO_CARRIER 44f08c3bdfSopenharmony_ci#define IFF_NO_CARRIER 0x0040 45f08c3bdfSopenharmony_ci#endif 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_cistatic struct { 48f08c3bdfSopenharmony_ci unsigned int flag; 49f08c3bdfSopenharmony_ci const char *name; 50f08c3bdfSopenharmony_ci} known_flags[] = { 51f08c3bdfSopenharmony_ci {IFF_TUN, "TUN"}, 52f08c3bdfSopenharmony_ci {IFF_TAP, "TAP"}, 53f08c3bdfSopenharmony_ci {IFF_NO_PI, "NO_PI"}, 54f08c3bdfSopenharmony_ci {IFF_ONE_QUEUE, "ONE_QUEUE"}, 55f08c3bdfSopenharmony_ci {IFF_VNET_HDR, "VNET_HDR"}, 56f08c3bdfSopenharmony_ci {IFF_MULTI_QUEUE, "MULTI_QUEUE"}, 57f08c3bdfSopenharmony_ci {IFF_NAPI, "IFF_NAPI"}, 58f08c3bdfSopenharmony_ci {IFF_NAPI_FRAGS, "IFF_NAPI_FRAGS"}, 59f08c3bdfSopenharmony_ci {IFF_NO_CARRIER, "IFF_NO_CARRIER"} 60f08c3bdfSopenharmony_ci}; 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_cistatic void verify_features(void) 63f08c3bdfSopenharmony_ci{ 64f08c3bdfSopenharmony_ci unsigned int features, i; 65f08c3bdfSopenharmony_ci 66f08c3bdfSopenharmony_ci int netfd = open("/dev/net/tun", O_RDWR); 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_ci /* Android has tun at /dev/tun */ 69f08c3bdfSopenharmony_ci if (netfd == -1 && (errno == ENODEV || errno == ENOENT)) 70f08c3bdfSopenharmony_ci netfd = open("/dev/tun", O_RDWR); 71f08c3bdfSopenharmony_ci 72f08c3bdfSopenharmony_ci if (netfd == -1) { 73f08c3bdfSopenharmony_ci if (errno == ENODEV || errno == ENOENT) 74f08c3bdfSopenharmony_ci tst_brk(TCONF, "TUN support is missing?"); 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "opening /dev/net/tun failed"); 77f08c3bdfSopenharmony_ci } 78f08c3bdfSopenharmony_ci 79f08c3bdfSopenharmony_ci SAFE_IOCTL(netfd, TUNGETFEATURES, &features); 80f08c3bdfSopenharmony_ci 81f08c3bdfSopenharmony_ci tst_res(TINFO, "Available features are: %#x", features); 82f08c3bdfSopenharmony_ci for (i = 0; i < ARRAY_SIZE(known_flags); i++) { 83f08c3bdfSopenharmony_ci if (features & known_flags[i].flag) { 84f08c3bdfSopenharmony_ci features &= ~known_flags[i].flag; 85f08c3bdfSopenharmony_ci tst_res(TPASS, "%s %#x", known_flags[i].name, 86f08c3bdfSopenharmony_ci known_flags[i].flag); 87f08c3bdfSopenharmony_ci } 88f08c3bdfSopenharmony_ci } 89f08c3bdfSopenharmony_ci if (features) 90f08c3bdfSopenharmony_ci tst_res(TFAIL, "(UNKNOWN %#x)", features); 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_ci SAFE_CLOSE(netfd); 93f08c3bdfSopenharmony_ci} 94f08c3bdfSopenharmony_ci 95f08c3bdfSopenharmony_cistatic struct tst_test test = { 96f08c3bdfSopenharmony_ci .test_all = verify_features, 97f08c3bdfSopenharmony_ci .needs_root = 1, 98f08c3bdfSopenharmony_ci}; 99