platform: properly handle peer-address for IPv4 addresses
Kernel allows to add the same IPv4 address that only differs by peer-address (IFL_ADDRESS): $ ip link add dummy type dummy $ ip address add 1.1.1.1 peer 1.1.1.3/24 dev dummy $ ip address add 1.1.1.1 peer 1.1.1.4/24 dev dummy RTNETLINK answers: File exists $ ip address add 1.1.1.1 peer 1.1.2.3/24 dev dummy $ ip address show dev dummy 2: dummy@NONE: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default link/ether 52:58:a7:1e:e8:93 brd ff:ff:ff:ff:ff:ff inet 1.1.1.1 peer 1.1.1.3/24 scope global dummy valid_lft forever preferred_lft forever inet 1.1.1.1 peer 1.1.2.3/24 scope global dummy valid_lft forever preferred_lft forever We must also consider peer-address, otherwise platform will treat two different addresses as one and the same. https://bugzilla.gnome.org/show_bug.cgi?id=756356
This commit is contained in:
@@ -179,7 +179,8 @@ static gboolean
|
|||||||
addresses_are_duplicate (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b)
|
addresses_are_duplicate (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b)
|
||||||
{
|
{
|
||||||
return a->address == b->address
|
return a->address == b->address
|
||||||
&& a->plen == b->plen;
|
&& a->plen == b->plen
|
||||||
|
&& nm_platform_ip4_address_equal_peer_net (a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -2014,6 +2015,7 @@ nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only
|
|||||||
const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, i);
|
const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, i);
|
||||||
hash_u32 (sum, address->address);
|
hash_u32 (sum, address->address);
|
||||||
hash_u32 (sum, address->plen);
|
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++) {
|
for (i = 0; i < nm_ip4_config_get_num_routes (config); i++) {
|
||||||
|
@@ -1031,15 +1031,24 @@ ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const NMPlatformIP4Address *
|
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);
|
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
|
||||||
int i;
|
int i;
|
||||||
|
NMPlatformIP4Address a = {
|
||||||
|
.ifindex = ifindex,
|
||||||
|
.address = addr,
|
||||||
|
.plen = plen,
|
||||||
|
.peer_address = peer_address,
|
||||||
|
};
|
||||||
|
|
||||||
for (i = 0; i < priv->ip4_addresses->len; i++) {
|
for (i = 0; i < priv->ip4_addresses->len; i++) {
|
||||||
NMPlatformIP4Address *address = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, 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;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4252,7 +4252,7 @@ ip4_address_add (NMPlatform *platform,
|
|||||||
plen, lifetime, preferred, 0,
|
plen, lifetime, preferred, 0,
|
||||||
label);
|
label);
|
||||||
return do_add_addrroute (platform,
|
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);
|
nlo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4283,8 +4283,7 @@ ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen,
|
|||||||
{
|
{
|
||||||
NMPObject obj_needle;
|
NMPObject obj_needle;
|
||||||
|
|
||||||
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_needle.ip4_address.peer_address = peer_address;
|
|
||||||
return do_delete_object (platform, &obj_needle, NULL);
|
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 *
|
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;
|
NMPObject obj_needle;
|
||||||
const NMPObject *obj;
|
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);
|
obj = nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle);
|
||||||
if (nmp_object_is_visible (obj))
|
if (nmp_object_is_visible (obj))
|
||||||
return &obj->ip4_address;
|
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 *
|
GArray *
|
||||||
nm_platform_ip4_address_get_all (NMPlatform *self, int ifindex)
|
nm_platform_ip4_address_get_all (NMPlatform *self, int ifindex)
|
||||||
{
|
{
|
||||||
@@ -1957,13 +1994,13 @@ nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr a
|
|||||||
}
|
}
|
||||||
|
|
||||||
const NMPlatformIP4Address *
|
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);
|
_CHECK_SELF (self, klass, NULL);
|
||||||
|
|
||||||
g_return_val_if_fail (plen > 0, 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 *
|
const NMPlatformIP6Address *
|
||||||
@@ -1985,7 +2022,9 @@ array_contains_ip4_address (const GArray *addresses, const NMPlatformIP4Address
|
|||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
NMPlatformIP4Address *candidate = &g_array_index (addresses, NMPlatformIP4Address, 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;
|
guint32 lifetime, preferred;
|
||||||
|
|
||||||
if (nmp_utils_lifetime_get (candidate->timestamp, candidate->lifetime, candidate->preferred,
|
if (nmp_utils_lifetime_get (candidate->timestamp, candidate->lifetime, candidate->preferred,
|
||||||
@@ -2702,6 +2741,12 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route)
|
|||||||
return 1; \
|
return 1; \
|
||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
|
||||||
|
#define _CMP_DIRECT(a, b) \
|
||||||
|
G_STMT_START { \
|
||||||
|
if ((a) != (b)) \
|
||||||
|
return ((a) < (b)) ? -1 : 1; \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
#define _CMP_FIELD(a, b, field) \
|
#define _CMP_FIELD(a, b, field) \
|
||||||
G_STMT_START { \
|
G_STMT_START { \
|
||||||
if (((a)->field) != ((b)->field)) \
|
if (((a)->field) != ((b)->field)) \
|
||||||
@@ -2784,12 +2829,20 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b)
|
|||||||
int
|
int
|
||||||
nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b)
|
nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b)
|
||||||
{
|
{
|
||||||
|
in_addr_t p_a, p_b;
|
||||||
|
|
||||||
_CMP_SELF (a, b);
|
_CMP_SELF (a, b);
|
||||||
_CMP_FIELD (a, b, ifindex);
|
_CMP_FIELD (a, b, ifindex);
|
||||||
_CMP_FIELD (a, b, source);
|
_CMP_FIELD (a, b, source);
|
||||||
_CMP_FIELD (a, b, address);
|
_CMP_FIELD (a, b, address);
|
||||||
_CMP_FIELD (a, b, peer_address);
|
|
||||||
_CMP_FIELD (a, b, plen);
|
_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, timestamp);
|
||||||
_CMP_FIELD (a, b, lifetime);
|
_CMP_FIELD (a, b, lifetime);
|
||||||
_CMP_FIELD (a, b, preferred);
|
_CMP_FIELD (a, b, preferred);
|
||||||
|
@@ -531,7 +531,7 @@ typedef struct {
|
|||||||
guint flags);
|
guint flags);
|
||||||
gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, int plen, in_addr_t peer_address);
|
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);
|
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);
|
const NMPlatformIP6Address *(*ip6_address_get) (NMPlatform *, int ifindex, struct in6_addr address, int plen);
|
||||||
|
|
||||||
GArray * (*ip4_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteFlags flags);
|
GArray * (*ip4_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteFlags flags);
|
||||||
@@ -705,7 +705,12 @@ 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_channel (NMPlatform *self, int ifindex, guint32 channel);
|
||||||
gboolean nm_platform_mesh_set_ssid (NMPlatform *self, int ifindex, const guint8 *ssid, gsize len);
|
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);
|
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_ip4_address_get_all (NMPlatform *self, int ifindex);
|
||||||
GArray *nm_platform_ip6_address_get_all (NMPlatform *self, int ifindex);
|
GArray *nm_platform_ip6_address_get_all (NMPlatform *self, int ifindex);
|
||||||
|
@@ -296,19 +296,20 @@ _vt_cmd_obj_stackinit_id_link (NMPObject *obj, const NMPObject *src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const NMPObject *
|
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);
|
nmp_object_stackinit (obj, NMP_OBJECT_TYPE_IP4_ADDRESS, NULL);
|
||||||
obj->ip4_address.ifindex = ifindex;
|
obj->ip4_address.ifindex = ifindex;
|
||||||
obj->ip4_address.address = address;
|
obj->ip4_address.address = address;
|
||||||
obj->ip4_address.plen = plen;
|
obj->ip4_address.plen = plen;
|
||||||
|
obj->ip4_address.peer_address = peer_address;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_vt_cmd_obj_stackinit_id_ip4_address (NMPObject *obj, const NMPObject *src)
|
_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 *
|
const NMPObject *
|
||||||
@@ -425,14 +426,18 @@ _vt_cmd_plobj_to_string_id_##type (const NMPlatformObject *_obj, char *buf, gsiz
|
|||||||
{ \
|
{ \
|
||||||
plat_type *const obj = (plat_type *) _obj; \
|
plat_type *const obj = (plat_type *) _obj; \
|
||||||
char buf1[NM_UTILS_INET_ADDRSTRLEN]; \
|
char buf1[NM_UTILS_INET_ADDRSTRLEN]; \
|
||||||
|
char buf2[NM_UTILS_INET_ADDRSTRLEN]; \
|
||||||
\
|
\
|
||||||
(void) buf1; \
|
(void) buf1; \
|
||||||
|
(void) buf2; \
|
||||||
g_snprintf (buf, buf_len, \
|
g_snprintf (buf, buf_len, \
|
||||||
__VA_ARGS__); \
|
__VA_ARGS__); \
|
||||||
return buf; \
|
return buf; \
|
||||||
}
|
}
|
||||||
_vt_cmd_plobj_to_string_id (link, NMPlatformLink, "%d", obj->ifindex);
|
_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 (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/%d", obj->ifindex, nm_utils_inet6_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 (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 (ip6_route, NMPlatformIP6Route, "%d: %s/%d %d", obj->ifindex, nm_utils_inet6_ntop (&obj->network, buf1), obj->plen, obj->metric);
|
||||||
@@ -533,6 +538,7 @@ _vt_cmd_plobj_id_copy (ip4_address, NMPlatformIP4Address, {
|
|||||||
dst->ifindex = src->ifindex;
|
dst->ifindex = src->ifindex;
|
||||||
dst->plen = src->plen;
|
dst->plen = src->plen;
|
||||||
dst->address = src->address;
|
dst->address = src->address;
|
||||||
|
dst->peer_address = src->peer_address;
|
||||||
});
|
});
|
||||||
_vt_cmd_plobj_id_copy (ip6_address, NMPlatformIP6Address, {
|
_vt_cmd_plobj_id_copy (ip6_address, NMPlatformIP6Address, {
|
||||||
dst->ifindex = src->ifindex;
|
dst->ifindex = src->ifindex;
|
||||||
@@ -619,7 +625,10 @@ _vt_cmd_plobj_id_equal (link, NMPlatformLink,
|
|||||||
_vt_cmd_plobj_id_equal (ip4_address, NMPlatformIP4Address,
|
_vt_cmd_plobj_id_equal (ip4_address, NMPlatformIP4Address,
|
||||||
obj1->ifindex == obj2->ifindex
|
obj1->ifindex == obj2->ifindex
|
||||||
&& obj1->plen == obj2->plen
|
&& 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,
|
_vt_cmd_plobj_id_equal (ip6_address, NMPlatformIP6Address,
|
||||||
obj1->ifindex == obj2->ifindex
|
obj1->ifindex == obj2->ifindex
|
||||||
&& obj1->plen == obj2->plen
|
&& obj1->plen == obj2->plen
|
||||||
@@ -655,21 +664,17 @@ _vt_cmd_plobj_id_hash_##type (const NMPlatformObject *_obj) \
|
|||||||
return hash; \
|
return hash; \
|
||||||
}
|
}
|
||||||
_vt_cmd_plobj_id_hash (link, NMPlatformLink, {
|
_vt_cmd_plobj_id_hash (link, NMPlatformLink, {
|
||||||
/* libnl considers:
|
|
||||||
* .oo_id_attrs = LINK_ATTR_IFINDEX | LINK_ATTR_FAMILY,
|
|
||||||
*/
|
|
||||||
hash = (guint) 3982791431u;
|
hash = (guint) 3982791431u;
|
||||||
hash = hash + ((guint) obj->ifindex);
|
hash = hash + ((guint) obj->ifindex);
|
||||||
})
|
})
|
||||||
_vt_cmd_plobj_id_hash (ip4_address, NMPlatformIP4Address, {
|
_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 = (guint) 3591309853u;
|
||||||
hash = hash + ((guint) obj->ifindex);
|
hash = hash + ((guint) obj->ifindex);
|
||||||
hash = hash * 33 + ((guint) obj->plen);
|
hash = hash * 33 + ((guint) obj->plen);
|
||||||
hash = hash * 33 + ((guint) obj->address);
|
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, {
|
_vt_cmd_plobj_id_hash (ip6_address, NMPlatformIP6Address, {
|
||||||
hash = (guint) 2907861637u;
|
hash = (guint) 2907861637u;
|
||||||
@@ -678,11 +683,6 @@ _vt_cmd_plobj_id_hash (ip6_address, NMPlatformIP6Address, {
|
|||||||
hash = hash * 33 + _id_hash_ip6_addr (&obj->address);
|
hash = hash * 33 + _id_hash_ip6_addr (&obj->address);
|
||||||
})
|
})
|
||||||
_vt_cmd_plobj_id_hash (ip4_route, NMPlatformIP4Route, {
|
_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 = (guint) 2569857221u;
|
||||||
hash = hash + ((guint) obj->ifindex);
|
hash = hash + ((guint) obj->ifindex);
|
||||||
hash = hash * 33 + ((guint) obj->plen);
|
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 (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 (NMPObject *obj, const NMPObject *src);
|
||||||
const NMPObject *nmp_object_stackinit_id_link (NMPObject *obj, int ifindex);
|
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_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_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);
|
const NMPObject *nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6_addr *network, int plen, guint32 metric);
|
||||||
|
@@ -624,11 +624,11 @@ do_ip6_address_add (char **argv)
|
|||||||
} else \
|
} else \
|
||||||
return FALSE; \
|
return FALSE; \
|
||||||
}
|
}
|
||||||
#define ADDR_CMD(cmdname) ADDR_CMD_FULL (ip4, cmdname, FALSE, 0) ADDR_CMD_FULL (ip6, cmdname, FALSE)
|
#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) ADDR_CMD_FULL (ip6, cmdname, TRUE)
|
#define ADDR_CMD_PRINT(cmdname, ...) ADDR_CMD_FULL (ip4, cmdname, TRUE, ##__VA_ARGS__) ADDR_CMD_FULL (ip6, cmdname, TRUE)
|
||||||
|
|
||||||
ADDR_CMD (delete)
|
ADDR_CMD (delete)
|
||||||
ADDR_CMD_PRINT (get)
|
ADDR_CMD_PRINT (get, 0)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
do_ip4_route_get_all (char **argv)
|
do_ip4_route_get_all (char **argv)
|
||||||
|
@@ -64,9 +64,9 @@ test_ip4_address (void)
|
|||||||
inet_pton (AF_INET, IP4_ADDRESS, &addr);
|
inet_pton (AF_INET, IP4_ADDRESS, &addr);
|
||||||
|
|
||||||
/* Add address */
|
/* Add address */
|
||||||
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));
|
||||||
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0, lifetime, preferred, NULL));
|
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0, 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));
|
||||||
accept_signal (address_added);
|
accept_signal (address_added);
|
||||||
|
|
||||||
/* Add address again (aka update) */
|
/* Add address again (aka update) */
|
||||||
@@ -85,7 +85,7 @@ test_ip4_address (void)
|
|||||||
|
|
||||||
/* Remove address */
|
/* Remove address */
|
||||||
g_assert (nm_platform_ip4_address_delete (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
|
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));
|
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
|
||||||
accept_signal (address_removed);
|
accept_signal (address_removed);
|
||||||
|
|
||||||
/* Remove address again */
|
/* Remove address again */
|
||||||
@@ -167,20 +167,20 @@ test_ip4_address_external (void)
|
|||||||
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
|
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
|
||||||
IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred);
|
IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred);
|
||||||
wait_signal (address_added);
|
wait_signal (address_added);
|
||||||
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));
|
||||||
run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME);
|
run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME);
|
||||||
wait_signal (address_removed);
|
wait_signal (address_removed);
|
||||||
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));
|
||||||
|
|
||||||
/* Add/delete conflict */
|
/* Add/delete conflict */
|
||||||
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
|
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
|
||||||
IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred);
|
IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred);
|
||||||
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0, lifetime, preferred, NULL));
|
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0, 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));
|
||||||
accept_signal (address_added);
|
accept_signal (address_added);
|
||||||
/*run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME);
|
/*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_delete (ifindex, addr, IP4_PLEN, 0));
|
||||||
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));
|
||||||
accept_signal (address_removed);*/
|
accept_signal (address_removed);*/
|
||||||
|
|
||||||
free_signal (address_added);
|
free_signal (address_added);
|
||||||
|
Reference in New Issue
Block a user