Merge ~smoser/cloud-init:bug/1692028-empty-macs-for-bymac into cloud-init:master

Proposed by Scott Moser
Status: Merged
Merged at revision: 2c0655feb9a194b5fbdfe90a5f847c16f1e15409
Proposed branch: ~smoser/cloud-init:bug/1692028-empty-macs-for-bymac
Merge into: cloud-init:master
Diff against target: 107 lines (+22/-8)
2 files modified
cloudinit/net/__init__.py (+3/-0)
tests/unittests/test_net.py (+19/-8)
Reviewer Review Type Date Requested Status
Scott Moser Approve
Server Team CI bot continuous-integration Approve
Ryan Harper Approve
Review via email: mp+324332@code.launchpad.net

Commit message

Fix get_interfaces_by_mac for empty macs

Some interfaces (greptap0 in the bug) have a mac address of
'00:00:00:00:00:00'. That was causing a duplicate mac detection
as the 'lo' device also has that mac.

The change here is to just ignore macs other than 'lo' that have that.

LP: #1692028

To post a comment you must log in.
Revision history for this message
Scott Moser (smoser) wrote :

I'm not sure where this 'gretap0' device comes from or if it would ever appear in the network data. I'd suggest that it would be bad for it to...

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ryan Harper (raharper) wrote :

GRE tap is an overlay network, I believe it's supported in openstack;
Google also found some AWS setup instructions mentioning gretap's

https://aws.amazon.com/articles/6234671078671125

Patch looks good to me.

review: Approve
Revision history for this message
Scott Moser (smoser) wrote :

Yeah, my question really was if we'd ever be expected to configure this device, or if its already configured...

Ie, i want to see network_json for this. It seems like there will be issues further down the road if we simply ignore the device in get_interfaces_by_mac but we're supposed to write a network configuration for it.

James, could you provide the config drive contents on the system you saw this on ?

Revision history for this message
Scott Moser (smoser) :
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Scott Moser (smoser) wrote :

As ryan has approved, and we've opened nova-lxd/lxd bugs at
 https://bugs.launchpad.net/cloud-archive/+bug/1692545
and
 https://github.com/lxc/lxd/issues/3338

I'm going to pull the change.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
2index a072a8d..8c6cd05 100644
3--- a/cloudinit/net/__init__.py
4+++ b/cloudinit/net/__init__.py
5@@ -393,6 +393,7 @@ def get_interfaces_by_mac():
6 else:
7 raise
8 ret = {}
9+ empty_mac = '00:00:00:00:00:00'
10 for name in devs:
11 if not interface_has_own_mac(name):
12 continue
13@@ -404,6 +405,8 @@ def get_interfaces_by_mac():
14 # some devices may not have a mac (tun0)
15 if not mac:
16 continue
17+ if mac == empty_mac and name != 'lo':
18+ continue
19 if mac in ret:
20 raise RuntimeError(
21 "duplicate mac found! both '%s' and '%s' have mac '%s'" %
22diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
23index 68a0157..8bd3f43 100644
24--- a/tests/unittests/test_net.py
25+++ b/tests/unittests/test_net.py
26@@ -1542,24 +1542,24 @@ class TestNetRenderers(CiTestCase):
27
28
29 class TestGetInterfacesByMac(CiTestCase):
30- _data = {'devices': ['enp0s1', 'enp0s2', 'bond1', 'bridge1',
31- 'bridge1-nic', 'tun0', 'bond1.101'],
32- 'bonds': ['bond1'],
33+ _data = {'bonds': ['bond1'],
34 'bridges': ['bridge1'],
35 'vlans': ['bond1.101'],
36 'own_macs': ['enp0s1', 'enp0s2', 'bridge1-nic', 'bridge1',
37- 'bond1.101'],
38+ 'bond1.101', 'lo'],
39 'macs': {'enp0s1': 'aa:aa:aa:aa:aa:01',
40 'enp0s2': 'aa:aa:aa:aa:aa:02',
41 'bond1': 'aa:aa:aa:aa:aa:01',
42 'bond1.101': 'aa:aa:aa:aa:aa:01',
43 'bridge1': 'aa:aa:aa:aa:aa:03',
44 'bridge1-nic': 'aa:aa:aa:aa:aa:03',
45+ 'lo': '00:00:00:00:00:00',
46+ 'greptap0': '00:00:00:00:00:00',
47 'tun0': None}}
48 data = {}
49
50 def _se_get_devicelist(self):
51- return self.data['devices']
52+ return list(self.data['devices'])
53
54 def _se_get_interface_mac(self, name):
55 return self.data['macs'][name]
56@@ -1575,6 +1575,7 @@ class TestGetInterfacesByMac(CiTestCase):
57
58 def _mock_setup(self):
59 self.data = copy.deepcopy(self._data)
60+ self.data['devices'] = set(list(self.data['macs'].keys()))
61 mocks = ('get_devicelist', 'get_interface_mac', 'is_bridge',
62 'interface_has_own_mac', 'is_vlan')
63 self.mocks = {}
64@@ -1602,7 +1603,7 @@ class TestGetInterfacesByMac(CiTestCase):
65 [mock.call('enp0s1'), mock.call('bond1')], any_order=True)
66 self.assertEqual(
67 {'aa:aa:aa:aa:aa:01': 'enp0s1', 'aa:aa:aa:aa:aa:02': 'enp0s2',
68- 'aa:aa:aa:aa:aa:03': 'bridge1-nic'},
69+ 'aa:aa:aa:aa:aa:03': 'bridge1-nic', '00:00:00:00:00:00': 'lo'},
70 ret)
71
72 def test_excludes_bridges(self):
73@@ -1611,7 +1612,7 @@ class TestGetInterfacesByMac(CiTestCase):
74 # set everything other than 'b1' to be a bridge.
75 # then expect b1 is the only thing left.
76 self.data['macs']['b1'] = 'aa:aa:aa:aa:aa:b1'
77- self.data['devices'].append('b1')
78+ self.data['devices'].add('b1')
79 self.data['bonds'] = []
80 self.data['own_macs'] = self.data['devices']
81 self.data['bridges'] = [f for f in self.data['devices'] if f != "b1"]
82@@ -1628,7 +1629,7 @@ class TestGetInterfacesByMac(CiTestCase):
83 # set everything other than 'b1' to be a vlan.
84 # then expect b1 is the only thing left.
85 self.data['macs']['b1'] = 'aa:aa:aa:aa:aa:b1'
86- self.data['devices'].append('b1')
87+ self.data['devices'].add('b1')
88 self.data['bonds'] = []
89 self.data['bridges'] = []
90 self.data['own_macs'] = self.data['devices']
91@@ -1640,6 +1641,16 @@ class TestGetInterfacesByMac(CiTestCase):
92 mock.call('b1')],
93 any_order=True)
94
95+ def test_duplicates_of_empty_mac_are_ok(self):
96+ """Duplicate macs of 00:00:00:00:00:00 should be skipped."""
97+ self._mock_setup()
98+ empty_mac = "00:00:00:00:00:00"
99+ addnics = ('greptap1', 'lo', 'greptap2')
100+ self.data['macs'].update(dict((k, empty_mac) for k in addnics))
101+ self.data['devices'].update(set(addnics))
102+ ret = net.get_interfaces_by_mac()
103+ self.assertEqual('lo', ret[empty_mac])
104+
105
106 def _gzip_data(data):
107 with io.BytesIO() as iobuf:

Subscribers

People subscribed via source and target branches