summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-08-13 07:45:49 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-08-16 21:57:31 +0900
commitf8b7c177640e19a0146fa26c4263e713b7045222 (patch)
tree02a9fb1852c527ff621994c31bc64123af6d08ee
parent8f388c4e4607f7e8ce1807e8c7dfcc17d68b9c55 (diff)
downloadsystemd-f8b7c177640e19a0146fa26c4263e713b7045222.tar.gz
network/tuntap: introduce KeepCarrier= setting
Closes #24267.
-rw-r--r--man/systemd.netdev.xml9
-rw-r--r--src/network/netdev/netdev-gperf.gperf2
-rw-r--r--src/network/netdev/tuntap.c16
-rw-r--r--src/network/netdev/tuntap.h2
-rw-r--r--test/fuzz/fuzz-netdev-parser/directives.netdev2
5 files changed, 31 insertions, 0 deletions
diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index 94c9308e46..266ad52df2 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -1558,6 +1558,15 @@
<filename>/dev/net/tun</filename> device.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>KeepCarrier=</varname></term>
+ <listitem>
+ <para>Takes a boolean. If enabled, to make the interface maintain its carrier status, the file
+ descriptor of the interface is kept open. This may be useful to keep the interface in running
+ state, for example while the backing process is temporarily shutdown. Defaults to
+ <literal>no</literal>.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf
index 162664ecf1..3cfcd51e63 100644
--- a/src/network/netdev/netdev-gperf.gperf
+++ b/src/network/netdev/netdev-gperf.gperf
@@ -185,12 +185,14 @@ Tun.PacketInfo, config_parse_bool,
Tun.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr)
Tun.User, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, user_name)
Tun.Group, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, group_name)
+Tun.KeepCarrier, config_parse_bool, 0, offsetof(TunTap, keep_fd)
Tap.OneQueue, config_parse_warn_compat, DISABLED_LEGACY, 0
Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
Tap.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr)
Tap.User, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, user_name)
Tap.Group, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, group_name)
+Tap.KeepCarrier, config_parse_bool, 0, offsetof(TunTap, keep_fd)
Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode)
Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0, offsetof(Bond, xmit_hash_policy)
Bond.LACPTransmitRate, config_parse_bond_lacp_rate, 0, offsetof(Bond, lacp_rate)
diff --git a/src/network/netdev/tuntap.c b/src/network/netdev/tuntap.c
index 8e9c1ca9b3..f48ebf268a 100644
--- a/src/network/netdev/tuntap.c
+++ b/src/network/netdev/tuntap.c
@@ -90,9 +90,22 @@ static int netdev_create_tuntap(NetDev *netdev) {
if (ioctl(fd, TUNSETPERSIST, 1) < 0)
return log_netdev_error_errno(netdev, errno, "TUNSETPERSIST failed: %m");
+ if (t->keep_fd)
+ t->fd = TAKE_FD(fd);
+
return 0;
}
+static void tuntap_init(NetDev *netdev) {
+ TunTap *t;
+
+ assert(netdev);
+ t = TUNTAP(netdev);
+ assert(t);
+
+ t->fd = -1;
+}
+
static void tuntap_done(NetDev *netdev) {
TunTap *t;
@@ -100,6 +113,7 @@ static void tuntap_done(NetDev *netdev) {
t = TUNTAP(netdev);
assert(t);
+ t->fd = safe_close(t->fd);
t->user_name = mfree(t->user_name);
t->group_name = mfree(t->group_name);
}
@@ -126,6 +140,7 @@ const NetDevVTable tun_vtable = {
.object_size = sizeof(TunTap),
.sections = NETDEV_COMMON_SECTIONS "Tun\0",
.config_verify = tuntap_verify,
+ .init = tuntap_init,
.done = tuntap_done,
.create = netdev_create_tuntap,
.create_type = NETDEV_CREATE_INDEPENDENT,
@@ -136,6 +151,7 @@ const NetDevVTable tap_vtable = {
.object_size = sizeof(TunTap),
.sections = NETDEV_COMMON_SECTIONS "Tap\0",
.config_verify = tuntap_verify,
+ .init = tuntap_init,
.done = tuntap_done,
.create = netdev_create_tuntap,
.create_type = NETDEV_CREATE_INDEPENDENT,
diff --git a/src/network/netdev/tuntap.h b/src/network/netdev/tuntap.h
index 4d1e643f43..52f2da9fab 100644
--- a/src/network/netdev/tuntap.h
+++ b/src/network/netdev/tuntap.h
@@ -8,11 +8,13 @@ typedef struct TunTap TunTap;
struct TunTap {
NetDev meta;
+ int fd;
char *user_name;
char *group_name;
bool multi_queue;
bool packet_info;
bool vnet_hdr;
+ bool keep_fd;
};
DEFINE_NETDEV_CAST(TUN, TunTap);
diff --git a/test/fuzz/fuzz-netdev-parser/directives.netdev b/test/fuzz/fuzz-netdev-parser/directives.netdev
index d5f3228065..309941f58d 100644
--- a/test/fuzz/fuzz-netdev-parser/directives.netdev
+++ b/test/fuzz/fuzz-netdev-parser/directives.netdev
@@ -171,6 +171,7 @@ User=
Group=
PacketInfo=
VNetHeader=
+KeepCarrier=
[IPVLAN]
Mode=
Flags=
@@ -184,6 +185,7 @@ PacketInfo=
VNetHeader=
Group=
User=
+KeepCarrier=
[NetDev]
Kind=
MACAddress=