def __init__(self, integ_br, root_helper, polling_interval): super(NVSDNeutronAgent, self).__init__() self.int_br = ovs_lib.OVSBridge(integ_br, root_helper) self.polling_interval = polling_interval self.root_helper = root_helper self.setup_rpc() self.ports = set()
def main(): """Main method for cleaning up OVS bridges. The utility cleans up the integration bridges used by Neutron. """ conf = setup_conf() conf() config.setup_logging() configuration_bridges = set( [conf.ovs_integration_bridge, conf.external_network_bridge]) ovs_bridges = set(ovs_lib.get_bridges(conf.AGENT.root_helper)) available_configuration_bridges = configuration_bridges & ovs_bridges if conf.ovs_all_ports: bridges = ovs_bridges else: bridges = available_configuration_bridges # Collect existing ports created by Neutron on configuration bridges. # After deleting ports from OVS bridges, we cannot determine which # ports were created by Neutron, so port information is collected now. ports = collect_neutron_ports(available_configuration_bridges, conf.AGENT.root_helper) for bridge in bridges: LOG.info(_LI("Cleaning bridge: %s"), bridge) ovs = ovs_lib.OVSBridge(bridge, conf.AGENT.root_helper) ovs.delete_ports(all_ports=conf.ovs_all_ports) # Remove remaining ports created by Neutron (usually veth pair) delete_neutron_ports(ports, conf.AGENT.root_helper) LOG.info(_LI("OVS cleanup completed successfully"))
def collect_neutron_ports(bridges, root_helper): """Collect ports created by Neutron from OVS.""" ports = [] for bridge in bridges: ovs = ovs_lib.OVSBridge(bridge, root_helper) ports += [port.port_name for port in ovs.get_vif_ports()] return ports
def setup_ancillary_bridges(self, integ_br, tun_br): '''Setup ancillary bridges - for example br-ex.''' ovs_bridges = set(ovs_lib.get_bridges(self.root_helper)) # Remove all known bridges ovs_bridges.remove(integ_br) if self.enable_tunneling: ovs_bridges.remove(tun_br) br_names = [ self.phys_brs[physical_network].br_name for physical_network in self.phys_brs ] ovs_bridges.difference_update(br_names) # Filter list of bridges to those that have external # bridge-id's configured br_names = [] for bridge in ovs_bridges: id = ovs_lib.get_bridge_external_bridge_id(self.root_helper, bridge) if id != bridge: br_names.append(bridge) ovs_bridges.difference_update(br_names) ancillary_bridges = [] for bridge in ovs_bridges: br = ovs_lib.OVSBridge(bridge, self.root_helper) LOG.info(_('Adding %s to list of bridges.'), bridge) ancillary_bridges.append(br) return ancillary_bridges
def __init__(self, integ_br, root_helper, polling_interval): self.int_br = ovs_lib.OVSBridge(integ_br, root_helper) self.polling_interval = polling_interval self.root_helper = root_helper self.setup_rpc() self.ports = set()
def ofctl_arg_supported(root_helper, cmd, **kwargs): """Verify if ovs-ofctl binary supports cmd with **kwargs. :param root_helper: utility to use when running shell commands. :param cmd: ovs-ofctl command to use for test. :param **kwargs: arguments to test with the command. :returns: a boolean if the supplied arguments are supported. """ br_name = 'br-test-%s' % utils.get_random_string(6) with ovs_lib.OVSBridge(br_name, root_helper) as test_br: full_args = [ "ovs-ofctl", cmd, test_br.br_name, ovs_lib._build_flow_expr_str(kwargs, cmd.split('-')[0]) ] try: agent_utils.execute(full_args, root_helper=root_helper) except RuntimeError as e: LOG.debug( "Exception while checking supported feature via " "command %s. Exception: %s", (full_args, e)) return False except Exception: LOG.exception( _LE("Unexpected exception while checking supported" " feature via command: %s"), full_args) return False else: return True
def setUp(self): super(OVS_Lib_Test, self).setUp() self.BR_NAME = "br-int" self.br = ovs_lib.OVSBridge(self.BR_NAME) self.execute = mock.patch.object( utils, "execute", spec=utils.execute).start()
def setup_integration_br(self, bridge_name, reset_br, out_of_band, controller_ip=None): '''Sets up the integration bridge. Create the bridge and remove all existing flows if reset_br is True. Otherwise, creates the bridge if not already existing. :param bridge_name: the name of the integration bridge. :param reset_br: A boolean to rest the bridge if True. :param out_of_band: A boolean indicating controller is out of band. :param controller_ip: IP address to use as the bridge controller. :returns: the integration bridge ''' int_br = ovs_lib.OVSBridge(bridge_name, self.root_helper) if reset_br: int_br.reset_bridge() int_br.remove_all_flows() else: int_br.create() # set the controller if controller_ip: int_br.run_vsctl( ["set-controller", bridge_name, "tcp:" + controller_ip]) if out_of_band: int_br.set_db_attribute("controller", bridge_name, "connection-mode", "out-of-band") return int_br
def __init__(self, ): self.conf = cfg.CONF self.root_helper = cconfig.get_root_helper(self.conf) self.external_br = ovs_lib.OVSBridge(EXTERNAL_BRIDGE, self.root_helper) self.sync = True self.ovs_restarted = False self.ip_wrapper = ip_lib.IPWrapper(self.root_helper)
def patch_supported(root_helper): seed = utils.get_random_string(6) name = "patchtest-" + seed peer_name = "peertest0-" + seed patch_name = "peertest1-" + seed with ovs_lib.OVSBridge(name, root_helper) as br: port = br.add_patch_port(patch_name, peer_name) return port != ovs_lib.INVALID_OFPORT
def setUp(self): super(OVS_Lib_Test, self).setUp() self.BR_NAME = "br-int" self.TO = "--timeout=10" self.root_helper = 'sudo' self.br = ovs_lib.OVSBridge(self.BR_NAME, self.root_helper) self.execute = mock.patch.object(utils, "execute", spec=utils.execute).start()
def setUp(self): super(OVS_Lib_Test, self).setUp() self.BR_NAME = "br-int" self.TO = "--timeout=2" self.root_helper = 'sudo' self.br = ovs_lib.OVSBridge(self.BR_NAME, self.root_helper) self.execute = mock.patch.object(utils, "execute").start() self.addCleanup(mock.patch.stopall)
def __init__(self, integ_br, polling_interval, root_helper, vs='ovs'): super(RestProxyAgent, self).__init__() self.polling_interval = polling_interval self._setup_rpc() self.sg_agent = SecurityGroupAgent(self.context, self.plugin_rpc, root_helper) if vs == 'ivs': self.int_br = IVSBridge(integ_br, root_helper) else: self.int_br = ovs_lib.OVSBridge(integ_br, root_helper)
def setUp(self): super(OVS_Lib_Test, self).setUp() self.BR_NAME = "br-int" self.TO = "--timeout=2" self.mox = mox.Mox() self.root_helper = 'sudo' self.br = ovs_lib.OVSBridge(self.BR_NAME, self.root_helper) self.mox.StubOutWithMock(utils, "execute") self.addCleanup(self.mox.UnsetStubs)
def test_bridge_lifecycle_ovsbridge(self): name = base.get_rand_name(prefix=base.BR_PREFIX) br = ovs_lib.OVSBridge(name) self.assertEqual(br.br_name, name) # Make sure that instantiating an OVSBridge does not actually create self.assertFalse(self.ovs.bridge_exists(name)) self.addCleanup(self.ovs.delete_bridge, name) br.create() self.assertTrue(self.ovs.bridge_exists(name)) br.destroy() self.assertFalse(self.ovs.bridge_exists(name))
def unplug_device(conf, device): try: device.link.delete() except RuntimeError: root_helper = agent_config.get_root_helper(conf) # Maybe the device is OVS port, so try to delete bridge_name = ovs_lib.get_bridge_for_iface(root_helper, device.name) if bridge_name: bridge = ovs_lib.OVSBridge(bridge_name, root_helper) bridge.delete_port(device.name) else: LOG.debug(_('Unable to find bridge for device: %s'), device.name)
def unplug_device(conf, device): try: device.link.delete() except RuntimeError: # Maybe the device is OVS port, so try to delete ovs = ovs_lib.BaseOVS() bridge_name = ovs.get_bridge_for_iface(device.name) if bridge_name: bridge = ovs_lib.OVSBridge(bridge_name) bridge.delete_port(device.name) else: LOG.debug('Unable to find bridge for device: %s', device.name)
def _ovs_add_port(self, bridge, device_name, port_id, mac_address, internal=True): attrs = [('external-ids:iface-id', port_id), ('external-ids:iface-status', 'active'), ('external-ids:attached-mac', mac_address)] if internal: attrs.insert(0, ('type', 'internal')) ovs = ovs_lib.OVSBridge(bridge, self.root_helper) ovs.replace_port(device_name, *attrs)
def setup_integration_br(self, bridge_name): '''Setup the integration bridge. Create patch ports and remove all existing flows. :param bridge_name: the name of the integration bridge. :returns: the integration bridge ''' int_br = ovs_lib.OVSBridge(bridge_name, self.root_helper) int_br.delete_port(cfg.CONF.OVS.int_peer_patch_port) int_br.remove_all_flows() # switch all traffic using L2 learning int_br.add_flow(priority=1, actions="normal") return int_br
def _ovs_add_port(self, bridge, device_name, port_id, mac_address, internal=True): attrs = [('external_ids', { 'iface-id': port_id, 'iface-status': 'active', 'attached-mac': mac_address })] if internal: attrs.insert(0, ('type', 'internal')) ovs = ovs_lib.OVSBridge(bridge) ovs.replace_port(device_name, *attrs)
def __init__(self): self.bus = None self.cached_topology = {} self.providers = [] try: bridge_mappings = q_utils.parse_mappings( cfg.CONF.OVS.bridge_mappings) except ValueError as e: raise ValueError(_("Parsing bridge_mappings failed: %s.") % e) self.integ_br = cfg.CONF.OVS.integration_bridge self.bridge_mappings = bridge_mappings self.root_helper = cfg.CONF.AGENT.root_helper self.int_br = ovs_lib.OVSBridge(self.integ_br, self.root_helper)
def unplug(self, device_name, bridge=None, namespace=None, prefix=None): """Unplug the interface.""" if not bridge: bridge = self.conf.ovs_integration_bridge tap_name = self._get_tap_name(device_name, prefix) self.check_bridge_exists(bridge) ovs = ovs_lib.OVSBridge(bridge) try: ovs.delete_port(tap_name) if self.conf.ovs_use_veth: device = ip_lib.IPDevice(device_name, namespace=namespace) device.link.delete() LOG.debug("Unplugged interface '%s'", device_name) except RuntimeError: LOG.error(_LE("Failed unplugging interface '%s'"), device_name)
def test_update_ports_returns_changed_vlan(self): br = ovs_lib.OVSBridge('br-int', 'sudo') mac = "ca:fe:de:ad:be:ef" port = ovs_lib.VifPort(1, 1, 1, mac, br) lvm = ovs_neutron_agent.LocalVLANMapping( 1, '1', None, 1, {port.vif_id: port}) local_vlan_map = {'1': lvm} vif_port_set = set([1, 3]) registered_ports = set([1, 2]) port_tags_dict = {1: []} expected = dict( added=set([3]), current=vif_port_set, removed=set([2]), updated=set([1]) ) with mock.patch.dict(self.agent.local_vlan_map, local_vlan_map): actual = self.mock_scan_ports( vif_port_set, registered_ports, port_tags_dict=port_tags_dict) self.assertEqual(expected, actual)
def _init_arping_port(self, physical_network, interface): bridge = self.bridge_mappings.get(physical_network) if not bridge: LOG.error( _("physical_network: %(physical_network)s " "in not in bridge_mappings: (bridge_mappings)s"), { 'physical_network': physical_network, 'bridge_mappings': self.bridge_mappings }) br = ovs_lib.OVSBridge(bridge, self.root_helper) port_name = ARPING_PORT_PREFIX + physical_network arping_port = br.add_port_for_bus(port_name) interface_port = br.get_port_ofport(interface) actions = "output:%s" % interface_port br.add_flow(priority=101, dl_type="0x0806", in_port=arping_port, actions=actions)
def __init__(self, integ_br, root_helper, polling_interval): '''Constructor. :param integ_br: name of the integration bridge. :param root_helper: utility to use when running shell cmds. :param polling_interval: interval (secs) to check the bridge. ''' self.int_br = ovs_lib.OVSBridge(integ_br, root_helper) self.polling_interval = polling_interval self.cur_ports = [] self.datapath_id = "0x%s" % self.int_br.get_datapath_id() self.agent_state = { 'binary': 'neutron-nec-agent', 'host': config.CONF.host, 'topic': q_const.L2_AGENT_TOPIC, 'configurations': {}, 'agent_type': q_const.AGENT_TYPE_NEC, 'start_flag': True} self.setup_rpc()
def setup_tunnel_br(self, tun_br): '''Setup the tunnel bridge. Creates tunnel bridge, and links it to the integration bridge using a patch port. :param tun_br: the name of the tunnel bridge. ''' self.tun_br = ovs_lib.OVSBridge(tun_br, self.root_helper) self.tun_br.reset_bridge() self.patch_tun_ofport = self.int_br.add_patch_port( cfg.CONF.OVS.int_peer_patch_port, cfg.CONF.OVS.tun_peer_patch_port) self.patch_int_ofport = self.tun_br.add_patch_port( cfg.CONF.OVS.tun_peer_patch_port, cfg.CONF.OVS.int_peer_patch_port) if int(self.patch_tun_ofport) < 0 or int(self.patch_int_ofport) < 0: LOG.error( _("Failed to create OVS patch port. Cannot have " "tunneling enabled on this agent, since this version " "of OVS does not support tunnels or patch ports. " "Agent terminated!")) exit(1) self.tun_br.remove_all_flows() self.tun_br.add_flow(priority=1, actions="drop")
def assert_ovs_bridge_empty(bridge_name): bridge = ovs_lib.OVSBridge(bridge_name) self.assertFalse(bridge.get_port_name_list())
def vxlan_supported(root_helper, from_ip='192.0.2.1', to_ip='192.0.2.2'): name = "vxlantest-" + utils.get_random_string(6) with ovs_lib.OVSBridge(name, root_helper) as br: port = br.add_tunnel_port(from_ip, to_ip, const.TYPE_VXLAN) return port != ovs_lib.INVALID_OFPORT
def setUp(self): super(TunnelTest, self).setUp() cfg.CONF.set_override('rpc_backend', 'neutron.openstack.common.rpc.impl_fake') cfg.CONF.set_override('report_interval', 0, 'AGENT') self.mox = mox.Mox() self.addCleanup(self.mox.UnsetStubs) self.INT_BRIDGE = 'integration_bridge' self.TUN_BRIDGE = 'tunnel_bridge' self.MAP_TUN_BRIDGE = 'tunnel_bridge_mapping' self.NET_MAPPING = {'net1': self.MAP_TUN_BRIDGE} self.INT_OFPORT = 11111 self.TUN_OFPORT = 22222 self.MAP_TUN_OFPORT = 33333 self.VETH_MTU = None self.inta = self.mox.CreateMock(ip_lib.IPDevice) self.intb = self.mox.CreateMock(ip_lib.IPDevice) self.inta.link = self.mox.CreateMock(ip_lib.IpLinkCommand) self.intb.link = self.mox.CreateMock(ip_lib.IpLinkCommand) self.mox.StubOutClassWithMocks(ovs_lib, 'OVSBridge') self.mock_int_bridge = ovs_lib.OVSBridge(self.INT_BRIDGE, 'sudo') self.mock_int_bridge.get_local_port_mac().AndReturn('000000000001') self.mock_int_bridge.delete_port('patch-tun') self.mock_int_bridge.remove_all_flows() self.mock_int_bridge.add_flow(priority=1, actions='normal') self.mock_map_tun_bridge = ovs_lib.OVSBridge(self.MAP_TUN_BRIDGE, 'sudo') self.mock_map_tun_bridge.br_name = self.MAP_TUN_BRIDGE self.mock_map_tun_bridge.remove_all_flows() self.mock_map_tun_bridge.add_flow(priority=1, actions='normal') self.mock_int_bridge.delete_port('int-tunnel_bridge_mapping') self.mock_map_tun_bridge.delete_port('phy-tunnel_bridge_mapping') self.mock_int_bridge.add_port(self.inta) self.mock_map_tun_bridge.add_port(self.intb) self.inta.link.set_up() self.intb.link.set_up() self.mock_int_bridge.add_flow(priority=2, in_port=None, actions='drop') self.mock_map_tun_bridge.add_flow(priority=2, in_port=None, actions='drop') self.mock_tun_bridge = ovs_lib.OVSBridge(self.TUN_BRIDGE, 'sudo') self.mock_tun_bridge.reset_bridge() self.mock_int_bridge.add_patch_port( 'patch-tun', 'patch-int').AndReturn(self.TUN_OFPORT) self.mock_tun_bridge.add_patch_port( 'patch-int', 'patch-tun').AndReturn(self.INT_OFPORT) self.mock_tun_bridge.remove_all_flows() self.mock_tun_bridge.add_flow(priority=1, in_port=self.INT_OFPORT, actions="resubmit(,%s)" % constants.PATCH_LV_TO_TUN) self.mock_tun_bridge.add_flow(priority=0, actions='drop') self.mock_tun_bridge.add_flow(table=constants.PATCH_LV_TO_TUN, dl_dst=UCAST_MAC, actions="resubmit(,%s)" % constants.UCAST_TO_TUN) self.mock_tun_bridge.add_flow(table=constants.PATCH_LV_TO_TUN, dl_dst=BCAST_MAC, actions="resubmit(,%s)" % constants.FLOOD_TO_TUN) for tunnel_type in constants.TUNNEL_NETWORK_TYPES: self.mock_tun_bridge.add_flow( table=constants.TUN_TABLE[tunnel_type], priority=0, actions="drop") learned_flow = ("table=%s," "priority=1," "hard_timeout=300," "NXM_OF_VLAN_TCI[0..11]," "NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]," "load:0->NXM_OF_VLAN_TCI[]," "load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[]," "output:NXM_OF_IN_PORT[]" % constants.UCAST_TO_TUN) self.mock_tun_bridge.add_flow(table=constants.LEARN_FROM_TUN, priority=1, actions="learn(%s),output:%s" % (learned_flow, self.INT_OFPORT)) self.mock_tun_bridge.add_flow(table=constants.UCAST_TO_TUN, priority=0, actions="resubmit(,%s)" % constants.FLOOD_TO_TUN) self.mock_tun_bridge.add_flow(table=constants.FLOOD_TO_TUN, priority=0, actions="drop") self.mox.StubOutWithMock(ip_lib, 'device_exists') ip_lib.device_exists('tunnel_bridge_mapping', 'sudo').AndReturn(True) ip_lib.device_exists('int-tunnel_bridge_mapping', 'sudo').AndReturn(True) self.mox.StubOutWithMock(ip_lib.IpLinkCommand, 'delete') ip_lib.IPDevice('int-tunnel_bridge_mapping').link.delete() self.mox.StubOutClassWithMocks(ip_lib, 'IPWrapper') ip_lib.IPWrapper('sudo').add_veth( 'int-tunnel_bridge_mapping', 'phy-tunnel_bridge_mapping').AndReturn([self.inta, self.intb]) self.mox.StubOutWithMock(ovs_lib, 'get_bridges') ovs_lib.get_bridges('sudo').AndReturn( [self.INT_BRIDGE, self.TUN_BRIDGE, self.MAP_TUN_BRIDGE])
def get_ovs_bridge(self, br_name): return ovs_lib.OVSBridge(br_name)