From 75a84677caab9161e3b347ddc20a4b387873d048 Mon Sep 17 00:00:00 2001 From: Antonio Cardace Date: Thu, 18 Jun 2020 18:11:41 +0200 Subject: nmcs-main: support adding additional routes This allows a provider to only add additional routes to the applied profile https://bugzilla.redhat.com/show_bug.cgi?id=1821787 --- clients/cloud-setup/main.c | 127 +++++++++++++++++++++--------------- clients/cloud-setup/nmcs-provider.c | 1 + clients/cloud-setup/nmcs-provider.h | 8 ++- 3 files changed, 80 insertions(+), 56 deletions(-) diff --git a/clients/cloud-setup/main.c b/clients/cloud-setup/main.c index b89943c61c..ad3a47cbe0 100644 --- a/clients/cloud-setup/main.c +++ b/clients/cloud-setup/main.c @@ -280,16 +280,17 @@ _nmc_mangle_connection (NMDevice *device, gboolean *out_changed) { NMSettingIPConfig *s_ip; - gboolean addrs_changed; - gboolean routes_changed; - gboolean rules_changed; gsize i; in_addr_t gateway; gint64 rt_metric; guint32 rt_table; + NMIPRoute *route_entry; + gboolean addrs_changed = FALSE; + gboolean rules_changed = FALSE; + gboolean routes_changed = FALSE; gs_unref_ptrarray GPtrArray *addrs_new = NULL; gs_unref_ptrarray GPtrArray *rules_new = NULL; - nm_auto_unref_ip_route NMIPRoute *route_new = NULL; + gs_unref_ptrarray GPtrArray *routes_new = NULL; if (!nm_streq0 (nm_connection_get_connection_type (connection), NM_SETTING_WIRED_SETTING_NAME)) return FALSE; @@ -298,62 +299,80 @@ _nmc_mangle_connection (NMDevice *device, if (!s_ip) return FALSE; - addrs_new = g_ptr_array_new_full (config_data->ipv4s_len, (GDestroyNotify) nm_ip_address_unref); - for (i = 0; i < config_data->ipv4s_len; i++) { - NMIPAddress *entry; + 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 = g_ptr_array_new_full (config_data->iproutes_len + !!config_data->ipv4s_len, + (GDestroyNotify) nm_ip_route_unref); + + if ( config_data->has_ipv4s + && config_data->has_cidr) { + for (i = 0; i < config_data->ipv4s_len; i++) { + NMIPAddress *entry; + + entry = nm_ip_address_new_binary (AF_INET, + &config_data->ipv4s_arr[i], + config_data->cidr_prefix, + NULL); + if (entry) + g_ptr_array_add (addrs_new, entry); + } - entry = nm_ip_address_new_binary (AF_INET, - &config_data->ipv4s_arr[i], - config_data->cidr_prefix, - NULL); - if (entry) - g_ptr_array_add (addrs_new, entry); + gateway = nm_utils_ip4_address_clear_host_address (config_data->cidr_addr, config_data->cidr_prefix); + ((guint8 *) &gateway)[3] += 1; + + rt_metric = 10; + rt_table = 30400 + config_data->iface_idx; + + route_entry = nm_ip_route_new_binary (AF_INET, + &nm_ip_addr_zero, + 0, + &gateway, + rt_metric, + NULL); + nm_ip_route_set_attribute (route_entry, + NM_IP_ROUTE_ATTRIBUTE_TABLE, + g_variant_new_uint32 (rt_table)); + g_ptr_array_add (routes_new, route_entry); + + for (i = 0; i < config_data->ipv4s_len; i++) { + NMIPRoutingRule *entry; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + entry = nm_ip_routing_rule_new (AF_INET); + nm_ip_routing_rule_set_priority (entry, rt_table); + nm_ip_routing_rule_set_from (entry, + _nm_utils_inet4_ntop (config_data->ipv4s_arr[i], sbuf), + 32); + nm_ip_routing_rule_set_table (entry, rt_table); + + nm_assert (nm_ip_routing_rule_validate (entry, NULL)); + + g_ptr_array_add (rules_new, entry); + } } - gateway = nm_utils_ip4_address_clear_host_address (config_data->cidr_addr, config_data->cidr_prefix); - ((guint8 *) &gateway)[3] += 1; - - rt_metric = 10; - rt_table = 30400 + config_data->iface_idx; - - route_new = nm_ip_route_new_binary (AF_INET, - &nm_ip_addr_zero, - 0, - &gateway, - rt_metric, - NULL); - nm_ip_route_set_attribute (route_new, - NM_IP_ROUTE_ATTRIBUTE_TABLE, - g_variant_new_uint32 (rt_table)); - - rules_new = g_ptr_array_new_full (config_data->ipv4s_len, (GDestroyNotify) nm_ip_routing_rule_unref); - for (i = 0; i < config_data->ipv4s_len; i++) { - NMIPRoutingRule *entry; - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - entry = nm_ip_routing_rule_new (AF_INET); - nm_ip_routing_rule_set_priority (entry, rt_table); - nm_ip_routing_rule_set_from (entry, - _nm_utils_inet4_ntop (config_data->ipv4s_arr[i], sbuf), - 32); - nm_ip_routing_rule_set_table (entry, rt_table); - - nm_assert (nm_ip_routing_rule_validate (entry, NULL)); - - g_ptr_array_add (rules_new, entry); - } + for (i = 0; i < config_data->iproutes_len; ++i) + g_ptr_array_add (routes_new, config_data->iproutes_arr[i]); - addrs_changed = nmcs_setting_ip_replace_ipv4_addresses (s_ip, - (NMIPAddress **) addrs_new->pdata, - addrs_new->len); + if (addrs_new->len) { + addrs_changed = nmcs_setting_ip_replace_ipv4_addresses (s_ip, + (NMIPAddress **) addrs_new->pdata, + addrs_new->len); + } - routes_changed = nmcs_setting_ip_replace_ipv4_routes (s_ip, - &route_new, - 1); + if (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); + if (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 diff --git a/clients/cloud-setup/nmcs-provider.c b/clients/cloud-setup/nmcs-provider.c index 1f1b6e600d..bc21d8769e 100644 --- a/clients/cloud-setup/nmcs-provider.c +++ b/clients/cloud-setup/nmcs-provider.c @@ -114,6 +114,7 @@ _iface_data_free (gpointer data) NMCSProviderGetConfigIfaceData *iface_data = data; g_free (iface_data->ipv4s_arr); + g_free (iface_data->iproutes_arr); nm_g_slice_free (iface_data); } diff --git a/clients/cloud-setup/nmcs-provider.h b/clients/cloud-setup/nmcs-provider.h index e5a44da19f..e5950f930e 100644 --- a/clients/cloud-setup/nmcs-provider.h +++ b/clients/cloud-setup/nmcs-provider.h @@ -18,6 +18,9 @@ typedef struct { bool has_ipv4s:1; bool has_cidr:1; + NMIPRoute **iproutes_arr; + gsize iproutes_len; + /* TRUE, if the configuration was requested via hwaddrs argument to * nmcs_provider_get_config(). */ bool was_requested:1; @@ -29,8 +32,9 @@ nmcs_provider_get_config_iface_data_is_valid (const NMCSProviderGetConfigIfaceDa { return config_data && config_data->iface_idx >= 0 - && config_data->has_cidr - && config_data->has_ipv4s; + && ( ( config_data->has_ipv4s + && config_data->has_cidr) + || config_data->iproutes_len); } NMCSProviderGetConfigIfaceData *nmcs_provider_get_config_iface_data_new (gboolean was_requested); -- cgit v1.2.1