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
This commit is contained in:
Thomas Haller 2021-04-20 10:52:04 +02:00
parent 889498c12c
commit c2629f72b0
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 48 additions and 1 deletions

View file

@ -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>

View file

@ -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;
@ -198,6 +215,17 @@ _get_config_fetch_done_cb_ipv4_ipaddress_x_privateipaddress(GObject * source
GET_CONFIG_FETCH_TYPE_IPV4_IPADDRESS_X_PRIVATEIPADDRESS);
}
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,
@ -288,6 +316,23 @@ _get_config_ips_prefix_list_cb(GObject *source, GAsyncResult *result, gpointer u
{
gs_free char *uri = NULL;
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),