Example #1
0
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')
Example #2
0
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)
Example #4
0
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 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)
Example #6
0
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')
Example #7
0
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()()
        # 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():
    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')
Example #11
0
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")
Example #12
0
 def test_full_restart_upstart(self, service, exists):
     exists.return_value = True
     ovs.full_restart()
     service.assert_called_with('start', 'openvswitch-force-reload-kmod')
Example #13
0
 def test_full_restart(self, service, exists):
     exists.return_value = False
     ovs.full_restart()
     service.assert_called_with('force-reload-kmod', 'openvswitch-switch')
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')
Example #17
0
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')
Example #18
0
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')