diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 3f9aec790b..e32e820a21 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -1017,6 +1017,10 @@ ipv6.ip6-privacy=0
global default is used. If the default is unspecified, the fallback value is either "stable-privacy"
or "eui64", depending on whether the per-profile setting is "default" or "default-or-eui64, respectively.
+
+ ipv6.clat
+ If left unspecified, CLAT is disabled.
+
ipv6.ra-timeout
If left unspecified, the default value depends on the sysctl solicitation settings.
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 2c154b3256..d9153f0b7c 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -1494,6 +1494,28 @@ _prop_get_connection_dns_over_tls(NMDevice *self)
NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT);
}
+static NMSettingIp6ConfigClat
+_prop_get_ipv6_clat(NMDevice *self)
+{
+ NMSettingIP6Config *s_ip6;
+ NMSettingIp6ConfigClat clat;
+
+ s_ip6 = nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP6_CONFIG);
+ if (!s_ip6)
+ return FALSE;
+
+ clat = nm_setting_ip6_config_get_clat(s_ip6);
+ if (clat != NM_SETTING_IP6_CONFIG_CLAT_DEFAULT)
+ return clat;
+
+ return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
+ NM_CON_DEFAULT("ipv6.clat"),
+ self,
+ NM_SETTING_IP6_CONFIG_CLAT_NO,
+ NM_SETTING_IP6_CONFIG_CLAT_YES,
+ NM_SETTING_IP6_CONFIG_CLAT_NO);
+}
+
static NMMptcpFlags
_prop_get_connection_mptcp_flags(NMDevice *self)
{
@@ -3615,6 +3637,7 @@ nm_device_create_l3_config_data_from_connection(NMDevice *self, NMConnection *co
nm_l3_config_data_set_dns_over_tls(l3cd, _prop_get_connection_dns_over_tls(self));
nm_l3_config_data_set_ip6_privacy(l3cd, _prop_get_ipv6_ip6_privacy(self));
nm_l3_config_data_set_mptcp_flags(l3cd, _prop_get_connection_mptcp_flags(self));
+ nm_l3_config_data_set_clat(l3cd, _prop_get_ipv6_clat(self));
return l3cd;
}
diff --git a/src/core/nm-l3-config-data.c b/src/core/nm-l3-config-data.c
index 996590f407..a241f74d4b 100644
--- a/src/core/nm-l3-config-data.c
+++ b/src/core/nm-l3-config-data.c
@@ -171,6 +171,7 @@ struct _NML3ConfigData {
bool routed_dns_4 : 1;
bool routed_dns_6 : 1;
+ bool clat : 1;
bool pref64_valid : 1;
};
@@ -524,6 +525,10 @@ nm_l3_config_data_log(const NML3ConfigData *self,
_L("nis-domain: %s", self->nis_domain->str);
}
+ if (!IS_IPv4 && self->clat) {
+ _L("clat: yes");
+ }
+
if (!IS_IPv4 && self->pref64_valid) {
_L("pref64_prefix: %s/%d",
nm_utils_inet6_ntop(&self->pref64_prefix, sbuf_addr),
@@ -1959,6 +1964,23 @@ nm_l3_config_data_set_network_id(NML3ConfigData *self, const char *value)
return nm_ref_string_reset_str(&self->network_id, value);
}
+gboolean
+nm_l3_config_data_set_clat(NML3ConfigData *self, gboolean val)
+{
+ if (self->clat == val)
+ return FALSE;
+ self->clat = val;
+ return TRUE;
+}
+
+gboolean
+nm_l3_config_data_get_clat(const NML3ConfigData *self)
+{
+ nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
+
+ return self->clat;
+}
+
gboolean
nm_l3_config_data_set_pref64_valid(NML3ConfigData *self, gboolean val)
{
@@ -2558,6 +2580,8 @@ nm_l3_config_data_cmp_full(const NML3ConfigData *a,
NM_CMP_DIRECT_UNSAFE(a->routed_dns_4, b->routed_dns_4);
NM_CMP_DIRECT_UNSAFE(a->routed_dns_6, b->routed_dns_6);
+ NM_CMP_DIRECT_UNSAFE(a->clat, b->clat);
+
NM_CMP_DIRECT(!!a->pref64_valid, !!b->pref64_valid);
if (a->pref64_valid) {
NM_CMP_DIRECT(a->pref64_plen, b->pref64_plen);
@@ -3620,6 +3644,9 @@ nm_l3_config_data_merge(NML3ConfigData *self,
if (src->routed_dns_6)
self->routed_dns_6 = TRUE;
+ if (src->clat)
+ self->clat = TRUE;
+
if (src->pref64_valid) {
self->pref64_prefix = src->pref64_prefix;
self->pref64_plen = src->pref64_plen;
diff --git a/src/core/nm-l3-config-data.h b/src/core/nm-l3-config-data.h
index 64ddc6484c..4db7c32347 100644
--- a/src/core/nm-l3-config-data.h
+++ b/src/core/nm-l3-config-data.h
@@ -494,6 +494,10 @@ gboolean nm_l3_config_data_set_network_id(NML3ConfigData *self, const char *netw
const char *nm_l3_config_data_get_network_id(const NML3ConfigData *self);
+gboolean nm_l3_config_data_set_clat(NML3ConfigData *self, gboolean val);
+
+gboolean nm_l3_config_data_get_clat(const NML3ConfigData *self);
+
gboolean nm_l3_config_data_set_pref64_valid(NML3ConfigData *self, gboolean val);
gboolean nm_l3_config_data_get_pref64_valid(const NML3ConfigData *self);
diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c
index 3ee6dacf7e..5f3c106982 100644
--- a/src/core/nm-l3cfg.c
+++ b/src/core/nm-l3cfg.c
@@ -4258,7 +4258,7 @@ _l3cfg_update_combined_config(NML3Cfg *self,
}
#if HAVE_CLAT
- if (nm_l3_config_data_get_pref64_valid(l3cd)) {
+ if (nm_l3_config_data_get_clat(l3cd) && nm_l3_config_data_get_pref64_valid(l3cd)) {
NMPlatformIPXRoute rx;
NMIPAddrTyped best_v6_gateway;
NMDedupMultiIter iter;