mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-15 13:00:19 +01:00
platform: merge branch 'th/platform-ipv4-peer-address-bgo756356'
https://bugzilla.gnome.org/show_bug.cgi?id=756356
This commit is contained in:
commit
6786164e78
17 changed files with 1008 additions and 208 deletions
|
|
@ -577,6 +577,12 @@ nmtst_get_rand (void)
|
|||
return __nmtst_internal.rand;
|
||||
}
|
||||
|
||||
inline static guint32
|
||||
nmtst_get_rand_int (void)
|
||||
{
|
||||
return g_rand_int (nmtst_get_rand ());
|
||||
}
|
||||
|
||||
inline static const char *
|
||||
nmtst_get_sudo_cmd (void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4862,8 +4862,8 @@ check_and_add_ipv6ll_addr (NMDevice *self)
|
|||
if (!nm_platform_ip6_address_add (NM_PLATFORM_GET,
|
||||
ip_ifindex,
|
||||
lladdr,
|
||||
in6addr_any,
|
||||
64,
|
||||
in6addr_any,
|
||||
NM_PLATFORM_LIFETIME_PERMANENT,
|
||||
NM_PLATFORM_LIFETIME_PERMANENT,
|
||||
0)) {
|
||||
|
|
@ -6856,12 +6856,21 @@ nm_device_set_ip4_config (NMDevice *self,
|
|||
|
||||
if (nm_device_uses_generated_assumed_connection (self)) {
|
||||
NMConnection *connection = nm_device_get_applied_connection (self);
|
||||
NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self));
|
||||
NMSetting *s_ip4;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (connection));
|
||||
g_object_freeze_notify (G_OBJECT (settings_connection));
|
||||
|
||||
nm_connection_remove_setting (settings_connection, NM_TYPE_SETTING_IP4_CONFIG);
|
||||
s_ip4 = nm_ip4_config_create_setting (priv->ip4_config);
|
||||
nm_connection_add_setting (settings_connection, s_ip4);
|
||||
|
||||
nm_connection_remove_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
||||
s_ip4 = nm_ip4_config_create_setting (priv->ip4_config);
|
||||
nm_connection_add_setting (connection, s_ip4);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (settings_connection));
|
||||
g_object_thaw_notify (G_OBJECT (connection));
|
||||
}
|
||||
|
||||
|
|
@ -7014,12 +7023,21 @@ nm_device_set_ip6_config (NMDevice *self,
|
|||
|
||||
if (nm_device_uses_generated_assumed_connection (self)) {
|
||||
NMConnection *connection = nm_device_get_applied_connection (self);
|
||||
NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self));
|
||||
NMSetting *s_ip6;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (connection));
|
||||
g_object_freeze_notify (G_OBJECT (settings_connection));
|
||||
|
||||
nm_connection_remove_setting (settings_connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
|
||||
nm_connection_add_setting (settings_connection, s_ip6);
|
||||
|
||||
nm_connection_remove_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
|
||||
nm_connection_add_setting (connection, s_ip6);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (settings_connection));
|
||||
g_object_thaw_notify (G_OBJECT (connection));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -176,9 +176,11 @@ nm_ip4_config_capture_resolv_conf (GArray *nameservers,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
addresses_are_duplicate (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b, gboolean consider_plen)
|
||||
addresses_are_duplicate (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b)
|
||||
{
|
||||
return a->address == b->address && (!consider_plen || a->plen == b->plen);
|
||||
return a->address == b->address
|
||||
&& a->plen == b->plen
|
||||
&& nm_platform_ip4_address_equal_peer_net (a, b);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -661,8 +663,7 @@ _addresses_get_index (const NMIP4Config *self, const NMPlatformIP4Address *addr)
|
|||
for (i = 0; i < priv->addresses->len; i++) {
|
||||
const NMPlatformIP4Address *a = &g_array_index (priv->addresses, NMPlatformIP4Address, i);
|
||||
|
||||
if (addr->address == a->address &&
|
||||
addr->plen == a->plen)
|
||||
if (addresses_are_duplicate (addr, a))
|
||||
return (int) i;
|
||||
}
|
||||
return -1;
|
||||
|
|
@ -994,7 +995,8 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
|
|||
if (nm_platform_ip4_address_cmp (src_addr = nm_ip4_config_get_address (src, i),
|
||||
dst_addr = nm_ip4_config_get_address (dst, i))) {
|
||||
are_equal = FALSE;
|
||||
if (!addresses_are_duplicate (src_addr, dst_addr, TRUE)) {
|
||||
if ( !addresses_are_duplicate (src_addr, dst_addr)
|
||||
|| (nm_platform_ip4_address_get_peer (src_addr) != nm_platform_ip4_address_get_peer (dst_addr))) {
|
||||
has_relevant_changes = TRUE;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1367,7 +1369,7 @@ nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new)
|
|||
for (i = 0; i < priv->addresses->len; i++ ) {
|
||||
NMPlatformIP4Address *item = &g_array_index (priv->addresses, NMPlatformIP4Address, i);
|
||||
|
||||
if (addresses_are_duplicate (item, new, FALSE)) {
|
||||
if (addresses_are_duplicate (item, new)) {
|
||||
if (nm_platform_ip4_address_cmp (item, new) == 0)
|
||||
return;
|
||||
|
||||
|
|
@ -1434,16 +1436,7 @@ gboolean
|
|||
nm_ip4_config_address_exists (const NMIP4Config *config,
|
||||
const NMPlatformIP4Address *needle)
|
||||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->addresses->len; i++) {
|
||||
const NMPlatformIP4Address *haystack = &g_array_index (priv->addresses, NMPlatformIP4Address, i);
|
||||
|
||||
if (needle->address == haystack->address && needle->plen == haystack->plen)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
return _addresses_get_index (config, needle) >= 0;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
|
@ -2023,6 +2016,7 @@ nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only
|
|||
const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, i);
|
||||
hash_u32 (sum, address->address);
|
||||
hash_u32 (sum, address->plen);
|
||||
hash_u32 (sum, nm_platform_ip4_address_get_peer_net (address));
|
||||
}
|
||||
|
||||
for (i = 0; i < nm_ip4_config_get_num_routes (config); i++) {
|
||||
|
|
@ -2169,6 +2163,12 @@ get_property (GObject *object, guint prop_id,
|
|||
g_variant_builder_add (&addr_builder, "{sv}",
|
||||
"prefix",
|
||||
g_variant_new_uint32 (address->plen));
|
||||
if ( address->peer_address
|
||||
&& address->peer_address != address->address) {
|
||||
g_variant_builder_add (&addr_builder, "{sv}",
|
||||
"peer",
|
||||
g_variant_new_string (nm_utils_inet4_ntop (address->peer_address, NULL)));
|
||||
}
|
||||
|
||||
if (*address->label) {
|
||||
g_variant_builder_add (&addr_builder, "{sv}",
|
||||
|
|
|
|||
|
|
@ -176,9 +176,9 @@ nm_ip6_config_capture_resolv_conf (GArray *nameservers,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
addresses_are_duplicate (const NMPlatformIP6Address *a, const NMPlatformIP6Address *b, gboolean consider_plen)
|
||||
addresses_are_duplicate (const NMPlatformIP6Address *a, const NMPlatformIP6Address *b)
|
||||
{
|
||||
return IN6_ARE_ADDR_EQUAL (&a->address, &b->address) && (!consider_plen || a->plen == b->plen);
|
||||
return IN6_ARE_ADDR_EQUAL (&a->address, &b->address);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -731,7 +731,7 @@ _addresses_get_index (const NMIP6Config *self, const NMPlatformIP6Address *addr)
|
|||
for (i = 0; i < priv->addresses->len; i++) {
|
||||
const NMPlatformIP6Address *a = &g_array_index (priv->addresses, NMPlatformIP6Address, i);
|
||||
|
||||
if (IN6_ARE_ADDR_EQUAL (&addr->address, &a->address))
|
||||
if (addresses_are_duplicate (a, addr))
|
||||
return (int) i;
|
||||
}
|
||||
return -1;
|
||||
|
|
@ -1012,7 +1012,10 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
|
|||
if (nm_platform_ip6_address_cmp (src_addr = nm_ip6_config_get_address (src, i),
|
||||
dst_addr = nm_ip6_config_get_address (dst, i))) {
|
||||
are_equal = FALSE;
|
||||
if (!addresses_are_duplicate (src_addr, dst_addr, TRUE)) {
|
||||
if ( !addresses_are_duplicate (src_addr, dst_addr)
|
||||
|| src_addr->plen != dst_addr->plen
|
||||
|| !IN6_ARE_ADDR_EQUAL (nm_platform_ip6_address_get_peer (src_addr),
|
||||
nm_platform_ip6_address_get_peer (dst_addr))) {
|
||||
has_relevant_changes = TRUE;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1283,7 +1286,7 @@ nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new)
|
|||
for (i = 0; i < priv->addresses->len; i++ ) {
|
||||
NMPlatformIP6Address *item = &g_array_index (priv->addresses, NMPlatformIP6Address, i);
|
||||
|
||||
if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) {
|
||||
if (addresses_are_duplicate (item, new)) {
|
||||
if (nm_platform_ip6_address_cmp (item, new) == 0)
|
||||
return;
|
||||
|
||||
|
|
@ -1350,17 +1353,7 @@ gboolean
|
|||
nm_ip6_config_address_exists (const NMIP6Config *config,
|
||||
const NMPlatformIP6Address *needle)
|
||||
{
|
||||
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->addresses->len; i++) {
|
||||
const NMPlatformIP6Address *haystack = &g_array_index (priv->addresses, NMPlatformIP6Address, i);
|
||||
|
||||
if ( IN6_ARE_ADDR_EQUAL (&needle->address, &haystack->address)
|
||||
&& needle->plen == haystack->plen)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
return _addresses_get_index (config, needle) >= 0;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
|
@ -1940,6 +1933,12 @@ get_property (GObject *object, guint prop_id,
|
|||
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, NULL)));
|
||||
}
|
||||
|
||||
g_variant_builder_add (&array_builder, "a{sv}", &addr_builder);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,9 +87,14 @@ G_DEFINE_TYPE (NMFakePlatform, nm_fake_platform, NM_TYPE_PLATFORM)
|
|||
|
||||
static void link_changed (NMPlatform *platform, NMFakePlatformLink *device, gboolean raise_signal);
|
||||
|
||||
static gboolean ip6_address_add (NMPlatform *platform, int ifindex,
|
||||
struct in6_addr addr, struct in6_addr peer_addr,
|
||||
int plen, guint32 lifetime, guint32 preferred, guint flags);
|
||||
static gboolean ip6_address_add (NMPlatform *platform,
|
||||
int ifindex,
|
||||
struct in6_addr addr,
|
||||
int plen,
|
||||
struct in6_addr peer_addr,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
guint flags);
|
||||
static gboolean ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen);
|
||||
|
||||
/******************************************************************/
|
||||
|
|
@ -335,7 +340,7 @@ link_changed (NMPlatform *platform, NMFakePlatformLink *device, gboolean raise_s
|
|||
|
||||
if (device->link.ifindex && !IN6_IS_ADDR_UNSPECIFIED (&device->ip6_lladdr)) {
|
||||
if (device->link.connected)
|
||||
ip6_address_add (platform, device->link.ifindex, device->ip6_lladdr, in6addr_any, 64, NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0);
|
||||
ip6_address_add (platform, device->link.ifindex, in6addr_any, 64, device->ip6_lladdr, NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0);
|
||||
else
|
||||
ip6_address_delete (platform, device->link.ifindex, device->ip6_lladdr, 64);
|
||||
}
|
||||
|
|
@ -886,9 +891,13 @@ ip6_address_get_all (NMPlatform *platform, int ifindex)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
ip4_address_add (NMPlatform *platform, int ifindex,
|
||||
in_addr_t addr, in_addr_t peer_addr,
|
||||
int plen, guint32 lifetime, guint32 preferred,
|
||||
ip4_address_add (NMPlatform *platform,
|
||||
int ifindex,
|
||||
in_addr_t addr,
|
||||
int plen,
|
||||
in_addr_t peer_addr,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
const char *label)
|
||||
{
|
||||
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
|
||||
|
|
@ -899,7 +908,7 @@ ip4_address_add (NMPlatform *platform, int ifindex,
|
|||
address.source = NM_IP_CONFIG_SOURCE_KERNEL;
|
||||
address.ifindex = ifindex;
|
||||
address.address = addr;
|
||||
address.peer_address = peer_addr;
|
||||
address.peer_address = peer_addr && peer_addr != addr ? peer_addr : 0;
|
||||
address.plen = plen;
|
||||
address.timestamp = nm_utils_get_monotonic_timestamp_s ();
|
||||
address.lifetime = lifetime;
|
||||
|
|
@ -916,6 +925,8 @@ ip4_address_add (NMPlatform *platform, int ifindex,
|
|||
continue;
|
||||
if (item->plen != address.plen)
|
||||
continue;
|
||||
if (!nm_platform_ip4_address_equal_peer_net (item, &address))
|
||||
continue;
|
||||
|
||||
memcpy (item, &address, sizeof (address));
|
||||
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex, &address, NM_PLATFORM_SIGNAL_CHANGED, NM_PLATFORM_REASON_INTERNAL);
|
||||
|
|
@ -929,9 +940,13 @@ ip4_address_add (NMPlatform *platform, int ifindex,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
ip6_address_add (NMPlatform *platform, int ifindex,
|
||||
struct in6_addr addr, struct in6_addr peer_addr,
|
||||
int plen, guint32 lifetime, guint32 preferred, guint flags)
|
||||
ip6_address_add (NMPlatform *platform,
|
||||
int ifindex,
|
||||
struct in6_addr addr,
|
||||
int plen,
|
||||
struct in6_addr peer_addr,
|
||||
guint32 lifetime,
|
||||
guint32 preferred, guint flags)
|
||||
{
|
||||
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
|
||||
NMPlatformIP6Address address;
|
||||
|
|
@ -941,7 +956,7 @@ ip6_address_add (NMPlatform *platform, int ifindex,
|
|||
address.source = NM_IP_CONFIG_SOURCE_KERNEL;
|
||||
address.ifindex = ifindex;
|
||||
address.address = addr;
|
||||
address.peer_address = peer_addr;
|
||||
address.peer_address = (IN6_IS_ADDR_UNSPECIFIED (&peer_addr) || IN6_ARE_ADDR_EQUAL (&addr, &peer_addr)) ? in6addr_any : peer_addr;
|
||||
address.plen = plen;
|
||||
address.timestamp = nm_utils_get_monotonic_timestamp_s ();
|
||||
address.lifetime = lifetime;
|
||||
|
|
@ -1018,15 +1033,24 @@ ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int
|
|||
}
|
||||
|
||||
static const NMPlatformIP4Address *
|
||||
ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, int plen)
|
||||
ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, in_addr_t peer_address)
|
||||
{
|
||||
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
|
||||
int i;
|
||||
NMPlatformIP4Address a = {
|
||||
.ifindex = ifindex,
|
||||
.address = addr,
|
||||
.plen = plen,
|
||||
.peer_address = peer_address,
|
||||
};
|
||||
|
||||
for (i = 0; i < priv->ip4_addresses->len; i++) {
|
||||
NMPlatformIP4Address *address = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i);
|
||||
|
||||
if (address->ifindex == ifindex && address->plen == plen && address->address == addr)
|
||||
if ( address->ifindex == ifindex
|
||||
&& address->plen == plen
|
||||
&& address->address == addr
|
||||
&& nm_platform_ip4_address_equal_peer_net (address, &a))
|
||||
return address;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4238,8 +4238,8 @@ static gboolean
|
|||
ip4_address_add (NMPlatform *platform,
|
||||
int ifindex,
|
||||
in_addr_t addr,
|
||||
in_addr_t peer_addr,
|
||||
int plen,
|
||||
in_addr_t peer_addr,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
const char *label)
|
||||
|
|
@ -4252,7 +4252,7 @@ ip4_address_add (NMPlatform *platform,
|
|||
plen, lifetime, preferred, 0,
|
||||
label);
|
||||
return do_add_addrroute (platform,
|
||||
nmp_object_stackinit_id_ip4_address (&obj_needle, ifindex, addr, plen),
|
||||
nmp_object_stackinit_id_ip4_address (&obj_needle, ifindex, addr, plen, peer_addr),
|
||||
nlo);
|
||||
}
|
||||
|
||||
|
|
@ -4260,8 +4260,8 @@ static gboolean
|
|||
ip6_address_add (NMPlatform *platform,
|
||||
int ifindex,
|
||||
struct in6_addr addr,
|
||||
struct in6_addr peer_addr,
|
||||
int plen,
|
||||
struct in6_addr peer_addr,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
guint flags)
|
||||
|
|
@ -4283,8 +4283,7 @@ ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen,
|
|||
{
|
||||
NMPObject obj_needle;
|
||||
|
||||
nmp_object_stackinit_id_ip4_address (&obj_needle, ifindex, addr, plen);
|
||||
obj_needle.ip4_address.peer_address = peer_address;
|
||||
nmp_object_stackinit_id_ip4_address (&obj_needle, ifindex, addr, plen, peer_address);
|
||||
return do_delete_object (platform, &obj_needle, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -4298,12 +4297,12 @@ ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int
|
|||
}
|
||||
|
||||
static const NMPlatformIP4Address *
|
||||
ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, int plen)
|
||||
ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, in_addr_t peer_address)
|
||||
{
|
||||
NMPObject obj_needle;
|
||||
const NMPObject *obj;
|
||||
|
||||
nmp_object_stackinit_id_ip4_address (&obj_needle, ifindex, addr, plen);
|
||||
nmp_object_stackinit_id_ip4_address (&obj_needle, ifindex, addr, plen, peer_address);
|
||||
obj = nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle);
|
||||
if (nmp_object_is_visible (obj))
|
||||
return &obj->ip4_address;
|
||||
|
|
|
|||
|
|
@ -1823,6 +1823,43 @@ _to_string_dev (NMPlatform *self, int ifindex, char *buf, size_t size)
|
|||
|
||||
/******************************************************************/
|
||||
|
||||
in_addr_t
|
||||
nm_platform_ip4_address_get_peer (const NMPlatformIP4Address *addr)
|
||||
{
|
||||
return addr->peer_address ?: addr->address;
|
||||
}
|
||||
|
||||
const struct in6_addr *
|
||||
nm_platform_ip6_address_get_peer (const NMPlatformIP6Address *addr)
|
||||
{
|
||||
if ( IN6_IS_ADDR_UNSPECIFIED (&addr->peer_address)
|
||||
|| IN6_ARE_ADDR_EQUAL (&addr->peer_address, &addr->address))
|
||||
return &addr->address;
|
||||
return &addr->peer_address;
|
||||
}
|
||||
|
||||
in_addr_t
|
||||
nm_platform_ip4_address_get_peer_net (const NMPlatformIP4Address *addr)
|
||||
{
|
||||
return (addr->peer_address ?: addr->address) & nm_utils_ip4_prefix_to_netmask (addr->plen);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_ip4_address_equal_peer_net (const NMPlatformIP4Address *addr1, const NMPlatformIP4Address *addr2)
|
||||
{
|
||||
guint32 a1, a2;
|
||||
|
||||
if (addr1->plen != addr2->plen)
|
||||
return FALSE;
|
||||
|
||||
/* For kernel, if the peer address is unset, that effectively means that
|
||||
* the peer address equals the local address. */
|
||||
a1 = addr1->peer_address ? addr1->peer_address : addr1->address;
|
||||
a2 = addr2->peer_address ? addr2->peer_address : addr2->address;
|
||||
|
||||
return ((a1 ^ a2) & nm_utils_ip4_prefix_to_netmask (addr1->plen)) == 0;
|
||||
}
|
||||
|
||||
GArray *
|
||||
nm_platform_ip4_address_get_all (NMPlatform *self, int ifindex)
|
||||
{
|
||||
|
|
@ -1849,8 +1886,8 @@ gboolean
|
|||
nm_platform_ip4_address_add (NMPlatform *self,
|
||||
int ifindex,
|
||||
in_addr_t address,
|
||||
in_addr_t peer_address,
|
||||
int plen,
|
||||
in_addr_t peer_address,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
const char *label)
|
||||
|
|
@ -1879,15 +1916,15 @@ nm_platform_ip4_address_add (NMPlatform *self,
|
|||
|
||||
_LOGD ("address: adding or updating IPv4 address: %s", nm_platform_ip4_address_to_string (&addr));
|
||||
}
|
||||
return klass->ip4_address_add (self, ifindex, address, peer_address, plen, lifetime, preferred, label);
|
||||
return klass->ip4_address_add (self, ifindex, address, plen, peer_address, lifetime, preferred, label);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_ip6_address_add (NMPlatform *self,
|
||||
int ifindex,
|
||||
struct in6_addr address,
|
||||
struct in6_addr peer_address,
|
||||
int plen,
|
||||
struct in6_addr peer_address,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
guint flags)
|
||||
|
|
@ -1914,7 +1951,7 @@ nm_platform_ip6_address_add (NMPlatform *self,
|
|||
|
||||
_LOGD ("address: adding or updating IPv6 address: %s", nm_platform_ip6_address_to_string (&addr));
|
||||
}
|
||||
return klass->ip6_address_add (self, ifindex, address, peer_address, plen, lifetime, preferred, flags);
|
||||
return klass->ip6_address_add (self, ifindex, address, plen, peer_address, lifetime, preferred, flags);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
@ -1957,13 +1994,13 @@ nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr a
|
|||
}
|
||||
|
||||
const NMPlatformIP4Address *
|
||||
nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, int plen)
|
||||
nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, int plen, guint32 peer_address)
|
||||
{
|
||||
_CHECK_SELF (self, klass, NULL);
|
||||
|
||||
g_return_val_if_fail (plen > 0, NULL);
|
||||
|
||||
return klass->ip4_address_get (self, ifindex, address, plen);
|
||||
return klass->ip4_address_get (self, ifindex, address, plen, peer_address);
|
||||
}
|
||||
|
||||
const NMPlatformIP6Address *
|
||||
|
|
@ -1985,7 +2022,9 @@ array_contains_ip4_address (const GArray *addresses, const NMPlatformIP4Address
|
|||
for (i = 0; i < len; i++) {
|
||||
NMPlatformIP4Address *candidate = &g_array_index (addresses, NMPlatformIP4Address, i);
|
||||
|
||||
if (candidate->address == address->address && candidate->plen == address->plen) {
|
||||
if ( candidate->address == address->address
|
||||
&& candidate->plen == address->plen
|
||||
&& nm_platform_ip4_address_equal_peer_net (candidate, address)) {
|
||||
guint32 lifetime, preferred;
|
||||
|
||||
if (nmp_utils_lifetime_get (candidate->timestamp, candidate->lifetime, candidate->preferred,
|
||||
|
|
@ -2069,7 +2108,7 @@ nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArray *known
|
|||
now, ADDRESS_LIFETIME_PADDING, &lifetime, &preferred))
|
||||
continue;
|
||||
|
||||
if (!nm_platform_ip4_address_add (self, ifindex, known_address->address, known_address->peer_address, known_address->plen, lifetime, preferred, known_address->label))
|
||||
if (!nm_platform_ip4_address_add (self, ifindex, known_address->address, known_address->plen, known_address->peer_address, lifetime, preferred, known_address->label))
|
||||
return FALSE;
|
||||
|
||||
if (out_added_addresses) {
|
||||
|
|
@ -2130,7 +2169,7 @@ nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known
|
|||
continue;
|
||||
|
||||
if (!nm_platform_ip6_address_add (self, ifindex, known_address->address,
|
||||
known_address->peer_address, known_address->plen,
|
||||
known_address->plen, known_address->peer_address,
|
||||
lifetime, preferred, known_address->flags))
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -2692,7 +2731,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route)
|
|||
return _nm_platform_to_string_buffer;
|
||||
}
|
||||
|
||||
#define _CMP_POINTER(a, b) \
|
||||
#define _CMP_SELF(a, b) \
|
||||
G_STMT_START { \
|
||||
if ((a) == (b)) \
|
||||
return 0; \
|
||||
|
|
@ -2702,6 +2741,19 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route)
|
|||
return 1; \
|
||||
} G_STMT_END
|
||||
|
||||
#define _CMP_DIRECT(a, b) \
|
||||
G_STMT_START { \
|
||||
if ((a) != (b)) \
|
||||
return ((a) < (b)) ? -1 : 1; \
|
||||
} G_STMT_END
|
||||
|
||||
#define _CMP_DIRECT_MEMCMP(a, b, size) \
|
||||
G_STMT_START { \
|
||||
int c = memcmp ((a), (b), (size)); \
|
||||
if (c != 0) \
|
||||
return c < 0 ? -1 : 1; \
|
||||
} G_STMT_END
|
||||
|
||||
#define _CMP_FIELD(a, b, field) \
|
||||
G_STMT_START { \
|
||||
if (((a)->field) != ((b)->field)) \
|
||||
|
|
@ -2757,7 +2809,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route)
|
|||
int
|
||||
nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b)
|
||||
{
|
||||
_CMP_POINTER (a, b);
|
||||
_CMP_SELF (a, b);
|
||||
_CMP_FIELD (a, b, ifindex);
|
||||
_CMP_FIELD (a, b, type);
|
||||
_CMP_FIELD_STR (a, b, name);
|
||||
|
|
@ -2784,12 +2836,20 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b)
|
|||
int
|
||||
nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b)
|
||||
{
|
||||
_CMP_POINTER (a, b);
|
||||
in_addr_t p_a, p_b;
|
||||
|
||||
_CMP_SELF (a, b);
|
||||
_CMP_FIELD (a, b, ifindex);
|
||||
_CMP_FIELD (a, b, source);
|
||||
_CMP_FIELD (a, b, address);
|
||||
_CMP_FIELD (a, b, peer_address);
|
||||
_CMP_FIELD (a, b, plen);
|
||||
|
||||
/* a peer-address of zero is the same as setting it to address.
|
||||
* Here we consider the full address, including the host-part. */
|
||||
p_a = nm_platform_ip4_address_get_peer (a);
|
||||
p_b = nm_platform_ip4_address_get_peer (b);
|
||||
_CMP_DIRECT (p_a, p_b);
|
||||
|
||||
_CMP_FIELD (a, b, timestamp);
|
||||
_CMP_FIELD (a, b, lifetime);
|
||||
_CMP_FIELD (a, b, preferred);
|
||||
|
|
@ -2800,11 +2860,17 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A
|
|||
int
|
||||
nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6Address *b)
|
||||
{
|
||||
_CMP_POINTER (a, b);
|
||||
const struct in6_addr *p_a, *p_b;
|
||||
|
||||
_CMP_SELF (a, b);
|
||||
_CMP_FIELD (a, b, ifindex);
|
||||
_CMP_FIELD (a, b, source);
|
||||
_CMP_FIELD_MEMCMP (a, b, address);
|
||||
_CMP_FIELD_MEMCMP (a, b, peer_address);
|
||||
|
||||
p_a = nm_platform_ip6_address_get_peer (a);
|
||||
p_b = nm_platform_ip6_address_get_peer (b);
|
||||
_CMP_DIRECT_MEMCMP (p_a, p_b, sizeof (*p_a));
|
||||
|
||||
_CMP_FIELD (a, b, plen);
|
||||
_CMP_FIELD (a, b, timestamp);
|
||||
_CMP_FIELD (a, b, lifetime);
|
||||
|
|
@ -2816,7 +2882,7 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A
|
|||
int
|
||||
nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b)
|
||||
{
|
||||
_CMP_POINTER (a, b);
|
||||
_CMP_SELF (a, b);
|
||||
_CMP_FIELD (a, b, ifindex);
|
||||
_CMP_FIELD (a, b, source);
|
||||
_CMP_FIELD (a, b, network);
|
||||
|
|
@ -2832,7 +2898,7 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route
|
|||
int
|
||||
nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b)
|
||||
{
|
||||
_CMP_POINTER (a, b);
|
||||
_CMP_SELF (a, b);
|
||||
_CMP_FIELD (a, b, ifindex);
|
||||
_CMP_FIELD (a, b, source);
|
||||
_CMP_FIELD_MEMCMP (a, b, network);
|
||||
|
|
@ -2843,9 +2909,6 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route
|
|||
return 0;
|
||||
}
|
||||
|
||||
#undef _CMP_FIELD
|
||||
#undef _CMP_FIELD_MEMCMP
|
||||
|
||||
/**
|
||||
* nm_platform_ip_address_cmp_expiry:
|
||||
* @a: a NMPlatformIPAddress to compare
|
||||
|
|
@ -2864,7 +2927,7 @@ nm_platform_ip_address_cmp_expiry (const NMPlatformIPAddress *a, const NMPlatfor
|
|||
{
|
||||
gint64 ta = 0, tb = 0;
|
||||
|
||||
_CMP_POINTER (a, b);
|
||||
_CMP_SELF (a, b);
|
||||
|
||||
if (a->lifetime == NM_PLATFORM_LIFETIME_PERMANENT || a->lifetime == 0)
|
||||
ta = G_MAXINT64;
|
||||
|
|
@ -2897,8 +2960,6 @@ nm_platform_ip_address_cmp_expiry (const NMPlatformIPAddress *a, const NMPlatfor
|
|||
return ta < tb ? -1 : 1;
|
||||
}
|
||||
|
||||
#undef _CMP_POINTER
|
||||
|
||||
const char *
|
||||
nm_platform_signal_change_type_to_string (NMPlatformSignalChangeType change_type)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -513,16 +513,25 @@ typedef struct {
|
|||
|
||||
GArray * (*ip4_address_get_all) (NMPlatform *, int ifindex);
|
||||
GArray * (*ip6_address_get_all) (NMPlatform *, int ifindex);
|
||||
gboolean (*ip4_address_add) (NMPlatform *, int ifindex,
|
||||
in_addr_t address, in_addr_t peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft,
|
||||
gboolean (*ip4_address_add) (NMPlatform *,
|
||||
int ifindex,
|
||||
in_addr_t address,
|
||||
int plen,
|
||||
in_addr_t peer_address,
|
||||
guint32 lifetime,
|
||||
guint32 preferred_lft,
|
||||
const char *label);
|
||||
gboolean (*ip6_address_add) (NMPlatform *, int ifindex,
|
||||
struct in6_addr address, struct in6_addr peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft, guint flags);
|
||||
gboolean (*ip6_address_add) (NMPlatform *,
|
||||
int ifindex,
|
||||
struct in6_addr address,
|
||||
int plen,
|
||||
struct in6_addr peer_address,
|
||||
guint32 lifetime,
|
||||
guint32 preferred_lft,
|
||||
guint flags);
|
||||
gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, int plen, in_addr_t peer_address);
|
||||
gboolean (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, int plen);
|
||||
const NMPlatformIP4Address *(*ip4_address_get) (NMPlatform *, int ifindex, in_addr_t address, int plen);
|
||||
const NMPlatformIP4Address *(*ip4_address_get) (NMPlatform *, int ifindex, in_addr_t address, int plen, in_addr_t peer_address);
|
||||
const NMPlatformIP6Address *(*ip6_address_get) (NMPlatform *, int ifindex, struct in6_addr address, int plen);
|
||||
|
||||
GArray * (*ip4_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteFlags flags);
|
||||
|
|
@ -696,17 +705,31 @@ guint32 nm_platform_mesh_get_channel (NMPlatform *self, int ifindex);
|
|||
gboolean nm_platform_mesh_set_channel (NMPlatform *self, int ifindex, guint32 channel);
|
||||
gboolean nm_platform_mesh_set_ssid (NMPlatform *self, int ifindex, const guint8 *ssid, gsize len);
|
||||
|
||||
const NMPlatformIP4Address *nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, int plen);
|
||||
in_addr_t nm_platform_ip4_address_get_peer (const NMPlatformIP4Address *addr);
|
||||
const struct in6_addr *nm_platform_ip6_address_get_peer (const NMPlatformIP6Address *addr);
|
||||
in_addr_t nm_platform_ip4_address_get_peer_net (const NMPlatformIP4Address *addr);
|
||||
gboolean nm_platform_ip4_address_equal_peer_net (const NMPlatformIP4Address *addr1, const NMPlatformIP4Address *addr2);
|
||||
|
||||
const NMPlatformIP4Address *nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, int plen, in_addr_t peer_address);
|
||||
const NMPlatformIP6Address *nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address, int plen);
|
||||
GArray *nm_platform_ip4_address_get_all (NMPlatform *self, int ifindex);
|
||||
GArray *nm_platform_ip6_address_get_all (NMPlatform *self, int ifindex);
|
||||
gboolean nm_platform_ip4_address_add (NMPlatform *self, int ifindex,
|
||||
in_addr_t address, in_addr_t peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft,
|
||||
gboolean nm_platform_ip4_address_add (NMPlatform *self,
|
||||
int ifindex,
|
||||
in_addr_t address,
|
||||
int plen,
|
||||
in_addr_t peer_address,
|
||||
guint32 lifetime,
|
||||
guint32 preferred_lft,
|
||||
const char *label);
|
||||
gboolean nm_platform_ip6_address_add (NMPlatform *self, int ifindex,
|
||||
struct in6_addr address, struct in6_addr peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft, guint flags);
|
||||
gboolean nm_platform_ip6_address_add (NMPlatform *self,
|
||||
int ifindex,
|
||||
struct in6_addr address,
|
||||
int plen,
|
||||
struct in6_addr peer_address,
|
||||
guint32 lifetime,
|
||||
guint32 preferred_lft,
|
||||
guint flags);
|
||||
gboolean nm_platform_ip4_address_delete (NMPlatform *self, int ifindex, in_addr_t address, int plen, in_addr_t peer_address);
|
||||
gboolean nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr address, int plen);
|
||||
gboolean nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArray *known_addresses, GPtrArray **out_added_addresses);
|
||||
|
|
|
|||
|
|
@ -296,19 +296,20 @@ _vt_cmd_obj_stackinit_id_link (NMPObject *obj, const NMPObject *src)
|
|||
}
|
||||
|
||||
const NMPObject *
|
||||
nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifindex, guint32 address, int plen)
|
||||
nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifindex, guint32 address, int plen, guint32 peer_address)
|
||||
{
|
||||
nmp_object_stackinit (obj, NMP_OBJECT_TYPE_IP4_ADDRESS, NULL);
|
||||
obj->ip4_address.ifindex = ifindex;
|
||||
obj->ip4_address.address = address;
|
||||
obj->ip4_address.plen = plen;
|
||||
obj->ip4_address.peer_address = peer_address;
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void
|
||||
_vt_cmd_obj_stackinit_id_ip4_address (NMPObject *obj, const NMPObject *src)
|
||||
{
|
||||
nmp_object_stackinit_id_ip4_address (obj, src->ip_address.ifindex, src->ip4_address.address, src->ip_address.plen);
|
||||
nmp_object_stackinit_id_ip4_address (obj, src->ip_address.ifindex, src->ip4_address.address, src->ip_address.plen, src->ip4_address.peer_address);
|
||||
}
|
||||
|
||||
const NMPObject *
|
||||
|
|
@ -425,17 +426,21 @@ _vt_cmd_plobj_to_string_id_##type (const NMPlatformObject *_obj, char *buf, gsiz
|
|||
{ \
|
||||
plat_type *const obj = (plat_type *) _obj; \
|
||||
char buf1[NM_UTILS_INET_ADDRSTRLEN]; \
|
||||
char buf2[NM_UTILS_INET_ADDRSTRLEN]; \
|
||||
\
|
||||
(void) buf1; \
|
||||
(void) buf2; \
|
||||
g_snprintf (buf, buf_len, \
|
||||
__VA_ARGS__); \
|
||||
return buf; \
|
||||
}
|
||||
_vt_cmd_plobj_to_string_id (link, NMPlatformLink, "%d", obj->ifindex);
|
||||
_vt_cmd_plobj_to_string_id (ip4_address, NMPlatformIP4Address, "%d: %s/%d", obj->ifindex, nm_utils_inet4_ntop ( obj->address, buf1), obj->plen);
|
||||
_vt_cmd_plobj_to_string_id (ip6_address, NMPlatformIP6Address, "%d: %s/%d", obj->ifindex, nm_utils_inet6_ntop (&obj->address, buf1), obj->plen);
|
||||
_vt_cmd_plobj_to_string_id (ip4_route, NMPlatformIP4Route, "%d: %s/%d %d", obj->ifindex, nm_utils_inet4_ntop ( obj->network, buf1), obj->plen, obj->metric);
|
||||
_vt_cmd_plobj_to_string_id (ip6_route, NMPlatformIP6Route, "%d: %s/%d %d", obj->ifindex, nm_utils_inet6_ntop (&obj->network, buf1), obj->plen, obj->metric);
|
||||
_vt_cmd_plobj_to_string_id (link, NMPlatformLink, "%d", obj->ifindex);
|
||||
_vt_cmd_plobj_to_string_id (ip4_address, NMPlatformIP4Address, "%d: %s/%d%s%s", obj->ifindex, nm_utils_inet4_ntop ( obj->address, buf1), obj->plen,
|
||||
obj->peer_address && obj->peer_address != obj->address ? "," : "",
|
||||
obj->peer_address && obj->peer_address != obj->address ? nm_utils_inet4_ntop (nm_platform_ip4_address_get_peer_net (obj), buf2) : "");
|
||||
_vt_cmd_plobj_to_string_id (ip6_address, NMPlatformIP6Address, "%d: %s", obj->ifindex, nm_utils_inet6_ntop (&obj->address, buf1));
|
||||
_vt_cmd_plobj_to_string_id (ip4_route, NMPlatformIP4Route, "%d: %s/%d %d", obj->ifindex, nm_utils_inet4_ntop ( obj->network, buf1), obj->plen, obj->metric);
|
||||
_vt_cmd_plobj_to_string_id (ip6_route, NMPlatformIP6Route, "%d: %s/%d %d", obj->ifindex, nm_utils_inet6_ntop (&obj->network, buf1), obj->plen, obj->metric);
|
||||
|
||||
int
|
||||
nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2)
|
||||
|
|
@ -533,10 +538,10 @@ _vt_cmd_plobj_id_copy (ip4_address, NMPlatformIP4Address, {
|
|||
dst->ifindex = src->ifindex;
|
||||
dst->plen = src->plen;
|
||||
dst->address = src->address;
|
||||
dst->peer_address = src->peer_address;
|
||||
});
|
||||
_vt_cmd_plobj_id_copy (ip6_address, NMPlatformIP6Address, {
|
||||
dst->ifindex = src->ifindex;
|
||||
dst->plen = src->plen;
|
||||
dst->address = src->address;
|
||||
});
|
||||
_vt_cmd_plobj_id_copy (ip4_route, NMPlatformIP4Route, {
|
||||
|
|
@ -619,10 +624,13 @@ _vt_cmd_plobj_id_equal (link, NMPlatformLink,
|
|||
_vt_cmd_plobj_id_equal (ip4_address, NMPlatformIP4Address,
|
||||
obj1->ifindex == obj2->ifindex
|
||||
&& obj1->plen == obj2->plen
|
||||
&& obj1->address == obj2->address);
|
||||
&& obj1->address == obj2->address
|
||||
/* for IPv4 addresses, you can add the same local address with differing peer-adddress
|
||||
* (IFA_ADDRESS), provided that their net-part differs. */
|
||||
&& nm_platform_ip4_address_equal_peer_net (obj1, obj2));
|
||||
_vt_cmd_plobj_id_equal (ip6_address, NMPlatformIP6Address,
|
||||
obj1->ifindex == obj2->ifindex
|
||||
&& obj1->plen == obj2->plen
|
||||
/* for IPv6 addresses, the prefix length is not part of the primary identifier. */
|
||||
&& IN6_ARE_ADDR_EQUAL (&obj1->address, &obj2->address));
|
||||
_vt_cmd_plobj_id_equal (ip4_route, NMPlatformIP4Route,
|
||||
obj1->ifindex == obj2->ifindex
|
||||
|
|
@ -655,34 +663,25 @@ _vt_cmd_plobj_id_hash_##type (const NMPlatformObject *_obj) \
|
|||
return hash; \
|
||||
}
|
||||
_vt_cmd_plobj_id_hash (link, NMPlatformLink, {
|
||||
/* libnl considers:
|
||||
* .oo_id_attrs = LINK_ATTR_IFINDEX | LINK_ATTR_FAMILY,
|
||||
*/
|
||||
hash = (guint) 3982791431u;
|
||||
hash = hash + ((guint) obj->ifindex);
|
||||
})
|
||||
_vt_cmd_plobj_id_hash (ip4_address, NMPlatformIP4Address, {
|
||||
/* libnl considers:
|
||||
* .oo_id_attrs = (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX |
|
||||
* ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN),
|
||||
*/
|
||||
hash = (guint) 3591309853u;
|
||||
hash = hash + ((guint) obj->ifindex);
|
||||
hash = hash * 33 + ((guint) obj->plen);
|
||||
hash = hash * 33 + ((guint) obj->address);
|
||||
|
||||
/* for IPv4 we must also consider the net-part of the peer-address (IFA_ADDRESS) */
|
||||
hash = hash * 33 + ((guint) (nm_platform_ip4_address_get_peer_net (obj)));
|
||||
})
|
||||
_vt_cmd_plobj_id_hash (ip6_address, NMPlatformIP6Address, {
|
||||
hash = (guint) 2907861637u;
|
||||
hash = hash + ((guint) obj->ifindex);
|
||||
hash = hash * 33 + ((guint) obj->plen);
|
||||
/* for IPv6 addresses, the prefix length is not part of the primary identifier. */
|
||||
hash = hash * 33 + _id_hash_ip6_addr (&obj->address);
|
||||
})
|
||||
_vt_cmd_plobj_id_hash (ip4_route, NMPlatformIP4Route, {
|
||||
/* libnl considers:
|
||||
* .oo_id_attrs = (ROUTE_ATTR_FAMILY | ROUTE_ATTR_TOS |
|
||||
* ROUTE_ATTR_TABLE | ROUTE_ATTR_DST |
|
||||
* ROUTE_ATTR_PRIO),
|
||||
*/
|
||||
hash = (guint) 2569857221u;
|
||||
hash = hash + ((guint) obj->ifindex);
|
||||
hash = hash * 33 + ((guint) obj->plen);
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ NMPObject *nmp_object_new_link (int ifindex);
|
|||
const NMPObject *nmp_object_stackinit (NMPObject *obj, NMPObjectType obj_type, const NMPlatformObject *plobj);
|
||||
const NMPObject *nmp_object_stackinit_id (NMPObject *obj, const NMPObject *src);
|
||||
const NMPObject *nmp_object_stackinit_id_link (NMPObject *obj, int ifindex);
|
||||
const NMPObject *nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifindex, guint32 address, int plen);
|
||||
const NMPObject *nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifindex, guint32 address, int plen, guint32 peer_address);
|
||||
const NMPObject *nmp_object_stackinit_id_ip6_address (NMPObject *obj, int ifindex, const struct in6_addr *address, int plen);
|
||||
const NMPObject *nmp_object_stackinit_id_ip4_route (NMPObject *obj, int ifindex, guint32 network, int plen, guint32 metric);
|
||||
const NMPObject *nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6_addr *network, int plen, guint32 metric);
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ do_ip4_address_add (char **argv)
|
|||
guint32 lifetime = strtol (*argv++, NULL, 10);
|
||||
guint32 preferred = strtol (*argv++, NULL, 10);
|
||||
|
||||
gboolean value = nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, address, 0, plen, lifetime, preferred, NULL);
|
||||
gboolean value = nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, address, plen, 0, lifetime, preferred, NULL);
|
||||
return value;
|
||||
} else
|
||||
return FALSE;
|
||||
|
|
@ -601,7 +601,7 @@ do_ip6_address_add (char **argv)
|
|||
guint32 preferred = strtol (*argv++, NULL, 10);
|
||||
guint flags = (*argv) ? rtnl_addr_str2flags (*argv++) : 0;
|
||||
|
||||
gboolean value = nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, address, in6addr_any, plen, lifetime, preferred, flags);
|
||||
gboolean value = nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, address, plen, in6addr_any, lifetime, preferred, flags);
|
||||
return value;
|
||||
} else
|
||||
return FALSE;
|
||||
|
|
@ -624,11 +624,11 @@ do_ip6_address_add (char **argv)
|
|||
} else \
|
||||
return FALSE; \
|
||||
}
|
||||
#define ADDR_CMD(cmdname) ADDR_CMD_FULL (ip4, cmdname, FALSE, 0) ADDR_CMD_FULL (ip6, cmdname, FALSE)
|
||||
#define ADDR_CMD_PRINT(cmdname) ADDR_CMD_FULL (ip4, cmdname, TRUE) ADDR_CMD_FULL (ip6, cmdname, TRUE)
|
||||
#define ADDR_CMD(cmdname, ...) ADDR_CMD_FULL (ip4, cmdname, FALSE, 0, ##__VA_ARGS__) ADDR_CMD_FULL (ip6, cmdname, FALSE)
|
||||
#define ADDR_CMD_PRINT(cmdname, ...) ADDR_CMD_FULL (ip4, cmdname, TRUE, ##__VA_ARGS__) ADDR_CMD_FULL (ip6, cmdname, TRUE)
|
||||
|
||||
ADDR_CMD (delete)
|
||||
ADDR_CMD_PRINT (get)
|
||||
ADDR_CMD_PRINT (get, 0)
|
||||
|
||||
static gboolean
|
||||
do_ip4_route_get_all (char **argv)
|
||||
|
|
|
|||
|
|
@ -4,10 +4,17 @@
|
|||
|
||||
#define DEVICE_NAME "nm-test-device"
|
||||
#define IP4_ADDRESS "192.0.2.1"
|
||||
#define IP4_ADDRESS_PEER "192.0.2.2"
|
||||
#define IP4_ADDRESS_PEER2 "192.0.3.1"
|
||||
#define IP4_PLEN 24
|
||||
#define IP6_ADDRESS "2001:db8:a:b:1:2:3:4"
|
||||
#define IP6_PLEN 64
|
||||
|
||||
static int DEVICE_IFINDEX = -1;
|
||||
static int EX = -1;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
ip4_address_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlatformIP4Address *received, NMPlatformSignalChangeType change_type, NMPlatformReason reason, SignalData *data)
|
||||
{
|
||||
|
|
@ -48,10 +55,12 @@ ip6_address_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex,
|
|||
_LOGD ("Received signal '%s' %dth time.", data->name, data->received_count);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_ip4_address (void)
|
||||
test_ip4_address_general (void)
|
||||
{
|
||||
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
|
||||
const int ifindex = DEVICE_IFINDEX;
|
||||
SignalData *address_added = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_address_callback, ifindex);
|
||||
SignalData *address_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip4_address_callback, ifindex);
|
||||
SignalData *address_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_address_callback, ifindex);
|
||||
|
|
@ -64,13 +73,13 @@ test_ip4_address (void)
|
|||
inet_pton (AF_INET, IP4_ADDRESS, &addr);
|
||||
|
||||
/* Add address */
|
||||
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
|
||||
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
|
||||
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
|
||||
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
|
||||
nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, 0, lifetime, preferred, NULL);
|
||||
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
|
||||
accept_signal (address_added);
|
||||
|
||||
/* Add address again (aka update) */
|
||||
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
|
||||
nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, 0, lifetime + 100, preferred + 50, NULL);
|
||||
accept_signals (address_changed, 0, 1);
|
||||
|
||||
/* Test address listing */
|
||||
|
|
@ -84,12 +93,12 @@ test_ip4_address (void)
|
|||
g_array_unref (addresses);
|
||||
|
||||
/* Remove address */
|
||||
g_assert (nm_platform_ip4_address_delete (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
|
||||
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
|
||||
nmtstp_ip4_address_del (EX, ifindex, addr, IP4_PLEN, 0);
|
||||
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
|
||||
accept_signal (address_removed);
|
||||
|
||||
/* Remove address again */
|
||||
g_assert (nm_platform_ip4_address_delete (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
|
||||
nmtstp_ip4_address_del (EX, ifindex, addr, IP4_PLEN, 0);
|
||||
|
||||
free_signal (address_added);
|
||||
free_signal (address_changed);
|
||||
|
|
@ -97,9 +106,9 @@ test_ip4_address (void)
|
|||
}
|
||||
|
||||
static void
|
||||
test_ip6_address (void)
|
||||
test_ip6_address_general (void)
|
||||
{
|
||||
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
|
||||
const int ifindex = DEVICE_IFINDEX;
|
||||
SignalData *address_added = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip6_address_callback, ifindex);
|
||||
SignalData *address_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip6_address_callback, ifindex);
|
||||
SignalData *address_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip6_address_callback, ifindex);
|
||||
|
|
@ -114,12 +123,12 @@ test_ip6_address (void)
|
|||
|
||||
/* Add address */
|
||||
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr, in6addr_any, IP6_PLEN, lifetime, preferred, flags));
|
||||
nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags);
|
||||
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
accept_signal (address_added);
|
||||
|
||||
/* Add address again (aka update) */
|
||||
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr, in6addr_any, IP6_PLEN, lifetime, preferred, flags));
|
||||
nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags);
|
||||
accept_signals (address_changed, 0, 1);
|
||||
|
||||
/* Test address listing */
|
||||
|
|
@ -133,12 +142,12 @@ test_ip6_address (void)
|
|||
g_array_unref (addresses);
|
||||
|
||||
/* Remove address */
|
||||
g_assert (nm_platform_ip6_address_delete (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
nmtstp_ip6_address_del (EX, ifindex, addr, IP6_PLEN);
|
||||
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
accept_signal (address_removed);
|
||||
|
||||
/* Remove address again */
|
||||
g_assert (nm_platform_ip6_address_delete (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
nmtstp_ip6_address_del (EX, ifindex, addr, IP6_PLEN);
|
||||
|
||||
free_signal (address_added);
|
||||
free_signal (address_changed);
|
||||
|
|
@ -146,11 +155,11 @@ test_ip6_address (void)
|
|||
}
|
||||
|
||||
static void
|
||||
test_ip4_address_external (void)
|
||||
test_ip4_address_general_2 (void)
|
||||
{
|
||||
const int ifindex = DEVICE_IFINDEX;
|
||||
SignalData *address_added = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_address_callback);
|
||||
SignalData *address_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_address_callback);
|
||||
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
|
||||
in_addr_t addr;
|
||||
guint32 lifetime = 2000;
|
||||
guint32 preferred = 1000;
|
||||
|
|
@ -161,38 +170,31 @@ test_ip4_address_external (void)
|
|||
/* Looks like addresses are not announced by kerenl when the interface
|
||||
* is down. Link-local IPv6 address is automatically added.
|
||||
*/
|
||||
g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME), NULL));
|
||||
g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, DEVICE_IFINDEX, NULL));
|
||||
|
||||
/* Add/delete notification */
|
||||
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
|
||||
IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred);
|
||||
wait_signal (address_added);
|
||||
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
|
||||
run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME);
|
||||
wait_signal (address_removed);
|
||||
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
|
||||
nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, 0, lifetime, preferred, NULL);
|
||||
accept_signal (address_added);
|
||||
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
|
||||
nmtstp_ip4_address_del (EX, ifindex, addr, IP4_PLEN, 0);
|
||||
accept_signal (address_removed);
|
||||
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
|
||||
|
||||
/* Add/delete conflict */
|
||||
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
|
||||
IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred);
|
||||
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
|
||||
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
|
||||
nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, 0, lifetime, preferred, NULL);
|
||||
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
|
||||
accept_signal (address_added);
|
||||
/*run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME);
|
||||
g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN, 0));
|
||||
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
|
||||
accept_signal (address_removed);*/
|
||||
|
||||
free_signal (address_added);
|
||||
free_signal (address_removed);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ip6_address_external (void)
|
||||
test_ip6_address_general_2 (void)
|
||||
{
|
||||
const int ifindex = DEVICE_IFINDEX;
|
||||
SignalData *address_added = add_signal (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip6_address_callback);
|
||||
SignalData *address_removed = add_signal (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip6_address_callback);
|
||||
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
|
||||
struct in6_addr addr;
|
||||
guint32 lifetime = 2000;
|
||||
guint32 preferred = 1000;
|
||||
|
|
@ -201,51 +203,143 @@ test_ip6_address_external (void)
|
|||
inet_pton (AF_INET6, IP6_ADDRESS, &addr);
|
||||
|
||||
/* Add/delete notification */
|
||||
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
|
||||
IP6_ADDRESS, IP6_PLEN, DEVICE_NAME, lifetime, preferred);
|
||||
wait_signal (address_added);
|
||||
nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, 0);
|
||||
accept_signal (address_added);
|
||||
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
run_command ("ip address delete %s/%d dev %s", IP6_ADDRESS, IP6_PLEN, DEVICE_NAME);
|
||||
wait_signal (address_removed);
|
||||
|
||||
nmtstp_ip6_address_del (EX, ifindex, addr, IP6_PLEN);
|
||||
accept_signal (address_removed);
|
||||
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
|
||||
/* Add/delete conflict */
|
||||
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
|
||||
IP6_ADDRESS, IP6_PLEN, DEVICE_NAME, lifetime, preferred);
|
||||
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr, in6addr_any, IP6_PLEN, lifetime, preferred, flags));
|
||||
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, 0);
|
||||
accept_signal (address_added);
|
||||
/*run_command ("ip address delete %s/%d dev %s", IP6_ADDRESS, IP6_PLEN, DEVICE_NAME);
|
||||
g_assert (nm_platform_ip6_address_delete (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
wait_signal (address_removed);*/
|
||||
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
|
||||
nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags);
|
||||
ensure_no_signal (address_added);
|
||||
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
|
||||
|
||||
free_signal (address_added);
|
||||
free_signal (address_removed);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_ip4_address_peer (void)
|
||||
{
|
||||
const int ifindex = DEVICE_IFINDEX;
|
||||
SignalData *address_added = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_address_callback);
|
||||
SignalData *address_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_address_callback);
|
||||
in_addr_t addr, addr_peer, addr_peer2;
|
||||
guint32 lifetime = 2000;
|
||||
guint32 preferred = 1000;
|
||||
const NMPlatformIP4Address *a;
|
||||
|
||||
inet_pton (AF_INET, IP4_ADDRESS, &addr);
|
||||
inet_pton (AF_INET, IP4_ADDRESS_PEER, &addr_peer);
|
||||
inet_pton (AF_INET, IP4_ADDRESS_PEER2, &addr_peer2);
|
||||
g_assert (ifindex > 0);
|
||||
|
||||
g_assert (addr != addr_peer);
|
||||
|
||||
g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL));
|
||||
accept_signals (address_removed, 0, G_MAXINT);
|
||||
accept_signals (address_added, 0, G_MAXINT);
|
||||
|
||||
/* Add/delete notification */
|
||||
nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr_peer, lifetime, preferred, NULL);
|
||||
accept_signal (address_added);
|
||||
g_assert ((a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer)));
|
||||
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2));
|
||||
|
||||
nmtstp_ip_address_assert_lifetime ((NMPlatformIPAddress *) a, -1, lifetime, preferred);
|
||||
|
||||
nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr_peer2, lifetime, preferred, NULL);
|
||||
accept_signal (address_added);
|
||||
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer));
|
||||
g_assert ((a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2)));
|
||||
|
||||
nmtstp_ip_address_assert_lifetime ((NMPlatformIPAddress *) a, -1, lifetime, preferred);
|
||||
|
||||
g_assert (addr != addr_peer);
|
||||
nmtstp_ip4_address_del (EX, ifindex, addr, IP4_PLEN, addr_peer);
|
||||
accept_signal (address_removed);
|
||||
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer));
|
||||
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2));
|
||||
|
||||
free_signal (address_added);
|
||||
free_signal (address_removed);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
init_tests (int *argc, char ***argv)
|
||||
{
|
||||
nmtst_init_with_logging (argc, argv, NULL, "ALL");
|
||||
}
|
||||
|
||||
void
|
||||
setup_tests (void)
|
||||
/*****************************************************************************
|
||||
* SETUP TESTS
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
const char *testpath;
|
||||
GTestFunc test_func;
|
||||
} TestSetup;
|
||||
|
||||
static void
|
||||
_g_test_run (gconstpointer user_data)
|
||||
{
|
||||
SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME);
|
||||
const TestSetup *s = user_data;
|
||||
int ifindex;
|
||||
|
||||
_LOGt ("TEST: start %s", s->testpath);
|
||||
|
||||
nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME));
|
||||
g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME));
|
||||
g_assert (nm_platform_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == NM_PLATFORM_ERROR_SUCCESS);
|
||||
accept_signal (link_added);
|
||||
free_signal (link_added);
|
||||
g_assert_cmpint (nm_platform_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL), ==, NM_PLATFORM_ERROR_SUCCESS);
|
||||
|
||||
g_test_add_func ("/address/internal/ip4", test_ip4_address);
|
||||
g_test_add_func ("/address/internal/ip6", test_ip6_address);
|
||||
ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
|
||||
g_assert_cmpint (ifindex, >, 0);
|
||||
g_assert_cmpint (DEVICE_IFINDEX, ==, -1);
|
||||
|
||||
if (strcmp (g_type_name (G_TYPE_FROM_INSTANCE (nm_platform_get ())), "NMFakePlatform")) {
|
||||
g_test_add_func ("/address/external/ip4", test_ip4_address_external);
|
||||
g_test_add_func ("/address/external/ip6", test_ip6_address_external);
|
||||
}
|
||||
DEVICE_IFINDEX = ifindex;
|
||||
EX = nmtstp_run_command_check_external_global ();
|
||||
|
||||
s->test_func ();
|
||||
|
||||
g_assert_cmpint (DEVICE_IFINDEX, ==, ifindex);
|
||||
DEVICE_IFINDEX = -1;
|
||||
|
||||
g_assert_cmpint (ifindex, ==, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME));
|
||||
g_assert (nm_platform_link_delete (NM_PLATFORM_GET, ifindex));
|
||||
_LOGt ("TEST: finished %s", s->testpath);
|
||||
}
|
||||
|
||||
static void
|
||||
_g_test_add_func (const char *testpath,
|
||||
GTestFunc test_func)
|
||||
{
|
||||
TestSetup *s;
|
||||
|
||||
s = g_new0 (TestSetup, 1);
|
||||
s->testpath = testpath;
|
||||
s->test_func = test_func;
|
||||
|
||||
g_test_add_data_func_full (testpath, s, _g_test_run, g_free);
|
||||
}
|
||||
|
||||
void
|
||||
setup_tests (void)
|
||||
{
|
||||
_g_test_add_func ("/address/ipv4/general", test_ip4_address_general);
|
||||
_g_test_add_func ("/address/ipv6/general", test_ip6_address_general);
|
||||
|
||||
_g_test_add_func ("/address/ipv4/general-2", test_ip4_address_general_2);
|
||||
_g_test_add_func ("/address/ipv6/general-2", test_ip6_address_general_2);
|
||||
|
||||
_g_test_add_func ("/address/ipv4/peer", test_ip4_address_peer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ test_cleanup_internal (void)
|
|||
g_assert (ifindex > 0);
|
||||
|
||||
/* Add routes and addresses */
|
||||
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr4, 0, plen4, lifetime, preferred, NULL));
|
||||
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr6, in6addr_any, plen6, lifetime, preferred, flags));
|
||||
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr4, plen4, 0, lifetime, preferred, NULL));
|
||||
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr6, plen6, in6addr_any, lifetime, preferred, flags));
|
||||
g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway4, 32, INADDR_ANY, 0, metric, mss));
|
||||
g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network4, plen4, gateway4, 0, metric, mss));
|
||||
g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway4, 0, metric, mss));
|
||||
|
|
|
|||
|
|
@ -10,9 +10,16 @@
|
|||
#define SIGNAL_DATA_FMT "'%s-%s' ifindex %d%s%s%s (%d times received)"
|
||||
#define SIGNAL_DATA_ARG(data) (data)->name, nm_platform_signal_change_type_to_string ((data)->change_type), (data)->ifindex, (data)->ifname ? " ifname '" : "", (data)->ifname ? (data)->ifname : "", (data)->ifname ? "'" : "", (data)->received_count
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
guint8 addr_ptr[1];
|
||||
in_addr_t addr4;
|
||||
struct in6_addr addr6;
|
||||
};
|
||||
} IPAddr;
|
||||
|
||||
gboolean
|
||||
nmtst_platform_is_root_test (void)
|
||||
nmtstp_is_root_test (void)
|
||||
{
|
||||
NM_PRAGMA_WARNING_DISABLE("-Wtautological-compare")
|
||||
return (SETUP == nm_linux_platform_setup);
|
||||
|
|
@ -20,9 +27,9 @@ nmtst_platform_is_root_test (void)
|
|||
}
|
||||
|
||||
gboolean
|
||||
nmtst_platform_is_sysfs_writable (void)
|
||||
nmtstp_is_sysfs_writable (void)
|
||||
{
|
||||
return !nmtst_platform_is_root_test ()
|
||||
return !nmtstp_is_root_test ()
|
||||
|| (access ("/sys/devices", W_OK) == 0);
|
||||
}
|
||||
|
||||
|
|
@ -69,6 +76,19 @@ _ensure_no_signal (const char *file, int line, const char *func, SignalData *dat
|
|||
g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal 0 times: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data));
|
||||
}
|
||||
|
||||
void
|
||||
_accept_or_wait_signal (const char *file, int line, const char *func, SignalData *data)
|
||||
{
|
||||
_LOGD ("NMPlatformSignalAssert: %s:%d, %s(): accept-or-wait signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data));
|
||||
if (data->received_count == 0) {
|
||||
data->loop = g_main_loop_new (NULL, FALSE);
|
||||
g_main_loop_run (data->loop);
|
||||
g_clear_pointer (&data->loop, g_main_loop_unref);
|
||||
}
|
||||
|
||||
_accept_signal (file, line, func, data);
|
||||
}
|
||||
|
||||
void
|
||||
_wait_signal (const char *file, int line, const char *func, SignalData *data)
|
||||
{
|
||||
|
|
@ -253,21 +273,534 @@ _assert_ip4_route_exists (const char *file, guint line, const char *func, gboole
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
run_command (const char *format, ...)
|
||||
int
|
||||
nmtstp_run_command (const char *format, ...)
|
||||
{
|
||||
char *command;
|
||||
int result;
|
||||
gs_free char *command = NULL;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, format);
|
||||
command = g_strdup_vprintf (format, ap);
|
||||
va_end (ap);
|
||||
|
||||
_LOGD ("Running command: %s", command);
|
||||
g_assert (!system (command));
|
||||
_LOGD ("Command finished.");
|
||||
g_free (command);
|
||||
result = system (command);
|
||||
_LOGD ("Command finished: result=%d", result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
GMainLoop *loop;
|
||||
gboolean timeout;
|
||||
guint id;
|
||||
} WaitForSignalData;
|
||||
|
||||
static void
|
||||
_wait_for_signal_cb (NMPlatform *platform,
|
||||
NMPObjectType obj_type,
|
||||
int ifindex,
|
||||
NMPlatformLink *plink,
|
||||
NMPlatformSignalChangeType change_type,
|
||||
NMPlatformReason reason,
|
||||
gpointer user_data)
|
||||
{
|
||||
WaitForSignalData *data = user_data;
|
||||
|
||||
g_main_loop_quit (data->loop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_wait_for_signal_timeout (gpointer user_data)
|
||||
{
|
||||
WaitForSignalData *data = user_data;
|
||||
|
||||
data->timeout = TRUE;
|
||||
data->id = 0;
|
||||
g_main_loop_quit (data->loop);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmtstp_wait_for_signal (guint timeout_ms)
|
||||
{
|
||||
WaitForSignalData data = { 0 };
|
||||
|
||||
guint id_link, id_ip4_address, id_ip6_address, id_ip4_route, id_ip6_route;
|
||||
|
||||
data.loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
id_link = g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
|
||||
id_ip4_address = g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
|
||||
id_ip6_address = g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
|
||||
id_ip4_route = g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
|
||||
id_ip6_route = g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data);
|
||||
|
||||
if (timeout_ms != 0)
|
||||
data.id = g_timeout_add (timeout_ms, _wait_for_signal_timeout, &data);
|
||||
|
||||
g_main_loop_run (data.loop);
|
||||
|
||||
g_assert (nm_clear_g_signal_handler (NM_PLATFORM_GET, &id_link));
|
||||
g_assert (nm_clear_g_signal_handler (NM_PLATFORM_GET, &id_ip4_address));
|
||||
g_assert (nm_clear_g_signal_handler (NM_PLATFORM_GET, &id_ip6_address));
|
||||
g_assert (nm_clear_g_signal_handler (NM_PLATFORM_GET, &id_ip4_route));
|
||||
g_assert (nm_clear_g_signal_handler (NM_PLATFORM_GET, &id_ip6_route));
|
||||
|
||||
if (nm_clear_g_source (&data.id))
|
||||
g_assert (timeout_ms != 0 && !data.timeout);
|
||||
|
||||
g_clear_pointer (&data.loop, g_main_loop_unref);
|
||||
|
||||
return !data.timeout;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmtstp_wait_for_signal_until (gint64 until_ms)
|
||||
{
|
||||
gint64 now;
|
||||
|
||||
while (TRUE) {
|
||||
now = nm_utils_get_monotonic_timestamp_ms ();
|
||||
|
||||
if (until_ms < now)
|
||||
return FALSE;
|
||||
|
||||
if (nmtstp_wait_for_signal (MAX (1, until_ms - now)))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
nmtstp_run_command_check_external_global (void)
|
||||
{
|
||||
if (!nmtstp_is_root_test ())
|
||||
return FALSE;
|
||||
switch (nmtst_get_rand_int () % 3) {
|
||||
case 0:
|
||||
return -1;
|
||||
case 1:
|
||||
return FALSE;
|
||||
default:
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmtstp_run_command_check_external (int external_command)
|
||||
{
|
||||
if (external_command != -1) {
|
||||
g_assert (NM_IN_SET (external_command, FALSE, TRUE));
|
||||
g_assert (!external_command || nmtstp_is_root_test ());
|
||||
return !!external_command;
|
||||
}
|
||||
if (!nmtstp_is_root_test ())
|
||||
return FALSE;
|
||||
return (nmtst_get_rand_int () % 2) == 0;
|
||||
}
|
||||
|
||||
#define CHECK_LIFETIME_MAX_DIFF 2
|
||||
|
||||
gboolean
|
||||
nmtstp_ip_address_check_lifetime (const NMPlatformIPAddress *addr,
|
||||
gint64 now,
|
||||
guint32 expected_lifetime,
|
||||
guint32 expected_preferred)
|
||||
{
|
||||
gint64 offset;
|
||||
int i;
|
||||
|
||||
g_assert (addr);
|
||||
|
||||
if (now == -1)
|
||||
now = nm_utils_get_monotonic_timestamp_s ();
|
||||
g_assert (now > 0);
|
||||
|
||||
g_assert (expected_preferred <= expected_lifetime);
|
||||
|
||||
if ( expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT
|
||||
&& expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT) {
|
||||
return addr->timestamp == 0
|
||||
&& addr->lifetime == NM_PLATFORM_LIFETIME_PERMANENT
|
||||
&& addr->preferred == NM_PLATFORM_LIFETIME_PERMANENT;
|
||||
}
|
||||
|
||||
if (addr->timestamp == 0)
|
||||
return FALSE;
|
||||
|
||||
offset = (gint64) now - addr->timestamp;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
guint32 lft = i ? expected_lifetime : expected_preferred;
|
||||
guint32 adr = i ? addr->lifetime : addr->preferred;
|
||||
|
||||
if (lft == NM_PLATFORM_LIFETIME_PERMANENT) {
|
||||
if (adr != NM_PLATFORM_LIFETIME_PERMANENT)
|
||||
return FALSE;
|
||||
} else {
|
||||
if ( adr - offset <= lft - CHECK_LIFETIME_MAX_DIFF
|
||||
|| adr - offset >= lft + CHECK_LIFETIME_MAX_DIFF)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nmtstp_ip_address_assert_lifetime (const NMPlatformIPAddress *addr,
|
||||
gint64 now,
|
||||
guint32 expected_lifetime,
|
||||
guint32 expected_preferred)
|
||||
{
|
||||
gint64 n = now;
|
||||
gint64 offset;
|
||||
int i;
|
||||
|
||||
g_assert (addr);
|
||||
|
||||
if (now == -1)
|
||||
now = nm_utils_get_monotonic_timestamp_s ();
|
||||
g_assert (now > 0);
|
||||
|
||||
g_assert (expected_preferred <= expected_lifetime);
|
||||
|
||||
if ( expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT
|
||||
&& expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT) {
|
||||
g_assert_cmpint (addr->timestamp, ==, 0);
|
||||
g_assert_cmpint (addr->lifetime, ==, NM_PLATFORM_LIFETIME_PERMANENT);
|
||||
g_assert_cmpint (addr->preferred, ==, NM_PLATFORM_LIFETIME_PERMANENT);
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert_cmpint (addr->timestamp, >, 0);
|
||||
g_assert_cmpint (addr->timestamp, <=, now);
|
||||
|
||||
offset = (gint64) now - addr->timestamp;
|
||||
g_assert_cmpint (offset, >=, 0);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
guint32 lft = i ? expected_lifetime : expected_preferred;
|
||||
guint32 adr = i ? addr->lifetime : addr->preferred;
|
||||
|
||||
if (lft == NM_PLATFORM_LIFETIME_PERMANENT)
|
||||
g_assert_cmpint (adr, ==, NM_PLATFORM_LIFETIME_PERMANENT);
|
||||
else {
|
||||
g_assert_cmpint (adr, <=, lft);
|
||||
g_assert_cmpint (offset, <=, adr);
|
||||
g_assert_cmpint (adr - offset, <=, lft + CHECK_LIFETIME_MAX_DIFF);
|
||||
g_assert_cmpint (adr - offset, >=, lft - CHECK_LIFETIME_MAX_DIFF);
|
||||
}
|
||||
}
|
||||
|
||||
g_assert (nmtstp_ip_address_check_lifetime (addr, n, expected_lifetime, expected_preferred));
|
||||
}
|
||||
|
||||
static void
|
||||
_ip_address_add (gboolean external_command,
|
||||
gboolean is_v4,
|
||||
int ifindex,
|
||||
const IPAddr *address,
|
||||
int plen,
|
||||
const IPAddr *peer_address,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
const char *label,
|
||||
guint flags)
|
||||
{
|
||||
gint64 end_time;
|
||||
|
||||
external_command = nmtstp_run_command_check_external (external_command);
|
||||
|
||||
if (external_command) {
|
||||
const char *ifname;
|
||||
gs_free char *s_valid = NULL;
|
||||
gs_free char *s_preferred = NULL;
|
||||
gs_free char *s_label = NULL;
|
||||
char b1[NM_UTILS_INET_ADDRSTRLEN], b2[NM_UTILS_INET_ADDRSTRLEN];
|
||||
|
||||
ifname = nm_platform_link_get_name (NM_PLATFORM_GET, ifindex);
|
||||
g_assert (ifname);
|
||||
|
||||
if (peer_address == address)
|
||||
peer_address = 0;
|
||||
|
||||
if (lifetime != NM_PLATFORM_LIFETIME_PERMANENT)
|
||||
s_valid = g_strdup_printf (" valid_lft %d", lifetime);
|
||||
if (preferred != NM_PLATFORM_LIFETIME_PERMANENT)
|
||||
s_preferred = g_strdup_printf (" preferred_lft %d", preferred);
|
||||
if (label)
|
||||
s_label = g_strdup_printf ("%s:%s", ifname, label);
|
||||
|
||||
if (is_v4) {
|
||||
g_assert (flags == 0);
|
||||
nmtstp_run_command_check ("ip address change %s%s%s/%d dev %s%s%s%s",
|
||||
nm_utils_inet4_ntop (address->addr4, b1),
|
||||
peer_address->addr4 ? " peer " : "",
|
||||
peer_address->addr4 ? nm_utils_inet4_ntop (peer_address->addr4, b2) : "",
|
||||
plen,
|
||||
ifname,
|
||||
s_valid ?: "",
|
||||
s_preferred ?: "",
|
||||
s_label ?: "");
|
||||
} else {
|
||||
g_assert (label == NULL);
|
||||
|
||||
/* flags not implemented (yet) */
|
||||
g_assert (flags == 0);
|
||||
nmtstp_run_command_check ("ip address change %s%s%s/%d dev %s%s%s%s",
|
||||
nm_utils_inet6_ntop (&address->addr6, b1),
|
||||
!IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) ? " peer " : "",
|
||||
!IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) ? nm_utils_inet6_ntop (&peer_address->addr6, b2) : "",
|
||||
plen,
|
||||
ifname,
|
||||
s_valid ?: "",
|
||||
s_preferred ?: "",
|
||||
s_label ?: "");
|
||||
}
|
||||
} else {
|
||||
gboolean success;
|
||||
|
||||
if (is_v4) {
|
||||
g_assert (flags == 0);
|
||||
success = nm_platform_ip4_address_add (NM_PLATFORM_GET,
|
||||
ifindex,
|
||||
address->addr4,
|
||||
plen,
|
||||
peer_address->addr4,
|
||||
lifetime,
|
||||
preferred,
|
||||
label);
|
||||
} else {
|
||||
g_assert (label == NULL);
|
||||
success = nm_platform_ip6_address_add (NM_PLATFORM_GET,
|
||||
ifindex,
|
||||
address->addr6,
|
||||
plen,
|
||||
peer_address->addr6,
|
||||
lifetime,
|
||||
preferred,
|
||||
flags);
|
||||
}
|
||||
g_assert (success);
|
||||
}
|
||||
|
||||
/* Let's wait until we see the address. */
|
||||
end_time = nm_utils_get_monotonic_timestamp_ms () + 250;
|
||||
do {
|
||||
|
||||
if (external_command)
|
||||
nm_platform_process_events (NM_PLATFORM_GET);
|
||||
|
||||
/* let's wait until we see the address as we added it. */
|
||||
if (is_v4) {
|
||||
const NMPlatformIP4Address *a;
|
||||
|
||||
g_assert (flags == 0);
|
||||
a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, address->addr4, plen, peer_address->addr4);
|
||||
if ( a
|
||||
&& nm_platform_ip4_address_get_peer (a) == (peer_address->addr4 ? peer_address->addr4 : address->addr4)
|
||||
&& nmtstp_ip_address_check_lifetime ((NMPlatformIPAddress*) a, -1, lifetime, preferred)
|
||||
&& strcmp (a->label, label ?: "") == 0)
|
||||
break;
|
||||
} else {
|
||||
const NMPlatformIP6Address *a;
|
||||
|
||||
g_assert (label == NULL);
|
||||
g_assert (flags == 0);
|
||||
|
||||
a = nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, address->addr6, plen);
|
||||
if ( a
|
||||
&& !memcmp (nm_platform_ip6_address_get_peer (a),
|
||||
(IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) || IN6_ARE_ADDR_EQUAL (&address->addr6, &peer_address->addr6))
|
||||
? &address->addr6 : &peer_address->addr6,
|
||||
sizeof (struct in6_addr))
|
||||
&& nmtstp_ip_address_check_lifetime ((NMPlatformIPAddress*) a, -1, lifetime, preferred))
|
||||
break;
|
||||
}
|
||||
|
||||
/* for internal command, we expect not to reach this line.*/
|
||||
g_assert (external_command);
|
||||
|
||||
/* timeout? */
|
||||
g_assert (nm_utils_get_monotonic_timestamp_ms () < end_time);
|
||||
|
||||
g_assert (nmtstp_wait_for_signal_until (end_time));
|
||||
} while (TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
nmtstp_ip4_address_add (gboolean external_command,
|
||||
int ifindex,
|
||||
in_addr_t address,
|
||||
int plen,
|
||||
in_addr_t peer_address,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
const char *label)
|
||||
{
|
||||
_ip_address_add (external_command,
|
||||
TRUE,
|
||||
ifindex,
|
||||
(IPAddr *) &address,
|
||||
plen,
|
||||
(IPAddr *) &peer_address,
|
||||
lifetime,
|
||||
preferred,
|
||||
label,
|
||||
0);
|
||||
}
|
||||
|
||||
void
|
||||
nmtstp_ip6_address_add (gboolean external_command,
|
||||
int ifindex,
|
||||
struct in6_addr address,
|
||||
int plen,
|
||||
struct in6_addr peer_address,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
guint flags)
|
||||
{
|
||||
_ip_address_add (external_command,
|
||||
FALSE,
|
||||
ifindex,
|
||||
(IPAddr *) &address,
|
||||
plen,
|
||||
(IPAddr *) &peer_address,
|
||||
lifetime,
|
||||
preferred,
|
||||
NULL,
|
||||
flags);
|
||||
}
|
||||
|
||||
static void
|
||||
_ip_address_del (gboolean external_command,
|
||||
gboolean is_v4,
|
||||
int ifindex,
|
||||
const IPAddr *address,
|
||||
int plen,
|
||||
const IPAddr *peer_address)
|
||||
{
|
||||
gint64 end_time;
|
||||
|
||||
external_command = nmtstp_run_command_check_external (external_command);
|
||||
|
||||
if (external_command) {
|
||||
const char *ifname;
|
||||
char b1[NM_UTILS_INET_ADDRSTRLEN], b2[NM_UTILS_INET_ADDRSTRLEN];
|
||||
int success;
|
||||
gboolean had_address;
|
||||
|
||||
ifname = nm_platform_link_get_name (NM_PLATFORM_GET, ifindex);
|
||||
g_assert (ifname);
|
||||
|
||||
if (peer_address == address)
|
||||
peer_address = 0;
|
||||
|
||||
/* let's wait until we see the address as we added it. */
|
||||
if (is_v4)
|
||||
had_address = !!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, address->addr4, plen, peer_address->addr4);
|
||||
else
|
||||
had_address = !!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, address->addr6, plen);
|
||||
|
||||
if (is_v4) {
|
||||
success = nmtstp_run_command ("ip address delete %s%s%s/%d dev %s",
|
||||
nm_utils_inet4_ntop (address->addr4, b1),
|
||||
peer_address->addr4 ? " peer " : "",
|
||||
peer_address->addr4 ? nm_utils_inet4_ntop (peer_address->addr4, b2) : "",
|
||||
plen,
|
||||
ifname);
|
||||
} else {
|
||||
g_assert (!peer_address);
|
||||
success = nmtstp_run_command ("ip address delete %s/%d dev %s",
|
||||
nm_utils_inet6_ntop (&address->addr6, b1),
|
||||
plen,
|
||||
ifname);
|
||||
}
|
||||
g_assert (success == 0 || !had_address);
|
||||
} else {
|
||||
gboolean success;
|
||||
|
||||
if (is_v4) {
|
||||
success = nm_platform_ip4_address_delete (NM_PLATFORM_GET,
|
||||
ifindex,
|
||||
address->addr4,
|
||||
plen,
|
||||
peer_address->addr4);
|
||||
} else {
|
||||
g_assert (!peer_address);
|
||||
success = nm_platform_ip6_address_delete (NM_PLATFORM_GET,
|
||||
ifindex,
|
||||
address->addr6,
|
||||
plen);
|
||||
}
|
||||
g_assert (success);
|
||||
}
|
||||
|
||||
/* Let's wait until we get the result */
|
||||
end_time = nm_utils_get_monotonic_timestamp_ms () + 250;
|
||||
do {
|
||||
if (external_command)
|
||||
nm_platform_process_events (NM_PLATFORM_GET);
|
||||
|
||||
/* let's wait until we see the address as we added it. */
|
||||
if (is_v4) {
|
||||
const NMPlatformIP4Address *a;
|
||||
|
||||
a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, address->addr4, plen, peer_address->addr4);
|
||||
if (!a)
|
||||
break;
|
||||
} else {
|
||||
const NMPlatformIP6Address *a;
|
||||
|
||||
a = nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, address->addr6, plen);
|
||||
if (!a)
|
||||
break;
|
||||
}
|
||||
|
||||
/* for internal command, we expect not to reach this line.*/
|
||||
g_assert (external_command);
|
||||
|
||||
/* timeout? */
|
||||
g_assert (nm_utils_get_monotonic_timestamp_ms () < end_time);
|
||||
|
||||
g_assert (nmtstp_wait_for_signal_until (end_time));
|
||||
} while (TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
nmtstp_ip4_address_del (gboolean external_command,
|
||||
int ifindex,
|
||||
in_addr_t address,
|
||||
int plen,
|
||||
in_addr_t peer_address)
|
||||
{
|
||||
_ip_address_del (external_command,
|
||||
TRUE,
|
||||
ifindex,
|
||||
(IPAddr *) &address,
|
||||
plen,
|
||||
(IPAddr *) &peer_address);
|
||||
}
|
||||
|
||||
void
|
||||
nmtstp_ip6_address_del (gboolean external_command,
|
||||
int ifindex,
|
||||
struct in6_addr address,
|
||||
int plen)
|
||||
{
|
||||
_ip_address_del (external_command,
|
||||
FALSE,
|
||||
ifindex,
|
||||
(IPAddr *) &address,
|
||||
plen,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE();
|
||||
|
||||
static gboolean
|
||||
|
|
@ -318,7 +851,7 @@ main (int argc, char **argv)
|
|||
|
||||
init_tests (&argc, &argv);
|
||||
|
||||
if ( nmtst_platform_is_root_test ()
|
||||
if ( nmtstp_is_root_test ()
|
||||
&& (geteuid () != 0 || getegid () != 0)) {
|
||||
if ( g_getenv ("NMTST_FORCE_REAL_ROOT")
|
||||
|| !unshare_user ()) {
|
||||
|
|
@ -335,7 +868,7 @@ main (int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (nmtst_platform_is_root_test () && !g_getenv ("NMTST_NO_UNSHARE")) {
|
||||
if (nmtstp_is_root_test () && !g_getenv ("NMTST_NO_UNSHARE")) {
|
||||
int errsv;
|
||||
|
||||
if (unshare (CLONE_NEWNET | CLONE_NEWNS) != 0) {
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ typedef struct {
|
|||
const char *ifname;
|
||||
} SignalData;
|
||||
|
||||
gboolean nmtst_platform_is_root_test (void);
|
||||
gboolean nmtst_platform_is_sysfs_writable (void);
|
||||
gboolean nmtstp_is_root_test (void);
|
||||
gboolean nmtstp_is_sysfs_writable (void);
|
||||
|
||||
SignalData *add_signal_full (const char *name, NMPlatformSignalChangeType change_type, GCallback callback, int ifindex, const char *ifname);
|
||||
#define add_signal(name, change_type, callback) add_signal_full (name, change_type, (GCallback) callback, 0, NULL)
|
||||
|
|
@ -53,11 +53,13 @@ SignalData *add_signal_full (const char *name, NMPlatformSignalChangeType change
|
|||
void _accept_signal (const char *file, int line, const char *func, SignalData *data);
|
||||
void _accept_signals (const char *file, int line, const char *func, SignalData *data, int min, int max);
|
||||
void _wait_signal (const char *file, int line, const char *func, SignalData *data);
|
||||
void _accept_or_wait_signal (const char *file, int line, const char *func, SignalData *data);
|
||||
void _ensure_no_signal (const char *file, int line, const char *func, SignalData *data);
|
||||
void _free_signal (const char *file, int line, const char *func, SignalData *data);
|
||||
#define accept_signal(data) _accept_signal(__FILE__, __LINE__, G_STRFUNC, data)
|
||||
#define accept_signals(data, min, max) _accept_signals(__FILE__, __LINE__, G_STRFUNC, data, min, max)
|
||||
#define wait_signal(data) _wait_signal(__FILE__, __LINE__, G_STRFUNC, data)
|
||||
#define accept_or_wait_signal(data) _accept_or_wait_signal(__FILE__, __LINE__, G_STRFUNC, data)
|
||||
#define ensure_no_signal(data) _ensure_no_signal(__FILE__, __LINE__, G_STRFUNC, data)
|
||||
#define free_signal(data) _free_signal(__FILE__, __LINE__, G_STRFUNC, data)
|
||||
|
||||
|
|
@ -68,7 +70,49 @@ void _assert_ip4_route_exists (const char *file, guint line, const char *func, g
|
|||
|
||||
void link_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlatformLink *received, NMPlatformSignalChangeType change_type, NMPlatformReason reason, SignalData *data);
|
||||
|
||||
void run_command (const char *format, ...);
|
||||
int nmtstp_run_command (const char *format, ...) __attribute__((__format__ (__printf__, 1, 2)));
|
||||
#define nmtstp_run_command_check(format, ...) do { g_assert_cmpint (nmtstp_run_command (format, __VA_ARGS__), ==, 0); } while (0)
|
||||
|
||||
gboolean nmtstp_wait_for_signal (guint timeout_ms);
|
||||
gboolean nmtstp_wait_for_signal_until (gint64 until_ms);
|
||||
|
||||
int nmtstp_run_command_check_external_global (void);
|
||||
gboolean nmtstp_run_command_check_external (int external_command);
|
||||
|
||||
gboolean nmtstp_ip_address_check_lifetime (const NMPlatformIPAddress *addr,
|
||||
gint64 now,
|
||||
guint32 expected_lifetime,
|
||||
guint32 expected_preferred);
|
||||
void nmtstp_ip_address_assert_lifetime (const NMPlatformIPAddress *addr,
|
||||
gint64 now,
|
||||
guint32 expected_lifetime,
|
||||
guint32 expected_preferred);
|
||||
void nmtstp_ip4_address_add (gboolean external_command,
|
||||
int ifindex,
|
||||
in_addr_t address,
|
||||
int plen,
|
||||
in_addr_t peer_address,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
const char *label);
|
||||
void nmtstp_ip6_address_add (gboolean external_command,
|
||||
int ifindex,
|
||||
struct in6_addr address,
|
||||
int plen,
|
||||
struct in6_addr peer_address,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
guint flags);
|
||||
void nmtstp_ip4_address_del (gboolean external_command,
|
||||
int ifindex,
|
||||
in_addr_t address,
|
||||
int plen,
|
||||
in_addr_t peer_address);
|
||||
void nmtstp_ip6_address_del (gboolean external_command,
|
||||
int ifindex,
|
||||
struct in6_addr address,
|
||||
int plen);
|
||||
|
||||
|
||||
void init_tests (int *argc, char ***argv);
|
||||
void setup_tests (void);
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ test_slave (int master, int type, SignalData *master_changed)
|
|||
/* Set slave option */
|
||||
switch (type) {
|
||||
case NM_LINK_TYPE_BRIDGE:
|
||||
if (nmtst_platform_is_sysfs_writable ()) {
|
||||
if (nmtstp_is_sysfs_writable ()) {
|
||||
g_assert (nm_platform_slave_set_option (NM_PLATFORM_GET, ifindex, "priority", "789"));
|
||||
value = nm_platform_slave_get_option (NM_PLATFORM_GET, ifindex, "priority");
|
||||
g_assert_cmpstr (value, ==, "789");
|
||||
|
|
@ -341,7 +341,7 @@ test_software (NMLinkType link_type, const char *link_typename)
|
|||
/* Set master option */
|
||||
switch (link_type) {
|
||||
case NM_LINK_TYPE_BRIDGE:
|
||||
if (nmtst_platform_is_sysfs_writable ()) {
|
||||
if (nmtstp_is_sysfs_writable ()) {
|
||||
g_assert (nm_platform_master_set_option (NM_PLATFORM_GET, ifindex, "forward_delay", "789"));
|
||||
value = nm_platform_master_get_option (NM_PLATFORM_GET, ifindex, "forward_delay");
|
||||
g_assert_cmpstr (value, ==, "789");
|
||||
|
|
@ -349,7 +349,7 @@ test_software (NMLinkType link_type, const char *link_typename)
|
|||
}
|
||||
break;
|
||||
case NM_LINK_TYPE_BOND:
|
||||
if (nmtst_platform_is_sysfs_writable ()) {
|
||||
if (nmtstp_is_sysfs_writable ()) {
|
||||
g_assert (nm_platform_master_set_option (NM_PLATFORM_GET, ifindex, "mode", "active-backup"));
|
||||
value = nm_platform_master_get_option (NM_PLATFORM_GET, ifindex, "mode");
|
||||
/* When reading back, the output looks slightly different. */
|
||||
|
|
@ -408,7 +408,7 @@ test_bridge (void)
|
|||
static void
|
||||
test_bond (void)
|
||||
{
|
||||
if (nmtst_platform_is_root_test () &&
|
||||
if (nmtstp_is_root_test () &&
|
||||
!g_file_test ("/proc/1/net/bonding", G_FILE_TEST_IS_DIR) &&
|
||||
system("modprobe --show bonding") != 0) {
|
||||
g_test_skip ("Skipping test for bonding: bonding module not available");
|
||||
|
|
@ -519,7 +519,7 @@ test_external (void)
|
|||
SignalData *link_changed, *link_removed;
|
||||
int ifindex;
|
||||
|
||||
run_command ("ip link add %s type %s", DEVICE_NAME, "dummy");
|
||||
nmtstp_run_command_check ("ip link add %s type %s", DEVICE_NAME, "dummy");
|
||||
wait_signal (link_added);
|
||||
|
||||
g_assert (nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME));
|
||||
|
|
@ -543,24 +543,24 @@ test_external (void)
|
|||
g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
|
||||
g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
|
||||
|
||||
run_command ("ip link set %s up", DEVICE_NAME);
|
||||
nmtstp_run_command_check ("ip link set %s up", DEVICE_NAME);
|
||||
wait_signal (link_changed);
|
||||
|
||||
g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
|
||||
g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
|
||||
run_command ("ip link set %s down", DEVICE_NAME);
|
||||
nmtstp_run_command_check ("ip link set %s down", DEVICE_NAME);
|
||||
wait_signal (link_changed);
|
||||
g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
|
||||
g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
|
||||
|
||||
run_command ("ip link set %s arp on", DEVICE_NAME);
|
||||
nmtstp_run_command_check ("ip link set %s arp on", DEVICE_NAME);
|
||||
wait_signal (link_changed);
|
||||
g_assert (nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
|
||||
run_command ("ip link set %s arp off", DEVICE_NAME);
|
||||
nmtstp_run_command_check ("ip link set %s arp off", DEVICE_NAME);
|
||||
wait_signal (link_changed);
|
||||
g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
|
||||
|
||||
run_command ("ip link del %s", DEVICE_NAME);
|
||||
nmtstp_run_command_check ("ip link del %s", DEVICE_NAME);
|
||||
wait_signal (link_removed);
|
||||
accept_signals (link_changed, 0, 1);
|
||||
g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME));
|
||||
|
|
|
|||
|
|
@ -377,8 +377,8 @@ setup_dev0_ip6 (int ifindex)
|
|||
nm_platform_ip6_address_add (NM_PLATFORM_GET,
|
||||
ifindex,
|
||||
*nmtst_inet6_from_string ("2001:db8:8086::666"),
|
||||
in6addr_any,
|
||||
64,
|
||||
in6addr_any,
|
||||
3600,
|
||||
3600,
|
||||
0);
|
||||
|
|
@ -481,8 +481,8 @@ update_dev0_ip6 (int ifindex)
|
|||
nm_platform_ip6_address_add (NM_PLATFORM_GET,
|
||||
ifindex,
|
||||
*nmtst_inet6_from_string ("2001:db8:8086::2"),
|
||||
in6addr_any,
|
||||
64,
|
||||
in6addr_any,
|
||||
3600,
|
||||
3600,
|
||||
0);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue