]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/tuntap: introduce KeepCarrier= setting
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 12 Aug 2022 22:45:49 +0000 (07:45 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 16 Aug 2022 12:57:31 +0000 (21:57 +0900)
Closes #24267.

man/systemd.netdev.xml
src/network/netdev/netdev-gperf.gperf
src/network/netdev/tuntap.c
src/network/netdev/tuntap.h
test/fuzz/fuzz-netdev-parser/directives.netdev

index 94c9308e46ab9de9c10673335d1646a9ba9f1fcf..266ad52df28d1de4261caf6dbe6db7519a8d3d47 100644 (file)
         <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>
 
index 162664ecf131afae5c85d4a19c9b6811b0d005e5..3cfcd51e63699b1c600a86b1bae6d1e89b9856ad 100644 (file)
@@ -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)
index 8e9c1ca9b3fe2bd2d0fae487aea8cb64ebe8b2e8..f48ebf268a99dae84b2e5539ddaa16b58fef88ca 100644 (file)
@@ -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,
index 4d1e643f4313f6ee4def870943b831bde02ca9fc..52f2da9fabe623839b1f97fed36c9f41ff9c8951 100644 (file)
@@ -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);
index d5f3228065c2b200873ee8de52a963c5b5d3ec0d..309941f58defe87980d182fb650f36e12d9b4ada 100644 (file)
@@ -171,6 +171,7 @@ User=
 Group=
 PacketInfo=
 VNetHeader=
+KeepCarrier=
 [IPVLAN]
 Mode=
 Flags=
@@ -184,6 +185,7 @@ PacketInfo=
 VNetHeader=
 Group=
 User=
+KeepCarrier=
 [NetDev]
 Kind=
 MACAddress=