diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-08-13 17:18:55 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-08-16 21:57:35 +0900 |
commit | af7a86b8a6b6510264b7ac0ae6a1e1d37d510ef5 (patch) | |
tree | dc45da1110cd80232ea6b2c899920d2542e08fde /src/network/networkd-manager.c | |
parent | f8b7c177640e19a0146fa26c4263e713b7045222 (diff) | |
download | systemd-af7a86b8a6b6510264b7ac0ae6a1e1d37d510ef5.tar.gz |
network/tuntap: save tun or tap file descriptor in fd store
Diffstat (limited to 'src/network/networkd-manager.c')
-rw-r--r-- | src/network/networkd-manager.c | 62 |
1 files changed, 49 insertions, 13 deletions
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 9b77f536c8..52c62d7297 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -8,7 +8,6 @@ #include <linux/nexthop.h> #include <linux/nl80211.h> -#include "sd-daemon.h" #include "sd-netlink.h" #include "alloc-util.h" @@ -18,6 +17,7 @@ #include "bus-polkit.h" #include "bus-util.h" #include "conf-parser.h" +#include "daemon-util.h" #include "def.h" #include "device-private.h" #include "device-util.h" @@ -58,6 +58,7 @@ #include "sysctl-util.h" #include "tclass.h" #include "tmpfile-util.h" +#include "tuntap.h" #include "udev-util.h" /* use 128 MB for receive socket kernel queue. */ @@ -243,22 +244,45 @@ static int manager_connect_udev(Manager *m) { return 0; } -static int systemd_netlink_fd(void) { - int n, fd, rtnl_fd = -EINVAL; +static int manager_listen_fds(Manager *m, int *ret_rtnl_fd) { + _cleanup_strv_free_ char **names = NULL; + int n, rtnl_fd = -1; - n = sd_listen_fds(true); - if (n <= 0) + assert(m); + assert(ret_rtnl_fd); + + n = sd_listen_fds_with_names(/* unset_environment = */ true, &names); + if (n < 0) + return n; + + if (strv_length(names) != (size_t) n) return -EINVAL; - for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) + for (int i = 0; i < n; i++) { + int fd = i + SD_LISTEN_FDS_START; + if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) { - if (rtnl_fd >= 0) - return -EINVAL; + if (rtnl_fd >= 0) { + log_debug("Received multiple netlink socket, ignoring."); + safe_close(fd); + continue; + } rtnl_fd = fd; + continue; } - return rtnl_fd; + if (manager_add_tuntap_fd(m, fd, names[i]) >= 0) + continue; + + if (m->test_mode) + safe_close(fd); + else + close_and_notify_warn(fd, names[i]); + } + + *ret_rtnl_fd = rtnl_fd; + return 0; } static int manager_connect_genl(Manager *m) { @@ -325,18 +349,21 @@ static int manager_setup_rtnl_filter(Manager *manager) { return sd_netlink_attach_filter(manager->rtnl, ELEMENTSOF(filter), filter); } -static int manager_connect_rtnl(Manager *m) { - int fd, r; +static int manager_connect_rtnl(Manager *m, int fd) { + _unused_ _cleanup_close_ int fd_close = fd; + int r; assert(m); - fd = systemd_netlink_fd(); + /* This takes input fd. */ + if (fd < 0) r = sd_netlink_open(&m->rtnl); else r = sd_netlink_open_fd(&m->rtnl, fd); if (r < 0) return r; + TAKE_FD(fd_close); /* Bump receiver buffer, but only if we are not called via socket activation, as in that * case systemd sets the receive buffer size for us, and the value in the .socket unit @@ -487,6 +514,7 @@ static int manager_set_keep_configuration(Manager *m) { } int manager_setup(Manager *m) { + _cleanup_close_ int rtnl_fd = -1; int r; assert(m); @@ -510,7 +538,11 @@ int manager_setup(Manager *m) { if (r < 0) return r; - r = manager_connect_rtnl(m); + r = manager_listen_fds(m, &rtnl_fd); + if (r < 0) + return r; + + r = manager_connect_rtnl(m, TAKE_FD(rtnl_fd)); if (r < 0) return r; @@ -600,6 +632,8 @@ Manager* manager_free(Manager *m) { m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref); + m->tuntap_fds_by_name = hashmap_free(m->tuntap_fds_by_name); + m->wiphy_by_name = hashmap_free(m->wiphy_by_name); m->wiphy_by_index = hashmap_free_with_destructor(m->wiphy_by_index, wiphy_free); @@ -678,6 +712,8 @@ int manager_load_config(Manager *m) { if (r < 0) return r; + manager_clear_unmanaged_tuntap_fds(m); + r = network_load(m, &m->networks); if (r < 0) return r; |