core: use nm_platform_ip[46]_address_pretty_sort_cmp() in "nm-ip[46]-config.c"

This commit is contained in:
Thomas Haller 2020-07-22 15:40:45 +02:00
parent 83bc1e8d60
commit 67bfcb49c9
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
5 changed files with 8 additions and 165 deletions

View file

@ -505,63 +505,11 @@ _notify_routes (NMIP4Config *self)
/*****************************************************************************/
static int
_addresses_sort_cmp_get_prio (in_addr_t addr)
{
if (nm_utils_ip4_address_is_link_local (addr))
return 0;
return 1;
}
static int
_addresses_sort_cmp (gconstpointer a, gconstpointer b, gpointer user_data)
{
int p1, p2;
const NMPlatformIP4Address *a1 = NMP_OBJECT_CAST_IP4_ADDRESS (*((const NMPObject **) a));
const NMPlatformIP4Address *a2 = NMP_OBJECT_CAST_IP4_ADDRESS (*((const NMPObject **) b));
guint32 n1, n2;
nm_assert (a1);
nm_assert (a2);
/* Sort by address type. For example link local will
* be sorted *after* a global address. */
p1 = _addresses_sort_cmp_get_prio (a1->address);
p2 = _addresses_sort_cmp_get_prio (a2->address);
if (p1 != p2)
return p1 > p2 ? -1 : 1;
/* Sort the addresses based on their source. */
if (a1->addr_source != a2->addr_source)
return a1->addr_source > a2->addr_source ? -1 : 1;
if ((a1->label[0] == '\0') != (a2->label[0] == '\0'))
return (a1->label[0] == '\0') ? -1 : 1;
/* Finally, sort addresses lexically. We compare only the
* network part so that the order of addresses in the same
* subnet (and thus also the primary/secondary role) is
* preserved.
*/
n1 = a1->address & _nm_utils_ip4_prefix_to_netmask (a1->plen);
n2 = a2->address & _nm_utils_ip4_prefix_to_netmask (a2->plen);
return memcmp (&n1, &n2, sizeof (guint32));
}
int
nmtst_ip4_config_addresses_sort_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b)
{
NMPObject o_a;
NMPObject o_b;
NMPObject *p_o_a = &o_a;
NMPObject *p_o_b = &o_b;
g_assert (a);
g_assert (b);
nmp_object_stackinit (&o_a, NMP_OBJECT_TYPE_IP4_ADDRESS, a);
nmp_object_stackinit (&o_b, NMP_OBJECT_TYPE_IP4_ADDRESS, b);
return _addresses_sort_cmp (&p_o_a, &p_o_b, NULL);
return nm_platform_ip4_address_pretty_sort_cmp (NMP_OBJECT_CAST_IP4_ADDRESS (*((const NMPObject **) a)),
NMP_OBJECT_CAST_IP4_ADDRESS (*((const NMPObject **) b)));
}
/*****************************************************************************/

View file

@ -603,6 +603,4 @@ nm_ip_config_intersect_alloc (const NMIPConfig *a,
}
}
int nmtst_ip4_config_addresses_sort_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b);
#endif /* __NETWORKMANAGER_IP4_CONFIG_H__ */

View file

@ -212,111 +212,20 @@ _notify_routes (NMIP6Config *self)
/*****************************************************************************/
static int
_addresses_sort_cmp_get_prio (const struct in6_addr *addr)
{
if (IN6_IS_ADDR_V4MAPPED (addr))
return 0;
if (IN6_IS_ADDR_V4COMPAT (addr))
return 1;
if (IN6_IS_ADDR_UNSPECIFIED (addr))
return 2;
if (IN6_IS_ADDR_LOOPBACK (addr))
return 3;
if (IN6_IS_ADDR_LINKLOCAL (addr))
return 4;
if (IN6_IS_ADDR_SITELOCAL (addr))
return 5;
return 6;
}
static int
_addresses_sort_cmp (const NMPlatformIP6Address *a1,
const NMPlatformIP6Address *a2,
gboolean prefer_temp)
{
int p1, p2, c;
gboolean perm1, perm2, tent1, tent2;
gboolean ipv6_privacy1, ipv6_privacy2;
/* tentative addresses are always sorted back... */
/* sort tentative addresses after non-tentative. */
tent1 = (a1->n_ifa_flags & IFA_F_TENTATIVE);
tent2 = (a2->n_ifa_flags & IFA_F_TENTATIVE);
if (tent1 != tent2)
return tent1 ? 1 : -1;
/* Sort by address type. For example link local will
* be sorted *after* site local or global. */
p1 = _addresses_sort_cmp_get_prio (&a1->address);
p2 = _addresses_sort_cmp_get_prio (&a2->address);
if (p1 != p2)
return p1 > p2 ? -1 : 1;
ipv6_privacy1 = !!(a1->n_ifa_flags & (IFA_F_MANAGETEMPADDR | IFA_F_TEMPORARY));
ipv6_privacy2 = !!(a2->n_ifa_flags & (IFA_F_MANAGETEMPADDR | IFA_F_TEMPORARY));
if (ipv6_privacy1 || ipv6_privacy2) {
gboolean public1 = TRUE, public2 = TRUE;
if (ipv6_privacy1) {
if (a1->n_ifa_flags & IFA_F_TEMPORARY)
public1 = prefer_temp;
else
public1 = !prefer_temp;
}
if (ipv6_privacy2) {
if (a2->n_ifa_flags & IFA_F_TEMPORARY)
public2 = prefer_temp;
else
public2 = !prefer_temp;
}
if (public1 != public2)
return public1 ? -1 : 1;
}
/* Sort the addresses based on their source. */
if (a1->addr_source != a2->addr_source)
return a1->addr_source > a2->addr_source ? -1 : 1;
/* sort permanent addresses before non-permanent. */
perm1 = (a1->n_ifa_flags & IFA_F_PERMANENT);
perm2 = (a2->n_ifa_flags & IFA_F_PERMANENT);
if (perm1 != perm2)
return perm1 ? -1 : 1;
/* finally sort addresses lexically */
c = memcmp (&a1->address, &a2->address, sizeof (a2->address));
return c != 0 ? c : memcmp (a1, a2, sizeof (*a1));
}
int
nmtst_ip6_config_addresses_sort_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6Address *b, gboolean prefer_temp)
{
g_assert (a);
g_assert (b);
return _addresses_sort_cmp (a, b, prefer_temp);
}
static int
_addresses_sort_cmp_prop (gconstpointer a, gconstpointer b, gpointer user_data)
{
return _addresses_sort_cmp (NMP_OBJECT_CAST_IP6_ADDRESS (*((const NMPObject **) a)),
NMP_OBJECT_CAST_IP6_ADDRESS (*((const NMPObject **) b)),
((NMSettingIP6ConfigPrivacy) GPOINTER_TO_INT (user_data)) == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR);
return nm_platform_ip6_address_pretty_sort_cmp (NMP_OBJECT_CAST_IP6_ADDRESS (*((const NMPObject **) a)),
NMP_OBJECT_CAST_IP6_ADDRESS (*((const NMPObject **) b)),
(((NMSettingIP6ConfigPrivacy) GPOINTER_TO_INT (user_data)) == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR));
}
static int
sort_captured_addresses (const CList *lst_a, const CList *lst_b, gconstpointer user_data)
{
const NMPlatformIP6Address *addr_a = NMP_OBJECT_CAST_IP6_ADDRESS (c_list_entry (lst_a, NMDedupMultiEntry, lst_entries)->obj);
const NMPlatformIP6Address *addr_b = NMP_OBJECT_CAST_IP6_ADDRESS (c_list_entry (lst_b, NMDedupMultiEntry, lst_entries)->obj);
nm_assert (addr_a);
nm_assert (addr_b);
return _addresses_sort_cmp (addr_a, addr_b,
((NMSettingIP6ConfigPrivacy) GPOINTER_TO_INT (user_data)) == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR);
return nm_platform_ip6_address_pretty_sort_cmp (NMP_OBJECT_CAST_IP6_ADDRESS (c_list_entry (lst_a, NMDedupMultiEntry, lst_entries)->obj),
NMP_OBJECT_CAST_IP6_ADDRESS (c_list_entry (lst_b, NMDedupMultiEntry, lst_entries)->obj),
(((NMSettingIP6ConfigPrivacy) GPOINTER_TO_INT (user_data)) == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR));
}
gboolean

View file

@ -220,6 +220,4 @@ void nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
void nm_ip6_config_update_routes_metric (NMIP6Config *self, gint64 metric);
int nmtst_ip6_config_addresses_sort_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6Address *b, gboolean prefer_temp);
#endif /* __NETWORKMANAGER_IP6_CONFIG_H__ */

View file

@ -9,7 +9,6 @@
#include "platform/nm-platform-utils.h"
#include "platform/nm-linux-platform.h"
#include "nm-ip4-config.h"
#include "nm-test-utils-core.h"
@ -670,27 +669,18 @@ test_platform_ip_address_pretty_sort_cmp (gconstpointer test_data)
const NMPlatformIPXAddress *b = (gconstpointer) (&addresses[j * ELM_SIZE]);
int c1;
int c2;
int c3;
int c4;
if (addr_family == AF_INET) {
c1 = nm_platform_ip4_address_pretty_sort_cmp (&a->a4, &b->a4);
c2 = nm_platform_ip4_address_pretty_sort_cmp (&b->a4, &a->a4);
c3 = nmtst_ip4_config_addresses_sort_cmp (&a->a4, &b->a4);
c4 = nmtst_ip4_config_addresses_sort_cmp (&b->a4, &a->a4);
} else {
c1 = nm_platform_ip6_address_pretty_sort_cmp (&a->a6, &b->a6, IPV6_PREFER_TEMP);
c2 = nm_platform_ip6_address_pretty_sort_cmp (&b->a6, &a->a6, IPV6_PREFER_TEMP);
c3 = nmtst_ip6_config_addresses_sort_cmp (&a->a6, &b->a6, IPV6_PREFER_TEMP);
c4 = nmtst_ip6_config_addresses_sort_cmp (&b->a6, &a->a6, IPV6_PREFER_TEMP);
}
#define _NORM(c) (((c) < 0) ? -1 : ((c) > 0))
g_assert_cmpint (c1, >=, -1);
g_assert_cmpint (c1, <=, 1);
g_assert_cmpint (c1, ==, -c2);
g_assert_cmpint (c1, ==, _NORM (c3));
g_assert_cmpint (c1, ==, -_NORM (c4));
}
}