mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-27 02:20:31 +01:00
cloud-setup: add initial ipv6 support
Adds support for configuring IPv6 addresses via providers. Currently, all nm-c-s IPv6 addresses are set with a /128 prefix.
This commit is contained in:
parent
03f30ac5cf
commit
b44ec3f19d
7 changed files with 91 additions and 31 deletions
|
|
@ -396,14 +396,18 @@ _nmc_mangle_connection(NMDevice *device,
|
|||
gboolean *out_changed)
|
||||
{
|
||||
NMSettingIPConfig *s_ip;
|
||||
NMSettingIPConfig *s_ip6;
|
||||
NMActiveConnection *ac;
|
||||
NMConnection *remote_connection;
|
||||
NMSettingIPConfig *remote_s_ip = NULL;
|
||||
NMSettingIPConfig *remote_s_ip = NULL;
|
||||
NMSettingIPConfig *remote_s_ip6 = NULL;
|
||||
gsize i;
|
||||
gboolean addrs_changed = FALSE;
|
||||
gboolean addr6s_changed = FALSE;
|
||||
gboolean rules_changed = FALSE;
|
||||
gboolean routes_changed = FALSE;
|
||||
gs_unref_ptrarray GPtrArray *addrs_new = NULL;
|
||||
gs_unref_ptrarray GPtrArray *addr6s_new = NULL;
|
||||
gs_unref_ptrarray GPtrArray *rules_new = NULL;
|
||||
gs_unref_ptrarray GPtrArray *routes_new = NULL;
|
||||
|
||||
|
|
@ -418,15 +422,19 @@ _nmc_mangle_connection(NMDevice *device,
|
|||
/* Preserve existing L3 configuration if not a VLAN */
|
||||
if (device) {
|
||||
if ((ac = nm_device_get_active_connection(device))
|
||||
&& (remote_connection = NM_CONNECTION(nm_active_connection_get_connection(ac))))
|
||||
remote_s_ip = nm_connection_get_setting_ip4_config(remote_connection);
|
||||
&& (remote_connection = NM_CONNECTION(nm_active_connection_get_connection(ac)))) {
|
||||
remote_s_ip = nm_connection_get_setting_ip4_config(remote_connection);
|
||||
remote_s_ip6 = nm_connection_get_setting_ip6_config(remote_connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s_ip = nm_connection_get_setting_ip4_config(connection);
|
||||
nm_assert(NM_IS_SETTING_IP4_CONFIG(s_ip));
|
||||
s_ip = nm_connection_get_setting_ip4_config(connection);
|
||||
s_ip6 = nm_connection_get_setting_ip6_config(connection);
|
||||
|
||||
addrs_new = g_ptr_array_new_full(config_data->ipv4s_len, (GDestroyNotify) nm_ip_address_unref);
|
||||
addr6s_new = g_ptr_array_new_full(config_data->ipv6s_len, (GDestroyNotify) nm_ip_address_unref);
|
||||
|
||||
addrs_new = g_ptr_array_new_full(config_data->ipv4s_len, (GDestroyNotify) nm_ip_address_unref);
|
||||
rules_new =
|
||||
g_ptr_array_new_full(config_data->ipv4s_len, (GDestroyNotify) nm_ip_routing_rule_unref);
|
||||
routes_new =
|
||||
|
|
@ -457,8 +465,16 @@ _nmc_mangle_connection(NMDevice *device,
|
|||
}
|
||||
}
|
||||
|
||||
if (result->num_valid_ifaces <= 1 && result->num_ipv4s <= 1) {
|
||||
/* this setup only has one interface and one IPv4 address (or less).
|
||||
if (remote_s_ip6) {
|
||||
guint len = nm_setting_ip_config_get_num_addresses(remote_s_ip6);
|
||||
for (int j = 0; j < len; j++) {
|
||||
g_ptr_array_add(addr6s_new,
|
||||
nm_ip_address_dup(nm_setting_ip_config_get_address(remote_s_ip6, j)));
|
||||
}
|
||||
}
|
||||
|
||||
if (result->num_valid_ifaces <= 1 && (result->num_ipv4s + result->num_ipv6s) <= 1) {
|
||||
/* this setup only has one interface and one IP address (or less).
|
||||
* We don't need to configure policy routing in this case. */
|
||||
NM_SET_OUT(out_skipped_single_addr, TRUE);
|
||||
} else if (config_data->has_ipv4s && config_data->has_cidr) {
|
||||
|
|
@ -537,22 +553,50 @@ _nmc_mangle_connection(NMDevice *device,
|
|||
}
|
||||
}
|
||||
|
||||
if (config_data->has_ipv6s) {
|
||||
NMIPAddress *addr_entry;
|
||||
|
||||
for (i = 0; i < config_data->ipv6s_len; i++) {
|
||||
addr_entry = nm_ip_address_new_binary(AF_INET6, &config_data->ipv6s_arr[i], 128, NULL);
|
||||
nm_assert(addr_entry);
|
||||
g_ptr_array_add(addr6s_new, addr_entry);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nm_g_ptr_array_len(config_data->iproutes); i++)
|
||||
g_ptr_array_add(routes_new, _nm_ip_route_ref(config_data->iproutes->pdata[i]));
|
||||
|
||||
addrs_changed = nmcs_setting_ip_replace_ipv4_addresses(s_ip,
|
||||
(NMIPAddress **) addrs_new->pdata,
|
||||
addrs_new->len);
|
||||
if (s_ip) {
|
||||
addrs_changed = nmcs_setting_ip_replace_ip_addresses(s_ip,
|
||||
(NMIPAddress **) addrs_new->pdata,
|
||||
addrs_new->len);
|
||||
|
||||
routes_changed = nmcs_setting_ip_replace_ipv4_routes(s_ip,
|
||||
(NMIPRoute **) routes_new->pdata,
|
||||
routes_new->len);
|
||||
routes_changed = nmcs_setting_ip_replace_ipv4_routes(s_ip,
|
||||
(NMIPRoute **) routes_new->pdata,
|
||||
routes_new->len);
|
||||
|
||||
rules_changed = nmcs_setting_ip_replace_ipv4_rules(s_ip,
|
||||
(NMIPRoutingRule **) rules_new->pdata,
|
||||
rules_new->len);
|
||||
rules_changed = nmcs_setting_ip_replace_ipv4_rules(s_ip,
|
||||
(NMIPRoutingRule **) rules_new->pdata,
|
||||
rules_new->len);
|
||||
}
|
||||
|
||||
NM_SET_OUT(out_changed, addrs_changed || routes_changed || rules_changed);
|
||||
if (s_ip6) {
|
||||
const char *method = nm_setting_ip_config_get_method(s_ip6);
|
||||
if (NM_IN_STRSET(method,
|
||||
NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
|
||||
NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) {
|
||||
g_object_set(s_ip6,
|
||||
NM_SETTING_IP_CONFIG_METHOD,
|
||||
NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
addr6s_changed = nmcs_setting_ip_replace_ip_addresses(s_ip6,
|
||||
(NMIPAddress **) addr6s_new->pdata,
|
||||
addr6s_new->len);
|
||||
}
|
||||
|
||||
NM_SET_OUT(out_changed, addrs_changed || addr6s_changed || routes_changed || rules_changed);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -612,9 +656,9 @@ try_again:
|
|||
return any_changes;
|
||||
}
|
||||
|
||||
if (!nm_connection_get_setting_ip4_config(applied_connection)) {
|
||||
_LOGD("config device %s: skip applied connection due to missing IPv4 configuration",
|
||||
hwaddr);
|
||||
if (!nm_connection_get_setting_ip4_config(applied_connection)
|
||||
&& !nm_connection_get_setting_ip6_config(applied_connection)) {
|
||||
_LOGD("config device %s: skip applied connection due to missing IP configuration", hwaddr);
|
||||
return any_changes;
|
||||
}
|
||||
|
||||
|
|
@ -739,7 +783,11 @@ _config_ethernet(SigTermData *sigterm_data,
|
|||
NM_SETTING_IP_CONFIG_METHOD,
|
||||
NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
|
||||
NULL));
|
||||
|
||||
nm_connection_add_setting(connection,
|
||||
g_object_new(NM_TYPE_SETTING_IP6_CONFIG,
|
||||
NM_SETTING_IP_CONFIG_METHOD,
|
||||
NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
|
||||
NULL));
|
||||
nm_connection_add_setting(connection,
|
||||
g_object_new(NM_TYPE_SETTING_WIRED,
|
||||
NM_SETTING_WIRED_MAC_ADDRESS,
|
||||
|
|
|
|||
|
|
@ -367,9 +367,9 @@ nmcs_utils_uri_complete_interned(const char *uri)
|
|||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nmcs_setting_ip_replace_ipv4_addresses(NMSettingIPConfig *s_ip,
|
||||
NMIPAddress **entries_arr,
|
||||
guint entries_len)
|
||||
nmcs_setting_ip_replace_ip_addresses(NMSettingIPConfig *s_ip,
|
||||
NMIPAddress **entries_arr,
|
||||
guint entries_len)
|
||||
{
|
||||
gboolean any_changes = FALSE;
|
||||
guint i_next;
|
||||
|
|
|
|||
|
|
@ -135,9 +135,9 @@ const char *nmcs_utils_uri_complete_interned(const char *uri);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean nmcs_setting_ip_replace_ipv4_addresses(NMSettingIPConfig *s_ip,
|
||||
NMIPAddress **entries_arr,
|
||||
guint entries_len);
|
||||
gboolean nmcs_setting_ip_replace_ip_addresses(NMSettingIPConfig *s_ip,
|
||||
NMIPAddress **entries_arr,
|
||||
guint entries_len);
|
||||
|
||||
gboolean nmcs_setting_ip_replace_ipv4_routes(NMSettingIPConfig *s_ip,
|
||||
NMIPRoute **entries_arr,
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ nmcs_provider_get_config_result_new(GHashTable *iface_datas)
|
|||
GHashTableIter h_iter;
|
||||
guint num_valid_ifaces = 0;
|
||||
guint num_ipv4s = 0;
|
||||
guint num_ipv6s = 0;
|
||||
GPtrArray *ptrarr;
|
||||
guint n_iface_datas;
|
||||
|
||||
|
|
@ -86,6 +87,7 @@ nmcs_provider_get_config_result_new(GHashTable *iface_datas)
|
|||
if (nmcs_provider_get_config_iface_data_is_valid(iface_data)) {
|
||||
num_valid_ifaces++;
|
||||
num_ipv4s += iface_data->ipv4s_len;
|
||||
num_ipv6s += iface_data->ipv6s_len;
|
||||
}
|
||||
g_ptr_array_add(ptrarr, (gpointer) iface_data);
|
||||
}
|
||||
|
|
@ -104,6 +106,7 @@ nmcs_provider_get_config_result_new(GHashTable *iface_datas)
|
|||
(const NMCSProviderGetConfigIfaceData **) g_ptr_array_free(ptrarr, FALSE),
|
||||
.num_valid_ifaces = num_valid_ifaces,
|
||||
.num_ipv4s = num_ipv4s,
|
||||
.num_ipv6s = num_ipv6s,
|
||||
};
|
||||
|
||||
#if NM_MORE_ASSERTS > 5
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ typedef struct {
|
|||
in_addr_t *ipv4s_arr;
|
||||
gsize ipv4s_len;
|
||||
|
||||
struct in6_addr *ipv6s_arr;
|
||||
gsize ipv6s_len;
|
||||
|
||||
/* If the interface was seen, get_config() should set this to a
|
||||
* unique, increasing, positive index. If the interface is requested,
|
||||
* it is initialized to -1. */
|
||||
|
|
@ -33,6 +36,7 @@ typedef struct {
|
|||
in_addr_t gateway;
|
||||
guint8 cidr_prefix;
|
||||
bool has_ipv4s : 1;
|
||||
bool has_ipv6s : 1;
|
||||
bool has_cidr : 1;
|
||||
bool has_gateway : 1;
|
||||
|
||||
|
|
@ -65,7 +69,7 @@ static inline gboolean
|
|||
nmcs_provider_get_config_iface_data_is_valid(const NMCSProviderGetConfigIfaceData *config_data)
|
||||
{
|
||||
return config_data && config_data->iface_idx >= 0
|
||||
&& ((config_data->has_ipv4s && config_data->has_cidr)
|
||||
&& ((config_data->has_ipv4s && config_data->has_cidr) || config_data->has_ipv6s
|
||||
|| nm_g_ptr_array_len(config_data->iproutes) > 0);
|
||||
}
|
||||
|
||||
|
|
@ -83,6 +87,7 @@ typedef struct {
|
|||
|
||||
/* the number of IPv4 addresses over all valid iface_datas. */
|
||||
guint num_ipv4s;
|
||||
guint num_ipv6s;
|
||||
|
||||
guint n_iface_datas;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ _test_ri4a(const char *const *addrs_before, const char *const *addrs_new)
|
|||
NM_PTRARRAY_LEN(addrs_before));
|
||||
g_assert_cmpint(arr->len, ==, n);
|
||||
|
||||
changed = nmcs_setting_ip_replace_ipv4_addresses(s_ip, (NMIPAddress **) arr->pdata, arr->len);
|
||||
changed = nmcs_setting_ip_replace_ip_addresses(s_ip, (NMIPAddress **) arr->pdata, arr->len);
|
||||
|
||||
g_assert_cmpint(changed, !=, nm_strv_equal(addrs_before, addrs_new));
|
||||
g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip), ==, n);
|
||||
|
|
|
|||
|
|
@ -2382,6 +2382,9 @@ class TestNmCloudSetup(unittest.TestCase):
|
|||
_ip1 = "172.31.26.249"
|
||||
_ip2 = "172.31.176.249"
|
||||
|
||||
_ip6_1 = "2001:db8:abab:abab:abab::"
|
||||
_ip6_2 = "2001:db8:cdcd:cdcd:cdcd::"
|
||||
|
||||
def cloud_setup_test(func):
|
||||
"""
|
||||
Runs the mock NetworkManager along with a mock cloud metadata service.
|
||||
|
|
@ -2449,11 +2452,12 @@ class TestNmCloudSetup(unittest.TestCase):
|
|||
self.ctx.srv.op_AddObj("WiredDevice", iface="eth1", mac=self._mac2)
|
||||
|
||||
def _mock_connection1(self):
|
||||
# Active connection that has IPv4 configured for device1
|
||||
# Active connection that has IPv4 and IPv6 configured for device1
|
||||
self.ctx.srv.addAndActivateConnection(
|
||||
{
|
||||
"connection": {"type": "802-3-ethernet", "id": "con-eth0"},
|
||||
"ipv4": {"method": "auto"},
|
||||
"ipv6": {"method": "auto"},
|
||||
},
|
||||
"/org/freedesktop/NetworkManager/Devices/1",
|
||||
delay=0,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue