summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/netdev/netdev.c28
-rw-r--r--src/network/netdev/netdev.h6
-rw-r--r--src/network/networkd-link.h4
-rw-r--r--src/network/networkd-manager.c4
-rw-r--r--src/network/networkd-network.c41
-rw-r--r--src/network/networkd-network.h2
6 files changed, 61 insertions, 24 deletions
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c
index f7598dc7ea..48ea6c9f77 100644
--- a/src/network/netdev/netdev.c
+++ b/src/network/netdev/netdev.c
@@ -34,6 +34,7 @@
#include "networkd-queue.h"
#include "networkd-setlink.h"
#include "networkd-sriov.h"
+#include "networkd-state-file.h"
#include "nlmon.h"
#include "path-lookup.h"
#include "siphash24.h"
@@ -351,16 +352,16 @@ void link_assign_netdev(Link *link) {
old = TAKE_PTR(link->netdev);
if (netdev_get(link->manager, link->ifname, &netdev) < 0)
- return;
+ goto not_found;
int ifindex = NETDEV_VTABLE(netdev)->get_ifindex ?
NETDEV_VTABLE(netdev)->get_ifindex(netdev, link->ifname) :
netdev->ifindex;
if (ifindex != link->ifindex)
- return;
+ goto not_found;
if (NETDEV_VTABLE(netdev)->iftype != link->iftype)
- return;
+ goto not_found;
if (!NETDEV_VTABLE(netdev)->skip_netdev_kind_check) {
const char *kind;
@@ -371,13 +372,23 @@ void link_assign_netdev(Link *link) {
kind = netdev_kind_to_string(netdev->kind);
if (!streq_ptr(kind, link->kind))
- return;
+ goto not_found;
}
link->netdev = netdev_ref(netdev);
- if (netdev != old)
- log_link_debug(link, "Found matching .netdev file: %s", netdev->filename);
+ if (netdev == old)
+ return; /* The same NetDev found. */
+
+ log_link_debug(link, "Found matching .netdev file: %s", netdev->filename);
+ link_dirty(link);
+ return;
+
+not_found:
+
+ if (old)
+ /* Previously assigned NetDev is detached from Manager? Update the state file. */
+ link_dirty(link);
}
void netdev_enter_failed(NetDev *netdev) {
@@ -1003,15 +1014,12 @@ int netdev_load_one(Manager *manager, const char *filename) {
return 0;
}
-int netdev_load(Manager *manager, bool reload) {
+int netdev_load(Manager *manager) {
_cleanup_strv_free_ char **files = NULL;
int r;
assert(manager);
- if (!reload)
- hashmap_clear_with_destructor(manager->netdevs, netdev_unref);
-
r = conf_files_list_strv(&files, ".netdev", NULL, 0, NETWORK_DIRS);
if (r < 0)
return log_error_errno(r, "Failed to enumerate netdev files: %m");
diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h
index 10b9d0dd77..b3969b6e3b 100644
--- a/src/network/netdev/netdev.h
+++ b/src/network/netdev/netdev.h
@@ -211,14 +211,14 @@ NetDev* netdev_detach_name(NetDev *netdev, const char *name);
void netdev_detach(NetDev *netdev);
int netdev_set_ifindex_internal(NetDev *netdev, int ifindex);
-int netdev_load(Manager *manager, bool reload);
+int netdev_load(Manager *manager);
int netdev_load_one(Manager *manager, const char *filename);
void netdev_drop(NetDev *netdev);
void netdev_enter_failed(NetDev *netdev);
int netdev_enter_ready(NetDev *netdev);
-NetDev *netdev_unref(NetDev *netdev);
-NetDev *netdev_ref(NetDev *netdev);
+NetDev* netdev_unref(NetDev *netdev);
+NetDev* netdev_ref(NetDev *netdev);
DEFINE_TRIVIAL_DESTRUCTOR(netdev_destroy_callback, NetDev, netdev_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref);
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index e29dd5d990..8ac7c35563 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -222,8 +222,8 @@ bool link_is_ready_to_configure(Link *link, bool allow_unmanaged);
void link_ntp_settings_clear(Link *link);
void link_dns_settings_clear(Link *link);
-Link *link_unref(Link *link);
-Link *link_ref(Link *link);
+Link* link_unref(Link *link);
+Link* link_ref(Link *link);
DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref);
DEFINE_TRIVIAL_DESTRUCTOR(link_netlink_destroy_callback, Link, link_unref);
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index fdaf3ff4d7..ca2b008a34 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -777,7 +777,7 @@ int manager_start(Manager *m) {
int manager_load_config(Manager *m) {
int r;
- r = netdev_load(m, false);
+ r = netdev_load(m);
if (r < 0)
return r;
@@ -1188,7 +1188,7 @@ int manager_reload(Manager *m, sd_bus_message *message) {
(void) notify_reloading();
- r = netdev_load(m, /* reload= */ true);
+ r = netdev_load(m);
if (r < 0)
goto finish;
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 3d399fe876..9cd683e9bc 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -598,24 +598,47 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
return 0;
}
-int network_load(Manager *manager, OrderedHashmap **networks) {
+int network_load(Manager *manager, OrderedHashmap **ret) {
_cleanup_strv_free_ char **files = NULL;
+ OrderedHashmap *networks = NULL;
int r;
assert(manager);
-
- ordered_hashmap_clear_with_destructor(*networks, network_unref);
+ assert(ret);
r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
if (r < 0)
return log_error_errno(r, "Failed to enumerate network files: %m");
STRV_FOREACH(f, files)
- (void) network_load_one(manager, networks, *f);
+ (void) network_load_one(manager, &networks, *f);
+ *ret = TAKE_PTR(networks);
return 0;
}
+static bool network_netdev_equal(Network *a, Network *b) {
+ assert(a);
+ assert(b);
+
+ if (a->batadv != b->batadv ||
+ a->bridge != b->bridge ||
+ a->bond != b->bond ||
+ a->vrf != b->vrf ||
+ a->xfrm != b->xfrm)
+ return false;
+
+ if (hashmap_size(a->stacked_netdevs) != hashmap_size(b->stacked_netdevs))
+ return false;
+
+ NetDev *n;
+ HASHMAP_FOREACH(n, a->stacked_netdevs)
+ if (hashmap_get(b->stacked_netdevs, n->ifname) != n)
+ return false;
+
+ return true;
+}
+
int network_reload(Manager *manager) {
OrderedHashmap *new_networks = NULL;
Network *n, *old;
@@ -630,15 +653,21 @@ int network_reload(Manager *manager) {
ORDERED_HASHMAP_FOREACH(n, new_networks) {
r = network_get_by_name(manager, n->name, &old);
if (r < 0) {
- log_debug("Found new .network file: %s", n->filename);
+ log_debug("%s: Found new .network file.", n->filename);
continue;
}
if (!stats_by_path_equal(n->stats_by_path, old->stats_by_path)) {
- log_debug("Found updated .network file: %s", n->filename);
+ log_debug("%s: Found updated .network file.", n->filename);
+ continue;
+ }
+
+ if (!network_netdev_equal(n, old)) {
+ log_debug("%s: Detected update of referenced .netdev file(s).", n->filename);
continue;
}
+ /* Nothing updated, use the existing Network object, and drop the new one. */
r = ordered_hashmap_replace(new_networks, old->name, old);
if (r < 0)
goto failure;
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index b4ab117928..30ea9ac352 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -419,7 +419,7 @@ Network *network_ref(Network *network);
Network *network_unref(Network *network);
DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_unref);
-int network_load(Manager *manager, OrderedHashmap **networks);
+int network_load(Manager *manager, OrderedHashmap **ret);
int network_reload(Manager *manager);
int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename);
int network_verify(Network *network);