~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/net/tun.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 
  3 #define _GNU_SOURCE
  4 
  5 #include <errno.h>
  6 #include <fcntl.h>
  7 #include <stdio.h>
  8 #include <stdlib.h>
  9 #include <string.h>
 10 #include <unistd.h>
 11 #include <linux/if.h>
 12 #include <linux/if_tun.h>
 13 #include <linux/netlink.h>
 14 #include <linux/rtnetlink.h>
 15 #include <sys/ioctl.h>
 16 #include <sys/socket.h>
 17 
 18 #include "../kselftest_harness.h"
 19 
 20 static int tun_attach(int fd, char *dev)
 21 {
 22         struct ifreq ifr;
 23 
 24         memset(&ifr, 0, sizeof(ifr));
 25         strcpy(ifr.ifr_name, dev);
 26         ifr.ifr_flags = IFF_ATTACH_QUEUE;
 27 
 28         return ioctl(fd, TUNSETQUEUE, (void *) &ifr);
 29 }
 30 
 31 static int tun_detach(int fd, char *dev)
 32 {
 33         struct ifreq ifr;
 34 
 35         memset(&ifr, 0, sizeof(ifr));
 36         strcpy(ifr.ifr_name, dev);
 37         ifr.ifr_flags = IFF_DETACH_QUEUE;
 38 
 39         return ioctl(fd, TUNSETQUEUE, (void *) &ifr);
 40 }
 41 
 42 static int tun_alloc(char *dev)
 43 {
 44         struct ifreq ifr;
 45         int fd, err;
 46 
 47         fd = open("/dev/net/tun", O_RDWR);
 48         if (fd < 0) {
 49                 fprintf(stderr, "can't open tun: %s\n", strerror(errno));
 50                 return fd;
 51         }
 52 
 53         memset(&ifr, 0, sizeof(ifr));
 54         strcpy(ifr.ifr_name, dev);
 55         ifr.ifr_flags = IFF_TAP | IFF_NAPI | IFF_MULTI_QUEUE;
 56 
 57         err = ioctl(fd, TUNSETIFF, (void *) &ifr);
 58         if (err < 0) {
 59                 fprintf(stderr, "can't TUNSETIFF: %s\n", strerror(errno));
 60                 close(fd);
 61                 return err;
 62         }
 63         strcpy(dev, ifr.ifr_name);
 64         return fd;
 65 }
 66 
 67 static int tun_delete(char *dev)
 68 {
 69         struct {
 70                 struct nlmsghdr  nh;
 71                 struct ifinfomsg ifm;
 72                 unsigned char    data[64];
 73         } req;
 74         struct rtattr *rta;
 75         int ret, rtnl;
 76 
 77         rtnl = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
 78         if (rtnl < 0) {
 79                 fprintf(stderr, "can't open rtnl: %s\n", strerror(errno));
 80                 return 1;
 81         }
 82 
 83         memset(&req, 0, sizeof(req));
 84         req.nh.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.ifm)));
 85         req.nh.nlmsg_flags = NLM_F_REQUEST;
 86         req.nh.nlmsg_type = RTM_DELLINK;
 87 
 88         req.ifm.ifi_family = AF_UNSPEC;
 89 
 90         rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.nh.nlmsg_len));
 91         rta->rta_type = IFLA_IFNAME;
 92         rta->rta_len = RTA_LENGTH(IFNAMSIZ);
 93         req.nh.nlmsg_len += rta->rta_len;
 94         memcpy(RTA_DATA(rta), dev, IFNAMSIZ);
 95 
 96         ret = send(rtnl, &req, req.nh.nlmsg_len, 0);
 97         if (ret < 0)
 98                 fprintf(stderr, "can't send: %s\n", strerror(errno));
 99         ret = (unsigned int)ret != req.nh.nlmsg_len;
100 
101         close(rtnl);
102         return ret;
103 }
104 
105 FIXTURE(tun)
106 {
107         char ifname[IFNAMSIZ];
108         int fd, fd2;
109 };
110 
111 FIXTURE_SETUP(tun)
112 {
113         memset(self->ifname, 0, sizeof(self->ifname));
114 
115         self->fd = tun_alloc(self->ifname);
116         ASSERT_GE(self->fd, 0);
117 
118         self->fd2 = tun_alloc(self->ifname);
119         ASSERT_GE(self->fd2, 0);
120 }
121 
122 FIXTURE_TEARDOWN(tun)
123 {
124         if (self->fd >= 0)
125                 close(self->fd);
126         if (self->fd2 >= 0)
127                 close(self->fd2);
128 }
129 
130 TEST_F(tun, delete_detach_close) {
131         EXPECT_EQ(tun_delete(self->ifname), 0);
132         EXPECT_EQ(tun_detach(self->fd, self->ifname), -1);
133         EXPECT_EQ(errno, 22);
134 }
135 
136 TEST_F(tun, detach_delete_close) {
137         EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
138         EXPECT_EQ(tun_delete(self->ifname), 0);
139 }
140 
141 TEST_F(tun, detach_close_delete) {
142         EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
143         close(self->fd);
144         self->fd = -1;
145         EXPECT_EQ(tun_delete(self->ifname), 0);
146 }
147 
148 TEST_F(tun, reattach_delete_close) {
149         EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
150         EXPECT_EQ(tun_attach(self->fd, self->ifname), 0);
151         EXPECT_EQ(tun_delete(self->ifname), 0);
152 }
153 
154 TEST_F(tun, reattach_close_delete) {
155         EXPECT_EQ(tun_detach(self->fd, self->ifname), 0);
156         EXPECT_EQ(tun_attach(self->fd, self->ifname), 0);
157         close(self->fd);
158         self->fd = -1;
159         EXPECT_EQ(tun_delete(self->ifname), 0);
160 }
161 
162 TEST_HARNESS_MAIN
163 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php