From d2524514827f67b6e5e8d9028bb25089f3d0f048 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 29 Oct 2024 00:35:27 +0900 Subject: [PATCH] network/tunnel: reuse existing 6rd SIT tunnel The 6rd SIT tunnel configuration can be updated without recreating the interface. Let's reuse existing tunnel. --- src/network/netdev/tunnel.c | 24 ++++++++++++------ src/network/netdev/tunnel.h | 1 - src/network/networkd-dhcp-prefix-delegation.c | 25 +++---------------- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/network/netdev/tunnel.c b/src/network/netdev/tunnel.c index 0299aef9eb8..14884555b65 100644 --- a/src/network/netdev/tunnel.c +++ b/src/network/netdev/tunnel.c @@ -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; } diff --git a/src/network/netdev/tunnel.h b/src/network/netdev/tunnel.h index cf26cfad98e..6cd03b032d2 100644 --- a/src/network/netdev/tunnel.h +++ b/src/network/netdev/tunnel.h @@ -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); diff --git a/src/network/networkd-dhcp-prefix-delegation.c b/src/network/networkd-dhcp-prefix-delegation.c index 2864c52488c..1f80513007c 100644 --- a/src/network/networkd-dhcp-prefix-delegation.c +++ b/src/network/networkd-dhcp-prefix-delegation.c @@ -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) { -- 2.47.3