Ejemplo n.º 1
0
    def _apply(self):
        """Apply the current in-memory set of iptables rules.

        This will blow away any rules left over from previous runs of the
        same component of Nova, and replace them with our current set of
        rules. This happens atomically, thanks to iptables-restore.

        """
        s = [('iptables', self.ipv4)]
        if self.use_ipv6:
            s += [('ip6tables', self.ipv6)]

        for cmd, tables in s:
            all_tables, _err = processutils.execute('%s-save' % (cmd,),
                                                    '-c', attempts=5,
                                                    run_as_root=True)
            all_lines = all_tables.split('\n')
            for table_name, table in six.iteritems(tables):
                start, end = self._find_table(all_lines, table_name)
                all_lines[start:end] = self._modify_rules(
                        all_lines[start:end], table, table_name)
                table.dirty = False
            processutils.execute('%s-restore' % (cmd,), '-c',
                                 process_input='\n'.join(all_lines),
                                 attempts=5, run_as_root=True)
Ejemplo n.º 2
0
    def _apply(self):
        """Apply the current in-memory set of iptables rules.

        This will blow away any rules left over from previous runs of the
        same component of Nova, and replace them with our current set of
        rules. This happens atomically, thanks to iptables-restore.

        """
        s = [('iptables', self.ipv4)]
        if self.use_ipv6:
            s += [('ip6tables', self.ipv6)]

        for cmd, tables in s:
            all_tables, _err = processutils.execute('%s-save' % (cmd, ),
                                                    '-c',
                                                    attempts=5,
                                                    run_as_root=True)
            all_lines = all_tables.split('\n')
            for table_name, table in six.iteritems(tables):
                start, end = self._find_table(all_lines, table_name)
                all_lines[start:end] = self._modify_rules(
                    all_lines[start:end], table, table_name)
                table.dirty = False
            processutils.execute('%s-restore' % (cmd, ),
                                 '-c',
                                 process_input='\n'.join(all_lines),
                                 attempts=5,
                                 run_as_root=True)
Ejemplo n.º 3
0
def delete_net_dev(dev):
    """Delete a network device only if it exists."""
    if device_exists(dev):
        try:
            processutils.execute("ip", "link", "delete", dev, check_exit_code=[0, 2, 254], run_as_root=True)
            LOG.debug("Net device removed: '%s'", dev)
        except processutils.ProcessExecutionError:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Failed removing net device: '%s'"), dev)
Ejemplo n.º 4
0
    def plug(self, instance, vif):
        """Plug into MidoNet's network port

        Bind the vif to a MidoNet virtual port.
        """
        dev = vif.devname
        port_id = vif.id
        linux_net.create_tap_dev(dev)
        processutils.execute('mm-ctl', '--bind-port', port_id, dev,
                             run_as_root=True)
Ejemplo n.º 5
0
    def unplug(self, vif):
        """Unplug from MidoNet network port

        Unbind the vif from a MidoNet virtual port.
        """
        dev = vif.devname
        port_id = vif.id
        processutils.execute('mm-ctl', '--unbind-port', port_id,
                             run_as_root=True)
        linux_net.delete_net_dev(dev)
Ejemplo n.º 6
0
def _ovs_vsctl(args, timeout=timeout):
    full_args = ["ovs-vsctl", "--timeout=%s" % timeout] + args
    try:
        return processutils.execute(*full_args, run_as_root=True)
    except Exception as e:
        LOG.error(_LE("Unable to execute %(cmd)s. Exception: %(exception)s"), {"cmd": full_args, "exception": e})
        raise exception.AgentError(method=full_args)
Ejemplo n.º 7
0
def ensure_vlan(vlan_num, bridge_interface, mac_address=None, mtu=None):
    """Create a vlan unless it already exists."""
    interface = "vlan%s" % vlan_num
    if not device_exists(interface):
        LOG.debug("Starting VLAN interface %s", interface)
        processutils.execute(
            "ip",
            "link",
            "add",
            "link",
            bridge_interface,
            "name",
            interface,
            "type",
            "vlan",
            "id",
            vlan_num,
            check_exit_code=[0, 2, 254],
            run_as_root=True,
        )
        # (danwent) the bridge will inherit this address, so we want to
        # make sure it is the value set from the NetworkManager
        if mac_address:
            processutils.execute(
                "ip", "link", "set", interface, "address", mac_address, check_exit_code=[0, 2, 254], run_as_root=True
            )
        processutils.execute("ip", "link", "set", interface, "up", check_exit_code=[0, 2, 254], run_as_root=True)
    # NOTE(vish): set mtu every time to ensure that changes to mtu get
    #             propogated
    _set_device_mtu(interface, mtu)
    return interface
Ejemplo n.º 8
0
def create_tap_dev(dev, mac_address=None):
    if not device_exists(dev):
        try:
            # First, try with 'ip'
            processutils.execute(
                "ip", "tuntap", "add", dev, "mode", "tap", check_exit_code=[0, 2, 254], run_as_root=True
            )
        except processutils.ProcessExecutionError:
            # Second option: tunctl
            processutils.execute("tunctl", "-b", "-t", dev, run_as_root=True)
        if mac_address:
            processutils.execute(
                "ip", "link", "set", dev, "address", mac_address, check_exit_code=[0, 2, 254], run_as_root=True
            )
        processutils.execute("ip", "link", "set", dev, "up", check_exit_code=[0, 2, 254], run_as_root=True)
Ejemplo n.º 9
0
def set_vf_interface_vlan(pci_addr, mac_addr, vlan=0):
    pf_ifname = pci.get_ifname_by_pci_address(pci_addr, pf_interface=True)
    vf_ifname = pci.get_ifname_by_pci_address(pci_addr)
    vf_num = pci.get_vf_num_by_pci_address(pci_addr)

    # Set the VF's mac address and vlan
    exit_code = [0, 2, 254]
    port_state = "up" if vlan > 0 else "down"
    processutils.execute(
        "ip",
        "link",
        "set",
        pf_ifname,
        "vf",
        vf_num,
        "mac",
        mac_addr,
        "vlan",
        vlan,
        check_exit_code=exit_code,
        run_as_root=True,
    )
    # Bring up/down the VF's interface
    processutils.execute("ip", "link", "set", vf_ifname, port_state, check_exit_code=exit_code, run_as_root=True)
Ejemplo n.º 10
0
def create_veth_pair(dev1_name, dev2_name, mtu):
    """Create a pair of veth devices with the specified names,
    deleting any previous devices with those names.
    """
    for dev in [dev1_name, dev2_name]:
        delete_net_dev(dev)

    processutils.execute("ip", "link", "add", dev1_name, "type", "veth", "peer", "name", dev2_name, run_as_root=True)
    for dev in [dev1_name, dev2_name]:
        processutils.execute("ip", "link", "set", dev, "up", run_as_root=True)
        processutils.execute("ip", "link", "set", dev, "promisc", "on")
        _set_device_mtu(dev, mtu)
Ejemplo n.º 11
0
    def unplug(self, vif):
        """UnPlug using hybrid strategy

        Unhook port from OVS, unhook port from bridge, delete
        bridge, and delete both veth devices.
        """
        br_name = vif.br_name
        v1_name, v2_name = vif.veth_pair_names

        if linux_net.device_exists(br_name):
            processutils.execute('brctl', 'delif', br_name, v1_name,
                                 run_as_root=True)
            processutils.execute('ip', 'link', 'set', br_name, 'down',
                                 run_as_root=True)
            processutils.execute('brctl', 'delbr', br_name,
                                 run_as_root=True)

        linux_net.delete_ovs_vif_port(vif.bridge_name, v2_name)
Ejemplo n.º 12
0
def create_ivs_vif_port(dev, iface_id, mac, instance_id):
    processutils.execute("ivs-ctl", "add-port", dev, run_as_root=True)
Ejemplo n.º 13
0
def delete_ivs_vif_port(dev):
    processutils.execute("ivs-ctl", "del-port", dev, run_as_root=True)
    processutils.execute("ip", "link", "delete", dev, run_as_root=True)
Ejemplo n.º 14
0
    def plug(self, instance, vif):
        """Plug using hybrid strategy

        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 OVS port. Then boot the
        VIF on the linux bridge using standard libvirt mechanisms.
        """
        iface_id = vif.ovs_interfaceid
        br_name = vif.br_name
        v1_name, v2_name = vif.veth_pair_names

        if not linux_net.device_exists(br_name):
            processutils.execute('brctl', 'addbr', br_name,
                                 run_as_root=True)
            processutils.execute('brctl', 'setfd', br_name, 0,
                                 run_as_root=True)
            processutils.execute('brctl', 'stp', br_name, 'off',
                                 run_as_root=True)
            syspath = '/sys/class/net/%s/bridge/multicast_snooping'
            syspath = syspath % br_name
            processutils.execute('tee', syspath, process_input='0',
                                 check_exit_code=[0, 1],
                                 run_as_root=True)

        if not linux_net.device_exists(v2_name):
            linux_net.create_veth_pair(v1_name, v2_name, self.network_device_mtu)
            processutils.execute('ip', 'link', 'set', br_name, 'up',
                                 run_as_root=True)
            processutils.execute('brctl', 'addif', br_name, v1_name,
                                 run_as_root=True)
            linux_net.create_ovs_vif_port(vif.bridge_name,
                                          v2_name, iface_id,
                                          vif.address, instance.uuid)
Ejemplo n.º 15
0
def _set_device_mtu(dev, mtu):
    """Set the device MTU."""
    processutils.execute("ip", "link", "set", dev, "mtu", mtu, check_exit_code=[0, 2, 254])
Ejemplo n.º 16
0
def delete_bridge_dev(dev):
    """Delete a network bridge."""
    if device_exists(dev):
        processutils.execute("ip", "link", "set", dev, "down", run_as_root=True)
        processutils.execute("brctl", "delbr", dev, run_as_root=True)
Ejemplo n.º 17
0
def ensure_bridge(bridge, interface, net_attrs=None, gateway=True, filtering=True):
    """Create a bridge unless it already exists.

    :param interface: the interface to create the bridge on.
    :param net_attrs: dictionary with  attributes used to create bridge.
    :param gateway: whether or not the bridge is a gateway.
    :param filtering: whether or not to create filters on the bridge.

    If net_attrs is set, it will add the net_attrs['gateway'] to the bridge
    using net_attrs['broadcast'] and net_attrs['cidr'].  It will also add
    the ip_v6 address specified in net_attrs['cidr_v6'] if use_ipv6 is set.

    The code will attempt to move any ips that already exist on the
    interface onto the bridge and reset the default gateway if necessary.

    """
    if not device_exists(bridge):
        LOG.debug("Starting Bridge %s", bridge)
        processutils.execute("brctl", "addbr", bridge, run_as_root=True)
        processutils.execute("brctl", "setfd", bridge, 0, run_as_root=True)
        # processutils.execute('brctl setageing %s 10' % bridge, run_as_root=True)
        processutils.execute("brctl", "stp", bridge, "off", run_as_root=True)
        # (danwent) bridge device MAC address can't be set directly.
        # instead it inherits the MAC address of the first device on the
        # bridge, which will either be the vlan interface, or a
        # physical NIC.
        processutils.execute("ip", "link", "set", bridge, "up", run_as_root=True)

    if interface:
        LOG.debug("Adding interface %(interface)s to bridge %(bridge)s", {"interface": interface, "bridge": bridge})
        out, err = processutils.execute("brctl", "addif", bridge, interface, check_exit_code=False, run_as_root=True)
        if err and err != "device %s is already a member of a bridge; " "can't enslave it to bridge %s.\n" % (
            interface,
            bridge,
        ):
            msg = _("Failed to add interface: %s") % err
            raise exception.NovaException(msg)

        out, err = processutils.execute("ip", "link", "set", interface, "up", check_exit_code=False, run_as_root=True)

        # NOTE(vish): This will break if there is already an ip on the
        #             interface, so we move any ips to the bridge
        # NOTE(danms): We also need to copy routes to the bridge so as
        #              not to break existing connectivity on the interface
        old_routes = []
        out, err = processutils.execute("ip", "route", "show", "dev", interface)
        for line in out.split("\n"):
            fields = line.split()
            if fields and "via" in fields:
                old_routes.append(fields)
                processutils.execute("ip", "route", "del", *fields, run_as_root=True)
        out, err = processutils.execute("ip", "addr", "show", "dev", interface, "scope", "global")
        for line in out.split("\n"):
            fields = line.split()
            if fields and fields[0] == "inet":
                if fields[-2] in ("secondary", "dynamic"):
                    params = fields[1:-2]
                else:
                    params = fields[1:-1]
                processutils.execute(
                    *_ip_bridge_cmd("del", params, fields[-1]), check_exit_code=[0, 2, 254], run_as_root=True
                )
                processutils.execute(
                    *_ip_bridge_cmd("add", params, bridge), check_exit_code=[0, 2, 254], run_as_root=True
                )
        for fields in old_routes:
            processutils.execute("ip", "route", "add", *fields, run_as_root=True)

    if filtering:
        # Don't forward traffic unless we were told to be a gateway
        ipv4_filter = iptables_manager.ipv4["filter"]
        if gateway:
            for rule in iptables_manager.get_gateway_rules(bridge):
                ipv4_filter.add_rule(*rule)
        else:
            ipv4_filter.add_rule(
                "FORWARD", ("--in-interface %s -j %s" % (bridge, iptables_manager.iptables_drop_action))
            )
            ipv4_filter.add_rule(
                "FORWARD", ("--out-interface %s -j %s" % (bridge, iptables_manager.iptables_drop_action))
            )