def port_update(self, context, **kwargs): LOG.debug("port_update received") port = kwargs.get('port') vnic_type = port.get(portbindings.VNIC_TYPE) if vnic_type and vnic_type == portbindings.VNIC_DIRECT_PHYSICAL: LOG.debug("The SR-IOV agent doesn't handle %s ports.", portbindings.VNIC_DIRECT_PHYSICAL) return # Put the port mac address in the updated_devices set. # Do not store port details, as if they're used for processing # notifications there is no guarantee the notifications are # processed in the same order as the relevant API requests. mac = port['mac_address'] pci_slot = port.get(portbindings.PROFILE, {}).get('pci_slot') if pci_slot: self.agent.updated_devices.add(agent_rpc.DeviceInfo(mac, pci_slot)) LOG.debug("port_update RPC received for port: %(id)s with MAC " "%(mac)s and PCI slot %(pci_slot)s slot", {'id': port['id'], 'mac': mac, 'pci_slot': pci_slot}) else: LOG.debug("No PCI Slot for port %(id)s with MAC %(mac)s; " "skipping", {'id': port['id'], 'mac': mac, 'pci_slot': pci_slot})
def setUp(self): super(TestSriovNicSwitchRpcCallbacks, self).setUp() self.context = object() self.agent = FakeAgent() sg_agent = object() self.sriov_rpc_callback = sriov_nic_agent.SriovNicSwitchRpcCallbacks( self.context, self.agent, sg_agent) self.device_info = agent_rpc.DeviceInfo(DEVICE_MAC, PCI_SLOT)
def treat_devices_added_updated(self, devices_info): try: rpc_devices_details = self.plugin_rpc.get_devices_details_list( self.context, devices_info, self.agent_id, self.conf.host) except Exception as e: LOG.debug( "Unable to get port details for devices " "with MAC addresses %(devices)s: %(e)s", { 'devices': devices_info, 'e': e }) # resync is needed return True devices_up = set() devices_down = set() resync = False for device_details in rpc_devices_details: mac_address = device_details['device'] LOG.debug("Port with MAC address %s is added", mac_address) if 'port_id' in device_details: LOG.info("Port %(device)s updated. Details: %(details)s", { 'device': mac_address, 'details': device_details }) port_id = device_details['port_id'] profile = device_details['profile'] device_info = agent_rpc.DeviceInfo(mac_address, profile.get('pci_slot')) spoofcheck = device_details.get('port_security_enabled', True) if self.treat_device( device_info, device_details['admin_state_up'], spoofcheck, device_details['propagate_uplink_status']): if device_details['admin_state_up']: devices_up.add(device_info) else: devices_down.add(device_info) else: resync = True self._update_network_ports(device_details['network_id'], port_id, device_info) self.ext_manager.handle_port(self.context, device_details) elif n_constants.NO_ACTIVE_BINDING in device_details: # Port was added but its binding in this agent # hasn't been activated yet. It will be treated as # added when binding is activated LOG.info("Device with MAC %s has no active binding in host", mac_address) else: LOG.info("Device with MAC %s not defined on plugin", mac_address) self.plugin_rpc.update_device_list(self.context, devices_up, devices_down, self.agent_id, self.conf.host) return resync
def test_treat_devices_added_updated_sends_host(self): agent = self.agent host = 'host1' cfg.CONF.set_override('host', host) agent.plugin_rpc = mock.Mock() agent.plugin_rpc.get_devices_details_list.return_value = [RPC_DEV1] devices = {agent_rpc.DeviceInfo(DEV1.mac, DEV1.pci_slot)} agent.treat_devices_added_updated(devices) agent.plugin_rpc.get_devices_details_list.assert_called_once_with( agent.context, devices, agent.agent_id, host)
def test_treat_devices_removed_with_existed_device(self, *args): agent = sriov_nic_agent.SriovNicSwitchAgent({}, {}, 0, {}, {}, {}) devices = {agent_rpc.DeviceInfo(DEVICE_MAC, PCI_SLOT)} with mock.patch.object(agent.plugin_rpc, "update_device_down") as fn_udd: fn_udd.return_value = {'device': DEVICE_MAC, 'exists': True} resync = agent.treat_devices_removed(devices) self.assertFalse(resync) self.assertTrue(fn_udd.called)
def test_treat_devices_removed_failed(self, *args): agent = sriov_nic_agent.SriovNicSwitchAgent({}, {}, 0, {}, {}, {}) devices = {agent_rpc.DeviceInfo(DEVICE_MAC, PCI_SLOT)} with mock.patch.object(agent.plugin_rpc, "update_device_down") as fn_udd: fn_udd.side_effect = Exception() with mock.patch.object(sriov_nic_agent.LOG, 'debug') as log: resync = agent.treat_devices_removed(devices) self.assertEqual(1, log.call_count) self.assertTrue(resync) self.assertTrue(fn_udd.called)
def test_get_assigned_devices_info(self): with mock.patch.object(pci_lib.PciDeviceIPWrapper, 'get_assigned_macs', return_value={0: self.ASSIGNED_MAC}), \ mock.patch.object(esm.PciOsWrapper, 'pf_device_exists', return_value=True), \ mock.patch.object(esm.PciOsWrapper, 'is_assigned_vf_direct', return_value=True): result = self.emb_switch.get_assigned_devices_info() device_info = agent_rpc.DeviceInfo(self.ASSIGNED_MAC, self.PCI_SLOT) self.assertEqual(1, len(result)) self.assertEqual(device_info, result[0])
def get_assigned_devices_info(self): """Get assigned Virtual Functions mac and pci slot information and populates vf_to_pci_slot mappings @return: list of VF pair (mac address, pci slot) """ assigned_devices_info = [] for pci_slot, vf_index in self.pci_slot_map.items(): mac = self.get_pci_device(pci_slot) if mac: assigned_devices_info.append( agent_rpc.DeviceInfo(mac, pci_slot)) return assigned_devices_info
from neutron_lib.api.definitions import portbindings from neutron_lib import constants from oslo_config import cfg from oslo_utils import uuidutils import pyroute2 from neutron.agent.l2 import l2_agent_extensions_manager as l2_ext_manager from neutron.agent import rpc as agent_rpc from neutron.plugins.ml2.drivers.mech_sriov.agent.common import config # noqa from neutron.plugins.ml2.drivers.mech_sriov.agent import sriov_nic_agent from neutron.privileged.agent.linux import ip_lib as priv_ip_lib from neutron.tests import base DEVICE_MAC = '11:22:33:44:55:66' PCI_SLOT = "0000:06:00.1" DEV1 = agent_rpc.DeviceInfo('mac1', 'pci_slot1') DEV2 = agent_rpc.DeviceInfo('mac2', 'pci_slot2') DEV3 = agent_rpc.DeviceInfo('mac3', 'pci_slot3') DEV4 = agent_rpc.DeviceInfo('mac4', 'pci_slot4') RPC_DEV1 = {'device': DEV1.mac, 'port_id': 'port123', 'network_id': 'net123', 'admin_state_up': True, 'propagate_uplink_status': False, 'network_type': 'vlan', 'segmentation_id': 100, 'profile': {'pci_slot': DEV1.pci_slot}, 'physical_network': 'physnet1', 'port_security_enabled': False} RPC_DEV2 = {'device': DEV2.mac, 'port_id': 'port321',