summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWen Liang <liangwen12year@gmail.com>2021-08-05 07:44:05 -0400
committerThomas Haller <thaller@redhat.com>2021-08-09 17:16:07 +0200
commit59633dbe117f97f5b453df6a4b1e5a918d2160e8 (patch)
tree3213c652ef50dda09b53fd12ce92bc9f048b4be0
parent0e7d26085211c1d387a43063c963b18774765953 (diff)
downloadNetworkManager-59633dbe117f97f5b453df6a4b1e5a918d2160e8.tar.gz
aliyun: reuse ipv4 gateway address returned by metadata server
The default ipv4 gateway address of the VPC in Aliyun cloud is not the first IP address in the CIDR subnet block, we should instead use the ipv4 gateway address retrieved from the metadata server in `_nmc_mangle_connection()`. https://bugzilla.redhat.com/show_bug.cgi?id=1823315 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/958 Signed-off-by: Wen Liang <liangwen12year@gmail.com> (cherry picked from commit 778e1f8493babb8e015e5334806de7099c66bafb)
-rw-r--r--man/nm-cloud-setup.xml6
-rw-r--r--src/nm-cloud-setup/main.c12
-rw-r--r--src/nm-cloud-setup/nmcs-provider-aliyun.c42
-rw-r--r--src/nm-cloud-setup/nmcs-provider.h2
4 files changed, 53 insertions, 9 deletions
diff --git a/man/nm-cloud-setup.xml b/man/nm-cloud-setup.xml
index 63a805eb6b..7493cc1d7f 100644
--- a/man/nm-cloud-setup.xml
+++ b/man/nm-cloud-setup.xml
@@ -410,8 +410,8 @@ ln -s /etc/systemd/system/timers.target.wants/nm-cloud-setup.timer /usr/lib/syst
<listitem>
<para>Choose a route table 30400 + the index of the interface and
add a default route <literal>0.0.0.0/0</literal>. The gateway
- is the first IP address in the CIDR subnet block. For
- example, we might get a route <literal>"0.0.0.0/0 10.0.0.1 10 table=30400"</literal>.</para>
+ is the default gateway retrieved from metadata server. For
+ example, we might get a route <literal>"0.0.0.0/0 10.0.0.253 10 table=30400"</literal>.</para>
</listitem>
<listitem>
<para>Finally, add a policy routing rule for each address. For example
@@ -419,7 +419,7 @@ ln -s /etc/systemd/system/timers.target.wants/nm-cloud-setup.timer /usr/lib/syst
</listitem>
</itemizedlist>
With above example, this roughly corresponds for interface <literal>eth0</literal> to
- <command>nmcli device modify "eth0" ipv4.addresses "10.0.0.150/24,10.0.0.150/24" ipv4.routes "0.0.0.0/0 10.0.0.1 10 table=30400" ipv4.routing-rules "priority 30400 from 10.0.0.150/32 table 30400, priority 30400 from 10.0.0.152/32 table 30400"</command>.
+ <command>nmcli device modify "eth0" ipv4.addresses "10.0.0.150/24,10.0.0.152/24" ipv4.routes "0.0.0.0/0 10.0.0.253 10 table=30400" ipv4.routing-rules "priority 30400 from 10.0.0.150/32 table 30400, priority 30400 from 10.0.0.152/32 table 30400"</command>.
Note that this replaces the previous addresses, routes and rules with the new information.
But also note that this only changes the run time configuration of the device. The
connection profile on disk is not affected.
diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c
index dc87ac42e0..8dc6785179 100644
--- a/src/nm-cloud-setup/main.c
+++ b/src/nm-cloud-setup/main.c
@@ -340,11 +340,13 @@ _nmc_mangle_connection(NMDevice * device,
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;
-
+ if (config_data->has_gateway && config_data->gateway) {
+ gateway = config_data->gateway;
+ } else {
+ 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;
diff --git a/src/nm-cloud-setup/nmcs-provider-aliyun.c b/src/nm-cloud-setup/nmcs-provider-aliyun.c
index b430b452d0..01a4af0ff5 100644
--- a/src/nm-cloud-setup/nmcs-provider-aliyun.c
+++ b/src/nm-cloud-setup/nmcs-provider-aliyun.c
@@ -123,7 +123,8 @@ detect(NMCSProvider *provider, GTask *task)
typedef enum {
GET_CONFIG_FETCH_DONE_TYPE_SUBNET_VPC_CIDR_BLOCK,
GET_CONFIG_FETCH_DONE_TYPE_PRIVATE_IPV4S,
- GET_CONFIG_FETCH_DONE_TYPE_NETMASK
+ GET_CONFIG_FETCH_DONE_TYPE_NETMASK,
+ GET_CONFIG_FETCH_DONE_TYPE_GATEWAY,
} GetConfigFetchDoneType;
static void
@@ -140,6 +141,7 @@ _get_config_fetch_done_cb(NMHttpClient * http_client,
in_addr_t tmp_addr;
int tmp_prefix;
in_addr_t netmask_bin;
+ in_addr_t gateway_bin;
gs_free const char ** s_addrs = NULL;
gsize i;
gsize len;
@@ -200,6 +202,17 @@ _get_config_fetch_done_cb(NMHttpClient * http_client,
config_iface_data->cidr_prefix = nm_utils_ip4_netmask_to_prefix(netmask_bin);
};
break;
+
+ case GET_CONFIG_FETCH_DONE_TYPE_GATEWAY:
+
+ if (nm_utils_parse_inaddr_bin(AF_INET,
+ g_bytes_get_data(response, NULL),
+ NULL,
+ &gateway_bin)) {
+ config_iface_data->has_gateway = TRUE;
+ config_iface_data->gateway = gateway_bin;
+ };
+ break;
}
out:
@@ -234,6 +247,15 @@ _get_config_fetch_done_cb_netmask(GObject *source, GAsyncResult *result, gpointe
GET_CONFIG_FETCH_DONE_TYPE_NETMASK);
}
+static void
+_get_config_fetch_done_cb_gateway(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ _get_config_fetch_done_cb(NM_HTTP_CLIENT(source),
+ result,
+ user_data,
+ GET_CONFIG_FETCH_DONE_TYPE_GATEWAY);
+}
+
typedef struct {
gssize iface_idx;
char path[0];
@@ -277,6 +299,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
gs_free char * uri1 = NULL;
gs_free char * uri2 = NULL;
gs_free char * uri3 = NULL;
+ gs_free char * uri4 = NULL;
const char * hwaddr;
if (!g_hash_table_lookup_extended(get_config_data->result_dict,
@@ -354,6 +377,23 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
NULL,
_get_config_fetch_done_cb_netmask,
nm_utils_user_data_pack(get_config_data, hwaddr));
+
+ get_config_data->n_pending++;
+ nm_http_client_poll_get(
+ http_client,
+ (uri4 = _aliyun_uri_interfaces(v_mac_data->path,
+ NM_STR_HAS_SUFFIX(v_mac_data->path, "/") ? "" : "/",
+ "gateway")),
+ HTTP_TIMEOUT_MS,
+ 512 * 1024,
+ 10000,
+ 1000,
+ NULL,
+ get_config_data->intern_cancellable,
+ NULL,
+ NULL,
+ _get_config_fetch_done_cb_gateway,
+ nm_utils_user_data_pack(get_config_data, hwaddr));
}
_nmcs_provider_get_config_task_maybe_return(get_config_data, NULL);
diff --git a/src/nm-cloud-setup/nmcs-provider.h b/src/nm-cloud-setup/nmcs-provider.h
index 3b0c2529ed..13212b8e4c 100644
--- a/src/nm-cloud-setup/nmcs-provider.h
+++ b/src/nm-cloud-setup/nmcs-provider.h
@@ -19,9 +19,11 @@ typedef struct {
gssize iface_idx;
in_addr_t cidr_addr;
+ in_addr_t gateway;
guint8 cidr_prefix;
bool has_ipv4s : 1;
bool has_cidr : 1;
+ bool has_gateway : 1;
NMIPRoute **iproutes_arr;
gsize iproutes_len;