summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2021-04-20 10:52:04 +0200
committerThomas Haller <thaller@redhat.com>2021-04-20 17:46:05 +0200
commitc2629f72b0e6b438bf3f2b93967f58c9defafea6 (patch)
tree738c4eaca3c07fae1437baed9a45e83c89a0da51
parent889498c12cc5cd4ab718cbc8adbccc1f197adda5 (diff)
downloadNetworkManager-c2629f72b0e6b438bf3f2b93967f58c9defafea6.tar.gz
cloud-setup/azure: fix detecting the gateway address
The code never set "iface_get_config->cidr_addr", despite setting "cidr_prefix" and "has_cidr". As a result, cloud-setup would think that the subnet is "0.0.0.0/$PLEN", and calculate the gateway as "0.0.0.1". As a result it would add a default route to table 30400 via 0.0.0.1, which is obviously wrong. How to detect the right gateway? Let's try obtain the subnet also via the meta data. That seems mostly correct, except that we only access subnet at index 0. What if there are multiple ones? I don't know. https://bugzilla.redhat.com/show_bug.cgi?id=1912236
-rw-r--r--man/nm-cloud-setup.xml4
-rw-r--r--src/nm-cloud-setup/nmcs-provider-azure.c45
2 files changed, 48 insertions, 1 deletions
diff --git a/man/nm-cloud-setup.xml b/man/nm-cloud-setup.xml
index 388ef3ba91..5657c7fcc7 100644
--- a/man/nm-cloud-setup.xml
+++ b/man/nm-cloud-setup.xml
@@ -317,7 +317,9 @@
<listitem>
<para>Then, for each IP address index fetch the address at
<literal>http://169.254.169.254/metadata/instance/network/interface/$IFACE_INDEX/ipv4/ipAddress/$ADDR_INDEX/privateIpAddress?format=text&amp;api-version=2017-04-02</literal>.
- Also fetch the size of the subnet (the netmask) for the interface from
+ Also fetch the size of the subnet and prefix for the interface from
+ <literal>http://169.254.169.254/metadata/instance/network/interface/$IFACE_INDEX/ipv4/subnet/0/address/?format=text&amp;api-version=2017-04-02</literal>.
+ and
<literal>http://169.254.169.254/metadata/instance/network/interface/$IFACE_INDEX/ipv4/subnet/0/prefix/?format=text&amp;api-version=2017-04-02</literal>.
</para>
</listitem>
diff --git a/src/nm-cloud-setup/nmcs-provider-azure.c b/src/nm-cloud-setup/nmcs-provider-azure.c
index 486c3dbbce..9ced8c4571 100644
--- a/src/nm-cloud-setup/nmcs-provider-azure.c
+++ b/src/nm-cloud-setup/nmcs-provider-azure.c
@@ -95,6 +95,7 @@ detect(NMCSProvider *provider, GTask *task)
typedef enum {
GET_CONFIG_FETCH_TYPE_IPV4_IPADDRESS_X_PRIVATEIPADDRESS,
+ GET_CONFIG_FETCH_TYPE_IPV4_SUBNET_0_ADDRESS,
GET_CONFIG_FETCH_TYPE_IPV4_SUBNET_0_PREFIX,
} GetConfigFetchType;
@@ -159,6 +160,18 @@ _get_config_fetch_done_cb(NMHttpClient * http_client,
iface_get_config->ipv4s_len++;
break;
+ case GET_CONFIG_FETCH_TYPE_IPV4_SUBNET_0_ADDRESS:
+
+ if (!nmcs_utils_ipaddr_normalize_bin(AF_INET, resp_str, resp_len, NULL, &tmp_addr)) {
+ error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, "ip is not a subnet address");
+ goto out_done;
+ }
+ _LOGD("interface[%" G_GSSIZE_FORMAT "]: received subnet address %s",
+ iface_data->intern_iface_idx,
+ _nm_utils_inet4_ntop(tmp_addr, tmp_addr_str));
+ iface_get_config->cidr_addr = tmp_addr;
+ break;
+
case GET_CONFIG_FETCH_TYPE_IPV4_SUBNET_0_PREFIX:
tmp_prefix = _nm_utils_ascii_str_to_int64_bin(resp_str, resp_len, 10, 0, 32, -1);
@@ -181,6 +194,10 @@ out_done:
--iface_data->n_iface_data_pending;
if (iface_data->n_iface_data_pending > 0)
return;
+
+ /* we surely have cidr_addr and cidr_prefix, otherwise
+ * we would have errored out above. */
+ iface_get_config->has_cidr = TRUE;
}
--get_config_data->n_pending;
@@ -199,6 +216,17 @@ _get_config_fetch_done_cb_ipv4_ipaddress_x_privateipaddress(GObject * source
}
static void
+_get_config_fetch_done_cb_ipv4_subnet_0_address(GObject * source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ _get_config_fetch_done_cb(NM_HTTP_CLIENT(source),
+ result,
+ user_data,
+ GET_CONFIG_FETCH_TYPE_IPV4_SUBNET_0_ADDRESS);
+}
+
+static void
_get_config_fetch_done_cb_ipv4_subnet_0_prefix(GObject * source,
GAsyncResult *result,
gpointer user_data)
@@ -291,6 +319,23 @@ _get_config_ips_prefix_list_cb(GObject *source, GAsyncResult *result, gpointer u
iface_data->n_iface_data_pending++;
nm_http_client_poll_get(
NM_HTTP_CLIENT(source),
+ (uri = _azure_uri_interfaces(iface_idx_str, "/ipv4/subnet/0/address/")),
+ HTTP_TIMEOUT_MS,
+ 512 * 1024,
+ 10000,
+ 1000,
+ NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ get_config_data->intern_cancellable,
+ NULL,
+ NULL,
+ _get_config_fetch_done_cb_ipv4_subnet_0_address,
+ iface_data);
+
+ nm_clear_g_free(&uri);
+
+ iface_data->n_iface_data_pending++;
+ nm_http_client_poll_get(
+ NM_HTTP_CLIENT(source),
(uri = _azure_uri_interfaces(iface_idx_str, "/ipv4/subnet/0/prefix/")),
HTTP_TIMEOUT_MS,
512 * 1024,