platform: merge branch 'th/platform-route-pt1-bgo785449'

- extend platform's route-compare() functions with a mode argument.
  Most important is the new mode NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID,
  which corresponds kernels ID of how routes compare.

- when deleting routes, set all known parameters in the netlink message.
  Previously we would omit paramters, but that causes kernel to delete
  the first matching route.

- cleanup fields of routes

https://bugzilla.gnome.org/show_bug.cgi?id=785449
This commit is contained in:
Thomas Haller 2017-08-03 19:01:03 +02:00
commit 6da6323080
21 changed files with 954 additions and 700 deletions

View file

@ -1188,7 +1188,7 @@ nm_ip_route_set_attribute (NMIPRoute *route, const char *name, GVariant *value)
static const NMVariantAttributeSpec * const ip_route_attribute_spec[] = {
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_SRC, G_VARIANT_TYPE_STRING, TRUE, TRUE, 'a'),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_FROM, G_VARIANT_TYPE_STRING, FALSE, TRUE, 'p'),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_TOS, G_VARIANT_TYPE_BYTE, TRUE, TRUE, 0 ),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_TOS, G_VARIANT_TYPE_BYTE, TRUE, FALSE, 0 ),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_WINDOW, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_CWND, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_INITCWND, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),

View file

@ -24,6 +24,93 @@
/*****************************************************************************/
#define NM_CMP_RETURN(c) \
G_STMT_START { \
const int _cc = (c); \
if (_cc) \
return _cc < 0 ? -1 : 1; \
} G_STMT_END
#define NM_CMP_SELF(a, b) \
G_STMT_START { \
typeof (a) _a = (a); \
typeof (b) _b = (b); \
\
if (_a == _b) \
return 0; \
if (!_a) \
return -1; \
if (!_b) \
return 1; \
} G_STMT_END
#define NM_CMP_DIRECT(a, b) \
G_STMT_START { \
typeof (a) _a = (a); \
typeof (b) _b = (b); \
\
if (_a != _b) \
return (_a < _b) ? -1 : 1; \
} G_STMT_END
#define NM_CMP_DIRECT_MEMCMP(a, b, size) \
NM_CMP_RETURN (memcmp ((a), (b), (size)))
#define NM_CMP_DIRECT_IN6ADDR(a, b) \
G_STMT_START { \
const struct in6_addr *const _a = (a); \
const struct in6_addr *const _b = (b); \
NM_CMP_RETURN (memcmp (_a, _b, sizeof (struct in6_addr))); \
} G_STMT_END
#define NM_CMP_FIELD(a, b, field) \
NM_CMP_DIRECT (((a)->field), ((b)->field))
#define NM_CMP_FIELD_UNSAFE(a, b, field) \
G_STMT_START { \
/* it's unsafe, because it evaluates the arguments more then once.
* This is necessary for bitfields, for which typeof() doesn't work. */ \
if (((a)->field) != ((b)->field)) \
return ((a)->field < ((b)->field)) ? -1 : 1; \
} G_STMT_END
#define NM_CMP_FIELD_BOOL(a, b, field) \
NM_CMP_DIRECT (!!((a)->field), !!((b)->field))
#define NM_CMP_FIELD_STR(a, b, field) \
NM_CMP_RETURN (strcmp (((a)->field), ((b)->field)))
#define NM_CMP_FIELD_STR_INTERNED(a, b, field) \
G_STMT_START { \
const char *_a = ((a)->field); \
const char *_b = ((b)->field); \
\
if (_a != _b) { \
NM_CMP_RETURN (g_strcmp0 (_a, _b)); \
} \
} G_STMT_END
#define NM_CMP_FIELD_STR0(a, b, field) \
NM_CMP_RETURN (g_strcmp0 (((a)->field), ((b)->field)))
#define NM_CMP_FIELD_MEMCMP_LEN(a, b, field, len) \
NM_CMP_RETURN (memcmp (&((a)->field), &((b)->field), \
MIN (len, sizeof ((a)->field))))
#define NM_CMP_FIELD_MEMCMP(a, b, field) \
NM_CMP_RETURN (memcmp (&((a)->field), \
&((b)->field), \
sizeof ((a)->field)))
#define NM_CMP_FIELD_IN6ADDR(a, b, field) \
G_STMT_START { \
const struct in6_addr *const _a = &((a)->field); \
const struct in6_addr *const _b = &((b)->field); \
NM_CMP_RETURN (memcmp (_a, _b, sizeof (struct in6_addr))); \
} G_STMT_END
/*****************************************************************************/
extern const void *const _NM_PTRARRAY_EMPTY[1];
#define NM_PTRARRAY_EMPTY(type) ((type const*) _NM_PTRARRAY_EMPTY)

View file

@ -316,28 +316,28 @@ nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_
return dst;
}
gboolean
nm_utils_ip6_address_same_prefix (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen)
int
nm_utils_ip6_address_same_prefix_cmp (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen)
{
int nbytes;
guint8 t, m;
guint8 va, vb, m;
if (plen >= 128)
return memcmp (addr_a, addr_b, sizeof (struct in6_addr)) == 0;
NM_CMP_DIRECT_MEMCMP (addr_a, addr_b, sizeof (struct in6_addr));
else {
nbytes = plen / 8;
if (nbytes)
NM_CMP_DIRECT_MEMCMP (addr_a, addr_b, nbytes);
nbytes = plen / 8;
if (nbytes) {
if (memcmp (addr_a, addr_b, nbytes) != 0)
return FALSE;
plen = plen % 8;
if (plen != 0) {
m = ~((1 << (8 - plen)) - 1);
va = ((((const guint8 *) addr_a))[nbytes]) & m;
vb = ((((const guint8 *) addr_b))[nbytes]) & m;
NM_CMP_DIRECT (va, vb);
}
}
plen = plen % 8;
if (plen == 0)
return TRUE;
m = ~((1 << (8 - plen)) - 1);
t = ((((const guint8 *) addr_a))[nbytes]) ^ ((((const guint8 *) addr_b))[nbytes]);
return (t & m) == 0;
return 0;
}
/*****************************************************************************/

View file

@ -111,18 +111,51 @@ extern const NMIPAddr nm_ip_addr_zero;
guint nm_utils_in6_addr_hash (const struct in6_addr *addr);
static inline guint
NM_HASH_COMBINE_IN6_ADDR (guint h, const struct in6_addr *addr)
{
return NM_HASH_COMBINE (h, addr ? nm_utils_in6_addr_hash (addr) : 0);
}
gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len);
gconstpointer nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen);
in_addr_t nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen);
const struct in6_addr *nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen);
gboolean nm_utils_ip6_address_same_prefix (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen);
int nm_utils_ip6_address_same_prefix_cmp (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen);
static inline gboolean
nm_utils_ip6_address_same_prefix (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen)
{
return nm_utils_ip6_address_same_prefix_cmp (addr_a, addr_b, plen) == 0;
}
#define NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX(a, b, plen) \
NM_CMP_RETURN (nm_utils_ip6_address_same_prefix_cmp ((a), (b), (plen)))
#define NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(a, b, plen) \
G_STMT_START { \
const guint8 _plen = (plen); \
const in_addr_t _aa = (a); \
const in_addr_t _ab = (b); \
\
NM_CMP_DIRECT (htonl (nm_utils_ip4_address_clear_host_address (_aa, _plen)), \
htonl (nm_utils_ip4_address_clear_host_address (_ab, _plen))); \
} G_STMT_END
static inline guint
NM_HASH_COMBINE_IN6ADDR (guint h, const struct in6_addr *addr)
{
if (!addr)
g_return_val_if_reached (h);
return NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (addr));
}
static inline guint
NM_HASH_COMBINE_IN6ADDR_PREFIX (guint h, const struct in6_addr *addr, guint8 plen)
{
struct in6_addr a;
if (!addr)
g_return_val_if_reached (h);
nm_utils_ip6_address_clear_host_address (&a, addr, plen);
/* we don't hash plen itself. The caller may want to do that.*/
return NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&a));
}
double nm_utils_exp10 (gint16 e);

View file

@ -212,7 +212,7 @@ _vt_routes_has_entry (const VTableIP *vtable, const GPtrArray *routes, const Ent
const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE (routes->pdata[i]);
route.rx.rt_source = r->rt_source;
if (nm_platform_ip4_route_cmp (r, &route.r4) == 0)
if (nm_platform_ip4_route_cmp_full (r, &route.r4) == 0)
return TRUE;
}
} else {
@ -220,7 +220,7 @@ _vt_routes_has_entry (const VTableIP *vtable, const GPtrArray *routes, const Ent
const NMPlatformIP6Route *r = NMP_OBJECT_CAST_IP6_ROUTE (routes->pdata[i]);
route.rx.rt_source = r->rt_source;
if (nm_platform_ip6_route_cmp (r, &route.r6) == 0)
if (nm_platform_ip6_route_cmp_full (r, &route.r6) == 0)
return TRUE;
}
}
@ -304,7 +304,7 @@ _platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, g
rt.plen = 0;
rt.metric = entry->effective_metric;
success = nm_platform_ip4_route_add (priv->platform, &rt);
success = nm_platform_ip4_route_add (priv->platform, NMP_NLM_FLAG_REPLACE, &rt);
} else {
NMPlatformIP6Route rt = entry->route.r6;
@ -312,7 +312,7 @@ _platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, g
rt.plen = 0;
rt.metric = entry->effective_metric;
success = nm_platform_ip6_route_add (priv->platform, &rt);
success = nm_platform_ip6_route_add (priv->platform, NMP_NLM_FLAG_REPLACE, &rt);
}
if (!success) {
_LOGW (vtable->vt->addr_family, "failed to add default route %s with effective metric %u",

View file

@ -76,16 +76,14 @@ gboolean
nm_ip_config_obj_id_equal_ip4_route (const NMPlatformIP4Route *r_a,
const NMPlatformIP4Route *r_b)
{
return r_a->network == r_b->network
&& r_a->plen == r_b->plen;
return nm_platform_ip4_route_cmp (r_a, r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST) == 0;
}
gboolean
nm_ip_config_obj_id_equal_ip6_route (const NMPlatformIP6Route *r_a,
const NMPlatformIP6Route *r_b)
{
return r_a->plen == r_b->plen
&& IN6_ARE_ADDR_EQUAL (&r_a->network, &r_b->network);
return nm_platform_ip6_route_cmp (r_a, r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST) == 0;
}
static guint
@ -104,17 +102,15 @@ _idx_obj_id_hash (const NMDedupMultiIdxType *idx_type,
break;
case NMP_OBJECT_TYPE_IP6_ADDRESS:
h = 851146661;
h = NM_HASH_COMBINE_IN6_ADDR (h, &o->ip6_address.address);
h = NM_HASH_COMBINE_IN6ADDR (h, &o->ip6_address.address);
break;
case NMP_OBJECT_TYPE_IP4_ROUTE:
h = 40303327;
h = NM_HASH_COMBINE (h, o->ip4_route.network);
h = NM_HASH_COMBINE (h, o->ip_route.plen);
h = NM_HASH_COMBINE (h, nm_platform_ip4_route_hash (NMP_OBJECT_CAST_IP4_ROUTE (o), NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST));
break;
case NMP_OBJECT_TYPE_IP6_ROUTE:
h = 577629323;
h = NM_HASH_COMBINE_IN6_ADDR (h, &o->ip6_route.network);
h = NM_HASH_COMBINE (h, o->ip_route.plen);
h = NM_HASH_COMBINE (h, nm_platform_ip6_route_hash (NMP_OBJECT_CAST_IP6_ROUTE (o), NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST));
break;
default:
g_return_val_if_reached (0);
@ -1512,7 +1508,7 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
if (!has)
break;
if (nm_platform_ip4_route_cmp (r_src, r_dst) != 0) {
if (nm_platform_ip4_route_cmp_full (r_src, r_dst) != 0) {
are_equal = FALSE;
if ( !nm_ip_config_obj_id_equal_ip4_route (r_src, r_dst)
|| r_src->gateway != r_dst->gateway

View file

@ -569,7 +569,6 @@ merge_route_attributes (NMIPRoute *s_route, NMPlatformIP6Route *r)
if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_ ## variant_type)) \
r->field = g_variant_get_ ## type (variant);
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_TOS, tos, BYTE, byte);
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_WINDOW, window, UINT32, uint32);
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_CWND, cwnd, UINT32, uint32);
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_INITCWND, initcwnd, UINT32, uint32);
@ -1291,7 +1290,7 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
if (!has)
break;
if (nm_platform_ip6_route_cmp (r_src, r_dst) != 0) {
if (nm_platform_ip6_route_cmp_full (r_src, r_dst) != 0) {
are_equal = FALSE;
if ( !nm_ip_config_obj_id_equal_ip6_route (r_src, r_dst)
|| r_src->metric != r_dst->metric

View file

@ -428,7 +428,7 @@ _route_equals_ignoring_ifindex (const VTableIP *vtable, const NMPlatformIPXRoute
r2_backup.rx.metric = (guint32) r2_metric;
r2 = &r2_backup;
}
return vtable->vt->route_cmp (r1, r2, FALSE) == 0;
return vtable->vt->route_cmp (r1, r2, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) == 0;
}
static NMPlatformIPXRoute *
@ -896,15 +896,16 @@ next:
gateway_routes = g_array_new (FALSE, FALSE, sizeof (guint));
g_array_append_val (gateway_routes, i_ipx_routes);
} else
vtable->vt->route_add (priv->platform, 0, cur_ipx_route, *p_effective_metric);
vtable->vt->route_add (priv->platform, NMP_NLM_FLAG_REPLACE,
cur_ipx_route, 0, *p_effective_metric);
}
if (gateway_routes) {
for (i = 0; i < gateway_routes->len; i++) {
i_ipx_routes = g_array_index (gateway_routes, guint, i);
vtable->vt->route_add (priv->platform, 0,
vtable->vt->route_add (priv->platform, NMP_NLM_FLAG_REPLACE,
ipx_routes->index->entries[i_ipx_routes],
effective_metrics[i_ipx_routes]);
0, effective_metrics[i_ipx_routes]);
}
g_array_unref (gateway_routes);
}
@ -953,7 +954,8 @@ next:
|| route_dest_cmp_result != 0
|| !_route_equals_ignoring_ifindex (vtable, cur_plat_route, cur_ipx_route, *p_effective_metric)) {
if (!vtable->vt->route_add (priv->platform, ifindex, cur_ipx_route, *p_effective_metric)) {
if (!vtable->vt->route_add (priv->platform, NMP_NLM_FLAG_REPLACE,
cur_ipx_route, ifindex, *p_effective_metric)) {
if (cur_ipx_route->rx.rt_source < NM_IP_CONFIG_SOURCE_USER) {
_LOGD (vtable->vt->addr_family,
"ignore error adding IPv%c route to kernel: %s",

View file

@ -195,7 +195,7 @@ nmtst_platform_ip6_route_full (const char *network, guint plen, const char *gate
static inline int
_nmtst_platform_ip4_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data)
{
return nm_platform_ip4_route_cmp ((const NMPlatformIP4Route *) a, (const NMPlatformIP4Route *) b);
return nm_platform_ip4_route_cmp_full ((const NMPlatformIP4Route *) a, (const NMPlatformIP4Route *) b);
}
static inline void
@ -215,7 +215,7 @@ nmtst_platform_ip4_routes_equal (const NMPlatformIP4Route *a, const NMPlatformIP
}
for (i = 0; i < len; i++) {
if (nm_platform_ip4_route_cmp (&a[i], &b[i]) != 0) {
if (nm_platform_ip4_route_cmp_full (&a[i], &b[i]) != 0) {
char buf[sizeof (_nm_utils_to_string_buffer)];
g_error ("Error comparing IPv4 route[%lu]: %s vs %s", (unsigned long) i,
@ -248,7 +248,7 @@ nmtst_platform_ip4_routes_equal_aptr (const NMPObject *const*a, const NMPlatform
static inline int
_nmtst_platform_ip6_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data)
{
return nm_platform_ip6_route_cmp ((const NMPlatformIP6Route *) a, (const NMPlatformIP6Route *) b);
return nm_platform_ip6_route_cmp_full ((const NMPlatformIP6Route *) a, (const NMPlatformIP6Route *) b);
}
static inline void
@ -268,7 +268,7 @@ nmtst_platform_ip6_routes_equal (const NMPlatformIP6Route *a, const NMPlatformIP
}
for (i = 0; i < len; i++) {
if (nm_platform_ip6_route_cmp (&a[i], &b[i]) != 0) {
if (nm_platform_ip6_route_cmp_full (&a[i], &b[i]) != 0) {
char buf[sizeof (_nm_utils_to_string_buffer)];
g_error ("Error comparing IPv6 route[%lu]: %s vs %s", (unsigned long) i,

View file

@ -1192,7 +1192,10 @@ ip_route_delete (NMPlatform *platform, const NMPObject *obj)
}
static gboolean
ipx_route_add (NMPlatform *platform, int addr_family, const NMPlatformObject *route)
ip_route_add (NMPlatform *platform,
NMPNlmFlags flags,
int addr_family,
const NMPlatformIPRoute *route)
{
NMDedupMultiIter iter;
nm_auto_nmpobj NMPObject *obj = NULL;
@ -1208,10 +1211,13 @@ ipx_route_add (NMPlatform *platform, int addr_family, const NMPlatformObject *ro
g_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
/* currently, only replace is implemented. */
g_assert (flags == NMP_NLM_FLAG_REPLACE);
obj = nmp_object_new (addr_family == AF_INET
? NMP_OBJECT_TYPE_IP4_ROUTE
: NMP_OBJECT_TYPE_IP6_ROUTE,
route);
(const NMPlatformObject *) route);
rt = &obj->ip_route;
rt->rt_source = nmp_utils_ip_config_source_round_trip_rtprot (rt->rt_source);
@ -1274,18 +1280,6 @@ ipx_route_add (NMPlatform *platform, int addr_family, const NMPlatformObject *ro
return TRUE;
}
static gboolean
ip4_route_add (NMPlatform *platform, const NMPlatformIP4Route *route)
{
return ipx_route_add (platform, AF_INET, (const NMPlatformObject *) route);
}
static gboolean
ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *route)
{
return ipx_route_add (platform, AF_INET6, (const NMPlatformObject *) route);
}
/*****************************************************************************/
static void
@ -1396,7 +1390,6 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
platform_class->ip4_address_delete = ip4_address_delete;
platform_class->ip6_address_delete = ip6_address_delete;
platform_class->ip4_route_add = ip4_route_add;
platform_class->ip6_route_add = ip6_route_add;
platform_class->ip_route_add = ip_route_add;
platform_class->ip_route_delete = ip_route_delete;
}

View file

@ -2018,9 +2018,13 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
memcpy (&obj->ip6_route.pref_src, nla_data (tb[RTA_PREFSRC]), addr_len);
}
if (!is_v4 && tb[RTA_SRC]) {
_check_addr_or_errout (tb, RTA_SRC, addr_len);
memcpy (&obj->ip6_route.src, nla_data (tb[RTA_SRC]), addr_len);
if (is_v4)
obj->ip4_route.tos = rtm->rtm_tos;
else {
if (tb[RTA_SRC]) {
_check_addr_or_errout (tb, RTA_SRC, addr_len);
memcpy (&obj->ip6_route.src, nla_data (tb[RTA_SRC]), addr_len);
}
obj->ip6_route.src_plen = rtm->rtm_src_len;
}
@ -2030,12 +2034,11 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
obj->ip_route.initcwnd = initcwnd;
obj->ip_route.initrwnd = initrwnd;
obj->ip_route.mtu = mtu;
obj->ip_route.tos = rtm->rtm_tos;
obj->ip_route.lock_window = NM_FLAGS_HAS (lock, 1 << RTAX_WINDOW);
obj->ip_route.lock_cwnd = NM_FLAGS_HAS (lock, 1 << RTAX_CWND);
obj->ip_route.lock_window = NM_FLAGS_HAS (lock, 1 << RTAX_WINDOW);
obj->ip_route.lock_cwnd = NM_FLAGS_HAS (lock, 1 << RTAX_CWND);
obj->ip_route.lock_initcwnd = NM_FLAGS_HAS (lock, 1 << RTAX_INITCWND);
obj->ip_route.lock_initrwnd = NM_FLAGS_HAS (lock, 1 << RTAX_INITRWND);
obj->ip_route.lock_mtu = NM_FLAGS_HAS (lock, 1 << RTAX_MTU);
obj->ip_route.lock_mtu = NM_FLAGS_HAS (lock, 1 << RTAX_MTU);
if (NM_FLAGS_HAS (rtm->rtm_flags, RTM_F_CLONED)) {
/* we must not straight way reject cloned routes, because we might have cached
@ -2414,38 +2417,42 @@ nla_put_failure:
g_return_val_if_reached (NULL);
}
static guint32
ip_route_get_lock_flag (const NMPlatformIPRoute *route)
{
return (((guint32) route->lock_window) << RTAX_WINDOW)
| (((guint32) route->lock_cwnd) << RTAX_CWND)
| (((guint32) route->lock_initcwnd) << RTAX_INITCWND)
| (((guint32) route->lock_initrwnd) << RTAX_INITRWND)
| (((guint32) route->lock_mtu) << RTAX_MTU);
}
/* Copied and modified from libnl3's build_route_msg() and rtnl_route_build_msg(). */
static struct nl_msg *
_nl_msg_new_route (int nlmsg_type,
int nlmsg_flags,
const NMPObject *obj,
NMIPConfigSource source,
unsigned char scope,
gconstpointer gateway,
guint32 mss,
gconstpointer pref_src,
gconstpointer src,
guint8 src_plen,
guint32 window,
guint32 cwnd,
guint32 initcwnd,
guint32 initrwnd,
guint32 mtu,
guint32 lock)
NMPNlmFlags nlmsgflags,
const NMPObject *obj)
{
struct nl_msg *msg;
const NMPClass *klass = NMP_OBJECT_GET_CLASS (obj);
gboolean is_v4 = klass->addr_family == AF_INET;
const guint32 lock = ip_route_get_lock_flag (NMP_OBJECT_CAST_IP_ROUTE (obj));
struct rtmsg rtmsg = {
.rtm_family = klass->addr_family,
.rtm_tos = obj->ip_route.tos,
.rtm_tos = is_v4
? obj->ip4_route.tos
: 0,
.rtm_table = RT_TABLE_MAIN, /* omit setting RTA_TABLE attribute */
.rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot (source),
.rtm_scope = scope,
.rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot (obj->ip_route.rt_source),
.rtm_scope = is_v4
? nm_platform_route_scope_inv (obj->ip4_route.scope_inv)
: RT_SCOPE_NOWHERE,
.rtm_type = RTN_UNICAST,
.rtm_flags = 0,
.rtm_dst_len = obj->ip_route.plen,
.rtm_src_len = src ? src_plen : 0,
.rtm_src_len = is_v4
? 0
: NMP_OBJECT_CAST_IP6_ROUTE (obj)->src_plen,
};
gsize addr_len;
@ -2453,7 +2460,8 @@ _nl_msg_new_route (int nlmsg_type,
nm_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
nm_assert (NM_IN_SET (nlmsg_type, RTM_NEWROUTE, RTM_DELROUTE));
msg = nlmsg_alloc_simple (nlmsg_type, nlmsg_flags);
nm_assert (((NMPNlmFlags) ((int) nlmsgflags)) == nlmsgflags);
msg = nlmsg_alloc_simple (nlmsg_type, (int) nlmsgflags);
if (!msg)
g_return_val_if_reached (NULL);
@ -2469,33 +2477,46 @@ _nl_msg_new_route (int nlmsg_type,
? (gconstpointer) &obj->ip4_route.network
: (gconstpointer) &obj->ip6_route.network);
if (src)
NLA_PUT (msg, RTA_SRC, addr_len, src);
if (!is_v4) {
if (!IN6_IS_ADDR_UNSPECIFIED (&NMP_OBJECT_CAST_IP6_ROUTE (obj)->src))
NLA_PUT (msg, RTA_SRC, addr_len, &obj->ip6_route.src);
}
NLA_PUT_U32 (msg, RTA_PRIORITY, obj->ip_route.metric);
if (pref_src)
NLA_PUT (msg, RTA_PREFSRC, addr_len, pref_src);
if (is_v4) {
if (NMP_OBJECT_CAST_IP4_ROUTE (obj)->pref_src)
NLA_PUT (msg, RTA_PREFSRC, addr_len, &obj->ip4_route.pref_src);
} else {
if (!IN6_IS_ADDR_UNSPECIFIED (&NMP_OBJECT_CAST_IP6_ROUTE (obj)->pref_src))
NLA_PUT (msg, RTA_PREFSRC, addr_len, &obj->ip6_route.pref_src);
}
if (mss || window || cwnd || initcwnd || initrwnd || mtu || lock) {
if ( obj->ip_route.mss
|| obj->ip_route.window
|| obj->ip_route.cwnd
|| obj->ip_route.initcwnd
|| obj->ip_route.initrwnd
|| obj->ip_route.mtu
|| lock) {
struct nlattr *metrics;
metrics = nla_nest_start (msg, RTA_METRICS);
if (!metrics)
goto nla_put_failure;
if (mss)
NLA_PUT_U32 (msg, RTAX_ADVMSS, mss);
if (window)
NLA_PUT_U32 (msg, RTAX_WINDOW, window);
if (cwnd)
NLA_PUT_U32 (msg, RTAX_CWND, cwnd);
if (initcwnd)
NLA_PUT_U32 (msg, RTAX_INITCWND, initcwnd);
if (initrwnd)
NLA_PUT_U32 (msg, RTAX_INITRWND, initrwnd);
if (mtu)
NLA_PUT_U32 (msg, RTAX_MTU, mtu);
if (obj->ip_route.mss)
NLA_PUT_U32 (msg, RTAX_ADVMSS, obj->ip_route.mss);
if (obj->ip_route.window)
NLA_PUT_U32 (msg, RTAX_WINDOW, obj->ip_route.window);
if (obj->ip_route.cwnd)
NLA_PUT_U32 (msg, RTAX_CWND, obj->ip_route.cwnd);
if (obj->ip_route.initcwnd)
NLA_PUT_U32 (msg, RTAX_INITCWND, obj->ip_route.initcwnd);
if (obj->ip_route.initrwnd)
NLA_PUT_U32 (msg, RTAX_INITRWND, obj->ip_route.initrwnd);
if (obj->ip_route.mtu)
NLA_PUT_U32 (msg, RTAX_MTU, obj->ip_route.mtu);
if (lock)
NLA_PUT_U32 (msg, RTAX_LOCK, lock);
@ -2503,9 +2524,12 @@ _nl_msg_new_route (int nlmsg_type,
}
/* We currently don't have need for multi-hop routes... */
if ( gateway
&& memcmp (gateway, &nm_ip_addr_zero, addr_len) != 0)
NLA_PUT (msg, RTA_GATEWAY, addr_len, gateway);
if (is_v4) {
NLA_PUT (msg, RTA_GATEWAY, addr_len, &obj->ip4_route.gateway);
} else {
if (!IN6_IS_ADDR_UNSPECIFIED (&obj->ip6_route.gateway))
NLA_PUT (msg, RTA_GATEWAY, addr_len, &obj->ip6_route.gateway);
}
NLA_PUT_U32 (msg, RTA_OIF, obj->ip_route.ifindex);
return msg;
@ -5675,73 +5699,40 @@ ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, gui
/*****************************************************************************/
static guint32
ip_route_get_lock_flag (NMPlatformIPRoute *route)
{
return (((guint32) route->lock_window) << RTAX_WINDOW)
| (((guint32) route->lock_cwnd) << RTAX_CWND)
| (((guint32) route->lock_initcwnd) << RTAX_INITCWND)
| (((guint32) route->lock_initrwnd) << RTAX_INITRWND)
| (((guint32) route->lock_mtu) << RTAX_MTU);
}
static gboolean
ip4_route_add (NMPlatform *platform, const NMPlatformIP4Route *route)
ip_route_add (NMPlatform *platform,
NMPNlmFlags flags,
int addr_family,
const NMPlatformIPRoute *route)
{
NMPObject obj;
NMPlatformIP4Route *r;
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
nmp_object_stackinit (&obj, NMP_OBJECT_TYPE_IP4_ROUTE, (const NMPlatformObject *) route);
r = NMP_OBJECT_CAST_IP4_ROUTE (&obj);
r->network = nm_utils_ip4_address_clear_host_address (r->network, r->plen);
nlmsg = _nl_msg_new_route (RTM_NEWROUTE,
NLM_F_CREATE | NLM_F_REPLACE,
&obj,
route->rt_source,
route->gateway ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK,
&route->gateway,
route->mss,
route->pref_src ? &route->pref_src : NULL,
NULL,
0,
route->window,
route->cwnd,
route->initcwnd,
route->initrwnd,
route->mtu,
ip_route_get_lock_flag ((NMPlatformIPRoute *) route));
return do_add_addrroute (platform, &obj, nlmsg);
}
static gboolean
ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *route)
{
NMPObject obj;
NMPlatformIP6Route *r;
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
NMPlatformIP4Route *r4;
NMPlatformIP6Route *r6;
nmp_object_stackinit (&obj, NMP_OBJECT_TYPE_IP6_ROUTE, (const NMPlatformObject *) route);
r = NMP_OBJECT_CAST_IP6_ROUTE (&obj);
nm_utils_ip6_address_clear_host_address (&r->network, &r->network, r->plen);
switch (addr_family) {
case AF_INET:
nmp_object_stackinit (&obj, NMP_OBJECT_TYPE_IP4_ROUTE, (const NMPlatformObject *) route);
r4 = NMP_OBJECT_CAST_IP4_ROUTE (&obj);
r4->network = nm_utils_ip4_address_clear_host_address (r4->network, r4->plen);
r4->rt_source = nmp_utils_ip_config_source_round_trip_rtprot (r4->rt_source),
r4->scope_inv = nm_platform_route_scope_inv (!r4->gateway
? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
break;
case AF_INET6:
nmp_object_stackinit (&obj, NMP_OBJECT_TYPE_IP6_ROUTE, (const NMPlatformObject *) route);
r6 = NMP_OBJECT_CAST_IP6_ROUTE (&obj);
nm_utils_ip6_address_clear_host_address (&r6->network, &r6->network, r6->plen);
r6->rt_source = nmp_utils_ip_config_source_round_trip_rtprot (r6->rt_source),
nm_utils_ip6_address_clear_host_address (&r6->src, &r6->src, r6->src_plen);
break;
default:
nm_assert_not_reached ();
}
nlmsg = _nl_msg_new_route (RTM_NEWROUTE,
NLM_F_CREATE | NLM_F_REPLACE,
&obj,
route->rt_source,
IN6_IS_ADDR_UNSPECIFIED (&route->gateway) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE,
&route->gateway,
route->mss,
!IN6_IS_ADDR_UNSPECIFIED (&route->pref_src) ? &route->pref_src : NULL,
!IN6_IS_ADDR_UNSPECIFIED (&route->src) ? &route->src : NULL,
route->src_plen,
route->window,
route->cwnd,
route->initcwnd,
route->initrwnd,
route->mtu,
ip_route_get_lock_flag ((NMPlatformIPRoute *) route));
nlmsg = _nl_msg_new_route (RTM_NEWROUTE, flags, &obj);
if (!nlmsg)
g_return_val_if_reached (FALSE);
return do_add_addrroute (platform, &obj, nlmsg);
}
@ -5789,24 +5780,9 @@ ip_route_delete (NMPlatform *platform,
}
}
nlmsg = _nl_msg_new_route (RTM_DELROUTE,
0,
obj,
NM_IP_CONFIG_SOURCE_UNKNOWN,
RT_SCOPE_NOWHERE,
NULL,
0,
NULL,
NULL,
0,
0,
0,
0,
0,
0,
0);
nlmsg = _nl_msg_new_route (RTM_DELROUTE, 0, obj);
if (!nlmsg)
return FALSE;
g_return_val_if_reached (FALSE);
return do_delete_object (platform, obj, nlmsg);
}
@ -6537,8 +6513,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->ip4_address_delete = ip4_address_delete;
platform_class->ip6_address_delete = ip6_address_delete;
platform_class->ip4_route_add = ip4_route_add;
platform_class->ip6_route_add = ip6_route_add;
platform_class->ip_route_add = ip_route_add;
platform_class->ip_route_delete = ip_route_delete;
platform_class->check_support_kernel_extended_ifa_flags = check_support_kernel_extended_ifa_flags;

File diff suppressed because it is too large Load diff

View file

@ -73,6 +73,72 @@ struct udev_device;
/* Redefine this in host's endianness */
#define NM_GRE_KEY 0x2000
typedef enum {
/* use our own platform enum for the nlmsg-flags. Otherwise, we'd have
* to include <linux/netlink.h> */
NMP_NLM_FLAG_F_REPLACE = 0x100, /* NLM_F_REPLACE, Override existing */
NMP_NLM_FLAG_F_EXCL = 0x200, /* NLM_F_EXCL, Do not touch, if it exists */
NMP_NLM_FLAG_F_CREATE = 0x400, /* NLM_F_CREATE, Create, if it does not exist */
NMP_NLM_FLAG_F_APPEND = 0x800, /* NLM_F_APPEND, Add to end of list */
/* the following aliases correspond to iproute2's `ip route CMD` for
* RTM_NEWROUTE, with CMD being one of add, change, replace, prepend,
* append and test. */
NMP_NLM_FLAG_ADD = NMP_NLM_FLAG_F_CREATE | NMP_NLM_FLAG_F_EXCL,
NMP_NLM_FLAG_CHANGE = NMP_NLM_FLAG_F_REPLACE,
NMP_NLM_FLAG_REPLACE = NMP_NLM_FLAG_F_CREATE | NMP_NLM_FLAG_F_REPLACE,
NMP_NLM_FLAG_PREPEND = NMP_NLM_FLAG_F_CREATE,
NMP_NLM_FLAG_APPEND = NMP_NLM_FLAG_F_CREATE | NMP_NLM_FLAG_F_APPEND,
NMP_NLM_FLAG_TEST = NMP_NLM_FLAG_F_EXCL,
} NMPNlmFlags;
typedef enum {
/* compare fields which kernel considers as similar routes.
* It is a looser comparisong then NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID
* and means that `ip route add` would fail to add two routes
* that have the same NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID.
* On the other hand, `ip route append` would allow that, as
* long as NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID differs. */
NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID,
/* compare two routes as kernel would allow to add them with
* `ip route append`. In other words, kernel does not allow you to
* add two routes (at the same time) which compare equal according
* to NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID.
*
* For the ID we can only recognize route fields that we actually implement.
* However, kernel supports more routing options, some of them also part of
* the ID. NetworkManager is oblivious to these options and will wrongly think
* that two routes are idential, while they are not. That can lead to an
* inconsistent platform cache. Not much what we can do about that, except
* implementing all options that kernel supports *sigh*. See rh#1337860.
*/
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID,
/* FIXME: this type is what NMPCache currently uses for object identity.
* Eventually, we want to use NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID,
* which is the same what kernel does. */
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE,
/* NMIP4Config and NMIP6Config also track a list of routes. They have their
* own notion of what equality means. Basically, they consider network/plen
* for IPv4 and IPv6. */
NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST,
/* compare all fields as they make sense for kernel. For example,
* a route destination 192.168.1.5/24 is not accepted by kernel and
* we treat it identical to 192.168.1.0/24. Semantically these
* routes are identical, but NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL will
* report them as different. */
NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY,
/* compare all fields. This should have the same effect as memcmp(),
* except allowing for undefined data in holes between field alignment.
*/
NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL,
} NMPlatformIPRouteCmpType;
typedef enum { /*< skip >*/
/* dummy value, to enforce that the enum type is signed and has a size
@ -287,7 +353,15 @@ typedef union {
/* The NMIPConfigSource. For routes that we receive from cache this corresponds
* to the rtm_protocol field (and is one of the NM_IP_CONFIG_SOURCE_RTPROT_* values).
* When adding a route, the source will be coerced to the protocol using
* nmp_utils_ip_config_source_coerce_to_rtprot(). */ \
* nmp_utils_ip_config_source_coerce_to_rtprot().
*
* rtm_protocol is part of the primary key of an IPv4 route (meaning, you can add
* two IPv4 routes that only differ in their rtm_protocol. For IPv6, that is not
* the case.
*
* When deleting an IPv4/IPv6 route, the rtm_protocol field must match (even
* if it is not part of the primary key for IPv6) -- unless rtm_protocol is set
* to zero, in which case the first matching route (with proto ignored) is deleted. */ \
NMIPConfigSource rt_source; \
\
guint8 plen; \
@ -297,21 +371,51 @@ typedef union {
* of platform users. This flag is internal to track those hidden
* routes. Such a route is not alive, according to nmp_object_is_alive(). */ \
bool rt_cloned:1; \
\
\
/* RTA_METRICS:
*
* For IPv4 routes, these properties are part of their
* ID (meaning: you can add otherwise idential IPv4 routes that
* only differ by the metric property).
* On the other hand, for IPv6 you cannot add two IPv6 routes that only differ
* by an RTA_METRICS property.
*
* When deleting a route, kernel seems to ignore the RTA_METRICS propeties.
* That is a problem/bug for IPv4 because you cannot explicitly select which
* route to delete. Kernel just picks the first. See rh#1475642. */ \
\
/* RTA_METRICS.RTAX_LOCK (iproute2: "lock" arguments) */ \
bool lock_window:1; \
bool lock_cwnd:1; \
bool lock_initcwnd:1; \
bool lock_initrwnd:1; \
bool lock_mtu:1; \
\
guint32 metric; \
/* RTA_METRICS.RTAX_ADVMSS (iproute2: advmss) */ \
guint32 mss; \
guint32 tos; \
\
/* RTA_METRICS.RTAX_WINDOW (iproute2: window) */ \
guint32 window; \
\
/* RTA_METRICS.RTAX_CWND (iproute2: cwnd) */ \
guint32 cwnd; \
\
/* RTA_METRICS.RTAX_INITCWND (iproute2: initcwnd) */ \
guint32 initcwnd; \
\
/* RTA_METRICS.RTAX_INITRWND (iproute2: initrwnd) */ \
guint32 initrwnd; \
\
/* RTA_METRICS.RTAX_MTU (iproute2: mtu) */ \
guint32 mtu; \
;
\
\
/* RTA_PRIORITY (iproute2: metric) */ \
guint32 metric; \
\
/*end*/
typedef struct {
__NMPlatformIPRoute_COMMON;
@ -327,22 +431,60 @@ typedef struct {
struct _NMPlatformIP4Route {
__NMPlatformIPRoute_COMMON;
in_addr_t network;
/* RTA_GATEWAY. The gateway is part of the primary key for a route */
in_addr_t gateway;
/* The bitwise inverse of the route scope. It is inverted so that the
* default value (RT_SCOPE_NOWHERE) is nul. */
guint8 scope_inv;
/* RTA_PREFSRC/rtnl_route_get_pref_src(). A value of zero means that
* no pref-src is set. */
/* RTA_PREFSRC (called "src" by iproute2).
*
* pref_src is part of the ID of an IPv4 route. When deleting a route,
* pref_src must match, unless set to 0.0.0.0 to match any. */
in_addr_t pref_src;
/* rtm_tos (iproute2: tos)
*
* For IPv4, tos is part of the weak-id (like metric).
*
* For IPv6, tos is ignored by kernel. */
guint8 tos;
/* The bitwise inverse of the route scope rtm_scope. It is inverted so that the
* default value (RT_SCOPE_NOWHERE) is zero. Use nm_platform_route_scope_inv()
* to convert back and forth between the inverese representation and the
* real value.
*
* rtm_scope is part of the primary key for IPv4 routes. When deleting a route,
* the scope must match, unless it is left at RT_SCOPE_NOWHERE, in which case the first
* matching route is deleted.
*
* For IPv6 routes, the scope is ignored and kernel always assumes global scope.
* Hence, this field is only in NMPlatformIP4Route. */
guint8 scope_inv;
};
struct _NMPlatformIP6Route {
__NMPlatformIPRoute_COMMON;
struct in6_addr network;
/* RTA_GATEWAY. The gateway is part of the primary key for a route */
struct in6_addr gateway;
/* RTA_PREFSRC (called "src" by iproute2).
*
* pref_src is not part of the ID for an IPv6 route. You cannot add two
* routes that only differ by pref_src.
*
* When deleting a route, pref_src is ignored by kernel. */
struct in6_addr pref_src;
/* RTA_SRC and rtm_src_len (called "from" by iproute2).
*
* Kernel clears the host part of src/src_plen.
*
* src/src_plen is part of the ID of a route just like network/plen. That is,
* Not only `ip route append`, but also `ip route add` allows to add routes that only
* differ in their src/src_plen.
*/
struct in6_addr src;
guint8 src_plen;
};
@ -364,9 +506,13 @@ typedef struct {
NMPObjectType obj_type;
int addr_family;
gsize sizeof_route;
int (*route_cmp) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, gboolean consider_host_part);
int (*route_cmp) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, NMPlatformIPRouteCmpType cmp_type);
const char *(*route_to_string) (const NMPlatformIPXRoute *route, char *buf, gsize len);
gboolean (*route_add) (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route, gint64 metric);
gboolean (*route_add) (NMPlatform *self,
NMPNlmFlags flags,
const NMPlatformIPXRoute *route,
int ifindex,
gint64 metric);
guint32 (*metric_normalize) (guint32 metric);
} NMPlatformVTableRoute;
@ -640,8 +786,10 @@ typedef struct {
gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address);
gboolean (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, guint8 plen);
gboolean (*ip4_route_add) (NMPlatform *, const NMPlatformIP4Route *route);
gboolean (*ip6_route_add) (NMPlatform *, const NMPlatformIP6Route *route);
gboolean (*ip_route_add) (NMPlatform *,
NMPNlmFlags flags,
int addr_family,
const NMPlatformIPRoute *route);
gboolean (*ip_route_delete) (NMPlatform *, const NMPObject *obj);
gboolean (*check_support_kernel_extended_ifa_flags) (NMPlatform *);
@ -954,8 +1102,10 @@ gboolean nm_platform_address_flush (NMPlatform *self, int ifindex);
const NMPlatformIP4Route *nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric);
const NMPlatformIP6Route *nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric);
gboolean nm_platform_ip4_route_add (NMPlatform *self, const NMPlatformIP4Route *route);
gboolean nm_platform_ip6_route_add (NMPlatform *self, const NMPlatformIP6Route *route);
gboolean nm_platform_ip4_route_add (NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP4Route *route);
gboolean nm_platform_ip6_route_add (NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP6Route *route);
gboolean nm_platform_ip_route_delete (NMPlatform *self, const NMPObject *route);
const char *nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len);
@ -991,26 +1141,27 @@ int nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVla
int nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b);
int nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b);
int nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6Address *b);
int nm_platform_ip4_route_cmp_full (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, gboolean consider_host_part);
int nm_platform_ip6_route_cmp_full (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, gboolean consider_host_part);
int nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, NMPlatformIPRouteCmpType cmp_type);
int nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, NMPlatformIPRouteCmpType cmp_type);
static inline int
nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b)
nm_platform_ip4_route_cmp_full (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b)
{
return nm_platform_ip4_route_cmp_full (a, b, TRUE);
return nm_platform_ip4_route_cmp (a, b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL);
}
static inline int
nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b)
nm_platform_ip6_route_cmp_full (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b)
{
return nm_platform_ip6_route_cmp_full (a, b, TRUE);
return nm_platform_ip6_route_cmp (a, b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL);
}
guint nm_platform_link_hash (const NMPlatformLink *obj);
guint nm_platform_ip4_address_hash (const NMPlatformIP4Address *obj);
guint nm_platform_ip6_address_hash (const NMPlatformIP6Address *obj);
guint nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj);
guint nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj);
guint nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type);
guint nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type);
guint nm_platform_lnk_gre_hash (const NMPlatformLnkGre *obj);
guint nm_platform_lnk_infiniband_hash (const NMPlatformLnkInfiniband *obj);
guint nm_platform_lnk_ip6tnl_hash (const NMPlatformLnkIp6Tnl *obj);
@ -1021,6 +1172,18 @@ guint nm_platform_lnk_sit_hash (const NMPlatformLnkSit *obj);
guint nm_platform_lnk_vlan_hash (const NMPlatformLnkVlan *obj);
guint nm_platform_lnk_vxlan_hash (const NMPlatformLnkVxlan *obj);
static inline guint
nm_platform_ip4_route_hash_full (const NMPlatformIP4Route *obj)
{
return nm_platform_ip4_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL);
}
static inline guint
nm_platform_ip6_route_hash_full (const NMPlatformIP6Route *obj)
{
return nm_platform_ip6_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL);
}
gboolean nm_platform_check_support_kernel_extended_ifa_flags (NMPlatform *self);
gboolean nm_platform_check_support_user_ipv6ll (NMPlatform *self);

View file

@ -225,21 +225,16 @@ _idx_obj_part (const DedupMultiIdxType *idx_type,
if (obj_b) {
return obj_type == NMP_OBJECT_GET_TYPE (obj_b)
&& obj_b->object.ifindex > 0
&& obj_a->ip_route.plen == obj_b->ip_route.plen
&& obj_a->ip_route.metric == obj_b->ip_route.metric
&& (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE
? obj_a->ip4_route.network == obj_b->ip4_route.network
: IN6_ARE_ADDR_EQUAL (&obj_a->ip6_route.network, &obj_b->ip6_route.network));
? (nm_platform_ip4_route_cmp (&obj_a->ip4_route, &obj_b->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) == 0)
: (nm_platform_ip6_route_cmp (&obj_a->ip6_route, &obj_b->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) == 0));
}
if (request_hash) {
h = (guint) idx_type->cache_id_type;
h = NM_HASH_COMBINE (h, obj_a->ip_route.plen);
h = NM_HASH_COMBINE (h, obj_a->ip_route.metric);
h = NM_HASH_COMBINE (h, obj_type);
if (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE)
h = NM_HASH_COMBINE (h, obj_a->ip4_route.network);
h = NM_HASH_COMBINE (h, nm_platform_ip4_route_hash (&obj_a->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID));
else
h = NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&obj_a->ip6_route.network));
h = NM_HASH_COMBINE (h, nm_platform_ip6_route_hash (&obj_a->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID));
return _HASH_NON_ZERO (h);
}
return 1;
@ -559,10 +554,9 @@ nmp_object_stackinit_id (NMPObject *obj, const NMPObject *src)
nm_assert (obj);
klass = NMP_OBJECT_GET_CLASS (src);
if (!klass->cmd_obj_stackinit_id)
_nmp_object_stackinit_from_class (obj, klass);
else
klass->cmd_obj_stackinit_id (obj, src);
_nmp_object_stackinit_from_class (obj, klass);
if (klass->cmd_plobj_id_copy)
klass->cmd_plobj_id_copy (&obj->object, &src->object);
return obj;
}
@ -574,12 +568,6 @@ nmp_object_stackinit_id_link (NMPObject *obj, int ifindex)
return obj;
}
static void
_vt_cmd_obj_stackinit_id_link (NMPObject *obj, const NMPObject *src)
{
nmp_object_stackinit_id_link (obj, src->link.ifindex);
}
const NMPObject *
nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifindex, guint32 address, guint8 plen, guint32 peer_address)
{
@ -591,12 +579,6 @@ nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifindex, guint32 addres
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, src->ip4_address.peer_address);
}
const NMPObject *
nmp_object_stackinit_id_ip6_address (NMPObject *obj, int ifindex, const struct in6_addr *address)
{
@ -607,12 +589,6 @@ nmp_object_stackinit_id_ip6_address (NMPObject *obj, int ifindex, const struct i
return obj;
}
static void
_vt_cmd_obj_stackinit_id_ip6_address (NMPObject *obj, const NMPObject *src)
{
nmp_object_stackinit_id_ip6_address (obj, src->ip_address.ifindex, &src->ip6_address.address);
}
const NMPObject *
nmp_object_stackinit_id_ip4_route (NMPObject *obj, int ifindex, guint32 network, guint8 plen, guint32 metric)
{
@ -624,12 +600,6 @@ nmp_object_stackinit_id_ip4_route (NMPObject *obj, int ifindex, guint32 network,
return obj;
}
static void
_vt_cmd_obj_stackinit_id_ip4_route (NMPObject *obj, const NMPObject *src)
{
nmp_object_stackinit_id_ip4_route (obj, src->ip_route.ifindex, src->ip4_route.network, src->ip_route.plen, src->ip_route.metric);
}
const NMPObject *
nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric)
{
@ -642,12 +612,6 @@ nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6
return obj;
}
static void
_vt_cmd_obj_stackinit_id_ip6_route (NMPObject *obj, const NMPObject *src)
{
nmp_object_stackinit_id_ip6_route (obj, src->ip_route.ifindex, &src->ip6_route.network, src->ip_route.plen, src->ip_route.metric);
}
/*****************************************************************************/
const char *
@ -1024,12 +988,14 @@ _vt_cmd_plobj_id_copy (ip4_route, NMPlatformIP4Route, {
dst->plen = src->plen;
dst->metric = src->metric;
dst->network = src->network;
nm_assert (nm_platform_ip4_route_cmp (dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE) == 0);
});
_vt_cmd_plobj_id_copy (ip6_route, NMPlatformIP6Route, {
dst->ifindex = src->ifindex;
dst->plen = src->plen;
dst->metric = src->metric;
dst->network = src->network;
nm_assert (nm_platform_ip6_route_cmp (dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE) == 0);
});
/* Uses internally nmp_object_copy(), hence it also violates the const
@ -1091,20 +1057,9 @@ _vt_cmd_plobj_id_equal (ip6_address, NMPlatformIP6Address,
/* 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
&& obj1->plen == obj2->plen
&& obj1->metric == obj2->metric
&& nm_utils_ip4_address_clear_host_address (obj1->network, obj1->plen) == nm_utils_ip4_address_clear_host_address (obj2->network, obj2->plen));
nm_platform_ip4_route_cmp (obj1, obj2, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE) == 0);
_vt_cmd_plobj_id_equal (ip6_route, NMPlatformIP6Route,
obj1->ifindex == obj2->ifindex
&& obj1->plen == obj2->plen
&& obj1->metric == obj2->metric
&& ({
struct in6_addr n1, n2;
IN6_ARE_ADDR_EQUAL(nm_utils_ip6_address_clear_host_address (&n1, &obj1->network, obj1->plen),
nm_utils_ip6_address_clear_host_address (&n2, &obj2->network, obj2->plen));
}));
nm_platform_ip6_route_cmp (obj1, obj2, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE) == 0);
guint
nmp_object_id_hash (const NMPObject *obj)
@ -1153,22 +1108,10 @@ _vt_cmd_plobj_id_hash (ip6_address, NMPlatformIP6Address, {
hash = NM_HASH_COMBINE (hash, nm_utils_in6_addr_hash (&obj->address));
})
_vt_cmd_plobj_id_hash (ip4_route, NMPlatformIP4Route, {
hash = (guint) 2569857221u;
hash = hash + ((guint) obj->ifindex);
hash = NM_HASH_COMBINE (hash, obj->plen);
hash = NM_HASH_COMBINE (hash, obj->metric);
hash = NM_HASH_COMBINE (hash, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen));
hash = nm_platform_ip4_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE);
})
_vt_cmd_plobj_id_hash (ip6_route, NMPlatformIP6Route, {
hash = (guint) 3999787007u;
hash = hash + ((guint) obj->ifindex);
hash = NM_HASH_COMBINE (hash, obj->plen);
hash = NM_HASH_COMBINE (hash, obj->metric);
hash = NM_HASH_COMBINE (hash,
({
struct in6_addr n1;
nm_utils_in6_addr_hash (nm_utils_ip6_address_clear_host_address (&n1, &obj->network, obj->plen));
}));
hash = nm_platform_ip6_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE);
})
gboolean
@ -2355,7 +2298,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.cmd_obj_hash = _vt_cmd_obj_hash_link,
.cmd_obj_cmp = _vt_cmd_obj_cmp_link,
.cmd_obj_copy = _vt_cmd_obj_copy_link,
.cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_link,
.cmd_obj_dispose = _vt_cmd_obj_dispose_link,
.cmd_obj_is_alive = _vt_cmd_obj_is_alive_link,
.cmd_obj_is_visible = _vt_cmd_obj_is_visible_link,
@ -2379,7 +2321,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.signal_type_id = NM_PLATFORM_SIGNAL_ID_IP4_ADDRESS,
.signal_type = NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED,
.supported_cache_ids = _supported_cache_ids_ipx_address,
.cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_ip4_address,
.cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address,
.cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_address,
.cmd_plobj_id_equal = _vt_cmd_plobj_id_equal_ip4_address,
@ -2400,7 +2341,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.signal_type_id = NM_PLATFORM_SIGNAL_ID_IP6_ADDRESS,
.signal_type = NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED,
.supported_cache_ids = _supported_cache_ids_ipx_address,
.cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_ip6_address,
.cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address,
.cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_address,
.cmd_plobj_id_equal = _vt_cmd_plobj_id_equal_ip6_address,
@ -2421,15 +2361,14 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.signal_type_id = NM_PLATFORM_SIGNAL_ID_IP4_ROUTE,
.signal_type = NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED,
.supported_cache_ids = _supported_cache_ids_ipx_route,
.cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_ip4_route,
.cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route,
.cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_route,
.cmd_plobj_id_equal = _vt_cmd_plobj_id_equal_ip4_route,
.cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip4_route,
.cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip4_route,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_route_to_string,
.cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip4_route_hash,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip4_route_cmp,
.cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip4_route_hash_full,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip4_route_cmp_full,
},
[NMP_OBJECT_TYPE_IP6_ROUTE - 1] = {
.parent = DEDUP_MULTI_OBJ_CLASS_INIT(),
@ -2442,15 +2381,14 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.signal_type_id = NM_PLATFORM_SIGNAL_ID_IP6_ROUTE,
.signal_type = NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED,
.supported_cache_ids = _supported_cache_ids_ipx_route,
.cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_ip6_route,
.cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route,
.cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_route,
.cmd_plobj_id_equal = _vt_cmd_plobj_id_equal_ip6_route,
.cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip6_route,
.cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip6_route,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_route_to_string,
.cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip6_route_hash,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip6_route_cmp,
.cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip6_route_hash_full,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip6_route_cmp_full,
},
[NMP_OBJECT_TYPE_LNK_GRE - 1] = {
.parent = DEDUP_MULTI_OBJ_CLASS_INIT(),

View file

@ -118,7 +118,6 @@ typedef struct {
guint (*cmd_obj_hash) (const NMPObject *obj);
int (*cmd_obj_cmp) (const NMPObject *obj1, const NMPObject *obj2);
void (*cmd_obj_copy) (NMPObject *dst, const NMPObject *src);
void (*cmd_obj_stackinit_id) (NMPObject *obj, const NMPObject *src);
void (*cmd_obj_dispose) (NMPObject *obj);
gboolean (*cmd_obj_is_alive) (const NMPObject *obj);
gboolean (*cmd_obj_is_visible) (const NMPObject *obj);

View file

@ -903,7 +903,7 @@ void nmtstp_ip4_route_add (NMPlatform *platform,
route.metric = metric;
route.mss = mss;
g_assert (nm_platform_ip4_route_add (platform, &route));
g_assert (nm_platform_ip4_route_add (platform, NMP_NLM_FLAG_REPLACE, &route));
}
void nmtstp_ip6_route_add (NMPlatform *platform,
@ -927,7 +927,7 @@ void nmtstp_ip6_route_add (NMPlatform *platform,
route.metric = metric;
route.mss = mss;
g_assert (nm_platform_ip6_route_add (platform, &route));
g_assert (nm_platform_ip6_route_add (platform, NMP_NLM_FLAG_REPLACE, &route));
}
/*****************************************************************************/

View file

@ -69,6 +69,8 @@ ip4_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMP
{
const NMPObjectType obj_type = obj_type_i;
const NMPlatformSignalChangeType change_type = change_type_i;
NMPObject o_id;
nm_auto_nmpobj NMPObject *o_id_p = nmp_object_new (NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
g_assert_cmpint (obj_type, ==, NMP_OBJECT_TYPE_IP4_ROUTE);
g_assert (received);
@ -76,6 +78,11 @@ ip4_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMP
g_assert (data && data->name);
g_assert_cmpstr (data->name, ==, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED);
/* run code for initializing the ID only */
nmp_object_stackinit_id (&o_id, NMP_OBJECT_UP_CAST (received));
nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), TRUE);
nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), FALSE);
if (data->ifindex && data->ifindex != received->ifindex)
return;
if (data->change_type != change_type)
@ -93,6 +100,8 @@ ip6_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMP
{
const NMPObjectType obj_type = obj_type_i;
const NMPlatformSignalChangeType change_type = change_type_i;
NMPObject o_id;
nm_auto_nmpobj NMPObject *o_id_p = nmp_object_new (NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
g_assert_cmpint (obj_type, ==, NMP_OBJECT_TYPE_IP6_ROUTE);
g_assert (received);
@ -100,6 +109,11 @@ ip6_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMP
g_assert (data && data->name);
g_assert_cmpstr (data->name, ==, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED);
/* run code for initializing the ID only */
nmp_object_stackinit_id (&o_id, NMP_OBJECT_UP_CAST (received));
nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), TRUE);
nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), FALSE);
if (data->ifindex && data->ifindex != received->ifindex)
return;
if (data->change_type != change_type)
@ -418,7 +432,7 @@ test_ip4_route_options (void)
route.mtu = 1350;
route.lock_cwnd = TRUE;
g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &route));
g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &route));
/* Test route listing */
routes = nmtstp_ip4_route_get_all (NM_PLATFORM_GET, ifindex);
@ -518,7 +532,7 @@ test_ip6_route_options (gconstpointer test_data)
_wait_for_ipv6_addr_non_tentative (NM_PLATFORM_GET, 400, IFINDEX, addr_n, addr_in6);
for (i = 0; i < rts_n; i++)
g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &rts_add[i]));
g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]));
routes = nmtstp_ip6_route_get_all (NM_PLATFORM_GET, IFINDEX);
switch (TEST_IDX) {

View file

@ -467,23 +467,25 @@ parse_route_options (NMIPRoute *route, int family, const char *line, GError **er
}
/* tos */
regex = g_regex_new ("(?:\\s|^)tos\\s+(\\S+)(?:$|\\s)", 0, 0, NULL);
g_regex_match (regex, line, 0, &match_info);
if (g_match_info_matches (match_info)) {
gs_free char *str = g_match_info_fetch (match_info, 1);
gint64 num = _nm_utils_ascii_str_to_int64 (str, 0, 0, G_MAXUINT8, -1);
if (family == AF_INET) {
regex = g_regex_new ("(?:\\s|^)tos\\s+(\\S+)(?:$|\\s)", 0, 0, NULL);
g_regex_match (regex, line, 0, &match_info);
if (g_match_info_matches (match_info)) {
gs_free char *str = g_match_info_fetch (match_info, 1);
gint64 num = _nm_utils_ascii_str_to_int64 (str, 16, 0, G_MAXUINT8, -1);
if (num == -1) {
g_match_info_free (match_info);
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid route %s '%s'", "tos", str);
goto out;
if (num == -1) {
g_match_info_free (match_info);
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid route %s '%s'", "tos", str);
goto out;
}
nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_TOS,
g_variant_new_byte ((guchar) num));
}
nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_TOS,
g_variant_new_byte ((guchar) num));
g_clear_pointer (&regex, g_regex_unref);
g_clear_pointer (&match_info, g_match_info_free);
}
g_clear_pointer (&regex, g_regex_unref);
g_clear_pointer (&match_info, g_match_info_free);
/* from */
if (family == AF_INET6) {

View file

@ -1893,7 +1893,7 @@ get_route_attributes_string (NMIPRoute *route, int family)
} else if (strstr (names[i], "lock-")) {
/* handled above */
} else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_TOS)) {
g_string_append_printf (str, "%s %u", names[i], (unsigned) g_variant_get_byte (attr));
g_string_append_printf (str, "%s 0x%02x", names[i], (unsigned) g_variant_get_byte (attr));
} else if ( nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_SRC)
|| nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_FROM)) {
char *arg = nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_SRC) ? "src" : "from";

View file

@ -4108,7 +4108,6 @@ test_write_wired_static (void)
route6 = nm_ip_route_new (AF_INET6, "::", 128, "2222:aaaa::9999", 1, &error);
g_assert_no_error (error);
nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_TOS, g_variant_new_byte (0xb8));
nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32 (100));
nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32 (1280));
nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, g_variant_new_boolean (TRUE));

View file

@ -822,7 +822,7 @@ _assert_route_check (const NMPlatformVTableRoute *vtable, gboolean has, const NM
c.r6 = route->r6;
c.rx.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (c.rx.rt_source);
}
if (!r || vtable->route_cmp (r, &c, TRUE) != 0) {
if (!r || vtable->route_cmp (r, &c, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL) != 0) {
g_error ("Invalid route. Expect %s, has %s",
vtable->route_to_string (&c, NULL, 0),
vtable->route_to_string (r, buf, sizeof (buf)));
@ -857,7 +857,7 @@ test_ip4_full_sync (test_fixture *fixture, gconstpointer user_data)
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r02);
_assert_route_check (vtable, FALSE, (const NMPlatformIPXRoute *) &r03);
vtable->route_add (NM_PLATFORM_GET, 0, (const NMPlatformIPXRoute *) &r03, -1);
vtable->route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, (const NMPlatformIPXRoute *) &r03, 0, -1);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r01);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r02);