Skip to content

Commit

Permalink
Move setting mac addresses for network devices to privsep.
Browse files Browse the repository at this point in the history
Change-Id: Ie8a31dd4d80e74b5700b3449ac42db7960843936
  • Loading branch information
mikalstill committed Jan 31, 2019
1 parent 16dda27 commit 13e283c
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 43 deletions.
13 changes: 6 additions & 7 deletions nova/network/linux_net.py
Expand Up @@ -1382,9 +1382,8 @@ def ensure_vlan(vlan_num, bridge_interface, mac_address=None, mtu=None,
# (danwent) the bridge will inherit this address, so we want to
# make sure it is the value set from the NetworkManager
if mac_address:
_execute('ip', 'link', 'set', interface, 'address',
mac_address, run_as_root=True,
check_exit_code=[0, 2, 254])
nova.privsep.linux_net.set_device_macaddr(
interface, mac_address)
nova.privsep.linux_net.set_device_enabled(interface)
# NOTE(vish): set mtu every time to ensure that changes to mtu get
# propagated
Expand Down Expand Up @@ -1449,8 +1448,8 @@ def ensure_bridge(bridge, interface, net_attrs=None, gateway=True,
if not CONF.fake_network:
interface_addrs = netifaces.ifaddresses(interface)
interface_mac = interface_addrs[netifaces.AF_LINK][0]['addr']
_execute('ip', 'link', 'set', bridge, 'address', interface_mac,
run_as_root=True)
nova.privsep.linux_net.set_device_macaddr(
bridge, interface_mac)

nova.privsep.linux_net.set_device_enabled(interface)

Expand Down Expand Up @@ -1665,8 +1664,8 @@ def plug(self, network, mac_address, gateway=True):
'external-ids:iface-status=active',
'--', 'set', 'Interface', dev,
'external-ids:attached-mac=%s' % mac_address])
_execute('ip', 'link', 'set', dev, 'address', mac_address,
run_as_root=True)
nova.privsep.linux_net.set_device_macaddr(
dev, mac_address)
nova.privsep.linux_net.set_device_mtu(dev, network.get('mtu'))
nova.privsep.linux_net.set_device_enabled(dev)
if not gateway:
Expand Down
15 changes: 5 additions & 10 deletions nova/network/linux_utils.py
Expand Up @@ -47,8 +47,7 @@ def create_tap_dev(dev, mac_address=None, multiqueue=False):
# Second option: tunctl
utils.execute('tunctl', '-b', '-t', dev, run_as_root=True)
if mac_address:
utils.execute('ip', 'link', 'set', dev, 'address', mac_address,
run_as_root=True, check_exit_code=[0, 2, 254])
nova.privsep.linux_net.set_device_macaddr(dev, mac_address)
nova.privsep.linux_net.set_device_enabled(dev)


Expand All @@ -59,20 +58,16 @@ def set_vf_interface_vlan(pci_addr, mac_addr, vlan=0):
vf_num = pci_utils.get_vf_num_by_pci_address(pci_addr)

# Set the VF's mac address and vlan
exit_code = [0, 2, 254]
port_state = 'up' if vlan > 0 else 'down'
utils.execute('ip', 'link', 'set', pf_ifname,
'vf', vf_num,
'mac', mac_addr,
'vlan', vlan,
run_as_root=True,
check_exit_code=exit_code)
check_exit_code=[0, 2, 254])
# Bring up/down the VF's interface
# TODO(edand): The mac is assigned as a workaround for the following issue
# https://bugzilla.redhat.com/show_bug.cgi?id=1372944
# once resolved it will be removed
utils.execute('ip', 'link', 'set', vf_ifname,
'address', mac_addr,
port_state,
run_as_root=True,
check_exit_code=exit_code)
port_state = 'up' if vlan > 0 else 'down'
nova.privsep.linux_net.set_device_macaddr(vf_ifname, mac_addr,
port_state=port_state)
10 changes: 10 additions & 0 deletions nova/privsep/linux_net.py
Expand Up @@ -91,6 +91,16 @@ def set_device_enabled(dev):
check_exit_code=[0, 2, 254])


@nova.privsep.sys_admin_pctxt.entrypoint
def set_device_macaddr(dev, mac_addr, port_state=None):
if port_state:
processutils.execute('ip', 'link', 'set', dev, 'address', mac_addr,
port_state, check_exit_code=[0, 2, 254])
else:
processutils.execute('ip', 'link', 'set', dev, 'address', mac_addr,
check_exit_code=[0, 2, 254])


@nova.privsep.sys_admin_pctxt.entrypoint
def create_veth_pair(dev1_name, dev2_name, mtu=None):
"""Create a pair of veth devices with the specified names,
Expand Down
1 change: 1 addition & 0 deletions nova/tests/functional/api_sample_tests/api_sample_base.py
Expand Up @@ -126,6 +126,7 @@ def fake_noop(*args, **kwargs):
self.stub_out('nova.privsep.linux_net.add_bridge', fake_noop)
self.stub_out('nova.privsep.linux_net.set_device_mtu', fake_noop)
self.stub_out('nova.privsep.linux_net.set_device_enabled', fake_noop)
self.stub_out('nova.privsep.linux_net.set_device_macaddr', fake_noop)

def _setup_services(self):
pass
18 changes: 10 additions & 8 deletions nova/tests/unit/network/test_linux_net.py
Expand Up @@ -1131,8 +1131,6 @@ def test_ensure_bridge_brings_up_interface(self):
'_execute': [
mock.call('brctl', 'addif', 'bridge', 'eth0',
run_as_root=True, check_exit_code=False),
mock.call('ip', 'link', 'set', 'bridge', 'address', fake_mac,
run_as_root=True),
mock.call('ip', 'route', 'show', 'dev', 'eth0'),
mock.call('ip', 'addr', 'show', 'dev', 'eth0', 'scope',
'global'),
Expand All @@ -1142,16 +1140,19 @@ def test_ensure_bridge_brings_up_interface(self):
mock.patch('nova.privsep.linux_net.device_exists',
return_value=True),
mock.patch('nova.privsep.linux_net.set_device_enabled'),
mock.patch('nova.privsep.linux_net.set_device_macaddr'),
mock.patch.object(linux_net, '_execute', return_value=('', '')),
mock.patch.object(netifaces, 'ifaddresses')
) as (device_exists, device_enabled, _execute, ifaddresses):
) as (device_exists, device_enabled, set_device_macaddr,
_execute, ifaddresses):
ifaddresses.return_value = fake_ifaces
driver = linux_net.LinuxBridgeInterfaceDriver()
driver.ensure_bridge('bridge', 'eth0')
device_exists.assert_has_calls(calls['device_exists'])
_execute.assert_has_calls(calls['_execute'])
ifaddresses.assert_called_once_with('eth0')
device_enabled.assert_called_once_with('eth0')
set_device_macaddr.assert_called_once_with('bridge', fake_mac)

def test_ensure_bridge_brclt_addif_exception(self):
def fake_execute(*cmd, **kwargs):
Expand Down Expand Up @@ -1285,8 +1286,10 @@ def test_remove_bridge(self, mock_delete, mock_execute, mock_exists):
@mock.patch('nova.privsep.linux_net.device_exists', return_value=False)
@mock.patch('nova.privsep.linux_net.set_device_mtu')
@mock.patch('nova.privsep.linux_net.set_device_enabled')
def test_ensure_vlan(self, mock_set_enabled, mock_set_device_mtu,
mock_device_exists, mock_execute):
@mock.patch('nova.privsep.linux_net.set_device_macaddr')
def test_ensure_vlan(self, mock_set_macaddr, mock_set_enabled,
mock_set_device_mtu, mock_device_exists,
mock_execute):
interface = linux_net.LinuxBridgeInterfaceDriver.ensure_vlan(
1, 'eth0', 'MAC', 'MTU', "vlan_name")
self.assertEqual("vlan_name", interface)
Expand All @@ -1295,13 +1298,12 @@ def test_ensure_vlan(self, mock_set_enabled, mock_set_device_mtu,
expected_execute_args = [
mock.call('ip', 'link', 'add', 'link', 'eth0', 'name', 'vlan_name',
'type', 'vlan', 'id', 1, check_exit_code=[0, 2, 254],
run_as_root=True),
mock.call('ip', 'link', 'set', 'vlan_name', 'address', 'MAC',
check_exit_code=[0, 2, 254], run_as_root=True)
run_as_root=True)
]
self.assertEqual(expected_execute_args, mock_execute.mock_calls)
mock_set_device_mtu.assert_called_once_with('vlan_name', 'MTU')
mock_set_enabled.assert_called_once_with('vlan_name')
mock_set_macaddr.assert_called_once_with('vlan_name', 'MAC')

@mock.patch.object(linux_net, '_execute')
@mock.patch('nova.privsep.linux_net.device_exists', return_value=True)
Expand Down
9 changes: 6 additions & 3 deletions nova/tests/unit/network/test_manager.py
Expand Up @@ -2839,8 +2839,9 @@ def setUp(self):
@mock.patch('nova.privsep.linux_net.add_bridge', return_value=('', ''))
@mock.patch('nova.privsep.linux_net.set_device_mtu')
@mock.patch('nova.privsep.linux_net.set_device_enabled')
def test_allocate_for_instance(self, mock_set_enabeld, mock_set_mtu,
mock_add_bridge):
@mock.patch('nova.privsep.linux_net.set_device_macaddr')
def test_allocate_for_instance(self, mock_set_macaddr, mock_set_enabled,
mock_set_mtu, mock_add_bridge):
address = "10.10.10.10"
self.flags(auto_assign_floating_ip=True)

Expand Down Expand Up @@ -2907,7 +2908,9 @@ def test_allocate_for_instance_illegal_network(self):
@mock.patch('nova.privsep.linux_net.add_bridge', return_value=('', ''))
@mock.patch('nova.privsep.linux_net.set_device_mtu')
@mock.patch('nova.privsep.linux_net.set_device_enabled')
def test_allocate_for_instance_with_mac(self, mock_enabled, mock_set_mtu,
@mock.patch('nova.privsep.linux_net.set_device_macaddr')
def test_allocate_for_instance_with_mac(self, mock_set_addr,
mock_enabled, mock_set_mtu,
mock_add_bridge):
available_macs = set(['ca:fe:de:ad:be:ef'])
inst = db.instance_create(self.context, {'host': HOST,
Expand Down
9 changes: 5 additions & 4 deletions nova/tests/unit/network/test_utils.py
Expand Up @@ -44,17 +44,18 @@ def test_create_tap_skipped_when_exists(self, mock_execute, mock_exists):

@mock.patch('nova.utils.execute')
@mock.patch('nova.privsep.linux_net.set_device_enabled')
def test_create_tap_dev_mac(self, mock_enabled, mock_execute):
@mock.patch('nova.privsep.linux_net.set_device_macaddr')
def test_create_tap_dev_mac(self, mock_set_macaddr, mock_enabled,
mock_execute):
net_utils.create_tap_dev('tap42', '00:11:22:33:44:55')

mock_execute.assert_has_calls([
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
run_as_root=True, check_exit_code=[0, 2, 254]),
mock.call('ip', 'link', 'set', 'tap42',
'address', '00:11:22:33:44:55',
run_as_root=True, check_exit_code=[0, 2, 254])
])
mock_enabled.assert_called_once_with('tap42')
mock_set_macaddr.assert_has_calls([
mock.call('tap42', '00:11:22:33:44:55')])

@mock.patch('nova.utils.execute')
@mock.patch('nova.privsep.linux_net.set_device_enabled')
Expand Down
17 changes: 8 additions & 9 deletions nova/tests/unit/virt/libvirt/test_vif.py
Expand Up @@ -950,8 +950,9 @@ def test_generic_driver_bridge(self):
@mock.patch.object(utils, 'execute')
@mock.patch.object(pci_utils, 'get_ifname_by_pci_address')
@mock.patch.object(pci_utils, 'get_vf_num_by_pci_address', return_value=1)
def _test_hw_veb_op(self, op, vlan, mock_get_vf_num, mock_get_ifname,
mock_execute):
@mock.patch('nova.privsep.linux_net.set_device_macaddr')
def _test_hw_veb_op(self, op, vlan, mock_set_macaddr, mock_get_vf_num,
mock_get_ifname, mock_execute):
mock_get_ifname.side_effect = ['eth1', 'eth13']
exit_code = [0, 2, 254]
port_state = 'up' if vlan > 0 else 'down'
Expand All @@ -967,18 +968,16 @@ def _test_hw_veb_op(self, op, vlan, mock_get_vf_num, mock_get_ifname,
self.vif_hw_veb_macvtap['address'],
'vlan', vlan,
run_as_root=True,
check_exit_code=exit_code),
mock.call('ip', 'link', 'set',
'eth13', 'address',
self.vif_hw_veb_macvtap['address'],
port_state,
run_as_root=True,
check_exit_code=exit_code)]
check_exit_code=exit_code)],
'set_macaddr': [mock.call('eth13',
self.vif_hw_veb_macvtap['address'],
port_state=port_state)]
}
op(self.instance, self.vif_hw_veb_macvtap)
mock_get_ifname.assert_has_calls(calls['get_ifname'])
mock_get_vf_num.assert_has_calls(calls['get_vf_num'])
mock_execute.assert_has_calls(calls['execute'])
mock_set_macaddr.assert_has_calls(calls['set_macaddr'])

def test_plug_hw_veb(self):
d = vif.LibvirtGenericVIFDriver()
Expand Down
6 changes: 4 additions & 2 deletions nova/tests/unit/virt/xenapi/test_xenapi.py
Expand Up @@ -1138,8 +1138,10 @@ def test_spawn_injects_auto_disk_config_to_xenstore(
@mock.patch('nova.privsep.linux_net.add_bridge', return_value=('', ''))
@mock.patch('nova.privsep.linux_net.set_device_mtu')
@mock.patch('nova.privsep.linux_net.set_device_enabled')
def test_spawn_vlanmanager(self, mock_set_enabled, mock_set_mtu,
mock_add_bridge, mock_create_vifs):
@mock.patch('nova.privsep.linux_net.set_device_macaddr')
def test_spawn_vlanmanager(self, mock_set_macaddr, mock_set_enabled,
mock_set_mtu, mock_add_bridge,
mock_create_vifs):
self.flags(network_manager='nova.network.manager.VlanManager',
vlan_interface='fake0')
# Reset network table
Expand Down

0 comments on commit 13e283c

Please sign in to comment.