def configure_ovs(): status_set('maintenance', 'Configuring ovs') if not service_running('openvswitch-switch'): full_restart() add_bridge(INT_BRIDGE) add_bridge(EXT_BRIDGE) ext_port_ctx = None if use_dvr(): ext_port_ctx = ExternalPortContext()() if ext_port_ctx and ext_port_ctx['ext_port']: add_bridge_port(EXT_BRIDGE, ext_port_ctx['ext_port']) portmaps = DataPortContext()() bridgemaps = parse_bridge_mappings(config('bridge-mappings')) for provider, br in bridgemaps.iteritems(): add_bridge(br) if not portmaps: continue for port, _br in portmaps.iteritems(): if _br == br: add_bridge_port(br, port, promisc=True) # Ensure this runs so that mtu is applied to data-port interfaces if # provided. service_restart('os-charm-phy-nic-mtu')
def configure_ovs(): status_set('maintenance', 'Configuring ovs') if not service_running('openvswitch-switch'): full_restart() datapath_type = 'system' add_bridge(INT_BRIDGE, datapath_type) #add_bridge(EXT_BRIDGE, datapath_type) add_bridge_port(INT_BRIDGE, config('aci-uplink-interface'), promisc=True)
def configure_ovs(): status_set('maintenance', 'Configuring ovs') if not service_running('openvswitch-switch'): full_restart() datapath_type = determine_datapath_type() add_bridge(INT_BRIDGE, datapath_type) add_bridge(EXT_BRIDGE, datapath_type) ext_port_ctx = None if use_dvr(): ext_port_ctx = ExternalPortContext()() if ext_port_ctx and ext_port_ctx['ext_port']: add_bridge_port(EXT_BRIDGE, ext_port_ctx['ext_port']) if not use_dpdk(): portmaps = DataPortContext()() bridgemaps = parse_bridge_mappings(config('bridge-mappings')) for br in bridgemaps.values(): add_bridge(br, datapath_type) if not portmaps: continue for port, _br in portmaps.items(): if _br == br: if not is_linuxbridge_interface(port): add_bridge_port(br, port, promisc=True) else: add_ovsbridge_linuxbridge(br, port) else: # NOTE: when in dpdk mode, add based on pci bus order # with type 'dpdk' dpdk_bridgemaps = neutron_ovs_context.resolve_dpdk_ports() device_index = 0 for br in dpdk_bridgemaps.values(): add_bridge(br, datapath_type) dpdk_add_bridge_port(br, 'dpdk{}'.format(device_index), port_type='dpdk') device_index += 1 target = config('ipfix-target') bridges = [INT_BRIDGE, EXT_BRIDGE] bridges.extend(bridgemaps.values()) if target: for bridge in bridges: disable_ipfix(bridge) enable_ipfix(bridge, target) else: # NOTE: removing ipfix setting from a bridge is idempotent and # will pass regardless of the existence of the setting for bridge in bridges: disable_ipfix(bridge) # Ensure this runs so that mtu is applied to data-port interfaces if # provided. # NOTE(ajkavanagh) for pause/resume we don't gate this as it's not a # running service, but rather running a few commands. service_restart('os-charm-phy-nic-mtu')
def test_add_bridge_port_promisc(self, check_call): ovs.add_bridge_port('test', 'eth1', promisc=True) check_call.assert_has_calls([ call(["ovs-vsctl", "--", "--may-exist", "add-port", 'test', 'eth1']), call(['ip', 'link', 'set', 'eth1', 'up']), call(['ip', 'link', 'set', 'eth1', 'promisc', 'on']) ]) self.assertTrue(self.log.call_count == 1)
def configure_ovs(): if config('plugin') == OVS: if not service_running('openvswitch-switch'): full_restart() add_bridge(INT_BRIDGE) add_bridge(EXT_BRIDGE) ext_port = config('ext-port') if ext_port: add_bridge_port(EXT_BRIDGE, ext_port)
def configure_ovs(): if config('plugin') in [OVS, OVS_ODL]: if not service_running('openvswitch-switch'): full_restart() add_bridge(INT_BRIDGE) add_bridge(EXT_BRIDGE) ext_port_ctx = ExternalPortContext()() if ext_port_ctx and ext_port_ctx['ext_port']: add_bridge_port(EXT_BRIDGE, ext_port_ctx['ext_port']) portmaps = DataPortContext()() bridgemaps = parse_bridge_mappings(config('bridge-mappings')) for br in bridgemaps.values(): add_bridge(br) if not portmaps: continue for port, _br in portmaps.items(): if _br == br: if not is_linuxbridge_interface(port): add_bridge_port(br, port, promisc=True) else: add_ovsbridge_linuxbridge(br, port) target = config('ipfix-target') bridges = [INT_BRIDGE, EXT_BRIDGE] bridges.extend(bridgemaps.values()) if target: for bridge in bridges: disable_ipfix(bridge) enable_ipfix(bridge, target) else: # NOTE: removing ipfix setting from a bridge is idempotent and # will pass regardless of the existence of the setting for bridge in bridges: disable_ipfix(bridge) # Ensure this runs so that mtu is applied to data-port interfaces if # provided. service_restart('os-charm-phy-nic-mtu')
def configure_ovs(): status_set('maintenance', 'Configuring ovs') if not service_running('openvswitch-switch'): full_restart() datapath_type = determine_datapath_type() add_bridge(INT_BRIDGE, datapath_type) add_bridge(EXT_BRIDGE, datapath_type) ext_port_ctx = None if use_dvr(): ext_port_ctx = ExternalPortContext()() if ext_port_ctx and ext_port_ctx['ext_port']: add_bridge_port(EXT_BRIDGE, ext_port_ctx['ext_port']) if not use_dpdk(): portmaps = DataPortContext()() bridgemaps = parse_bridge_mappings(config('bridge-mappings')) for br in bridgemaps.itervalues(): add_bridge(br, datapath_type) if not portmaps: continue for port, _br in portmaps.iteritems(): if _br == br: add_bridge_port(br, port, promisc=True) else: # NOTE: when in dpdk mode, add based on pci bus order # with type 'dpdk' dpdk_bridgemaps = neutron_ovs_context.resolve_dpdk_ports() device_index = 0 for br in dpdk_bridgemaps.itervalues(): add_bridge(br, datapath_type) dpdk_add_bridge_port(br, 'dpdk{}'.format(device_index), port_type='dpdk') device_index += 1 # Ensure this runs so that mtu is applied to data-port interfaces if # provided. # NOTE(ajkavanagh) for pause/resume we don't gate this as it's not a # running service, but rather running a few commands. service_restart('os-charm-phy-nic-mtu')
def configure_ovs(): if config('plugin') in [OVS, OVS_ODL]: if not service_running('openvswitch-switch'): full_restart() add_bridge(INT_BRIDGE) add_bridge(EXT_BRIDGE) ext_port_ctx = ExternalPortContext()() if ext_port_ctx and ext_port_ctx['ext_port']: add_bridge_port(EXT_BRIDGE, ext_port_ctx['ext_port']) portmaps = DataPortContext()() # TODO: fudge in external network? bridgemaps = parse_bridge_mappings(config('bridge-mappings')) for provider, br in bridgemaps.iteritems(): add_bridge(br) if not portmaps: continue for port, _br in portmaps.iteritems(): if _br == br: add_bridge_port(br, port, promisc=True)
def configure_ovs(): if config("plugin") in [OVS, OVS_ODL]: if not service_running("openvswitch-switch"): full_restart() add_bridge(INT_BRIDGE) add_bridge(EXT_BRIDGE) ext_port_ctx = ExternalPortContext()() if ext_port_ctx and ext_port_ctx["ext_port"]: add_bridge_port(EXT_BRIDGE, ext_port_ctx["ext_port"]) portmaps = DataPortContext()() bridgemaps = parse_bridge_mappings(config("bridge-mappings")) for provider, br in bridgemaps.iteritems(): add_bridge(br) if not portmaps: continue for port, _br in portmaps.iteritems(): if _br == br: add_bridge_port(br, port, promisc=True) # Ensure this runs so that mtu is applied to data-port interfaces if # provided. service_restart("os-charm-phy-nic-mtu")
def test_add_bridge_port(self): self.patch_object(ovs.subprocess, 'check_call') self.patch_object(ovs, 'log') ovs.add_bridge_port('test', 'eth1') self.check_call.assert_has_calls([ mock.call( ['ovs-vsctl', '--', '--may-exist', 'add-port', 'test', 'eth1']), mock.call(['ip', 'link', 'set', 'eth1', 'up']), mock.call(['ip', 'link', 'set', 'eth1', 'promisc', 'off']) ]) self.assertTrue(self.log.call_count == 1) self.check_call.reset_mock() self.log.reset_mock() ovs.add_bridge_port('test', 'eth1', promisc=True) self.check_call.assert_has_calls([ mock.call( ['ovs-vsctl', '--', '--may-exist', 'add-port', 'test', 'eth1']), mock.call(['ip', 'link', 'set', 'eth1', 'up']), mock.call(['ip', 'link', 'set', 'eth1', 'promisc', 'on']) ]) self.assertTrue(self.log.call_count == 1) self.check_call.reset_mock() ovs.add_bridge_port('test', 'eth1', exclusive=True, linkup=False) self.check_call.assert_has_calls([ mock.call(['ovs-vsctl', '--', 'add-port', 'test', 'eth1']), mock.call(['ip', 'link', 'set', 'eth1', 'promisc', 'off']) ]) self.check_call.reset_mock() self.patch_object(ovs, '_dict_to_vsctl_set') self._dict_to_vsctl_set.return_value = [['--', 'fakeextradata']] ovs.add_bridge_port('test', 'eth1', ifdata={'fakeinput': None}) self._dict_to_vsctl_set.assert_called_once_with({'fakeinput': None}, 'Interface', 'eth1') self.check_call.assert_has_calls([ mock.call([ 'ovs-vsctl', '--', '--may-exist', 'add-port', 'test', 'eth1', '--', 'fakeextradata' ]), mock.call(['ip', 'link', 'set', 'eth1', 'up']), mock.call(['ip', 'link', 'set', 'eth1', 'promisc', 'off']) ])
def configure_bridges(self): """Configure Open vSwitch bridges ports and interfaces.""" if self.check_if_paused() != (None, None): ch_core.hookenv.log( 'Unit is paused, defer Open vSwitch bridge ' 'port interface configuration tasks.', level=ch_core.hookenv.INFO) return bpi = os_context.BridgePortInterfaceMap(bridges_key=self.bridges_key) bond_config = os_context.BondConfig() ch_core.hookenv.log('BridgePortInterfaceMap: "{}"'.format(bpi.items()), level=ch_core.hookenv.DEBUG) # build map of bridges to ovn networks with existing if-mapping on host # and at the same time build ovn-bridge-mappings string ovn_br_map_str = '' ovnbridges = collections.defaultdict(list) config_obm = self.config['ovn-bridge-mappings'] or '' for pair in sorted(config_obm.split()): network, bridge = pair.split(':', 1) if bridge in bpi: ovnbridges[bridge].append(network) if ovn_br_map_str: ovn_br_map_str += ',' ovn_br_map_str += '{}:{}'.format(network, bridge) bridges = ch_ovsdb.SimpleOVSDB('ovs-vsctl').bridge ports = ch_ovsdb.SimpleOVSDB('ovs-vsctl').port for bridge in bridges.find('external_ids:charm-ovn-chassis=managed'): # remove bridges and ports that are managed by us and no longer in # config if bridge['name'] not in bpi and bridge['name'] != 'br-int': ch_core.hookenv.log( 'removing bridge "{}" as it is no longer' 'present in configuration for this unit.'.format( bridge['name']), level=ch_core.hookenv.DEBUG) ch_ovs.del_bridge(bridge['name']) else: for port in ports.find( 'external_ids:charm-ovn-chassis={}'.format( bridge['name'])): if port['name'] not in bpi[bridge['name']]: ch_core.hookenv.log( 'removing port "{}" from bridge ' '"{}" as it is no longer present ' 'in configuration for this unit.'.format( port['name'], bridge['name']), level=ch_core.hookenv.DEBUG) ch_ovs.del_bridge_port(bridge['name'], port['name']) brdata = { 'external-ids': { 'charm-ovn-chassis': 'managed' }, 'protocols': 'OpenFlow13,OpenFlow15', } if self.options.enable_dpdk: brdata.update({'datapath-type': 'netdev'}) else: brdata.update({'datapath-type': 'system'}) # we always update the integration bridge to make sure it has settings # apropriate for the current charm configuration ch_ovs.add_bridge( 'br-int', brdata={ **brdata, **{ # for the integration bridge we want the datapath to await # controller action before adding any flows. This is to avoid # switching packets between isolated logical networks before # `ovn-controller` starts up. 'fail-mode': 'secure', # Suppress in-band control flows for the integration bridge, # refer to ovn-architecture(7) for more details. 'other-config': { 'disable-in-band': 'true' }, }, }) for br in bpi: if br not in ovnbridges: continue ch_ovs.add_bridge( br, brdata={ **brdata, # for bridges used for external connectivity we want the # datapath to act like an ordinary MAC-learning switch. **{ 'fail-mode': 'standalone' }, }) for port in bpi[br]: ifdatamap = bpi.get_ifdatamap(br, port) ifdatamap = { port: { **ifdata, **{ 'external-ids': { 'charm-ovn-chassis': br } }, } for port, ifdata in ifdatamap.items() } if len(ifdatamap) > 1: ch_ovs.add_bridge_bond(br, port, list(ifdatamap.keys()), bond_config.get_ovs_portdata(port), ifdatamap) else: ch_ovs.add_bridge_port( br, port, ifdata=ifdatamap.get(port, {}), linkup=not self.options.enable_dpdk, promisc=None, portdata={'external-ids': { 'charm-ovn-chassis': br }}) opvs = ch_ovsdb.SimpleOVSDB('ovs-vsctl').open_vswitch if ovn_br_map_str: opvs.set('.', 'external_ids:ovn-bridge-mappings', ovn_br_map_str) # NOTE(fnordahl): Workaround for LP: #1848757 opvs.set('.', 'external_ids:ovn-cms-options', 'enable-chassis-as-gw') else: opvs.remove('.', 'external_ids', 'ovn-bridge-mappings') # NOTE(fnordahl): Workaround for LP: #1848757 opvs.remove('.', 'external_ids', 'ovn-cms-options')
def configure_ovs(): """Configure the OVS plugin. This function uses the config.yaml parameters ext-port, data-port and bridge-mappings to configure the bridges and ports on the ovs on the unit. Note that the ext-port is deprecated and data-port/bridge-mappings are preferred. Thus, if data-port is set, then ext-port is ignored (and if set, then it is removed from the set of bridges unless it is defined in bridge-mappings/data-port). A warning is issued, if both data-port and ext-port are set. """ status_set('maintenance', 'Configuring ovs') if not service_running('openvswitch-switch'): full_restart() # all bridges use the same datapath_type brdata = { 'datapath-type': determine_datapath_type(), } brdata.update(generate_external_ids()) add_bridge(INT_BRIDGE, brdata=brdata) add_bridge(EXT_BRIDGE, brdata=brdata) # If data-port is defined in the config, we can ignore ext-port value # and log an error to the unit's log if config('data-port') and config('ext-port'): log( "Both ext-port and data-port are set. ext-port is deprecated" " and is not used when data-port is set.", level=ERROR) ext_port_ctx = None if use_dvr(): ext_port_ctx = ExternalPortContext()() # Set ext-port only if data-port isn't defined. if not config('data-port') and ext_port_ctx and ext_port_ctx['ext_port']: add_bridge_port(EXT_BRIDGE, ext_port_ctx['ext_port'], ifdata=generate_external_ids(EXT_BRIDGE), portdata=generate_external_ids(EXT_BRIDGE)) modern_ovs = ovs_has_late_dpdk_init() bridgemaps = None portmaps = None if not use_dpdk(): # NOTE(jamespage): # Its possible to support both hardware offloaded 'direct' ports # and default 'openvswitch' ports on the same hypervisor, so # configure bridge mappings in addition to any hardware offload # enablement. portmaps = DataPortContext()() bridgemaps = parse_bridge_mappings(config('bridge-mappings')) for br in bridgemaps.values(): add_bridge(br, brdata=brdata) if not portmaps: continue for port, _br in portmaps.items(): if _br == br: if not is_linuxbridge_interface(port): add_bridge_port(br, port, promisc=True, ifdata=generate_external_ids(br), portdata=generate_external_ids(br)) else: log('{} is a Linux bridge: using Linux bridges in the ' 'data-port config is deprecated for removal after ' '21.10 release of OpenStack charms.'.format(port), level=WARNING) add_ovsbridge_linuxbridge( br, port, ifdata=generate_external_ids(br), portdata=generate_external_ids(br)) # NOTE(jamespage): # hw-offload and dpdk are mutually exclusive so log and error # and skip any subsequent DPDK configuration if use_dpdk() and use_hw_offload(): log( 'DPDK and Hardware offload are mutually exclusive, ' 'please disable enable-dpdk or enable-hardware-offload', level=ERROR) elif use_dpdk(): log('Configuring bridges with DPDK', level=DEBUG) # TODO(sahid): We should also take into account the # "physical-network-mtus" in case different MTUs are # configured based on physical networks. global_mtu = ( neutron_ovs_context.NeutronAPIContext()()['global_physnet_mtu']) dpdk_context = OVSDPDKDeviceContext() devices = dpdk_context.devices() portmaps = parse_data_port_mappings(config('data-port')) bridgemaps = parse_bridge_mappings(config('bridge-mappings')) bridge_port_interface_map = BridgePortInterfaceMap() bond_config = BondConfig() for br, port_iface_map in bridge_port_interface_map.items(): log('Adding DPDK bridge: {}:{}'.format(br, brdata), level=DEBUG) add_bridge(br, brdata=brdata) if modern_ovs: for port in port_iface_map.keys(): ifdatamap = bridge_port_interface_map.get_ifdatamap( br, port) # set external-ids for all interfaces for iface in ifdatamap: ifdatamap[iface].update(generate_external_ids(br)) # NOTE: DPDK bonds are referenced by name and can be found # in the data-port config, regular DPDK ports are # referenced by MAC addresses and their names should # never be found in data-port if port in portmaps.keys(): portdata = bond_config.get_ovs_portdata(port) portdata.update(generate_external_ids(br)) log('Adding DPDK bond: {}({}) to bridge: {}'.format( port, list(ifdatamap.keys()), br), level=DEBUG) add_bridge_bond(br, port, list(ifdatamap.keys()), portdata=portdata, ifdatamap=ifdatamap) else: log('Adding DPDK port: {} to bridge: {}'.format( port, br), level=DEBUG) ifdata = ifdatamap[port] add_bridge_port(br, port, ifdata=ifdata, portdata=generate_external_ids(br), linkup=False, promisc=None) if not modern_ovs: # port enumeration in legacy OVS-DPDK must follow alphabetic order # of the PCI addresses dev_idx = 0 for pci, mac in sorted(devices.items()): # if mac.entity is a bridge, then the port can be added # directly, otherwise it is a bond (supported only in # modern_ovs) or misconfiguration if mac.entity in bridgemaps.values(): ifdata = {'type': 'dpdk', 'mtu-request': global_mtu} ifdata.update(generate_external_ids(mac.entity)) ifname = 'dpdk{}'.format(dev_idx) log('Adding DPDK port {}:{} to bridge {}'.format( ifname, ifdata, mac.entity), level=DEBUG) add_bridge_port(mac.entity, ifname, ifdata=ifdata, portdata=generate_external_ids(mac.entity), linkup=False, promisc=None) else: log('DPDK device {} skipped, {} is not a bridge'.format( pci, mac.entity), level=WARNING) dev_idx += 1 target = config('ipfix-target') bridges = [INT_BRIDGE, EXT_BRIDGE] if bridgemaps: bridges.extend(bridgemaps.values()) elif portmaps: bridges.extend([bridge_mac.entity for bridge_mac in portmaps.values()]) if target: for bridge in bridges: disable_ipfix(bridge) enable_ipfix(bridge, target) else: # NOTE: removing ipfix setting from a bridge is idempotent and # will pass regardless of the existence of the setting for bridge in bridges: disable_ipfix(bridge) # Ensure this runs so that mtu is applied to data-port interfaces if # provided. # NOTE(ajkavanagh) for pause/resume we don't gate this as it's not a # running service, but rather running a few commands. if not init_is_systemd(): service_restart('os-charm-phy-nic-mtu')
def configure_ovs(): """Configure the OVS plugin. This function uses the config.yaml parameters ext-port, data-port and bridge-mappings to configure the bridges and ports on the ovs on the unit. Note that the ext-port is deprecated and data-port/bridge-mappings are preferred. Thus, if data-port is set, then ext-port is ignored (and if set, then it is removed from the set of bridges unless it is defined in bridge-mappings/data-port). A warning is issued, if both data-port and ext-port are set. """ if config('plugin') in [OVS, OVS_ODL]: if not service_running('openvswitch-switch'): full_restart() # Get existing set of bridges and ports current_bridges_and_ports = get_bridges_and_ports_map() log("configure OVS: Current bridges and ports map: {}".format( ", ".join("{}: {}".format(b, ",".join(v)) for b, v in current_bridges_and_ports.items()))) add_bridge(INT_BRIDGE, brdata=_ovs_additional_data()) add_bridge(EXT_BRIDGE, brdata=_ovs_additional_data()) ext_port_ctx = ExternalPortContext()() portmaps = DataPortContext()() bridgemaps = parse_bridge_mappings(config('bridge-mappings')) # if we have portmaps, then we ignore its value and log an # error/warning to the unit's log. if config('data-port') and config('ext-port'): log( "Both ext-port and data-port are set. ext-port is deprecated" " and is not used when data-port is set", level=ERROR) # only use ext-port if data-port is not set if not portmaps and ext_port_ctx and ext_port_ctx['ext_port']: _port = ext_port_ctx['ext_port'] add_bridge_port(EXT_BRIDGE, _port, ifdata=_ovs_additional_data(EXT_BRIDGE), portdata=_ovs_additional_data(EXT_BRIDGE)) log("DEPRECATION: using ext-port to set the port {} on the " "EXT_BRIDGE ({}) is deprecated. Please use data-port instead." .format(_port, EXT_BRIDGE), level=WARNING) for br in bridgemaps.values(): add_bridge(br, brdata=_ovs_additional_data()) if not portmaps: continue for port, _br in portmaps.items(): if _br == br: if not is_linuxbridge_interface(port): add_bridge_port(br, port, promisc=True, ifdata=_ovs_additional_data(br), portdata=_ovs_additional_data(br)) else: # NOTE(lourot): this will raise on focal+ and/or if the # system has no `ifup`. See lp:1877594 add_ovsbridge_linuxbridge( br, port, ifdata=_ovs_additional_data(br), portdata=_ovs_additional_data(br)) target = config('ipfix-target') bridges = [INT_BRIDGE, EXT_BRIDGE] bridges.extend(bridgemaps.values()) if target: for bridge in bridges: disable_ipfix(bridge) enable_ipfix(bridge, target) else: # NOTE: removing ipfix setting from a bridge is idempotent and # will pass regardless of the existence of the setting for bridge in bridges: disable_ipfix(bridge) new_bridges_and_ports = get_bridges_and_ports_map() log("configure OVS: Final bridges and ports map: {}".format(", ".join( "{}: {}".format(b, ",".join(v)) for b, v in new_bridges_and_ports.items())), level=DEBUG) # Ensure this runs so that mtu is applied to data-port interfaces if # provided. service_restart('os-charm-phy-nic-mtu')
def configure_ovs(): status_set('maintenance', 'Configuring ovs') if not service_running('openvswitch-switch'): full_restart() datapath_type = determine_datapath_type() add_bridge(INT_BRIDGE, datapath_type) add_bridge(EXT_BRIDGE, datapath_type) ext_port_ctx = None if use_dvr(): ext_port_ctx = ExternalPortContext()() if ext_port_ctx and ext_port_ctx['ext_port']: add_bridge_port(EXT_BRIDGE, ext_port_ctx['ext_port']) modern_ovs = ovs_has_late_dpdk_init() bridgemaps = None if not use_dpdk(): portmaps = DataPortContext()() bridgemaps = parse_bridge_mappings(config('bridge-mappings')) for br in bridgemaps.values(): add_bridge(br, datapath_type) if not portmaps: continue for port, _br in portmaps.items(): if _br == br: if not is_linuxbridge_interface(port): add_bridge_port(br, port, promisc=True) else: add_ovsbridge_linuxbridge(br, port) else: # NOTE: when in dpdk mode, add based on pci bus order # with type 'dpdk' bridgemaps = neutron_ovs_context.resolve_dpdk_bridges() device_index = 0 for pci_address, br in bridgemaps.items(): add_bridge(br, datapath_type) if modern_ovs: portname = 'dpdk-{}'.format( hashlib.sha1(pci_address.encode('UTF-8')).hexdigest()[:7] ) else: portname = 'dpdk{}'.format(device_index) dpdk_add_bridge_port(br, portname, pci_address) device_index += 1 if modern_ovs: bondmaps = neutron_ovs_context.resolve_dpdk_bonds() bridge_bond_map = DPDKBridgeBondMap() portmap = parse_data_port_mappings(config('data-port')) for pci_address, bond in bondmaps.items(): if bond in portmap: add_bridge(portmap[bond], datapath_type) portname = 'dpdk-{}'.format( hashlib.sha1(pci_address.encode('UTF-8')) .hexdigest()[:7] ) bridge_bond_map.add_port(portmap[bond], bond, portname, pci_address) bond_configs = DPDKBondsConfig() for br, bonds in bridge_bond_map.items(): for bond, port_map in bonds.items(): dpdk_add_bridge_bond(br, bond, port_map) dpdk_set_bond_config( bond, bond_configs.get_bond_config(bond) ) target = config('ipfix-target') bridges = [INT_BRIDGE, EXT_BRIDGE] if bridgemaps: bridges.extend(bridgemaps.values()) if target: for bridge in bridges: disable_ipfix(bridge) enable_ipfix(bridge, target) else: # NOTE: removing ipfix setting from a bridge is idempotent and # will pass regardless of the existence of the setting for bridge in bridges: disable_ipfix(bridge) # Ensure this runs so that mtu is applied to data-port interfaces if # provided. # NOTE(ajkavanagh) for pause/resume we don't gate this as it's not a # running service, but rather running a few commands. service_restart('os-charm-phy-nic-mtu')
def configure_ovs(): status_set('maintenance', 'Configuring ovs') if not service_running('openvswitch-switch'): full_restart() datapath_type = determine_datapath_type() add_bridge(INT_BRIDGE, datapath_type) add_bridge(EXT_BRIDGE, datapath_type) ext_port_ctx = None if use_dvr(): ext_port_ctx = ExternalPortContext()() if ext_port_ctx and ext_port_ctx['ext_port']: add_bridge_port(EXT_BRIDGE, ext_port_ctx['ext_port']) modern_ovs = ovs_has_late_dpdk_init() bridgemaps = None if not use_dpdk(): # NOTE(jamespage): # Its possible to support both hardware offloaded 'direct' ports # and default 'openvswitch' ports on the same hypervisor, so # configure bridge mappings in addition to any hardware offload # enablement. portmaps = DataPortContext()() bridgemaps = parse_bridge_mappings(config('bridge-mappings')) for br in bridgemaps.values(): add_bridge(br, datapath_type) if not portmaps: continue for port, _br in portmaps.items(): if _br == br: if not is_linuxbridge_interface(port): add_bridge_port(br, port, promisc=True) else: add_ovsbridge_linuxbridge(br, port) # NOTE(jamespage): # hw-offload and dpdk are mutually exclusive so log and error # and skip any subsequent DPDK configuration if use_dpdk() and use_hw_offload(): log( 'DPDK and Hardware offload are mutually exclusive, ' 'please disable enable-dpdk or enable-hardware-offload', level=ERROR) elif use_dpdk(): log('Configuring bridges with DPDK', level=DEBUG) global_mtu = ( neutron_ovs_context.NeutronAPIContext()()['global_physnet_mtu']) # NOTE: when in dpdk mode, add based on pci bus order # with type 'dpdk' bridgemaps = neutron_ovs_context.resolve_dpdk_bridges() log('bridgemaps: {}'.format(bridgemaps), level=DEBUG) device_index = 0 for pci_address, br in bridgemaps.items(): log('Adding DPDK bridge: {}:{}'.format(br, datapath_type), level=DEBUG) add_bridge(br, datapath_type) if modern_ovs: portname = 'dpdk-{}'.format( hashlib.sha1(pci_address.encode('UTF-8')).hexdigest()[:7]) else: portname = 'dpdk{}'.format(device_index) log('Adding DPDK port: {}:{}:{}'.format(br, portname, pci_address), level=DEBUG) dpdk_add_bridge_port(br, portname, pci_address) # TODO(sahid): We should also take into account the # "physical-network-mtus" in case different MTUs are # configured based on physical networks. dpdk_set_mtu_request(portname, global_mtu) device_index += 1 if modern_ovs: log('Configuring bridges with modern_ovs/DPDK', level=DEBUG) bondmaps = neutron_ovs_context.resolve_dpdk_bonds() log('bondmaps: {}'.format(bondmaps), level=DEBUG) bridge_bond_map = DPDKBridgeBondMap() portmap = parse_data_port_mappings(config('data-port')) log('portmap: {}'.format(portmap), level=DEBUG) for pci_address, bond in bondmaps.items(): if bond in portmap: log('Adding DPDK bridge: {}:{}'.format( portmap[bond], datapath_type), level=DEBUG) add_bridge(portmap[bond], datapath_type) portname = 'dpdk-{}'.format( hashlib.sha1( pci_address.encode('UTF-8')).hexdigest()[:7]) bridge_bond_map.add_port(portmap[bond], bond, portname, pci_address) log('bridge_bond_map: {}'.format(bridge_bond_map), level=DEBUG) bond_configs = DPDKBondsConfig() for br, bonds in bridge_bond_map.items(): for bond, port_map in bonds.items(): log('Adding DPDK bond: {}:{}:{}'.format( br, bond, port_map), level=DEBUG) dpdk_add_bridge_bond(br, bond, port_map) dpdk_set_interfaces_mtu(global_mtu, port_map.keys()) log('Configuring DPDK bond: {}:{}'.format( bond, bond_configs.get_bond_config(bond)), level=DEBUG) dpdk_set_bond_config(bond, bond_configs.get_bond_config(bond)) target = config('ipfix-target') bridges = [INT_BRIDGE, EXT_BRIDGE] if bridgemaps: bridges.extend(bridgemaps.values()) if target: for bridge in bridges: disable_ipfix(bridge) enable_ipfix(bridge, target) else: # NOTE: removing ipfix setting from a bridge is idempotent and # will pass regardless of the existence of the setting for bridge in bridges: disable_ipfix(bridge) # Ensure this runs so that mtu is applied to data-port interfaces if # provided. # NOTE(ajkavanagh) for pause/resume we don't gate this as it's not a # running service, but rather running a few commands. if not init_is_systemd(): service_restart('os-charm-phy-nic-mtu')