summaryrefslogtreecommitdiff
path: root/src/network/networkd-manager.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-08-13 17:18:55 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-08-16 21:57:35 +0900
commitaf7a86b8a6b6510264b7ac0ae6a1e1d37d510ef5 (patch)
treedc45da1110cd80232ea6b2c899920d2542e08fde /src/network/networkd-manager.c
parentf8b7c177640e19a0146fa26c4263e713b7045222 (diff)
downloadsystemd-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.c62
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;