From 5650c82a8ea044ed433c05a56111161a07fb6225 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 26 Nov 2015 12:02:29 +0100 Subject: [PATCH] platform: workaround kernel bug about missing IFLA_LINK/parent when creating veth The related bug rh#1285827 in kernel causes a missing IFLA_LINK/parent attribute when creating a veth pair: # ip monitor link & [1] 6745 # ip link add dev vm1 type veth peer name vm2 30: vm2@NONE: mtu 1500 qdisc noop state DOWN link/ether be:e3:b7:0e:14:52 brd ff:ff:ff:ff:ff:ff 31: vm1@vm2: mtu 1500 qdisc noop state DOWN link/ether da:e6:a6:c5:42:54 brd ff:ff:ff:ff:ff:ff Add a workaround and test. Related: https://bugzilla.redhat.com/show_bug.cgi?id=1285827 --- src/platform/nm-linux-platform.c | 9 ++++++ src/platform/tests/test-link.c | 47 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index b68df0da2e..4f9d712e2e 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2802,6 +2802,15 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP break; } } + if ( new->link.type == NM_LINK_TYPE_VETH + && new->link.parent == 0) { + /* the initial notification when adding a veth pair can lack the parent/IFLA_LINK + * (https://bugzilla.redhat.com/show_bug.cgi?id=1285827). + * Request it again. */ + delayed_action_schedule (platform, + DELAYED_ACTION_TYPE_REFRESH_LINK, + GINT_TO_POINTER (new->link.ifindex)); + } } { /* on enslave/release, we also refresh the master. */ diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 5b9355d04d..8dd68ecb5f 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -1371,6 +1371,51 @@ test_vlan_set_xgress (void) /*****************************************************************************/ +static void +test_nl_bugs_veth (void) +{ + const char *IFACE_VETH0 = "nm-test-veth0"; + const char *IFACE_VETH1 = "nm-test-veth1"; + int ifindex_veth0, ifindex_veth1; + int i; + const NMPlatformLink *pllink_veth0, *pllink_veth1; + + /* create veth pair. */ + nmtstp_run_command_check ("ip link add dev %s type veth peer name %s", IFACE_VETH0, IFACE_VETH1); + ifindex_veth0 = nmtstp_assert_wait_for_link (IFACE_VETH0, NM_LINK_TYPE_VETH, 100)->ifindex; + ifindex_veth1 = nmtstp_assert_wait_for_link (IFACE_VETH1, NM_LINK_TYPE_VETH, 100)->ifindex; + + /* assert that nm_platform_veth_get_properties() returns the expected peer ifindexes. */ + g_assert (nm_platform_veth_get_properties (NM_PLATFORM_GET, ifindex_veth0, &i)); + g_assert_cmpint (i, ==, ifindex_veth1); + + g_assert (nm_platform_veth_get_properties (NM_PLATFORM_GET, ifindex_veth1, &i)); + g_assert_cmpint (i, ==, ifindex_veth0); + + /* assert that NMPlatformLink.parent is the peer-ifindex. */ + pllink_veth0 = nm_platform_link_get (NM_PLATFORM_GET, ifindex_veth0); + g_assert (pllink_veth0); + if (pllink_veth0->parent == 0) { + /* pre-4.1 kernels don't support exposing the veth peer as IFA_LINK. skip the remainder + * of the test. */ + goto out; + } + g_assert_cmpint (pllink_veth0->parent, ==, ifindex_veth1); + + + /* The following tests whether we have a workaround for kernel bug + * https://bugzilla.redhat.com/show_bug.cgi?id=1285827 in place. */ + pllink_veth1 = nm_platform_link_get (NM_PLATFORM_GET, ifindex_veth1); + g_assert (pllink_veth1); + g_assert_cmpint (pllink_veth1->parent, ==, ifindex_veth0); + +out: + g_assert (nm_platform_link_delete (NM_PLATFORM_GET, ifindex_veth0)); + nm_platform_link_delete (NM_PLATFORM_GET, ifindex_veth1); +} + +/*****************************************************************************/ + void init_tests (int *argc, char ***argv) { @@ -1406,5 +1451,7 @@ setup_tests (void) test_software_detect_add ("/link/software/detect/vxlan/1", NM_LINK_TYPE_VXLAN, 1); g_test_add_func ("/link/software/vlan/set-xgress", test_vlan_set_xgress); + + g_test_add_func ("/link/nl-bugs/veth", test_nl_bugs_veth); } }