core: merge IPv4/IPv6 implementations of nm_utils_ip_{addresses,routes}_to_dbus()

This commit is contained in:
Thomas Haller 2020-07-30 13:24:48 +02:00
parent 52c9504ef4
commit 43d031d37f
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
4 changed files with 166 additions and 259 deletions

View file

@ -1375,7 +1375,7 @@ _addresses_sort_cmp_4 (gconstpointer a, gconstpointer b, gpointer user_data)
}
static int
_addresses_sort_cmp_prop_6 (gconstpointer a, gconstpointer b, gpointer user_data)
_addresses_sort_cmp_6 (gconstpointer a, gconstpointer b, gpointer user_data)
{
return nm_platform_ip6_address_pretty_sort_cmp (NMP_OBJECT_CAST_IP6_ADDRESS (*((const NMPObject **) a)),
NMP_OBJECT_CAST_IP6_ADDRESS (*((const NMPObject **) b)),
@ -1383,143 +1383,109 @@ _addresses_sort_cmp_prop_6 (gconstpointer a, gconstpointer b, gpointer user_data
}
void
nm_utils_ip4_addresses_to_dbus (const NMDedupMultiHeadEntry *head_entry,
const NMPObject *best_default_route,
GVariant **out_address_data,
GVariant **out_addresses)
nm_utils_ip_addresses_to_dbus (int addr_family,
const NMDedupMultiHeadEntry *head_entry,
const NMPObject *best_default_route,
NMSettingIP6ConfigPrivacy ipv6_privacy,
GVariant **out_address_data,
GVariant **out_addresses)
{
char addr_str[NM_UTILS_INET_ADDRSTRLEN];
const gboolean IS_IPv4 = NM_IS_IPv4 (addr_family);
GVariantBuilder builder_data;
GVariantBuilder builder_legacy;
char addr_str[NM_UTILS_INET_ADDRSTRLEN];
gs_free const NMPObject **addresses = NULL;
guint naddr;
guint i;
nm_assert_addr_family (addr_family);
if (out_address_data)
g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}"));
if (out_addresses)
g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("aau"));
if (out_addresses) {
if (IS_IPv4)
g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("aau"));
else
g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("a(ayuay)"));
}
if (head_entry) {
gs_free const NMPObject **addresses = NULL;
guint naddr;
if (!head_entry)
goto out;
addresses = (const NMPObject **) nm_dedup_multi_objs_to_array_head (head_entry, NULL, NULL, &naddr);
addresses = (const NMPObject **) nm_dedup_multi_objs_to_array_head (head_entry, NULL, NULL, &naddr);
nm_assert (addresses && naddr);
nm_assert (addresses && naddr);
g_qsort_with_data (addresses,
naddr,
sizeof (addresses[0]),
_addresses_sort_cmp_4,
NULL);
g_qsort_with_data (addresses,
naddr,
sizeof (addresses[0]),
IS_IPv4
? _addresses_sort_cmp_4
: _addresses_sort_cmp_6,
GINT_TO_POINTER (ipv6_privacy));
/* Build address data variant */
for (i = 0; i < naddr; i++) {
const NMPlatformIP4Address *address = NMP_OBJECT_CAST_IP4_ADDRESS (addresses[i]);
for (i = 0; i < naddr; i++) {
const NMPlatformIPXAddress *address = NMP_OBJECT_CAST_IPX_ADDRESS (addresses[i]);
if (out_address_data) {
GVariantBuilder addr_builder;
if (out_address_data) {
GVariantBuilder addr_builder;
gconstpointer p;
g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&addr_builder, "{sv}",
"address",
g_variant_new_string (nm_utils_inet_ntop (addr_family, address->ax.address_ptr, addr_str)));
g_variant_builder_add (&addr_builder, "{sv}",
"prefix",
g_variant_new_uint32 (address->ax.plen));
p = NULL;
if (IS_IPv4) {
if (address->a4.peer_address != address->a4.address)
p = &address->a4.peer_address;
} else {
if ( !IN6_IS_ADDR_UNSPECIFIED (&address->a6.peer_address)
&& !IN6_ARE_ADDR_EQUAL (&address->a6.peer_address, &address->a6.address))
p = &address->a6.peer_address;
}
if (p) {
g_variant_builder_add (&addr_builder, "{sv}",
"address",
g_variant_new_string (_nm_utils_inet4_ntop (address->address, addr_str)));
g_variant_builder_add (&addr_builder, "{sv}",
"prefix",
g_variant_new_uint32 (address->plen));
if (address->peer_address != address->address) {
g_variant_builder_add (&addr_builder, "{sv}",
"peer",
g_variant_new_string (_nm_utils_inet4_ntop (address->peer_address, addr_str)));
}
if (*address->label) {
g_variant_builder_add (&addr_builder, "{sv}",
NM_IP_ADDRESS_ATTRIBUTE_LABEL,
g_variant_new_string (address->label));
}
g_variant_builder_add (&builder_data, "a{sv}", &addr_builder);
"peer",
g_variant_new_string (nm_utils_inet_ntop (addr_family, p, addr_str)));
}
if (out_addresses) {
if (IS_IPv4) {
if (*address->a4.label) {
g_variant_builder_add (&addr_builder, "{sv}",
NM_IP_ADDRESS_ATTRIBUTE_LABEL,
g_variant_new_string (address->a4.label));
}
}
g_variant_builder_add (&builder_data, "a{sv}", &addr_builder);
}
if (out_addresses) {
if (IS_IPv4) {
const guint32 dbus_addr[3] = {
address->address,
address->plen,
( i == 0
&& best_default_route)
? NMP_OBJECT_CAST_IP4_ROUTE (best_default_route)->gateway
: (guint32) 0,
address->a4.address,
address->a4.plen,
( i == 0
&& best_default_route)
? NMP_OBJECT_CAST_IP4_ROUTE (best_default_route)->gateway
: (guint32) 0,
};
g_variant_builder_add (&builder_legacy, "@au",
g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
dbus_addr, 3, sizeof (guint32)));
}
}
}
NM_SET_OUT (out_address_data, g_variant_builder_end (&builder_data));
NM_SET_OUT (out_addresses, g_variant_builder_end (&builder_legacy));
}
void
nm_utils_ip6_addresses_to_dbus (const NMDedupMultiHeadEntry *head_entry,
NMSettingIP6ConfigPrivacy ipv6_privacy,
const NMPObject *best_default_route,
GVariant **out_address_data,
GVariant **out_addresses)
{
char sbuf[NM_UTILS_INET_ADDRSTRLEN];
GVariantBuilder builder_data;
GVariantBuilder builder_legacy;
if (out_address_data)
g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}"));
if (out_addresses)
g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("a(ayuay)"));
if (head_entry) {
gs_free const NMPObject **addresses = NULL;
guint naddr;
guint i;
addresses = (const NMPObject **) nm_dedup_multi_objs_to_array_head (head_entry, NULL, NULL, &naddr);
nm_assert (addresses && naddr);
g_qsort_with_data (addresses,
naddr,
sizeof (addresses[0]),
_addresses_sort_cmp_prop_6,
GINT_TO_POINTER (ipv6_privacy));
for (i = 0; i < naddr; i++) {
const NMPlatformIP6Address *address = NMP_OBJECT_CAST_IP6_ADDRESS (addresses[i]);
if (out_address_data) {
GVariantBuilder addr_builder;
g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&addr_builder, "{sv}",
"address",
g_variant_new_string (_nm_utils_inet6_ntop (&address->address, sbuf)));
g_variant_builder_add (&addr_builder, "{sv}",
"prefix",
g_variant_new_uint32 (address->plen));
if ( !IN6_IS_ADDR_UNSPECIFIED (&address->peer_address)
&& !IN6_ARE_ADDR_EQUAL (&address->peer_address, &address->address)) {
g_variant_builder_add (&addr_builder, "{sv}",
"peer",
g_variant_new_string (_nm_utils_inet6_ntop (&address->peer_address, sbuf)));
}
g_variant_builder_add (&builder_data, "a{sv}", &addr_builder);
}
if (out_addresses) {
} else {
g_variant_builder_add (&builder_legacy, "(@ayu@ay)",
g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
&address->address, 16, 1),
address->plen,
&address->a6.address, 16, 1),
address->a6.plen,
g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
( i == 0
&& best_default_route)
@ -1530,169 +1496,112 @@ nm_utils_ip6_addresses_to_dbus (const NMDedupMultiHeadEntry *head_entry,
}
}
out:
NM_SET_OUT (out_address_data, g_variant_builder_end (&builder_data));
NM_SET_OUT (out_addresses, g_variant_builder_end (&builder_legacy));
}
static gboolean
_route_valid_4 (const NMPlatformIP4Route *r)
{
return r
&& r->plen <= 32
&& r->network == nm_utils_ip4_address_clear_host_address (r->network, r->plen);
}
static gboolean
_route_valid_6 (const NMPlatformIP6Route *r)
{
struct in6_addr n;
return r
&& r->plen <= 128
&& (memcmp (&r->network,
nm_utils_ip6_address_clear_host_address (&n, &r->network, r->plen),
sizeof (n)) == 0);
}
void
nm_utils_ip4_routes_to_dbus (const NMDedupMultiHeadEntry *head_entry,
GVariant **out_route_data,
GVariant **out_routes)
nm_utils_ip_routes_to_dbus (int addr_family,
const NMDedupMultiHeadEntry *head_entry,
GVariant **out_route_data,
GVariant **out_routes)
{
const gboolean IS_IPv4 = NM_IS_IPv4 (addr_family);
NMDedupMultiIter iter;
const NMPlatformIP4Route *route;
const NMPObject *obj;
GVariantBuilder builder_data;
GVariantBuilder builder_legacy;
char addr_str[NM_UTILS_INET_ADDRSTRLEN];
nm_assert_addr_family (addr_family);
if (out_route_data)
g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}"));
if (out_routes)
g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("aau"));
if (out_routes) {
if (IS_IPv4)
g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("aau"));
else
g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("a(ayuayu)"));
}
nm_dedup_multi_iter_init (&iter, head_entry);
while (nm_platform_dedup_multi_iter_next_ip4_route (&iter, &route)) {
GVariantBuilder route_builder;
while (nm_platform_dedup_multi_iter_next_obj (&iter, &obj, NMP_OBJECT_TYPE_IP_ROUTE (IS_IPv4))) {
const NMPlatformIPXRoute *r = NMP_OBJECT_CAST_IPX_ROUTE (obj);
struct in6_addr n;
nm_assert (_route_valid_4 (route));
nm_assert (r);
nm_assert (r->rx.plen <= 8u * nm_utils_addr_family_to_size (addr_family));
nm_assert ( !IS_IPv4
|| r->r4.network == nm_utils_ip4_address_clear_host_address (r->r4.network, r->r4.plen));
nm_assert ( IS_IPv4
|| (memcmp (&r->r6.network,
nm_utils_ip6_address_clear_host_address (&n, &r->r6.network, r->r6.plen),
sizeof (n)) == 0));
if (route->type_coerced != nm_platform_route_type_coerce (RTN_UNICAST))
if (r->rx.type_coerced != nm_platform_route_type_coerce (RTN_UNICAST))
continue;
if (out_route_data) {
GVariantBuilder route_builder;
gconstpointer gateway;
g_variant_builder_init (&route_builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&route_builder, "{sv}",
"dest",
g_variant_new_string (_nm_utils_inet4_ntop (route->network, addr_str)));
g_variant_new_string (nm_utils_inet_ntop (addr_family, r->rx.network_ptr, addr_str)));
g_variant_builder_add (&route_builder, "{sv}",
"prefix",
g_variant_new_uint32 (route->plen));
if (route->gateway) {
g_variant_new_uint32 (r->rx.plen));
gateway = nm_platform_ip_route_get_gateway (addr_family, &r->rx);
if (!nm_ip_addr_is_null (addr_family, gateway)) {
g_variant_builder_add (&route_builder, "{sv}",
"next-hop",
g_variant_new_string (_nm_utils_inet4_ntop (route->gateway, addr_str)));
g_variant_new_string (nm_utils_inet_ntop (addr_family, gateway, addr_str)));
}
g_variant_builder_add (&route_builder, "{sv}",
"metric",
g_variant_new_uint32 (route->metric));
g_variant_new_uint32 (r->rx.metric));
if (!nm_platform_route_table_is_main (route->table_coerced)) {
if (!nm_platform_route_table_is_main (r->rx.table_coerced)) {
g_variant_builder_add (&route_builder, "{sv}",
"table",
g_variant_new_uint32 (nm_platform_route_table_uncoerce (route->table_coerced, TRUE)));
g_variant_new_uint32 (nm_platform_route_table_uncoerce (r->rx.table_coerced, TRUE)));
}
g_variant_builder_add (&builder_data, "a{sv}", &route_builder);
}
if (out_routes) {
/* legacy versions of nm_ip4_route_set_prefix() in libnm-util assert that the
/* legacy versions of nm_ip[46]_route_set_prefix() in libnm-util assert that the
* plen is positive. Skip the default routes not to break older clients. */
if ( nm_platform_route_table_is_main (route->table_coerced)
&& !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) {
if ( !nm_platform_route_table_is_main (r->rx.table_coerced)
|| NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r))
continue;
if (IS_IPv4) {
const guint32 dbus_route[4] = {
route->network,
route->plen,
route->gateway,
route->metric,
r->r4.network,
r->r4.plen,
r->r4.gateway,
r->r4.metric,
};
g_variant_builder_add (&builder_legacy, "@au",
g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
dbus_route, 4, sizeof (guint32)));
}
}
}
NM_SET_OUT (out_route_data, g_variant_builder_end (&builder_data));
NM_SET_OUT (out_routes, g_variant_builder_end (&builder_legacy));
}
void
nm_utils_ip6_routes_to_dbus (const NMDedupMultiHeadEntry *head_entry,
GVariant **out_route_data,
GVariant **out_routes)
{
NMDedupMultiIter iter;
char sbuf[NM_UTILS_INET_ADDRSTRLEN];
const NMPlatformIP6Route *route;
GVariantBuilder builder_data;
GVariantBuilder builder_legacy;
if (out_route_data)
g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}"));
if (out_routes)
g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("a(ayuayu)"));
nm_dedup_multi_iter_init (&iter, head_entry);
while (nm_platform_dedup_multi_iter_next_ip6_route (&iter, &route)) {
nm_assert (_route_valid_6 (route));
if (route->type_coerced != nm_platform_route_type_coerce (RTN_UNICAST))
continue;
if (out_route_data) {
GVariantBuilder route_builder;
g_variant_builder_init (&route_builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&route_builder, "{sv}",
"dest",
g_variant_new_string (_nm_utils_inet6_ntop (&route->network, sbuf)));
g_variant_builder_add (&route_builder, "{sv}",
"prefix",
g_variant_new_uint32 (route->plen));
if (!IN6_IS_ADDR_UNSPECIFIED (&route->gateway)) {
g_variant_builder_add (&route_builder, "{sv}",
"next-hop",
g_variant_new_string (_nm_utils_inet6_ntop (&route->gateway, sbuf)));
}
g_variant_builder_add (&route_builder, "{sv}",
"metric",
g_variant_new_uint32 (route->metric));
if (!nm_platform_route_table_is_main (route->table_coerced)) {
g_variant_builder_add (&route_builder, "{sv}",
"table",
g_variant_new_uint32 (nm_platform_route_table_uncoerce (route->table_coerced, TRUE)));
}
g_variant_builder_add (&builder_data, "a{sv}", &route_builder);
}
if (out_routes) {
/* legacy versions of nm_ip6_route_set_prefix() in libnm-util assert that the
* plen is positive. Skip the default routes not to break older clients. */
if ( nm_platform_route_table_is_main (route->table_coerced)
&& !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) {
} else {
g_variant_builder_add (&builder_legacy, "(@ayu@ayu)",
g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
&route->network, 16, 1),
(guint32) route->plen,
&r->r6.network, 16, 1),
(guint32) r->r6.plen,
g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
&route->gateway, 16, 1),
(guint32) route->metric);
&r->r6.gateway, 16, 1),
(guint32) r->r6.metric);
}
}
}

View file

@ -147,23 +147,16 @@ void nm_utils_ip_route_attribute_to_platform (int addr_family,
NMPlatformIPRoute *r,
guint32 route_table);
void nm_utils_ip4_addresses_to_dbus (const NMDedupMultiHeadEntry *head_entry,
const NMPObject *best_default_route,
GVariant **out_address_data,
GVariant **out_addresses);
void nm_utils_ip_addresses_to_dbus (int addr_family,
const NMDedupMultiHeadEntry *head_entry,
const NMPObject *best_default_route,
NMSettingIP6ConfigPrivacy ipv6_privacy,
GVariant **out_address_data,
GVariant **out_addresses);
void nm_utils_ip6_addresses_to_dbus (const NMDedupMultiHeadEntry *head_entry,
NMSettingIP6ConfigPrivacy ipv6_privacy,
const NMPObject *best_default_route,
GVariant **out_address_data,
GVariant **out_addresses);
void nm_utils_ip4_routes_to_dbus (const NMDedupMultiHeadEntry *head_entry,
GVariant **out_route_data,
GVariant **out_routes);
void nm_utils_ip6_routes_to_dbus (const NMDedupMultiHeadEntry *head_entry,
GVariant **out_route_data,
GVariant **out_routes);
void nm_utils_ip_routes_to_dbus (int addr_family,
const NMDedupMultiHeadEntry *head_entry,
GVariant **out_route_data,
GVariant **out_routes);
#endif /* __NETWORKMANAGER_UTILS_H__ */

View file

@ -2956,10 +2956,12 @@ get_property (GObject *object, guint prop_id,
nm_assert (!!priv->address_data_variant == !!priv->addresses_variant);
if (!priv->address_data_variant) {
nm_utils_ip4_addresses_to_dbus (nm_ip4_config_lookup_addresses (self),
priv->best_default_route,
&priv->address_data_variant,
&priv->addresses_variant);
nm_utils_ip_addresses_to_dbus (AF_INET,
nm_ip4_config_lookup_addresses (self),
priv->best_default_route,
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
&priv->address_data_variant,
&priv->addresses_variant);
g_variant_ref_sink (priv->address_data_variant);
g_variant_ref_sink (priv->addresses_variant);
}
@ -2974,9 +2976,10 @@ get_property (GObject *object, guint prop_id,
nm_assert (!!priv->route_data_variant == !!priv->routes_variant);
if (!priv->route_data_variant) {
nm_utils_ip4_routes_to_dbus (nm_ip4_config_lookup_routes (self),
&priv->route_data_variant,
&priv->routes_variant);
nm_utils_ip_routes_to_dbus (AF_INET,
nm_ip4_config_lookup_routes (self),
&priv->route_data_variant,
&priv->routes_variant);
g_variant_ref_sink (priv->route_data_variant);
g_variant_ref_sink (priv->routes_variant);
}

View file

@ -2477,11 +2477,12 @@ get_property (GObject *object, guint prop_id,
nm_assert (!!priv->address_data_variant == !!priv->addresses_variant);
if (!priv->address_data_variant) {
nm_utils_ip6_addresses_to_dbus (nm_ip6_config_lookup_addresses (self),
priv->privacy,
priv->best_default_route,
&priv->address_data_variant,
&priv->addresses_variant);
nm_utils_ip_addresses_to_dbus (AF_INET6,
nm_ip6_config_lookup_addresses (self),
priv->best_default_route,
priv->privacy,
&priv->address_data_variant,
&priv->addresses_variant);
g_variant_ref_sink (priv->address_data_variant);
g_variant_ref_sink (priv->addresses_variant);
}
@ -2496,9 +2497,10 @@ get_property (GObject *object, guint prop_id,
nm_assert (!!priv->route_data_variant == !!priv->routes_variant);
if (!priv->route_data_variant) {
nm_utils_ip6_routes_to_dbus (nm_ip6_config_lookup_routes (self),
&priv->route_data_variant,
&priv->routes_variant);
nm_utils_ip_routes_to_dbus (AF_INET6,
nm_ip6_config_lookup_routes (self),
&priv->route_data_variant,
&priv->routes_variant);
g_variant_ref_sink (priv->route_data_variant);
g_variant_ref_sink (priv->routes_variant);
}