Thomas Haller 2022-06-27 10:55:24 +02:00
commit 076ffabe71
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
15 changed files with 86 additions and 69 deletions

View file

@ -805,7 +805,7 @@ handle_settings(GVariant *v_dict, gpointer user_data)
_LOGW("invalid 'Netmask': %s", s ?: "");
goto out;
}
address.plen = nm_utils_ip4_netmask_to_prefix(address_network);
address.plen = _nm_utils_ip4_netmask_to_prefix(address_network);
_LOGI("Address: %s", nm_platform_ip4_address_to_string(&address, sbuf, sizeof(sbuf)));
nm_l3_config_data_add_address_4(priv->l3cd_4, &address);

View file

@ -228,6 +228,16 @@ nm_dhcp_client_get_effective_client_id(NMDhcpClient *self)
return priv->effective_client_id;
}
NML3ConfigData *
nm_dhcp_client_create_l3cd(NMDhcpClient *self)
{
NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self);
return nm_l3_config_data_new(nm_l3cfg_get_multi_idx(priv->config.l3cfg),
nm_l3cfg_get_ifindex(priv->config.l3cfg),
NM_IP_CONFIG_SOURCE_DHCP);
}
/*****************************************************************************/
void

View file

@ -288,6 +288,8 @@ int nm_dhcp_client_get_ifindex(NMDhcpClient *self);
void nm_dhcp_client_set_effective_client_id(NMDhcpClient *self, GBytes *client_id);
GBytes *nm_dhcp_client_get_effective_client_id(NMDhcpClient *self);
NML3ConfigData *nm_dhcp_client_create_l3cd(NMDhcpClient *self);
/*****************************************************************************
* Client data
*****************************************************************************/

View file

@ -164,7 +164,8 @@ lease_option_consume_route(const uint8_t **datap,
/*****************************************************************************/
static gboolean
lease_parse_address(NDhcp4ClientLease *lease,
lease_parse_address(NMDhcpNettools *self /* for logging context only */,
NDhcp4ClientLease *lease,
NML3ConfigData *l3cd,
const char *iface,
GHashTable *options,
@ -237,19 +238,32 @@ lease_parse_address(NDhcp4ClientLease *lease,
}
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_SUBNET_MASK, &l_data, &l_data_len);
if (r != 0
|| !nm_dhcp_lease_data_parse_in_addr(l_data,
l_data_len,
&a_netmask,
iface,
NM_DHCP_OPTION_DHCP4_SUBNET_MASK)) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_UNKNOWN,
"could not get netmask from lease");
return FALSE;
}
if (r == N_DHCP4_E_UNSET) {
char str1[NM_UTILS_INET_ADDRSTRLEN];
char str2[NM_UTILS_INET_ADDRSTRLEN];
a_plen = nm_utils_ip4_netmask_to_prefix(a_netmask);
/* Some DHCP servers may not set the subnet-mask (issue#1037).
* Do the same as the dhclient plugin and use a default. */
a_plen = _nm_utils_ip4_get_default_prefix(a_address.s_addr);
a_netmask = _nm_utils_ip4_prefix_to_netmask(a_plen);
_LOGT("missing subnet mask (option 1). Guess %s based on IP address %s",
_nm_utils_inet4_ntop(a_netmask, str1),
_nm_utils_inet4_ntop(a_address.s_addr, str2));
} else {
if (r != 0
|| !nm_dhcp_lease_data_parse_in_addr(l_data,
l_data_len,
&a_netmask,
iface,
NM_DHCP_OPTION_DHCP4_SUBNET_MASK)) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_UNKNOWN,
"could not get netmask from lease");
return FALSE;
}
a_plen = _nm_utils_ip4_netmask_to_prefix(a_netmask);
a_netmask = _nm_utils_ip4_prefix_to_netmask(a_plen);
}
nm_dhcp_option_add_option_in_addr(options,
AF_INET,
@ -589,12 +603,9 @@ lease_parse_private_options(NDhcp4ClientLease *lease, GHashTable *options)
}
static NML3ConfigData *
lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
const char *iface,
int ifindex,
NDhcp4ClientLease *lease,
GError **error)
lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **error)
{
const char *iface;
nm_auto_str_buf NMStrBuf sbuf = NM_STR_BUF_INIT(0, FALSE);
nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
gs_unref_hashtable GHashTable *options = NULL;
@ -607,13 +618,15 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
struct in_addr v_inaddr_s;
int r;
g_return_val_if_fail(lease != NULL, NULL);
nm_assert(lease);
l3cd = nm_l3_config_data_new(multi_idx, ifindex, NM_IP_CONFIG_SOURCE_DHCP);
iface = nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self));
l3cd = nm_dhcp_client_create_l3cd(NM_DHCP_CLIENT(self));
options = nm_dhcp_option_create_options_dict();
if (!lease_parse_address(lease, l3cd, iface, options, &lease_address, error))
if (!lease_parse_address(self, lease, l3cd, iface, options, &lease_address, error))
return NULL;
r = n_dhcp4_client_lease_get_server_identifier(lease, &v_inaddr_s);
@ -877,9 +890,7 @@ lease_save(NMDhcpNettools *self, NDhcp4ClientLease *lease, const char *lease_fil
static void
bound4_handle(NMDhcpNettools *self, guint event, NDhcp4ClientLease *lease)
{
NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
NMDhcpClient *client = NM_DHCP_CLIENT(self);
const NMDhcpClientConfig *client_config;
NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
gs_free_error GError *error = NULL;
@ -888,12 +899,7 @@ bound4_handle(NMDhcpNettools *self, guint event, NDhcp4ClientLease *lease)
_LOGT("lease available (%s)", (event == N_DHCP4_CLIENT_EVENT_GRANTED) ? "granted" : "extended");
client_config = nm_dhcp_client_get_config(client);
l3cd = lease_to_ip4_config(nm_dhcp_client_get_multi_idx(client),
client_config->iface,
nm_dhcp_client_get_ifindex(client),
lease,
&error);
l3cd = lease_to_ip4_config(self, lease, &error);
if (!l3cd) {
_LOGW("failure to parse lease: %s", error->message);

View file

@ -68,13 +68,7 @@ G_DEFINE_TYPE(NMDhcpSystemd, nm_dhcp_systemd, NM_TYPE_DHCP_CLIENT)
/*****************************************************************************/
static NML3ConfigData *
lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
const char *iface,
int ifindex,
sd_dhcp6_lease *lease,
gboolean info_only,
gint32 ts,
GError **error)
lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GError **error)
{
nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
gs_unref_hashtable GHashTable *options = NULL;
@ -90,11 +84,11 @@ lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
nm_assert(lease);
l3cd = nm_l3_config_data_new(multi_idx, ifindex, NM_IP_CONFIG_SOURCE_DHCP);
l3cd = nm_dhcp_client_create_l3cd(NM_DHCP_CLIENT(self));
options = nm_dhcp_option_create_options_dict();
if (!info_only) {
if (!nm_dhcp_client_get_config(NM_DHCP_CLIENT(self))->v6.info_only) {
gboolean has_any_addresses = FALSE;
uint32_t lft_pref;
uint32_t lft_valid;
@ -192,17 +186,13 @@ lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
static void
bound6_handle(NMDhcpSystemd *self)
{
NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE(self);
const gint32 ts = nm_utils_get_monotonic_timestamp_sec();
const char *iface = nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self));
const NMDhcpClientConfig *client_config;
NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE(self);
const gint32 ts = nm_utils_get_monotonic_timestamp_sec();
nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
gs_free_error GError *error = NULL;
NMPlatformIP6Address prefix = {0};
sd_dhcp6_lease *lease = NULL;
client_config = nm_dhcp_client_get_config(NM_DHCP_CLIENT(self));
if (sd_dhcp6_client_get_lease(priv->client6, &lease) < 0 || !lease) {
_LOGW(" no lease!");
_nm_dhcp_client_notify(NM_DHCP_CLIENT(self), NM_DHCP_CLIENT_EVENT_TYPE_FAIL, NULL);
@ -211,13 +201,7 @@ bound6_handle(NMDhcpSystemd *self)
_LOGD("lease available");
l3cd = lease_to_ip6_config(nm_dhcp_client_get_multi_idx(NM_DHCP_CLIENT(self)),
iface,
nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)),
lease,
client_config->v6.info_only,
ts,
&error);
l3cd = lease_to_ip6_config(self, lease, ts, &error);
if (!l3cd) {
_LOGW("%s", error->message);

View file

@ -423,7 +423,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
str = g_hash_table_lookup(options, "subnet_mask");
if (str && (inet_pton(AF_INET, str, &tmp_addr) > 0)) {
plen = nm_utils_ip4_netmask_to_prefix(tmp_addr);
plen = _nm_utils_ip4_netmask_to_prefix(tmp_addr);
_LOG2I(LOGD_DHCP4, iface, " plen %d (%s)", plen, str);
} else {
/* Get default netmask for the IP according to appropriate class. */

View file

@ -777,7 +777,7 @@ read_full_ip4_address(shvarFile *ifcfg,
if (!read_ip4_address(ifcfg, numbered_tag(tag, "NETMASK", which), &has_key, &a, error))
return FALSE;
if (has_key)
prefix = nm_utils_ip4_netmask_to_prefix(a);
prefix = _nm_utils_ip4_netmask_to_prefix(a);
else {
if (base_addr)
prefix = nm_ip_address_get_prefix(base_addr);
@ -1450,7 +1450,7 @@ read_one_ip4_route(shvarFile *ifcfg, guint32 which, NMIPRoute **out_route, GErro
error))
return FALSE;
if (has_key) {
prefix = nm_utils_ip4_netmask_to_prefix(netmask);
prefix = _nm_utils_ip4_netmask_to_prefix(netmask);
if (netmask != _nm_utils_ip4_prefix_to_netmask(prefix)) {
g_set_error(error,
NM_SETTINGS_ERROR,

View file

@ -451,7 +451,7 @@ update_ip4_setting_from_if_block(NMConnection *connection, if_block *block, GErr
netmask_v);
return FALSE;
} else {
netmask_int = nm_utils_ip4_netmask_to_prefix(tmp_mask);
netmask_int = _nm_utils_ip4_netmask_to_prefix(tmp_mask);
}
}

View file

@ -3131,7 +3131,7 @@ _signal_handle(NMSupplicantInterface *self,
_set_p2p_assigned_addr(iface,
addr_data,
nm_utils_ip4_netmask_to_prefix(netmask));
_nm_utils_ip4_netmask_to_prefix(netmask));
} else {
_LOGW("P2P: GroupStarted signaled invalid IP Address information");
}

View file

@ -1558,29 +1558,33 @@ nm_utils_ip4_routes_from_variant(GVariant *value)
/**
* nm_utils_ip4_netmask_to_prefix:
* @netmask: an IPv4 netmask in network byte order
* @netmask: an IPv4 netmask in network byte order.
* Usually the netmask has all leading bits up to the prefix
* set so that the netmask is identical to having the first
* prefix bits of the address set.
* If that is not the case and there are "holes" in the
* mask, the prefix is determined based on the lowest bit
* set.
*
* Returns: the CIDR prefix represented by the netmask
**/
guint32
nm_utils_ip4_netmask_to_prefix(guint32 netmask)
{
G_STATIC_ASSERT_EXPR(__SIZEOF_INT__ == 4);
G_STATIC_ASSERT_EXPR(sizeof(int) == 4);
G_STATIC_ASSERT_EXPR(sizeof(netmask) == 4);
return ((netmask != 0u) ? (guint32) (32 - __builtin_ctz(ntohl(netmask))) : 0u);
return _nm_utils_ip4_netmask_to_prefix(netmask);
}
/**
* nm_utils_ip4_prefix_to_netmask:
* @prefix: a CIDR prefix
* @prefix: a CIDR prefix, must be not larger than 32.
*
* Returns: the netmask represented by the prefix, in network byte order
**/
guint32
nm_utils_ip4_prefix_to_netmask(guint32 prefix)
{
g_return_val_if_fail(prefix <= 32, 0xffffffffu);
return _nm_utils_ip4_prefix_to_netmask(prefix);
}

View file

@ -4925,7 +4925,7 @@ _netmask_to_prefix(guint32 netmask)
/* we re-implemented the netmask-to-prefix code differently. Check
* that they agree. */
g_assert_cmpint(prefix, ==, nm_utils_ip4_netmask_to_prefix(netmask));
g_assert_cmpint(prefix, ==, _nm_utils_ip4_netmask_to_prefix(netmask));
return prefix;
}

View file

@ -389,6 +389,17 @@ gboolean nm_utils_get_ipv6_interface_identifier(NMLinkType link_type,
/*****************************************************************************/
static inline guint32
_nm_utils_ip4_netmask_to_prefix(in_addr_t subnetmask)
{
G_STATIC_ASSERT_EXPR(__SIZEOF_INT__ == 4);
G_STATIC_ASSERT_EXPR(sizeof(int) == 4);
G_STATIC_ASSERT_EXPR(sizeof(guint) == 4);
G_STATIC_ASSERT_EXPR(sizeof(subnetmask) == 4);
return ((subnetmask != 0u) ? (guint32) (32 - __builtin_ctz(ntohl(subnetmask))) : 0u);
}
/**
* _nm_utils_ip4_prefix_to_netmask:
* @prefix: a CIDR prefix

View file

@ -203,7 +203,7 @@ _get_config_fetch_done_cb(NMHttpClient *http_client,
g_bytes_get_data(response, NULL),
NULL,
&netmask_bin)) {
config_iface_data->cidr_prefix = nm_utils_ip4_netmask_to_prefix(netmask_bin);
config_iface_data->cidr_prefix = _nm_utils_ip4_netmask_to_prefix(netmask_bin);
};
break;

View file

@ -633,7 +633,7 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument)
NMIPAddr addr;
if (is_ipv4 && nm_utils_parse_inaddr_bin(AF_INET, netmask, NULL, &addr))
client_ip_prefix = nm_utils_ip4_netmask_to_prefix(addr.addr4);
client_ip_prefix = _nm_utils_ip4_netmask_to_prefix(addr.addr4);
else
client_ip_prefix = _nm_utils_ascii_str_to_int64(netmask, 10, 0, is_ipv4 ? 32 : 128, -1);

View file

@ -288,7 +288,7 @@ nmi_dt_reader_parse(const char *sysfs_dir)
guint32 netmask_v4;
nm_ip_address_get_address_binary(netmask, &netmask_v4);
prefix = nm_utils_ip4_netmask_to_prefix(netmask_v4);
prefix = _nm_utils_ip4_netmask_to_prefix(netmask_v4);
}
if (prefix == -1)