diff --git a/src/core/nm-l3-config-data.c b/src/core/nm-l3-config-data.c index 8d1d6ec926..b2996e1c52 100644 --- a/src/core/nm-l3-config-data.c +++ b/src/core/nm-l3-config-data.c @@ -125,8 +125,18 @@ struct _NML3ConfigData { NMSettingConnectionDnsOverTls dns_over_tls; NMSettingConnectionDnssec dnssec; NMUtilsIPv6IfaceId ip6_token; - NMSettingIp4ConfigClat clat; NMRefString *network_id; + NMSettingIp4ConfigClat clat; /* this indicates the 'administrative' CLAT state, i.e. whether + * CLAT will be started once we receive a PREF64 */ + + /* The runtime CLAT state */ + struct { + struct in6_addr ip6; + struct in6_addr pref64; + in_addr_t ip4; + guint8 pref64_plen; + bool enabled; + } clat_state; NML3ConfigDatFlags flags; @@ -535,6 +545,14 @@ nm_l3_config_data_log(const NML3ConfigData *self, _L("clat: auto"); else if (self->clat == NM_SETTING_IP4_CONFIG_CLAT_FORCE) _L("clat: force"); + + if (self->clat_state.enabled) { + _L("clat-state: ip4=%s/32, pref64=%s/%u, ip6=%s/64", + nm_inet4_ntop(self->clat_state.ip4, sbuf + NM_INET_ADDRSTRLEN), + nm_inet6_ntop(&self->clat_state.pref64, sbuf), + self->clat_state.pref64_plen, + nm_inet6_ntop(&self->clat_state.ip6, sbuf_addr)); + } } if (!IS_IPv4 && self->pref64_valid) { @@ -2047,6 +2065,46 @@ nm_l3_config_data_get_clat(const NML3ConfigData *self) return self->clat; } +gboolean +nm_l3_config_data_get_clat_state(const NML3ConfigData *self, + struct in6_addr *out_ip6, + struct in6_addr *out_pref64, + guint8 *out_pref64_plen, + in_addr_t *out_ip4) +{ + if (!self || !self->clat_state.enabled) + return FALSE; + NM_SET_OUT(out_ip6, self->clat_state.ip6); + NM_SET_OUT(out_pref64, self->clat_state.pref64); + NM_SET_OUT(out_pref64_plen, self->clat_state.pref64_plen); + NM_SET_OUT(out_ip4, self->clat_state.ip4); + return TRUE; +} + +void +nm_l3_config_data_set_clat_state(NML3ConfigData *self, + gboolean enabled, + const struct in6_addr *ip6, + const struct in6_addr *pref64, + guint8 pref64_plen, + in_addr_t ip4) +{ + nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE)); + + self->clat_state.enabled = enabled; + if (enabled) { + self->clat_state.ip6 = *ip6; + self->clat_state.pref64 = *pref64; + self->clat_state.pref64_plen = pref64_plen; + self->clat_state.ip4 = ip4; + } else { + self->clat_state.ip6 = in6addr_any; + self->clat_state.pref64 = in6addr_any; + self->clat_state.pref64_plen = 0; + self->clat_state.ip4 = 0; + } +} + gboolean nm_l3_config_data_set_pref64_valid(NML3ConfigData *self, gboolean val) { @@ -2650,6 +2708,14 @@ nm_l3_config_data_cmp_full(const NML3ConfigData *a, NM_CMP_DIRECT_UNSAFE(a->clat, b->clat); + NM_CMP_DIRECT(!!a->clat_state.enabled, !!b->clat_state.enabled); + if (a->clat_state.enabled) { + NM_CMP_DIRECT_IN6ADDR(&a->clat_state.ip6, &b->clat_state.ip6); + NM_CMP_DIRECT_IN6ADDR(&a->clat_state.pref64, &b->clat_state.pref64); + NM_CMP_DIRECT(a->clat_state.pref64_plen, b->clat_state.pref64_plen); + NM_CMP_DIRECT(a->clat_state.ip4, b->clat_state.ip4); + } + NM_CMP_DIRECT(!!a->pref64_valid, !!b->pref64_valid); if (a->pref64_valid) { NM_CMP_DIRECT(a->pref64_plen, b->pref64_plen); @@ -3735,6 +3801,10 @@ nm_l3_config_data_merge(NML3ConfigData *self, self->clat = src->clat; } + if (!self->clat_state.enabled && src->clat_state.enabled) { + self->clat_state = src->clat_state; + } + 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 5fbc6c7b03..cc340f9d3d 100644 --- a/src/core/nm-l3-config-data.h +++ b/src/core/nm-l3-config-data.h @@ -507,6 +507,19 @@ gboolean nm_l3_config_data_set_clat(NML3ConfigData *self, NMSettingIp4ConfigClat NMSettingIp4ConfigClat nm_l3_config_data_get_clat(const NML3ConfigData *self); +gboolean nm_l3_config_data_get_clat_state(const NML3ConfigData *self, + struct in6_addr *out_ip6, + struct in6_addr *out_pref64, + guint8 *out_pref64_plen, + in_addr_t *out_ip4); + +void nm_l3_config_data_set_clat_state(NML3ConfigData *self, + gboolean enabled, + const struct in6_addr *ip6, + const struct in6_addr *pref64, + guint8 pref64_plen, + in_addr_t ip4); + gboolean nm_l3_config_data_set_pref64_valid(NML3ConfigData *self, gboolean val); gboolean nm_l3_config_data_get_pref64_valid(const NML3ConfigData *self);