summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--src/libsystemd/sd-rtnl/sd-rtnl.c2
-rw-r--r--src/network/networkd-manager.c47
-rw-r--r--units/systemd-networkd.service.in1
-rw-r--r--units/systemd-networkd.socket20
5 files changed, 63 insertions, 9 deletions
diff --git a/Makefile.am b/Makefile.am
index e3ba11c8c0..fdadda7d31 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5668,9 +5668,11 @@ tests += \
nodist_systemunit_DATA += \
units/systemd-networkd.service \
+ units/systemd-networkd.socket \
units/systemd-networkd-wait-online.service
GENERAL_ALIASES += \
+ $(systemunitdir)/systemd-networkd.socket $(pkgsysconfdir)/system/sockets.target.wants/systemd-networkd.socket \
$(systemunitdir)/systemd-networkd.service $(pkgsysconfdir)/system/multi-user.target.wants/systemd-networkd.service \
$(systemunitdir)/systemd-networkd-wait-online.service $(pkgsysconfdir)/system/network-online.target.wants/systemd-networkd-wait-online.service
diff --git a/src/libsystemd/sd-rtnl/sd-rtnl.c b/src/libsystemd/sd-rtnl/sd-rtnl.c
index 767c583735..45ba50a856 100644
--- a/src/libsystemd/sd-rtnl/sd-rtnl.c
+++ b/src/libsystemd/sd-rtnl/sd-rtnl.c
@@ -74,7 +74,7 @@ int sd_rtnl_new_from_netlink(sd_rtnl **ret, int fd) {
assert_return(ret, -EINVAL);
- r = sd_rtnl_new(ret);
+ r = sd_rtnl_new(&rtnl);
if (r < 0)
return r;
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 4c9043486a..49e353a7b1 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -35,6 +35,7 @@
#include "virt.h"
#include "sd-rtnl.h"
+#include "sd-daemon.h"
/* use 8 MB for receive socket kernel queue. */
#define RCVBUF_SIZE (8*1024*1024)
@@ -75,9 +76,33 @@ static int setup_default_address_pool(Manager *m) {
return 0;
}
+static int systemd_netlink_fd(int *ret) {
+ int n, fd, rtnl_fd = -1;
+
+ n = sd_listen_fds(true);
+ if (n <= 0)
+ return -EINVAL;
+
+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
+ if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
+ if (rtnl_fd >= 0)
+ return -EINVAL;
+
+ rtnl_fd = fd;
+ }
+ }
+
+ if (rtnl_fd < 0)
+ return -EINVAL;
+
+ *ret = rtnl_fd;
+
+ return 0;
+}
+
int manager_new(Manager **ret) {
_cleanup_manager_free_ Manager *m = NULL;
- int r;
+ int r, fd;
m = new0(Manager, 1);
if (!m)
@@ -96,14 +121,20 @@ int manager_new(Manager **ret) {
sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
- r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
- RTNLGRP_IPV6_IFADDR);
- if (r < 0)
- return r;
+ if (systemd_netlink_fd(&fd) < 0) {
+ r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
+ RTNLGRP_IPV6_IFADDR);
+ if (r < 0)
+ return r;
- r = sd_rtnl_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
- if (r < 0)
- return r;
+ r = sd_rtnl_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
+ if (r < 0)
+ return r;
+ } else {
+ r = sd_rtnl_new_from_netlink(&m->rtnl, fd);
+ if (r < 0)
+ return r;
+ }
r = sd_bus_default_system(&m->bus);
if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
diff --git a/units/systemd-networkd.service.in b/units/systemd-networkd.service.in
index fe92da2123..fab278e92c 100644
--- a/units/systemd-networkd.service.in
+++ b/units/systemd-networkd.service.in
@@ -29,3 +29,4 @@ WatchdogSec=1min
[Install]
WantedBy=multi-user.target
+Also=systemd-networkd.socket
diff --git a/units/systemd-networkd.socket b/units/systemd-networkd.socket
new file mode 100644
index 0000000000..d15ee9ed83
--- /dev/null
+++ b/units/systemd-networkd.socket
@@ -0,0 +1,20 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=networkd rtnetlink socket
+Documentation=man:systemd-networkd.service(8) man:rtnetlink(7)
+DefaultDependencies=no
+Before=sockets.target
+
+[Socket]
+ReceiveBuffer=8M
+ListenNetlink=route 273
+PassCredentials=yes
+
+[Install]
+WantedBy=sockets.target