summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2015-10-02 16:52:49 +0200
committerTom Gundersen <teg@jklm.no>2015-11-11 16:16:47 +0100
commit5e5b137acc7094c9a1b8e7634b426dd445688bf0 (patch)
tree7b4d12eeefa2ebd076a38d38c274bc5394caf984
parent3116c225d2e3c0d8e6b3f4d4a9b48443cc7baf2d (diff)
networkd: link - drop foreign config when configuring link
This is a change in behavior: Before we would never remove any state, only add to it, we now drop unwanted state from any link the moment we start managing it. Note however, that we still will not remove any foreign state added at runtime, to avoid any feedback loops. However, we make no guarantees about coexisting with third-party tools that change the state of the links we manage.
-rw-r--r--src/network/networkd-link.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index a7d0908bdd..00c57b2960 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -2017,6 +2017,35 @@ static int link_set_ipv6_hop_limit(Link *link) {
return 0;
}
+static int link_drop_foreign_config(Link *link) {
+ Address *address;
+ Route *route;
+ Iterator i;
+ int r;
+
+ SET_FOREACH(address, link->addresses_foreign, i) {
+ /* we consider IPv6LL addresses to be managed by the kernel */
+ if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
+ continue;
+
+ r = address_remove(address, link, link_address_remove_handler);
+ if (r < 0)
+ return r;
+ }
+
+ SET_FOREACH(route, link->routes_foreign, i) {
+ /* do not touch routes managed by the kernel */
+ if (route->protocol == RTPROT_KERNEL)
+ continue;
+
+ r = route_remove(route, link, link_address_remove_handler);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
static int link_configure(Link *link) {
int r;
@@ -2024,6 +2053,10 @@ static int link_configure(Link *link) {
assert(link->network);
assert(link->state == LINK_STATE_PENDING);
+ r = link_drop_foreign_config(link);
+ if (r < 0)
+ return r;
+
r = link_set_bridge_fdb(link);
if (r < 0)
return r;