1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* NetworkManager audit support
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Copyright 2016 Red Hat, Inc.
21 #include "nm-default.h"
24 #include <sys/mount.h>
26 #include <sys/types.h>
28 #include "nmp-object.h"
29 #include "nmp-netns.h"
30 #include "nm-platform-utils.h"
32 #include "test-common.h"
33 #include "nm-test-utils.h"
37 #define LO_TYPEDESC "loopback"
39 #define DUMMY_TYPEDESC "dummy"
40 #define BOGUS_NAME "nm-bogus-device"
41 #define BOGUS_IFINDEX INT_MAX
42 #define SLAVE_NAME "nm-test-slave"
43 #define PARENT_NAME "nm-test-parent"
48 #define _ADD_DUMMY(platform, name) \
49 g_assert_cmpint (nm_platform_link_dummy_add ((platform), (name), NULL), ==, NM_PLATFORM_ERROR_SUCCESS)
56 g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, BOGUS_NAME));
57 g_assert (!nm_platform_link_delete (NM_PLATFORM_GET, BOGUS_IFINDEX));
58 g_assert (!nm_platform_link_get_ifindex (NM_PLATFORM_GET, BOGUS_NAME));
59 g_assert (!nm_platform_link_get_name (NM_PLATFORM_GET, BOGUS_IFINDEX));
60 g_assert (!nm_platform_link_get_type (NM_PLATFORM_GET, BOGUS_IFINDEX));
61 g_assert (!nm_platform_link_get_type_name (NM_PLATFORM_GET, BOGUS_IFINDEX));
63 g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *");
64 g_assert (!nm_platform_link_set_up (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL));
66 g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *");
67 g_assert (!nm_platform_link_set_down (NM_PLATFORM_GET, BOGUS_IFINDEX));
69 g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *");
70 g_assert (!nm_platform_link_set_arp (NM_PLATFORM_GET, BOGUS_IFINDEX));
72 g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *");
73 g_assert (!nm_platform_link_set_noarp (NM_PLATFORM_GET, BOGUS_IFINDEX));
75 g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, BOGUS_IFINDEX));
76 g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, BOGUS_IFINDEX));
77 g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, BOGUS_IFINDEX));
79 g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, &addrlen));
81 g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL));
83 g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *");
84 g_assert (!nm_platform_link_set_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX, MTU));
86 g_assert (!nm_platform_link_get_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX));
88 g_assert (!nm_platform_link_supports_carrier_detect (NM_PLATFORM_GET, BOGUS_IFINDEX));
89 g_assert (!nm_platform_link_supports_vlans (NM_PLATFORM_GET, BOGUS_IFINDEX));
91 g_assert (!nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL));
92 g_assert (!nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, BOGUS_IFINDEX, 0, 0));
93 g_assert (!nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, BOGUS_IFINDEX, 0, 0));
99 g_assert (nm_platform_link_get_by_ifname (NM_PLATFORM_GET, LO_NAME));
100 g_assert_cmpint (nm_platform_link_get_type (NM_PLATFORM_GET, LO_INDEX), ==, NM_LINK_TYPE_LOOPBACK);
101 g_assert_cmpint (nm_platform_link_get_ifindex (NM_PLATFORM_GET, LO_NAME), ==, LO_INDEX);
102 g_assert_cmpstr (nm_platform_link_get_name (NM_PLATFORM_GET, LO_INDEX), ==, LO_NAME);
103 g_assert_cmpstr (nm_platform_link_get_type_name (NM_PLATFORM_GET, LO_INDEX), ==, LO_TYPEDESC);
105 g_assert (nm_platform_link_supports_carrier_detect (NM_PLATFORM_GET, LO_INDEX));
106 g_assert (!nm_platform_link_supports_vlans (NM_PLATFORM_GET, LO_INDEX));
110 software_add (NMLinkType link_type, const char *name)
113 case NM_LINK_TYPE_DUMMY:
114 return nm_platform_link_dummy_add (NM_PLATFORM_GET, name, NULL) == NM_PLATFORM_ERROR_SUCCESS;
115 case NM_LINK_TYPE_BRIDGE:
116 return nm_platform_link_bridge_add (NM_PLATFORM_GET, name, NULL, 0, NULL) == NM_PLATFORM_ERROR_SUCCESS;
117 case NM_LINK_TYPE_BOND:
119 gboolean bond0_exists = !!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "bond0");
120 NMPlatformError plerr;
122 plerr = nm_platform_link_bond_add (NM_PLATFORM_GET, name, NULL);
124 /* Check that bond0 is *not* automatically created. */
126 g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "bond0"));
127 return plerr == NM_PLATFORM_ERROR_SUCCESS;
129 case NM_LINK_TYPE_TEAM:
130 return nm_platform_link_team_add (NM_PLATFORM_GET, name, NULL) == NM_PLATFORM_ERROR_SUCCESS;
131 case NM_LINK_TYPE_VLAN: {
132 SignalData *parent_added;
133 SignalData *parent_changed;
135 /* Don't call link_callback for the bridge interface */
136 parent_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, PARENT_NAME);
137 if (nm_platform_link_bridge_add (NM_PLATFORM_GET, PARENT_NAME, NULL, 0, NULL) == NM_PLATFORM_ERROR_SUCCESS)
138 accept_signal (parent_added);
139 free_signal (parent_added);
142 int parent_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME);
143 gboolean was_up = nm_platform_link_is_up (NM_PLATFORM_GET, parent_ifindex);
145 parent_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, parent_ifindex);
146 g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, parent_ifindex, NULL));
148 /* when NM is running in the background, it will mess with addrgenmode which might cause additional signals. */
149 accept_signals (parent_changed, 0, 1);
151 accept_signal (parent_changed);
152 free_signal (parent_changed);
154 return nm_platform_link_vlan_add (NM_PLATFORM_GET, name, parent_ifindex, VLAN_ID, 0, NULL) == NM_PLATFORM_ERROR_SUCCESS;
158 g_error ("Link type %d unhandled.", link_type);
160 g_assert_not_reached ();
164 test_link_changed_signal_cb (NMPlatform *platform,
165 NMPObjectType obj_type,
167 const NMPlatformIP4Route *route,
168 NMPlatformSignalChangeType change_type,
169 gboolean *p_test_link_changed_signal_arg)
171 /* test invocation of platform signals with multiple listeners
172 * connected to the signal. Platform signals have enum-typed
173 * arguments and there seem to be an issue with invoking such
174 * signals on s390x and ppc64 archs.
175 * https://bugzilla.redhat.com/show_bug.cgi?id=1260577
177 * As the test shows, the failure is not reproducible for
180 g_assert (NM_IS_PLATFORM (platform));
181 g_assert (platform == NM_PLATFORM_GET);
183 g_assert (ifindex > 0);
186 g_assert_cmpint (obj_type, ==, NMP_OBJECT_TYPE_LINK);
188 g_assert_cmpint ((gint64) change_type, !=, (gint64) 0);
189 g_assert_cmpint (change_type, !=, NM_PLATFORM_SIGNAL_NONE);
191 *p_test_link_changed_signal_arg = TRUE;
195 test_slave (int master, int type, SignalData *master_changed)
198 SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, SLAVE_NAME);
199 SignalData *link_changed, *link_removed;
201 NMLinkType link_type = nm_platform_link_get_type (NM_PLATFORM_GET, master);
202 gboolean test_link_changed_signal_arg1;
203 gboolean test_link_changed_signal_arg2;
205 g_assert (NM_IN_SET (link_type, NM_LINK_TYPE_TEAM, NM_LINK_TYPE_BOND, NM_LINK_TYPE_BRIDGE));
207 g_assert (software_add (type, SLAVE_NAME));
208 ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, SLAVE_NAME);
209 g_assert (ifindex > 0);
210 link_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, ifindex);
211 link_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, ifindex);
212 accept_signal (link_added);
214 /* Set the slave up to see whether master's IFF_LOWER_UP is set correctly.
216 * See https://bugzilla.redhat.com/show_bug.cgi?id=910348
218 g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
219 g_assert (nm_platform_link_set_down (NM_PLATFORM_GET, ifindex));
220 g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
221 ensure_no_signal (link_changed);
224 link_changed->ifindex = ifindex;
225 g_assert (nm_platform_link_enslave (NM_PLATFORM_GET, master, ifindex));
226 g_assert_cmpint (nm_platform_link_get_master (NM_PLATFORM_GET, ifindex), ==, master);
228 accept_signals (link_changed, 1, 3);
229 accept_signals (master_changed, 0, 1);
231 /* enslaveing brings put the slave */
232 if (NM_IN_SET (link_type, NM_LINK_TYPE_BOND, NM_LINK_TYPE_TEAM))
233 g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
235 g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
237 test_link_changed_signal_arg1 = FALSE;
238 test_link_changed_signal_arg2 = FALSE;
239 g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (test_link_changed_signal_cb), &test_link_changed_signal_arg1);
240 g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (test_link_changed_signal_cb), &test_link_changed_signal_arg2);
243 g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, master, NULL));
244 g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, master));
245 accept_signals (master_changed, 1, 2);
247 g_signal_handlers_disconnect_by_func (NM_PLATFORM_GET, G_CALLBACK (test_link_changed_signal_cb), &test_link_changed_signal_arg1);
248 g_signal_handlers_disconnect_by_func (NM_PLATFORM_GET, G_CALLBACK (test_link_changed_signal_cb), &test_link_changed_signal_arg2);
249 g_assert (test_link_changed_signal_arg1);
250 g_assert (test_link_changed_signal_arg2);
252 /* Master with a disconnected slave is disconnected
254 * For some reason, bonding and teaming slaves are automatically set up. We
255 * need to set them back down for this test.
257 switch (nm_platform_link_get_type (NM_PLATFORM_GET, master)) {
258 case NM_LINK_TYPE_BOND:
259 case NM_LINK_TYPE_TEAM:
260 g_assert (nm_platform_link_set_down (NM_PLATFORM_GET, ifindex));
261 accept_signal (link_changed);
262 accept_signals (master_changed, 0, 2);
267 g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
268 g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
269 if (nm_platform_link_is_connected (NM_PLATFORM_GET, master)) {
270 if (nm_platform_link_get_type (NM_PLATFORM_GET, master) == NM_LINK_TYPE_TEAM) {
271 /* Older team versions (e.g. Fedora 17) have a bug that team master stays
272 * IFF_LOWER_UP even if its slave is down. Double check it with iproute2 and if
273 * `ip link` also claims master to be up, accept it. */
274 char *stdout_str = NULL;
276 nmtst_spawn_sync (NULL, &stdout_str, NULL, 0, "/sbin/ip", "link", "show", "dev", nm_platform_link_get_name (NM_PLATFORM_GET, master));
278 g_assert (strstr (stdout_str, "LOWER_UP"));
281 g_assert_not_reached ();
284 /* Set slave up and see if master gets up too */
285 g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL));
286 g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
287 g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, master));
288 accept_signals (link_changed, 1, 3);
289 /* NM running, can cause additional change of addrgenmode */
290 accept_signals (master_changed, 1, 2);
294 * Gracefully succeed if already enslaved.
296 ensure_no_signal (link_changed);
297 g_assert (nm_platform_link_enslave (NM_PLATFORM_GET, master, ifindex));
298 accept_signals (link_changed, 0, 2);
299 ensure_no_signal (master_changed);
301 /* Set slave option */
303 case NM_LINK_TYPE_BRIDGE:
304 if (nmtstp_is_sysfs_writable ()) {
305 g_assert (nm_platform_sysctl_slave_set_option (NM_PLATFORM_GET, ifindex, "priority", "789"));
306 value = nm_platform_sysctl_slave_get_option (NM_PLATFORM_GET, ifindex, "priority");
307 g_assert_cmpstr (value, ==, "789");
316 ensure_no_signal (link_added);
317 ensure_no_signal (link_changed);
318 ensure_no_signal (link_removed);
319 g_assert (nm_platform_link_release (NM_PLATFORM_GET, master, ifindex));
320 g_assert_cmpint (nm_platform_link_get_master (NM_PLATFORM_GET, ifindex), ==, 0);
321 if (link_changed->received_count > 0) {
322 accept_signals (link_added, 0, 1);
323 accept_signals (link_changed, 1, 3);
324 accept_signals (link_removed, 0, 1);
326 /* Due to https://bugzilla.redhat.com/show_bug.cgi?id=1285719 , kernel might send a
327 * wrong RTM_DELLINK message so that we instead see an removed+added signal. */
328 accept_signal (link_added);
329 ensure_no_signal (link_changed);
330 accept_signal (link_removed);
332 accept_signals (master_changed, 1, 2);
334 ensure_no_signal (master_changed);
337 ensure_no_signal (link_changed);
338 g_assert (!nm_platform_link_release (NM_PLATFORM_GET, master, ifindex));
340 ensure_no_signal (master_changed);
343 ensure_no_signal (link_added);
344 ensure_no_signal (link_changed);
345 ensure_no_signal (link_removed);
346 nmtstp_link_del (-1, ifindex, NULL);
347 accept_signals (master_changed, 0, 1);
348 accept_signals (link_changed, 0, 1);
349 accept_signal (link_removed);
351 free_signal (link_added);
352 free_signal (link_changed);
353 free_signal (link_removed);
357 test_software (NMLinkType link_type, const char *link_typename)
361 int vlan_parent = -1, vlan_id;
363 SignalData *link_added, *link_changed, *link_removed;
366 link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME);
367 g_assert (software_add (link_type, DEVICE_NAME));
368 accept_signal (link_added);
369 g_assert (nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME));
370 ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
371 g_assert (ifindex >= 0);
372 g_assert_cmpint (nm_platform_link_get_type (NM_PLATFORM_GET, ifindex), ==, link_type);
373 g_assert_cmpstr (nm_platform_link_get_type_name (NM_PLATFORM_GET, ifindex), ==, link_typename);
374 link_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, ifindex);
375 link_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, ifindex);
376 if (link_type == NM_LINK_TYPE_VLAN) {
377 const NMPlatformLink *plink;
378 const NMPlatformLnkVlan *plnk;
380 plnk = nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, &plink);
384 vlan_parent = plink->parent;
386 g_assert_cmpint (vlan_parent, ==, nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME));
387 g_assert_cmpint (vlan_id, ==, VLAN_ID);
391 g_assert (!software_add (link_type, DEVICE_NAME));
394 g_assert (nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
395 g_assert (nm_platform_link_set_noarp (NM_PLATFORM_GET, ifindex));
396 g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
397 accept_signals (link_changed, 1, 2);
398 g_assert (nm_platform_link_set_arp (NM_PLATFORM_GET, ifindex));
399 g_assert (nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
400 accept_signal (link_changed);
402 /* Set master option */
404 case NM_LINK_TYPE_BRIDGE:
405 if (nmtstp_is_sysfs_writable ()) {
406 g_assert (nm_platform_sysctl_master_set_option (NM_PLATFORM_GET, ifindex, "forward_delay", "789"));
407 value = nm_platform_sysctl_master_get_option (NM_PLATFORM_GET, ifindex, "forward_delay");
408 g_assert_cmpstr (value, ==, "789");
412 case NM_LINK_TYPE_BOND:
413 if (nmtstp_is_sysfs_writable ()) {
414 g_assert (nm_platform_sysctl_master_set_option (NM_PLATFORM_GET, ifindex, "mode", "active-backup"));
415 value = nm_platform_sysctl_master_get_option (NM_PLATFORM_GET, ifindex, "mode");
416 /* When reading back, the output looks slightly different. */
417 g_assert (g_str_has_prefix (value, "active-backup"));
425 /* Enslave and release */
427 case NM_LINK_TYPE_BRIDGE:
428 case NM_LINK_TYPE_BOND:
429 case NM_LINK_TYPE_TEAM:
430 link_changed->ifindex = ifindex;
431 test_slave (ifindex, NM_LINK_TYPE_DUMMY, link_changed);
432 link_changed->ifindex = 0;
437 free_signal (link_changed);
440 nmtstp_link_del (-1, ifindex, DEVICE_NAME);
441 accept_signal (link_removed);
444 g_assert (!nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)));
445 g_assert (!nm_platform_link_delete (NM_PLATFORM_GET, ifindex));
447 /* VLAN: Delete parent */
448 if (link_type == NM_LINK_TYPE_VLAN) {
449 SignalData *link_removed_parent = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, vlan_parent);
451 nmtstp_link_del (-1, vlan_parent, NULL);
452 accept_signal (link_removed_parent);
453 free_signal (link_removed_parent);
456 /* No pending signal */
457 free_signal (link_added);
458 free_signal (link_removed);
464 test_software (NM_LINK_TYPE_BRIDGE, "bridge");
470 if (nmtstp_is_root_test () &&
471 !g_file_test ("/proc/1/net/bonding", G_FILE_TEST_IS_DIR) &&
472 system("modprobe --show bonding") != 0) {
473 g_test_skip ("Skipping test for bonding: bonding module not available");
477 test_software (NM_LINK_TYPE_BOND, "bond");
483 test_software (NM_LINK_TYPE_TEAM, "team");
489 test_software (NM_LINK_TYPE_VLAN, "vlan");
492 /*****************************************************************************/
495 test_bridge_addr (void)
499 const NMPlatformLink *plink = NULL;
501 nm_utils_hwaddr_aton ("de:ad:be:ef:00:11", addr, sizeof (addr));
503 g_assert_cmpint (nm_platform_link_bridge_add (NM_PLATFORM_GET, DEVICE_NAME, addr, sizeof (addr), &plink), ==, NM_PLATFORM_ERROR_SUCCESS);
506 g_assert_cmpstr (link.name, ==, DEVICE_NAME);
508 g_assert_cmpint (link.addr.len, ==, sizeof (addr));
509 g_assert (!memcmp (link.addr.data, addr, sizeof (addr)));
511 plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex);
514 if (nm_platform_check_support_user_ipv6ll (NM_PLATFORM_GET)) {
515 g_assert (!nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex));
516 g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_EUI64);
518 g_assert (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, TRUE));
519 g_assert (nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex));
520 plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex);
522 g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_NONE);
524 g_assert (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, FALSE));
525 g_assert (!nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex));
526 plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex);
528 g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_EUI64);
531 g_assert_cmpint (plink->addr.len, ==, sizeof (addr));
532 g_assert (!memcmp (plink->addr.data, addr, sizeof (addr)));
534 nmtstp_link_del (-1, link.ifindex, link.name);
537 /*****************************************************************************/
542 SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME);
543 SignalData *link_changed, *link_removed;
544 const char mac[6] = { 0x00, 0xff, 0x11, 0xee, 0x22, 0xdd };
549 /* Check the functions for non-existent devices */
550 g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME));
551 g_assert (!nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME));
554 g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == NM_PLATFORM_ERROR_SUCCESS);
555 accept_signal (link_added);
557 /* Try to add again */
558 g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == NM_PLATFORM_ERROR_EXISTS);
560 /* Check device index, name and type */
561 ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
562 g_assert (ifindex > 0);
563 g_assert_cmpstr (nm_platform_link_get_name (NM_PLATFORM_GET, ifindex), ==, DEVICE_NAME);
564 g_assert_cmpint (nm_platform_link_get_type (NM_PLATFORM_GET, ifindex), ==, NM_LINK_TYPE_DUMMY);
565 g_assert_cmpstr (nm_platform_link_get_type_name (NM_PLATFORM_GET, ifindex), ==, DUMMY_TYPEDESC);
566 link_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, ifindex);
567 link_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, ifindex);
570 g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
571 g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
572 g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL));
573 g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
574 g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
575 accept_signal (link_changed);
576 g_assert (nm_platform_link_set_down (NM_PLATFORM_GET, ifindex));
577 g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
578 g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
579 accept_signal (link_changed);
582 g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
583 g_assert (nm_platform_link_set_arp (NM_PLATFORM_GET, ifindex));
584 g_assert (nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
585 accept_signal (link_changed);
586 g_assert (nm_platform_link_set_noarp (NM_PLATFORM_GET, ifindex));
587 g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
588 accept_signal (link_changed);
591 g_assert (!nm_platform_link_supports_carrier_detect (NM_PLATFORM_GET, ifindex));
592 g_assert (nm_platform_link_supports_vlans (NM_PLATFORM_GET, ifindex));
594 /* Set MAC address */
595 g_assert (nm_platform_link_set_address (NM_PLATFORM_GET, ifindex, mac, sizeof (mac)));
596 address = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &addrlen);
597 g_assert (addrlen == sizeof(mac));
598 g_assert (!memcmp (address, mac, addrlen));
599 address = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, NULL);
600 g_assert (!memcmp (address, mac, addrlen));
601 accept_signal (link_changed);
604 g_assert (nm_platform_link_set_mtu (NM_PLATFORM_GET, ifindex, MTU));
605 g_assert_cmpint (nm_platform_link_get_mtu (NM_PLATFORM_GET, ifindex), ==, MTU);
606 accept_signal (link_changed);
609 nmtstp_link_del (-1, ifindex, DEVICE_NAME);
610 accept_signal (link_removed);
612 /* Try to delete again */
613 g_assert (!nm_platform_link_delete (NM_PLATFORM_GET, ifindex));
615 free_signal (link_added);
616 free_signal (link_changed);
617 free_signal (link_removed);
620 /*****************************************************************************/
625 const NMPlatformLink *pllink;
626 SignalData *link_added, *link_changed, *link_removed;
629 link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME);
631 nmtstp_run_command_check ("ip link add %s type %s", DEVICE_NAME, "dummy");
632 wait_signal (link_added);
634 g_assert (nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME));
635 ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
636 g_assert (ifindex > 0);
637 g_assert_cmpstr (nm_platform_link_get_name (NM_PLATFORM_GET, ifindex), ==, DEVICE_NAME);
638 g_assert_cmpint (nm_platform_link_get_type (NM_PLATFORM_GET, ifindex), ==, NM_LINK_TYPE_DUMMY);
639 g_assert_cmpstr (nm_platform_link_get_type_name (NM_PLATFORM_GET, ifindex), ==, DUMMY_TYPEDESC);
640 link_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, ifindex);
641 link_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, ifindex);
643 pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex);
645 if (!pllink->initialized) {
646 /* we still lack the notification via UDEV. Expect another link changed signal. */
647 wait_signal (link_changed);
650 /* Up/connected/arp */
651 g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
652 g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
653 g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
655 nmtstp_run_command_check ("ip link set %s up", DEVICE_NAME);
656 wait_signal (link_changed);
658 g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
659 g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
660 nmtstp_run_command_check ("ip link set %s down", DEVICE_NAME);
661 wait_signal (link_changed);
662 g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
663 g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
665 nmtstp_run_command_check ("ip link set %s arp on", DEVICE_NAME);
666 wait_signal (link_changed);
667 g_assert (nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
668 nmtstp_run_command_check ("ip link set %s arp off", DEVICE_NAME);
669 wait_signal (link_changed);
670 g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex));
672 nmtstp_run_command_check ("ip link del %s", DEVICE_NAME);
673 wait_signal (link_removed);
674 accept_signals (link_changed, 0, 1);
675 g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME));
677 free_signal (link_added);
678 free_signal (link_changed);
679 free_signal (link_removed);
682 /*****************************************************************************/
685 NMLinkType link_type;
687 gboolean external_command;
688 } TestAddSoftwareDetectData;
691 test_software_detect (gconstpointer user_data)
693 const TestAddSoftwareDetectData *test_data = user_data;
694 int ifindex, ifindex_parent;
695 const NMPlatformLink *plink;
696 const NMPObject *lnk;
698 const gboolean ext = test_data->external_command;
700 nmtstp_run_command_check ("ip link add %s type dummy", PARENT_NAME);
701 ifindex_parent = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, PARENT_NAME, NM_LINK_TYPE_DUMMY, 100)->ifindex;
703 switch (test_data->link_type) {
704 case NM_LINK_TYPE_GRE: {
705 NMPlatformLnkGre lnk_gre = { };
706 gboolean gracefully_skip = FALSE;
708 lnk_gre.local = nmtst_inet4_from_string ("192.168.233.204");
709 lnk_gre.remote = nmtst_inet4_from_string ("172.168.10.25");
710 lnk_gre.parent_ifindex = ifindex_parent;
713 lnk_gre.path_mtu_discovery = TRUE;
715 if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "gre0")) {
716 /* Seems that the ip_gre module is not loaded... try to load it. */
717 gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip_gre", NULL) != 0;
720 if (!nmtstp_link_gre_add (ext, DEVICE_NAME, &lnk_gre)) {
721 if (gracefully_skip) {
722 g_test_skip ("Cannot create gre tunnel because of missing ip_gre module (modprobe ip_gre)");
723 goto out_delete_parent;
725 g_error ("Failed adding GRE tunnel");
729 case NM_LINK_TYPE_IPIP: {
730 NMPlatformLnkIpIp lnk_ipip = { };
731 gboolean gracefully_skip = FALSE;
733 if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "tunl0")) {
734 /* Seems that the ipip module is not loaded... try to load it. */
735 gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ipip", NULL) != 0;
738 lnk_ipip.local = nmtst_inet4_from_string ("1.2.3.4");
739 lnk_ipip.remote = nmtst_inet4_from_string ("5.6.7.8");
740 lnk_ipip.parent_ifindex = ifindex_parent;
742 lnk_ipip.path_mtu_discovery = FALSE;
744 if (!nmtstp_link_ipip_add (ext, DEVICE_NAME, &lnk_ipip)) {
745 if (gracefully_skip) {
746 g_test_skip ("Cannot create ipip tunnel because of missing ipip module (modprobe ipip)");
747 goto out_delete_parent;
749 g_error ("Failed adding IPIP tunnel");
753 case NM_LINK_TYPE_IP6TNL: {
754 NMPlatformLnkIp6Tnl lnk_ip6tnl = { };
755 gboolean gracefully_skip = FALSE;
757 if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "ip6tnl0")) {
758 /* Seems that the ip6_tunnel module is not loaded... try to load it. */
759 gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_tunnel", NULL) != 0;
762 lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::15");
763 lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::16");
764 lnk_ip6tnl.parent_ifindex = ifindex_parent;
765 lnk_ip6tnl.tclass = 20;
766 lnk_ip6tnl.encap_limit = 6;
767 lnk_ip6tnl.flow_label = 1337;
768 lnk_ip6tnl.proto = IPPROTO_IPV6;
770 if (!nmtstp_link_ip6tnl_add (ext, DEVICE_NAME, &lnk_ip6tnl)) {
771 if (gracefully_skip) {
772 g_test_skip ("Cannot create ip6tnl tunnel because of missing ip6_tunnel module (modprobe ip6_tunnel)");
773 goto out_delete_parent;
775 g_error ("Failed adding IP6TNL tunnel");
779 case NM_LINK_TYPE_MACVLAN: {
780 NMPlatformLnkMacvlan lnk_macvlan = { };
782 lnk_macvlan.mode = MACVLAN_MODE_BRIDGE;
783 lnk_macvlan.no_promisc = FALSE;
784 lnk_macvlan.tap = FALSE;
786 if (!nmtstp_link_macvlan_add (ext, DEVICE_NAME, ifindex_parent, &lnk_macvlan))
787 g_error ("Failed adding MACVLAN interface");
790 case NM_LINK_TYPE_MACVTAP: {
791 NMPlatformLnkMacvtap lnk_macvtap = { };
793 lnk_macvtap.mode = MACVLAN_MODE_PRIVATE;
794 lnk_macvtap.no_promisc = FALSE;
795 lnk_macvtap.tap = TRUE;
797 if (!nmtstp_link_macvlan_add (ext, DEVICE_NAME, ifindex_parent, &lnk_macvtap))
798 g_error ("Failed adding MACVTAP interface");
801 case NM_LINK_TYPE_SIT: {
802 NMPlatformLnkSit lnk_sit = { };
803 gboolean gracefully_skip = FALSE;
805 lnk_sit.local = nmtst_inet4_from_string ("192.168.200.1");
806 lnk_sit.remote = nmtst_inet4_from_string ("172.25.100.14");
807 lnk_sit.parent_ifindex = ifindex_parent;
810 lnk_sit.path_mtu_discovery = FALSE;
812 if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "sit0")) {
813 /* Seems that the sit module is not loaded... try to load it. */
814 gracefully_skip = nm_utils_modprobe (NULL, TRUE, "sit", NULL) != 0;
817 if (!nmtstp_link_sit_add (ext, DEVICE_NAME, &lnk_sit)) {
818 if (gracefully_skip) {
819 g_test_skip ("Cannot create sit tunnel because of missing sit module (modprobe sit)");
820 goto out_delete_parent;
822 g_error ("Failed adding SIT tunnel");
826 case NM_LINK_TYPE_VLAN:
827 nmtstp_run_command_check ("ip link add name %s link %s type vlan id 1242", DEVICE_NAME, PARENT_NAME);
829 case NM_LINK_TYPE_VXLAN: {
830 NMPlatformLnkVxlan lnk_vxlan = { };
832 switch (test_data->test_mode) {
834 lnk_vxlan.parent_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME);
836 lnk_vxlan.local = nmtst_inet4_from_string ("23.1.2.164");
837 lnk_vxlan.group = nmtst_inet4_from_string ("239.1.2.134");
838 lnk_vxlan.dst_port = 4789;
839 lnk_vxlan.learning = TRUE;
840 lnk_vxlan.ageing = 1245;
843 lnk_vxlan.parent_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME);
844 lnk_vxlan.id = 11214423;
845 lnk_vxlan.local6 = *nmtst_inet6_from_string ("1:2:3:4:334:23::23");
846 lnk_vxlan.group6 = *nmtst_inet6_from_string ("ff0e::115");
848 lnk_vxlan.dst_port = 57412;
849 lnk_vxlan.src_port_min = 1000;
850 lnk_vxlan.src_port_max = 1003;
851 lnk_vxlan.learning = TRUE;
852 lnk_vxlan.ageing = 3245;
856 g_assert (nmtstp_link_vxlan_add (ext, DEVICE_NAME, &lnk_vxlan));
860 g_assert_not_reached ();
863 ifindex = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, DEVICE_NAME, test_data->link_type, 100)->ifindex;
865 nmtstp_link_set_updown (-1, ifindex_parent, TRUE);
867 for (i_step = 0; i_step < 5; i_step++) {
869 _LOGD ("test-software-detect: step %u", i_step);
870 if (nmtst_is_debug ())
871 nmtstp_run_command_check ("ip -d link show %s", DEVICE_NAME);
874 gboolean set_up = (i_step % 2) == 1;
876 if ( test_data->link_type == NM_LINK_TYPE_VXLAN
878 /* On RHEL-7, we need to add a tiny sleep here, otherwise,
879 * upping the vxlan device fails with EADDRINUSE.
880 * https://bugzilla.redhat.com/show_bug.cgi?id=1277131 */
883 nmtstp_link_set_updown (-1, ifindex, set_up);
886 lnk = nm_platform_link_get_lnk (NM_PLATFORM_GET, ifindex, test_data->link_type, &plink);
888 g_assert_cmpint (plink->ifindex, ==, ifindex);
891 switch (test_data->link_type) {
892 case NM_LINK_TYPE_GRE: {
893 const NMPlatformLnkGre *plnk = &lnk->lnk_gre;
895 g_assert (plnk == nm_platform_link_get_lnk_gre (NM_PLATFORM_GET, ifindex, NULL));
896 g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
897 g_assert_cmpint (plnk->input_flags, ==, 0);
898 g_assert_cmpint (plnk->output_flags, ==, 0);
899 g_assert_cmpint (plnk->input_key, ==, 0);
900 g_assert_cmpint (plnk->output_key, ==, 0);
901 nmtst_assert_ip4_address (plnk->local, "192.168.233.204");
902 nmtst_assert_ip4_address (plnk->remote, "172.168.10.25");
903 g_assert_cmpint (plnk->ttl, ==, 174);
904 g_assert_cmpint (plnk->tos, ==, 37);
905 g_assert_cmpint (plnk->path_mtu_discovery, ==, TRUE);
908 case NM_LINK_TYPE_IP6TNL: {
909 const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl;
911 g_assert (plnk == nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, ifindex, NULL));
912 g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
913 nmtst_assert_ip6_address (&plnk->local, "fd01::15");
914 nmtst_assert_ip6_address (&plnk->remote, "fd01::16");
915 g_assert_cmpint (plnk->ttl, ==, 0);
916 g_assert_cmpint (plnk->tclass, ==, 20);
917 g_assert_cmpint (plnk->encap_limit, ==, 6);
918 g_assert_cmpint (plnk->flow_label, ==, 1337);
919 g_assert_cmpint (plnk->proto, ==, IPPROTO_IPV6);
922 case NM_LINK_TYPE_IPIP: {
923 const NMPlatformLnkIpIp *plnk = &lnk->lnk_ipip;
925 g_assert (plnk == nm_platform_link_get_lnk_ipip (NM_PLATFORM_GET, ifindex, NULL));
926 g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
927 nmtst_assert_ip4_address (plnk->local, "1.2.3.4");
928 nmtst_assert_ip4_address (plnk->remote, "5.6.7.8");
929 g_assert_cmpint (plnk->ttl, ==, 0);
930 g_assert_cmpint (plnk->tos, ==, 32);
931 g_assert_cmpint (plnk->path_mtu_discovery, ==, FALSE);
934 case NM_LINK_TYPE_MACVLAN: {
935 const NMPlatformLnkMacvlan *plnk = &lnk->lnk_macvlan;
937 g_assert (plnk == nm_platform_link_get_lnk_macvlan (NM_PLATFORM_GET, ifindex, NULL));
938 g_assert_cmpint (plnk->no_promisc, ==, FALSE);
939 g_assert_cmpint (plnk->mode, ==, MACVLAN_MODE_BRIDGE);
942 case NM_LINK_TYPE_MACVTAP: {
943 const NMPlatformLnkMacvtap *plnk = &lnk->lnk_macvlan;
945 g_assert (plnk == nm_platform_link_get_lnk_macvtap (NM_PLATFORM_GET, ifindex, NULL));
946 g_assert_cmpint (plnk->no_promisc, ==, FALSE);
947 g_assert_cmpint (plnk->mode, ==, MACVLAN_MODE_PRIVATE);
950 case NM_LINK_TYPE_SIT: {
951 const NMPlatformLnkSit *plnk = &lnk->lnk_sit;
953 g_assert (plnk == nm_platform_link_get_lnk_sit (NM_PLATFORM_GET, ifindex, NULL));
954 g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
955 nmtst_assert_ip4_address (plnk->local, "192.168.200.1");
956 nmtst_assert_ip4_address (plnk->remote, "172.25.100.14");
957 g_assert_cmpint (plnk->ttl, ==, 0);
958 g_assert_cmpint (plnk->tos, ==, 31);
959 g_assert_cmpint (plnk->path_mtu_discovery, ==, FALSE);
962 case NM_LINK_TYPE_VLAN: {
963 const NMPlatformLnkVlan *plnk = &lnk->lnk_vlan;
965 g_assert (plnk == nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, NULL));
966 g_assert_cmpint (plnk->id, ==, 1242);
969 case NM_LINK_TYPE_VXLAN: {
970 const NMPlatformLnkVxlan *plnk = &lnk->lnk_vxlan;
972 g_assert (plnk == nm_platform_link_get_lnk_vxlan (NM_PLATFORM_GET, ifindex, NULL));
973 g_assert_cmpint (plnk->parent_ifindex, !=, 0);
974 g_assert_cmpint (plnk->tos, ==, 0);
975 g_assert_cmpint (plnk->learning, ==, TRUE);
976 g_assert_cmpint (plnk->limit, ==, 0);
977 g_assert_cmpint (plnk->proxy, ==, FALSE);
978 g_assert_cmpint (plnk->rsc, ==, FALSE);
979 g_assert_cmpint (plnk->l2miss, ==, FALSE);
980 g_assert_cmpint (plnk->l3miss, ==, FALSE);
982 switch (test_data->test_mode) {
984 g_assert_cmpint (plnk->id, ==, 42);
985 nmtst_assert_ip4_address (plnk->local, "23.1.2.164");
986 nmtst_assert_ip4_address (plnk->group, "239.1.2.134");
987 nmtst_assert_ip6_address (&plnk->group6, "::");
988 nmtst_assert_ip6_address (&plnk->local6, "::");
989 g_assert_cmpint (plnk->ttl, ==, 0);
990 g_assert_cmpint (plnk->ageing, ==, 1245);
991 g_assert_cmpint (plnk->dst_port, ==, 4789);
992 if ( plnk->src_port_min != 0
993 || plnk->src_port_max != 0) {
994 /* on some kernels, omiting the port range results in setting
995 * following default port range. */
996 g_assert_cmpint (plnk->src_port_min, ==, 32768);
997 g_assert_cmpint (plnk->src_port_max, ==, 61000);
1001 g_assert_cmpint (plnk->id, ==, 11214423);
1002 nmtst_assert_ip4_address (plnk->local, "0.0.0.0");
1003 nmtst_assert_ip4_address (plnk->group, "0.0.0.0");
1004 nmtst_assert_ip6_address (&plnk->group6, "ff0e::115");
1005 nmtst_assert_ip6_address (&plnk->local6, "1:2:3:4:334:23::23");
1006 g_assert_cmpint (plnk->ageing, ==, 3245);
1007 g_assert_cmpint (plnk->dst_port, ==, 57412);
1008 g_assert_cmpint (plnk->ttl, ==, 32);
1009 g_assert_cmpint (plnk->src_port_min, ==, 1000);
1010 g_assert_cmpint (plnk->src_port_max, ==, 1003);
1016 g_assert_not_reached ();
1020 nmtstp_link_del (-1, ifindex, DEVICE_NAME);
1022 nmtstp_link_del (-1, ifindex_parent, PARENT_NAME);
1026 test_software_detect_add (const char *testpath,
1027 NMLinkType link_type,
1030 TestAddSoftwareDetectData *test_data;
1033 test_data = g_new0 (TestAddSoftwareDetectData, 1);
1034 test_data->link_type = link_type;
1035 test_data->test_mode = test_mode;
1036 test_data->external_command = TRUE;
1038 path = g_strdup_printf ("%s/external", testpath);
1039 g_test_add_data_func_full (path, test_data, test_software_detect, g_free);
1042 test_data = g_new0 (TestAddSoftwareDetectData, 1);
1043 test_data->link_type = link_type;
1044 test_data->test_mode = test_mode;
1045 test_data->external_command = FALSE;
1047 path = g_strdup_printf ("%s/platform", testpath);
1048 g_test_add_data_func_full (path, test_data, test_software_detect, g_free);
1051 test_data = g_new0 (TestAddSoftwareDetectData, 1);
1052 test_data->link_type = link_type;
1053 test_data->test_mode = test_mode;
1054 test_data->external_command = -1;
1056 path = g_strdup_printf ("%s/random", testpath);
1057 g_test_add_data_func_full (path, test_data, test_software_detect, g_free);
1061 /*****************************************************************************/
1064 _assert_xgress_qos_mappings_impl (int ifindex,
1065 gboolean is_ingress_map ,
1070 const NMPlatformLink *plink;
1071 const NMPObject *lnk;
1073 const NMVlanQosMapping *map;
1077 lnk = nm_platform_link_get_lnk (NM_PLATFORM_GET, ifindex, NM_LINK_TYPE_VLAN, &plink);
1080 g_assert_cmpint (plink->ifindex, ==, ifindex);
1082 g_assert (&lnk->lnk_vlan == nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, NULL));
1084 if (nmtst_is_debug ())
1085 nmtstp_run_command_check ("ip -d link show %s", plink->name);
1087 if (is_ingress_map) {
1088 map = lnk->_lnk_vlan.ingress_qos_map;
1089 n_map = lnk->_lnk_vlan.n_ingress_qos_map;
1091 map = lnk->_lnk_vlan.egress_qos_map;
1092 n_map = lnk->_lnk_vlan.n_egress_qos_map;
1095 if (n_entries != -1)
1096 g_assert_cmpint (n_map, ==, n_entries);
1098 for (i = 0; i < n_map; i++) {
1099 if (is_ingress_map) {
1100 g_assert_cmpint (map[i].from, >=, 0);
1101 g_assert_cmpint (map[i].from, <=, 7);
1104 g_assert_cmpint (map[i - 1].from, <, map[i].from);
1108 for (; n > 0; n--) {
1109 gboolean found = FALSE;
1110 guint from = va_arg (ap, guint);
1111 guint to = va_arg (ap, guint);
1113 for (i = 0; i < n_map; i++) {
1114 if (map[i].from == from) {
1118 g_assert (map[i].to == to);
1125 #define _assert_xgress_qos_mappings(ifindex, is_ingress_map, n_entries, ...) \
1126 _assert_xgress_qos_mappings_impl ((ifindex), (is_ingress_map), (n_entries), \
1127 (G_STATIC_ASSERT_EXPR ((NM_NARG (__VA_ARGS__) % 2) == 0), NM_NARG (__VA_ARGS__) / 2), \
1129 #define _assert_ingress_qos_mappings(ifindex, n_entries, ...) _assert_xgress_qos_mappings (ifindex, TRUE, n_entries, __VA_ARGS__)
1130 #define _assert_egress_qos_mappings(ifindex, n_entries, ...) _assert_xgress_qos_mappings (ifindex, FALSE, n_entries, __VA_ARGS__)
1133 _assert_vlan_flags (int ifindex, NMVlanFlags flags)
1135 const NMPlatformLnkVlan *plnk;
1137 plnk = nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, NULL);
1139 g_assert_cmpint (plnk->flags, ==, flags);
1143 test_vlan_set_xgress (void)
1145 int ifindex, ifindex_parent;
1147 nmtstp_run_command_check ("ip link add %s type dummy", PARENT_NAME);
1148 ifindex_parent = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, PARENT_NAME, NM_LINK_TYPE_DUMMY, 100)->ifindex;
1150 nmtstp_run_command_check ("ip link add name %s link %s type vlan id 1245", DEVICE_NAME, PARENT_NAME);
1151 ifindex = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, DEVICE_NAME, NM_LINK_TYPE_VLAN, 100)->ifindex;
1153 /* ingress-qos-map */
1155 g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 4, 5));
1156 _assert_ingress_qos_mappings (ifindex, 1,
1159 g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 3, 7));
1160 _assert_ingress_qos_mappings (ifindex, 2,
1164 g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 3, 8));
1165 _assert_ingress_qos_mappings (ifindex, 2,
1169 g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, 4));
1170 _assert_ingress_qos_mappings (ifindex, 3,
1175 g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, G_MAXUINT32));
1176 _assert_ingress_qos_mappings (ifindex, 3,
1181 g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, G_MAXUINT32 - 1));
1182 _assert_ingress_qos_mappings (ifindex, 3,
1187 g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, 5));
1188 _assert_ingress_qos_mappings (ifindex, 3,
1193 g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, 5));
1194 _assert_ingress_qos_mappings (ifindex, 3,
1199 /* Set invalid values: */
1200 g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 8, 3));
1201 _assert_ingress_qos_mappings (ifindex, 3,
1206 g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 9, 4));
1207 _assert_ingress_qos_mappings (ifindex, 3,
1212 /* egress-qos-map */
1214 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 7, 3));
1215 _assert_egress_qos_mappings (ifindex, 1,
1218 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 8, 4));
1219 _assert_egress_qos_mappings (ifindex, 2,
1223 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 0, 4));
1224 _assert_egress_qos_mappings (ifindex, 3,
1229 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 1, 4));
1230 _assert_egress_qos_mappings (ifindex, 4,
1236 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 1, 5));
1237 _assert_egress_qos_mappings (ifindex, 4,
1243 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 9, 5));
1244 _assert_egress_qos_mappings (ifindex, 5,
1251 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 8, 5));
1252 _assert_egress_qos_mappings (ifindex, 5,
1259 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 8, 0));
1260 _assert_egress_qos_mappings (ifindex, 4,
1266 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 0, 0));
1267 _assert_egress_qos_mappings (ifindex, 3,
1272 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 100, 4));
1273 _assert_egress_qos_mappings (ifindex, 4,
1279 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, G_MAXUINT32, 4));
1280 _assert_egress_qos_mappings (ifindex, 5,
1287 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, G_MAXUINT32, 8));
1288 _assert_egress_qos_mappings (ifindex, 5,
1295 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, G_MAXUINT32, 0));
1296 _assert_egress_qos_mappings (ifindex, 4,
1302 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 100, 0));
1303 _assert_egress_qos_mappings (ifindex, 3,
1308 g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 1, 0));
1309 _assert_egress_qos_mappings (ifindex, 2,
1314 const NMVlanQosMapping ingress_map[] = {
1315 { .from = 1, .to = 5 },
1318 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1324 G_N_ELEMENTS (ingress_map),
1328 _assert_ingress_qos_mappings (ifindex, 1,
1333 const NMVlanQosMapping ingress_map[] = {
1334 { .from = 3, .to = 5 },
1335 { .from = 7, .to = 1655 },
1336 { .from = 7, .to = 17655 },
1337 { .from = 5, .to = 754 },
1338 { .from = 4, .to = 12 },
1341 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1347 G_N_ELEMENTS (ingress_map),
1351 _assert_ingress_qos_mappings (ifindex, 4,
1359 const NMVlanQosMapping ingress_map[] = {
1360 { .from = 3, .to = 18 },
1361 { .from = 6, .to = 121 },
1364 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1370 G_N_ELEMENTS (ingress_map),
1374 _assert_ingress_qos_mappings (ifindex, 5,
1383 const NMVlanQosMapping ingress_map[] = {
1384 { .from = 3, .to = 0 },
1385 { .from = 6, .to = 7 },
1388 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1394 G_N_ELEMENTS (ingress_map),
1398 _assert_ingress_qos_mappings (ifindex, 1,
1404 const NMVlanQosMapping ingress_map[] = {
1405 { .from = 1, .to = 5 },
1408 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1414 G_N_ELEMENTS (ingress_map),
1418 _assert_ingress_qos_mappings (ifindex, 1,
1423 const NMVlanQosMapping egress_map[] = {
1424 { .from = 5, .to = 1 },
1427 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1436 G_N_ELEMENTS (egress_map)));
1437 _assert_egress_qos_mappings (ifindex, 1,
1442 const NMVlanQosMapping egress_map[] = {
1443 { .from = 5, .to = 3 },
1444 { .from = 1655, .to = 5 },
1445 { .from = 1655, .to = 7 },
1446 { .from = G_MAXUINT32, .to = 6 },
1447 { .from = G_MAXUINT32, .to = 8 },
1448 { .from = 754, .to = 4 },
1449 { .from = 3, .to = 2 },
1452 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1461 G_N_ELEMENTS (egress_map)));
1462 _assert_egress_qos_mappings (ifindex, 5,
1471 const NMVlanQosMapping egress_map[] = {
1472 { .from = 754, .to = 3 },
1473 { .from = 755, .to = 8 },
1474 { .from = 1655, .to = 0 },
1475 { .from = 6, .to = 1 },
1478 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1487 G_N_ELEMENTS (egress_map)));
1488 _assert_egress_qos_mappings (ifindex, 5,
1497 const NMVlanQosMapping egress_map[] = {
1498 { .from = 6, .to = 0 },
1499 { .from = 3, .to = 4 },
1502 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1511 G_N_ELEMENTS (egress_map)));
1512 _assert_egress_qos_mappings (ifindex, 1,
1517 const NMVlanQosMapping egress_map[] = {
1518 { .from = 1, .to = 5 },
1521 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1530 G_N_ELEMENTS (egress_map)));
1531 _assert_egress_qos_mappings (ifindex, 1,
1536 const NMVlanQosMapping ingress_map[] = {
1537 { .from = 6, .to = 145 },
1538 { .from = 4, .to = 1 },
1539 { .from = 6, .to = 12 },
1541 const NMVlanQosMapping egress_map[] = {
1542 { .from = 1, .to = 5 },
1543 { .from = 3232, .to = 7 },
1546 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1548 NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP,
1549 NM_VLAN_FLAG_REORDER_HEADERS,
1552 G_N_ELEMENTS (ingress_map),
1555 G_N_ELEMENTS (egress_map)));
1556 _assert_ingress_qos_mappings (ifindex, 2,
1559 _assert_egress_qos_mappings (ifindex, 2,
1562 _assert_vlan_flags (ifindex, NM_VLAN_FLAG_REORDER_HEADERS);
1566 const NMVlanQosMapping ingress_map[] = {
1567 { .from = 6, .to = 145 },
1568 { .from = 4, .to = 1 },
1569 { .from = 6, .to = 12 },
1571 const NMVlanQosMapping egress_map[] = {
1572 { .from = 1, .to = 7 },
1573 { .from = 64, .to = 10 },
1574 { .from = 64, .to = 10 },
1575 { .from = 64, .to = 10 },
1576 { .from = 64, .to = 10 },
1577 { .from = 3232, .to = 0 },
1578 { .from = 64, .to = 4 },
1581 g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
1587 G_N_ELEMENTS (ingress_map),
1590 G_N_ELEMENTS (egress_map)));
1591 _assert_ingress_qos_mappings (ifindex, 2,
1594 _assert_egress_qos_mappings (ifindex, 2,
1597 _assert_vlan_flags (ifindex, NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP);
1600 nmtstp_link_del (-1, ifindex, DEVICE_NAME);
1601 nmtstp_link_del (-1, ifindex_parent, PARENT_NAME);
1604 /*****************************************************************************/
1607 test_create_many_links_do (guint n_devices)
1609 gint64 time, start_time = nm_utils_get_monotonic_timestamp_ns ();
1612 const NMPlatformLink *pllink;
1613 gs_unref_array GArray *ifindexes = g_array_sized_new (FALSE, FALSE, sizeof (int), n_devices);
1614 const gint EX = ((int) (nmtst_get_rand_int () % 4)) - 1;
1616 g_assert (EX >= -1 && EX <= 2);
1618 _LOGI (">>> create devices (EX=%d)...", EX);
1620 for (i = 0; i < n_devices; i++) {
1621 nm_sprintf_buf (name, "t-%05u", i);
1623 /* This mode is different from letting nmtstp_link_dummy_add()
1624 * because in this case we don't process any platform events
1625 * while adding all the links. */
1626 nmtstp_run_command_check ("ip link add %s type dummy", name);
1628 nmtstp_link_dummy_add (EX, name);
1631 _LOGI (">>> process events after creating devices...");
1633 nm_platform_process_events (NM_PLATFORM_GET);
1635 _LOGI (">>> check devices...");
1637 for (i = 0; i < n_devices; i++) {
1638 nm_sprintf_buf (name, "t-%05u", i);
1640 pllink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, name);
1642 g_assert_cmpint (pllink->type, ==, NM_LINK_TYPE_DUMMY);
1643 g_assert_cmpstr (pllink->name, ==, name);
1645 g_array_append_val (ifindexes, pllink->ifindex);
1648 _LOGI (">>> delete devices...");
1650 g_assert_cmpint (ifindexes->len, ==, n_devices);
1651 for (i = 0; i < n_devices; i++) {
1652 nm_sprintf_buf (name, "t-%05u", i);
1655 nmtstp_run_command_check ("ip link delete %s", name);
1657 nmtstp_link_del (EX, g_array_index (ifindexes, int, i), name);
1660 _LOGI (">>> process events after deleting devices...");
1661 nm_platform_process_events (NM_PLATFORM_GET);
1663 time = nm_utils_get_monotonic_timestamp_ns () - start_time;
1664 _LOGI (">>> finished in %ld.%09ld seconds", (long) (time / NM_UTILS_NS_PER_SECOND), (long) (time % NM_UTILS_NS_PER_SECOND));
1668 test_create_many_links (gconstpointer user_data)
1670 guint n_devices = GPOINTER_TO_UINT (user_data);
1672 if (n_devices > 100 && nmtst_test_quick ()) {
1673 g_print ("Skipping test: don't run long running test %s (NMTST_DEBUG=slow)\n", g_get_prgname () ?: "test-link-linux");
1674 g_test_skip ("Skip long running test");
1678 test_create_many_links_do (n_devices);
1681 /*****************************************************************************/
1684 test_nl_bugs_veth (void)
1686 const char *IFACE_VETH0 = "nm-test-veth0";
1687 const char *IFACE_VETH1 = "nm-test-veth1";
1688 int ifindex_veth0, ifindex_veth1;
1690 const NMPlatformLink *pllink_veth0, *pllink_veth1;
1691 gs_free_error GError *error = NULL;
1692 NMTstpNamespaceHandle *ns_handle = NULL;
1694 /* create veth pair. */
1695 nmtstp_run_command_check ("ip link add dev %s type veth peer name %s", IFACE_VETH0, IFACE_VETH1);
1696 ifindex_veth0 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_VETH0, NM_LINK_TYPE_VETH, 100)->ifindex;
1697 ifindex_veth1 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_VETH1, NM_LINK_TYPE_VETH, 100)->ifindex;
1699 /* assert that nm_platform_link_veth_get_properties() returns the expected peer ifindexes. */
1700 g_assert (nm_platform_link_veth_get_properties (NM_PLATFORM_GET, ifindex_veth0, &i));
1701 g_assert_cmpint (i, ==, ifindex_veth1);
1703 g_assert (nm_platform_link_veth_get_properties (NM_PLATFORM_GET, ifindex_veth1, &i));
1704 g_assert_cmpint (i, ==, ifindex_veth0);
1706 /* assert that NMPlatformLink.parent is the peer-ifindex. */
1707 pllink_veth0 = nm_platform_link_get (NM_PLATFORM_GET, ifindex_veth0);
1708 g_assert (pllink_veth0);
1709 if (pllink_veth0->parent == 0) {
1710 /* pre-4.1 kernels don't support exposing the veth peer as IFA_LINK. skip the remainder
1714 g_assert_cmpint (pllink_veth0->parent, ==, ifindex_veth1);
1717 /* The following tests whether we have a workaround for kernel bug
1718 * https://bugzilla.redhat.com/show_bug.cgi?id=1285827 in place. */
1719 pllink_veth1 = nm_platform_link_get (NM_PLATFORM_GET, ifindex_veth1);
1720 g_assert (pllink_veth1);
1721 g_assert_cmpint (pllink_veth1->parent, ==, ifindex_veth0);
1724 /* move one veth peer to another namespace and check that the
1725 * parent/IFLA_LINK of the remaining peer properly updates
1726 * (https://bugzilla.redhat.com/show_bug.cgi?id=1262908). */
1727 ns_handle = nmtstp_namespace_create (CLONE_NEWNET, &error);
1728 g_assert_no_error (error);
1729 g_assert (ns_handle);
1731 nmtstp_run_command_check ("ip link set %s netns %ld", IFACE_VETH1, (long) nmtstp_namespace_handle_get_pid (ns_handle));
1732 NMTST_WAIT_ASSERT (100, {
1733 nmtstp_wait_for_signal (NM_PLATFORM_GET, 50);
1734 nm_platform_process_events (NM_PLATFORM_GET);
1736 pllink_veth1 = nm_platform_link_get (NM_PLATFORM_GET, ifindex_veth1);
1737 pllink_veth0 = nm_platform_link_get (NM_PLATFORM_GET, ifindex_veth0);
1740 && pllink_veth0->parent == NM_PLATFORM_LINK_OTHER_NETNS) {
1746 nmtstp_link_del (-1, ifindex_veth0, IFACE_VETH0);
1747 g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_veth0, IFACE_VETH0));
1748 g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_veth1, IFACE_VETH1));
1749 nmtstp_namespace_handle_release (ns_handle);
1752 /*****************************************************************************/
1755 test_nl_bugs_spuroius_newlink (void)
1757 const char *IFACE_BOND0 = "nm-test-bond0";
1758 const char *IFACE_DUMMY0 = "nm-test-dummy0";
1759 int ifindex_bond0, ifindex_dummy0;
1760 const NMPlatformLink *pllink;
1761 gboolean wait_for_settle;
1763 /* see https://bugzilla.redhat.com/show_bug.cgi?id=1285719 */
1765 nmtstp_run_command_check ("ip link add %s type dummy", IFACE_DUMMY0);
1766 ifindex_dummy0 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_DUMMY0, NM_LINK_TYPE_DUMMY, 100)->ifindex;
1768 nmtstp_run_command_check ("ip link add %s type bond", IFACE_BOND0);
1769 ifindex_bond0 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_BOND0, NM_LINK_TYPE_BOND, 100)->ifindex;
1771 nmtstp_link_set_updown (-1, ifindex_bond0, TRUE);
1773 nmtstp_run_command_check ("ip link set %s master %s", IFACE_DUMMY0, IFACE_BOND0);
1774 NMTST_WAIT_ASSERT (100, {
1775 nmtstp_wait_for_signal (NM_PLATFORM_GET, 50);
1777 pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex_dummy0);
1779 if (pllink->master == ifindex_bond0)
1783 nmtstp_run_command_check ("ip link del %s", IFACE_BOND0);
1785 wait_for_settle = TRUE;
1786 nmtstp_wait_for_signal (NM_PLATFORM_GET, 50);
1788 nm_platform_process_events (NM_PLATFORM_GET);
1789 pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex_bond0);
1792 if (wait_for_settle) {
1793 wait_for_settle = FALSE;
1794 NMTST_WAIT (300, { nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); });
1798 g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_bond0, IFACE_BOND0));
1799 nmtstp_link_del (-1, ifindex_dummy0, IFACE_DUMMY0);
1802 /*****************************************************************************/
1805 test_nl_bugs_spuroius_dellink (void)
1807 const char *IFACE_BRIDGE0 = "nm-test-bridge0";
1808 const char *IFACE_DUMMY0 = "nm-test-dummy0";
1809 int ifindex_bridge0, ifindex_dummy0;
1810 const NMPlatformLink *pllink;
1811 gboolean wait_for_settle;
1813 /* see https://bugzilla.redhat.com/show_bug.cgi?id=1285719 */
1815 nmtstp_run_command_check ("ip link add %s type dummy", IFACE_DUMMY0);
1816 ifindex_dummy0 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_DUMMY0, NM_LINK_TYPE_DUMMY, 100)->ifindex;
1818 nmtstp_run_command_check ("ip link add %s type bridge", IFACE_BRIDGE0);
1819 ifindex_bridge0 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_BRIDGE0, NM_LINK_TYPE_BRIDGE, 100)->ifindex;
1821 nmtstp_link_set_updown (-1, ifindex_bridge0, TRUE);
1823 nmtstp_run_command_check ("ip link set %s master %s", IFACE_DUMMY0, IFACE_BRIDGE0);
1824 NMTST_WAIT_ASSERT (100, {
1825 nmtstp_wait_for_signal (NM_PLATFORM_GET, 50);
1827 pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex_dummy0);
1829 if (pllink->master == ifindex_bridge0)
1833 nm_platform_process_events (NM_PLATFORM_GET);
1835 nmtstp_run_command_check ("ip link set %s nomaster", IFACE_DUMMY0);
1837 wait_for_settle = TRUE;
1838 nmtstp_wait_for_signal (NM_PLATFORM_GET, 50);
1840 nm_platform_process_events (NM_PLATFORM_GET);
1841 pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex_bridge0);
1843 pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex_dummy0);
1845 g_assert_cmpint (pllink->parent, ==, 0);
1847 if (wait_for_settle) {
1848 wait_for_settle = FALSE;
1849 NMTST_WAIT (300, { nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); });
1853 nmtstp_link_del (-1, ifindex_bridge0, IFACE_BRIDGE0);
1854 nmtstp_link_del (-1, ifindex_dummy0, IFACE_DUMMY0);
1857 /******************************************************************/
1860 _test_netns_setup (gpointer fixture, gconstpointer test_data)
1862 /* the singleton platform instance has netns support disabled.
1863 * Destroy the instance before the test and re-create it afterwards. */
1864 g_object_unref (nm_platform_get ());
1868 _test_netns_teardown (gpointer fixture, gconstpointer test_data)
1870 /* re-create platform instance */
1875 _test_netns_create_platform (void)
1878 NMPlatform *platform;
1880 netns = nmp_netns_new ();
1881 g_assert (NMP_IS_NETNS (netns));
1883 platform = g_object_new (NM_TYPE_LINUX_PLATFORM, NM_PLATFORM_NETNS_SUPPORT, TRUE, NULL);
1884 g_assert (NM_IS_LINUX_PLATFORM (platform));
1886 nmp_netns_pop (netns);
1887 g_object_unref (netns);
1893 _test_netns_check_skip (void)
1895 static int support = -1;
1896 static int support_errsv = 0;
1899 netns = nmp_netns_get_current ();
1901 g_test_skip ("No netns support");
1905 g_assert (nmp_netns_get_fd_net (netns) > 0);
1907 if (support == -1) {
1908 support = (setns (nmp_netns_get_fd_net (netns), CLONE_NEWNET) == 0);
1910 support_errsv = errno;
1913 _LOGD ("setns() failed with \"%s\". This indicates missing support (valgrind?)", g_strerror (support_errsv));
1914 g_test_skip ("No netns support (setns failed)");
1920 /******************************************************************/
1923 test_netns_general (gpointer fixture, gconstpointer test_data)
1925 gs_unref_object NMPlatform *platform_1 = NULL;
1926 gs_unref_object NMPlatform *platform_2 = NULL;
1927 NMPNetns *netns_tmp;
1930 gboolean ethtool_support;
1932 if (_test_netns_check_skip ())
1935 platform_1 = g_object_new (NM_TYPE_LINUX_PLATFORM, NM_PLATFORM_NETNS_SUPPORT, TRUE, NULL);
1936 platform_2 = _test_netns_create_platform ();
1938 /* add some dummy devices. The "other-*" devices are there to bump the ifindex */
1939 for (k = 0; k < 2; k++) {
1940 NMPlatform *p = (k == 0 ? platform_1 : platform_2);
1941 const char *id = (k == 0 ? "a" : "b");
1943 for (i = 0, j = nmtst_get_rand_int () % 5; i < j; i++)
1944 _ADD_DUMMY (p, nm_sprintf_buf (sbuf, "other-a-%s-%02d", id, i));
1946 _ADD_DUMMY (p, "dummy1_");
1948 for (i = 0, j = nmtst_get_rand_int () % 5; i < j; i++)
1949 _ADD_DUMMY (p, nm_sprintf_buf (sbuf, "other-b-%s-%02d", id, i));
1951 _ADD_DUMMY (p, nm_sprintf_buf (sbuf, "dummy2%s", id));
1953 for (i = 0, j = nmtst_get_rand_int () % 5; i < j; i++)
1954 _ADD_DUMMY (p, nm_sprintf_buf (sbuf, "other-c-%s-%02d", id, i));
1957 g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/sys/devices/virtual/net/dummy1_/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex));
1958 g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/sys/devices/virtual/net/dummy2a/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy2a", NM_LINK_TYPE_DUMMY)->ifindex));
1959 g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/sys/devices/virtual/net/dummy2b/ifindex"), ==, NULL);
1961 g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/sys/devices/virtual/net/dummy1_/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex));
1962 g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/sys/devices/virtual/net/dummy2a/ifindex"), ==, NULL);
1963 g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/sys/devices/virtual/net/dummy2b/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy2b", NM_LINK_TYPE_DUMMY)->ifindex));
1965 for (i = 0; i < 10; i++) {
1969 j = nmtst_get_rand_int () % 2;
1971 if (nmtst_get_rand_int () % 2) {
1973 if (nmtst_get_rand_int () % 2)
1974 path = "/proc/sys/net/ipv6/conf/dummy1_/disable_ipv6";
1976 path = "/proc/sys/net/ipv6/conf/dummy2a/disable_ipv6";
1979 if (nmtst_get_rand_int () % 2)
1980 path = "/proc/sys/net/ipv6/conf/dummy1_/disable_ipv6";
1982 path = "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6";
1984 g_assert (nm_platform_sysctl_set (pl, path, nm_sprintf_buf (sbuf, "%d", j)));
1985 g_assert_cmpstr (nm_platform_sysctl_get (pl, path), ==, nm_sprintf_buf (sbuf, "%d", j));
1987 g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6"), ==, NULL);
1988 g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/proc/sys/net/ipv6/conf/dummy2a/disable_ipv6"), ==, NULL);
1990 /* older kernels (Ubuntu 12.04) don't support ethtool -i for dummy devices. Work around that and
1991 * skip asserts that are known to fail. */
1992 ethtool_support = nmtstp_run_command ("ethtool -i dummy1_ > /dev/null") == 0;
1993 if (ethtool_support) {
1994 g_assert ( nmp_utils_ethtool_get_driver_info ("dummy1_", NULL, NULL, NULL));
1995 g_assert ( nmp_utils_ethtool_get_driver_info ("dummy2a", NULL, NULL, NULL));
1996 g_assert (!nmp_utils_ethtool_get_driver_info ("dummy2b", NULL, NULL, NULL));
1997 g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy1_ > /dev/null"), ==, 0);
1998 g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2a > /dev/null"), ==, 0);
1999 g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2b 2> /dev/null"), !=, 0);
2002 g_assert (nm_platform_netns_push (platform_2, &netns_tmp));
2004 if (ethtool_support) {
2005 g_assert ( nmp_utils_ethtool_get_driver_info ("dummy1_", NULL, NULL, NULL));
2006 g_assert (!nmp_utils_ethtool_get_driver_info ("dummy2a", NULL, NULL, NULL));
2007 g_assert ( nmp_utils_ethtool_get_driver_info ("dummy2b", NULL, NULL, NULL));
2008 g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy1_ > /dev/null"), ==, 0);
2009 g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2a 2> /dev/null"), !=, 0);
2010 g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2b > /dev/null"), ==, 0);
2013 nmp_netns_pop (netns_tmp);
2016 /*****************************************************************************/
2019 test_netns_set_netns (gpointer fixture, gconstpointer test_data)
2021 NMPlatform *platforms[3];
2022 gs_unref_object NMPlatform *platform_0 = NULL;
2023 gs_unref_object NMPlatform *platform_1 = NULL;
2024 gs_unref_object NMPlatform *platform_2 = NULL;
2025 nm_auto_pop_netns NMPNetns *netns_pop = NULL;
2028 if (_test_netns_check_skip ())
2031 platforms[0] = platform_0 = g_object_new (NM_TYPE_LINUX_PLATFORM, NM_PLATFORM_NETNS_SUPPORT, TRUE, NULL);
2032 platforms[1] = platform_1 = _test_netns_create_platform ();
2033 platforms[2] = platform_2 = _test_netns_create_platform ();
2035 i = nmtst_get_rand_int () % 4;
2037 g_assert (nm_platform_netns_push (platforms[i], &netns_pop));
2039 #define LINK_MOVE_NAME "link-move"
2040 g_assert (!nm_platform_link_get_by_ifname (platform_1, LINK_MOVE_NAME));
2041 g_assert (!nm_platform_link_get_by_ifname (platform_2, LINK_MOVE_NAME));
2042 _ADD_DUMMY (platform_1, LINK_MOVE_NAME);
2043 g_assert ( nm_platform_link_get_by_ifname (platform_1, LINK_MOVE_NAME));
2044 g_assert (!nm_platform_link_get_by_ifname (platform_2, LINK_MOVE_NAME));
2045 g_assert (nm_platform_link_set_netns (platform_1,
2046 nm_platform_link_get_by_ifname (platform_1, LINK_MOVE_NAME)->ifindex,
2047 nmp_netns_get_fd_net (nm_platform_netns_get (platform_2))));
2048 g_assert (!nm_platform_link_get_by_ifname (platform_1, LINK_MOVE_NAME));
2049 g_assert (!nm_platform_link_get_by_ifname (platform_2, LINK_MOVE_NAME));
2050 nmtstp_assert_wait_for_link (platform_2, LINK_MOVE_NAME, NM_LINK_TYPE_DUMMY, 100);
2051 g_assert (!nm_platform_link_get_by_ifname (platform_1, LINK_MOVE_NAME));
2052 g_assert ( nm_platform_link_get_by_ifname (platform_2, LINK_MOVE_NAME));
2055 /*****************************************************************************/
2058 _get_current_namespace_id (int ns_type)
2061 GError *error = NULL;
2066 p = "/proc/self/ns/net";
2069 p = "/proc/self/ns/mnt";
2072 g_assert_not_reached ();
2075 id = g_file_read_link (p, &error);
2076 g_assert_no_error (error);
2082 _get_sysctl_value (const char *path)
2085 gs_free_error GError *error = NULL;
2087 if (!g_file_get_contents (path, &data, NULL, &error)) {
2088 nmtst_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT, NULL);
2091 g_assert_no_error (error);
2099 test_netns_push (gpointer fixture, gconstpointer test_data)
2101 gs_unref_object NMPlatform *platform_0 = NULL;
2102 gs_unref_object NMPlatform *platform_1 = NULL;
2103 gs_unref_object NMPlatform *platform_2 = NULL;
2104 nm_auto_pop_netns NMPNetns *netns_pop = NULL;
2105 gs_unref_ptrarray GPtrArray *device_names = g_ptr_array_new_with_free_func (g_free);
2107 const int ns_types_list[] = { CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWNET | CLONE_NEWNS };
2108 const int ns_types_test[] = { CLONE_NEWNET, CLONE_NEWNS };
2110 NMPlatform *platform;
2111 const char *device_name;
2112 const char *sysctl_path;
2113 const char *sysctl_value;
2117 PlatformData pl[3] = { };
2118 PlatformData *pl_base;
2125 if (_test_netns_check_skip ())
2128 pl[0].platform = platform_0 = g_object_new (NM_TYPE_LINUX_PLATFORM, NM_PLATFORM_NETNS_SUPPORT, TRUE, NULL);
2129 pl[1].platform = platform_1 = _test_netns_create_platform ();
2130 pl[2].platform = platform_2 = _test_netns_create_platform ();
2133 i = nmtst_get_rand_int () % (G_N_ELEMENTS (pl) + 1);
2134 if (i < G_N_ELEMENTS (pl)) {
2136 g_assert (nm_platform_netns_push (pl[i].platform, &netns_pop));
2139 for (i = 0; i < G_N_ELEMENTS (pl); i++) {
2140 nm_auto_pop_netns NMPNetns *netns_free = NULL;
2143 g_assert (nm_platform_netns_push (pl[i].platform, &netns_free));
2145 tmp = g_strdup_printf ("nmtst-dev-%d", i);
2146 g_ptr_array_add (device_names, tmp);
2147 pl[i].device_name = tmp;
2149 tmp = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/disable_ipv6", pl[i].device_name);
2150 g_ptr_array_add (device_names, tmp);
2151 pl[i].sysctl_path = tmp;
2153 pl[i].sysctl_value = nmtst_get_rand_int () % 2 ? "1" : "0";
2155 _ADD_DUMMY (pl[i].platform, pl[i].device_name);
2157 g_assert (nm_platform_sysctl_set (pl[i].platform, pl[i].sysctl_path, pl[i].sysctl_value));
2159 tmp = _get_current_namespace_id (CLONE_NEWNET);
2160 g_ptr_array_add (device_names, tmp);
2163 tmp = _get_current_namespace_id (CLONE_NEWNS);
2164 g_ptr_array_add (device_names, tmp);
2168 nstack = nmtst_get_rand_int () % (G_N_ELEMENTS (stack) + 1);
2169 for (i = 0; i < nstack; i++) {
2170 stack[i].pl = &pl[nmtst_get_rand_int () % G_N_ELEMENTS (pl)];
2171 stack[i].ns_types = ns_types_list[nmtst_get_rand_int () % G_N_ELEMENTS (ns_types_list)];
2173 nmp_netns_push_type (nm_platform_netns_get (stack[i].pl->platform), stack[i].ns_types);
2176 /* pop some again. */
2177 for (i = nmtst_get_rand_int () % (nstack + 1); i > 0; i--) {
2178 g_assert (nstack > 0);
2180 nmp_netns_pop (nm_platform_netns_get (stack[nstack].pl->platform));
2183 for (i = 0; i < G_N_ELEMENTS (ns_types_test); i++) {
2184 int ns_type = ns_types_test[i];
2186 gs_free char *current_namespace_id = NULL;
2189 for (j = nstack; j >= 1; ) {
2191 if (NM_FLAGS_HAS (stack[j].ns_types, ns_type)) {
2197 current_namespace_id = _get_current_namespace_id (ns_type);
2199 if (ns_type == CLONE_NEWNET) {
2200 g_assert_cmpstr (current_namespace_id, ==, p->ns_net);
2201 for (j = 0; j < G_N_ELEMENTS (pl); j++) {
2202 gs_free char *data = NULL;
2205 g_assert_cmpint (nmtstp_run_command ("ip link show %s 1>/dev/null", pl[j].device_name), ==, 0);
2207 g_assert_cmpint (nmtstp_run_command ("ip link show %s 2>/dev/null", pl[j].device_name), !=, 0);
2209 data = _get_sysctl_value (pl[j].sysctl_path);
2211 g_assert_cmpstr (data, ==, pl[j].sysctl_value);
2215 } else if (ns_type == CLONE_NEWNS) {
2216 g_assert_cmpstr (current_namespace_id, ==, p->ns_mnt);
2217 for (j = 0; j < G_N_ELEMENTS (pl); j++) {
2219 gs_free char *data = NULL;
2221 nm_sprintf_buf (path, "/sys/devices/virtual/net/%s/ifindex", pl[j].device_name);
2223 data = _get_sysctl_value (path);
2225 g_assert_cmpstr (data, ==, nm_sprintf_buf (path, "%d", nmtstp_link_get_typed (p->platform, 0, p->device_name, NM_LINK_TYPE_DUMMY)->ifindex));
2230 g_assert_not_reached ();
2234 for (i = nstack; i >= 1; ) {
2236 nmp_netns_pop (nm_platform_netns_get (stack[i].pl->platform));
2240 /*****************************************************************************/
2243 test_netns_bind_to_path (gpointer fixture, gconstpointer test_data)
2245 #define P_VAR_RUN "/var/run"
2246 #define P_VAR_RUN_NETNS "/var/run/netns"
2247 #define P_VAR_RUN_NETNS_BINDNAME "/var/run/netns/"P_NETNS_BINDNAME
2248 #define P_NETNS_BINDNAME "nmtst-iproute2-netns"
2249 gs_unref_object NMPlatform *platform_0 = NULL;
2250 gs_unref_object NMPlatform *platform_1 = NULL;
2251 gs_unref_object NMPlatform *platform_2 = NULL;
2252 nm_auto_pop_netns NMPNetns *netns_pop = NULL;
2253 NMPlatform *platforms[3];
2257 if (_test_netns_check_skip ())
2260 g_assert_cmpint (mount ("tmpfs", P_VAR_RUN, "tmpfs", MS_NOATIME | MS_NODEV | MS_NOSUID, "mode=0755,size=32K"), ==, 0);
2261 g_assert_cmpint (mkdir (P_VAR_RUN_NETNS, 755), ==, 0);
2263 platforms[0] = platform_0 = g_object_new (NM_TYPE_LINUX_PLATFORM, NM_PLATFORM_NETNS_SUPPORT, TRUE, NULL);
2264 platforms[1] = platform_1 = _test_netns_create_platform ();
2265 platforms[2] = platform_2 = _test_netns_create_platform ();
2267 i = nmtst_get_rand_int () % 4;
2269 g_assert (nm_platform_netns_push (platforms[i], &netns_pop));
2271 i = (nmtst_get_rand_int () % 2) + 1;
2272 netns = nm_platform_netns_get (platforms[i]);
2274 _ADD_DUMMY (platforms[i], "dummy2b");
2276 g_assert (!g_file_test (P_VAR_RUN_NETNS_BINDNAME, G_FILE_TEST_EXISTS));
2277 g_assert_cmpint (nmtstp_run_command ("ip netns exec "P_NETNS_BINDNAME" true 2>/dev/null"), !=, 0);
2279 g_assert (nmp_netns_bind_to_path (netns, P_VAR_RUN_NETNS_BINDNAME, NULL));
2281 g_assert (g_file_test (P_VAR_RUN_NETNS_BINDNAME, G_FILE_TEST_EXISTS));
2282 g_assert_cmpint (nmtstp_run_command ("ip netns exec "P_NETNS_BINDNAME" true"), ==, 0);
2283 g_assert_cmpint (nmtstp_run_command ("ip netns exec "P_NETNS_BINDNAME" ip link show dummy2b 1>/dev/null"), ==, 0);
2285 g_assert (nmp_netns_bind_to_path_destroy (netns, P_VAR_RUN_NETNS_BINDNAME));
2287 g_assert (!g_file_test (P_VAR_RUN_NETNS_BINDNAME, G_FILE_TEST_EXISTS));
2288 g_assert_cmpint (nmtstp_run_command ("ip netns exec "P_NETNS_BINDNAME" true 2>/dev/null"), !=, 0);
2290 g_assert_cmpint (umount (P_VAR_RUN), ==, 0);
2293 /*****************************************************************************/
2296 init_tests (int *argc, char ***argv)
2298 nmtst_init_with_logging (argc, argv, NULL, "ALL");
2304 nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME));
2305 nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, SLAVE_NAME));
2306 nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME));
2307 g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME));
2308 g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, SLAVE_NAME));
2309 g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, PARENT_NAME));
2311 g_test_add_func ("/link/bogus", test_bogus);
2312 g_test_add_func ("/link/loopback", test_loopback);
2313 g_test_add_func ("/link/internal", test_internal);
2314 g_test_add_func ("/link/software/bridge", test_bridge);
2315 g_test_add_func ("/link/software/bond", test_bond);
2316 g_test_add_func ("/link/software/team", test_team);
2317 g_test_add_func ("/link/software/vlan", test_vlan);
2318 g_test_add_func ("/link/software/bridge/addr", test_bridge_addr);
2320 if (nmtstp_is_root_test ()) {
2321 g_test_add_func ("/link/external", test_external);
2323 test_software_detect_add ("/link/software/detect/gre", NM_LINK_TYPE_GRE, 0);
2324 test_software_detect_add ("/link/software/detect/ip6tnl", NM_LINK_TYPE_IP6TNL, 0);
2325 test_software_detect_add ("/link/software/detect/ipip", NM_LINK_TYPE_IPIP, 0);
2326 test_software_detect_add ("/link/software/detect/macvlan", NM_LINK_TYPE_MACVLAN, 0);
2327 test_software_detect_add ("/link/software/detect/macvtap", NM_LINK_TYPE_MACVTAP, 0);
2328 test_software_detect_add ("/link/software/detect/sit", NM_LINK_TYPE_SIT, 0);
2329 test_software_detect_add ("/link/software/detect/vlan", NM_LINK_TYPE_VLAN, 0);
2330 test_software_detect_add ("/link/software/detect/vxlan/0", NM_LINK_TYPE_VXLAN, 0);
2331 test_software_detect_add ("/link/software/detect/vxlan/1", NM_LINK_TYPE_VXLAN, 1);
2333 g_test_add_func ("/link/software/vlan/set-xgress", test_vlan_set_xgress);
2335 g_test_add_data_func ("/link/create-many-links/20", GUINT_TO_POINTER (20), test_create_many_links);
2336 g_test_add_data_func ("/link/create-many-links/1000", GUINT_TO_POINTER (1000), test_create_many_links);
2338 g_test_add_func ("/link/nl-bugs/veth", test_nl_bugs_veth);
2339 g_test_add_func ("/link/nl-bugs/spurious-newlink", test_nl_bugs_spuroius_newlink);
2340 g_test_add_func ("/link/nl-bugs/spurious-dellink", test_nl_bugs_spuroius_dellink);
2342 g_test_add_vtable ("/general/netns/general", 0, NULL, _test_netns_setup, test_netns_general, _test_netns_teardown);
2343 g_test_add_vtable ("/general/netns/set-netns", 0, NULL, _test_netns_setup, test_netns_set_netns, _test_netns_teardown);
2344 g_test_add_vtable ("/general/netns/push", 0, NULL, _test_netns_setup, test_netns_push, _test_netns_teardown);
2345 g_test_add_vtable ("/general/netns/bind-to-path", 0, NULL, _test_netns_setup, test_netns_bind_to_path, _test_netns_teardown);