summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-10-28 17:23:54 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-10-31 10:41:44 +0100
commitb8b0c1a065395e42749b0e1aaef82e5f457468d8 (patch)
tree149e33b24a14298b985ff63b64cc2554d864e913 /src
parentNEWS: fix typo (diff)
downloadsystemd-b8b0c1a065395e42749b0e1aaef82e5f457468d8.tar.xz
systemd-b8b0c1a065395e42749b0e1aaef82e5f457468d8.zip
network: update tunnel or vxlan interface if the local address is changed
If a tunnel or vxlan is configured with Local=dhcp4 or so, then the local address needs to be changed when it is changed. Fixes #24854.
Diffstat (limited to 'src')
-rw-r--r--src/network/netdev/netdev.c11
-rw-r--r--src/network/netdev/netdev.h6
-rw-r--r--src/network/netdev/tunnel.c18
-rw-r--r--src/network/netdev/vxlan.c9
-rw-r--r--src/network/networkd-dhcp4.c4
-rw-r--r--src/network/networkd-dhcp6.c4
-rw-r--r--src/network/networkd-ipv4ll.c4
-rw-r--r--src/network/networkd-link.c16
-rw-r--r--src/network/networkd-link.h3
-rw-r--r--src/network/networkd-ndisc.c2
10 files changed, 75 insertions, 2 deletions
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c
index 1e046397d5..85760c741d 100644
--- a/src/network/netdev/netdev.c
+++ b/src/network/netdev/netdev.c
@@ -413,6 +413,17 @@ int netdev_enter_ready(NetDev *netdev) {
return 0;
}
+bool netdev_needs_reconfigure(NetDev *netdev, NetDevLocalAddressType type) {
+ assert(netdev);
+ assert(type < _NETDEV_LOCAL_ADDRESS_TYPE_MAX);
+
+ if (type < 0)
+ return true;
+
+ return NETDEV_VTABLE(netdev)->needs_reconfigure &&
+ NETDEV_VTABLE(netdev)->needs_reconfigure(netdev, type);
+}
+
/* callback for netdev's created without a backing Link */
static int netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev *netdev) {
int r;
diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h
index 106f47acad..765496d044 100644
--- a/src/network/netdev/netdev.h
+++ b/src/network/netdev/netdev.h
@@ -8,6 +8,7 @@
#include "hash-funcs.h"
#include "list.h"
#include "log-link.h"
+#include "netdev-util.h"
#include "networkd-link.h"
#include "time-util.h"
@@ -186,6 +187,10 @@ typedef struct NetDevVTable {
/* provides if MTU can be set. If this is not set, assumed to be yes. */
bool (*can_set_mtu)(NetDev *netdev, uint32_t mtu);
+ /* provides if the netdev needs to be reconfigured when a specified type of address on the underlying
+ * interface is updated. */
+ bool (*needs_reconfigure)(NetDev *netdev, NetDevLocalAddressType type);
+
/* expected iftype, e.g. ARPHRD_ETHER. */
uint16_t iftype;
@@ -237,6 +242,7 @@ int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
int netdev_generate_hw_addr(NetDev *netdev, Link *link, const char *name,
const struct hw_addr_data *hw_addr, struct hw_addr_data *ret);
+bool netdev_needs_reconfigure(NetDev *netdev, NetDevLocalAddressType type);
int link_request_stacked_netdev(Link *link, NetDev *netdev);
const char* netdev_kind_to_string(NetDevKind d) _const_;
diff --git a/src/network/netdev/tunnel.c b/src/network/netdev/tunnel.c
index 26f7f207da..0339c49c8f 100644
--- a/src/network/netdev/tunnel.c
+++ b/src/network/netdev/tunnel.c
@@ -708,6 +708,14 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
return 0;
}
+static bool tunnel_needs_reconfigure(NetDev *netdev, NetDevLocalAddressType type) {
+ assert(type >= 0 && type < _NETDEV_LOCAL_ADDRESS_TYPE_MAX);
+
+ Tunnel *t = ASSERT_PTR(TUNNEL(netdev));
+
+ return t->local_type == type;
+}
+
static int unset_local(Tunnel *t) {
assert(t);
@@ -1119,6 +1127,7 @@ const NetDevVTable ipip_vtable = {
.create_type = NETDEV_CREATE_STACKED,
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
.config_verify = netdev_tunnel_verify,
+ .needs_reconfigure = tunnel_needs_reconfigure,
.iftype = ARPHRD_TUNNEL,
};
@@ -1130,6 +1139,7 @@ const NetDevVTable sit_vtable = {
.create_type = NETDEV_CREATE_STACKED,
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
.config_verify = netdev_tunnel_verify,
+ .needs_reconfigure = tunnel_needs_reconfigure,
.iftype = ARPHRD_SIT,
};
@@ -1141,6 +1151,7 @@ const NetDevVTable vti_vtable = {
.create_type = NETDEV_CREATE_STACKED,
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
.config_verify = netdev_tunnel_verify,
+ .needs_reconfigure = tunnel_needs_reconfigure,
.iftype = ARPHRD_TUNNEL,
};
@@ -1152,6 +1163,7 @@ const NetDevVTable vti6_vtable = {
.create_type = NETDEV_CREATE_STACKED,
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
.config_verify = netdev_tunnel_verify,
+ .needs_reconfigure = tunnel_needs_reconfigure,
.iftype = ARPHRD_TUNNEL6,
};
@@ -1163,6 +1175,7 @@ const NetDevVTable gre_vtable = {
.create_type = NETDEV_CREATE_STACKED,
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
.config_verify = netdev_tunnel_verify,
+ .needs_reconfigure = tunnel_needs_reconfigure,
.iftype = ARPHRD_IPGRE,
};
@@ -1174,6 +1187,7 @@ const NetDevVTable gretap_vtable = {
.create_type = NETDEV_CREATE_STACKED,
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
.config_verify = netdev_tunnel_verify,
+ .needs_reconfigure = tunnel_needs_reconfigure,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};
@@ -1186,6 +1200,7 @@ const NetDevVTable ip6gre_vtable = {
.create_type = NETDEV_CREATE_STACKED,
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
.config_verify = netdev_tunnel_verify,
+ .needs_reconfigure = tunnel_needs_reconfigure,
.iftype = ARPHRD_IP6GRE,
};
@@ -1197,6 +1212,7 @@ const NetDevVTable ip6gretap_vtable = {
.create_type = NETDEV_CREATE_STACKED,
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
.config_verify = netdev_tunnel_verify,
+ .needs_reconfigure = tunnel_needs_reconfigure,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};
@@ -1209,6 +1225,7 @@ const NetDevVTable ip6tnl_vtable = {
.create_type = NETDEV_CREATE_STACKED,
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
.config_verify = netdev_tunnel_verify,
+ .needs_reconfigure = tunnel_needs_reconfigure,
.iftype = ARPHRD_TUNNEL6,
};
@@ -1220,6 +1237,7 @@ const NetDevVTable erspan_vtable = {
.create_type = NETDEV_CREATE_STACKED,
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
.config_verify = netdev_tunnel_verify,
+ .needs_reconfigure = tunnel_needs_reconfigure,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};
diff --git a/src/network/netdev/vxlan.c b/src/network/netdev/vxlan.c
index 2c4aaecbf0..9f22794d34 100644
--- a/src/network/netdev/vxlan.c
+++ b/src/network/netdev/vxlan.c
@@ -415,6 +415,14 @@ static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
return 0;
}
+static bool vxlan_needs_reconfigure(NetDev *netdev, NetDevLocalAddressType type) {
+ assert(type >= 0 && type < _NETDEV_LOCAL_ADDRESS_TYPE_MAX);
+
+ VxLan *v = VXLAN(netdev);
+
+ return v->local_type == type;
+}
+
static int netdev_vxlan_is_ready_to_create(NetDev *netdev, Link *link) {
VxLan *v = VXLAN(netdev);
@@ -445,6 +453,7 @@ const NetDevVTable vxlan_vtable = {
.is_ready_to_create = netdev_vxlan_is_ready_to_create,
.config_verify = netdev_vxlan_verify,
.can_set_mtu = vxlan_can_set_mtu,
+ .needs_reconfigure = vxlan_needs_reconfigure,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 2dd29bca94..bda3a561d9 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -326,6 +326,10 @@ int dhcp4_check_ready(Link *link) {
if (r < 0)
return r;
+ r = link_request_stacked_netdevs(link, NETDEV_LOCAL_ADDRESS_DHCP4);
+ if (r < 0)
+ return r;
+
r = sd_ipv4ll_stop(link->ipv4ll);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to drop IPv4 link-local address: %m");
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index b49f51f684..1eb5138d5e 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -122,6 +122,10 @@ int dhcp6_check_ready(Link *link) {
if (r < 0)
return r;
+ r = link_request_stacked_netdevs(link, NETDEV_LOCAL_ADDRESS_DHCP6);
+ if (r < 0)
+ return r;
+
link_check_ready(link);
return 0;
}
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index 299aaedd07..ea960593bb 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -109,6 +109,10 @@ static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
log_link_debug(link, "IPv4 link-local claim "IPV4_ADDRESS_FMT_STR,
IPV4_ADDRESS_FMT_VAL(address->in_addr.in));
+ r = link_request_stacked_netdevs(link, NETDEV_LOCAL_ADDRESS_IPV4LL);
+ if (r < 0)
+ return r;
+
return link_request_address(link, address, NULL, ipv4ll_address_handler, NULL);
}
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 4aa24a27e0..be8826b49c 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -640,15 +640,23 @@ static int link_request_static_configs(Link *link) {
return 0;
}
-static int link_request_stacked_netdevs(Link *link) {
+int link_request_stacked_netdevs(Link *link, NetDevLocalAddressType type) {
NetDev *netdev;
int r;
assert(link);
+ if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
+ return 0;
+
+ assert(link->network);
+
link->stacked_netdevs_created = false;
HASHMAP_FOREACH(netdev, link->network->stacked_netdevs) {
+ if (!netdev_needs_reconfigure(netdev, type))
+ continue;
+
r = link_request_stacked_netdev(link, netdev);
if (r < 0)
return r;
@@ -776,6 +784,10 @@ int link_ipv6ll_gained(Link *link) {
if (r < 0)
return r;
+ r = link_request_stacked_netdevs(link, NETDEV_LOCAL_ADDRESS_IPV6LL);
+ if (r < 0)
+ return r;
+
link_check_ready(link);
return 0;
}
@@ -1188,7 +1200,7 @@ static int link_configure(Link *link) {
if (r < 0)
return r;
- r = link_request_stacked_netdevs(link);
+ r = link_request_stacked_netdevs(link, _NETDEV_LOCAL_ADDRESS_TYPE_INVALID);
if (r < 0)
return r;
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index 8ac7c35563..86aba9556b 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -19,6 +19,7 @@
#include "ether-addr-util.h"
#include "log-link.h"
+#include "netdev.h"
#include "netif-util.h"
#include "network-util.h"
#include "networkd-bridge-vlan.h"
@@ -257,6 +258,8 @@ void link_free_engines(Link *link);
const char* link_state_to_string(LinkState s) _const_;
LinkState link_state_from_string(const char *s) _pure_;
+int link_request_stacked_netdevs(Link *link, NetDevLocalAddressType type);
+
int link_reconfigure_impl(Link *link, bool force);
int link_reconfigure(Link *link, bool force);
int link_reconfigure_on_bus_method_reload(Link *link, sd_bus_message *message);
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index 46f3954725..0773e9e8ca 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -2141,6 +2141,8 @@ static int ndisc_drop_outdated(Link *link, const struct in6_addr *router, usec_t
updated = true;
}
+ RET_GATHER(ret, link_request_stacked_netdevs(link, NETDEV_LOCAL_ADDRESS_SLAAC));
+
if (updated)
link_dirty(link);