]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/netdev/tuntap.c
netdev: do not assign unused values
[thirdparty/systemd.git] / src / network / netdev / tuntap.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
30ae9dfd 2
dccca82b 3#include <errno.h>
634f0f98 4#include <fcntl.h>
30ae9dfd 5#include <linux/if_tun.h>
634f0f98 6#include <net/if.h>
e306723e 7#include <netinet/if_ether.h>
634f0f98
ZJS
8#include <sys/ioctl.h>
9#include <sys/stat.h>
10#include <sys/types.h>
30ae9dfd 11
b5efdb8a 12#include "alloc-util.h"
3ffd4af2 13#include "fd-util.h"
441e9ae4 14#include "netdev/tuntap.h"
b1d4f8e1 15#include "user-util.h"
30ae9dfd
SS
16
17#define TUN_DEV "/dev/net/tun"
18
30ae9dfd 19static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) {
aa9f1140 20 TunTap *t;
30ae9dfd
SS
21
22 assert(netdev);
aa9f1140 23 assert(netdev->ifname);
30ae9dfd
SS
24 assert(ifr);
25
aa9f1140
TG
26 if (netdev->kind == NETDEV_KIND_TAP) {
27 t = TAP(netdev);
30ae9dfd 28 ifr->ifr_flags |= IFF_TAP;
aa9f1140
TG
29 } else {
30 t = TUN(netdev);
63dadd90 31 ifr->ifr_flags |= IFF_TUN;
aa9f1140 32 }
63dadd90 33
aa9f1140 34 if (!t->packet_info)
30ae9dfd
SS
35 ifr->ifr_flags |= IFF_NO_PI;
36
aa9f1140 37 if (t->one_queue)
30ae9dfd
SS
38 ifr->ifr_flags |= IFF_ONE_QUEUE;
39
aa9f1140 40 if (t->multi_queue)
30ae9dfd
SS
41 ifr->ifr_flags |= IFF_MULTI_QUEUE;
42
f5f07dbf
SS
43 if (t->vnet_hdr)
44 ifr->ifr_flags |= IFF_VNET_HDR;
45
30ae9dfd
SS
46 strncpy(ifr->ifr_name, netdev->ifname, IFNAMSIZ-1);
47
48 return 0;
49}
50
51static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
52 _cleanup_close_ int fd;
aa9f1140 53 TunTap *t = NULL;
30ae9dfd
SS
54 const char *user;
55 const char *group;
56 uid_t uid;
57 gid_t gid;
6f44acfb 58 int r;
30ae9dfd 59
aa9f1140
TG
60 assert(netdev);
61 assert(ifr);
62
30ae9dfd 63 fd = open(TUN_DEV, O_RDWR);
ce67afb0
SS
64 if (fd < 0)
65 return log_netdev_error_errno(netdev, -errno, "Failed to open tun dev: %m");
30ae9dfd 66
ad16158c 67 if (ioctl(fd, TUNSETIFF, ifr) < 0)
ce67afb0 68 return log_netdev_error_errno(netdev, -errno, "TUNSETIFF failed on tun dev: %m");
30ae9dfd 69
aa9f1140
TG
70 if (netdev->kind == NETDEV_KIND_TAP)
71 t = TAP(netdev);
72 else
73 t = TUN(netdev);
74
75 assert(t);
30ae9dfd 76
9ed794a3 77 if (t->user_name) {
aa9f1140
TG
78
79 user = t->user_name;
30ae9dfd
SS
80
81 r = get_user_creds(&user, &uid, NULL, NULL, NULL);
ce67afb0
SS
82 if (r < 0)
83 return log_netdev_error_errno(netdev, r, "Cannot resolve user name %s: %m", t->user_name);
30ae9dfd 84
ad16158c 85 if (ioctl(fd, TUNSETOWNER, uid) < 0)
ce67afb0 86 return log_netdev_error_errno(netdev, -errno, "TUNSETOWNER failed on tun dev: %m");
30ae9dfd
SS
87 }
88
98b32556 89 if (t->group_name) {
30ae9dfd 90
aa9f1140 91 group = t->group_name;
30ae9dfd
SS
92
93 r = get_group_creds(&group, &gid);
ce67afb0
SS
94 if (r < 0)
95 return log_netdev_error_errno(netdev, r, "Cannot resolve group name %s: %m", t->group_name);
30ae9dfd 96
ad16158c 97 if (ioctl(fd, TUNSETGROUP, gid) < 0)
ce67afb0 98 return log_netdev_error_errno(netdev, -errno, "TUNSETGROUP failed on tun dev: %m");
30ae9dfd
SS
99
100 }
101
ad16158c 102 if (ioctl(fd, TUNSETPERSIST, 1) < 0)
ce67afb0 103 return log_netdev_error_errno(netdev, -errno, "TUNSETPERSIST failed on tun dev: %m");
30ae9dfd 104
6f44acfb 105 return 0;
30ae9dfd
SS
106}
107
3be1d7e0 108static int netdev_create_tuntap(NetDev *netdev) {
aa9f1140 109 struct ifreq ifr = {};
30ae9dfd
SS
110 int r;
111
30ae9dfd 112 r = netdev_fill_tuntap_message(netdev, &ifr);
9ed794a3 113 if (r < 0)
30ae9dfd
SS
114 return r;
115
30ae9dfd
SS
116 return netdev_tuntap_add(netdev, &ifr);
117}
3be1d7e0 118
aa9f1140
TG
119static void tuntap_done(NetDev *netdev) {
120 TunTap *t = NULL;
121
122 assert(netdev);
123
124 if (netdev->kind == NETDEV_KIND_TUN)
125 t = TUN(netdev);
126 else
127 t = TAP(netdev);
128
129 assert(t);
130
a1e58e8e
LP
131 t->user_name = mfree(t->user_name);
132 t->group_name = mfree(t->group_name);
aa9f1140
TG
133}
134
e0fbf1fc 135static int tuntap_verify(NetDev *netdev, const char *filename) {
e0fbf1fc
TG
136 assert(netdev);
137
4e964aa0 138 if (netdev->mtu != 0)
98b32556 139 log_netdev_warning(netdev, "MTU configured for %s, ignoring", netdev_kind_to_string(netdev->kind));
e0fbf1fc 140
98b32556
LP
141 if (netdev->mac)
142 log_netdev_warning(netdev, "MAC configured for %s, ignoring", netdev_kind_to_string(netdev->kind));
e0fbf1fc
TG
143
144 return 0;
145}
146
3be1d7e0 147const NetDevVTable tun_vtable = {
aa9f1140
TG
148 .object_size = sizeof(TunTap),
149 .sections = "Match\0NetDev\0Tun\0",
e0fbf1fc 150 .config_verify = tuntap_verify,
aa9f1140 151 .done = tuntap_done,
3be1d7e0 152 .create = netdev_create_tuntap,
aa9f1140 153 .create_type = NETDEV_CREATE_INDEPENDENT,
3be1d7e0
TG
154};
155
156const NetDevVTable tap_vtable = {
aa9f1140
TG
157 .object_size = sizeof(TunTap),
158 .sections = "Match\0NetDev\0Tap\0",
e0fbf1fc 159 .config_verify = tuntap_verify,
aa9f1140 160 .done = tuntap_done,
3be1d7e0 161 .create = netdev_create_tuntap,
aa9f1140 162 .create_type = NETDEV_CREATE_INDEPENDENT,
3be1d7e0 163};