]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/tunnel: reuse existing 6rd SIT tunnel
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 28 Oct 2024 15:35:27 +0000 (00:35 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 29 Oct 2024 18:17:09 +0000 (03:17 +0900)
The 6rd SIT tunnel configuration can be updated without recreating the
interface. Let's reuse existing tunnel.

src/network/netdev/tunnel.c
src/network/netdev/tunnel.h
src/network/networkd-dhcp-prefix-delegation.c

index 0299aef9eb8f9009cf44eec7fb806e5d3504d1fa..14884555b65944ad582b0e7c8ae9db94351a36f5 100644 (file)
@@ -34,7 +34,7 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_ip6tnl_mode, ip6tnl_mode, Ip6TnlMode);
 
 #define HASH_KEY SD_ID128_MAKE(74,c4,de,12,f3,d9,41,34,bb,3d,c1,a4,42,93,50,87)
 
-int dhcp4_pd_create_6rd_tunnel_name(Link *link, char **ret) {
+static int dhcp4_pd_create_6rd_tunnel_name(Link *link) {
         _cleanup_free_ char *ifname_alloc = NULL;
         uint8_t ipv4masklen, sixrd_prefixlen, *buf, *p;
         struct in_addr ipv4address;
@@ -47,13 +47,16 @@ int dhcp4_pd_create_6rd_tunnel_name(Link *link, char **ret) {
         assert(link);
         assert(link->dhcp_lease);
 
+        if (link->dhcp4_6rd_tunnel_name)
+                return 0; /* Already set. Do not change even if the 6rd option is changed. */
+
         r = sd_dhcp_lease_get_address(link->dhcp_lease, &ipv4address);
         if (r < 0)
-                return log_link_debug_errno(link, r, "Failed to get DHCPv4 address: %m");
+                return r;
 
         r = sd_dhcp_lease_get_6rd(link->dhcp_lease, &ipv4masklen, &sixrd_prefixlen, &sixrd_prefix, NULL, NULL);
         if (r < 0)
-                return log_link_debug_errno(link, r, "Failed to get 6rd option: %m");
+                return r;
 
         sz = sizeof(uint8_t) * 2 + sizeof(struct in6_addr) + sizeof(struct in_addr);
         buf = newa(uint8_t, sz);
@@ -80,9 +83,9 @@ int dhcp4_pd_create_6rd_tunnel_name(Link *link, char **ret) {
 
         ifname_alloc = strdup(ifname);
         if (!ifname_alloc)
-                return log_oom_debug();
+                return -ENOMEM;
 
-        *ret = TAKE_PTR(ifname_alloc);
+        link->dhcp4_6rd_tunnel_name = TAKE_PTR(ifname_alloc);
         return 0;
 }
 
@@ -91,13 +94,13 @@ int dhcp4_pd_create_6rd_tunnel(Link *link, link_netlink_message_handler_t callba
         uint8_t ipv4masklen, sixrd_prefixlen;
         struct in_addr ipv4address;
         struct in6_addr sixrd_prefix;
+        Link *sit = NULL;
         int r;
 
         assert(link);
         assert(link->manager);
         assert(link->manager->rtnl);
         assert(link->dhcp_lease);
-        assert(link->dhcp4_6rd_tunnel_name);
         assert(callback);
 
         r = sd_dhcp_lease_get_address(link->dhcp_lease, &ipv4address);
@@ -108,7 +111,13 @@ int dhcp4_pd_create_6rd_tunnel(Link *link, link_netlink_message_handler_t callba
         if (r < 0)
                 return r;
 
-        r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_NEWLINK, 0);
+        r = dhcp4_pd_create_6rd_tunnel_name(link);
+        if (r < 0)
+                return r;
+
+        (void) link_get_by_name(link->manager, link->dhcp4_6rd_tunnel_name, &sit);
+
+        r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_NEWLINK, sit ? sit->ifindex : 0);
         if (r < 0)
                 return r;
 
@@ -164,7 +173,6 @@ int dhcp4_pd_create_6rd_tunnel(Link *link, link_netlink_message_handler_t callba
                 return r;
 
         link_ref(link);
-
         return 0;
 }
 
index cf26cfad98e9ced9576dfa87f133d459d877bf02..6cd03b032d2195ac20e2ba0b1eacff9825e4be96 100644 (file)
@@ -69,7 +69,6 @@ typedef struct Tunnel {
         uint8_t sixrd_prefixlen;
 } Tunnel;
 
-int dhcp4_pd_create_6rd_tunnel_name(Link *link, char **ret);
 int dhcp4_pd_create_6rd_tunnel(Link *link, link_netlink_message_handler_t callback);
 
 DEFINE_NETDEV_CAST(IPIP, Tunnel);
index 2864c52488ccd91608b72d776a6c64a7efa40709..1f80513007c03b303d020ac28de94a5d6009e4e7 100644 (file)
@@ -961,7 +961,6 @@ static int dhcp4_pd_6rd_tunnel_create_handler(sd_netlink *rtnl, sd_netlink_messa
 }
 
 int dhcp4_pd_prefix_acquired(Link *uplink) {
-        _cleanup_free_ char *tunnel_name = NULL;
         uint8_t ipv4masklen, sixrd_prefixlen, pd_prefixlen;
         struct in6_addr sixrd_prefix, pd_prefix;
         struct in_addr ipv4address;
@@ -1010,28 +1009,10 @@ int dhcp4_pd_prefix_acquired(Link *uplink) {
         if (r < 0)
                 return r;
 
-        /* Generate 6rd SIT tunnel device name. */
-        r = dhcp4_pd_create_6rd_tunnel_name(uplink, &tunnel_name);
+        /* Create or update 6rd SIT tunnel device. */
+        r = dhcp4_pd_create_6rd_tunnel(uplink, dhcp4_pd_6rd_tunnel_create_handler);
         if (r < 0)
-                return r;
-
-        /* Remove old tunnel device if exists. */
-        if (!streq_ptr(uplink->dhcp4_6rd_tunnel_name, tunnel_name)) {
-                Link *old_tunnel;
-
-                if (uplink->dhcp4_6rd_tunnel_name &&
-                    link_get_by_name(uplink->manager, uplink->dhcp4_6rd_tunnel_name, &old_tunnel) >= 0)
-                        (void) link_remove(old_tunnel);
-
-                free_and_replace(uplink->dhcp4_6rd_tunnel_name, tunnel_name);
-        }
-
-        /* Create 6rd SIT tunnel device if it does not exist yet. */
-        if (link_get_by_name(uplink->manager, uplink->dhcp4_6rd_tunnel_name, NULL) < 0) {
-                r = dhcp4_pd_create_6rd_tunnel(uplink, dhcp4_pd_6rd_tunnel_create_handler);
-                if (r < 0)
-                        return log_link_warning_errno(uplink, r, "Failed to create 6rd SIT tunnel: %m");
-        }
+                return log_link_warning_errno(uplink, r, "Failed to create or update 6rd SIT tunnel: %m");
 
         /* Then, assign subnet prefixes to downstream interfaces. */
         HASHMAP_FOREACH(link, uplink->manager->links_by_index) {