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)
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
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
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()
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)
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)
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()
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
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()
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)
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]
def getNodeAddressOnPrefix(self, prefix, id): if IP.isIpv6(prefix): return self.__getNodeIPv6AddressOnPrefix(prefix, id) else: return self.__getNodeIPv4AddressOnPrefix(prefix, id)
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
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)