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 15:05:51 +0200
commit75386a02773276c470451d72402a08e5ca83a86c (patch)
tree1b7de82d4e811fdf86c7ee8251b6b3ba39b31d93
parent0d26a341dd099663d31f95706c28a010ac887cd1 (diff)
downloadNetworkManager-th/cloud-setup-azure-fix-gateway.tar.gz
cloud-setup/azure: fix detecting the gateway addressth/cloud-setup-azure-fix-gateway
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,