Blob Blame History Raw
From de86e93cc7993e068b7328bf69ec08b0aa02ca98 Mon Sep 17 00:00:00 2001
From: Eduardo Otubo <otubo@redhat.com>
Date: Wed, 19 Feb 2020 13:32:56 +0100
Subject: [PATCH 3/3] net: add is_master check for filtering device list

RH-Author: Eduardo Otubo <otubo@redhat.com>
Message-id: <20200219133256.9544-3-otubo@redhat.com>
Patchwork-id: 93937
O-Subject: [RHEL-7.9 cloud-init PATCHv2 2/2] net: add is_master check for filtering device list
Bugzilla: 1768770
RH-Acked-by: Mohammed Gamal <mgamal@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>

commit 059d049c57cac02cdeaca832233a19712e0b4ded
Author: Ryan Harper <ryan.harper@canonical.com>
Date:   Tue Sep 17 10:11:00 2019 +0000

    net: add is_master check for filtering device list

    Some network devices are transformed into a bond via kernel magic
    and do not have the 'bonding' sysfs attribute, but like a bond they
    have a duplicate MAC of other bond members.  On Azure Advanced
    Networking SRIOV devices are auto bonded and will have the same MAC
    as the HyperV nic.  We can detect this via the 'master' sysfs attribute
    in the device sysfs path and this patch adds this to the list of devices
    we ignore when enumerating device lists.

    LP: #1844191

Conflicts: Removing checks `has_master()' for net failover functions. Such
functions are not present because are not required so far.

Signed-off-by: Eduardo Otubo <otubo@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 cloudinit/net/__init__.py        |  6 ++++++
 cloudinit/net/tests/test_init.py | 17 +++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
index e758006..41659b1 100644
--- a/cloudinit/net/__init__.py
+++ b/cloudinit/net/__init__.py
@@ -108,6 +108,10 @@ def is_bond(devname):
     return os.path.exists(sys_dev_path(devname, "bonding"))
 
 
+def has_master(devname):
+    return os.path.exists(sys_dev_path(devname, path="master"))
+
+
 def is_renamed(devname):
     """
     /* interface name assignment types (sysfs name_assign_type attribute) */
@@ -624,6 +628,8 @@ def get_interfaces():
             continue
         if is_bond(name):
             continue
+        if has_master(name):
+            continue
         mac = get_interface_mac(name)
         # some devices may not have a mac (tun0)
         if not mac:
diff --git a/cloudinit/net/tests/test_init.py b/cloudinit/net/tests/test_init.py
index f55c31e..5519867 100644
--- a/cloudinit/net/tests/test_init.py
+++ b/cloudinit/net/tests/test_init.py
@@ -157,6 +157,12 @@ class TestReadSysNet(CiTestCase):
         ensure_file(os.path.join(self.sysdir, 'eth0', 'bonding'))
         self.assertTrue(net.is_bond('eth0'))
 
+    def test_has_master(self):
+        """has_master is True when /sys/net/devname/master exists."""
+        self.assertFalse(net.has_master('enP1s1'))
+        ensure_file(os.path.join(self.sysdir, 'enP1s1', 'master'))
+        self.assertTrue(net.has_master('enP1s1'))
+
     def test_is_vlan(self):
         """is_vlan is True when /sys/net/devname/uevent has DEVTYPE=vlan."""
         ensure_file(os.path.join(self.sysdir, 'eth0', 'uevent'))
@@ -364,6 +370,17 @@ class TestGetInterfaceMAC(CiTestCase):
         expected = [('eth2', 'aa:bb:cc:aa:bb:cc', None, None)]
         self.assertEqual(expected, net.get_interfaces())
 
+    def test_get_interfaces_by_mac_skips_master_devs(self):
+        """Ignore interfaces with a master device which would have dup mac."""
+        mac1 = mac2 = 'aa:bb:cc:aa:bb:cc'
+        write_file(os.path.join(self.sysdir, 'eth1', 'addr_assign_type'), '0')
+        write_file(os.path.join(self.sysdir, 'eth1', 'address'), mac1)
+        write_file(os.path.join(self.sysdir, 'eth1', 'master'), "blah")
+        write_file(os.path.join(self.sysdir, 'eth2', 'addr_assign_type'), '0')
+        write_file(os.path.join(self.sysdir, 'eth2', 'address'), mac2)
+        expected = [('eth2', mac2, None, None)]
+        self.assertEqual(expected, net.get_interfaces())
+
 
 class TestInterfaceHasOwnMAC(CiTestCase):
 
-- 
1.8.3.1