From e3276ba6febd970899a536db2dde82256cdf1f94 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 19:47:44 +0200 Subject: [PATCH 01/31] core/utils: add NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER() switch case NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT() is useful because unless compiled with NM_MORE_ASSERTS, there is no assertion. An assertion includes the function name, and can make the function ineligible for inlining. (cherry picked from commit fbfe2ef216a09fb76be85c4bfd667b8392da5d0e) --- src/nm-core-utils.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index f77b43e2a3..22d92d6535 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -220,11 +220,13 @@ fcn_name (lookup_type val, char *buf, gsize len) \ /*****************************************************************************/ -#define NM_UTILS_LOOKUP_DEFAULT(v) return (v) -#define NM_UTILS_LOOKUP_DEFAULT_WARN(v) g_return_val_if_reached (v) -#define NM_UTILS_LOOKUP_ITEM(v, n) (void) 0; case v: return (n); (void) 0 -#define NM_UTILS_LOOKUP_STR_ITEM(v, n) NM_UTILS_LOOKUP_ITEM(v, ""n"") -#define NM_UTILS_LOOKUP_ITEM_IGNORE(v) (void) 0; case v: break; (void) 0 +#define NM_UTILS_LOOKUP_DEFAULT(v) return (v) +#define NM_UTILS_LOOKUP_DEFAULT_WARN(v) g_return_val_if_reached (v) +#define NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT(v) { nm_assert_not_reached (); return (v); } +#define NM_UTILS_LOOKUP_ITEM(v, n) (void) 0; case v: return (n); (void) 0 +#define NM_UTILS_LOOKUP_STR_ITEM(v, n) NM_UTILS_LOOKUP_ITEM(v, ""n"") +#define NM_UTILS_LOOKUP_ITEM_IGNORE(v) (void) 0; case v: break; (void) 0 +#define NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER() (void) 0; default: break; (void) 0 #define _NM_UTILS_LOOKUP_DEFINE(scope, fcn_name, lookup_type, result_type, unknown_val, ...) \ scope result_type \ From 6451e9ce731bd0009126bff528ed86854e0ebac4 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 16:53:02 +0200 Subject: [PATCH 02/31] nmtst: add nmtst_rand_buf() util (cherry picked from commit 0e78ce5ed6ef20fc54623d601cc3d0c3fea67d05) --- shared/nm-test-utils.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/shared/nm-test-utils.h b/shared/nm-test-utils.h index 2503245761..8e21186dda 100644 --- a/shared/nm-test-utils.h +++ b/shared/nm-test-utils.h @@ -782,6 +782,34 @@ nmtst_get_rand_int (void) return g_rand_int (nmtst_get_rand ()); } +inline static gpointer +nmtst_rand_buf (GRand *rand, gpointer buffer, gsize buffer_length) +{ + guint32 v; + guint8 *b = buffer; + + if (!buffer_length) + return buffer; + + g_assert (buffer); + + if (!rand) + rand = nmtst_get_rand (); + + for (; buffer_length >= sizeof (guint32); buffer_length -= sizeof (guint32), b += sizeof (guint32)) { + v = g_rand_int (rand); + memcpy (b, &v, sizeof (guint32)); + } + if (buffer_length > 0) { + v = g_rand_int (rand); + do { + *(b++) = v & 0xFF; + v >>= 8; + } while (--buffer_length > 0); + } + return buffer; +} + inline static void * nmtst_rand_perm (GRand *rand, void *dst, const void *src, gsize elmt_size, gsize n_elmt) { From 71cd1935d971769e7a4567a2adb6731f0c6be3bc Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 15:33:53 +0200 Subject: [PATCH 03/31] nmtst: add nmtst_platform_ip4_address() util (cherry picked from commit 2e6ec6d8ac8a4ec0ee51a03b8bd1118a72f0f59b) --- shared/nm-test-utils.h | 47 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/shared/nm-test-utils.h b/shared/nm-test-utils.h index 8e21186dda..b792a69c85 100644 --- a/shared/nm-test-utils.h +++ b/shared/nm-test-utils.h @@ -1179,11 +1179,54 @@ _nmtst_assert_resolve_relative_path_equals (const char *f1, const char *f2, cons #ifdef __NETWORKMANAGER_PLATFORM_H__ +inline static NMPlatformIP4Address * +nmtst_platform_ip4_address (const char *address, const char *peer_address, guint plen) +{ + static NMPlatformIP4Address addr; + + g_assert (plen <= 32); + + memset (&addr, 0, sizeof (addr)); + addr.address = nmtst_inet4_from_string (address); + if (peer_address) + addr.peer_address = nmtst_inet4_from_string (peer_address); + else + addr.peer_address = addr.address; + addr.plen = plen; + + return &addr; +} + +inline static NMPlatformIP4Address * +nmtst_platform_ip4_address_full (const char *address, const char *peer_address, guint plen, + int ifindex, NMIPConfigSource source, guint32 timestamp, + guint32 lifetime, guint32 preferred, guint32 flags, + const char *label) +{ + NMPlatformIP4Address *addr = nmtst_platform_ip4_address (address, peer_address, plen); + + G_STATIC_ASSERT (IFNAMSIZ == sizeof (addr->label)); + g_assert (!label || strlen (label) < IFNAMSIZ); + + addr->ifindex = ifindex; + addr->source = source; + addr->timestamp = timestamp; + addr->lifetime = lifetime; + addr->preferred = preferred; + addr->n_ifa_flags = flags; + if (label) + g_strlcpy (addr->label, label, sizeof (addr->label)); + + return addr; +} + inline static NMPlatformIP6Address * nmtst_platform_ip6_address (const char *address, const char *peer_address, guint plen) { static NMPlatformIP6Address addr; + g_assert (plen <= 128); + memset (&addr, 0, sizeof (addr)); addr.address = *nmtst_inet6_from_string (address); addr.peer_address = *nmtst_inet6_from_string (peer_address); @@ -1214,6 +1257,8 @@ nmtst_platform_ip4_route (const char *network, guint plen, const char *gateway) { static NMPlatformIP4Route route; + g_assert (plen <= 32); + memset (&route, 0, sizeof (route)); route.network = nmtst_inet4_from_string (network); route.plen = plen; @@ -1246,6 +1291,8 @@ nmtst_platform_ip6_route (const char *network, guint plen, const char *gateway) { static NMPlatformIP6Route route; + nm_assert (plen <= 128); + memset (&route, 0, sizeof (route)); route.network = *nmtst_inet6_from_string (network); route.plen = plen; From 3e5a6893c8192a80efe4829146929a64d499c57c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 15:44:55 +0200 Subject: [PATCH 04/31] ip-config/tests: refactor tests to use utilities from "nm-test-utils.h" (cherry picked from commit b3daf156de2fc27e545e11ff36e4d93a25c3e145) --- src/tests/test-ip4-config.c | 88 +++++++++++-------------------------- 1 file changed, 25 insertions(+), 63 deletions(-) diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c index 2b743c8c3c..9d38dc27b7 100644 --- a/src/tests/test-ip4-config.c +++ b/src/tests/test-ip4-config.c @@ -28,44 +28,6 @@ #include "nm-test-utils.h" -static void -addr_init (NMPlatformIP4Address *a, const char *addr, const char *peer, guint plen) -{ - memset (a, 0, sizeof (*a)); - g_assert (inet_pton (AF_INET, addr, (void *) &a->address) == 1); - if (peer) - g_assert (inet_pton (AF_INET, peer, (void *) &a->peer_address) == 1); - else - a->peer_address = a->address; - a->plen = plen; -} - -static void -route_new (NMPlatformIP4Route *route, const char *network, guint plen, const char *gw) -{ - guint n; - - g_assert (route); - memset (route, 0, sizeof (*route)); - g_assert (inet_pton (AF_INET, network, (void *) &n) == 1); - route->network = n; - route->plen = plen; - if (gw) { - n = 0; - g_assert (inet_pton (AF_INET, gw, (void *) &n) == 1); - route->gateway = n; - } -} - -static guint32 -addr_to_num (const char *addr) -{ - guint n; - - g_assert (inet_pton (AF_INET, addr, (void *) &n) == 1); - return n; -} - static NMIP4Config * build_test_config (void) { @@ -76,29 +38,29 @@ build_test_config (void) /* Build up the config to subtract */ config = nm_ip4_config_new (1); - addr_init (&addr, "192.168.1.10", "1.2.3.4", 24); + addr = *nmtst_platform_ip4_address ("192.168.1.10", "1.2.3.4", 24); nm_ip4_config_add_address (config, &addr); - - route_new (&route, "10.0.0.0", 8, "192.168.1.1"); + + route = *nmtst_platform_ip4_route ("10.0.0.0", 8, "192.168.1.1"); nm_ip4_config_add_route (config, &route); - route_new (&route, "172.16.0.0", 16, "192.168.1.1"); + route = *nmtst_platform_ip4_route ("172.16.0.0", 16, "192.168.1.1"); nm_ip4_config_add_route (config, &route); - nm_ip4_config_set_gateway (config, addr_to_num ("192.168.1.1")); + nm_ip4_config_set_gateway (config, nmtst_inet4_from_string ("192.168.1.1")); - nm_ip4_config_add_nameserver (config, addr_to_num ("4.2.2.1")); - nm_ip4_config_add_nameserver (config, addr_to_num ("4.2.2.2")); + nm_ip4_config_add_nameserver (config, nmtst_inet4_from_string ("4.2.2.1")); + nm_ip4_config_add_nameserver (config, nmtst_inet4_from_string ("4.2.2.2")); nm_ip4_config_add_domain (config, "foobar.com"); nm_ip4_config_add_domain (config, "baz.com"); nm_ip4_config_add_search (config, "blahblah.com"); nm_ip4_config_add_search (config, "beatbox.com"); - nm_ip4_config_add_nis_server (config, addr_to_num ("1.2.3.9")); - nm_ip4_config_add_nis_server (config, addr_to_num ("1.2.3.10")); + nm_ip4_config_add_nis_server (config, nmtst_inet4_from_string ("1.2.3.9")); + nm_ip4_config_add_nis_server (config, nmtst_inet4_from_string ("1.2.3.10")); - nm_ip4_config_add_wins (config, addr_to_num ("4.2.3.9")); - nm_ip4_config_add_wins (config, addr_to_num ("4.2.3.10")); + nm_ip4_config_add_wins (config, nmtst_inet4_from_string ("4.2.3.9")); + nm_ip4_config_add_wins (config, nmtst_inet4_from_string ("4.2.3.10")); return config; } @@ -116,12 +78,12 @@ test_subtract (void) const char *expected_route_dest = "8.7.6.5"; guint32 expected_route_plen = 8; const char *expected_route_next_hop = "192.168.1.1"; - guint32 expected_ns1 = addr_to_num ("8.8.8.8"); - guint32 expected_ns2 = addr_to_num ("8.8.8.9"); + guint32 expected_ns1 = nmtst_inet4_from_string ("8.8.8.8"); + guint32 expected_ns2 = nmtst_inet4_from_string ("8.8.8.9"); const char *expected_domain = "wonderfalls.com"; const char *expected_search = "somewhere.com"; - guint32 expected_nis = addr_to_num ("1.2.3.13"); - guint32 expected_wins = addr_to_num ("2.3.4.5"); + guint32 expected_nis = nmtst_inet4_from_string ("1.2.3.13"); + guint32 expected_wins = nmtst_inet4_from_string ("2.3.4.5"); guint32 expected_mss = 1400; guint32 expected_mtu = 1492; @@ -129,10 +91,10 @@ test_subtract (void) /* add a couple more things to the test config */ dst = build_test_config (); - addr_init (&addr, expected_addr, NULL, expected_addr_plen); + addr = *nmtst_platform_ip4_address (expected_addr, NULL, expected_addr_plen); nm_ip4_config_add_address (dst, &addr); - - route_new (&route, expected_route_dest, expected_route_plen, expected_route_next_hop); + + route = *nmtst_platform_ip4_route (expected_route_dest, expected_route_plen, expected_route_next_hop); nm_ip4_config_add_route (dst, &route); nm_ip4_config_add_nameserver (dst, expected_ns1); @@ -152,7 +114,7 @@ test_subtract (void) g_assert_cmpuint (nm_ip4_config_get_num_addresses (dst), ==, 1); test_addr = nm_ip4_config_get_address (dst, 0); g_assert (test_addr != NULL); - g_assert_cmpuint (test_addr->address, ==, addr_to_num (expected_addr)); + g_assert_cmpuint (test_addr->address, ==, nmtst_inet4_from_string (expected_addr)); g_assert_cmpuint (test_addr->peer_address, ==, test_addr->address); g_assert_cmpuint (test_addr->plen, ==, expected_addr_plen); @@ -161,9 +123,9 @@ test_subtract (void) g_assert_cmpuint (nm_ip4_config_get_num_routes (dst), ==, 1); test_route = nm_ip4_config_get_route (dst, 0); g_assert (test_route != NULL); - g_assert_cmpuint (test_route->network, ==, addr_to_num (expected_route_dest)); + g_assert_cmpuint (test_route->network, ==, nmtst_inet4_from_string (expected_route_dest)); g_assert_cmpuint (test_route->plen, ==, expected_route_plen); - g_assert_cmpuint (test_route->gateway, ==, addr_to_num (expected_route_next_hop)); + g_assert_cmpuint (test_route->gateway, ==, nmtst_inet4_from_string (expected_route_next_hop)); g_assert_cmpuint (nm_ip4_config_get_num_nameservers (dst), ==, 2); g_assert_cmpuint (nm_ip4_config_get_nameserver (dst, 0), ==, expected_ns1); @@ -198,7 +160,7 @@ test_compare_with_source (void) b = nm_ip4_config_new (2); /* Address */ - addr_init (&addr, "1.2.3.4", NULL, 24); + addr = *nmtst_platform_ip4_address ("1.2.3.4", NULL, 24); addr.source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_address (a, &addr); @@ -206,7 +168,7 @@ test_compare_with_source (void) nm_ip4_config_add_address (b, &addr); /* Route */ - route_new (&route, "10.0.0.0", 8, "192.168.1.1"); + route = *nmtst_platform_ip4_route ("10.0.0.0", 8, "192.168.1.1"); route.source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_route (a, &route); @@ -230,7 +192,7 @@ test_add_address_with_source (void) a = nm_ip4_config_new (1); /* Test that a higher priority source is not overwritten */ - addr_init (&addr, "1.2.3.4", NULL, 24); + addr = *nmtst_platform_ip4_address ("1.2.3.4", NULL, 24); addr.source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_address (a, &addr); @@ -270,7 +232,7 @@ test_add_route_with_source (void) a = nm_ip4_config_new (1); /* Test that a higher priority source is not overwritten */ - route_new (&route, "1.2.3.4", 24, "1.2.3.1"); + route = *nmtst_platform_ip4_route ("1.2.3.4", 24, "1.2.3.1"); route.source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_route (a, &route); From ba5d2103fe8f1d480ea6ae835879608cb78bd1c0 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 18:12:33 +0200 Subject: [PATCH 05/31] dnsmasq/tests: make use of nmtst util to initialize NMPlatformIP4Address (cherry picked from commit a18fca36a5306d68a749e9680394169ce3af6caa) --- .../tests/test-dnsmasq-utils.c | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/dnsmasq-manager/tests/test-dnsmasq-utils.c b/src/dnsmasq-manager/tests/test-dnsmasq-utils.c index 850ae4f6fb..aeec5879a1 100644 --- a/src/dnsmasq-manager/tests/test-dnsmasq-utils.c +++ b/src/dnsmasq-manager/tests/test-dnsmasq-utils.c @@ -26,14 +26,6 @@ #include "nm-test-utils.h" -static NMPlatformIP4Address * -_set_addr (NMPlatformIP4Address *addr, const char *address, int plen) -{ - memset (addr, 0, sizeof (*addr)); - nm_platform_ip4_address_set_addr (addr, nmtst_inet4_from_string (address), plen); - return addr; -} - static void test_address_ranges (void) { @@ -42,50 +34,50 @@ test_address_ranges (void) char last[INET_ADDRSTRLEN]; char *error_desc = NULL; - _set_addr (&addr, "192.168.0.1", 24); + addr = *nmtst_platform_ip4_address ("192.168.0.1", NULL, 24); g_assert (nm_dnsmasq_utils_get_range (&addr, first, last, &error_desc)); g_assert (error_desc == NULL); g_assert_cmpstr (first, ==, "192.168.0.10"); g_assert_cmpstr (last, ==, "192.168.0.254"); - _set_addr (&addr, "192.168.0.99", 24); + addr = *nmtst_platform_ip4_address ("192.168.0.99", NULL, 24); g_assert (nm_dnsmasq_utils_get_range (&addr, first, last, &error_desc)); g_assert (error_desc == NULL); g_assert_cmpstr (first, ==, "192.168.0.108"); g_assert_cmpstr (last, ==, "192.168.0.254"); - _set_addr (&addr, "192.168.0.254", 24); + addr = *nmtst_platform_ip4_address ("192.168.0.254", NULL, 24); g_assert (nm_dnsmasq_utils_get_range (&addr, first, last, &error_desc)); g_assert (error_desc == NULL); g_assert_cmpstr (first, ==, "192.168.0.1"); g_assert_cmpstr (last, ==, "192.168.0.245"); /* Smaller networks */ - _set_addr (&addr, "1.2.3.1", 30); + addr = *nmtst_platform_ip4_address ("1.2.3.1", NULL, 30); g_assert (nm_dnsmasq_utils_get_range (&addr, first, last, &error_desc)); g_assert (error_desc == NULL); g_assert_cmpstr (first, ==, "1.2.3.2"); g_assert_cmpstr (last, ==, "1.2.3.2"); - _set_addr (&addr, "1.2.3.1", 29); + addr = *nmtst_platform_ip4_address ("1.2.3.1", NULL, 29); g_assert (nm_dnsmasq_utils_get_range (&addr, first, last, &error_desc)); g_assert (error_desc == NULL); g_assert_cmpstr (first, ==, "1.2.3.2"); g_assert_cmpstr (last, ==, "1.2.3.6"); - _set_addr (&addr, "1.2.3.1", 28); + addr = *nmtst_platform_ip4_address ("1.2.3.1", NULL, 28); g_assert (nm_dnsmasq_utils_get_range (&addr, first, last, &error_desc)); g_assert (error_desc == NULL); g_assert_cmpstr (first, ==, "1.2.3.3"); g_assert_cmpstr (last, ==, "1.2.3.14"); - _set_addr (&addr, "1.2.3.1", 26); + addr = *nmtst_platform_ip4_address ("1.2.3.1", NULL, 26); g_assert (nm_dnsmasq_utils_get_range (&addr, first, last, &error_desc)); g_assert (error_desc == NULL); g_assert_cmpstr (first, ==, "1.2.3.8"); g_assert_cmpstr (last, ==, "1.2.3.62"); - _set_addr (&addr, "1.2.3.1", 31); + addr = *nmtst_platform_ip4_address ("1.2.3.1", NULL, 31); g_assert (nm_dnsmasq_utils_get_range (&addr, first, last, &error_desc) == FALSE); g_assert (error_desc); g_free (error_desc); From 52175860852aab90263dd85b59a8efd8de01053c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 17:33:19 +0200 Subject: [PATCH 06/31] core: add nm_utils_ip6_address_same_prefix() util (cherry picked from commit db3175d9c086b97a4f47facbc6fda7723c16ca94) --- src/nm-core-utils.c | 27 ++++++++- src/nm-core-utils.h | 1 + src/tests/test-general.c | 117 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 1 deletion(-) diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 6cdd00e0d7..714aaa9279 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -233,7 +233,6 @@ nm_ethernet_address_is_valid (gconstpointer addr, gssize len) return TRUE; } - /* nm_utils_ip4_address_clear_host_address: * @addr: source ip6 address * @plen: prefix length of network @@ -279,6 +278,32 @@ 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 nbytes; + guint8 t, m; + + if (plen >= 128) + return memcmp (addr_a, addr_b, sizeof (struct in6_addr)) == 0; + + nbytes = plen / 8; + if (nbytes) { + if (memcmp (addr_a, addr_b, nbytes) != 0) + return FALSE; + } + + 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; +} + +/*****************************************************************************/ + void nm_utils_array_remove_at_indexes (GArray *array, const guint *indexes_to_delete, gsize len) { diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 22d92d6535..280be04736 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -100,6 +100,7 @@ gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len); 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); /** * nm_utils_ip6_route_metric_normalize: diff --git a/src/tests/test-general.c b/src/tests/test-general.c index b25125904b..a45357e810 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -98,6 +98,122 @@ test_nm_utils_ip6_address_clear_host_address (void) g_rand_free (r); } +/*****************************************************************************/ + +static void +_test_same_prefix (const char *a1, const char *a2, guint8 plen) +{ + struct in6_addr a = *nmtst_inet6_from_string (a1); + struct in6_addr b = *nmtst_inet6_from_string (a2); + + g_assert (nm_utils_ip6_address_same_prefix (&a, &b, plen)); +} + +static void +test_nm_utils_ip6_address_same_prefix (void) +{ + guint n, i; + const guint N = 100; + union { + guint8 ptr[sizeof (struct in6_addr)]; + struct in6_addr val; + } a, b, addrmask, addrmask_bit; + guint8 plen; + + /* test#1 */ + for (n = 0; n < N; n++) { + gboolean is_same = n < N / 2; + gboolean result; + + nmtst_rand_buf (NULL, a.ptr, sizeof (a)); + nmtst_rand_buf (NULL, b.ptr, sizeof (b)); +again_plen: + plen = nmtst_get_rand_int () % 129; + if (!is_same && NM_IN_SET (plen, 0, 128)) + goto again_plen; + + if (plen < 128) { + for (i = 0; (i + 1) * 8 <= plen; i++) + b.ptr[i] = a.ptr[i]; + if (plen % 8) { + guint8 mask; + + g_assert (i < sizeof (a)); + mask = ~((1 << (8 - (plen % 8))) - 1); + b.ptr[i] = (a.ptr[i] & mask) | (b.ptr[i] & ~mask); + if (!is_same) { + mask = (1 << (8 - (plen % 8))); + b.ptr[i] = (b.ptr[i] & ~mask) | ~(b.ptr[i] & mask); + } + } else if (!is_same) { + g_assert (i > 0); + + b.ptr[i - 1] = (b.ptr[i - 1] & ~0x1) | ~(b.ptr[i - 1] & 0x1); + } + } else + b = a; + + result = nm_utils_ip6_address_same_prefix (&a.val, &b.val, plen); + g_assert (result == is_same); + g_assert (NM_IN_SET (result, TRUE, FALSE)); + } + + /* test#2 */ + for (n = 0; n < N; n++) { + nmtst_rand_buf (NULL, a.ptr, sizeof (a)); + nmtst_rand_buf (NULL, b.ptr, sizeof (b)); + plen = nmtst_get_rand_int () % 129; + + memset (addrmask.ptr, 0xFF, sizeof (addrmask)); + nm_utils_ip6_address_clear_host_address (&addrmask.val, &addrmask.val, plen); + + for (i = 0; i < sizeof (a); i++) + b.ptr[i] = (a.ptr[i] & addrmask.ptr[i]) | (b.ptr[i] & ~addrmask.ptr[i]); + + g_assert (nm_utils_ip6_address_same_prefix (&a.val, &b.val, plen) == TRUE); + } + + /* test#3 */ + for (n = 0; n < N; n++) { + gboolean reached = FALSE; + + nmtst_rand_buf (NULL, a.ptr, sizeof (a)); + nmtst_rand_buf (NULL, b.ptr, sizeof (b)); + plen = nmtst_get_rand_int () % 129; + + if (!plen) + continue; + + memset (addrmask.ptr, 0xFF, sizeof (addrmask)); + nm_utils_ip6_address_clear_host_address (&addrmask.val, &addrmask.val, plen); + + memset (addrmask_bit.ptr, 0xFF, sizeof (addrmask_bit)); + nm_utils_ip6_address_clear_host_address (&addrmask_bit.val, &addrmask_bit.val, plen - 1); + + for (i = 0; i < sizeof (a); i++) + b.ptr[i] = (a.ptr[i] & addrmask.ptr[i]) | (b.ptr[i] & ~addrmask.ptr[i]); + + /* flip the last bit. */ + for (i = 0; i < sizeof (a); i++) { + guint8 mask = addrmask.ptr[i] ^ addrmask_bit.ptr[i]; + if (mask) { + g_assert (!reached); + g_assert (nm_utils_is_power_of_two (mask)); + reached = TRUE; + b.ptr[i] = (b.ptr[i] & ~mask) | ~(b.ptr[i] & mask); + } + } + g_assert (reached); + + g_assert (nm_utils_ip6_address_same_prefix (&a.val, &b.val, plen) == FALSE); + } + + /* test#4 */ + _test_same_prefix ("::", "::1", 10); + _test_same_prefix ("abcd::", "abcd::1", 10); +} + +/*****************************************************************************/ static void test_nm_utils_log_connection_diff (void) @@ -1257,6 +1373,7 @@ main (int argc, char **argv) g_test_add_func ("/general/nm_utils_strbuf_append", test_nm_utils_strbuf_append); g_test_add_func ("/general/nm_utils_ip6_address_clear_host_address", test_nm_utils_ip6_address_clear_host_address); + g_test_add_func ("/general/nm_utils_ip6_address_same_prefix", test_nm_utils_ip6_address_same_prefix); g_test_add_func ("/general/nm_utils_log_connection_diff", test_nm_utils_log_connection_diff); g_test_add_func ("/general/connection-match/basic", test_connection_match_basic); From a0b561eda395810c792bb224db35b908a400af03 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 15:53:54 +0200 Subject: [PATCH 07/31] ip6-config: use nm_utils_ip6_address_same_prefix(). Instead of same_prefix() in nm_ip6_config_destination_is_direct(), use nm_utils_ip6_address_same_prefix(). (cherry picked from commit 966fcdba1bcb56a663373bbfc5c7ac6ee7157275) --- src/nm-ip6-config.c | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 6d83bd53a3..102aeab5fa 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -95,24 +95,6 @@ nm_ip6_config_get_ifindex (const NMIP6Config *config) /******************************************************************/ -static gboolean -same_prefix (const struct in6_addr *address1, const struct in6_addr *address2, int plen) -{ - const guint8 *bytes1 = (const guint8 *) address1; - const guint8 *bytes2 = (const guint8 *) address2; - int nbytes = plen / 8; - int nbits = plen % 8; - int masked1 = bytes1[nbytes] >> (8 - nbits); - int masked2 = bytes2[nbytes] >> (8 - nbits); - - if (nbytes && memcmp (bytes1, bytes2, nbytes)) - return FALSE; - - return masked1 == masked2; -} - -/******************************************************************/ - /** * nm_ip6_config_capture_resolv_conf(): * @nameservers: array of struct in6_addr @@ -713,11 +695,15 @@ nm_ip6_config_destination_is_direct (const NMIP6Config *config, const struct in6 int num = nm_ip6_config_get_num_addresses (config); int i; + nm_assert (network); + nm_assert (plen <= 128); + for (i = 0; i < num; i++) { const NMPlatformIP6Address *item = nm_ip6_config_get_address (config, i); - if (item->plen <= plen && same_prefix (&item->address, network, item->plen) && - !(item->n_ifa_flags & IFA_F_NOPREFIXROUTE)) + if ( item->plen <= plen + && !NM_FLAGS_HAS (item->n_ifa_flags, IFA_F_NOPREFIXROUTE) + && nm_utils_ip6_address_same_prefix (&item->address, network, item->plen)) return TRUE; } @@ -1473,7 +1459,6 @@ nm_ip6_config_get_direct_route_for_host (const NMIP6Config *config, const struct { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); guint i; - struct in6_addr network2, host2; NMPlatformIP6Route *best_route = NULL; g_return_val_if_fail (host && !IN6_IS_ADDR_UNSPECIFIED (host), NULL); @@ -1487,10 +1472,7 @@ nm_ip6_config_get_direct_route_for_host (const NMIP6Config *config, const struct if (best_route && best_route->plen > item->plen) continue; - nm_utils_ip6_address_clear_host_address (&host2, host, item->plen); - nm_utils_ip6_address_clear_host_address (&network2, &item->network, item->plen); - - if (!IN6_ARE_ADDR_EQUAL (&network2, &host2)) + if (!nm_utils_ip6_address_same_prefix (host, &item->network, item->plen)) continue; if (best_route && From 98766a96f2c5fb8b1395c61b4dce2b5cbb4192a5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 10:16:06 +0200 Subject: [PATCH 08/31] shared: add _nm_packed macro for __attribute__((packed)) (cherry picked from commit 9a1e0b97dab494a419a88960aba09f1c3ccd8b50) --- shared/nm-macros-internal.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shared/nm-macros-internal.h b/shared/nm-macros-internal.h index 4176231800..384bca66fe 100644 --- a/shared/nm-macros-internal.h +++ b/shared/nm-macros-internal.h @@ -26,7 +26,9 @@ /********************************************************/ -#define nm_auto(fcn) __attribute ((cleanup(fcn))) +#define _nm_packed __attribute__ ((packed)) + +#define nm_auto(fcn) __attribute__ ((cleanup(fcn))) /** * nm_auto_free: From 72f36d1b5acabbcb35772b4e5b4c0ca0901450cd Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 5 Apr 2016 18:59:38 +0200 Subject: [PATCH 09/31] nmp-object: refactor initializing NMPCacheId As we get more NMPCacheIdType values, it's better to have for each type a pre-declared list of supported types, instead of iterating over all types and letting _nmp_object_init_cache_id() figure out that the cache-id-type is unsupported on that object. (cherry picked from commit fe78ae0b6a62b8f8a7c5cc74a8e0eb447ac84125) --- src/platform/nmp-object.c | 50 +++++++++++++++++++++++++++++++-------- src/platform/nmp-object.h | 4 ++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index adeb3aabe3..4148bd4fb4 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -1100,6 +1100,13 @@ _nmp_object_init_cache_id (const NMPObject *obj, NMPCacheIdType id_type, NMPCach } } +static const guint8 _supported_cache_ids_link[] = { + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_TYPE_VISIBLE_ONLY, + NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, + 0, +}; + static gboolean _vt_cmd_obj_init_cache_id_link (const NMPObject *obj, NMPCacheIdType id_type, NMPCacheId *id, const NMPCacheId **out_id) { @@ -1117,6 +1124,13 @@ _vt_cmd_obj_init_cache_id_link (const NMPObject *obj, NMPCacheIdType id_type, NM return TRUE; } +static const guint8 _supported_cache_ids_ipx_address[] = { + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_TYPE_VISIBLE_ONLY, + NMP_CACHE_ID_TYPE_ADDRROUTE_VISIBLE_BY_IFINDEX, + 0, +}; + static gboolean _vt_cmd_obj_init_cache_id_ipx_address (const NMPObject *obj, NMPCacheIdType id_type, NMPCacheId *id, const NMPCacheId **out_id) { @@ -1135,6 +1149,17 @@ _vt_cmd_obj_init_cache_id_ipx_address (const NMPObject *obj, NMPCacheIdType id_t return TRUE; } +static const guint8 _supported_cache_ids_ipx_route[] = { + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_TYPE_VISIBLE_ONLY, + NMP_CACHE_ID_TYPE_ADDRROUTE_VISIBLE_BY_IFINDEX, + NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_NO_DEFAULT, + NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_ONLY_DEFAULT, + NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_NO_DEFAULT, + NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_ONLY_DEFAULT, + 0, +}; + static gboolean _vt_cmd_obj_init_cache_id_ipx_route (const NMPObject *obj, NMPCacheIdType id_type, NMPCacheId *id, const NMPCacheId **out_id) { @@ -1425,13 +1450,13 @@ nmp_cache_lookup_all_to_hash (const NMPCache *cache, static void _nmp_cache_update_cache (NMPCache *cache, NMPObject *obj, gboolean remove) { - NMPCacheIdType id_type; + const guint8 *id_type; - for (id_type = 0; id_type <= NMP_CACHE_ID_TYPE_MAX; id_type++) { + for (id_type = NMP_OBJECT_GET_CLASS (obj)->supported_cache_ids; *id_type; id_type++) { NMPCacheId cache_id_storage; const NMPCacheId *cache_id; - if (!_nmp_object_init_cache_id (obj, id_type, &cache_id_storage, &cache_id)) + if (!_nmp_object_init_cache_id (obj, *id_type, &cache_id_storage, &cache_id)) continue; if (!cache_id) continue; @@ -1480,19 +1505,19 @@ _nmp_cache_update_remove (NMPCache *cache, NMPObject *obj) static void _nmp_cache_update_update (NMPCache *cache, NMPObject *obj, const NMPObject *new) { - NMPCacheIdType id_type; + const guint8 *id_type; nm_assert (NMP_OBJECT_GET_CLASS (obj) == NMP_OBJECT_GET_CLASS (new)); nm_assert (obj->is_cached); nm_assert (!new->is_cached); - for (id_type = 0; id_type <= NMP_CACHE_ID_TYPE_MAX; id_type++) { + for (id_type = NMP_OBJECT_GET_CLASS (obj)->supported_cache_ids; *id_type; id_type++) { NMPCacheId cache_id_storage_obj, cache_id_storage_new; const NMPCacheId *cache_id_obj, *cache_id_new; - if (!_nmp_object_init_cache_id (obj, id_type, &cache_id_storage_obj, &cache_id_obj)) + if (!_nmp_object_init_cache_id (obj, *id_type, &cache_id_storage_obj, &cache_id_obj)) continue; - if (!_nmp_object_init_cache_id (new, id_type, &cache_id_storage_new, &cache_id_new)) + if (!_nmp_object_init_cache_id (new, *id_type, &cache_id_storage_new, &cache_id_new)) g_assert_not_reached (); if (!nm_multi_index_move (cache->idx_multi, (NMMultiIndexId *) cache_id_obj, (NMMultiIndexId *) cache_id_new, &obj->object)) g_assert_not_reached (); @@ -1891,13 +1916,13 @@ ASSERT_nmp_cache_is_consistent (const NMPCache *cache) g_hash_table_iter_init (&iter_hash, cache->idx_main); while (g_hash_table_iter_next (&iter_hash, (gpointer *) &obj, NULL)) { - NMPCacheIdType id_type; + const guint8 *id_type; g_assert (NMP_OBJECT_IS_VALID (obj)); g_assert (nmp_object_is_alive (obj)); - for (id_type = 0; id_type <= NMP_CACHE_ID_TYPE_MAX; id_type++) { - if (!_nmp_object_init_cache_id (obj, id_type, &cache_id_storage, &cache_id)) + for (id_type = NMP_OBJECT_GET_CLASS (obj)->supported_cache_ids; *id_type; id_type++) { + if (!_nmp_object_init_cache_id (obj, *id_type, &cache_id_storage, &cache_id)) continue; if (!cache_id) continue; @@ -1943,6 +1968,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .rtm_gettype = RTM_GETLINK, .signal_type_id = NM_PLATFORM_SIGNAL_ID_LINK, .signal_type = NM_PLATFORM_SIGNAL_LINK_CHANGED, + .supported_cache_ids = _supported_cache_ids_link, .cmd_obj_init_cache_id = _vt_cmd_obj_init_cache_id_link, .cmd_obj_cmp = _vt_cmd_obj_cmp_link, .cmd_obj_copy = _vt_cmd_obj_copy_link, @@ -1967,6 +1993,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .rtm_gettype = RTM_GETADDR, .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_init_cache_id = _vt_cmd_obj_init_cache_id_ipx_address, .cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_ip4_address, .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address, @@ -1986,6 +2013,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .rtm_gettype = RTM_GETADDR, .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_init_cache_id = _vt_cmd_obj_init_cache_id_ipx_address, .cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_ip6_address, .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address, @@ -2005,6 +2033,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .rtm_gettype = RTM_GETROUTE, .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_init_cache_id = _vt_cmd_obj_init_cache_id_ipx_route, .cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_ip4_route, .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, @@ -2024,6 +2053,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .rtm_gettype = RTM_GETROUTE, .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_init_cache_id = _vt_cmd_obj_init_cache_id_ipx_route, .cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_ip6_route, .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 6d5b9627ce..bdea0a3703 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -57,6 +57,8 @@ typedef enum { /*< skip >*/ * matching v4/v6 and ifindex -- or maybe not at all if it isn't visible. * */ typedef enum { /*< skip >*/ + NMP_CACHE_ID_TYPE_NONE, + /* all the objects of a certain type */ NMP_CACHE_ID_TYPE_OBJECT_TYPE, @@ -124,6 +126,8 @@ typedef struct { const char *obj_type_name; const char *signal_type; + const guint8 *supported_cache_ids; + /* Only for NMPObjectLnk* types. */ NMLinkType lnk_link_type; From 395a09cfc7be6fa3450ca6673c8a1bf278a3f8ee Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 11:03:05 +0200 Subject: [PATCH 10/31] nmp-object: refactor handling of NMPCacheId to consider only relevant part of union NMPCacheId is a union with fields for all known NMPCacheIdTypes. Up to now, we always cloned the entire union, computed the hash over all (possibly unset) fields and used memcmp() unanimously. That was ok, because NMPCacheId was 16 bytes in total and cache-id types that consumed less bytes didn't have a large overhead. Next, we will add a new cache id type which increases the size of NMPCacheId to 24 bytes. So, while possibly only a fraction of the instances is that large, they would all have to pay that price. Change that to consider and clone only those parts of the id that are actually used. (cherry picked from commit b1e3deaf2fbc845324b663ba385b5b01339bf77e) --- src/platform/nmp-object.c | 65 +++++++++++++++++++++++++++++---------- src/platform/nmp-object.h | 9 +++--- 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 4148bd4fb4..740ed8d102 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -952,26 +952,44 @@ _vt_cmd_obj_is_visible_link (const NMPObject *obj) /******************************************************************/ +#define _STRUCT_SIZE(struct_type, field) \ + (G_STRUCT_OFFSET (struct_type, field) + sizeof (((struct_type *) NULL)->field)) + +_NM_UTILS_LOOKUP_DEFINE (static, _nmp_cache_id_size_by_type, NMPCacheIdType, guint, + NM_UTILS_LOOKUP_DEFAULT (({ nm_assert_not_reached (); sizeof (NMPCacheId); })), + NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_OBJECT_TYPE, _STRUCT_SIZE (NMPCacheId, object_type)), + NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_OBJECT_TYPE_VISIBLE_ONLY, _STRUCT_SIZE (NMPCacheId, object_type)), + NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_NO_DEFAULT, _STRUCT_SIZE (NMPCacheId, object_type)), + NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_ONLY_DEFAULT, _STRUCT_SIZE (NMPCacheId, object_type)), + NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_ADDRROUTE_VISIBLE_BY_IFINDEX, _STRUCT_SIZE (NMPCacheId, object_type_by_ifindex)), + NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_NO_DEFAULT, _STRUCT_SIZE (NMPCacheId, object_type_by_ifindex)), + NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_ONLY_DEFAULT, _STRUCT_SIZE (NMPCacheId, object_type_by_ifindex)), + NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, _STRUCT_SIZE (NMPCacheId, link_by_ifname)), + NM_UTILS_LOOKUP_ITEM_IGNORE (NMP_CACHE_ID_TYPE_NONE), + NM_UTILS_LOOKUP_ITEM_IGNORE (__NMP_CACHE_ID_TYPE_MAX), +); + gboolean nmp_cache_id_equal (const NMPCacheId *a, const NMPCacheId *b) { - /* just memcmp() the entire id. This is potentially dangerous, because - * the struct is not __attribute__((packed)) and not all types have the - * same size. It is important, to memset() the entire struct to 0, - * not only the relevant fields. - * - * You anyway should use the nmp_cache_id_init_*() functions on a stack-allocated - * struct. */ - return memcmp (a, b, sizeof (NMPCacheId)) == 0; + if (a->_id_type != b->_id_type) + return FALSE; + return memcmp (a, b, _nmp_cache_id_size_by_type (a->_id_type)) == 0; } guint nmp_cache_id_hash (const NMPCacheId *id) { guint hash = 5381; - guint i; + guint i, n; - for (i = 0; i < sizeof (NMPCacheId); i++) + /* for hashing we only iterate over the actually set bytes and skip the + * zero padding at the end (which depends on the type of the id). + * + * For the equal implementation, we don't care about that and compare the + * entire NMPCacheId sized struct. */ + n = _nmp_cache_id_size_by_type (id->_id_type); + for (i = 0; i < n; i++) hash = ((hash << 5) + hash) + ((char *) id)[i]; /* hash * 33 + c */ return hash; } @@ -980,27 +998,42 @@ NMPCacheId * nmp_cache_id_clone (const NMPCacheId *id) { NMPCacheId *id2; + guint n; - id2 = g_slice_new (NMPCacheId); - memcpy (id2, id, sizeof (NMPCacheId)); + n = _nmp_cache_id_size_by_type (id->_id_type); + id2 = g_slice_alloc (n); + memcpy (id2, id, n); return id2; } void nmp_cache_id_destroy (NMPCacheId *id) { - g_slice_free (NMPCacheId, id); + guint n; + + n = _nmp_cache_id_size_by_type (id->_id_type); + g_slice_free1 (n, id); } /******************************************************************/ NMPCacheId _nmp_cache_id_static; -static NMPCacheId * +static void _nmp_cache_id_init (NMPCacheId *id, NMPCacheIdType id_type) { memset (id, 0, sizeof (NMPCacheId)); id->_id_type = id_type; +} + +NMPCacheId * +nmp_cache_id_copy (NMPCacheId *id, const NMPCacheId *src) +{ + guint n; + + memset (id, 0, sizeof (NMPCacheId)); + n = _nmp_cache_id_size_by_type (src->_id_type); + memcpy (id, src, n); return id; } @@ -1028,7 +1061,7 @@ nmp_cache_id_init_addrroute_visible_by_ifindex (NMPCacheId *id, _nmp_cache_id_init (id, NMP_CACHE_ID_TYPE_ADDRROUTE_VISIBLE_BY_IFINDEX); id->object_type_by_ifindex.obj_type = obj_type; - id->object_type_by_ifindex.ifindex = ifindex; + memcpy (&id->object_type_by_ifindex._misaligned_ifindex, &ifindex, sizeof (int)); return id; } @@ -1055,7 +1088,7 @@ nmp_cache_id_init_routes_visible (NMPCacheId *id, g_return_val_if_reached (NULL); id->object_type_by_ifindex.obj_type = obj_type; - id->object_type_by_ifindex.ifindex = ifindex; + memcpy (&id->object_type_by_ifindex._misaligned_ifindex, &ifindex, sizeof (int)); return id; } diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index bdea0a3703..253c453ab3 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -89,7 +89,7 @@ typedef struct { union { NMMultiIndexId base; guint8 _id_type; /* NMPCacheIdType as guint8 */ - struct { + struct _nm_packed { /* NMP_CACHE_ID_TYPE_OBJECT_TYPE */ /* NMP_CACHE_ID_TYPE_OBJECT_TYPE_VISIBLE_ONLY */ /* NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_NO_DEFAULT */ @@ -97,15 +97,15 @@ typedef struct { guint8 _id_type; guint8 obj_type; /* NMPObjectType as guint8 */ } object_type; - struct { + struct _nm_packed { /* NMP_CACHE_ID_TYPE_ADDRROUTE_VISIBLE_BY_IFINDEX */ /* NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_NO_DEFAULT */ /* NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_ONLY_DEFAULT */ guint8 _id_type; guint8 obj_type; /* NMPObjectType as guint8 */ - int ifindex; + int _misaligned_ifindex; } object_type_by_ifindex; - struct { + struct _nm_packed { /* NMP_CACHE_ID_TYPE_LINK_BY_IFNAME */ guint8 _id_type; char ifname_short[IFNAMSIZ - 1]; /* don't include the trailing NUL so the struct fits in 4 bytes. */ @@ -379,6 +379,7 @@ guint nmp_cache_id_hash (const NMPCacheId *id); NMPCacheId *nmp_cache_id_clone (const NMPCacheId *id); void nmp_cache_id_destroy (NMPCacheId *id); +NMPCacheId *nmp_cache_id_copy (NMPCacheId *id, const NMPCacheId *src); NMPCacheId *nmp_cache_id_init_object_type (NMPCacheId *id, NMPObjectType obj_type, gboolean visible_only); NMPCacheId *nmp_cache_id_init_addrroute_visible_by_ifindex (NMPCacheId *id, NMPObjectType obj_type, int ifindex); NMPCacheId *nmp_cache_id_init_routes_visible (NMPCacheId *id, NMPObjectType obj_type, gboolean with_default, gboolean with_non_default, int ifindex); From 08cce6c0ef94dbfb6f306fe39172b4c1dae1b3b8 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 14:19:05 +0200 Subject: [PATCH 11/31] platform: change @plen field of NMPlatformIPxRoute to type guint8 On netlink layer, this field is uint8_t/uchar. A larger (signed) plen makes no sense. Adjust the signatures to have only guint8. (cherry picked from commit 14ee5dd2f828063baff3dffd937bafc53c6d3323) --- src/devices/nm-device.c | 1 + src/dhcp-manager/nm-dhcp-systemd.c | 3 ++- src/dhcp-manager/nm-dhcp-utils.c | 2 +- src/dhcp-manager/tests/test-dhcp-utils.c | 2 ++ src/nm-iface-helper.c | 3 ++- src/nm-ip4-config.c | 11 ++++++---- src/nm-ip4-config.h | 2 +- src/nm-ip6-config.c | 11 ++++++---- src/nm-ip6-config.h | 2 +- src/nm-route-manager.c | 2 +- src/platform/nm-fake-platform.c | 14 +++++++------ src/platform/nm-linux-platform.c | 20 ++++++++++-------- src/platform/nm-platform.c | 22 +++++++++++--------- src/platform/nm-platform.h | 26 ++++++++++++------------ src/platform/nmp-object.c | 4 ++-- src/platform/nmp-object.h | 4 ++-- src/platform/tests/test-route.c | 4 ++-- src/vpn-manager/nm-vpn-connection.c | 12 +++++++---- 18 files changed, 83 insertions(+), 62 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index dde9af9481..3d949ec2d8 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -5725,6 +5725,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self) if (discovered_route->plen > 0) { memset (&route, 0, sizeof (route)); route.network = discovered_route->network; + nm_assert (discovered_route->plen <= 128); route.plen = discovered_route->plen; route.gateway = discovered_route->gateway; route.source = NM_IP_CONFIG_SOURCE_RDISC; diff --git a/src/dhcp-manager/nm-dhcp-systemd.c b/src/dhcp-manager/nm-dhcp-systemd.c index 91fa880305..5d49c27e44 100644 --- a/src/dhcp-manager/nm-dhcp-systemd.c +++ b/src/dhcp-manager/nm-dhcp-systemd.c @@ -312,7 +312,8 @@ lease_to_ip4_config (const char *iface, continue; route.network = a.s_addr; - if (sd_dhcp_route_get_destination_prefix_length (routes[i], &plen) < 0) + if ( sd_dhcp_route_get_destination_prefix_length (routes[i], &plen) < 0 + || plen > 32) continue; route.plen = plen; diff --git a/src/dhcp-manager/nm-dhcp-utils.c b/src/dhcp-manager/nm-dhcp-utils.c index be563a6971..571b1c2213 100644 --- a/src/dhcp-manager/nm-dhcp-utils.c +++ b/src/dhcp-manager/nm-dhcp-utils.c @@ -60,7 +60,7 @@ ip4_process_dhcpcd_rfc3442_routes (const char *str, *slash = '\0'; errno = 0; rt_cidr = strtol (slash + 1, NULL, 10); - if ((errno == EINVAL) || (errno == ERANGE)) { + if (errno || rt_cidr > 32) { nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route cidr: '%s'", slash + 1); continue; } diff --git a/src/dhcp-manager/tests/test-dhcp-utils.c b/src/dhcp-manager/tests/test-dhcp-utils.c index 162f2dd4cd..f477c061fb 100644 --- a/src/dhcp-manager/tests/test-dhcp-utils.c +++ b/src/dhcp-manager/tests/test-dhcp-utils.c @@ -208,6 +208,8 @@ ip4_test_route (NMIP4Config *ip4_config, const NMPlatformIP4Route *route; guint32 tmp; + g_assert (expected_prefix <= 32); + route = nm_ip4_config_get_route (ip4_config, route_num); g_assert (inet_pton (AF_INET, expected_dest, &tmp) > 0); g_assert (route->network == tmp); diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index 5a697537c1..20f7729a43 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -213,7 +213,8 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da * local configuration or user preferences are, so sending routes * with a prefix length of 0 is quite rude and thus ignored. */ - if (discovered_route->plen > 0) { + if ( discovered_route->plen > 0 + && discovered_route->plen <= 128) { memset (&route, 0, sizeof (route)); route.network = discovered_route->network; route.plen = discovered_route->plen; diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 4b27edf74b..78c3f94f4f 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -486,7 +486,12 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu memset (&route, 0, sizeof (route)); nm_ip_route_get_dest_binary (s_route, &route.network); + route.plen = nm_ip_route_get_prefix (s_route); + nm_assert (route.plen <= 32); + if (route.plen == 0) + continue; + nm_ip_route_get_next_hop_binary (s_route, &route.gateway); if (nm_ip_route_get_metric (s_route) == -1) route.metric = default_route_metric; @@ -494,8 +499,6 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu route.metric = nm_ip_route_get_metric (s_route); route.source = NM_IP_CONFIG_SOURCE_USER; - g_assert (route.plen > 0); - nm_ip4_config_add_route (config, &route); } @@ -1328,7 +1331,7 @@ nm_ip4_config_dump (const NMIP4Config *config, const char *detail) } gboolean -nm_ip4_config_destination_is_direct (const NMIP4Config *config, guint32 network, int plen) +nm_ip4_config_destination_is_direct (const NMIP4Config *config, guint32 network, guint8 plen) { guint naddresses = nm_ip4_config_get_num_addresses (config); int i; @@ -1567,7 +1570,7 @@ nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new) int i; g_return_if_fail (new != NULL); - g_return_if_fail (new->plen > 0); + g_return_if_fail (new->plen > 0 && new->plen <= 32); g_assert (priv->ifindex); for (i = 0; i < priv->routes->len; i++ ) { diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index 02bc8b07f1..b1a5768740 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -79,7 +79,7 @@ void nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMe void nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src); void nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src); gboolean nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relevant_changes); -gboolean nm_ip4_config_destination_is_direct (const NMIP4Config *config, guint32 dest, int plen); +gboolean nm_ip4_config_destination_is_direct (const NMIP4Config *config, guint32 dest, guint8 plen); void nm_ip4_config_dump (const NMIP4Config *config, const char *detail); /* Gateways */ diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 102aeab5fa..ab0b67d842 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -470,7 +470,12 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu memset (&route, 0, sizeof (route)); nm_ip_route_get_dest_binary (s_route, &route.network); + route.plen = nm_ip_route_get_prefix (s_route); + nm_assert (route.plen <= 128); + if (route.plen == 0) + continue; + nm_ip_route_get_next_hop_binary (s_route, &route.gateway); if (nm_ip_route_get_metric (s_route) == -1) route.metric = default_route_metric; @@ -478,8 +483,6 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu route.metric = nm_ip_route_get_metric (s_route); route.source = NM_IP_CONFIG_SOURCE_USER; - g_assert (route.plen > 0); - nm_ip6_config_add_route (config, &route); } @@ -690,7 +693,7 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFl } gboolean -nm_ip6_config_destination_is_direct (const NMIP6Config *config, const struct in6_addr *network, int plen) +nm_ip6_config_destination_is_direct (const NMIP6Config *config, const struct in6_addr *network, guint8 plen) { int num = nm_ip6_config_get_num_addresses (config); int i; @@ -1401,7 +1404,7 @@ nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new) int i; g_return_if_fail (new != NULL); - g_return_if_fail (new->plen > 0); + g_return_if_fail (new->plen > 0 && new->plen <= 128); g_assert (priv->ifindex); for (i = 0; i < priv->routes->len; i++ ) { diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index 5ca64ac372..5e66d500e4 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -81,7 +81,7 @@ void nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMe void nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src); void nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src); gboolean nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relevant_changes); -int nm_ip6_config_destination_is_direct (const NMIP6Config *config, const struct in6_addr *dest, int plen); +int nm_ip6_config_destination_is_direct (const NMIP6Config *config, const struct in6_addr *dest, guint8 plen); void nm_ip6_config_dump (const NMIP6Config *config, const char *detail); /* Gateways */ diff --git a/src/nm-route-manager.c b/src/nm-route-manager.c index 3cf241186b..05e28c7426 100644 --- a/src/nm-route-manager.c +++ b/src/nm-route-manager.c @@ -221,7 +221,7 @@ _v6_route_dest_cmp (const NMPlatformIP6Route *r1, const NMPlatformIP6Route *r2) CMP_AND_RETURN_INT (r1->plen, r2->plen); nm_utils_ip6_address_clear_host_address (&n1, &r1->network, r1->plen); - nm_utils_ip6_address_clear_host_address (&n2, &r2->network, r2->plen); + nm_utils_ip6_address_clear_host_address (&n2, &r2->network, r2->plen ); return memcmp (&n1, &n2, sizeof (n1)); } diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index fdb11eac56..fc3875c724 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -1129,7 +1129,7 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags fl } static gboolean -ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric) +ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1153,7 +1153,7 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen } static gboolean -ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric) +ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1180,7 +1180,7 @@ ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, in static gboolean ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, - in_addr_t network, int plen, in_addr_t gateway, + in_addr_t network, guint8 plen, in_addr_t gateway, in_addr_t pref_src, guint32 metric, guint32 mss) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); @@ -1188,6 +1188,8 @@ ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, guint i; guint8 scope; + g_assert (plen <= 32); + scope = gateway == 0 ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE; memset (&route, 0, sizeof (route)); @@ -1247,7 +1249,7 @@ ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, static gboolean ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, - struct in6_addr network, int plen, struct in6_addr gateway, + struct in6_addr network, guint8 plen, struct in6_addr gateway, guint32 metric, guint32 mss) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); @@ -1313,7 +1315,7 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, } static const NMPlatformIP4Route * -ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric) +ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1332,7 +1334,7 @@ ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, int plen, g } static const NMPlatformIP6Route * -ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric) +ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 3282e698ce..e8d75c0837 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -330,9 +330,8 @@ _nm_ip_config_source_from_rtprot (guint rtprot) } static void -clear_host_address (int family, const void *network, int plen, void *dst) +clear_host_address (int family, const void *network, guint8 plen, void *dst) { - g_return_if_fail (plen == (guint8)plen); g_return_if_fail (network); switch (family) { @@ -1779,6 +1778,9 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) ? sizeof (in_addr_t) : sizeof (struct in6_addr); + if (rtm->rtm_dst_len > (is_v4 ? 32 : 128)) + goto errout; + /***************************************************************** * parse nexthops. Only handle routes with one nh. *****************************************************************/ @@ -2255,7 +2257,7 @@ _nl_msg_new_route (int nlmsg_type, NMIPConfigSource source, unsigned char scope, gconstpointer network, - int plen, + guint8 plen, gconstpointer gateway, guint32 metric, guint32 mss, @@ -5454,7 +5456,7 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags fl static gboolean ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, - in_addr_t network, int plen, in_addr_t gateway, + in_addr_t network, guint8 plen, in_addr_t gateway, in_addr_t pref_src, guint32 metric, guint32 mss) { NMPObject obj_id; @@ -5479,7 +5481,7 @@ ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, static gboolean ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, - struct in6_addr network, int plen, struct in6_addr gateway, + struct in6_addr network, guint8 plen, struct in6_addr gateway, guint32 metric, guint32 mss) { NMPObject obj_id; @@ -5503,7 +5505,7 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, } static gboolean -ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric) +ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); nm_auto_nlmsg struct nl_msg *nlmsg = NULL; @@ -5559,7 +5561,7 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen } static gboolean -ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric) +ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; NMPObject obj_id; @@ -5587,7 +5589,7 @@ ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, in } static const NMPlatformIP4Route * -ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric) +ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) { NMPObject obj_id; const NMPObject *obj; @@ -5600,7 +5602,7 @@ ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, int plen, g } static const NMPlatformIP6Route * -ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric) +ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) { NMPObject obj_id; const NMPObject *obj; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 5a399b316a..744363b123 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -2854,13 +2854,13 @@ nm_platform_ip6_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRoute gboolean nm_platform_ip4_route_add (NMPlatform *self, int ifindex, NMIPConfigSource source, - in_addr_t network, int plen, + in_addr_t network, guint8 plen, in_addr_t gateway, in_addr_t pref_src, guint32 metric, guint32 mss) { _CHECK_SELF (self, klass, FALSE); - g_return_val_if_fail (0 <= plen && plen <= 32, FALSE); + g_return_val_if_fail (plen <= 32, FALSE); if (_LOGD_ENABLED ()) { NMPlatformIP4Route route = { 0 }; @@ -2882,12 +2882,12 @@ nm_platform_ip4_route_add (NMPlatform *self, gboolean nm_platform_ip6_route_add (NMPlatform *self, int ifindex, NMIPConfigSource source, - struct in6_addr network, int plen, struct in6_addr gateway, + struct in6_addr network, guint8 plen, struct in6_addr gateway, guint32 metric, guint32 mss) { _CHECK_SELF (self, klass, FALSE); - g_return_val_if_fail (0 <= plen && plen <= 128, FALSE); + g_return_val_if_fail (plen <= 128, FALSE); if (_LOGD_ENABLED ()) { NMPlatformIP6Route route = { 0 }; @@ -2906,7 +2906,7 @@ nm_platform_ip6_route_add (NMPlatform *self, } gboolean -nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, int plen, guint32 metric) +nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric) { char str_dev[TO_STRING_DEV_BUF_SIZE]; @@ -2919,7 +2919,7 @@ nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, } gboolean -nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, int plen, guint32 metric) +nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) { char str_dev[TO_STRING_DEV_BUF_SIZE]; @@ -2932,7 +2932,7 @@ nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr net } const NMPlatformIP4Route * -nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, int plen, guint32 metric) +nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric) { _CHECK_SELF (self, klass, FALSE); @@ -2940,7 +2940,7 @@ nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, int } const NMPlatformIP6Route * -nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, int plen, guint32 metric) +nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) { _CHECK_SELF (self, klass, FALSE); @@ -3631,7 +3631,8 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi "%s%s" /* scope */ "%s%s" /* pref-src */ "", - s_network, route->plen, + s_network, + route->plen, s_gateway, str_dev, route->metric, @@ -3678,7 +3679,8 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi " mss %"G_GUINT32_FORMAT " src %s" /* source */ "", - s_network, route->plen, + s_network, + route->plen, s_gateway, str_dev, route->metric, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 15bd2fdeef..fbfa470174 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -302,7 +302,7 @@ typedef union { #define __NMPlatformIPRoute_COMMON \ __NMPlatformObject_COMMON; \ NMIPConfigSource source; \ - int plen; \ + guint8 plen; \ guint32 metric; \ guint32 mss; \ ; @@ -615,15 +615,15 @@ typedef struct { GArray * (*ip4_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteFlags flags); GArray * (*ip6_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteFlags flags); gboolean (*ip4_route_add) (NMPlatform *, int ifindex, NMIPConfigSource source, - in_addr_t network, int plen, in_addr_t gateway, + in_addr_t network, guint8 plen, in_addr_t gateway, in_addr_t pref_src, guint32 metric, guint32 mss); gboolean (*ip6_route_add) (NMPlatform *, int ifindex, NMIPConfigSource source, - struct in6_addr network, int plen, struct in6_addr gateway, + struct in6_addr network, guint8 plen, struct in6_addr gateway, guint32 metric, guint32 mss); - gboolean (*ip4_route_delete) (NMPlatform *, int ifindex, in_addr_t network, int plen, guint32 metric); - gboolean (*ip6_route_delete) (NMPlatform *, int ifindex, struct in6_addr network, int plen, guint32 metric); - const NMPlatformIP4Route *(*ip4_route_get) (NMPlatform *, int ifindex, in_addr_t network, int plen, guint32 metric); - const NMPlatformIP6Route *(*ip6_route_get) (NMPlatform *, int ifindex, struct in6_addr network, int plen, guint32 metric); + gboolean (*ip4_route_delete) (NMPlatform *, int ifindex, in_addr_t network, guint8 plen, guint32 metric); + gboolean (*ip6_route_delete) (NMPlatform *, int ifindex, struct in6_addr network, guint8 plen, guint32 metric); + const NMPlatformIP4Route *(*ip4_route_get) (NMPlatform *, int ifindex, in_addr_t network, guint8 plen, guint32 metric); + const NMPlatformIP6Route *(*ip6_route_get) (NMPlatform *, int ifindex, struct in6_addr network, guint8 plen, guint32 metric); gboolean (*check_support_kernel_extended_ifa_flags) (NMPlatform *); gboolean (*check_support_user_ipv6ll) (NMPlatform *); @@ -888,18 +888,18 @@ gboolean nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArr gboolean nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known_addresses, gboolean keep_link_local); gboolean nm_platform_address_flush (NMPlatform *self, int ifindex); -const NMPlatformIP4Route *nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, int plen, guint32 metric); -const NMPlatformIP6Route *nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, int plen, guint32 metric); +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); GArray *nm_platform_ip4_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRouteFlags flags); GArray *nm_platform_ip6_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRouteFlags flags); gboolean nm_platform_ip4_route_add (NMPlatform *self, int ifindex, NMIPConfigSource source, - in_addr_t network, int plen, in_addr_t gateway, + in_addr_t network, guint8 plen, in_addr_t gateway, in_addr_t pref_src, guint32 metric, guint32 mss); gboolean nm_platform_ip6_route_add (NMPlatform *self, int ifindex, NMIPConfigSource source, - struct in6_addr network, int plen, struct in6_addr gateway, + struct in6_addr network, guint8 plen, struct in6_addr gateway, guint32 metric, guint32 mss); -gboolean nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, int plen, guint32 metric); -gboolean nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, int plen, guint32 metric); +gboolean nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric); +gboolean nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric); const char *nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len); const char *nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 740ed8d102..fcd4894487 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -377,7 +377,7 @@ _vt_cmd_obj_stackinit_id_ip6_address (NMPObject *obj, const NMPObject *src) } const NMPObject * -nmp_object_stackinit_id_ip4_route (NMPObject *obj, int ifindex, guint32 network, int plen, guint32 metric) +nmp_object_stackinit_id_ip4_route (NMPObject *obj, int ifindex, guint32 network, guint8 plen, guint32 metric) { nmp_object_stackinit (obj, NMP_OBJECT_TYPE_IP4_ROUTE, NULL); obj->ip4_route.ifindex = ifindex; @@ -394,7 +394,7 @@ _vt_cmd_obj_stackinit_id_ip4_route (NMPObject *obj, const NMPObject *src) } const NMPObject * -nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6_addr *network, int plen, guint32 metric) +nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric) { nmp_object_stackinit (obj, NMP_OBJECT_TYPE_IP6_ROUTE, NULL); obj->ip6_route.ifindex = ifindex; diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 253c453ab3..71e6e876ad 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -347,8 +347,8 @@ 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, 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); +const NMPObject *nmp_object_stackinit_id_ip4_route (NMPObject *obj, int ifindex, guint32 network, guint8 plen, guint32 metric); +const NMPObject *nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric); const char *nmp_object_to_string (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size); int nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2); diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 85851854ea..09ffbb6899 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -142,7 +142,7 @@ test_ip4_route (void) GArray *routes; NMPlatformIP4Route rts[3]; in_addr_t network; - int plen = 24; + guint8 plen = 24; in_addr_t gateway; /* Choose a high metric so that we hopefully don't conflict. */ int metric = 22986; @@ -229,7 +229,7 @@ test_ip6_route (void) GArray *routes; NMPlatformIP6Route rts[3]; struct in6_addr network; - int plen = 64; + guint8 plen = 64; struct in6_addr gateway; /* Choose a high metric so that we hopefully don't conflict. */ int metric = 22987; diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index cbc7c69d34..7efcc7829b 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -1439,6 +1439,9 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) route.metric = route_metric; route.source = NM_IP_CONFIG_SOURCE_VPN; + if (route.plen > 32) + break; + /* Ignore host routes to the VPN gateway since NM adds one itself * below. Since NM knows more about the routing situation than * the VPN server, we want to use the NM created route instead of @@ -1448,7 +1451,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) nm_ip4_config_add_route (config, &route); break; default: - _LOGW ("VPN connection: received invalid IPv4 route"); + break; } g_variant_unref (v); } @@ -1565,10 +1568,11 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) memset (&route, 0, sizeof (route)); - if (!ip6_addr_from_variant (dest, &route.network)) { - _LOGW ("VPN connection: received invalid IPv6 dest address"); + if (!ip6_addr_from_variant (dest, &route.network)) + goto next; + + if (prefix > 128) goto next; - } route.plen = prefix; ip6_addr_from_variant (next_hop, &route.gateway); From 4873850fd4c19ecaff9f8743002045239d03301a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 18:04:26 +0200 Subject: [PATCH 12/31] platform: change @plen field of NMPlatformIPxAddress to type guint8 On netlink layer, this field is uint8_t/uchar. A larger (signed) plen makes no sense. Adjust the signatures to have only guint8. (cherry picked from commit 44768f0311deb9082c69e3525693091a59788ebb) --- src/devices/wwan/nm-modem-broadband.c | 6 ++++-- src/dhcp-manager/nm-dhcp-utils.c | 3 ++- src/dnsmasq-manager/nm-dnsmasq-utils.c | 2 +- src/nm-ip4-config.c | 7 +++++++ src/nm-ip6-config.c | 5 +++++ src/platform/nm-fake-platform.c | 23 +++++++++++---------- src/platform/nm-linux-platform.c | 17 +++++++++------- src/platform/nm-platform.c | 28 ++++++++++++++------------ src/platform/nm-platform.h | 28 +++++++++++++------------- src/platform/nmp-object.c | 4 ++-- src/platform/nmp-object.h | 4 ++-- src/platform/tests/test-address.c | 2 +- src/ppp-manager/nm-ppp-manager.c | 6 +++++- src/vpn-manager/nm-vpn-connection.c | 8 ++++---- 14 files changed, 84 insertions(+), 59 deletions(-) diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 769e6a2753..9539fefd3d 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -870,7 +870,8 @@ static_stage3_ip4_done (NMModemBroadband *self) address.peer_address = address_network; address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv4_config); address.source = NM_IP_CONFIG_SOURCE_WWAN; - nm_ip4_config_add_address (config, &address); + if (address.plen <= 32) + nm_ip4_config_add_address (config, &address); nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); @@ -960,7 +961,8 @@ stage3_ip6_done (NMModemBroadband *self) config = nm_ip6_config_new (nm_platform_link_get_ifindex (NM_PLATFORM_GET, data_port)); address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv6_config); - nm_ip6_config_add_address (config, &address); + if (address.plen <= 128) + nm_ip6_config_add_address (config, &address); nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); diff --git a/src/dhcp-manager/nm-dhcp-utils.c b/src/dhcp-manager/nm-dhcp-utils.c index 571b1c2213..a88a7e6d51 100644 --- a/src/dhcp-manager/nm-dhcp-utils.c +++ b/src/dhcp-manager/nm-dhcp-utils.c @@ -382,7 +382,8 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex, in_addr_t addr; NMPlatformIP4Address address; char *str = NULL; - guint32 gwaddr = 0, plen = 0; + guint32 gwaddr = 0; + guint8 plen = 0; g_return_val_if_fail (options != NULL, NULL); diff --git a/src/dnsmasq-manager/nm-dnsmasq-utils.c b/src/dnsmasq-manager/nm-dnsmasq-utils.c index bf8faecd52..3786f37d44 100644 --- a/src/dnsmasq-manager/nm-dnsmasq-utils.c +++ b/src/dnsmasq-manager/nm-dnsmasq-utils.c @@ -34,7 +34,7 @@ nm_dnsmasq_utils_get_range (const NMPlatformIP4Address *addr, char **out_error_desc) { guint32 host = addr->address; - guint32 prefix = addr->plen; + guint8 prefix = addr->plen; guint32 netmask = nm_utils_ip4_prefix_to_netmask (prefix); guint32 first, last, reserved; diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 78c3f94f4f..d6f6a9b3fc 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -365,6 +365,8 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_fu if (addr->plen == 0) continue; + nm_assert (addr->plen <= 32); + route.ifindex = ifindex; route.source = NM_IP_CONFIG_SOURCE_KERNEL; @@ -466,6 +468,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu nm_ip_address_get_address_binary (s_addr, &address.address); address.peer_address = address.address; address.plen = nm_ip_address_get_prefix (s_addr); + nm_assert (address.plen <= 32); address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT; address.preferred = NM_PLATFORM_LIFETIME_PERMANENT; address.source = NM_IP_CONFIG_SOURCE_USER; @@ -564,6 +567,10 @@ nm_ip4_config_create_setting (const NMIP4Config *config) continue; } + /* FIXME: NMIPAddress doesn't support zero prefixes. */ + if (address->plen == 0) + continue; + /* Static address found. */ if (!method) method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index ab0b67d842..0b32901bf1 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -454,6 +454,7 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu memset (&address, 0, sizeof (address)); nm_ip_address_get_address_binary (s_addr, &address.address); address.plen = nm_ip_address_get_prefix (s_addr); + nm_assert (address.plen <= 128); address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT; address.preferred = NM_PLATFORM_LIFETIME_PERMANENT; address.source = NM_IP_CONFIG_SOURCE_USER; @@ -555,6 +556,10 @@ nm_ip6_config_create_setting (const NMIP6Config *config) continue; } + /* FIXME: NMIPAddress does not support zero prefixes. */ + if (address->plen == 0) + continue; + /* Static address found. */ if (!method || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index fc3875c724..15d9c54301 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -91,17 +91,17 @@ static void link_changed (NMPlatform *platform, NMFakePlatformLink *device, gboo static gboolean ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, - int plen, + guint8 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); +static gboolean ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, guint8 plen); /******************************************************************/ static gboolean -_ip4_address_equal_peer_net (in_addr_t peer1, in_addr_t peer2, int plen) +_ip4_address_equal_peer_net (in_addr_t peer1, in_addr_t peer2, guint8 plen) { return ((peer1 ^ peer2) & nm_utils_ip4_prefix_to_netmask (plen)) == 0; } @@ -886,7 +886,7 @@ static gboolean ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, - int plen, + guint8 plen, in_addr_t peer_addr, guint32 lifetime, guint32 preferred, @@ -938,7 +938,7 @@ static gboolean ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, - int plen, + guint8 plen, struct in6_addr peer_addr, guint32 lifetime, guint32 preferred, @@ -982,7 +982,7 @@ ip6_address_add (NMPlatform *platform, } static gboolean -ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, in_addr_t peer_address) +ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, guint8 plen, in_addr_t peer_address) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1007,7 +1007,7 @@ ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, } static gboolean -ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen) +ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, guint8 plen) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1031,7 +1031,7 @@ 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, in_addr_t peer_address) +ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, guint8 plen, in_addr_t peer_address) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1050,7 +1050,7 @@ ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, in } static const NMPlatformIP6Address * -ip6_address_get (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen) +ip6_address_get (NMPlatform *platform, int ifindex, struct in6_addr addr, guint8 plen) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1058,8 +1058,9 @@ ip6_address_get (NMPlatform *platform, int ifindex, struct in6_addr addr, int pl for (i = 0; i < priv->ip6_addresses->len; i++) { NMPlatformIP6Address *address = &g_array_index (priv->ip6_addresses, NMPlatformIP6Address, i); - if (address->ifindex == ifindex && address->plen == plen && - IN6_ARE_ADDR_EQUAL (&address->address, &addr)) + if ( address->ifindex == ifindex + && address->plen == plen + && IN6_ARE_ADDR_EQUAL (&address->address, &addr)) return address; } diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index e8d75c0837..668f0f5a1f 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -1640,6 +1640,9 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) ? sizeof (in_addr_t) : sizeof (struct in6_addr); + if (ifa->ifa_prefixlen > (is_v4 ? 32 : 128)) + goto errout; + /*****************************************************************/ obj = nmp_object_new (is_v4 ? NMP_OBJECT_TYPE_IP4_ADDRESS : NMP_OBJECT_TYPE_IP6_ADDRESS, NULL); @@ -2160,7 +2163,7 @@ _nl_msg_new_address (int nlmsg_type, int family, int ifindex, gconstpointer address, - int plen, + guint8 plen, gconstpointer peer_address, guint32 flags, int scope, @@ -5268,7 +5271,7 @@ static gboolean ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, - int plen, + guint8 plen, in_addr_t peer_addr, guint32 lifetime, guint32 preferred, @@ -5299,7 +5302,7 @@ static gboolean ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, - int plen, + guint8 plen, struct in6_addr peer_addr, guint32 lifetime, guint32 preferred, @@ -5326,7 +5329,7 @@ ip6_address_add (NMPlatform *platform, } static gboolean -ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, in_addr_t peer_address) +ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, guint8 plen, in_addr_t peer_address) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; NMPObject obj_id; @@ -5351,7 +5354,7 @@ ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, } static gboolean -ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen) +ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, guint8 plen) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; NMPObject obj_id; @@ -5376,7 +5379,7 @@ 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, in_addr_t peer_address) +ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, guint8 plen, in_addr_t peer_address) { NMPObject obj_id; const NMPObject *obj; @@ -5389,7 +5392,7 @@ ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, in } static const NMPlatformIP6Address * -ip6_address_get (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen) +ip6_address_get (NMPlatform *platform, int ifindex, struct in6_addr addr, guint8 plen) { NMPObject obj_id; const NMPObject *obj; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 744363b123..07ec4cf0b3 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -2459,8 +2459,10 @@ nm_platform_ethtool_get_link_speed (NMPlatform *self, const char *ifname, guint3 /******************************************************************/ void -nm_platform_ip4_address_set_addr (NMPlatformIP4Address *addr, in_addr_t address, int plen) +nm_platform_ip4_address_set_addr (NMPlatformIP4Address *addr, in_addr_t address, guint8 plen) { + nm_assert (plen <= 32); + addr->address = address; addr->peer_address = address; addr->plen = plen; @@ -2499,7 +2501,7 @@ gboolean nm_platform_ip4_address_add (NMPlatform *self, int ifindex, in_addr_t address, - int plen, + guint8 plen, in_addr_t peer_address, guint32 lifetime, guint32 preferred, @@ -2509,7 +2511,7 @@ nm_platform_ip4_address_add (NMPlatform *self, _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (plen > 0, FALSE); + g_return_val_if_fail (plen <= 32, FALSE); g_return_val_if_fail (lifetime > 0, FALSE); g_return_val_if_fail (preferred <= lifetime, FALSE); g_return_val_if_fail (!label || strlen (label) < sizeof (((NMPlatformIP4Address *) NULL)->label), FALSE); @@ -2537,7 +2539,7 @@ gboolean nm_platform_ip6_address_add (NMPlatform *self, int ifindex, struct in6_addr address, - int plen, + guint8 plen, struct in6_addr peer_address, guint32 lifetime, guint32 preferred, @@ -2546,7 +2548,7 @@ nm_platform_ip6_address_add (NMPlatform *self, _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (plen > 0, FALSE); + g_return_val_if_fail (plen <= 128, FALSE); g_return_val_if_fail (lifetime > 0, FALSE); g_return_val_if_fail (preferred <= lifetime, FALSE); @@ -2568,7 +2570,7 @@ nm_platform_ip6_address_add (NMPlatform *self, } gboolean -nm_platform_ip4_address_delete (NMPlatform *self, int ifindex, in_addr_t address, int plen, in_addr_t peer_address) +nm_platform_ip4_address_delete (NMPlatform *self, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address) { char str_dev[TO_STRING_DEV_BUF_SIZE]; char str_peer2[NM_UTILS_INET_ADDRSTRLEN]; @@ -2577,7 +2579,7 @@ nm_platform_ip4_address_delete (NMPlatform *self, int ifindex, in_addr_t address _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (plen > 0, FALSE); + g_return_val_if_fail (plen <= 32, FALSE); _LOGD ("address: deleting IPv4 address %s/%d, %sifindex %d%s", nm_utils_inet4_ntop (address, NULL), plen, @@ -2589,14 +2591,14 @@ nm_platform_ip4_address_delete (NMPlatform *self, int ifindex, in_addr_t address } gboolean -nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr address, int plen) +nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen) { char str_dev[TO_STRING_DEV_BUF_SIZE]; _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (plen > 0, FALSE); + g_return_val_if_fail (plen <= 128, FALSE); _LOGD ("address: deleting IPv6 address %s/%d, ifindex %d%s", nm_utils_inet6_ntop (&address, NULL), plen, ifindex, @@ -2605,21 +2607,21 @@ 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, guint32 peer_address) +nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, guint8 plen, guint32 peer_address) { _CHECK_SELF (self, klass, NULL); - g_return_val_if_fail (plen > 0, NULL); + g_return_val_if_fail (plen <= 32, NULL); return klass->ip4_address_get (self, ifindex, address, plen, peer_address); } const NMPlatformIP6Address * -nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address, int plen) +nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen) { _CHECK_SELF (self, klass, NULL); - g_return_val_if_fail (plen > 0, NULL); + g_return_val_if_fail (plen <= 128, NULL); return klass->ip6_address_get (self, ifindex, address, plen); } diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index fbfa470174..10fe282db0 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -226,7 +226,7 @@ typedef struct { * IFA_FLAGS attribute. */ \ guint32 n_ifa_flags; \ \ - int plen; \ + guint8 plen; \ ; /** @@ -593,7 +593,7 @@ typedef struct { gboolean (*ip4_address_add) (NMPlatform *, int ifindex, in_addr_t address, - int plen, + guint8 plen, in_addr_t peer_address, guint32 lifetime, guint32 preferred_lft, @@ -602,15 +602,15 @@ typedef struct { gboolean (*ip6_address_add) (NMPlatform *, int ifindex, struct in6_addr address, - int plen, + guint8 plen, struct in6_addr peer_address, guint32 lifetime, guint32 preferred_lft, guint32 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, in_addr_t peer_address); - const NMPlatformIP6Address *(*ip6_address_get) (NMPlatform *, int ifindex, struct in6_addr address, int plen); + 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); + const NMPlatformIP4Address *(*ip4_address_get) (NMPlatform *, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address); + const NMPlatformIP6Address *(*ip6_address_get) (NMPlatform *, int ifindex, struct in6_addr address, guint8 plen); GArray * (*ip4_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteFlags flags); GArray * (*ip6_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteFlags flags); @@ -835,10 +835,10 @@ 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); -void nm_platform_ip4_address_set_addr (NMPlatformIP4Address *addr, in_addr_t address, int plen); +void nm_platform_ip4_address_set_addr (NMPlatformIP4Address *addr, in_addr_t address, guint8 plen); const struct in6_addr *nm_platform_ip6_address_get_peer (const NMPlatformIP6Address *addr); -const NMPlatformIP4Address *nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, int plen, in_addr_t peer_address); +const NMPlatformIP4Address *nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address); NMPlatformError nm_platform_link_gre_add (NMPlatform *self, const char *name, @@ -862,13 +862,13 @@ NMPlatformError nm_platform_link_sit_add (NMPlatform *self, const NMPlatformLnkSit *props, const NMPlatformLink **out_link); -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, guint8 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, - int plen, + guint8 plen, in_addr_t peer_address, guint32 lifetime, guint32 preferred_lft, @@ -877,13 +877,13 @@ gboolean nm_platform_ip4_address_add (NMPlatform *self, gboolean nm_platform_ip6_address_add (NMPlatform *self, int ifindex, struct in6_addr address, - int plen, + guint8 plen, struct in6_addr peer_address, guint32 lifetime, guint32 preferred_lft, guint32 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_delete (NMPlatform *self, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address); +gboolean nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen); gboolean nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArray *known_addresses, GPtrArray **out_added_addresses); gboolean nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known_addresses, gboolean keep_link_local); gboolean nm_platform_address_flush (NMPlatform *self, int ifindex); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index fcd4894487..07ea9fe1d5 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -343,7 +343,7 @@ _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, guint32 peer_address) +nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifindex, guint32 address, guint8 plen, guint32 peer_address) { nmp_object_stackinit (obj, NMP_OBJECT_TYPE_IP4_ADDRESS, NULL); obj->ip4_address.ifindex = ifindex; @@ -360,7 +360,7 @@ _vt_cmd_obj_stackinit_id_ip4_address (NMPObject *obj, const NMPObject *src) } const NMPObject * -nmp_object_stackinit_id_ip6_address (NMPObject *obj, int ifindex, const struct in6_addr *address, int plen) +nmp_object_stackinit_id_ip6_address (NMPObject *obj, int ifindex, const struct in6_addr *address, guint8 plen) { nmp_object_stackinit (obj, NMP_OBJECT_TYPE_IP6_ADDRESS, NULL); obj->ip4_address.ifindex = ifindex; diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 71e6e876ad..72d6270814 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -345,8 +345,8 @@ 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, 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_address (NMPObject *obj, int ifindex, guint32 address, guint8 plen, guint32 peer_address); +const NMPObject *nmp_object_stackinit_id_ip6_address (NMPObject *obj, int ifindex, const struct in6_addr *address, guint8 plen); const NMPObject *nmp_object_stackinit_id_ip4_route (NMPObject *obj, int ifindex, guint32 network, guint8 plen, guint32 metric); const NMPObject *nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric); diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c index 83a0bfd3c2..15b00203a6 100644 --- a/src/platform/tests/test-address.c +++ b/src/platform/tests/test-address.c @@ -308,7 +308,7 @@ test_ip4_address_peer_zero (void) in_addr_t addr, addr_peer; guint32 lifetime = 2000; guint32 preferred = 1000; - const int plen = 24; + const gint8 plen = 24; const char *label = NULL; in_addr_t peers[3], r_peers[3]; int i; diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 18a28690e0..89a7addf84 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -481,7 +481,7 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, if (g_variant_lookup (config_dict, NM_PPP_IP4_CONFIG_PREFIX, "u", &u32)) address.plen = u32; - if (address.address && address.plen) { + if (address.address && address.plen && address.plen <= 32) { address.source = NM_IP_CONFIG_SOURCE_PPP; nm_ip4_config_add_address (config, &address); } else { @@ -554,6 +554,7 @@ impl_ppp_manager_set_ip6_config (NMPPPManager *manager, NMPlatformIP6Address addr; struct in6_addr a; NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT; + gboolean has_peer = FALSE; _LOGI ("(IPv6 Config Get) reply received."); @@ -567,9 +568,12 @@ impl_ppp_manager_set_ip6_config (NMPPPManager *manager, if (iid_value_to_ll6_addr (config_dict, NM_PPP_IP6_CONFIG_PEER_IID, &a, NULL)) { nm_ip6_config_set_gateway (config, &a); addr.peer_address = a; + has_peer = TRUE; } if (iid_value_to_ll6_addr (config_dict, NM_PPP_IP6_CONFIG_OUR_IID, &addr.address, &iid)) { + if (!has_peer) + addr.peer_address = addr.address; nm_ip6_config_add_address (config, &addr); if (set_ip_config_common (manager, config_dict, NM_PPP_IP6_CONFIG_INTERFACE, NULL)) { diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 7efcc7829b..2945ad34ad 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -1387,11 +1387,11 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, "u", &u32)) address.plen = u32; - if (address.address && address.plen) { + if (address.address && address.plen && address.plen <= 32) { address.source = NM_IP_CONFIG_SOURCE_VPN; nm_ip4_config_add_address (config, &address); } else { - _LOGE ("invalid IP4 config received!"); + _LOGW ("invalid IP4 config received!"); g_object_unref (config); nm_vpn_connection_config_maybe_complete (self, FALSE); return; @@ -1524,11 +1524,11 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_PREFIX, "u", &u32)) address.plen = u32; - if (!IN6_IS_ADDR_UNSPECIFIED (&address.address) && address.plen) { + if (!IN6_IS_ADDR_UNSPECIFIED (&address.address) && address.plen && address.plen <= 128) { address.source = NM_IP_CONFIG_SOURCE_VPN; nm_ip6_config_add_address (config, &address); } else { - _LOGE ("invalid IP6 config received!"); + _LOGW ("invalid IP6 config received!"); g_object_unref (config); nm_vpn_connection_config_maybe_complete (self, FALSE); return; From b5bd562614ceda41db6b5615e995dcc7e8a8ba39 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 12:14:53 +0200 Subject: [PATCH 13/31] platform: add nm_linux_platform_new() constructor (cherry picked from commit 45a9a6b30b953dab94f4e741509e4199d70c3c9b) --- src/platform/nm-linux-platform.c | 11 ++++++++++- src/platform/nm-linux-platform.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 668f0f5a1f..f83b650be4 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2417,12 +2417,21 @@ NM_LINUX_PLATFORM_GET_PRIVATE (const void *self) G_DEFINE_TYPE (NMLinuxPlatform, nm_linux_platform, NM_TYPE_PLATFORM) +NMPlatform * +nm_linux_platform_new (gboolean netns_support) +{ + return g_object_new (NM_TYPE_LINUX_PLATFORM, + NM_PLATFORM_REGISTER_SINGLETON, FALSE, + NM_PLATFORM_NETNS_SUPPORT, netns_support, + NULL); +} + void nm_linux_platform_setup (void) { g_object_new (NM_TYPE_LINUX_PLATFORM, - NM_PLATFORM_NETNS_SUPPORT, FALSE, NM_PLATFORM_REGISTER_SINGLETON, TRUE, + NM_PLATFORM_NETNS_SUPPORT, FALSE, NULL); } diff --git a/src/platform/nm-linux-platform.h b/src/platform/nm-linux-platform.h index a9e2cd82f9..4ae2fd1400 100644 --- a/src/platform/nm-linux-platform.h +++ b/src/platform/nm-linux-platform.h @@ -48,6 +48,8 @@ typedef struct { GType nm_linux_platform_get_type (void); +NMPlatform *nm_linux_platform_new (gboolean netns_support); + void nm_linux_platform_setup (void); #endif /* __NETWORKMANAGER_LINUX_PLATFORM_H__ */ From d306ac633ad3ee6bcb3104e1e33eeaf3976541e4 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 12:22:44 +0200 Subject: [PATCH 14/31] platform: add NM_PLATFORM_NETNS_SUPPORT_DEFAULT (cherry picked from commit d6b3081f7ba625cc18cf4f077534e93c94ab7ae1) --- src/platform/nm-platform.c | 2 +- src/platform/nm-platform.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 07ec4cf0b3..69b0d420ca 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -4261,7 +4261,7 @@ nm_platform_class_init (NMPlatformClass *platform_class) g_object_class_install_property (object_class, PROP_NETNS_SUPPORT, g_param_spec_boolean (NM_PLATFORM_NETNS_SUPPORT, "", "", - FALSE, + NM_PLATFORM_NETNS_SUPPORT_DEFAULT, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 10fe282db0..9f055b042c 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -40,6 +40,8 @@ #define NM_IS_PLATFORM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_PLATFORM)) #define NM_PLATFORM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_PLATFORM, NMPlatformClass)) +#define NM_PLATFORM_NETNS_SUPPORT_DEFAULT FALSE + /******************************************************************/ #define NM_PLATFORM_NETNS_SUPPORT "netns-support" From 04890bc7094ef18ad372a54950c7589e71225371 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 12:18:16 +0200 Subject: [PATCH 15/31] platform/tests: use nm_linux_platform_new() (cherry picked from commit 35e7703bdc9c1c1fb4ee3e90a903f2a72b142844) --- src/platform/tests/test-general.c | 4 ++-- src/platform/tests/test-link.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/platform/tests/test-general.c b/src/platform/tests/test-general.c index 66f72fa570..d8d925614b 100644 --- a/src/platform/tests/test-general.c +++ b/src/platform/tests/test-general.c @@ -35,7 +35,7 @@ test_init_linux_platform (void) { gs_unref_object NMPlatform *platform = NULL; - platform = g_object_new (NM_TYPE_LINUX_PLATFORM, NULL); + platform = nm_linux_platform_new (NM_PLATFORM_NETNS_SUPPORT_DEFAULT); } /******************************************************************/ @@ -46,7 +46,7 @@ test_link_get_all (void) gs_unref_object NMPlatform *platform = NULL; gs_unref_array GArray *links = NULL; - platform = g_object_new (NM_TYPE_LINUX_PLATFORM, NULL); + platform = nm_linux_platform_new (NM_PLATFORM_NETNS_SUPPORT_DEFAULT); links = nm_platform_link_get_all (platform); } diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 94695edcd1..9118198c64 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -1880,7 +1880,7 @@ _test_netns_create_platform (void) netns = nmp_netns_new (); g_assert (NMP_IS_NETNS (netns)); - platform = g_object_new (NM_TYPE_LINUX_PLATFORM, NM_PLATFORM_NETNS_SUPPORT, TRUE, NULL); + platform = nm_linux_platform_new (TRUE); g_assert (NM_IS_LINUX_PLATFORM (platform)); nmp_netns_pop (netns); @@ -1932,7 +1932,7 @@ test_netns_general (gpointer fixture, gconstpointer test_data) if (_test_netns_check_skip ()) return; - platform_1 = g_object_new (NM_TYPE_LINUX_PLATFORM, NM_PLATFORM_NETNS_SUPPORT, TRUE, NULL); + platform_1 = nm_linux_platform_new (TRUE); platform_2 = _test_netns_create_platform (); /* add some dummy devices. The "other-*" devices are there to bump the ifindex */ @@ -2028,7 +2028,7 @@ test_netns_set_netns (gpointer fixture, gconstpointer test_data) if (_test_netns_check_skip ()) return; - platforms[0] = platform_0 = g_object_new (NM_TYPE_LINUX_PLATFORM, NM_PLATFORM_NETNS_SUPPORT, TRUE, NULL); + platforms[0] = platform_0 = nm_linux_platform_new (TRUE); platforms[1] = platform_1 = _test_netns_create_platform (); platforms[2] = platform_2 = _test_netns_create_platform (); @@ -2125,7 +2125,7 @@ test_netns_push (gpointer fixture, gconstpointer test_data) if (_test_netns_check_skip ()) return; - pl[0].platform = platform_0 = g_object_new (NM_TYPE_LINUX_PLATFORM, NM_PLATFORM_NETNS_SUPPORT, TRUE, NULL); + pl[0].platform = platform_0 = nm_linux_platform_new (TRUE); pl[1].platform = platform_1 = _test_netns_create_platform (); pl[2].platform = platform_2 = _test_netns_create_platform (); @@ -2257,7 +2257,7 @@ test_netns_bind_to_path (gpointer fixture, gconstpointer test_data) if (_test_netns_check_skip ()) return; - platforms[0] = platform_0 = g_object_new (NM_TYPE_LINUX_PLATFORM, NM_PLATFORM_NETNS_SUPPORT, TRUE, NULL); + platforms[0] = platform_0 = nm_linux_platform_new (TRUE); platforms[1] = platform_1 = _test_netns_create_platform (); platforms[2] = platform_2 = _test_netns_create_platform (); From bbec8844e22d49656c874a7ab5afe5b8ea9bd8a0 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 21:05:49 +0200 Subject: [PATCH 16/31] platform/tests/trivial: move code around (cherry picked from commit 56753ee41fe21da29c47cd60c194290e26569aa5) --- src/platform/tests/test-common.c | 348 +++++++++++++++++-------------- src/platform/tests/test-common.h | 43 ++-- 2 files changed, 214 insertions(+), 177 deletions(-) diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index e9fffe9041..1a1d8b63dd 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -32,6 +32,8 @@ #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 +/*****************************************************************************/ + gboolean nmtstp_is_root_test (void) { @@ -47,6 +49,8 @@ nmtstp_is_sysfs_writable (void) || (access ("/sys/devices", W_OK) == 0); } +/*****************************************************************************/ + SignalData * add_signal_full (const char *name, NMPlatformSignalChangeType change_type, GCallback callback, int ifindex, const char *ifname) { @@ -180,6 +184,8 @@ link_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlat g_error ("Added/changed link not found in the local cache."); } +/*****************************************************************************/ + gboolean ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric) { @@ -287,6 +293,8 @@ _assert_ip4_route_exists (const char *file, guint line, const char *func, gboole } } +/*****************************************************************************/ + int nmtstp_run_command (const char *format, ...) { @@ -432,6 +440,8 @@ nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NML return plink; } +/*****************************************************************************/ + int nmtstp_run_command_check_external_global (void) { @@ -460,6 +470,8 @@ nmtstp_run_command_check_external (int external_command) return (nmtst_get_rand_int () % 2) == 0; } +/*****************************************************************************/ + #define CHECK_LIFETIME_MAX_DIFF 2 gboolean @@ -556,6 +568,8 @@ nmtstp_ip_address_assert_lifetime (const NMPlatformIPAddress *addr, g_assert (nmtstp_ip_address_check_lifetime (addr, n, expected_lifetime, expected_preferred)); } +/*****************************************************************************/ + static void _ip_address_add (gboolean external_command, gboolean is_v4, @@ -692,6 +706,173 @@ _ip_address_add (gboolean external_command, } 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, + guint32 flags, + const char *label) +{ + _ip_address_add (external_command, + TRUE, + ifindex, + (NMIPAddr *) &address, + plen, + (NMIPAddr *) &peer_address, + lifetime, + preferred, + flags, + 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, + guint32 flags) +{ + _ip_address_add (external_command, + FALSE, + ifindex, + (NMIPAddr *) &address, + plen, + (NMIPAddr *) &peer_address, + lifetime, + preferred, + flags, + NULL); +} + +/*****************************************************************************/ + +static void +_ip_address_del (gboolean external_command, + gboolean is_v4, + int ifindex, + const NMIPAddr *address, + int plen, + const NMIPAddr *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); + + /* 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 != address->addr4 ? " peer " : "", + peer_address->addr4 != 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); + + g_assert (nmtstp_wait_for_signal_until (NM_PLATFORM_GET, 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, + (NMIPAddr *) &address, + plen, + (NMIPAddr *) &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, + (NMIPAddr *) &address, + plen, + NULL); +} + +/*****************************************************************************/ + #define _assert_pllink(platform, success, pllink, name, type) \ G_STMT_START { \ const NMPlatformLink *_pllink = (pllink); \ @@ -1000,168 +1181,7 @@ nmtstp_link_vxlan_add (gboolean external_command, return pllink; } -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, - guint32 flags, - const char *label) -{ - _ip_address_add (external_command, - TRUE, - ifindex, - (NMIPAddr *) &address, - plen, - (NMIPAddr *) &peer_address, - lifetime, - preferred, - flags, - 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, - guint32 flags) -{ - _ip_address_add (external_command, - FALSE, - ifindex, - (NMIPAddr *) &address, - plen, - (NMIPAddr *) &peer_address, - lifetime, - preferred, - flags, - NULL); -} - -static void -_ip_address_del (gboolean external_command, - gboolean is_v4, - int ifindex, - const NMIPAddr *address, - int plen, - const NMIPAddr *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); - - /* 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 != address->addr4 ? " peer " : "", - peer_address->addr4 != 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); - - g_assert (nmtstp_wait_for_signal_until (NM_PLATFORM_GET, 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, - (NMIPAddr *) &address, - plen, - (NMIPAddr *) &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, - (NMIPAddr *) &address, - plen, - NULL); -} +/*****************************************************************************/ const NMPlatformLink * nmtstp_link_get_typed (NMPlatform *platform, @@ -1210,6 +1230,8 @@ nmtstp_link_get (NMPlatform *platform, return nmtstp_link_get_typed (platform, ifindex, name, NM_LINK_TYPE_NONE); } +/*****************************************************************************/ + void nmtstp_link_del (gboolean external_command, int ifindex, @@ -1254,6 +1276,8 @@ nmtstp_link_del (gboolean external_command, } while (TRUE); } +/*****************************************************************************/ + void nmtstp_link_set_updown (gboolean external_command, int ifindex, diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 825611934c..3d2c6bfce1 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -38,16 +38,6 @@ /*********************************************************************************************/ -typedef struct { - gulong handler_id; - const char *name; - NMPlatformSignalChangeType change_type; - gint received_count; - GMainLoop *loop; - int ifindex; - const char *ifname; -} SignalData; - gboolean nmtstp_is_root_test (void); gboolean nmtstp_is_sysfs_writable (void); @@ -64,6 +54,16 @@ int nmtstp_namespace_get_fd_for_process (pid_t pid, const char *ns_name); /******************************************************************************/ +typedef struct { + gulong handler_id; + const char *name; + NMPlatformSignalChangeType change_type; + gint received_count; + GMainLoop *loop; + int ifindex; + const char *ifname; +} SignalData; + 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) #define add_signal_ifindex(name, change_type, callback, ifindex) add_signal_full (name, change_type, (GCallback) callback, ifindex, NULL) @@ -81,16 +81,15 @@ void _free_signal (const char *file, int line, const char *func, SignalData *dat #define ensure_no_signal(data) _ensure_no_signal(__FILE__, __LINE__, G_STRFUNC, data) #define free_signal(data) _free_signal(__FILE__, __LINE__, G_STRFUNC, data) -gboolean ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric); - -void _assert_ip4_route_exists (const char *file, guint line, const char *func, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric); -#define assert_ip4_route_exists(exists, ifname, network, plen, metric) _assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, exists, ifname, network, plen, metric) - void link_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlatformLink *received, NMPlatformSignalChangeType change_type, SignalData *data); +/*****************************************************************************/ + int nmtstp_run_command (const char *format, ...) __attribute__((__format__ (__printf__, 1, 2))); #define nmtstp_run_command_check(...) do { g_assert_cmpint (nmtstp_run_command (__VA_ARGS__), ==, 0); } while (0) +/*****************************************************************************/ + gboolean nmtstp_wait_for_signal (NMPlatform *platform, guint timeout_ms); gboolean nmtstp_wait_for_signal_until (NMPlatform *platform, gint64 until_ms); const NMPlatformLink *nmtstp_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms); @@ -99,9 +98,20 @@ const NMPlatformLink *nmtstp_wait_for_link_until (NMPlatform *platform, const ch const NMPlatformLink *nmtstp_assert_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms); const NMPlatformLink *nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms); +/*****************************************************************************/ + int nmtstp_run_command_check_external_global (void); gboolean nmtstp_run_command_check_external (int external_command); +/*****************************************************************************/ + +gboolean ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric); + +void _assert_ip4_route_exists (const char *file, guint line, const char *func, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric); +#define assert_ip4_route_exists(exists, ifname, network, plen, metric) _assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, exists, ifname, network, plen, metric) + +/*****************************************************************************/ + gboolean nmtstp_ip_address_check_lifetime (const NMPlatformIPAddress *addr, gint64 now, guint32 expected_lifetime, @@ -110,6 +120,7 @@ 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, @@ -137,6 +148,8 @@ void nmtstp_ip6_address_del (gboolean external_command, struct in6_addr address, int plen); +/*****************************************************************************/ + const NMPlatformLink *nmtstp_link_get_typed (NMPlatform *platform, int ifindex, const char *name, NMLinkType link_type); const NMPlatformLink *nmtstp_link_get (NMPlatform *platform, int ifindex, const char *name); From a314272d467db04def6c271447162348ad10fdbf Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 12:06:04 +0200 Subject: [PATCH 17/31] platform/tests: cleanup includes (cherry picked from commit 93c81a809d4c8eb6845e12f6c9b762e07cbf37e9) --- src/platform/tests/test-common.c | 2 -- src/platform/tests/test-common.h | 1 - 2 files changed, 3 deletions(-) diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 1a1d8b63dd..f07edac93d 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -27,8 +27,6 @@ #include "test-common.h" -#include "nm-test-utils.h" - #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 diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 3d2c6bfce1..25c8d56cf0 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -4,7 +4,6 @@ #include #include -#include "nm-default.h" #include "nm-platform.h" #include "nm-fake-platform.h" #include "nm-linux-platform.h" From 7d6b286e1fd218314bc5b5c0041f54753a569011 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Apr 2016 21:16:49 +0200 Subject: [PATCH 18/31] platform/tests/trivial: rename init_tests() and setup_tests() function Make it clear that they are nmtstp functions, i.e. they are found in the header "test-common.h". (cherry picked from commit 25d826ec49585953a5e4ec50995c864ed0bf257f) --- src/devices/tests/test-arping.c | 4 ++-- src/devices/tests/test-lldp.c | 4 ++-- src/platform/tests/test-address.c | 4 ++-- src/platform/tests/test-cleanup.c | 4 ++-- src/platform/tests/test-common.c | 4 ++-- src/platform/tests/test-common.h | 6 ++++-- src/platform/tests/test-link.c | 4 ++-- src/platform/tests/test-route.c | 4 ++-- src/tests/test-route-manager.c | 4 ++-- 9 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/devices/tests/test-arping.c b/src/devices/tests/test-arping.c index 72d28a7ac4..f22d85f0e4 100644 --- a/src/devices/tests/test-arping.c +++ b/src/devices/tests/test-arping.c @@ -126,13 +126,13 @@ fixture_teardown (test_fixture *fixture, gconstpointer user_data) } void -init_tests (int *argc, char ***argv) +_nmtstp_init_tests (int *argc, char ***argv) { nmtst_init_with_logging (argc, argv, NULL, "ALL"); } void -setup_tests (void) +_nmtstp_setup_tests (void) { g_test_add ("/arping/1", test_fixture, NULL, fixture_setup, test_arping_1, fixture_teardown); g_test_add ("/arping/2", test_fixture, NULL, fixture_setup, test_arping_2, fixture_teardown); diff --git a/src/devices/tests/test-lldp.c b/src/devices/tests/test-lldp.c index 1b7f536d03..bff85e6c94 100644 --- a/src/devices/tests/test-lldp.c +++ b/src/devices/tests/test-lldp.c @@ -435,13 +435,13 @@ _test_recv_fixture_teardown (TestRecvFixture *fixture, gconstpointer user_data) /*****************************************************************************/ void -init_tests (int *argc, char ***argv) +_nmtstp_init_tests (int *argc, char ***argv) { nmtst_init_assert_logging (argc, argv, "WARN", "ALL"); } void -setup_tests (void) +_nmtstp_setup_tests (void) { #define _TEST_ADD_RECV(testpath, testdata) \ g_test_add (testpath, TestRecvFixture, testdata, _test_recv_fixture_setup, test_recv, _test_recv_fixture_teardown) diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c index 15b00203a6..304361e255 100644 --- a/src/platform/tests/test-address.c +++ b/src/platform/tests/test-address.c @@ -355,7 +355,7 @@ test_ip4_address_peer_zero (void) /*****************************************************************************/ void -init_tests (int *argc, char ***argv) +_nmtstp_init_tests (int *argc, char ***argv) { nmtst_init_with_logging (argc, argv, NULL, "ALL"); } @@ -412,7 +412,7 @@ _g_test_add_func (const char *testpath, } void -setup_tests (void) +_nmtstp_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); diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index 4036daad10..3b52487a56 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -107,13 +107,13 @@ test_cleanup_internal (void) } void -init_tests (int *argc, char ***argv) +_nmtstp_init_tests (int *argc, char ***argv) { nmtst_init_with_logging (argc, argv, NULL, "ALL"); } void -setup_tests (void) +_nmtstp_setup_tests (void) { 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)); diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index f07edac93d..06daa07434 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -1535,7 +1535,7 @@ main (int argc, char **argv) int result; const char *program = *argv; - init_tests (&argc, &argv); + _nmtstp_init_tests (&argc, &argv); if ( nmtstp_is_root_test () && (geteuid () != 0 || getegid () != 0)) { @@ -1593,7 +1593,7 @@ main (int argc, char **argv) SETUP (); - setup_tests (); + _nmtstp_setup_tests (); result = g_test_run (); diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 25c8d56cf0..c7543a30af 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -182,6 +182,8 @@ void nmtstp_link_del (gboolean external_command, int ifindex, const char *name); -void init_tests (int *argc, char ***argv); -void setup_tests (void); +/*****************************************************************************/ + +void _nmtstp_init_tests (int *argc, char ***argv); +void _nmtstp_setup_tests (void); diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 9118198c64..f96cedc727 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -2293,13 +2293,13 @@ test_netns_bind_to_path (gpointer fixture, gconstpointer test_data) /*****************************************************************************/ void -init_tests (int *argc, char ***argv) +_nmtstp_init_tests (int *argc, char ***argv) { nmtst_init_with_logging (argc, argv, NULL, "ALL"); } void -setup_tests (void) +_nmtstp_setup_tests (void) { nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)); nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, SLAVE_NAME)); diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 09ffbb6899..ab1d578b15 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -329,13 +329,13 @@ test_ip4_zero_gateway (void) /*****************************************************************************/ void -init_tests (int *argc, char ***argv) +_nmtstp_init_tests (int *argc, char ***argv) { nmtst_init_with_logging (argc, argv, NULL, "ALL"); } void -setup_tests (void) +_nmtstp_setup_tests (void) { SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME); diff --git a/src/tests/test-route-manager.c b/src/tests/test-route-manager.c index b32775da6c..c753174d8e 100644 --- a/src/tests/test-route-manager.c +++ b/src/tests/test-route-manager.c @@ -906,13 +906,13 @@ fixture_teardown (test_fixture *fixture, gconstpointer user_data) /*****************************************************************************/ void -init_tests (int *argc, char ***argv) +_nmtstp_init_tests (int *argc, char ***argv) { nmtst_init_assert_logging (argc, argv, "WARN", "ALL"); } void -setup_tests (void) +_nmtstp_setup_tests (void) { g_test_add ("/route-manager/ip4", test_fixture, NULL, fixture_setup, test_ip4, fixture_teardown); g_test_add ("/route-manager/ip6", test_fixture, NULL, fixture_setup, test_ip6, fixture_teardown); From bd76c1e2d0fd4b4dd850bc5b8480e3ae978798e7 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 11:54:28 +0200 Subject: [PATCH 19/31] platform/tests/trivial: rename ip4_route_exists() functions to have nmtstp prefix (cherry picked from commit f8f8c516e0a17abe2305ad06fa289edfbb094fc6) --- src/platform/tests/test-common.c | 6 ++--- src/platform/tests/test-common.h | 6 ++--- src/platform/tests/test-route.c | 38 ++++++++++++++++---------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 06daa07434..cfe3b57360 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -185,7 +185,7 @@ link_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlat /*****************************************************************************/ gboolean -ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric) +nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric) { gs_free char *arg_network = NULL; const char *argv[] = { @@ -263,7 +263,7 @@ ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric) } void -_assert_ip4_route_exists (const char *file, guint line, const char *func, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric) +_nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric) { int ifindex; gboolean exists_checked; @@ -271,7 +271,7 @@ _assert_ip4_route_exists (const char *file, guint line, const char *func, gboole /* Check for existance of the route by spawning iproute2. Do this because platform * code might be entirely borked, but we expect ip-route to give a correct result. * If the ip command cannot be found, we accept this as success. */ - exists_checked = ip4_route_exists (ifname, network, plen, metric); + exists_checked = nmtstp_ip4_route_exists (ifname, network, plen, metric); if (exists_checked != -1 && !exists_checked != !exists) { g_error ("[%s:%u] %s(): We expect the ip4 route %s/%d metric %u %s, but it %s", file, line, func, diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index c7543a30af..9d4fe88225 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -104,10 +104,10 @@ gboolean nmtstp_run_command_check_external (int external_command); /*****************************************************************************/ -gboolean ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric); +gboolean nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric); -void _assert_ip4_route_exists (const char *file, guint line, const char *func, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric); -#define assert_ip4_route_exists(exists, ifname, network, plen, metric) _assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, exists, ifname, network, plen, metric) +void _nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric); +#define nmtstp_assert_ip4_route_exists(exists, ifname, network, plen, metric) _nmtstp_assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, exists, ifname, network, plen, metric) /*****************************************************************************/ diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index ab1d578b15..20c68118c2 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -82,50 +82,50 @@ test_ip4_route_metric0 (void) int mss = 1000; /* No routes initially */ - assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); /* add the first route */ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, metric, mss)); accept_signal (route_added); - assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); /* Deleting route with metric 0 does nothing */ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); ensure_no_signal (route_removed); - assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); /* add the second route */ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, 0, mss)); accept_signal (route_added); - assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, 0); - assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); /* Delete route with metric 0 */ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); accept_signal (route_removed); - assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); /* Delete route with metric 0 again (we expect nothing to happen) */ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); ensure_no_signal (route_removed); - assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); /* Delete the other route */ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); accept_signal (route_removed); - assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); free_signal (route_added); free_signal (route_changed); @@ -156,9 +156,9 @@ test_ip4_route (void) accept_signal (route_added); /* Add route */ - assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss)); - assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); accept_signal (route_added); /* Add route again */ @@ -166,9 +166,9 @@ test_ip4_route (void) accept_signals (route_changed, 0, 1); /* Add default route */ - assert_ip4_route_exists (FALSE, DEVICE_NAME, 0, 0, metric); + nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, 0, 0, metric); g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss)); - assert_ip4_route_exists (TRUE, DEVICE_NAME, 0, 0, metric); + nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, 0, 0, metric); accept_signal (route_added); /* Add default route again */ @@ -208,7 +208,7 @@ test_ip4_route (void) /* Remove route */ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); - assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); accept_signal (route_removed); /* Remove route again */ From df74df710e7e4f6ccd2a307fa6c5a7f197b92af2 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 12:35:36 +0200 Subject: [PATCH 20/31] platform/tests: change build order to first build test-common.c and platform core (cherry picked from commit 468501d0b009b0cec759017a663ff4ce5eb5dd0c) --- src/platform/tests/Makefile.am | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/platform/tests/Makefile.am b/src/platform/tests/Makefile.am index ebf20e15d6..5af4ce91d4 100644 --- a/src/platform/tests/Makefile.am +++ b/src/platform/tests/Makefile.am @@ -50,56 +50,56 @@ EXTRA_DIST = test-common.h monitor_SOURCES = monitor.c $(PLATFORM_SOURCES) monitor_LDADD = $(PLATFORM_LDADD) -test_link_fake_SOURCES = test-link.c $(TEST_SOURCES) +test_link_fake_SOURCES = $(TEST_SOURCES) test-link.c test_link_fake_CPPFLAGS = \ $(AM_CPPFLAGS) \ -DSETUP=nm_fake_platform_setup \ -DKERNEL_HACKS=0 test_link_fake_LDADD = $(PLATFORM_LDADD) -test_link_linux_SOURCES = test-link.c $(TEST_SOURCES) +test_link_linux_SOURCES = $(TEST_SOURCES) test-link.c test_link_linux_CPPFLAGS = \ $(AM_CPPFLAGS) \ -DSETUP=nm_linux_platform_setup \ -DKERNEL_HACKS=1 test_link_linux_LDADD = $(PLATFORM_LDADD) -test_address_fake_SOURCES = test-address.c $(TEST_SOURCES) +test_address_fake_SOURCES = $(TEST_SOURCES) test-address.c test_address_fake_CPPFLAGS = \ $(AM_CPPFLAGS) \ -DSETUP=nm_fake_platform_setup \ -DKERNEL_HACKS=0 test_address_fake_LDADD = $(PLATFORM_LDADD) -test_address_linux_SOURCES = test-address.c $(TEST_SOURCES) +test_address_linux_SOURCES = $(TEST_SOURCES) test-address.c test_address_linux_CPPFLAGS = \ $(AM_CPPFLAGS) \ -DSETUP=nm_linux_platform_setup \ -DKERNEL_HACKS=1 test_address_linux_LDADD = $(PLATFORM_LDADD) -test_route_fake_SOURCES = test-route.c $(TEST_SOURCES) +test_route_fake_SOURCES = $(TEST_SOURCES) test-route.c test_route_fake_CPPFLAGS = \ $(AM_CPPFLAGS) \ -DSETUP=nm_fake_platform_setup \ -DKERNEL_HACKS=0 test_route_fake_LDADD = $(PLATFORM_LDADD) -test_route_linux_SOURCES = test-route.c $(TEST_SOURCES) +test_route_linux_SOURCES = $(TEST_SOURCES) test-route.c test_route_linux_CPPFLAGS = \ $(AM_CPPFLAGS) \ -DSETUP=nm_linux_platform_setup \ -DKERNEL_HACKS=1 test_route_linux_LDADD = $(PLATFORM_LDADD) -test_cleanup_fake_SOURCES = test-cleanup.c $(TEST_SOURCES) +test_cleanup_fake_SOURCES = $(TEST_SOURCES) test-cleanup.c test_cleanup_fake_CPPFLAGS = \ $(AM_CPPFLAGS) \ -DSETUP=nm_fake_platform_setup \ -DKERNEL_HACKS=0 test_cleanup_fake_LDADD = $(PLATFORM_LDADD) -test_cleanup_linux_SOURCES = test-cleanup.c $(TEST_SOURCES) +test_cleanup_linux_SOURCES = $(TEST_SOURCES) test-cleanup.c test_cleanup_linux_CPPFLAGS = \ $(AM_CPPFLAGS) \ -DSETUP=nm_linux_platform_setup \ From a79a94fcfd77db59734491509d03e29cada8450e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 12:32:00 +0200 Subject: [PATCH 21/31] platform/tests: add @platform argument to nmtstp functions This allows tests to use these functions on a different platform instance then on the singleton. The change makes the argument list longer, which is unfortunate. On the other hand, it makes those functions more useful in general. You can't have it all. Also, they now follow the pattern of most functions in NM where the type is a singleton: you always pass the singleton to the function, although in the usual case there is only one singleton instance. This allows to use the function also on the non-singleton instance. (cherry picked from commit c4151ebb5bae48f37737126b35116ea97fd93428) --- src/devices/tests/test-arping.c | 2 +- src/platform/tests/test-address.c | 40 +++--- src/platform/tests/test-common.c | 223 +++++++++++++++++++----------- src/platform/tests/test-common.h | 43 ++++-- src/platform/tests/test-link.c | 52 +++---- src/platform/tests/test-route.c | 38 ++--- 6 files changed, 233 insertions(+), 165 deletions(-) diff --git a/src/devices/tests/test-arping.c b/src/devices/tests/test-arping.c index f22d85f0e4..244d0715ec 100644 --- a/src/devices/tests/test-arping.c +++ b/src/devices/tests/test-arping.c @@ -79,7 +79,7 @@ test_arping_common (test_fixture *fixture, TestInfo *info) g_assert (nm_arping_manager_add_address (manager, info->addresses[i])); for (i = 0; info->peer_addresses[i]; i++) { - nmtstp_ip4_address_add (FALSE, fixture->ifindex1, info->peer_addresses[i], + nmtstp_ip4_address_add (NULL, FALSE, fixture->ifindex1, info->peer_addresses[i], 24, 0, 3600, 1800, 0, NULL); } diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c index 304361e255..05a1444814 100644 --- a/src/platform/tests/test-address.c +++ b/src/platform/tests/test-address.c @@ -94,12 +94,12 @@ test_ip4_address_general (void) /* Add address */ g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); - nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); + nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); accept_signal (address_added); /* Add address again (aka update) */ - nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr, lifetime + 100, preferred + 50, 0, NULL); + nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr, lifetime + 100, preferred + 50, 0, NULL); accept_signals (address_changed, 0, 1); /* Test address listing */ @@ -114,12 +114,12 @@ test_ip4_address_general (void) g_array_unref (addresses); /* Remove address */ - nmtstp_ip4_address_del (EX, ifindex, addr, IP4_PLEN, addr); + nmtstp_ip4_address_del (NULL, EX, ifindex, addr, IP4_PLEN, addr); g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); accept_signal (address_removed); /* Remove address again */ - nmtstp_ip4_address_del (EX, ifindex, addr, IP4_PLEN, addr); + nmtstp_ip4_address_del (NULL, EX, ifindex, addr, IP4_PLEN, addr); free_signal (address_added); free_signal (address_changed); @@ -144,12 +144,12 @@ test_ip6_address_general (void) /* Add address */ 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); + nmtstp_ip6_address_add (NULL, 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) */ - nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags); + nmtstp_ip6_address_add (NULL, EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags); accept_signals (address_changed, 0, 1); /* Test address listing */ @@ -163,12 +163,12 @@ test_ip6_address_general (void) g_array_unref (addresses); /* Remove address */ - nmtstp_ip6_address_del (EX, ifindex, addr, IP6_PLEN); + nmtstp_ip6_address_del (NULL, 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 */ - nmtstp_ip6_address_del (EX, ifindex, addr, IP6_PLEN); + nmtstp_ip6_address_del (NULL, EX, ifindex, addr, IP6_PLEN); /* ensure not pending signal. */ accept_signals (address_changed, 0, 1); @@ -197,15 +197,15 @@ test_ip4_address_general_2 (void) g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, DEVICE_IFINDEX, NULL)); /* Add/delete notification */ - nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); + nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); accept_signal (address_added); g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); - nmtstp_ip4_address_del (EX, ifindex, addr, IP4_PLEN, addr); + nmtstp_ip4_address_del (NULL, EX, ifindex, addr, IP4_PLEN, addr); accept_signal (address_removed); g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); /* Add/delete conflict */ - nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); + nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); accept_signal (address_added); @@ -227,20 +227,20 @@ test_ip6_address_general_2 (void) inet_pton (AF_INET6, IP6_ADDRESS, &addr); /* Add/delete notification */ - nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, 0); + nmtstp_ip6_address_add (NULL, 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)); - nmtstp_ip6_address_del (EX, ifindex, addr, IP6_PLEN); + nmtstp_ip6_address_del (NULL, 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 */ - nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, 0); + nmtstp_ip6_address_add (NULL, 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)); - nmtstp_ip6_address_add (EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags); + nmtstp_ip6_address_add (NULL, 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)); @@ -273,7 +273,7 @@ test_ip4_address_peer (void) accept_signals (address_added, 0, G_MAXINT); /* Add/delete notification */ - nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr_peer, lifetime, preferred, 0, NULL); + nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr_peer, lifetime, preferred, 0, NULL); accept_signal (address_added); a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer); g_assert (a); @@ -281,7 +281,7 @@ test_ip4_address_peer (void) nmtstp_ip_address_assert_lifetime ((NMPlatformIPAddress *) a, -1, lifetime, preferred); - nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr_peer2, lifetime, preferred, 0, NULL); + nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr_peer2, lifetime, preferred, 0, NULL); accept_signal (address_added); g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer)); a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2); @@ -290,7 +290,7 @@ test_ip4_address_peer (void) 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); + nmtstp_ip4_address_del (NULL, 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)); @@ -328,7 +328,7 @@ test_ip4_address_peer_zero (void) for (i = 0; i < G_N_ELEMENTS (peers); i++) { g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, plen, r_peers[i])); - nmtstp_ip4_address_add (EX, ifindex, addr, plen, r_peers[i], lifetime, preferred, 0, label); + nmtstp_ip4_address_add (NULL, EX, ifindex, addr, plen, r_peers[i], lifetime, preferred, 0, label); addrs = nm_platform_ip4_address_get_all (NM_PLATFORM_GET, ifindex); g_assert (addrs); @@ -343,7 +343,7 @@ test_ip4_address_peer_zero (void) for (i = 0; i < G_N_ELEMENTS (peers); i++) { g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, plen, r_peers[i])); - nmtstp_ip4_address_del (EX, ifindex, addr, plen, r_peers[i]); + nmtstp_ip4_address_del (NULL, EX, ifindex, addr, plen, r_peers[i]); addrs = nm_platform_ip4_address_get_all (NM_PLATFORM_GET, ifindex); g_assert (addrs); diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index cfe3b57360..8fcafd64b5 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -47,6 +47,18 @@ nmtstp_is_sysfs_writable (void) || (access ("/sys/devices", W_OK) == 0); } +static void +_init_platform (NMPlatform **platform, gboolean external_command) +{ + g_assert (platform); + if (!*platform) + *platform = NM_PLATFORM_GET; + g_assert (NM_IS_PLATFORM (*platform)); + + if (external_command) + g_assert (NM_IS_LINUX_PLATFORM (*platform)); +} + /*****************************************************************************/ SignalData * @@ -209,7 +221,7 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 g_assert (!strstr (ifname, " metric ")); g_assert (plen >= 0 && plen <= 32); - if (!NM_IS_LINUX_PLATFORM (nm_platform_get ())) { + if (!nmtstp_is_root_test ()) { /* If we don't test against linux-platform, we don't actually configure any * routes in the system. */ return -1; @@ -263,11 +275,13 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 } void -_nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric) +_nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric) { int ifindex; gboolean exists_checked; + _init_platform (&platform, FALSE); + /* Check for existance of the route by spawning iproute2. Do this because platform * code might be entirely borked, but we expect ip-route to give a correct result. * If the ip command cannot be found, we accept this as success. */ @@ -280,9 +294,9 @@ _nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, exists ? "doesn't" : "does"); } - ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, ifname); + ifindex = nm_platform_link_get_ifindex (platform, ifname); g_assert (ifindex > 0); - if (!nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric) != !exists) { + if (!nm_platform_ip4_route_get (platform, ifindex, network, plen, metric) != !exists) { g_error ("[%s:%u] %s(): The ip4 route %s/%d metric %u %s, but platform thinks %s", file, line, func, nm_utils_inet4_ntop (network, NULL), plen, metric, @@ -349,8 +363,7 @@ nmtstp_wait_for_signal (NMPlatform *platform, guint timeout_ms) WaitForSignalData data = { 0 }; gulong id_link, id_ip4_address, id_ip6_address, id_ip4_route, id_ip6_route; - if (!platform) - platform = NM_PLATFORM_GET; + _init_platform (&platform, FALSE); data.loop = g_main_loop_new (NULL, FALSE); @@ -407,10 +420,12 @@ nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType const NMPlatformLink *plink; gint64 now; + _init_platform (&platform, FALSE); + while (TRUE) { now = nm_utils_get_monotonic_timestamp_ms (); - plink = nm_platform_link_get_by_ifname (platform ?: NM_PLATFORM_GET, ifname); + plink = nm_platform_link_get_by_ifname (platform, ifname); if ( plink && (expected_link_type == NM_LINK_TYPE_NONE || plink->type == expected_link_type)) return plink; @@ -569,7 +584,8 @@ nmtstp_ip_address_assert_lifetime (const NMPlatformIPAddress *addr, /*****************************************************************************/ static void -_ip_address_add (gboolean external_command, +_ip_address_add (NMPlatform *platform, + gboolean external_command, gboolean is_v4, int ifindex, const NMIPAddr *address, @@ -584,6 +600,8 @@ _ip_address_add (gboolean external_command, external_command = nmtstp_run_command_check_external (external_command); + _init_platform (&platform, external_command); + if (external_command) { const char *ifname; gs_free char *s_valid = NULL; @@ -591,7 +609,7 @@ _ip_address_add (gboolean external_command, 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); + ifname = nm_platform_link_get_name (platform, ifindex); g_assert (ifname); if (lifetime != NM_PLATFORM_LIFETIME_PERMANENT) @@ -640,7 +658,7 @@ _ip_address_add (gboolean external_command, gboolean success; if (is_v4) { - success = nm_platform_ip4_address_add (NM_PLATFORM_GET, + success = nm_platform_ip4_address_add (platform, ifindex, address->addr4, plen, @@ -651,7 +669,7 @@ _ip_address_add (gboolean external_command, label); } else { g_assert (label == NULL); - success = nm_platform_ip6_address_add (NM_PLATFORM_GET, + success = nm_platform_ip6_address_add (platform, ifindex, address->addr6, plen, @@ -668,14 +686,14 @@ _ip_address_add (gboolean external_command, do { if (external_command) - nm_platform_process_events (NM_PLATFORM_GET); + nm_platform_process_events (platform); /* 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); + a = nm_platform_ip4_address_get (platform, ifindex, address->addr4, plen, peer_address->addr4); if ( a && a->peer_address == peer_address->addr4 && nmtstp_ip_address_check_lifetime ((NMPlatformIPAddress*) a, -1, lifetime, preferred) @@ -687,7 +705,7 @@ _ip_address_add (gboolean external_command, g_assert (label == NULL); g_assert (flags == 0); - a = nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, address->addr6, plen); + a = nm_platform_ip6_address_get (platform, 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)) @@ -700,12 +718,13 @@ _ip_address_add (gboolean external_command, /* for internal command, we expect not to reach this line.*/ g_assert (external_command); - g_assert (nmtstp_wait_for_signal_until (NM_PLATFORM_GET, end_time)); + g_assert (nmtstp_wait_for_signal_until (platform, end_time)); } while (TRUE); } void -nmtstp_ip4_address_add (gboolean external_command, +nmtstp_ip4_address_add (NMPlatform *platform, + gboolean external_command, int ifindex, in_addr_t address, int plen, @@ -715,7 +734,8 @@ nmtstp_ip4_address_add (gboolean external_command, guint32 flags, const char *label) { - _ip_address_add (external_command, + _ip_address_add (platform, + external_command, TRUE, ifindex, (NMIPAddr *) &address, @@ -728,7 +748,8 @@ nmtstp_ip4_address_add (gboolean external_command, } void -nmtstp_ip6_address_add (gboolean external_command, +nmtstp_ip6_address_add (NMPlatform *platform, + gboolean external_command, int ifindex, struct in6_addr address, int plen, @@ -737,7 +758,8 @@ nmtstp_ip6_address_add (gboolean external_command, guint32 preferred, guint32 flags) { - _ip_address_add (external_command, + _ip_address_add (platform, + external_command, FALSE, ifindex, (NMIPAddr *) &address, @@ -752,7 +774,8 @@ nmtstp_ip6_address_add (gboolean external_command, /*****************************************************************************/ static void -_ip_address_del (gboolean external_command, +_ip_address_del (NMPlatform *platform, + gboolean external_command, gboolean is_v4, int ifindex, const NMIPAddr *address, @@ -763,20 +786,22 @@ _ip_address_del (gboolean external_command, external_command = nmtstp_run_command_check_external (external_command); + _init_platform (&platform, 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); + ifname = nm_platform_link_get_name (platform, ifindex); g_assert (ifname); /* 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); + had_address = !!nm_platform_ip4_address_get (platform, ifindex, address->addr4, plen, peer_address->addr4); else - had_address = !!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, address->addr6, plen); + had_address = !!nm_platform_ip6_address_get (platform, ifindex, address->addr6, plen); if (is_v4) { success = nmtstp_run_command ("ip address delete %s%s%s/%d dev %s", @@ -797,14 +822,14 @@ _ip_address_del (gboolean external_command, gboolean success; if (is_v4) { - success = nm_platform_ip4_address_delete (NM_PLATFORM_GET, + success = nm_platform_ip4_address_delete (platform, ifindex, address->addr4, plen, peer_address->addr4); } else { g_assert (!peer_address); - success = nm_platform_ip6_address_delete (NM_PLATFORM_GET, + success = nm_platform_ip6_address_delete (platform, ifindex, address->addr6, plen); @@ -816,19 +841,19 @@ _ip_address_del (gboolean external_command, end_time = nm_utils_get_monotonic_timestamp_ms () + 250; do { if (external_command) - nm_platform_process_events (NM_PLATFORM_GET); + nm_platform_process_events (platform); /* 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); + a = nm_platform_ip4_address_get (platform, 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); + a = nm_platform_ip6_address_get (platform, ifindex, address->addr6, plen); if (!a) break; } @@ -836,18 +861,20 @@ _ip_address_del (gboolean external_command, /* for internal command, we expect not to reach this line.*/ g_assert (external_command); - g_assert (nmtstp_wait_for_signal_until (NM_PLATFORM_GET, end_time)); + g_assert (nmtstp_wait_for_signal_until (platform, end_time)); } while (TRUE); } void -nmtstp_ip4_address_del (gboolean external_command, +nmtstp_ip4_address_del (NMPlatform *platform, + gboolean external_command, int ifindex, in_addr_t address, int plen, in_addr_t peer_address) { - _ip_address_del (external_command, + _ip_address_del (platform, + external_command, TRUE, ifindex, (NMIPAddr *) &address, @@ -856,12 +883,14 @@ nmtstp_ip4_address_del (gboolean external_command, } void -nmtstp_ip6_address_del (gboolean external_command, +nmtstp_ip6_address_del (NMPlatform *platform, + gboolean external_command, int ifindex, struct in6_addr address, int plen) { - _ip_address_del (external_command, + _ip_address_del (platform, + external_command, FALSE, ifindex, (NMIPAddr *) &address, @@ -885,7 +914,8 @@ nmtstp_ip6_address_del (gboolean external_command, } G_STMT_END const NMPlatformLink * -nmtstp_link_dummy_add (gboolean external_command, +nmtstp_link_dummy_add (NMPlatform *platform, + gboolean external_command, const char *name) { const NMPlatformLink *pllink = NULL; @@ -895,21 +925,24 @@ nmtstp_link_dummy_add (gboolean external_command, external_command = nmtstp_run_command_check_external (external_command); + _init_platform (&platform, external_command); + if (external_command) { success = !nmtstp_run_command ("ip link add %s type dummy", name); if (success) - pllink = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, name, NM_LINK_TYPE_DUMMY, 100); + pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_DUMMY, 100); } else - success = nm_platform_link_dummy_add (NM_PLATFORM_GET, name, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = nm_platform_link_dummy_add (platform, name, &pllink) == NM_PLATFORM_ERROR_SUCCESS; g_assert (success); - _assert_pllink (NM_PLATFORM_GET, success, pllink, name, NM_LINK_TYPE_DUMMY); + _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_DUMMY); return pllink; } const NMPlatformLink * -nmtstp_link_gre_add (gboolean external_command, +nmtstp_link_gre_add (NMPlatform *platform, + gboolean external_command, const char *name, const NMPlatformLnkGre *lnk) { @@ -921,11 +954,13 @@ nmtstp_link_gre_add (gboolean external_command, external_command = nmtstp_run_command_check_external (external_command); + _init_platform (&platform, external_command); + if (external_command) { gs_free char *dev = NULL; if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (NM_PLATFORM_GET, lnk->parent_ifindex)); + dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); success = !nmtstp_run_command ("ip tunnel add %s mode gre %s local %s remote %s ttl %u tos %02x %s", name, @@ -936,17 +971,18 @@ nmtstp_link_gre_add (gboolean external_command, lnk->tos, lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); if (success) - pllink = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, name, NM_LINK_TYPE_GRE, 100); + pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_GRE, 100); } else - success = nm_platform_link_gre_add (NM_PLATFORM_GET, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = nm_platform_link_gre_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; - _assert_pllink (NM_PLATFORM_GET, success, pllink, name, NM_LINK_TYPE_GRE); + _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_GRE); return pllink; } const NMPlatformLink * -nmtstp_link_ip6tnl_add (gboolean external_command, +nmtstp_link_ip6tnl_add (NMPlatform *platform, + gboolean external_command, const char *name, const NMPlatformLnkIp6Tnl *lnk) { @@ -958,12 +994,14 @@ nmtstp_link_ip6tnl_add (gboolean external_command, external_command = nmtstp_run_command_check_external (external_command); + _init_platform (&platform, external_command); + if (external_command) { gs_free char *dev = NULL; const char *mode; if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (NM_PLATFORM_GET, lnk->parent_ifindex)); + dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); switch (lnk->proto) { case IPPROTO_IPIP: @@ -987,17 +1025,18 @@ nmtstp_link_ip6tnl_add (gboolean external_command, lnk->encap_limit, lnk->flow_label); if (success) - pllink = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, name, NM_LINK_TYPE_IP6TNL, 100); + pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_IP6TNL, 100); } else - success = nm_platform_link_ip6tnl_add (NM_PLATFORM_GET, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = nm_platform_link_ip6tnl_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; - _assert_pllink (NM_PLATFORM_GET, success, pllink, name, NM_LINK_TYPE_IP6TNL); + _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_IP6TNL); return pllink; } const NMPlatformLink * -nmtstp_link_ipip_add (gboolean external_command, +nmtstp_link_ipip_add (NMPlatform *platform, + gboolean external_command, const char *name, const NMPlatformLnkIpIp *lnk) { @@ -1009,11 +1048,13 @@ nmtstp_link_ipip_add (gboolean external_command, external_command = nmtstp_run_command_check_external (external_command); + _init_platform (&platform, external_command); + if (external_command) { gs_free char *dev = NULL; if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (NM_PLATFORM_GET, lnk->parent_ifindex)); + dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); success = !nmtstp_run_command ("ip tunnel add %s mode ipip %s local %s remote %s ttl %u tos %02x %s", name, @@ -1024,17 +1065,18 @@ nmtstp_link_ipip_add (gboolean external_command, lnk->tos, lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); if (success) - pllink = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, name, NM_LINK_TYPE_IPIP, 100); + pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_IPIP, 100); } else - success = nm_platform_link_ipip_add (NM_PLATFORM_GET, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = nm_platform_link_ipip_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; - _assert_pllink (NM_PLATFORM_GET, success, pllink, name, NM_LINK_TYPE_IPIP); + _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_IPIP); return pllink; } const NMPlatformLink * -nmtstp_link_macvlan_add (gboolean external_command, +nmtstp_link_macvlan_add (NMPlatform *platform, + gboolean external_command, const char *name, int parent, const NMPlatformLnkMacvlan *lnk) @@ -1047,6 +1089,8 @@ nmtstp_link_macvlan_add (gboolean external_command, external_command = nmtstp_run_command_check_external (external_command); + _init_platform (&platform, external_command); + link_type = lnk->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN; if (external_command) { @@ -1058,7 +1102,7 @@ nmtstp_link_macvlan_add (gboolean external_command, [MACVLAN_MODE_PASSTHRU] = "passthru", }; - dev = nm_platform_link_get_name (NM_PLATFORM_GET, parent); + dev = nm_platform_link_get_name (platform, parent); g_assert (dev); g_assert_cmpint (lnk->mode, <, G_N_ELEMENTS (modes)); @@ -1069,17 +1113,18 @@ nmtstp_link_macvlan_add (gboolean external_command, modes[lnk->mode], lnk->no_promisc ? "nopromisc" : ""); if (success) - pllink = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, name, link_type, 100); + pllink = nmtstp_assert_wait_for_link (platform, name, link_type, 100); } else - success = nm_platform_link_macvlan_add (NM_PLATFORM_GET, name, parent, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = nm_platform_link_macvlan_add (platform, name, parent, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; - _assert_pllink (NM_PLATFORM_GET, success, pllink, name, link_type); + _assert_pllink (platform, success, pllink, name, link_type); return pllink; } const NMPlatformLink * -nmtstp_link_sit_add (gboolean external_command, +nmtstp_link_sit_add (NMPlatform *platform, + gboolean external_command, const char *name, const NMPlatformLnkSit *lnk) { @@ -1091,13 +1136,15 @@ nmtstp_link_sit_add (gboolean external_command, external_command = nmtstp_run_command_check_external (external_command); + _init_platform (&platform, external_command); + if (external_command) { const char *dev = ""; if (lnk->parent_ifindex) { const char *parent_name; - parent_name = nm_platform_link_get_name (NM_PLATFORM_GET, lnk->parent_ifindex); + parent_name = nm_platform_link_get_name (platform, lnk->parent_ifindex); g_assert (parent_name); dev = nm_sprintf_bufa (100, " dev %s", parent_name); } @@ -1111,17 +1158,18 @@ nmtstp_link_sit_add (gboolean external_command, lnk->tos, lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); if (success) - pllink = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, name, NM_LINK_TYPE_SIT, 100); + pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_SIT, 100); } else - success = nm_platform_link_sit_add (NM_PLATFORM_GET, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = nm_platform_link_sit_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; - _assert_pllink (NM_PLATFORM_GET, success, pllink, name, NM_LINK_TYPE_SIT); + _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_SIT); return pllink; } const NMPlatformLink * -nmtstp_link_vxlan_add (gboolean external_command, +nmtstp_link_vxlan_add (NMPlatform *platform, + gboolean external_command, const char *name, const NMPlatformLnkVxlan *lnk) { @@ -1133,12 +1181,14 @@ nmtstp_link_vxlan_add (gboolean external_command, external_command = nmtstp_run_command_check_external (external_command); + _init_platform (&platform, external_command); + if (external_command) { gs_free char *dev = NULL; gs_free char *local = NULL, *remote = NULL; if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (NM_PLATFORM_GET, lnk->parent_ifindex)); + dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); if (lnk->local) local = g_strdup_printf ("%s", nm_utils_inet4_ntop (lnk->local, NULL)); @@ -1164,12 +1214,12 @@ nmtstp_link_vxlan_add (gboolean external_command, /* Older versions of iproute2 don't support adding vxlan devices. * On failure, fallback to using platform code. */ if (err == 0) - pllink = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, name, NM_LINK_TYPE_VXLAN, 100); + pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_VXLAN, 100); else _LOGI ("Adding vxlan device via iproute2 failed. Assume iproute2 is not up to the task."); } if (!pllink) { - plerr = nm_platform_link_vxlan_add (NM_PLATFORM_GET, name, lnk, &pllink); + plerr = nm_platform_link_vxlan_add (platform, name, lnk, &pllink); g_assert_cmpint (plerr, ==, NM_PLATFORM_ERROR_SUCCESS); g_assert (pllink); } @@ -1189,8 +1239,7 @@ nmtstp_link_get_typed (NMPlatform *platform, { const NMPlatformLink *pllink = NULL; - if (!platform) - platform = NM_PLATFORM_GET; + _init_platform (&platform, FALSE); if (ifindex > 0) { pllink = nm_platform_link_get (platform, ifindex); @@ -1231,7 +1280,8 @@ nmtstp_link_get (NMPlatform *platform, /*****************************************************************************/ void -nmtstp_link_del (gboolean external_command, +nmtstp_link_del (NMPlatform *platform, + gboolean external_command, int ifindex, const char *name) { @@ -1240,19 +1290,21 @@ nmtstp_link_del (gboolean external_command, gboolean success; gs_free char *name_copy = NULL; - pllink = nmtstp_link_get (NM_PLATFORM_GET, ifindex, name); + external_command = nmtstp_run_command_check_external (external_command); + + _init_platform (&platform, external_command); + + pllink = nmtstp_link_get (platform, ifindex, name); g_assert (pllink); name = name_copy = g_strdup (pllink->name); ifindex = pllink->ifindex; - external_command = nmtstp_run_command_check_external (external_command); - if (external_command) { nmtstp_run_command_check ("ip link delete %s", name); } else { - success = nm_platform_link_delete (NM_PLATFORM_GET, ifindex); + success = nm_platform_link_delete (platform, ifindex); g_assert (success); } @@ -1260,24 +1312,25 @@ nmtstp_link_del (gboolean external_command, end_time = nm_utils_get_monotonic_timestamp_ms () + 250; do { if (external_command) - nm_platform_process_events (NM_PLATFORM_GET); + nm_platform_process_events (platform); - if (!nm_platform_link_get (NM_PLATFORM_GET, ifindex)) { - g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, name)); + if (!nm_platform_link_get (platform, ifindex)) { + g_assert (!nm_platform_link_get_by_ifname (platform, name)); break; } /* for internal command, we expect not to reach this line.*/ g_assert (external_command); - g_assert (nmtstp_wait_for_signal_until (NM_PLATFORM_GET, end_time)); + g_assert (nmtstp_wait_for_signal_until (platform, end_time)); } while (TRUE); } /*****************************************************************************/ void -nmtstp_link_set_updown (gboolean external_command, +nmtstp_link_set_updown (NMPlatform *platform, + gboolean external_command, int ifindex, gboolean up) { @@ -1286,10 +1339,12 @@ nmtstp_link_set_updown (gboolean external_command, external_command = nmtstp_run_command_check_external (external_command); + _init_platform (&platform, external_command); + if (external_command) { const char *ifname; - ifname = nm_platform_link_get_name (NM_PLATFORM_GET, ifindex); + ifname = nm_platform_link_get_name (platform, ifindex); g_assert (ifname); nmtstp_run_command_check ("ip link set %s %s", @@ -1297,19 +1352,19 @@ nmtstp_link_set_updown (gboolean external_command, up ? "up" : "down"); } else { if (up) - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL)); + g_assert (nm_platform_link_set_up (platform, ifindex, NULL)); else - g_assert (nm_platform_link_set_down (NM_PLATFORM_GET, ifindex)); + g_assert (nm_platform_link_set_down (platform, ifindex)); } /* 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); + nm_platform_process_events (platform); /* let's wait until we see the address as we added it. */ - plink = nm_platform_link_get (NM_PLATFORM_GET, ifindex); + plink = nm_platform_link_get (platform, ifindex); g_assert (plink); if (NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP) == !!up) @@ -1318,7 +1373,7 @@ nmtstp_link_set_updown (gboolean external_command, /* for internal command, we expect not to reach this line.*/ g_assert (external_command); - g_assert (nmtstp_wait_for_signal_until (NM_PLATFORM_GET, end_time)); + g_assert (nmtstp_wait_for_signal_until (platform, end_time)); } while (TRUE); } diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 9d4fe88225..4a75281eaa 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -106,8 +106,8 @@ gboolean nmtstp_run_command_check_external (int external_command); gboolean nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric); -void _nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric); -#define nmtstp_assert_ip4_route_exists(exists, ifname, network, plen, metric) _nmtstp_assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, exists, ifname, network, plen, metric) +void _nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric); +#define nmtstp_assert_ip4_route_exists(platform, exists, ifname, network, plen, metric) _nmtstp_assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, platform, exists, ifname, network, plen, metric) /*****************************************************************************/ @@ -120,7 +120,8 @@ void nmtstp_ip_address_assert_lifetime (const NMPlatformIPAddress *addr, guint32 expected_lifetime, guint32 expected_preferred); -void nmtstp_ip4_address_add (gboolean external_command, +void nmtstp_ip4_address_add (NMPlatform *platform, + gboolean external_command, int ifindex, in_addr_t address, int plen, @@ -129,7 +130,8 @@ void nmtstp_ip4_address_add (gboolean external_command, guint32 preferred, guint32 flags, const char *label); -void nmtstp_ip6_address_add (gboolean external_command, +void nmtstp_ip6_address_add (NMPlatform *platform, + gboolean external_command, int ifindex, struct in6_addr address, int plen, @@ -137,12 +139,14 @@ void nmtstp_ip6_address_add (gboolean external_command, guint32 lifetime, guint32 preferred, guint32 flags); -void nmtstp_ip4_address_del (gboolean external_command, +void nmtstp_ip4_address_del (NMPlatform *platform, + gboolean external_command, int ifindex, in_addr_t address, int plen, in_addr_t peer_address); -void nmtstp_ip6_address_del (gboolean external_command, +void nmtstp_ip6_address_del (NMPlatform *platform, + gboolean external_command, int ifindex, struct in6_addr address, int plen); @@ -152,33 +156,42 @@ void nmtstp_ip6_address_del (gboolean external_command, const NMPlatformLink *nmtstp_link_get_typed (NMPlatform *platform, int ifindex, const char *name, NMLinkType link_type); const NMPlatformLink *nmtstp_link_get (NMPlatform *platform, int ifindex, const char *name); -void nmtstp_link_set_updown (gboolean external_command, +void nmtstp_link_set_updown (NMPlatform *platform, + gboolean external_command, int ifindex, gboolean up); -const NMPlatformLink *nmtstp_link_dummy_add (gboolean external_command, +const NMPlatformLink *nmtstp_link_dummy_add (NMPlatform *platform, + gboolean external_command, const char *name); -const NMPlatformLink *nmtstp_link_gre_add (gboolean external_command, +const NMPlatformLink *nmtstp_link_gre_add (NMPlatform *platform, + gboolean external_command, const char *name, const NMPlatformLnkGre *lnk); -const NMPlatformLink *nmtstp_link_ip6tnl_add (gboolean external_command, +const NMPlatformLink *nmtstp_link_ip6tnl_add (NMPlatform *platform, + gboolean external_command, const char *name, const NMPlatformLnkIp6Tnl *lnk); -const NMPlatformLink *nmtstp_link_ipip_add (gboolean external_command, +const NMPlatformLink *nmtstp_link_ipip_add (NMPlatform *platform, + gboolean external_command, const char *name, const NMPlatformLnkIpIp *lnk); -const NMPlatformLink *nmtstp_link_macvlan_add (gboolean external_command, +const NMPlatformLink *nmtstp_link_macvlan_add (NMPlatform *platform, + gboolean external_command, const char *name, int parent, const NMPlatformLnkMacvlan *lnk); -const NMPlatformLink *nmtstp_link_sit_add (gboolean external_command, +const NMPlatformLink *nmtstp_link_sit_add (NMPlatform *platform, + gboolean external_command, const char *name, const NMPlatformLnkSit *lnk); -const NMPlatformLink *nmtstp_link_vxlan_add (gboolean external_command, +const NMPlatformLink *nmtstp_link_vxlan_add (NMPlatform *platform, + gboolean external_command, const char *name, const NMPlatformLnkVxlan *lnk); -void nmtstp_link_del (gboolean external_command, +void nmtstp_link_del (NMPlatform *platform, + gboolean external_command, int ifindex, const char *name); diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index f96cedc727..9d548aabdb 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -343,7 +343,7 @@ test_slave (int master, int type, SignalData *master_changed) ensure_no_signal (link_added); ensure_no_signal (link_changed); ensure_no_signal (link_removed); - nmtstp_link_del (-1, ifindex, NULL); + nmtstp_link_del (NULL, -1, ifindex, NULL); accept_signals (master_changed, 0, 1); accept_signals (link_changed, 0, 1); accept_signal (link_removed); @@ -437,7 +437,7 @@ test_software (NMLinkType link_type, const char *link_typename) free_signal (link_changed); /* Delete */ - nmtstp_link_del (-1, ifindex, DEVICE_NAME); + nmtstp_link_del (NULL, -1, ifindex, DEVICE_NAME); accept_signal (link_removed); /* Delete again */ @@ -448,7 +448,7 @@ test_software (NMLinkType link_type, const char *link_typename) if (link_type == NM_LINK_TYPE_VLAN) { SignalData *link_removed_parent = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, vlan_parent); - nmtstp_link_del (-1, vlan_parent, NULL); + nmtstp_link_del (NULL, -1, vlan_parent, NULL); accept_signal (link_removed_parent); free_signal (link_removed_parent); } @@ -531,7 +531,7 @@ test_bridge_addr (void) g_assert_cmpint (plink->addr.len, ==, sizeof (addr)); g_assert (!memcmp (plink->addr.data, addr, sizeof (addr))); - nmtstp_link_del (-1, link.ifindex, link.name); + nmtstp_link_del (NULL, -1, link.ifindex, link.name); } /*****************************************************************************/ @@ -606,7 +606,7 @@ test_internal (void) accept_signal (link_changed); /* Delete device */ - nmtstp_link_del (-1, ifindex, DEVICE_NAME); + nmtstp_link_del (NULL, -1, ifindex, DEVICE_NAME); accept_signal (link_removed); /* Try to delete again */ @@ -717,7 +717,7 @@ test_software_detect (gconstpointer user_data) gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip_gre", NULL) != 0; } - if (!nmtstp_link_gre_add (ext, DEVICE_NAME, &lnk_gre)) { + if (!nmtstp_link_gre_add (NULL, ext, DEVICE_NAME, &lnk_gre)) { if (gracefully_skip) { g_test_skip ("Cannot create gre tunnel because of missing ip_gre module (modprobe ip_gre)"); goto out_delete_parent; @@ -741,7 +741,7 @@ test_software_detect (gconstpointer user_data) lnk_ipip.tos = 32; lnk_ipip.path_mtu_discovery = FALSE; - if (!nmtstp_link_ipip_add (ext, DEVICE_NAME, &lnk_ipip)) { + if (!nmtstp_link_ipip_add (NULL, ext, DEVICE_NAME, &lnk_ipip)) { if (gracefully_skip) { g_test_skip ("Cannot create ipip tunnel because of missing ipip module (modprobe ipip)"); goto out_delete_parent; @@ -767,7 +767,7 @@ test_software_detect (gconstpointer user_data) lnk_ip6tnl.flow_label = 1337; lnk_ip6tnl.proto = IPPROTO_IPV6; - if (!nmtstp_link_ip6tnl_add (ext, DEVICE_NAME, &lnk_ip6tnl)) { + if (!nmtstp_link_ip6tnl_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) { if (gracefully_skip) { g_test_skip ("Cannot create ip6tnl tunnel because of missing ip6_tunnel module (modprobe ip6_tunnel)"); goto out_delete_parent; @@ -783,7 +783,7 @@ test_software_detect (gconstpointer user_data) lnk_macvlan.no_promisc = FALSE; lnk_macvlan.tap = FALSE; - if (!nmtstp_link_macvlan_add (ext, DEVICE_NAME, ifindex_parent, &lnk_macvlan)) + if (!nmtstp_link_macvlan_add (NULL, ext, DEVICE_NAME, ifindex_parent, &lnk_macvlan)) g_error ("Failed adding MACVLAN interface"); break; } @@ -794,7 +794,7 @@ test_software_detect (gconstpointer user_data) lnk_macvtap.no_promisc = FALSE; lnk_macvtap.tap = TRUE; - if (!nmtstp_link_macvlan_add (ext, DEVICE_NAME, ifindex_parent, &lnk_macvtap)) + if (!nmtstp_link_macvlan_add (NULL, ext, DEVICE_NAME, ifindex_parent, &lnk_macvtap)) g_error ("Failed adding MACVTAP interface"); break; } @@ -814,7 +814,7 @@ test_software_detect (gconstpointer user_data) gracefully_skip = nm_utils_modprobe (NULL, TRUE, "sit", NULL) != 0; } - if (!nmtstp_link_sit_add (ext, DEVICE_NAME, &lnk_sit)) { + if (!nmtstp_link_sit_add (NULL, ext, DEVICE_NAME, &lnk_sit)) { if (gracefully_skip) { g_test_skip ("Cannot create sit tunnel because of missing sit module (modprobe sit)"); goto out_delete_parent; @@ -853,7 +853,7 @@ test_software_detect (gconstpointer user_data) break; } - g_assert (nmtstp_link_vxlan_add (ext, DEVICE_NAME, &lnk_vxlan)); + g_assert (nmtstp_link_vxlan_add (NULL, ext, DEVICE_NAME, &lnk_vxlan)); break; } default: @@ -862,7 +862,7 @@ test_software_detect (gconstpointer user_data) ifindex = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, DEVICE_NAME, test_data->link_type, 100)->ifindex; - nmtstp_link_set_updown (-1, ifindex_parent, TRUE); + nmtstp_link_set_updown (NULL, -1, ifindex_parent, TRUE); for (i_step = 0; i_step < 5; i_step++) { @@ -880,7 +880,7 @@ test_software_detect (gconstpointer user_data) * https://bugzilla.redhat.com/show_bug.cgi?id=1277131 */ g_usleep (1); } - nmtstp_link_set_updown (-1, ifindex, set_up); + nmtstp_link_set_updown (NULL, -1, ifindex, set_up); } lnk = nm_platform_link_get_lnk (NM_PLATFORM_GET, ifindex, test_data->link_type, &plink); @@ -1017,9 +1017,9 @@ test_software_detect (gconstpointer user_data) } } - nmtstp_link_del (-1, ifindex, DEVICE_NAME); + nmtstp_link_del (NULL, -1, ifindex, DEVICE_NAME); out_delete_parent: - nmtstp_link_del (-1, ifindex_parent, PARENT_NAME); + nmtstp_link_del (NULL, -1, ifindex_parent, PARENT_NAME); } static void @@ -1597,8 +1597,8 @@ test_vlan_set_xgress (void) _assert_vlan_flags (ifindex, NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP); } - nmtstp_link_del (-1, ifindex, DEVICE_NAME); - nmtstp_link_del (-1, ifindex_parent, PARENT_NAME); + nmtstp_link_del (NULL, -1, ifindex, DEVICE_NAME); + nmtstp_link_del (NULL, -1, ifindex_parent, PARENT_NAME); } /*****************************************************************************/ @@ -1625,7 +1625,7 @@ test_create_many_links_do (guint n_devices) * while adding all the links. */ nmtstp_run_command_check ("ip link add %s type dummy", name); } else - nmtstp_link_dummy_add (EX, name); + nmtstp_link_dummy_add (NULL, EX, name); } _LOGI (">>> process events after creating devices..."); @@ -1654,7 +1654,7 @@ test_create_many_links_do (guint n_devices) if (EX == 2) nmtstp_run_command_check ("ip link delete %s", name); else - nmtstp_link_del (EX, g_array_index (ifindexes, int, i), name); + nmtstp_link_del (NULL, EX, g_array_index (ifindexes, int, i), name); } _LOGI (">>> process events after deleting devices..."); @@ -1743,7 +1743,7 @@ test_nl_bugs_veth (void) }); out: - nmtstp_link_del (-1, ifindex_veth0, IFACE_VETH0); + nmtstp_link_del (NULL, -1, ifindex_veth0, IFACE_VETH0); g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_veth0, IFACE_VETH0)); g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_veth1, IFACE_VETH1)); nmtstp_namespace_handle_release (ns_handle); @@ -1768,7 +1768,7 @@ test_nl_bugs_spuroius_newlink (void) nmtstp_run_command_check ("ip link add %s type bond", IFACE_BOND0); ifindex_bond0 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_BOND0, NM_LINK_TYPE_BOND, 100)->ifindex; - nmtstp_link_set_updown (-1, ifindex_bond0, TRUE); + nmtstp_link_set_updown (NULL, -1, ifindex_bond0, TRUE); nmtstp_run_command_check ("ip link set %s master %s", IFACE_DUMMY0, IFACE_BOND0); NMTST_WAIT_ASSERT (100, { @@ -1796,7 +1796,7 @@ again: } g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_bond0, IFACE_BOND0)); - nmtstp_link_del (-1, ifindex_dummy0, IFACE_DUMMY0); + nmtstp_link_del (NULL, -1, ifindex_dummy0, IFACE_DUMMY0); } /*****************************************************************************/ @@ -1818,7 +1818,7 @@ test_nl_bugs_spuroius_dellink (void) nmtstp_run_command_check ("ip link add %s type bridge", IFACE_BRIDGE0); ifindex_bridge0 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_BRIDGE0, NM_LINK_TYPE_BRIDGE, 100)->ifindex; - nmtstp_link_set_updown (-1, ifindex_bridge0, TRUE); + nmtstp_link_set_updown (NULL, -1, ifindex_bridge0, TRUE); nmtstp_run_command_check ("ip link set %s master %s", IFACE_DUMMY0, IFACE_BRIDGE0); NMTST_WAIT_ASSERT (100, { @@ -1850,8 +1850,8 @@ again: goto again; } - nmtstp_link_del (-1, ifindex_bridge0, IFACE_BRIDGE0); - nmtstp_link_del (-1, ifindex_dummy0, IFACE_DUMMY0); + nmtstp_link_del (NULL, -1, ifindex_bridge0, IFACE_BRIDGE0); + nmtstp_link_del (NULL, -1, ifindex_dummy0, IFACE_DUMMY0); } /******************************************************************/ diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 20c68118c2..a50392a66f 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -82,50 +82,50 @@ test_ip4_route_metric0 (void) int mss = 1000; /* No routes initially */ - nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric); /* add the first route */ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, metric, mss)); accept_signal (route_added); - nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); /* Deleting route with metric 0 does nothing */ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); ensure_no_signal (route_removed); - nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); /* add the second route */ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, 0, mss)); accept_signal (route_added); - nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); /* Delete route with metric 0 */ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); accept_signal (route_removed); - nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); /* Delete route with metric 0 again (we expect nothing to happen) */ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); ensure_no_signal (route_removed); - nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); /* Delete the other route */ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); accept_signal (route_removed); - nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric); free_signal (route_added); free_signal (route_changed); @@ -156,9 +156,9 @@ test_ip4_route (void) accept_signal (route_added); /* Add route */ - nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric); g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss)); - nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); accept_signal (route_added); /* Add route again */ @@ -166,9 +166,9 @@ test_ip4_route (void) accept_signals (route_changed, 0, 1); /* Add default route */ - nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, 0, 0, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, 0, 0, metric); g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss)); - nmtstp_assert_ip4_route_exists (TRUE, DEVICE_NAME, 0, 0, metric); + nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, 0, 0, metric); accept_signal (route_added); /* Add default route again */ @@ -208,7 +208,7 @@ test_ip4_route (void) /* Remove route */ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); - nmtstp_assert_ip4_route_exists (FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric); accept_signal (route_removed); /* Remove route again */ From 86e4975c60bab2ff2330c1ce01d96938f5337db6 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 13:22:57 +0200 Subject: [PATCH 22/31] platform/tests: improve nmtstp_wait_for_signal() to return number of signals Instead of returning only TRUE/FALSE, return the number of signals that were received while waiting. This make the API cleared, because previously I always had to check anew whether wait-for-signal returns TRUE or FALSE on timeout. Also, add nmtstp_assert_wait_for_signal() and nmtstp_assert_wait_for_signal_until() macros. (cherry picked from commit af55476bf1761685852e6a4feca3bc4dfc26b0a3) --- src/platform/tests/test-common.c | 33 +++++++++++++++++--------------- src/platform/tests/test-common.h | 16 ++++++++++++++-- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 8fcafd64b5..b1947a6d11 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -329,7 +329,7 @@ nmtstp_run_command (const char *format, ...) typedef struct { GMainLoop *loop; - gboolean timeout; + guint signal_counts; guint id; } WaitForSignalData; @@ -343,6 +343,8 @@ _wait_for_signal_cb (NMPlatform *platform, { WaitForSignalData *data = user_data; + data->signal_counts++; + nm_clear_g_source (&data->id); g_main_loop_quit (data->loop); } @@ -351,13 +353,13 @@ _wait_for_signal_timeout (gpointer user_data) { WaitForSignalData *data = user_data; - data->timeout = TRUE; + g_assert (data->id); data->id = 0; g_main_loop_quit (data->loop); return G_SOURCE_REMOVE; } -gboolean +guint nmtstp_wait_for_signal (NMPlatform *platform, guint timeout_ms) { WaitForSignalData data = { 0 }; @@ -378,33 +380,34 @@ nmtstp_wait_for_signal (NMPlatform *platform, guint timeout_ms) g_main_loop_run (data.loop); + g_assert (!data.id); g_assert (nm_clear_g_signal_handler (platform, &id_link)); g_assert (nm_clear_g_signal_handler (platform, &id_ip4_address)); g_assert (nm_clear_g_signal_handler (platform, &id_ip6_address)); g_assert (nm_clear_g_signal_handler (platform, &id_ip4_route)); g_assert (nm_clear_g_signal_handler (platform, &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; + /* return the number of signals, or 0 if timeout was reached .*/ + return data.signal_counts; } -gboolean +guint nmtstp_wait_for_signal_until (NMPlatform *platform, gint64 until_ms) { gint64 now; + guint signal_counts; while (TRUE) { now = nm_utils_get_monotonic_timestamp_ms (); if (until_ms < now) - return FALSE; + return 0; - if (nmtstp_wait_for_signal (platform, MAX (1, until_ms - now))) - return TRUE; + signal_counts = nmtstp_wait_for_signal (platform, MAX (1, until_ms - now)); + if (signal_counts) + return signal_counts; } } @@ -718,7 +721,7 @@ _ip_address_add (NMPlatform *platform, /* for internal command, we expect not to reach this line.*/ g_assert (external_command); - g_assert (nmtstp_wait_for_signal_until (platform, end_time)); + nmtstp_assert_wait_for_signal_until (platform, end_time); } while (TRUE); } @@ -861,7 +864,7 @@ _ip_address_del (NMPlatform *platform, /* for internal command, we expect not to reach this line.*/ g_assert (external_command); - g_assert (nmtstp_wait_for_signal_until (platform, end_time)); + nmtstp_assert_wait_for_signal_until (platform, end_time); } while (TRUE); } @@ -1322,7 +1325,7 @@ nmtstp_link_del (NMPlatform *platform, /* for internal command, we expect not to reach this line.*/ g_assert (external_command); - g_assert (nmtstp_wait_for_signal_until (platform, end_time)); + nmtstp_assert_wait_for_signal_until (platform, end_time); } while (TRUE); } @@ -1373,7 +1376,7 @@ nmtstp_link_set_updown (NMPlatform *platform, /* for internal command, we expect not to reach this line.*/ g_assert (external_command); - g_assert (nmtstp_wait_for_signal_until (platform, end_time)); + nmtstp_assert_wait_for_signal_until (platform, end_time); } while (TRUE); } diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 4a75281eaa..0e3cf10ba4 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -89,11 +89,23 @@ int nmtstp_run_command (const char *format, ...) __attribute__((__format__ (__pr /*****************************************************************************/ -gboolean nmtstp_wait_for_signal (NMPlatform *platform, guint timeout_ms); -gboolean nmtstp_wait_for_signal_until (NMPlatform *platform, gint64 until_ms); +guint nmtstp_wait_for_signal (NMPlatform *platform, guint timeout_ms); +guint nmtstp_wait_for_signal_until (NMPlatform *platform, gint64 until_ms); const NMPlatformLink *nmtstp_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms); const NMPlatformLink *nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms); +#define nmtstp_assert_wait_for_signal(platform, timeout_ms) \ + G_STMT_START { \ + if (nmtstp_wait_for_signal (platform, timeout_ms) == 0) \ + g_assert_not_reached (); \ + } G_STMT_END + +#define nmtstp_assert_wait_for_signal_until(platform, until_ms) \ + G_STMT_START { \ + if (nmtstp_wait_for_signal_until (platform, until_ms) == 0) \ + g_assert_not_reached (); \ + } G_STMT_END + const NMPlatformLink *nmtstp_assert_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms); const NMPlatformLink *nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms); From c7f62fcd81429fe93cb5ec82654eb6b4aaf5b394 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 10 Apr 2016 12:01:51 +0200 Subject: [PATCH 23/31] platform: expose nmp_utils_ip_config_source_to/from_rtprot() Will be used also from the tests. (cherry picked from commit 198baca8303ffa65d0c00fe36fa5c31dffb488a3) --- src/platform/nm-linux-platform.c | 43 ++---------------------------- src/platform/nm-platform-utils.c | 45 ++++++++++++++++++++++++++++++++ src/platform/nm-platform-utils.h | 3 +++ 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index f83b650be4..702a6ee206 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -290,45 +290,6 @@ _support_user_ipv6ll_detect (struct nlattr **tb) * Various utilities ******************************************************************/ -static guint -_nm_ip_config_source_to_rtprot (NMIPConfigSource source) -{ - switch (source) { - case NM_IP_CONFIG_SOURCE_UNKNOWN: - return RTPROT_UNSPEC; - case NM_IP_CONFIG_SOURCE_KERNEL: - case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: - return RTPROT_KERNEL; - case NM_IP_CONFIG_SOURCE_DHCP: - return RTPROT_DHCP; - case NM_IP_CONFIG_SOURCE_RDISC: - return RTPROT_RA; - - default: - return RTPROT_STATIC; - } -} - -static NMIPConfigSource -_nm_ip_config_source_from_rtprot (guint rtprot) -{ - switch (rtprot) { - case RTPROT_UNSPEC: - return NM_IP_CONFIG_SOURCE_UNKNOWN; - case RTPROT_KERNEL: - return NM_IP_CONFIG_SOURCE_RTPROT_KERNEL; - case RTPROT_REDIRECT: - return NM_IP_CONFIG_SOURCE_KERNEL; - case RTPROT_RA: - return NM_IP_CONFIG_SOURCE_RDISC; - case RTPROT_DHCP: - return NM_IP_CONFIG_SOURCE_DHCP; - - default: - return NM_IP_CONFIG_SOURCE_USER; - } -} - static void clear_host_address (int family, const void *network, guint8 plen, void *dst) { @@ -1911,7 +1872,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) * */ obj->ip_route.source = _NM_IP_CONFIG_SOURCE_RTM_F_CLONED; } else - obj->ip_route.source = _nm_ip_config_source_from_rtprot (rtm->rtm_protocol); + obj->ip_route.source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol); obj_result = obj; obj = NULL; @@ -2271,7 +2232,7 @@ _nl_msg_new_route (int nlmsg_type, .rtm_family = family, .rtm_tos = 0, .rtm_table = RT_TABLE_MAIN, /* omit setting RTA_TABLE attribute */ - .rtm_protocol = _nm_ip_config_source_to_rtprot (source), + .rtm_protocol = nmp_utils_ip_config_source_to_rtprot (source), .rtm_scope = scope, .rtm_type = RTN_UNICAST, .rtm_flags = 0, diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index d0c92a787c..b4542adf8d 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "nm-utils.h" #include "nm-setting-wired.h" @@ -412,6 +413,10 @@ out: return g_intern_string (driver); } +/****************************************************************************** + * utils + *****************************************************************************/ + gboolean nmp_utils_device_exists (const char *name) { @@ -427,3 +432,43 @@ nmp_utils_device_exists (const char *name) nm_utils_ifname_cpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], name); return g_file_test (sysdir, G_FILE_TEST_EXISTS); } + +guint +nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source) +{ + switch (source) { + case NM_IP_CONFIG_SOURCE_UNKNOWN: + return RTPROT_UNSPEC; + case NM_IP_CONFIG_SOURCE_KERNEL: + case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: + return RTPROT_KERNEL; + case NM_IP_CONFIG_SOURCE_DHCP: + return RTPROT_DHCP; + case NM_IP_CONFIG_SOURCE_RDISC: + return RTPROT_RA; + + default: + return RTPROT_STATIC; + } +} + +NMIPConfigSource +nmp_utils_ip_config_source_from_rtprot (guint rtprot) +{ + switch (rtprot) { + case RTPROT_UNSPEC: + return NM_IP_CONFIG_SOURCE_UNKNOWN; + case RTPROT_KERNEL: + return NM_IP_CONFIG_SOURCE_RTPROT_KERNEL; + case RTPROT_REDIRECT: + return NM_IP_CONFIG_SOURCE_KERNEL; + case RTPROT_RA: + return NM_IP_CONFIG_SOURCE_RDISC; + case RTPROT_DHCP: + return NM_IP_CONFIG_SOURCE_DHCP; + + default: + return NM_IP_CONFIG_SOURCE_USER; + } +} + diff --git a/src/platform/nm-platform-utils.h b/src/platform/nm-platform-utils.h index 976bd8db40..f259474719 100644 --- a/src/platform/nm-platform-utils.h +++ b/src/platform/nm-platform-utils.h @@ -54,4 +54,7 @@ const char *nmp_utils_udev_get_driver (GUdevDevice *device); gboolean nmp_utils_device_exists (const char *name); +guint nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source); +NMIPConfigSource nmp_utils_ip_config_source_from_rtprot (guint rtprot); + #endif /* __NM_PLATFORM_UTILS_H__ */ From 53823384b54e6e5ffd581d6bec56549344f94eb0 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 17:14:03 +0200 Subject: [PATCH 24/31] platform: add macro FOR_EACH_DELAYED_ACTION() (cherry picked from commit 15e357c30a27907a23ed5fa9b42610d51818b3ec) --- src/platform/nm-linux-platform.c | 85 +++++++++++++++----------------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 702a6ee206..1c312d31f8 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -198,6 +198,10 @@ typedef enum { DELAYED_ACTION_TYPE_MAX = __DELAYED_ACTION_TYPE_MAX -1, } DelayedActionType; +#define FOR_EACH_DELAYED_ACTION(iflags, flags_all) \ + for ((iflags) = (DelayedActionType) 0x1LL; (iflags) <= DELAYED_ACTION_TYPE_MAX; (iflags) <<= 1) \ + if (NM_FLAGS_HAS (flags_all, iflags)) + typedef enum { /* Negative values are errors from kernel. Add dummy member to * make enum signed. */ @@ -2936,9 +2940,8 @@ delayed_action_handle_one (NMPlatform *platform) priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_ALL; if (_LOGt_ENABLED ()) { - for (iflags = (DelayedActionType) 0x1LL; iflags <= DELAYED_ACTION_TYPE_MAX; iflags <<= 1) { - if (NM_FLAGS_HAS (flags, iflags)) - _LOGt_delayed_action (iflags, NULL, "handle"); + FOR_EACH_DELAYED_ACTION (iflags, flags) { + _LOGt_delayed_action (iflags, NULL, "handle"); } } @@ -3023,9 +3026,8 @@ delayed_action_schedule (NMPlatform *platform, DelayedActionType action_type, gp priv->delayed_action.flags |= action_type; if (_LOGt_ENABLED ()) { - for (iflags = (DelayedActionType) 0x1LL; iflags <= DELAYED_ACTION_TYPE_MAX; iflags <<= 1) { - if (NM_FLAGS_HAS (action_type, iflags)) - _LOGt_delayed_action (iflags, user_data, "schedule"); + FOR_EACH_DELAYED_ACTION (iflags, action_type) { + _LOGt_delayed_action (iflags, user_data, "schedule"); } } } @@ -3421,48 +3423,43 @@ do_request_all_no_delayed_actions (NMPlatform *platform, DelayedActionType actio nm_assert (!NM_FLAGS_ANY (action_type, ~DELAYED_ACTION_TYPE_REFRESH_ALL)); action_type &= DELAYED_ACTION_TYPE_REFRESH_ALL; - for (iflags = (DelayedActionType) 0x1LL; iflags <= DELAYED_ACTION_TYPE_MAX; iflags <<= 1) { - if (NM_FLAGS_HAS (action_type, iflags)) - cache_prune_candidates_record_all (platform, delayed_action_refresh_to_object_type (iflags)); + FOR_EACH_DELAYED_ACTION (iflags, action_type) { + cache_prune_candidates_record_all (platform, delayed_action_refresh_to_object_type (iflags)); } - for (iflags = (DelayedActionType) 0x1LL; iflags <= DELAYED_ACTION_TYPE_MAX; iflags <<= 1) { - if (NM_FLAGS_HAS (action_type, iflags)) { - NMPObjectType obj_type = delayed_action_refresh_to_object_type (iflags); - const NMPClass *klass = nmp_class_from_type (obj_type); - nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - struct rtgenmsg gmsg = { - .rtgen_family = klass->addr_family, - }; - int nle; + FOR_EACH_DELAYED_ACTION (iflags, action_type) { + NMPObjectType obj_type = delayed_action_refresh_to_object_type (iflags); + const NMPClass *klass = nmp_class_from_type (obj_type); + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + struct rtgenmsg gmsg = { + .rtgen_family = klass->addr_family, + }; + int nle; - /* clear any delayed action that request a refresh of this object type. */ - priv->delayed_action.flags &= ~iflags; - _LOGt_delayed_action (iflags, NULL, "handle (do-request-all)"); - if (obj_type == NMP_OBJECT_TYPE_LINK) { - priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK; - g_ptr_array_set_size (priv->delayed_action.list_refresh_link, 0); - _LOGt_delayed_action (DELAYED_ACTION_TYPE_REFRESH_LINK, NULL, "clear (do-request-all)"); - } - - event_handler_read_netlink (platform, FALSE); - - /* reimplement - * nl_rtgen_request (sk, klass->rtm_gettype, klass->addr_family, NLM_F_DUMP); - * because we need the sequence number. - */ - nlmsg = nlmsg_alloc_simple (klass->rtm_gettype, NLM_F_DUMP); - if (!nlmsg) - goto next; - - nle = nlmsg_append (nlmsg, &gmsg, sizeof (gmsg), NLMSG_ALIGNTO); - if (nle < 0) - goto next; - - _nl_send_auto_with_seq (platform, nlmsg, NULL); + /* clear any delayed action that request a refresh of this object type. */ + priv->delayed_action.flags &= ~iflags; + _LOGt_delayed_action (iflags, NULL, "handle (do-request-all)"); + if (obj_type == NMP_OBJECT_TYPE_LINK) { + priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK; + g_ptr_array_set_size (priv->delayed_action.list_refresh_link, 0); + _LOGt_delayed_action (DELAYED_ACTION_TYPE_REFRESH_LINK, NULL, "clear (do-request-all)"); } -next: - ; + + event_handler_read_netlink (platform, FALSE); + + /* reimplement + * nl_rtgen_request (sk, klass->rtm_gettype, klass->addr_family, NLM_F_DUMP); + * because we need the sequence number. + */ + nlmsg = nlmsg_alloc_simple (klass->rtm_gettype, NLM_F_DUMP); + if (!nlmsg) + continue; + + nle = nlmsg_append (nlmsg, &gmsg, sizeof (gmsg), NLMSG_ALIGNTO); + if (nle < 0) + continue; + + _nl_send_auto_with_seq (platform, nlmsg, NULL); } } From a20e11d268219d22d32ae3816e6e4655a5be520c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 21:16:51 +0200 Subject: [PATCH 25/31] platform: #ifdef out nlh_seq_last_handled if it's unused This is not for performance. It's to separate the relavant parts from a part that is only for logging/asserts. (cherry picked from commit c59687c6b29047d618417a0e46fddf728ae7797a) --- src/platform/nm-linux-platform.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 1c312d31f8..21f89de949 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2349,7 +2349,9 @@ typedef struct _NMLinuxPlatformPrivate NMLinuxPlatformPrivate; struct _NMLinuxPlatformPrivate { struct nl_sock *nlh; guint32 nlh_seq_next; +#ifdef NM_MORE_LOGGING guint32 nlh_seq_last_handled; +#endif NMPCache *cache; GIOChannel *event_channel; guint event_id; @@ -3503,9 +3505,11 @@ event_seq_check (NMPlatform *platform, struct nl_msg *msg, WaitForNlResponseResu } } +#ifdef NM_MORE_LOGGING if (seq_number != priv->nlh_seq_last_handled) _LOGt ("netlink: recvmsg: unwaited sequence number %u", seq_number); priv->nlh_seq_last_handled = seq_number; +#endif } static void From c0e0e5e92c73daab2df55238f15aed8ae04e3d4f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 8 Apr 2016 12:25:41 +0200 Subject: [PATCH 26/31] platform: refactor delayed_action_wait_for_nl_response_complete() (cherry picked from commit 90550a276bb1c29083af29e76676a94d7d55378d) --- src/platform/nm-linux-platform.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 21f89de949..0e562d6181 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2339,8 +2339,8 @@ _support_kernel_extended_ifa_flags_get (void) typedef struct { guint32 seq_number; - gint64 timeout_abs_ns; WaitForNlResponseResult seq_result; + gint64 timeout_abs_ns; WaitForNlResponseResult *out_seq_result; } DelayedActionWaitForNlResponseData; @@ -2814,7 +2814,6 @@ delayed_action_wait_for_nl_response_complete (NMPlatform *platform, { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); DelayedActionWaitForNlResponseData *data; - WaitForNlResponseResult *out_seq_result; nm_assert (NM_FLAGS_HAS (priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)); nm_assert (idx < priv->delayed_action.list_wait_for_nl_response->len); @@ -2824,16 +2823,12 @@ delayed_action_wait_for_nl_response_complete (NMPlatform *platform, _LOGt_delayed_action (DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE, data, "complete"); - out_seq_result = data->out_seq_result; + if (priv->delayed_action.list_wait_for_nl_response->len <= 1) + priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE; + if (data->out_seq_result) + *data->out_seq_result = seq_result; g_array_remove_index_fast (priv->delayed_action.list_wait_for_nl_response, idx); - /* Note: @data is invalidated at this point */ - - if (priv->delayed_action.list_wait_for_nl_response->len <= 0) - priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE; - - if (out_seq_result) - *out_seq_result = seq_result; } static void From d6478fa7644b7d2e591cf56968e8a6f6bbb108ba Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 21:19:45 +0200 Subject: [PATCH 27/31] platform: refactor calling event_seq_check() This makes more sense with the next commit. (cherry picked from commit 8bf635af0e174b1bb8b5e4201b82f27da7350191) --- src/platform/nm-linux-platform.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 0e562d6181..4d05f2173f 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -3468,15 +3468,12 @@ do_request_one_type (NMPlatform *platform, NMPObjectType obj_type) } static void -event_seq_check (NMPlatform *platform, struct nl_msg *msg, WaitForNlResponseResult seq_result) +event_seq_check (NMPlatform *platform, guint32 seq_number, WaitForNlResponseResult seq_result) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); DelayedActionWaitForNlResponseData *data; - guint32 seq_number; guint i; - seq_number = nlmsg_hdr (msg)->nlmsg_seq; - if (seq_number == 0) return; @@ -5655,6 +5652,8 @@ continue_reading: while (nlmsg_ok (hdr, n)) { nm_auto_nlmsg struct nl_msg *msg = NULL; gboolean abort_parsing = FALSE; + gboolean process_valid_msg = FALSE; + guint32 seq_number; msg = nlmsg_convert (hdr); if (!msg) { @@ -5739,7 +5738,12 @@ continue_reading: seq_result = -errsv; } else seq_result = WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK; - } else { + } else + process_valid_msg = TRUE; + + seq_number = nlmsg_hdr (msg)->nlmsg_seq; + + if (process_valid_msg) { /* Valid message (not checking for MULTIPART bit to * get along with broken kernels. NL_SKIP has no * effect on this. */ @@ -5749,7 +5753,7 @@ continue_reading: seq_result = WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK; } - event_seq_check (platform, msg, seq_result); + event_seq_check (platform, seq_number, seq_result); if (abort_parsing) goto stop; From 6beb383bd777397b12b604d16ffb33e6953d9ca4 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 7 Apr 2016 19:02:19 +0200 Subject: [PATCH 28/31] platform: track refresh-all actions that are in progress We aim to keep the platform cache up-to-date only via the netlink events. However, due to kernel shortcomings we often have to resync by re-requesting the data, which especially for routes and addresses means a full dump (as you cannot request only specific route/address information). Thus it makes sense to avoid expensive dumps whenever we can. We schedule dumps via "delayed-actions" and that is already smart so that muliple schedulings are combined. However, before requesting a new dump, we clear the flag that indicates that a dump is scheduled. Thus, while processing the result of of a dump, we would re-schedule anew which can be necessary in some cases. In certain cases, we don't require a full resync, when we are in the middle of processing a dump, because that one dump will provide us with the full picture. Thus, we can avoid scheduling a new dump if - we already scheduled a delayed action - we are in the middle or processing a dump. This can now be checked via delayed_action_refresh_all_in_progress(). (cherry picked from commit ff8c82e7e165f3e10ba95ecddced9cad789c8a32) --- src/platform/nm-linux-platform.c | 131 +++++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 14 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 4d05f2173f..f6fb1ba301 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -176,13 +176,22 @@ * Forward declarations and enums ******************************************************************/ +enum { + DELAYED_ACTION_IDX_REFRESH_ALL_LINKS, + DELAYED_ACTION_IDX_REFRESH_ALL_IP4_ADDRESSES, + DELAYED_ACTION_IDX_REFRESH_ALL_IP6_ADDRESSES, + DELAYED_ACTION_IDX_REFRESH_ALL_IP4_ROUTES, + DELAYED_ACTION_IDX_REFRESH_ALL_IP6_ROUTES, + _DELAYED_ACTION_IDX_REFRESH_ALL_NUM, +}; + typedef enum { DELAYED_ACTION_TYPE_NONE = 0, - DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS = (1LL << 0), - DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES = (1LL << 1), - DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES = (1LL << 2), - DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES = (1LL << 3), - DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES = (1LL << 4), + DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS = (1LL << DELAYED_ACTION_IDX_REFRESH_ALL_LINKS), + DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES = (1LL << DELAYED_ACTION_IDX_REFRESH_ALL_IP4_ADDRESSES), + DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES = (1LL << DELAYED_ACTION_IDX_REFRESH_ALL_IP6_ADDRESSES), + DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES = (1LL << DELAYED_ACTION_IDX_REFRESH_ALL_IP4_ROUTES), + DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES = (1LL << DELAYED_ACTION_IDX_REFRESH_ALL_IP6_ROUTES), DELAYED_ACTION_TYPE_REFRESH_LINK = (1LL << 5), DELAYED_ACTION_TYPE_MASTER_CONNECTED = (1LL << 6), DELAYED_ACTION_TYPE_READ_NETLINK = (1LL << 7), @@ -2342,6 +2351,7 @@ typedef struct { WaitForNlResponseResult seq_result; gint64 timeout_abs_ns; WaitForNlResponseResult *out_seq_result; + gint *out_refresh_all_in_progess; } DelayedActionWaitForNlResponseData; typedef struct _NMLinuxPlatformPrivate NMLinuxPlatformPrivate; @@ -2352,6 +2362,7 @@ struct _NMLinuxPlatformPrivate { #ifdef NM_MORE_LOGGING guint32 nlh_seq_last_handled; #endif + guint32 nlh_seq_last_seen; NMPCache *cache; GIOChannel *event_channel; guint event_id; @@ -2362,10 +2373,18 @@ struct _NMLinuxPlatformPrivate { GUdevClient *udev_client; struct { + /* which delayed actions are scheduled, as marked in @flags. + * Some types have additional arguments in the fields below. */ DelayedActionType flags; + + /* counter that a refresh all action is in progress, separated + * by type. */ + gint refresh_all_in_progess[_DELAYED_ACTION_IDX_REFRESH_ALL_NUM]; + GPtrArray *list_master_connected; GPtrArray *list_refresh_link; GArray *list_wait_for_nl_response; + gint is_handling; } delayed_action; @@ -2740,6 +2759,16 @@ delayed_action_refresh_to_object_type (DelayedActionType action_type) } } +_NM_UTILS_LOOKUP_DEFINE (static, delayed_action_refresh_all_to_idx, DelayedActionType, guint, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT (0), + NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS, DELAYED_ACTION_IDX_REFRESH_ALL_LINKS), + NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES, DELAYED_ACTION_IDX_REFRESH_ALL_IP4_ADDRESSES), + NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES, DELAYED_ACTION_IDX_REFRESH_ALL_IP6_ADDRESSES), + NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES, DELAYED_ACTION_IDX_REFRESH_ALL_IP4_ROUTES), + NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, DELAYED_ACTION_IDX_REFRESH_ALL_IP6_ROUTES), + NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER (), +); + static const char * delayed_action_to_string (DelayedActionType action_type) { @@ -2807,6 +2836,24 @@ delayed_action_to_string_full (DelayedActionType action_type, gpointer user_data /*****************************************************************************/ +static gboolean +delayed_action_refresh_all_in_progress (NMPlatform *platform, DelayedActionType action_type) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + + nm_assert (nm_utils_is_power_of_two (action_type)); + nm_assert (NM_FLAGS_ANY (action_type, DELAYED_ACTION_TYPE_REFRESH_ALL)); + nm_assert (!NM_FLAGS_ANY (action_type, ~DELAYED_ACTION_TYPE_REFRESH_ALL)); + + if (NM_FLAGS_ANY (priv->delayed_action.flags, action_type)) + return TRUE; + + if (priv->delayed_action.refresh_all_in_progess[delayed_action_refresh_all_to_idx (action_type)] > 0) + return TRUE; + + return FALSE; +} + static void delayed_action_wait_for_nl_response_complete (NMPlatform *platform, guint idx, @@ -2827,6 +2874,10 @@ delayed_action_wait_for_nl_response_complete (NMPlatform *platform, priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE; if (data->out_seq_result) *data->out_seq_result = seq_result; + if (data->out_refresh_all_in_progess) { + nm_assert (*data->out_refresh_all_in_progess > 0); + *data->out_refresh_all_in_progess -= 1; + } g_array_remove_index_fast (priv->delayed_action.list_wait_for_nl_response, idx); } @@ -3032,12 +3083,14 @@ delayed_action_schedule (NMPlatform *platform, DelayedActionType action_type, gp static void delayed_action_schedule_WAIT_FOR_NL_RESPONSE (NMPlatform *platform, guint32 seq_number, - WaitForNlResponseResult *out_seq_result) + WaitForNlResponseResult *out_seq_result, + gint *out_refresh_all_in_progess) { DelayedActionWaitForNlResponseData data = { .seq_number = seq_number, .timeout_abs_ns = nm_utils_get_monotonic_timestamp_ns () + (200 * (NM_UTILS_NS_PER_SECOND / 1000)), .out_seq_result = out_seq_result, + .out_refresh_all_in_progess = out_refresh_all_in_progess, }; delayed_action_schedule (platform, @@ -3352,7 +3405,8 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP static int _nl_send_auto_with_seq (NMPlatform *platform, struct nl_msg *nlmsg, - WaitForNlResponseResult *out_seq_result) + WaitForNlResponseResult *out_seq_result, + gint *out_refresh_all_in_progess) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); guint32 seq; @@ -3367,7 +3421,7 @@ _nl_send_auto_with_seq (NMPlatform *platform, if (nle >= 0) { nle = 0; - delayed_action_schedule_WAIT_FOR_NL_RESPONSE (platform, seq, out_seq_result); + delayed_action_schedule_WAIT_FOR_NL_RESPONSE (platform, seq, out_seq_result, out_refresh_all_in_progess); } else _LOGD ("netlink: send: failed sending message: %s (%d)", nl_geterror (nle), nle); @@ -3401,7 +3455,7 @@ do_request_link_no_delayed_actions (NMPlatform *platform, int ifindex, const cha 0, 0); if (nlmsg) - _nl_send_auto_with_seq (platform, nlmsg, NULL); + _nl_send_auto_with_seq (platform, nlmsg, NULL, NULL); } static void @@ -3432,6 +3486,11 @@ do_request_all_no_delayed_actions (NMPlatform *platform, DelayedActionType actio .rtgen_family = klass->addr_family, }; int nle; + gint *out_refresh_all_in_progess; + + out_refresh_all_in_progess = &priv->delayed_action.refresh_all_in_progess[delayed_action_refresh_all_to_idx (iflags)]; + nm_assert (*out_refresh_all_in_progess >= 0); + *out_refresh_all_in_progess += 1; /* clear any delayed action that request a refresh of this object type. */ priv->delayed_action.flags &= ~iflags; @@ -3456,7 +3515,10 @@ do_request_all_no_delayed_actions (NMPlatform *platform, DelayedActionType actio if (nle < 0) continue; - _nl_send_auto_with_seq (platform, nlmsg, NULL); + if (_nl_send_auto_with_seq (platform, nlmsg, NULL, out_refresh_all_in_progess) < 0) { + nm_assert (*out_refresh_all_in_progess > 0); + *out_refresh_all_in_progess -= 1; + } } } @@ -3467,6 +3529,38 @@ do_request_one_type (NMPlatform *platform, NMPObjectType obj_type) delayed_action_handle_all (platform, FALSE); } +static void +event_seq_check_refresh_all (NMPlatform *platform, guint32 seq_number) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + DelayedActionWaitForNlResponseData *data; + guint i; + + (void) delayed_action_refresh_all_in_progress; + + if (NM_IN_SET (seq_number, 0, priv->nlh_seq_last_seen)) + return; + + if (NM_FLAGS_HAS (priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)) { + nm_assert (priv->delayed_action.list_wait_for_nl_response->len > 0); + + for (i = 0; i < priv->delayed_action.list_wait_for_nl_response->len; i++) { + data = &g_array_index (priv->delayed_action.list_wait_for_nl_response, DelayedActionWaitForNlResponseData, i); + + if (data->seq_number == priv->nlh_seq_last_seen) { + if (data->out_refresh_all_in_progess) { + nm_assert (*data->out_refresh_all_in_progess > 0); + *data->out_refresh_all_in_progess -= 1; + data->out_refresh_all_in_progess = NULL; + break; + } + } + } + } + + priv->nlh_seq_last_seen = seq_number; +} + static void event_seq_check (NMPlatform *platform, guint32 seq_number, WaitForNlResponseResult seq_result) { @@ -3698,7 +3792,7 @@ do_add_link_with_lookup (NMPlatform *platform, } } - nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result); + nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result, NULL); if (nle < 0) { _LOGE ("do-add-link[%s/%s]: failed sending netlink request \"%s\" (%d)", name, @@ -3749,7 +3843,7 @@ do_add_addrroute (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg * event_handler_read_netlink (platform, FALSE); - nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result); + nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result, NULL); if (nle < 0) { _LOGE ("do-add-%s[%s]: failure sending netlink request \"%s\" (%d)", NMP_OBJECT_GET_CLASS (obj_id)->obj_type_name, @@ -3802,7 +3896,7 @@ do_delete_object (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg * event_handler_read_netlink (platform, FALSE); - nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result); + nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result, NULL); if (nle < 0) { _LOGE ("do-delete-%s[%s]: failure sending netlink request \"%s\" (%d)", NMP_OBJECT_GET_CLASS (obj_id)->obj_type_name, @@ -3863,7 +3957,7 @@ do_change_link (NMPlatform *platform, return NM_PLATFORM_ERROR_UNSPECIFIED; retry: - nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result); + nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result, NULL); if (nle < 0) { _LOGE ("do-change-link[%d]: failure sending netlink request \"%s\" (%d)", ifindex, @@ -5743,6 +5837,15 @@ continue_reading: seq_number = nlmsg_hdr (msg)->nlmsg_seq; + /* check whether the seq number is different from before, and + * whether the previous number (@nlh_seq_last_seen) is a pending + * refresh-all request. In that case, the pending request is thereby + * completed. + * + * We must do that before processing the message with event_valid_msg(), + * because we must track the completion of the pending request before that. */ + event_seq_check_refresh_all (platform, seq_number); + if (process_valid_msg) { /* Valid message (not checking for MULTIPART bit to * get along with broken kernels. NL_SKIP has no From bb654d8c257bc04a603099c7111a53dcc9e82644 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 8 Apr 2016 12:40:35 +0200 Subject: [PATCH 29/31] platform: use _NM_UTILS_LOOKUP_DEFINE() (cherry picked from commit 20618901dde4def664c78b251d67313eb7be7aa8) --- src/platform/nm-linux-platform.c | 74 ++++++++++++++------------------ 1 file changed, 33 insertions(+), 41 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index f6fb1ba301..e746475eca 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2733,31 +2733,25 @@ do_emit_signal (NMPlatform *platform, const NMPObject *obj, NMPCacheOpsType cach /******************************************************************/ -static DelayedActionType -delayed_action_refresh_from_object_type (NMPObjectType obj_type) -{ - switch (obj_type) { - case NMP_OBJECT_TYPE_LINK: return DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS; - case NMP_OBJECT_TYPE_IP4_ADDRESS: return DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES; - case NMP_OBJECT_TYPE_IP6_ADDRESS: return DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES; - case NMP_OBJECT_TYPE_IP4_ROUTE: return DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES; - case NMP_OBJECT_TYPE_IP6_ROUTE: return DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES; - default: g_return_val_if_reached (DELAYED_ACTION_TYPE_NONE); - } -} +_NM_UTILS_LOOKUP_DEFINE (static, delayed_action_refresh_from_object_type, NMPObjectType, DelayedActionType, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT (DELAYED_ACTION_TYPE_NONE), + NM_UTILS_LOOKUP_ITEM (NMP_OBJECT_TYPE_LINK, DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS), + NM_UTILS_LOOKUP_ITEM (NMP_OBJECT_TYPE_IP4_ADDRESS, DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES), + NM_UTILS_LOOKUP_ITEM (NMP_OBJECT_TYPE_IP6_ADDRESS, DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES), + NM_UTILS_LOOKUP_ITEM (NMP_OBJECT_TYPE_IP4_ROUTE, DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES), + NM_UTILS_LOOKUP_ITEM (NMP_OBJECT_TYPE_IP6_ROUTE, DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES), + NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER (), +); -static NMPObjectType -delayed_action_refresh_to_object_type (DelayedActionType action_type) -{ - switch (action_type) { - case DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS: return NMP_OBJECT_TYPE_LINK; - case DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES: return NMP_OBJECT_TYPE_IP4_ADDRESS; - case DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES: return NMP_OBJECT_TYPE_IP6_ADDRESS; - case DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES: return NMP_OBJECT_TYPE_IP4_ROUTE; - case DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES: return NMP_OBJECT_TYPE_IP6_ROUTE; - default: g_return_val_if_reached (NMP_OBJECT_TYPE_UNKNOWN); - } -} +_NM_UTILS_LOOKUP_DEFINE (static, delayed_action_refresh_to_object_type, DelayedActionType, NMPObjectType, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT (NMP_OBJECT_TYPE_UNKNOWN), + NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS, NMP_OBJECT_TYPE_LINK), + NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES, NMP_OBJECT_TYPE_IP4_ADDRESS), + NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES, NMP_OBJECT_TYPE_IP6_ADDRESS), + NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES, NMP_OBJECT_TYPE_IP4_ROUTE), + NM_UTILS_LOOKUP_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, NMP_OBJECT_TYPE_IP6_ROUTE), + NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER (), +); _NM_UTILS_LOOKUP_DEFINE (static, delayed_action_refresh_all_to_idx, DelayedActionType, guint, NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT (0), @@ -2769,23 +2763,21 @@ _NM_UTILS_LOOKUP_DEFINE (static, delayed_action_refresh_all_to_idx, DelayedActio NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER (), ); -static const char * -delayed_action_to_string (DelayedActionType action_type) -{ - switch (action_type) { - case DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS : return "refresh-all-links"; - case DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES : return "refresh-all-ip4-addresses"; - case DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES : return "refresh-all-ip6-addresses"; - case DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES : return "refresh-all-ip4-routes"; - case DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES : return "refresh-all-ip6-routes"; - case DELAYED_ACTION_TYPE_REFRESH_LINK : return "refresh-link"; - case DELAYED_ACTION_TYPE_MASTER_CONNECTED : return "master-connected"; - case DELAYED_ACTION_TYPE_READ_NETLINK : return "read-netlink"; - case DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE : return "wait-for-nl-response"; - default: - return "unknown"; - } -} +NM_UTILS_LOOKUP_STR_DEFINE_STATIC (delayed_action_to_string, DelayedActionType, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT ("unknown"), + NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS, "refresh-all-links"), + NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES, "refresh-all-ip4-addresses"), + NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ADDRESSES, "refresh-all-ip6-addresses"), + NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES, "refresh-all-ip4-routes"), + NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, "refresh-all-ip6-routes"), + NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_REFRESH_LINK, "refresh-link"), + NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_MASTER_CONNECTED, "master-connected"), + NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_READ_NETLINK, "read-netlink"), + NM_UTILS_LOOKUP_STR_ITEM (DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE, "wait-for-nl-response"), + NM_UTILS_LOOKUP_ITEM_IGNORE (DELAYED_ACTION_TYPE_NONE), + NM_UTILS_LOOKUP_ITEM_IGNORE (DELAYED_ACTION_TYPE_REFRESH_ALL), + NM_UTILS_LOOKUP_ITEM_IGNORE (__DELAYED_ACTION_TYPE_MAX), +); static const char * delayed_action_to_string_full (DelayedActionType action_type, gpointer user_data, char *buf, gsize buf_size) From ec35bb8236fd4e06b3d580d6f5ad17891ea4a3b8 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 10 Apr 2016 11:21:50 +0200 Subject: [PATCH 30/31] platform: ensure cache consistency for routes by workaround missing kernel event Consider: unshare -n ip link add d0 type dummy ip link add d1 type dummy ip link set d0 up ip link set d1 up ip addr add 192.168.100.5/24 dev d0 ip addr add 192.168.101.5/24 dev d1 ip route add 192.168.200.0/24 via 192.168.100.1 ip monitor & ip route change 192.168.200.0/24 via 192.168.101.1 #prints 192.168.200.0/24 via 192.168.101.1 dev d1 ip route show #192.168.100.0/24 dev d0 proto kernel scope link src 192.168.100.5 #192.168.101.0/24 dev d1 proto kernel scope link src 192.168.101.5 #192.168.200.0/24 via 192.168.101.1 dev d1 Note that `ip route change` replaced the exising route. "Replaced" in this case means: the previous route on device "d0" got removed and a new route on "d1" was added. However, kernel only sent one RTM_NEWROUTE event, no RTM_DELROUTE that notifies about this change. We need to workaround that by re-synching the routes when we receive a RTM_NEWROUTE notification. (cherry picked from commit f8b2cadfc194b17d2d52d75f13cb0ab1f5fb4146) --- src/platform/nm-linux-platform.c | 46 +++++++++++++- src/platform/nmp-object.c | 105 ++++++++++++++++++++++++++++++- src/platform/nmp-object.h | 29 +++++++++ 3 files changed, 174 insertions(+), 6 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index e746475eca..f4a4ba86d8 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -3169,7 +3169,7 @@ cache_prune_candidates_prune (NMPlatform *platform) static void cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMPCacheOpsType ops_type, gpointer user_data) { - NMPlatform *platform = NM_PLATFORM (user_data); + NMPlatform *platform = user_data; NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); const NMPClass *klass; char str_buf[sizeof (_nm_utils_to_string_buffer)]; @@ -3181,6 +3181,7 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP nm_assert (ops_type != NMP_CACHE_OPS_REMOVED || (new == NULL && NMP_OBJECT_IS_VALID (old) && nmp_object_is_alive (old))); nm_assert (ops_type != NMP_CACHE_OPS_UPDATED || (NMP_OBJECT_IS_VALID (old) && nmp_object_is_alive (old) && NMP_OBJECT_IS_VALID (new) && nmp_object_is_alive (new))); nm_assert (new == NULL || old == NULL || nmp_object_id_equal (new, old)); + nm_assert (!old || !new || NMP_OBJECT_GET_CLASS (old) == NMP_OBJECT_GET_CLASS (new)); klass = old ? NMP_OBJECT_GET_CLASS (old) : NMP_OBJECT_GET_CLASS (new); @@ -3387,11 +3388,49 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP NULL); } } + break; default: break; } } +static void +cache_post (NMPlatform *platform, + struct nlmsghdr *msghdr, + NMPCacheOpsType cache_op, + NMPObject *obj, + NMPObject *obj_cache) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + + nm_assert (NMP_OBJECT_IS_VALID (obj)); + nm_assert (!obj_cache || nmp_object_id_equal (obj, obj_cache)); + + if (msghdr->nlmsg_type == RTM_NEWROUTE) { + DelayedActionType action_type; + + action_type = NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_IP4_ROUTE + ? DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES + : DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES; + if ( !delayed_action_refresh_all_in_progress (platform, action_type) + && nmp_cache_find_other_route_for_same_destination (priv->cache, obj)) { + /* via `iproute route change` the user can update an existing route which effectively + * means that a new object (with a different ID) comes into existance, replacing the + * old on. In other words, as the ID of the object changes, we really see a new + * object with the old one deleted. + * However, kernel decides not to send a RTM_DELROUTE event for that. + * + * To hack around that, check if the update leaves us with multiple routes for the + * same network/plen,metric part. In that case, we cannot do better then requesting + * all routes anew, which sucks. + * + * One mitigation to avoid a dump is only to request a new dump, if we are not in + * the middle of an ongoing dump (delayed_action_refresh_all_in_progress). */ + delayed_action_schedule (platform, action_type, NULL); + } + } +} + /******************************************************************/ static int @@ -3528,8 +3567,6 @@ event_seq_check_refresh_all (NMPlatform *platform, guint32 seq_number) DelayedActionWaitForNlResponseData *data; guint i; - (void) delayed_action_refresh_all_in_progress; - if (NM_IN_SET (seq_number, 0, priv->nlh_seq_last_seen)) return; @@ -3635,6 +3672,9 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_event case RTM_NEWADDR: case RTM_NEWROUTE: cache_op = nmp_cache_update_netlink (priv->cache, obj, &obj_cache, &was_visible, cache_pre_hook, platform); + + cache_post (platform, msghdr, cache_op, obj, obj_cache); + do_emit_signal (platform, obj_cache, cache_op, was_visible); break; diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 07ea9fe1d5..eb7e1ca401 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -965,6 +965,8 @@ _NM_UTILS_LOOKUP_DEFINE (static, _nmp_cache_id_size_by_type, NMPCacheIdType, gui NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_NO_DEFAULT, _STRUCT_SIZE (NMPCacheId, object_type_by_ifindex)), NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_ONLY_DEFAULT, _STRUCT_SIZE (NMPCacheId, object_type_by_ifindex)), NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, _STRUCT_SIZE (NMPCacheId, link_by_ifname)), + NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP4, _STRUCT_SIZE (NMPCacheId, routes_by_destination_ip4)), + NM_UTILS_LOOKUP_ITEM (NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP6, _STRUCT_SIZE (NMPCacheId, routes_by_destination_ip6)), NM_UTILS_LOOKUP_ITEM_IGNORE (NMP_CACHE_ID_TYPE_NONE), NM_UTILS_LOOKUP_ITEM_IGNORE (__NMP_CACHE_ID_TYPE_MAX), ); @@ -1110,6 +1112,33 @@ nmp_cache_id_init_link_by_ifname (NMPCacheId *id, return id; } +NMPCacheId * +nmp_cache_id_init_routes_by_destination_ip4 (NMPCacheId *id, + guint32 network, + guint8 plen, + guint32 metric) +{ + _nmp_cache_id_init (id, NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP4); + id->routes_by_destination_ip4.plen = plen; + memcpy (&id->routes_by_destination_ip4._misaligned_metric, &metric, sizeof (guint32)); + memcpy (&id->routes_by_destination_ip4._misaligned_network, &network, sizeof (guint32)); + return id; +} + +NMPCacheId * +nmp_cache_id_init_routes_by_destination_ip6 (NMPCacheId *id, + const struct in6_addr *network, + guint8 plen, + guint32 metric) +{ + _nmp_cache_id_init (id, NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP6); + id->routes_by_destination_ip4.plen = plen; + memcpy (&id->routes_by_destination_ip6._misaligned_metric, &metric, sizeof (guint32)); + if (network) + memcpy (&id->routes_by_destination_ip6._misaligned_network, network, sizeof (struct in6_addr)); + return id; +} + /******************************************************************/ static gboolean @@ -1182,7 +1211,7 @@ _vt_cmd_obj_init_cache_id_ipx_address (const NMPObject *obj, NMPCacheIdType id_t return TRUE; } -static const guint8 _supported_cache_ids_ipx_route[] = { +static const guint8 _supported_cache_ids_ip4_route[] = { NMP_CACHE_ID_TYPE_OBJECT_TYPE, NMP_CACHE_ID_TYPE_OBJECT_TYPE_VISIBLE_ONLY, NMP_CACHE_ID_TYPE_ADDRROUTE_VISIBLE_BY_IFINDEX, @@ -1190,6 +1219,19 @@ static const guint8 _supported_cache_ids_ipx_route[] = { NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_ONLY_DEFAULT, NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_NO_DEFAULT, NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_ONLY_DEFAULT, + NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP4, + 0, +}; + +static const guint8 _supported_cache_ids_ip6_route[] = { + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_TYPE_VISIBLE_ONLY, + NMP_CACHE_ID_TYPE_ADDRROUTE_VISIBLE_BY_IFINDEX, + NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_NO_DEFAULT, + NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_ONLY_DEFAULT, + NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_NO_DEFAULT, + NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_ONLY_DEFAULT, + NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP6, 0, }; @@ -1236,6 +1278,18 @@ _vt_cmd_obj_init_cache_id_ipx_route (const NMPObject *obj, NMPCacheIdType id_typ return TRUE; } break; + case NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP4: + if (NMP_OBJECT_GET_CLASS (obj)->obj_type == NMP_OBJECT_TYPE_IP4_ROUTE) { + *out_id = nmp_cache_id_init_routes_by_destination_ip4 (id, obj->ip4_route.network, obj->ip_route.plen, obj->ip_route.metric); + return TRUE; + } + return FALSE; + case NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP6: + if (NMP_OBJECT_GET_CLASS (obj)->obj_type == NMP_OBJECT_TYPE_IP6_ROUTE) { + *out_id = nmp_cache_id_init_routes_by_destination_ip6 (id, &obj->ip6_route.network, obj->ip_route.plen, obj->ip_route.metric); + return TRUE; + } + return FALSE; default: return FALSE; } @@ -1404,6 +1458,51 @@ nmp_cache_lookup_link (const NMPCache *cache, int ifindex) return nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&obj_needle, ifindex)); } +/** + * nmp_cache_find_other_route_for_same_destination: + * @cache: + * @route: + * + * Look into the cache whether there is a route to the same destination, + * in terms of network/plen,metric. + * + * Returns: (transfer none): the first found route object from the cache + * that has the same (network/plen,metric) values as @route, but has different + * ID. Or %NULL, if no such route exists. + */ +const NMPObject * +nmp_cache_find_other_route_for_same_destination (const NMPCache *cache, const NMPObject *route) +{ + NMPCacheId cache_id; + const NMPlatformObject *const *list; + + nm_assert (cache); + + switch (NMP_OBJECT_GET_TYPE (route)) { + case NMP_OBJECT_TYPE_IP4_ROUTE: + nmp_cache_id_init_routes_by_destination_ip4 (&cache_id, route->ip4_route.network, route->ip_route.plen, route->ip_route.metric); + break; + case NMP_OBJECT_TYPE_IP6_ROUTE: + nmp_cache_id_init_routes_by_destination_ip6 (&cache_id, &route->ip6_route.network, route->ip_route.plen, route->ip_route.metric); + break; + default: + g_return_val_if_reached (NULL); + } + + list = nmp_cache_lookup_multi (cache, &cache_id, NULL); + if (list) { + for (; *list; list++) { + const NMPObject *candidate = NMP_OBJECT_UP_CAST (*list); + + nm_assert (NMP_OBJECT_GET_CLASS (route) == NMP_OBJECT_GET_CLASS (candidate)); + + if (!nmp_object_id_equal (route, candidate)) + return candidate; + } + } + return NULL; +} + const NMPObject * nmp_cache_lookup_link_full (const NMPCache *cache, int ifindex, @@ -2066,7 +2165,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .rtm_gettype = RTM_GETROUTE, .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, + .supported_cache_ids = _supported_cache_ids_ip4_route, .cmd_obj_init_cache_id = _vt_cmd_obj_init_cache_id_ipx_route, .cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_ip4_route, .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, @@ -2086,7 +2185,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .rtm_gettype = RTM_GETROUTE, .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, + .supported_cache_ids = _supported_cache_ids_ip6_route, .cmd_obj_init_cache_id = _vt_cmd_obj_init_cache_id_ipx_route, .cmd_obj_stackinit_id = _vt_cmd_obj_stackinit_id_ip6_route, .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 72d6270814..c5241037d5 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -79,6 +79,17 @@ typedef enum { /*< skip >*/ NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_NO_DEFAULT, NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_ONLY_DEFAULT, + /* Consider all the destination fields of a route, that is, the ID without the ifindex + * and gateway (meaning: network/plen,metric). + * The reason for this is that `ip route change` can replace an existing route + * and modify it's ifindex/gateway. Effectively, that means it deletes an existing + * route and adds a different one (as the ID of the route changes). However, it only + * sends one RTM_NEWADDR notification without notifying about the deletion. We detect + * that by having this index to contain overlapping routes which require special + * cache-resync. */ + NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP4, + NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP6, + __NMP_CACHE_ID_TYPE_MAX, NMP_CACHE_ID_TYPE_MAX = __NMP_CACHE_ID_TYPE_MAX - 1, } NMPCacheIdType; @@ -110,6 +121,20 @@ typedef struct { guint8 _id_type; char ifname_short[IFNAMSIZ - 1]; /* don't include the trailing NUL so the struct fits in 4 bytes. */ } link_by_ifname; + struct _nm_packed { + /* NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP6 */ + guint8 _id_type; + guint8 plen; + guint32 _misaligned_metric; + guint32 _misaligned_network; + } routes_by_destination_ip4; + struct _nm_packed { + /* NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP4 */ + guint8 _id_type; + guint8 plen; + guint32 _misaligned_metric; + struct in6_addr _misaligned_network; + } routes_by_destination_ip6; }; } NMPCacheId; @@ -384,12 +409,16 @@ NMPCacheId *nmp_cache_id_init_object_type (NMPCacheId *id, NMPObjectType obj_typ NMPCacheId *nmp_cache_id_init_addrroute_visible_by_ifindex (NMPCacheId *id, NMPObjectType obj_type, int ifindex); NMPCacheId *nmp_cache_id_init_routes_visible (NMPCacheId *id, NMPObjectType obj_type, gboolean with_default, gboolean with_non_default, int ifindex); NMPCacheId *nmp_cache_id_init_link_by_ifname (NMPCacheId *id, const char *ifname); +NMPCacheId *nmp_cache_id_init_routes_by_destination_ip4 (NMPCacheId *id, guint32 network, guint8 plen, guint32 metric); +NMPCacheId *nmp_cache_id_init_routes_by_destination_ip6 (NMPCacheId *id, const struct in6_addr *network, guint8 plen, guint32 metric); const NMPlatformObject *const *nmp_cache_lookup_multi (const NMPCache *cache, const NMPCacheId *cache_id, guint *out_len); GArray *nmp_cache_lookup_multi_to_array (const NMPCache *cache, NMPObjectType obj_type, const NMPCacheId *cache_id); const NMPObject *nmp_cache_lookup_obj (const NMPCache *cache, const NMPObject *obj); const NMPObject *nmp_cache_lookup_link (const NMPCache *cache, int ifindex); +const NMPObject *nmp_cache_find_other_route_for_same_destination (const NMPCache *cache, const NMPObject *route); + const NMPObject *nmp_cache_lookup_link_full (const NMPCache *cache, int ifindex, const char *ifname, From 0a97605d2e9ecaf6ba984195ecda7a8d5422adbd Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 8 Apr 2016 15:05:35 +0200 Subject: [PATCH 31/31] platform: set NLM_F_EXCL when adding links When adding a link, set both NLM_F_CREATE and NLM_F_EXCL flags. `ip route add` and systemd-networkd sets NLM_F_EXCL too. (cherry picked from commit 4bb76fb4c3f25e0ab2477ee1665b162b038b654e) --- src/platform/nm-linux-platform.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index f4a4ba86d8..ded019e642 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -4058,7 +4058,7 @@ link_add (NMPlatform *platform, name, nm_link_type_to_string (type), (int) type); nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE, + NLM_F_CREATE | NLM_F_EXCL, 0, name, 0, @@ -4450,7 +4450,7 @@ vlan_add (NMPlatform *platform, name, parent, vlan_id, (unsigned int) vlan_flags); nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE, + NLM_F_CREATE | NLM_F_EXCL, 0, name, 0, @@ -4494,7 +4494,7 @@ link_gre_add (NMPlatform *platform, nm_utils_inet4_ntop (props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE, + NLM_F_CREATE | NLM_F_EXCL, 0, name, 0, @@ -4550,7 +4550,7 @@ link_ip6tnl_add (NMPlatform *platform, nm_utils_inet6_ntop (&props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE, + NLM_F_CREATE | NLM_F_EXCL, 0, name, 0, @@ -4610,7 +4610,7 @@ link_ipip_add (NMPlatform *platform, nm_utils_inet4_ntop (props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE, + NLM_F_CREATE | NLM_F_EXCL, 0, name, 0, @@ -4660,7 +4660,7 @@ link_macvlan_add (NMPlatform *platform, props->mode); nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE, + NLM_F_CREATE | NLM_F_EXCL, 0, name, 0, @@ -4710,7 +4710,7 @@ link_sit_add (NMPlatform *platform, nm_utils_inet4_ntop (props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE, + NLM_F_CREATE | NLM_F_EXCL, 0, name, 0, @@ -4759,7 +4759,7 @@ link_vxlan_add (NMPlatform *platform, name, props->parent_ifindex, props->id); nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE, + NLM_F_CREATE | NLM_F_EXCL, 0, name, 0,