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)
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)
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.")
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)))
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")
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!")
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)
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)
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))
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)
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")
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}")
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")
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")
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)
def _create(self): #TODO virtual method msg = "Classes derived from SoftDevice MUST define a create method." raise DeviceError(msg)
def peer_name(self): raise DeviceError( "The VethDevice peer_name property should not be accessed directly. " "Use the RemoteDevice.peer_name instead.")
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)