Esempio n. 1
0
File: Device.py Progetto: jbenc/lnst
    def _update_netlink(self, nl_msg):
        if self.if_index != nl_msg['index']:
            msg = "if_index of netlink message (%s) doesn't match "\
                  "the device's (%s)." % (nl_msg['index'], self.if_index)
            raise DeviceError(msg)

        if nl_msg['header']['type'] == RTM_NEWLINK:
            if self.if_index != nl_msg['index']:
                raise DeviceError("RTM_NEWLINK message passed to incorrect "\
                                  "Device object.")

            self._nl_msg = nl_msg
        elif nl_msg['header']['type'] == RTM_NEWADDR:
            if self.if_index != nl_msg['index']:
                raise DeviceError("RTM_NEWADDR message passed to incorrect "\
                                  "Device object.")

            addr = IpAddress(nl_msg.get_attr('IFA_ADDRESS'))
            addr.prefixlen = nl_msg["prefixlen"]

            if addr not in self._ip_addrs:
                self._ip_addrs.append(addr)
        elif nl_msg['header']['type'] == RTM_DELADDR:
            if self.if_index != nl_msg['index']:
                raise DeviceError("RTM_DELADDR message passed to incorrect "\
                                  "Device object.")

            addr = IpAddress(nl_msg.get_attr('IFA_ADDRESS'))
            addr.prefixlen = nl_msg["prefixlen"]

            if addr in self._ip_addrs:
                self._ip_addrs.remove(addr)
Esempio n. 2
0
    def __init__(self, ifmanager, *args, **kwargs):
        if "external" not in kwargs:
            self._mandatory_opts = ["vxlan_id"]
            if "group" in kwargs and "remote" in kwargs:
                raise DeviceError(
                    "group and remote cannot both be specified for vxlan")

            if "group" not in kwargs and "remote" not in kwargs:
                raise DeviceError(
                    "One of group or remote must be specified for vxlan")

            if "group" in kwargs and "realdev" not in kwargs:
                raise DeviceError("'group' requires realdev to be specified")

            if kwargs.get("remote", False) and ipaddress(
                    kwargs["remote"]).is_multicast:
                logging.debug("ATTENTION: non-unicast remote IP set: %s" %
                              str(kwargs["remote"]))

            if kwargs.get(
                    "group",
                    False) and not ipaddress(kwargs["group"]).is_multicast:
                logging.debug("ATTENTION: non-multicast group IP set: %s" %
                              str(kwargs["group"]))

        super(VxlanDevice, self).__init__(ifmanager, *args, **kwargs)
Esempio n. 3
0
    def _set_nested_nl_attr(self, msg, value, *args):
        if len(args) == 1:
            self._set_nl_attr(msg, value, args[0])
        elif len(args) > 1:
            if args[0] not in msg:
                msg[args[0]] = {"attrs": {}}
            elif not isinstance(msg[args[0]],
                                dict) or "attrs" not in msg[args[0]]:
                raise DeviceError("Error constructing nested nl msg.")

            attrs = msg[args[0]]["attrs"]
            self._set_nested_nl_attr(attrs, value, *args[1:])
        else:
            raise DeviceError("Error constructing nested nl msg.")
Esempio n. 4
0
    def ip_add(self, addr, peer=None):
        """add an ip address

        Args:
            addr -- an address accepted by the ipaddress factory method
            peer -- an address of a peer interface for point-to-point
                    deployments, accepted by the ipaddress factory method
        """
        ip = ipaddress(addr)
        if ip not in self.ips:
            kwargs = dict(index=self.ifindex,
                          local=str(ip),
                          address=str(ip),
                          mask=ip.prefixlen)
            if peer:
                kwargs['address'] = str(ipaddress(peer))

            self._ipr_wrapper("addr", "add", **kwargs)

        for i in range(5):
            logging.debug(
                "Waiting for ip address to be added {} of 5".format(i))
            time.sleep(1)
            self._if_manager.rescan_devices()
            if addr in self.ips:
                break
        else:
            raise DeviceError("Failed to configure ip address {}".format(
                str(ip)))
Esempio n. 5
0
    def create_device(self, clsname, args=[], kwargs={}):
        devcls = self._device_classes[clsname]

        try:
            device = devcls(self, *args, **kwargs)
        except KeyError as e:
            raise DeviceConfigError("%s is a mandatory argument" % e)
        device._create()
        device._bulk_enabled = False

        self.request_netlink_dump()
        self.pull_netlink_messages_into_queue()

        device_found = False
        while len(self._msg_queue):
            msg = self._msg_queue.popleft()
            if msg.get_attr("IFLA_IFNAME") == device.name:
                device_found = True
                device._init_netlink(msg)
                self._devices[msg['index']] = device
            else:
                self._handle_netlink_msg(msg)

        if device_found:
            return device
        else:
            raise DeviceError("Device creation failed")
Esempio n. 6
0
    def _write_pause_frames(self, rx_val, tx_val):
        ethtool_cmd = "ethtool -A {}".format(self.name)
        ethtool_opts = ""

        for feature, value in [('rx', rx_val), ('tx', tx_val)]:
            if value is None:
                continue

            ethtool_opts += " {} {}".format(feature, 'on' if value else 'off')

        if len(ethtool_opts) == 0:
            return

        try:
            exec_cmd(ethtool_cmd + ethtool_opts)
        except ExecCmdFail as e:
            if e.get_retval() == 79:
                raise DeviceConfigError(
                    "Could not modify pause settings for %s." % self.name)

        timeout = 5
        while timeout > 0:
            if self._pause_frames_match(rx_val, tx_val):
                break
            time.sleep(1)
            timeout -= 1

        if timeout == 0:
            raise DeviceError("Pause frames not set!")
Esempio n. 7
0
    def _update_netlink(self, nl_msg):
        if getattr(self, "_deleted"):
            raise DeviceDeleted("Device was deleted.")

        if self.ifindex != nl_msg['index']:
            msg = "ifindex of netlink message (%s) doesn't match "\
                  "the device's (%s)." % (nl_msg['index'], self.ifindex)
            raise DeviceError(msg)

        if nl_msg['header']['type'] == RTM_NEWLINK:
            self._nl_msg = nl_msg
        elif nl_msg['header']['type'] == RTM_NEWADDR:
            addr = ipaddress(nl_msg.get_attr('IFA_ADDRESS'),
                             flags=nl_msg.get_attr("IFA_FLAGS"))
            addr.prefixlen = nl_msg["prefixlen"]

            if addr not in self._ip_addrs:
                self._ip_addrs.append(addr)
            else:
                old_idx = self._ip_addrs.index(addr)
                addr_old = self._ip_addrs[old_idx]
                if addr.flags != addr_old.flags:
                    self._ip_addrs.pop(old_idx)
                    self._ip_addrs.append(addr)

        elif nl_msg['header']['type'] == RTM_DELADDR:
            addr = ipaddress(nl_msg.get_attr('IFA_ADDRESS'))
            addr.prefixlen = nl_msg["prefixlen"]

            if addr in self._ip_addrs:
                self._ip_addrs.remove(addr)
Esempio n. 8
0
    def _create(self):
        """Creates a new netdevice of the corresponding type

        Method to be implemented by derived classes where applicable.
        """
        msg = "Can't create a hardware ethernet device."
        raise DeviceError(msg)
Esempio n. 9
0
 def port_del(self, dev):
     if isinstance(dev, Device):
         exec_cmd("ovs-vsctl del-port %s %s" % (self.name, dev.name))
     elif isinstance(dev, str):
         exec_cmd("ovs-vsctl del-port %s %s" % (self.name, dev))
     else:
         raise DeviceError("Invalid port_del argument %s" % str(dev))
Esempio n. 10
0
    def _create(self):
        domain_ctl = self._machine.get_domain_ctl()

        if self.orig_hwaddr:
            if self._machine.get_dev_by_hwaddr(self.orig_hwaddr):
                msg = "Device with hwaddr %s already exists" % self.orig_hwaddr
                raise DeviceError(msg)
        else:
            mac_pool = self._machine.get_mac_pool()
            while True:
                hwaddr = hwaddress(mac_pool.get_addr())
                if not self._machine.get_dev_by_hwaddr(hwaddr):
                    self.orig_hwaddr = hwaddr
                    break

        bridges = self._machine.get_network_bridges()
        if self.network in bridges:
            net_ctl = bridges[self.network]
        else:
            bridges[self.network] = net_ctl = VirtNetCtl()
            net_ctl.init()

        net_name = net_ctl.get_name()

        logging.info("Creating virtual device with hwaddr='%s' on machine %s",
                     self.orig_hwaddr, self._machine.get_id())

        domain_ctl.attach_interface(self.orig_hwaddr, net_name,
                                    self.virt_driver)
        # The sleep here is necessary, because udev sometimes renames the
        # newly created device
        sleep(1)
Esempio n. 11
0
    def arp_ip_target(self, val):
        if isinstance(val, list):
            new = []
            for i in val:
                try:
                    new.append(str(ipaddress(i)))
                except:
                    DeviceError(
                        "Invalid value, expected a list of ip addresses")
        elif val is None:
            new = []
        else:
            try:
                new = [ipaddress(val)]
            except:
                raise DeviceError(
                    "Invalid value, expected a list of ip addresses")

        ip_str = ",".join(new)
        self._set_linkinfo_data_attr("IFLA_BOND_ARP_IP_TARGET", ip_str)
        self._nl_link_sync("set")
Esempio n. 12
0
    def _create(self):
        try:
            self._l2tp_api = L2tp()
        except NetlinkError:
            raise DeviceError(
                "Could not initialize pyroute's L2TP API. Please check if l2tp_eth module is loaded."
            )

        session = {
            "tunnel_id": self._tunnel_id,
            "session_id": self._session_id,
            "peer_session_id": self._peer_session_id,
        }
        if self._name is None:
            self._name = session["ifname"] = self._ifmanager.assign_name(
                self._name_template)

        try:
            self._l2tp_api.create_session(**session)
        except NetlinkError as e:
            raise DeviceError(f"Could not create an L2TP session: {e}")
Esempio n. 13
0
    def master(self, dev):
        """set dev as the master of this device

        Args:
            dev -- accepts a Device object of the master object.
                When None, removes the current master from the Device."""
        if isinstance(dev, Device):
            master_idx = dev.ifindex
        elif dev is None:
            master_idx = 0
        else:
            raise DeviceError("Invalid dev argument.")

        self._update_attr(master_idx, "IFLA_MASTER")
        self._nl_link_sync("set")
Esempio n. 14
0
File: Device.py Progetto: jbenc/lnst
    def master(self, dev):
        """set dev as the master of this device

        Args:
            dev -- accepts a Device object of the master object.
                When None, removes the current master from the Device."""
        if isinstance(dev, Device):
            master_idx = dev.if_index
        elif dev is None:
            master_idx = 0
        else:
            raise DeviceError("Invalid dev argument.")
        with pyroute2.IPRoute() as ipr:
            try:
                ipr.link("set", index=self.if_index, master=master_idx)
            except pyroute2.netlink.NetlinkError:
                raise DeviceConfigValueError("Invalid master interface")
Esempio n. 15
0
    def _update_netlink(self, nl_msg):
        if getattr(self, "_deleted"):
            raise DeviceDeleted("Device was deleted.")

        if self.ifindex != nl_msg['index']:
            msg = "ifindex of netlink message (%s) doesn't match "\
                  "the device's (%s)." % (nl_msg['index'], self.ifindex)
            raise DeviceError(msg)

        if nl_msg['header']['type'] == RTM_NEWLINK:
            self._nl_msg = nl_msg
        elif nl_msg['header']['type'] == RTM_NEWADDR:
            if nl_msg['family'] == AF_INET:
                """
                from if_addr.h:
                /*
                 * Important comment:
                 * IFA_ADDRESS is prefix address, rather than local interface address.
                 * It makes no difference for normally configured broadcast interfaces,
                 * but for point-to-point IFA_ADDRESS is DESTINATION address,
                 * local address is supplied in IFA_LOCAL attribute.
                 */
                """
                addr = ipaddress(nl_msg.get_attr('IFA_LOCAL'),
                                 flags=nl_msg.get_attr("IFA_FLAGS"))
            else:
                addr = ipaddress(nl_msg.get_attr('IFA_ADDRESS'),
                                 flags=nl_msg.get_attr("IFA_FLAGS"))

            addr.prefixlen = nl_msg["prefixlen"]

            if addr not in self._ip_addrs:
                self._ip_addrs.append(addr)
            else:
                old_idx = self._ip_addrs.index(addr)
                addr_old = self._ip_addrs[old_idx]
                if addr.flags != addr_old.flags:
                    self._ip_addrs.pop(old_idx)
                    self._ip_addrs.append(addr)

        elif nl_msg['header']['type'] == RTM_DELADDR:
            addr = ipaddress(nl_msg.get_attr('IFA_ADDRESS'))
            addr.prefixlen = nl_msg["prefixlen"]

            if addr in self._ip_addrs:
                self._ip_addrs.remove(addr)
Esempio n. 16
0
 def _create(self):
     #TODO virtual method
     msg = "Classes derived from SoftDevice MUST define a create method."
     raise DeviceError(msg)
Esempio n. 17
0
 def peer_name(self):
     raise DeviceError(
         "The VethDevice peer_name property should not be accessed directly. "
         "Use the RemoteDevice.peer_name instead.")
Esempio n. 18
0
    def __init__(self, ifmanager, *args, **kwargs):
        if kwargs.get("mode",
                      False) and not kwargs["mode"] in self._mode_mapping:
            raise DeviceError("Invalid mode specified for the ipip device")

        super(IpIpDevice, self).__init__(ifmanager, *args, **kwargs)