summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/import/importd.c1
-rw-r--r--src/network/networkd-link.c10
-rw-r--r--src/network/networkd-link.h6
-rw-r--r--src/network/networkd-manager.c42
-rw-r--r--src/network/networkd.c2
-rw-r--r--src/network/networkd.h2
-rw-r--r--units/systemd-networkd.service.in2
7 files changed, 58 insertions, 7 deletions
diff --git a/src/import/importd.c b/src/import/importd.c
index 47157857c8..1222bf3cd2 100644
--- a/src/import/importd.c
+++ b/src/import/importd.c
@@ -30,6 +30,7 @@
#include "socket-util.h"
#include "mkdir.h"
#include "import-util.h"
+#include "def.h"
typedef struct Transfer Transfer;
typedef struct Manager Manager;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 1442230b51..eff1ce94be 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -35,7 +35,7 @@
#include "conf-parser.h"
#include "dhcp-lease-internal.h"
-static bool link_dhcp6_enabled(Link *link) {
+bool link_dhcp6_enabled(Link *link) {
if (link->flags & IFF_LOOPBACK)
return false;
@@ -45,7 +45,7 @@ static bool link_dhcp6_enabled(Link *link) {
return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES);
}
-static bool link_dhcp4_enabled(Link *link) {
+bool link_dhcp4_enabled(Link *link) {
if (link->flags & IFF_LOOPBACK)
return false;
@@ -55,7 +55,7 @@ static bool link_dhcp4_enabled(Link *link) {
return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES);
}
-static bool link_dhcp4_server_enabled(Link *link) {
+bool link_dhcp4_server_enabled(Link *link) {
if (link->flags & IFF_LOOPBACK)
return false;
@@ -65,7 +65,7 @@ static bool link_dhcp4_server_enabled(Link *link) {
return link->network->dhcp_server;
}
-static bool link_ipv4ll_enabled(Link *link) {
+bool link_ipv4ll_enabled(Link *link) {
if (link->flags & IFF_LOOPBACK)
return false;
@@ -75,7 +75,7 @@ static bool link_ipv4ll_enabled(Link *link) {
return link->network->ipv4ll;
}
-static bool link_lldp_enabled(Link *link) {
+bool link_lldp_enabled(Link *link) {
if (link->flags & IFF_LOOPBACK)
return false;
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index b23712011e..ce83f24da3 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -114,6 +114,12 @@ int ipv4ll_configure(Link *link);
int dhcp4_configure(Link *link);
int icmp6_configure(Link *link);
+bool link_lldp_enabled(Link *link);
+bool link_ipv4ll_enabled(Link *link);
+bool link_dhcp4_server_enabled(Link *link);
+bool link_dhcp4_enabled(Link *link);
+bool link_dhcp6_enabled(Link *link);
+
const char* link_state_to_string(LinkState s) _const_;
LinkState link_state_from_string(const char *s) _pure_;
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 40328a36c9..02ab9f95ef 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -31,6 +31,8 @@
#include "libudev-private.h"
#include "udev-util.h"
#include "rtnl-util.h"
+#include "bus-util.h"
+#include "def.h"
#include "mkdir.h"
#include "virt.h"
@@ -497,6 +499,46 @@ void manager_free(Manager *m) {
free(m);
}
+static bool manager_check_idle(void *userdata) {
+ Manager *m = userdata;
+ Link *link;
+ Iterator i;
+
+ assert(m);
+
+ HASHMAP_FOREACH(link, m->links, i) {
+ /* we are not woken on udev activity, so let's just wait for the
+ * pending udev event */
+ if (link->state == LINK_STATE_PENDING)
+ return false;
+
+ if (!link->network)
+ continue;
+
+ /* we are not woken on netork activity, so let's stay around */
+ if (link_lldp_enabled(link) ||
+ link_ipv4ll_enabled(link) ||
+ link_dhcp4_server_enabled(link) ||
+ link_dhcp4_enabled(link) ||
+ link_dhcp6_enabled(link))
+ return false;
+ }
+
+ return true;
+}
+
+int manager_run(Manager *m) {
+ assert(m);
+
+ return bus_event_loop_with_idle(
+ m->event,
+ m->bus,
+ "org.freedesktop.network1",
+ DEFAULT_EXIT_USEC,
+ manager_check_idle,
+ m);
+}
+
int manager_load_config(Manager *m) {
int r;
diff --git a/src/network/networkd.c b/src/network/networkd.c
index 0aaef8b792..571f523898 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -110,7 +110,7 @@ int main(int argc, char *argv[]) {
"READY=1\n"
"STATUS=Processing requests...");
- r = sd_event_loop(m->event);
+ r = manager_run(m);
if (r < 0) {
log_error_errno(r, "Event loop failed: %m");
goto out;
diff --git a/src/network/networkd.h b/src/network/networkd.h
index 9f3a5ea9d5..e6d84f105b 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -239,6 +239,8 @@ extern const sd_bus_vtable manager_vtable[];
int manager_new(Manager **ret);
void manager_free(Manager *m);
+int manager_run(Manager *m);
+
int manager_load_config(Manager *m);
bool manager_should_reload(Manager *m);
diff --git a/units/systemd-networkd.service.in b/units/systemd-networkd.service.in
index fab278e92c..5a91b8e499 100644
--- a/units/systemd-networkd.service.in
+++ b/units/systemd-networkd.service.in
@@ -19,7 +19,7 @@ Wants=network.target
[Service]
Type=notify
-Restart=always
+Restart=on-failure
RestartSec=0
ExecStart=@rootlibexecdir@/systemd-networkd
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER