]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: update tunnel or vxlan interface if the local address is changed
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 28 Oct 2024 16:23:54 +0000 (01:23 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 31 Oct 2024 09:41:44 +0000 (18:41 +0900)
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.

src/network/netdev/netdev.c
src/network/netdev/netdev.h
src/network/netdev/tunnel.c
src/network/netdev/vxlan.c
src/network/networkd-dhcp4.c
src/network/networkd-dhcp6.c
src/network/networkd-ipv4ll.c
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-ndisc.c

index 1e046397d502e208faf3cdfceb78e9dcb94e63b7..85760c741d02df2f2ac92a7f5fccdd878053a7a5 100644 (file)
@@ -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;
index 106f47acadad0c20993487d880d2d3d9d65bdb6e..765496d04471f831c84ddafac60704b9c2693f48 100644 (file)
@@ -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_;
index 26f7f207da1e832f9d8c2cdc35e36bb665b0386b..0339c49c8fac36daa993cc3dd90fd4756f011738 100644 (file)
@@ -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,
 };
index 2c4aaecbf0c1586e7ae1e13fbc810cad0c6b9362..9f22794d34880077911203aa03ffe0542119d95a 100644 (file)
@@ -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,
 };
index 2dd29bca948636b8067e7253e5a0e82682fcf71b..bda3a561d940d521d6be5bf951ef885c4d97c2a9 100644 (file)
@@ -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");
index b49f51f68439f63943f029284ea1a8403b488209..1eb5138d5e015b8a1e3808c40022a698cae495e8 100644 (file)
@@ -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;
 }
index 299aaedd070a66da4c410f78f0853764ca482ccb..ea960593bbce1000234fb96916c9cda9e486d1ba 100644 (file)
@@ -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);
 }
 
index 4aa24a27e0bccb46e2e4c88a9a608cc0dc8e7ac5..be8826b49c5b8656e36d5696ccdfec62f1071d4e 100644 (file)
@@ -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;
 
index 8ac7c3556324e4ea77cbfe3c0a820493a73734f3..86aba9556bdc44f9376be2936971b6d04da61298 100644 (file)
@@ -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);
index 46f39547254c3e33272e0ce6038bcbdd1b2e5dd0..0773e9e8ca8fac2ee91e640bb49f443c9422ac7a 100644 (file)
@@ -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);