示例#1
0
 def __delete_route(self):
     if self.to == "default" and self.via_device:
         self.__call_delete_route(4)
         self.__call_delete_route(6)
     else:
         if IP.isIpv6(self.to) or IP.isIpv6(self.via_address):
             self.__call_delete_route(6)
         else:
             self.__call_delete_route(4)
示例#2
0
文件: State.py 项目: turon/happy
    def setNetworkRoute(self, network_id, to, record, state=None):
        network_record = self.getNetwork(network_id, state)
        if network_record is not None:
            if "route" not in list(network_record.keys()):
                network_record["route"] = {}

            if ("via" in list(record.keys()) and IP.isIpv6(record["via"])) or \
               ("prefix" in list(record.keys()) and IP.isIpv6(record["prefix"])):
                to = to + "_v6"
            else:
                to = to + "_v4"

            network_record["route"][to] = record
示例#3
0
    def setNodeRoute(self, node_id, to, record, state=None):
        node_record = self.getNode(node_id, state)
        if node_record is not None:
            if "route" not in node_record.keys():
                node_record["route"] = {}

            if ("via" in record.keys() and IP.isIpv6(record["via"])) or \
               ("prefix" in record.keys() and IP.isIpv6(record["prefix"])):
                to = to + "_v6"
            else:
                to = to + "_v4"

            node_record["route"][to] = record
示例#4
0
    def __configure_node_address(self):
        network_links = self.getNetworkLinkIds(self.network_id)

        for link_id in network_links:
            node_id = self.getLinkNode(link_id)

            options = happy.HappyNodeAddress.option()
            options["quiet"] = self.quiet
            options["node_id"] = node_id

            interface_id = self.getNodeInterfaceFromLink(link_id, node_id)
            options["interface"] = interface_id

            if IP.isIpv6(self.address):
                nid = self.getInterfaceId(interface_id, node_id)
            else:
                nid = self.getNextNetworkIPv4Id(self.ip_prefix,
                                                self.network_id)

            options["address"] = self.getNodeAddressOnPrefix(
                self.ip_prefix, nid)

            if self.add:
                options["add"] = True
            else:
                options["delete"] = True

            addrctrl = happy.HappyNodeAddress.HappyNodeAddress(options)
            ret = addrctrl.run()

            self.readState()
示例#5
0
    def __delete_address(self):
        cmd = "ip "
        if IP.isIpv6(self.address):
            cmd += "-6 "
        cmd += "addr del " + str(self.ip_address) + "/" + str(self.ip_mask) + " dev " + self.interface

        cmd = self.runAsRoot(cmd)
        ret = self.CallAtNode(self.node_id, cmd)
示例#6
0
    def __traceroute_to_address(self, addr):
        cmd = ""

        if IP.isIpv6(addr):
            cmd += "traceroute6"
        else:
            cmd += "traceroute"

        if IP.isMulticast(addr):
            cmd += ""

        cmd += " " + addr

        out, err = self.CallAtNodeForOutput(self.source, cmd)

        return (out, err)
示例#7
0
    def __add_address(self):
        cmd = "ip "

        if IP.isIpv6(self.address):
            cmd += "-6 "

        cmd += "addr add " + str(self.ip_address) + "/" + str(self.ip_mask) + " dev " + self.interface

        cmd = self.runAsRoot(cmd)
        ret = self.CallAtNode(self.node_id, cmd)

        # We have disabled DAD, but under high load we can still see the
        # address in "tentative" for a few milliseconds.
        # If DAD is re-enabled, we should poll all interfaces at once after the topology
        # has been brought up, so the interfaces can come up in parallel.
        self.waitForDAD()
示例#8
0
    def getNextNetworkIPv4Id(self, prefix, network_id=None):
        if network_id is None:
            network_id = self.network_id

        network_links = self.getNetworkLinkIds(network_id)

        all_ips = []

        for node_id in self.getNodeIds():
            node_links = self.getNodeLinkIds(node_id)
            link_ids = list(set(network_links).intersection(node_links))

            node_ips = []
            for link_id in link_ids:
                interface_id = self.getNodeInterfaceFromLink(link_id, node_id)
                node_ips += self.getNodeInterfaceAddresses(
                    interface_id, node_id)

            all_ips += node_ips

        ids = []

        prefix_list = prefix.split(".")
        if len(prefix_list) < 3:
            print hred("Invalid prefix %s, guessing id" % (prefix))
            return 100

        for ip in all_ips:
            if IP.isIpv6(ip):
                continue

            ip_list = ip.split(".")

            if prefix_list[0] != ip_list[0] or prefix_list[1] != ip_list[1] or \
               prefix_list[2] != ip_list[2]:
                continue

            ids.append(int(ip_list[3]))

        if ids == []:
            # Start addresses from 2
            return 2

        ids.sort()

        return ids[-1] + 1
示例#9
0
    def __assign_network_addresses(self):
        network_prefixes = self.getNetworkPrefixes(self.network_id)

        for prefix in network_prefixes:
            options = happy.HappyNodeAddress.option()
            options["quiet"] = self.quiet
            options["node_id"] = self.node_id
            options["interface"] = self.node_interface_name

            if IP.isIpv6(prefix):
                nid = self.getInterfaceId(self.node_interface_name, self.node_id)
            else:
                nid = self.getNextNetworkIPv4Id(prefix, self.network_id)

            options["address"] = self.getNodeAddressOnPrefix(prefix, nid)

            options["add"] = True

            addrctrl = happy.HappyNodeAddress.HappyNodeAddress(options)

            ret = addrctrl.run()
示例#10
0
    def __ping_on_address(self, addr):
        cmd = ""

        if IP.isIpv6(addr):
            cmd += "ping6"
        else:
            cmd += "ping"

        cmd += " -c " + str(self.count)

        if self.size is not None:
            cmd += " -s " + str(self.size)

        if IP.isMulticast(addr):
            cmd += ""

        cmd += " " + addr

        out, err = self.CallAtNodeForOutput(self.source, cmd)

        return (out, err)
示例#11
0
    def __pre_check(self):
        # Check if the name of the new node is given
        if not self.node_id:
            emsg = "Missing name of the new virtual node that IP routes should be managed."
            self.logger.error("[localhost] HappyNodeRoute: %s" % (emsg))
            self.exit()

        # Check if the name of new node is not a duplicate (that it does not already exists).
        if not self._nodeExists():
            emsg = "virtual node %s does not exist." % (self.node_id)
            self.logger.warning("[%s] HappyNodeRoute: %s" % (self.node_id, emsg))

        if not self.delete:
            self.add = True

        # Check if address is given
        if not self.to:
            emsg = "Missing address for virtual node destination (to)."
            self.logger.error("[%s] HappyNodeRoute: %s" % (self.node_id, emsg))
            self.exit()

        # Check if address is given
        if not self.via:
            emsg = "Missing address for virtual gateway (via)."
            self.logger.error("[%s] HappyNodeRoute: %s" % (self.node_id, emsg))
            self.exit()

        # Check for mix IP addresses
        if IP.isIpAddress(self.to) and IP.isIpAddress(self.via) and IP.isIpv6(self.to) != IP.isIpv6(self.via):
            emsg = "Mixing addresses %s and %s." % (self.to, self.via)
            self.logger.error("[%s] HappyNodeRoute: %s" % (self.node_id, emsg))
            self.exit()

        # Check if destination is a node
        if self.to != "default" and not IP.isIpAddress(self.to):
            if not self._nodeExists(self.to):
                emsg = "Don't know what %s to-address is. If it is a node, it can't be found." % (self.to)
                self.logger.error("[localhost] HappyNodeRoute: %s" % (emsg))
                self.exit()
            else:
                # 'to' is a node
                emsg = "Destination address must be 'default' or a IP address."
                self.logger.error("[localhost] HappyNodeRoute: %s" % (emsg))
                self.exit()

        if IP.isIpAddress(self.to):
            self.to = IP.paddingZeros(self.to)

        # Check if gateway is a node
        if IP.isIpAddress(self.via):
            self.via_address = self.via
            self.via_address = IP.paddingZeros(self.via_address)
            return

        if self._nodeInterfaceExists(self.via):
            self.via_device = self.via
            return

        if not self._nodeExists(self.via):
            emsg = "Don't know what %s via-address is. If it is a node, it can't be found." % (self.to)
            self.logger.error("[localhost] HappyNodeRoute: %s" % (emsg))
            self.exit()

        this_node_networks = self.getNodeNetworkIds(self.node_id)
        gateway_networks = self.getNodeNetworkIds(self.via)
        common_networks = list(set(this_node_networks).intersection(gateway_networks))

        if len(common_networks) == 0:
            emsg = "Node %s and gateway node %s are not on the same network." % \
                (self.node_id, self.via)
            self.logger.error("[localhost] HappyNodeRoute: %s" % (emsg))
            self.exit()

        if len(common_networks) > 1 and not self.prefix:
            emsg = "Node %s and gateway %s share more than one network. Need gateway prefix to disambiguate." % \
                (self.node_id, self.via)
            self.logger.error("[localhost] HappyNodeRoute: %s" % (emsg))
            self.exit()

        if not self.prefix:

            gateway_addresses = self.getNodeAddressesOnNetwork(common_networks[0], self.via)

            if len(gateway_addresses) == 0:
                emsg = "Gateway node (via) %s does not have any IP addresses." % \
                    (self.via)
                self.logger.error("[localhost] HappyNodeRoute: %s" % (emsg))
                self.exit()

            if len(gateway_addresses) > 1 and self.prefix is None:
                emsg = "Node %s has more than one IP address. Need gateway prefix to disambiguate." % \
                    (self.via)
                self.logger.error("[localhost] HappyNodeRoute: %s" % (emsg))
                self.exit()

            # We find gateway address without using prefix.
            self.via_address = gateway_addresses[0]
            return

        else:
            if not IP.isIpAddress(self.prefix):
                emsg = "Prefix %s is not a valid IP address."
                self.logger.error("[localhost] HappyNodeRoute: %s" % (emsg))
                self.exit()

            self.ip_prefix, self.ip_mask = IP.splitAddressMask(self.prefix)
            self.prefix = IP.getPrefix(self.ip_prefix, self.ip_mask)

            gateway_addresses = self.getNodeAddressesOnNetworkOnPrefix(common_networks[0], self.prefix, self.via)

            if len(gateway_addresses) == 0:
                emsg = "Cannot find any IP address on %s with prefix %s." % (self.via, self.prefix)
                self.logger.error("[localhost] HappyNodeRoute: %s" % (emsg))
                self.exit()

            if len(gateway_addresses) > 1:
                emsg = "Found more than one IP address on %s with prefix %s. (%s)" % \
                  (self.via, self.prefix, ",".join(gateway_addresses))
                self.logger.error("[localhost] HappyNodeRoute: %s" % (emsg))
                self.exit()

            self.via_address = gateway_addresses[0]
示例#12
0
 def getNodeAddressOnPrefix(self, prefix, id):
     if IP.isIpv6(prefix):
         return self.__getNodeIPv6AddressOnPrefix(prefix, id)
     else:
         return self.__getNodeIPv4AddressOnPrefix(prefix, id)
示例#13
0
    def __pre_check(self):
        # Check if the name of the new network is given
        if not self.network_id:
            emsg = "Missing name of the virtual network that should be configured with a route."
            self.logger.error("[localhost] HappyNetworkRoute: %s" % (emsg))
            self.exit()

        # Check if the name of new network is not a duplicate (that it does not already exists).
        if not self._networkExists():
            emsg = "virtual network %s does not exist." % (self.network_id)
            self.logger.error("[%s] HappyNetworkRoute: %s" % (self.network_id, emsg))
            self.exit()

        if not self.delete:
            self.add = True

        # Check if 'to' is given
        if not self.to:
            emsg = "Missing destination address for virtual network (to)."
            self.logger.error("[%s] HappyNetworkRoute: %s" % (self.node_id, emsg))
            self.exit()

        # Check if 'via' is given
        if not self.via:
            emsg = "Missing gateway address for virtual network (via)."
            self.logger.error("[%s] HappyNetworkRoute: %s" % (self.node_id, emsg))
            self.exit()

        # Check for mix IP addresses
        if IP.isIpAddress(self.to) and IP.isIpAddress(self.via) and IP.isIpv6(self.to) != IP.isIpv6(self.via):
            emsg = "Mixing addresses %s and %s." % (self.to, self.via)
            self.logger.error("[%s] HappyNetworkRoute: %s" % (self.node_id, emsg))
            self.exit()

        # Check if destination is a node
        if self.to != "default" and not IP.isIpAddress(self.to):
            if not self._nodeExists(self.to):
                emsg = "Don't know what %s to-address is. If it is a node, it can't be found." % (self.to)
                self.logger.error("[localhost] HappyNetworkRoute: %s" % (emsg))
                self.exit()
            else:
                # 'to' is a node
                emsg = "Destination address must be 'default' or a IP address."
                self.logger.error("[localhost] HappyNetworkRoute: %s" % (emsg))
                self.exit()

        if IP.isIpAddress(self.to):
            self.to = IP.paddingZeros(self.to)

        # Check if gateway is an address or a node
        if IP.isIpAddress(self.via):
            self.via = IP.paddingZeros(self.via)
            self.via_node = self.getNodeIdFromAddress(self.via)

            if self.via_node is None or not self._nodeExists(self.via_node):
                emsg = "Cannot find a node that would match %s." % (self.via)
                self.logger.error("[localhost] HappyNetworkRoute: %s" % (emsg))
                self.exit()

            return

        if self._nodeExists(self.via):
            self.via_node = self.via
示例#14
0
    def __pre_check(self):
        # Sanity check the transport
        if self.transport != "udp" and self.transport != "tcp" and self.transport != "raw":
            emsg = "Transport type must be one of 'raw', 'tcp', or 'udp'."
            self.__log_error_and_exit(emsg)

        # Sanity check the IP version
        if self.ipversion != "4" and self.ipversion != "6":
            emsg = "The IP version must be one of '4' or '6'."
            self.__log_error_and_exit(emsg)

        # There must be exactly one sender
        if self.sender['node'] == None:
            emsg = "The test must have exactly one sender."
            self.__log_error_and_exit(emsg)

        # There must be exactly one receiver
        if self.sender['node'] == None:
            emsg = "The test must have exactly one receiver."
            self.__log_error_and_exit(emsg)

        # Each specified sender and receiver node must exist in the
        # loaded Happy configuration.

        self.__checkNodeExists(self.sender['node'], "sender")

        self.__checkNodeExists(self.receiver['node'], "receiver")

        # Use the sender and receiver node names, specified prefix,
        # and IP version and attempt to lookup addresses for the
        # sender and receiver.

        # First, sanity check the prefix

        if self.prefix == None:
            emsg = "Please specifiy a valid IPv%s prefix." % (self.ipversion)
            self.__log_error_and_exit(emsg)

        # Second, sanity check the prefix against the IP version.

        if (self.ipversion == "4" and not IP.isIpv4(self.prefix)) or (
                self.ipversion == "6" and not IP.isIpv6(self.prefix)):
            emsg = "The specified prefix %s is the wrong address family for IPv%s" % (
                self.prefix, self.ipversion)
            self.__log_error_and_exit(emsg)

        # Finally, find and take the first matching addresses for the
        # node names and specified prefix.

        rips = self.getNodeAddressesOnPrefix(self.prefix,
                                             self.receiver['node'])

        if rips != None and len(rips) > 0:
            self.receiver['ip'] = rips[0]

        sips = self.getNodeAddressesOnPrefix(self.prefix, self.sender['node'])

        if sips != None and len(sips) > 0:
            self.sender['ip'] = sips[0]

        # Check if all unknowns were found

        if self.receiver['ip'] == None:
            emsg = "Could not find IP address of the receiver node, %s" % (
                self.receiver['node'])
            self.__log_error_and_exit(emsg)

        if self.sender['ip'] == None:
            emsg = "Could not find IP address of the sender node, %s" % (
                self.sender['node'])
            self.__log_error_and_exit(emsg)

        if self.tx_size == None or not self.tx_size.isdigit():
            emsg = "Please specify a valid size of data to send per transmission."
            self.__log_error_and_exit(emsg)

        if self.rx_tx_length == None or not self.rx_tx_length.isdigit():
            emsg = "Please specify a valid total length of data to send and receive."
            self.__log_error_and_exit(emsg)

        if not self.interval == None and not self.interval.isdigit():
            emsg = "Please specify a valid send interval in milliseconds."
            self.__log_error_and_exit(emsg)