diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index 66be7b55c301..4f1c470e952d 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -1231,18 +1231,6 @@ def _ovs_vsctl(args): raise exception.OvsConfigurationFailure(inner_exception=e) -def create_ivs_vif_port(dev, iface_id, mac, instance_id): - utils.execute('ivs-ctl', 'add-port', - dev, run_as_root=True) - - -def delete_ivs_vif_port(dev): - utils.execute('ivs-ctl', 'del-port', dev, - run_as_root=True) - utils.execute('ip', 'link', 'delete', dev, - run_as_root=True) - - def create_tap_dev(dev, mac_address=None, multiqueue=False): if not linux_net_utils.device_exists(dev): try: diff --git a/nova/network/os_vif_util.py b/nova/network/os_vif_util.py index fe5e52fe9e49..1634fb36ff4a 100644 --- a/nova/network/os_vif_util.py +++ b/nova/network/os_vif_util.py @@ -410,7 +410,20 @@ def _nova_to_osvif_vif_vhostuser(vif): # VIF_TYPE_IVS = 'ivs' def _nova_to_osvif_vif_ivs(vif): - raise NotImplementedError() + if _is_firewall_required(vif) or vif.is_hybrid_plug_enabled(): + obj = _get_vif_instance( + vif, + objects.vif.VIFBridge, + plugin="ivs", + vif_name=_get_vif_name(vif), + bridge_name=_get_hybrid_bridge_name(vif)) + else: + obj = _get_vif_instance( + vif, + objects.vif.VIFGeneric, + plugin="ivs", + vif_name=_get_vif_name(vif)) + return obj # VIF_TYPE_DVS = 'dvs' diff --git a/nova/privsep/libvirt.py b/nova/privsep/libvirt.py index 8260e264bb3a..64d46b90d654 100644 --- a/nova/privsep/libvirt.py +++ b/nova/privsep/libvirt.py @@ -121,15 +121,6 @@ def enable_hairpin(interface): f.write('1') -@nova.privsep.sys_admin_pctxt.entrypoint -def add_bridge(interface): - """Create a bridge. - - :param interface: the name of the bridge - """ - processutils.execute('brctl', 'addbr', interface) - - @nova.privsep.sys_admin_pctxt.entrypoint def delete_bridge(interface): """Delete a bridge. @@ -139,54 +130,6 @@ def delete_bridge(interface): processutils.execute('brctl', 'delbr', interface) -@nova.privsep.sys_admin_pctxt.entrypoint -def zero_bridge_forward_delay(interface): - """Set the forward delay on a bridge to zero. - - :param interface: the name of the bridge - """ - processutils.execute('brctl', 'setfd', interface, 0) - - -@nova.privsep.sys_admin_pctxt.entrypoint -def disable_bridge_stp(interface): - """Disable spanning tree protocol for the named bridge. - - :param interface: the name of the bridge - """ - processutils.execute('brctl', 'stp', interface, 'off') - - -@nova.privsep.sys_admin_pctxt.entrypoint -def toggle_interface(interface, updown): - """Bring named interfaces up or down. - - :param interface: the name of the bridge - :param updown: 'up', or 'down' - """ - processutils.execute('ip', 'link', 'set', interface, updown) - - -@nova.privsep.sys_admin_pctxt.entrypoint -def bridge_add_interface(bridge, newif): - """Add an interface to a bridge - - :param bridge: the name of the bridge - :param newif: the name of the interface to add - """ - processutils.execute('brctl', 'addif', bridge, newif) - - -@nova.privsep.sys_admin_pctxt.entrypoint -def bridge_delete_interface(bridge, removeif): - """Remove an interface from a bridge - - :param bridge: the name of the bridge - :param removeif: the name of the interface to delete - """ - processutils.execute('brctl', 'delif', bridge, removeif) - - @nova.privsep.sys_admin_pctxt.entrypoint def plug_infiniband_vif(vnic_mac, device_id, fabric, net_model, pci_slot): processutils.execute('ebrctl', 'add-port', vnic_mac, device_id, @@ -254,21 +197,6 @@ def unplug_contrail_vif(port_id): processutils.execute(*cmd) -@nova.privsep.sys_admin_pctxt.entrypoint -def disable_multicast_snooping(interface): - """Disable multicast snooping for a bridge.""" - with open('/sys/class/net/%s/bridge/multicast_snooping' % interface, - 'w') as f: - f.write('0') - - -@nova.privsep.sys_admin_pctxt.entrypoint -def disable_ipv6(interface): - """Disable ipv6 for a bridge.""" - with open('/proc/sys/net/ipv6/conf/%s/disable_ipv' % interface, 'w') as f: - f.write('1') - - @nova.privsep.sys_admin_pctxt.entrypoint def readpty(path): # TODO(mikal): I'm not a huge fan that we don't enforce a valid pty path diff --git a/nova/tests/unit/network/test_os_vif_util.py b/nova/tests/unit/network/test_os_vif_util.py index 8ae338d76b03..1864f99a48cd 100644 --- a/nova/tests/unit/network/test_os_vif_util.py +++ b/nova/tests/unit/network/test_os_vif_util.py @@ -974,8 +974,33 @@ class OSVIFUtilTestCase(test.NoDBTestCase): ) actual = os_vif_util.nova_to_osvif_vif(vif) + # expected vif_name is nic + vif_id, with total length 14 chars + expected_vif_name = 'nicdc065497-3c' - self.assertIsNone(actual) + self.assertIsInstance(actual, osv_objects.vif.VIFGeneric) + self.assertEqual(expected_vif_name, actual.vif_name) + + def test_nova_to_osvif_vif_ivs_bridged(self): + vif = model.VIF( + id="dc065497-3c8d-4f44-8fb4-e1d33c16a536", + type=model.VIF_TYPE_IVS, + address="22:52:25:62:e2:aa", + network=model.Network( + id="b82c1929-051e-481d-8110-4669916c7915", + label="Demo Net", + subnets=[]), + details={ + model.VIF_DETAILS_PORT_FILTER: True, + model.VIF_DETAILS_OVS_HYBRID_PLUG: True, + } + ) + + actual = os_vif_util.nova_to_osvif_vif(vif) + # expected vif_name is nic + vif_id, with total length 14 chars + expected_vif_name = 'nicdc065497-3c' + + self.assertIsInstance(actual, osv_objects.vif.VIFBridge) + self.assertEqual(expected_vif_name, actual.vif_name) def test_nova_to_osvif_vif_unknown(self): vif = model.VIF( diff --git a/nova/tests/unit/virt/libvirt/test_designer.py b/nova/tests/unit/virt/libvirt/test_designer.py index 7f3323a1a724..dba09dafd086 100644 --- a/nova/tests/unit/virt/libvirt/test_designer.py +++ b/nova/tests/unit/virt/libvirt/test_designer.py @@ -58,14 +58,6 @@ class DesignerTestCase(test.NoDBTestCase): self.assertEqual('fake-queues', conf.vhost_queues) self.assertEqual(1024, conf.vhost_rx_queue_size) - def test_set_vif_host_backend_bridge_config(self): - conf = config.LibvirtConfigGuestInterface() - designer.set_vif_host_backend_bridge_config(conf, 'fake-bridge', - 'fake-tap') - self.assertEqual('bridge', conf.net_type) - self.assertEqual('fake-bridge', conf.source_dev) - self.assertEqual('fake-tap', conf.target_dev) - def test_set_vif_host_backend_ethernet_config_libvirt_1_3_3(self): conf = config.LibvirtConfigGuestInterface() mock_host = mock.Mock(autospec=host.Host) diff --git a/nova/tests/unit/virt/libvirt/test_vif.py b/nova/tests/unit/virt/libvirt/test_vif.py index 5866931f41d1..902c9738ad87 100644 --- a/nova/tests/unit/virt/libvirt/test_vif.py +++ b/nova/tests/unit/virt/libvirt/test_vif.py @@ -12,8 +12,6 @@ # License for the specific language governing permissions and limitations # under the License. -import os - import fixtures from lxml import etree import mock @@ -99,13 +97,6 @@ class LibvirtVifTestCase(test.NoDBTestCase): bridge_interface=None, vlan=99, mtu=1000) - network_ivs = network_model.Network(id=uuids.network, - bridge='br0', - label=None, - subnets=[subnet_bridge_4, subnet_bridge_6], - bridge_interface=None, - vlan=99) - vif_agilio_ovs = network_model.VIF(id=uuids.vif, address='ca:fe:de:ad:be:ef', network=network_ovs, @@ -167,38 +158,6 @@ class LibvirtVifTestCase(test.NoDBTestCase): devname=None, ovs_interfaceid=None) - vif_ivs = network_model.VIF(id=uuids.vif, - address='ca:fe:de:ad:be:ef', - network=network_ivs, - type=network_model.VIF_TYPE_IVS, - devname='tap-xxx-yyy-zzz', - ovs_interfaceid=uuids.ovs) - - vif_ivs_filter_cap = network_model.VIF(id=uuids.vif, - address='ca:fe:de:ad:be:ef', - network=network_ivs, - type=network_model.VIF_TYPE_IVS, - details={'port_filter': True}, - devname='tap-xxx-yyy-zzz', - ovs_interfaceid=uuids.ovs) - - vif_ivs_hybrid = network_model.VIF(id=uuids.vif, - address='ca:fe:de:ad:be:ef', - network=network_ivs, - type=network_model.VIF_TYPE_IVS, - details={ - 'port_filter': True, - 'ovs_hybrid_plug': True}, - devname='tap-xxx-yyy-zzz', - ovs_interfaceid=uuids.ovs) - - vif_ivs_legacy = network_model.VIF(id=uuids.vif, - address='ca:fe:de:ad:be:ef', - network=network_ovs, - type=None, - devname=None, - ovs_interfaceid='aaa') - vif_none = network_model.VIF(id=uuids.vif, address='ca:fe:de:ad:be:ef', network=network_bridge, @@ -898,7 +857,6 @@ class LibvirtVifTestCase(test.NoDBTestCase): self._test_model_qemu( self.vif_bridge, self.vif_ovs, - self.vif_ivs, self.vif_8021qbg, self.vif_iovisor ) @@ -931,25 +889,6 @@ class LibvirtVifTestCase(test.NoDBTestCase): self.vif_bridge, self.vif_bridge['network']['bridge']) - def _check_ivs_ethernet_driver(self, d, vif, dev_prefix): - self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver") - xml = self._get_instance_xml(d, vif) - node = self._get_node(xml) - self._assertTypeAndMacEquals(node, "ethernet", "target", "dev", - self.vif_ivs, prefix=dev_prefix) - script = node.find("script") - self.assertIsNone(script) - - @mock.patch('nova.privsep.libvirt.bridge_delete_interface') - @mock.patch('nova.privsep.libvirt.toggle_interface') - @mock.patch('nova.privsep.libvirt.delete_bridge') - def test_unplug_ivs_ethernet(self, delete_bridge, toggle_interface, - bridge_delete_interface): - d = vif.LibvirtGenericVIFDriver() - with mock.patch.object(linux_net, 'delete_ivs_vif_port') as delete: - delete.side_effect = processutils.ProcessExecutionError - d.unplug(self.instance, self.vif_ivs) - @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) @@ -993,87 +932,6 @@ class LibvirtVifTestCase(test.NoDBTestCase): d = vif.LibvirtGenericVIFDriver() self._test_hw_veb_op(d.unplug, 0) - def test_plug_ivs_hybrid(self): - with test.nested( - mock.patch('nova.network.linux_utils.device_exists', - return_value=False), - mock.patch('nova.network.linux_utils.create_veth_pair'), - mock.patch.object(linux_net, 'create_ivs_vif_port'), - mock.patch.object(os.path, 'exists', return_value=True), - mock.patch('nova.privsep.libvirt.disable_multicast_snooping'), - mock.patch('nova.privsep.libvirt.disable_ipv6'), - mock.patch('nova.privsep.libvirt.add_bridge'), - mock.patch('nova.privsep.libvirt.zero_bridge_forward_delay'), - mock.patch('nova.privsep.libvirt.disable_bridge_stp'), - mock.patch('nova.privsep.libvirt.toggle_interface'), - mock.patch('nova.privsep.libvirt.bridge_add_interface') - ) as (device_exists, create_veth_pair, create_ivs_vif_port, - path_exists, disable_multicast_snooping, disable_ipv6, - add_bridge, zero_bridge_forward_delay, disable_bridge_stp, - toggle_interface, bridge_add_interface): - d = vif.LibvirtGenericVIFDriver() - d.plug(self.instance, self.vif_ivs) - - qvo_want = "qvo" + self.vif_ivs['id'] - qvo_want = qvo_want[:network_model.NIC_NAME_LEN] - qbr_want = "qbr" + self.vif_ivs['id'] - qbr_want = qbr_want[:network_model.NIC_NAME_LEN] - qvb_want = "qvb" + self.vif_ivs['id'] - qvb_want = qvb_want[:network_model.NIC_NAME_LEN] - - device_exists.assert_has_calls([mock.call(qbr_want), - mock.call(qvo_want)]) - create_veth_pair.assert_has_calls( - [mock.call(qvb_want, qvo_want, None)]) - create_ivs_vif_port.assert_has_calls( - [mock.call(qvo_want, uuids.ovs, - 'ca:fe:de:ad:be:ef', - 'f0000000-0000-0000-0000-000000000001')]) - - disable_multicast_snooping.assert_has_calls( - [mock.call(qbr_want)]) - disable_ipv6.assert_has_calls([mock.call(qbr_want)]) - add_bridge.assert_has_calls([mock.call(qbr_want)]) - zero_bridge_forward_delay.assert_has_calls( - [mock.call(qbr_want)]) - disable_bridge_stp.assert_has_calls([mock.call(qbr_want)]) - toggle_interface.assert_has_calls( - [mock.call(qbr_want, 'up')]) - bridge_add_interface.assert_has_calls( - [mock.call(qbr_want, qvb_want)]) - - def test_unplug_ivs_hybrid(self): - with test.nested( - mock.patch.object(utils, 'execute'), - mock.patch.object(linux_net, 'delete_ivs_vif_port'), - mock.patch('nova.privsep.libvirt.bridge_delete_interface'), - mock.patch('nova.privsep.libvirt.toggle_interface'), - mock.patch('nova.privsep.libvirt.delete_bridge') - ) as (execute, delete_ivs_vif_port, bridge_delete_interface, - toggle_interface, delete_bridge): - d = vif.LibvirtGenericVIFDriver() - d.unplug(self.instance, self.vif_ivs) - - qvo_want = "qvo" + self.vif_ivs['id'] - qvo_want = qvo_want[:network_model.NIC_NAME_LEN] - qbr_want = "qbr" + self.vif_ivs['id'] - qbr_want = qbr_want[:network_model.NIC_NAME_LEN] - qvb_want = "qvb" + self.vif_ivs['id'] - qvb_want = qvb_want[:network_model.NIC_NAME_LEN] - - delete_ivs_vif_port.assert_has_calls([mock.call(qvo_want)]) - bridge_delete_interface.assert_has_calls( - [mock.call(qbr_want, qvb_want)]) - toggle_interface.assert_has_calls( - [mock.call(qbr_want, 'down')]) - delete_bridge.assert_has_calls([mock.call(qbr_want)]) - - @mock.patch('nova.privsep.libvirt.bridge_delete_interface', - side_effect=processutils.ProcessExecutionError) - def test_unplug_ivs_hybrid_bridge_does_not_exist(self, bdi): - d = vif.LibvirtGenericVIFDriver() - d.unplug(self.instance, self.vif_ivs) - @mock.patch('nova.privsep.libvirt.unplug_plumgrid_vif', side_effect=processutils.ProcessExecutionError) def test_unplug_iovisor(self, mock_unplug): @@ -1144,19 +1002,6 @@ class LibvirtVifTestCase(test.NoDBTestCase): 'NovaVMPort', self.vif_vrouter['devname'], self.vif_vrouter['address'], '0.0.0.0', None) - def test_ivs_ethernet_driver(self): - d = vif.LibvirtGenericVIFDriver() - self._check_ivs_ethernet_driver(d, - self.vif_ivs, - "tap") - - def _check_ivs_virtualport_driver(self, d, vif, want_iface_id): - self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver") - xml = self._get_instance_xml(d, vif) - node = self._get_node(xml) - self._assertTypeAndMacEquals(node, "ethernet", "target", "dev", - vif, vif['devname']) - def _check_ovs_virtualport_driver(self, d, vif, want_iface_id): self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver") xml = self._get_instance_xml(d, vif) @@ -1181,41 +1026,6 @@ class LibvirtVifTestCase(test.NoDBTestCase): self.vif_ovs, want_iface_id) - def test_generic_ivs_virtualport_driver(self): - d = vif.LibvirtGenericVIFDriver() - want_iface_id = self.vif_ivs['ovs_interfaceid'] - self._check_ivs_virtualport_driver(d, - self.vif_ivs, - want_iface_id) - - def test_ivs_plug_with_nova_firewall(self): - d = vif.LibvirtGenericVIFDriver() - br_want = "qbr" + self.vif_ivs['id'] - br_want = br_want[:network_model.NIC_NAME_LEN] - xml = self._get_instance_xml(d, self.vif_ivs) - node = self._get_node(xml) - self._assertTypeAndMacEquals(node, "bridge", "source", "bridge", - self.vif_ivs, br_want, 1) - - def test_ivs_plug_with_port_filter_direct_no_nova_firewall(self): - d = vif.LibvirtGenericVIFDriver() - br_want = "qbr" + self.vif_ivs_hybrid['id'] - br_want = br_want[:network_model.NIC_NAME_LEN] - self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver") - xml = self._get_instance_xml(d, self.vif_ivs_hybrid) - node = self._get_node(xml) - self._assertTypeAndMacEquals(node, "bridge", "source", "bridge", - self.vif_ivs_hybrid, br_want, 0) - - def test_ivs_plug_with_port_hybrid_no_nova_firewall(self): - d = vif.LibvirtGenericVIFDriver() - br_want = self.vif_ivs_filter_cap['devname'] - self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver") - xml = self._get_instance_xml(d, self.vif_ivs_filter_cap) - node = self._get_node(xml) - self._assertTypeAndMacEquals(node, "ethernet", "target", "dev", - self.vif_ivs_filter_cap, br_want, 0) - def test_direct_plug_with_port_filter_cap_no_nova_firewall(self): d = vif.LibvirtGenericVIFDriver() br_want = self.vif_midonet['devname'] @@ -1239,14 +1049,6 @@ class LibvirtVifTestCase(test.NoDBTestCase): self.vif_ovs, br_want) - def test_ivs_hybrid_driver(self): - d = vif.LibvirtGenericVIFDriver() - br_want = "qbr" + self.vif_ivs['id'] - br_want = br_want[:network_model.NIC_NAME_LEN] - self._check_neutron_hybrid_driver(d, - self.vif_ivs, - br_want) - def test_ib_hostdev_driver(self): d = vif.LibvirtGenericVIFDriver() xml = self._get_instance_xml(d, self.vif_ib_hostdev) @@ -1403,11 +1205,11 @@ class LibvirtVifTestCase(test.NoDBTestCase): def test_generic_iovisor_driver(self): d = vif.LibvirtGenericVIFDriver() self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver") - br_want = self.vif_ivs['devname'] - xml = self._get_instance_xml(d, self.vif_ivs) + br_want = self.vif_iovisor['devname'] + xml = self._get_instance_xml(d, self.vif_iovisor) node = self._get_node(xml) self._assertTypeAndMacEquals(node, "ethernet", "target", "dev", - self.vif_ivs, br_want) + self.vif_iovisor, br_want) def test_generic_8021qbg_driver(self): d = vif.LibvirtGenericVIFDriver() diff --git a/nova/virt/libvirt/designer.py b/nova/virt/libvirt/designer.py index 488b9aef89ff..89038f3bc9ad 100644 --- a/nova/virt/libvirt/designer.py +++ b/nova/virt/libvirt/designer.py @@ -43,16 +43,6 @@ def set_vif_guest_frontend_config(conf, mac, model, driver, queues, conf.vhost_rx_queue_size = rx_queue_size -def set_vif_host_backend_bridge_config(conf, brname, tapname=None): - """Populate a LibvirtConfigGuestInterface instance - with host backend details for a software bridge. - """ - conf.net_type = "bridge" - conf.source_dev = brname - if tapname: - conf.target_dev = tapname - - def set_vif_host_backend_ethernet_config(conf, tapname, host): """Populate a LibvirtConfigGuestInterface instance with host backend details for an externally configured diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index af9385cd45ae..5be6c96da1cd 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -18,7 +18,6 @@ """VIF drivers for libvirt.""" -import copy import os import os_vif @@ -230,9 +229,6 @@ class LibvirtGenericVIFDriver(object): def get_ovs_interfaceid(self, vif): return vif.get('ovs_interfaceid') or vif['id'] - def get_br_name(self, iface_id): - return ("qbr" + iface_id)[:network_model.NIC_NAME_LEN] - def get_veth_pair_names(self, iface_id): return (("qvb%s" % iface_id)[:network_model.NIC_NAME_LEN], ("qvo%s" % iface_id)[:network_model.NIC_NAME_LEN]) @@ -241,13 +237,6 @@ class LibvirtGenericVIFDriver(object): def is_no_op_firewall(): return CONF.firewall_driver == "nova.virt.firewall.NoopFirewallDriver" - def get_firewall_required(self, vif): - if vif.is_neutron_filtering_enabled(): - return False - if self.is_no_op_firewall(): - return False - return True - def get_firewall_required_os_vif(self, vif): if vif.has_traffic_filtering: return False @@ -255,66 +244,6 @@ class LibvirtGenericVIFDriver(object): return False return True - def get_config_bridge(self, instance, vif, image_meta, - inst_type, virt_type, host): - """Get VIF configurations for bridge type.""" - conf = self.get_base_config(instance, vif['address'], image_meta, - inst_type, virt_type, vif['vnic_type'], - host) - - designer.set_vif_host_backend_bridge_config( - conf, self.get_bridge_name(vif), - self.get_vif_devname(vif)) - - mac_id = vif['address'].replace(':', '') - name = "nova-instance-" + instance.name + "-" + mac_id - if self.get_firewall_required(vif): - conf.filtername = name - designer.set_vif_bandwidth_config(conf, inst_type) - - return conf - - def get_config_ivs_hybrid(self, instance, vif, image_meta, - inst_type, virt_type, host): - newvif = copy.deepcopy(vif) - newvif['network']['bridge'] = self.get_br_name(vif['id']) - return self.get_config_bridge(instance, - newvif, - image_meta, - inst_type, - virt_type, - host) - - def get_config_ivs_ethernet(self, instance, vif, image_meta, - inst_type, virt_type, host): - conf = self.get_base_config(instance, - vif['address'], - image_meta, - inst_type, - virt_type, - vif['vnic_type'], - host) - - dev = self.get_vif_devname(vif) - designer.set_vif_host_backend_ethernet_config(conf, dev, host) - - return conf - - def get_config_ivs(self, instance, vif, image_meta, - inst_type, virt_type, host): - if self.get_firewall_required(vif) or vif.is_hybrid_plug_enabled(): - return self.get_config_ivs_hybrid(instance, vif, - image_meta, - inst_type, - virt_type, - host) - else: - return self.get_config_ivs_ethernet(instance, vif, - image_meta, - inst_type, - virt_type, - host) - def get_config_802qbg(self, instance, vif, image_meta, inst_type, virt_type, host): conf = self.get_base_config(instance, vif['address'], image_meta, @@ -530,6 +459,10 @@ class LibvirtGenericVIFDriver(object): designer.set_vif_bandwidth_config(conf, inst_type) return conf + def _set_config_VIFGeneric(self, instance, vif, conf, host): + dev = self.get_vif_devname(vif) + designer.set_vif_host_backend_ethernet_config(conf, dev, host) + def _set_config_VIFBridge(self, instance, vif, conf, host=None): conf.net_type = "bridge" conf.source_dev = vif.bridge_name @@ -658,46 +591,6 @@ class LibvirtGenericVIFDriver(object): return func(instance, vif, image_meta, inst_type, virt_type, host) - def plug_ivs_hybrid(self, instance, vif): - """Plug using hybrid strategy (same as OVS) - - Create a per-VIF linux bridge, then link that bridge to the OVS - integration bridge via a veth device, setting up the other end - of the veth device just like a normal IVS port. Then boot the - VIF on the linux bridge using standard libvirt mechanisms. - """ - iface_id = self.get_ovs_interfaceid(vif) - br_name = self.get_br_name(vif['id']) - v1_name, v2_name = self.get_veth_pair_names(vif['id']) - - if not linux_net_utils.device_exists(br_name): - nova.privsep.libvirt.add_bridge(br_name) - nova.privsep.libvirt.zero_bridge_forward_delay(br_name) - nova.privsep.libvirt.disable_bridge_stp(br_name) - nova.privsep.libvirt.disable_multicast_snooping(br_name) - nova.privsep.libvirt.disable_ipv6(br_name) - - if not linux_net_utils.device_exists(v2_name): - mtu = vif['network'].get_meta('mtu') - linux_net_utils.create_veth_pair(v1_name, v2_name, mtu) - nova.privsep.libvirt.toggle_interface(br_name, 'up') - nova.privsep.libvirt.bridge_add_interface(br_name, v1_name) - linux_net.create_ivs_vif_port(v2_name, iface_id, - vif['address'], instance.uuid) - - def plug_ivs_ethernet(self, instance, vif): - iface_id = self.get_ovs_interfaceid(vif) - dev = self.get_vif_devname(vif) - linux_net.create_tap_dev(dev) - linux_net.create_ivs_vif_port(dev, iface_id, vif['address'], - instance.uuid) - - def plug_ivs(self, instance, vif): - if self.get_firewall_required(vif) or vif.is_hybrid_plug_enabled(): - self.plug_ivs_hybrid(instance, vif) - else: - self.plug_ivs_ethernet(instance, vif) - def plug_ib_hostdev(self, instance, vif): fabric = vif.get_physical_network() if not fabric: @@ -870,36 +763,6 @@ class LibvirtGenericVIFDriver(object): "vif_type=%s") % vif_type) func(instance, vif) - def unplug_ivs_hybrid(self, instance, vif): - """UnPlug using hybrid strategy (same as OVS) - - Unhook port from IVS, unhook port from bridge, delete - bridge, and delete both veth devices. - """ - try: - br_name = self.get_br_name(vif['id']) - v1_name, v2_name = self.get_veth_pair_names(vif['id']) - - nova.privsep.libvirt.bridge_delete_interface(br_name, v1_name) - nova.privsep.libvirt.toggle_interface(br_name, 'down') - nova.privsep.libvirt.delete_bridge(br_name) - linux_net.delete_ivs_vif_port(v2_name) - except processutils.ProcessExecutionError: - LOG.exception(_("Failed while unplugging vif"), instance=instance) - - def unplug_ivs_ethernet(self, instance, vif): - """Unplug the VIF by deleting the port from the bridge.""" - try: - linux_net.delete_ivs_vif_port(self.get_vif_devname(vif)) - except processutils.ProcessExecutionError: - LOG.exception(_("Failed while unplugging vif"), instance=instance) - - def unplug_ivs(self, instance, vif): - if self.get_firewall_required(vif) or vif.is_hybrid_plug_enabled(): - self.unplug_ivs_hybrid(instance, vif) - else: - self.unplug_ivs_ethernet(instance, vif) - def unplug_ib_hostdev(self, instance, vif): fabric = vif.get_physical_network() if not fabric: diff --git a/releasenotes/notes/move-ivs-plug-unplug-to-separate-os-vif-plugin-f7ee42da4ed9739b.yaml b/releasenotes/notes/move-ivs-plug-unplug-to-separate-os-vif-plugin-f7ee42da4ed9739b.yaml new file mode 100644 index 000000000000..b3d29e2b44f3 --- /dev/null +++ b/releasenotes/notes/move-ivs-plug-unplug-to-separate-os-vif-plugin-f7ee42da4ed9739b.yaml @@ -0,0 +1,11 @@ +--- +upgrade: + - | + This release moves the livirt driver ``IVS`` VIF plug-unplug to a separate + package called ``os-vif-bigswitch``. This package is a requirement on + compute nodes when using ``networking-bigswitch`` as neutron ML2 and L3 + driver. + Releases are available on https://pypi.org/project/os-vif-bigswitch/. Major + version for the package matches upstream neutron version number. Minor + version tracks compatiblity with Big Cloud Fabric (BCF) releases, and + typically is set to the lowest supported BCF release.