def createbridgedsession(self, numnodes, verbose=False): """ Build a topology consisting of the given number of LxcNodes connected to a WLAN. """ # IP subnet prefix = ipaddress.Ipv4Prefix("10.0.0.0/16") self.session = Session(1) # emulated network self.net = self.session.create_node(cls=core.nodes.network.WlanNode, name="wlan1") prev = None for i in range(1, numnodes + 1): addr = "%s/%s" % (prefix.addr(i), 32) tmp = self.session.create_node(cls=core.nodes.base.CoreNode, _id=i, name="n%d" % i) tmp.newnetif(self.net, [addr]) self.nodes.append(tmp) self.session.services.add_services(tmp, "router", "IPForward") self.session.services.boot_services(tmp) self.staticroutes(i, prefix, numnodes) # link each node in a chain, with the previous node if prev: self.net.link(prev.netif(0), tmp.netif(0)) prev = tmp
def createemanesession(self, numnodes, verbose=False, cls=None, values=None): """ Build a topology consisting of the given number of LxcNodes connected to an EMANE WLAN. """ prefix = ipaddress.Ipv4Prefix("10.0.0.0/16") self.session = Session(2) self.session.node_count = str(numnodes + 1) self.session.master = True self.session.location.setrefgeo(47.57917, -122.13232, 2.00000) self.session.location.refscale = 150.0 self.session.emane.loadmodels() self.net = self.session.create_node(cls=EmaneNode, _id=numnodes + 1, name="wlan1") self.net.verbose = verbose # self.session.emane.addobj(self.net) for i in range(1, numnodes + 1): addr = "%s/%s" % (prefix.addr(i), 32) tmp = self.session.create_node(cls=core.nodes.base.CoreNode, _id=i, name="n%d" % i) # tmp.setposition(i * 20, 50, None) tmp.setposition(50, 50, None) tmp.newnetif(self.net, [addr]) self.nodes.append(tmp) self.session.services.add_services(tmp, "router", "IPForward") if values is None: values = cls.getdefaultvalues() self.session.emane.setconfig(self.net.id, cls.name, values) self.session.instantiate() self.info("waiting %s sec (TAP bring-up)" % 2) time.sleep(2) for i in range(1, numnodes + 1): tmp = self.nodes[i - 1] self.session.services.boot_services(tmp) self.staticroutes(i, prefix, numnodes)
def create_session(self, _id=None, master=True): """ Create a new CORE session, set to master if running standalone. :param int _id: session id for new session :param bool master: sets session to master :return: created session :rtype: EmuSession """ if not _id: while True: _id = self.session_id_gen.next() if _id not in self.sessions: break session = Session(_id, config=self.config) logging.info("created session: %s", _id) if master: session.master = True self.sessions[_id] = session return session
def topology(self, numnodes, linkprob, verbose=False): """ Build a topology consisting of the given number of ManetNodes connected to a WLAN and probabilty of links and set the session, WLAN, and node list objects. """ # IP subnet prefix = ipaddress.Ipv4Prefix("10.14.0.0/16") self.session = Session(1) # emulated network self.net = self.session.create_node(cls=core.nodes.network.WlanNode) for i in range(1, numnodes + 1): addr = "%s/%s" % (prefix.addr(i), 32) tmp = self.session.create_node(cls=ManetNode, ipaddr=addr, _id="%d" % i, name="n%d" % i) tmp.newnetif(self.net, [addr]) self.nodes.append(tmp) # connect nodes with probability linkprob for i in range(numnodes): for j in range(i + 1, numnodes): r = random.random() if r < linkprob: if self.verbose: self.info("linking (%d,%d)" % (i, j)) self.net.link(self.nodes[i].netif(0), self.nodes[j].netif(0)) # force one link to avoid partitions (should check if this is needed) j = i while j == i: j = random.randint(0, numnodes - 1) if self.verbose: self.info("linking (%d,%d)" % (i, j)) self.net.link(self.nodes[i].netif(0), self.nodes[j].netif(0)) self.nodes[i].boot() # run the boot.sh script on all nodes to start Quagga for i in range(numnodes): self.nodes[i].cmd(["./%s" % self.nodes[i].bootsh])
def main(): usagestr = "usage: %prog [-h] [options] [args]" parser = optparse.OptionParser(usage=usagestr) parser.set_defaults(waittime=0.2, numnodes=0, bridges=0, retries=0, logfile=None, services=None) parser.add_option( "-w", "--waittime", dest="waittime", type=float, help="number of seconds to wait between node creation" " (default = %s)" % parser.defaults["waittime"], ) parser.add_option( "-n", "--numnodes", dest="numnodes", type=int, help="number of nodes (default = unlimited)", ) parser.add_option( "-b", "--bridges", dest="bridges", type=int, help="number of nodes per bridge; 0 = one bridge " "(def. = %s)" % parser.defaults["bridges"], ) parser.add_option( "-r", "--retry", dest="retries", type=int, help="number of retries on error (default = %s)" % parser.defaults["retries"], ) parser.add_option( "-l", "--log", dest="logfile", type=str, help="log memory usage to this file (default = %s)" % parser.defaults["logfile"], ) parser.add_option( "-s", "--services", dest="services", type=str, help="pipe-delimited list of services added to each " "node (default = %s)\n(Example: zebra|OSPFv2|OSPFv3|" "IPForward)" % parser.defaults["services"], ) def usage(msg=None, err=0): sys.stdout.write("\n") if msg: sys.stdout.write(msg + "\n\n") parser.print_help() sys.exit(err) options, args = parser.parse_args() for a in args: sys.stderr.write("ignoring command line argument: %s\n" % a) start = datetime.datetime.now() prefix = ipaddress.Ipv4Prefix("10.83.0.0/16") print("Testing how many network namespace nodes this machine can create.") print(" - %s" % linuxversion()) mem = memfree() print(" - %.02f GB total memory (%.02f GB swap)" % (mem["total"] / GBD, mem["stotal"] / GBD)) print(" - using IPv4 network prefix %s" % prefix) print(" - using wait time of %s" % options.waittime) print(" - using %d nodes per bridge" % options.bridges) print(" - will retry %d times on failure" % options.retries) print(" - adding these services to each node: %s" % options.services) print(" ") lfp = None if options.logfile is not None: # initialize a csv log file header lfp = open(options.logfile, "a") lfp.write("# log from howmanynodes.py %s\n" % time.ctime()) lfp.write("# options = %s\n#\n" % options) lfp.write("# numnodes,%s\n" % ",".join(MEMKEYS)) lfp.flush() session = Session(1) switch = session.create_node(cls=core.nodes.network.SwitchNode) switchlist.append(switch) print("Added bridge %s (%d)." % (switch.brname, len(switchlist))) i = 0 retry_count = options.retries while True: i += 1 # optionally add a bridge (options.bridges nodes per bridge) try: if 0 < options.bridges <= switch.numnetif(): switch = session.create_node(cls=core.nodes.network.SwitchNode) switchlist.append(switch) print("\nAdded bridge %s (%d) for node %d." % (switch.brname, len(switchlist), i)) except Exception as e: print("At %d bridges (%d nodes) caught exception:\n%s\n" % (len(switchlist), i - 1, e)) break # create a node try: n = session.create_node(cls=core.nodes.base.CoreNode, name="n%d" % i) n.newnetif(switch, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)]) n.cmd([ constants.SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0" ]) if options.services is not None: session.services.add_services(n, "", options.services.split("|")) session.services.boot_services(n) nodelist.append(n) if i % 25 == 0: print("\n%s nodes created " % i) mem = memfree() free = mem["free"] + mem["buff"] + mem["cached"] swap = mem["stotal"] - mem["sfree"] print("(%.02f/%.02f GB free/swap)" % (free / GBD, swap / GBD)) if lfp: lfp.write("%d," % i) lfp.write("%s\n" % ",".join(str(mem[x]) for x in MEMKEYS)) lfp.flush() else: sys.stdout.write(".") sys.stdout.flush() time.sleep(options.waittime) except Exception as e: print("At %d nodes caught exception:\n" % i, e) if retry_count > 0: print("\nWill retry creating node %d." % i) shutil.rmtree(n.nodedir, ignore_errors=True) retry_count -= 1 i -= 1 time.sleep(options.waittime) continue else: print("Stopping at %d nodes!" % i) break if i == options.numnodes: print("Stopping at %d nodes due to numnodes option." % i) break # node creation was successful at this point retry_count = options.retries if lfp: lfp.flush() lfp.close() print("elapsed time: %s" % (datetime.datetime.now() - start)) print("Use the core-cleanup script to remove nodes and bridges.")
def global_session(request, patcher, global_coreemu): mkdir = not request.config.getoption("mock") session = Session(1000, {"emane_prefix": "/usr"}, mkdir) yield session session.shutdown()
def main(): usagestr = "usage: %prog [-h] [options] [args]" parser = optparse.OptionParser(usage=usagestr) parser.set_defaults(numnodes=5, slave=None) parser.add_option("-n", "--numnodes", dest="numnodes", type=int, help="number of nodes") parser.add_option("-s", "--slave-server", dest="slave", type=str, help="slave server IP address") def usage(msg=None, err=0): sys.stdout.write("\n") if msg: sys.stdout.write(msg + "\n\n") parser.print_help() sys.exit(err) # parse command line options (options, args) = parser.parse_args() if options.numnodes < 1: usage("invalid number of nodes: %s" % options.numnodes) if not options.slave: usage("slave server IP address (-s) is a required argument") for a in args: sys.stderr.write("ignoring command line argument: '%s'\n" % a) start = datetime.datetime.now() prefix = ipaddress.Ipv4Prefix("10.83.0.0/16") session = Session(1) server = globals().get("server") if server is not None: server.addsession(session) # distributed setup - connect to slave server slaveport = options.slave.split(":") slave = slaveport[0] if len(slaveport) > 1: port = int(slaveport[1]) else: port = CORE_API_PORT print("connecting to slave at %s:%d" % (slave, port)) session.broker.addserver(slave, slave, port) session.broker.setupserver(slave) session.set_state(EventTypes.CONFIGURATION_STATE) tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.CONFIGURATION_STATE.value) session.broker.handlerawmsg(coreapi.CoreEventMessage.pack(0, tlvdata)) switch = session.create_node(cls=core.nodes.network.SwitchNode, name="switch") switch.setposition(x=80, y=50) num_local = options.numnodes / 2 num_remote = options.numnodes / 2 + options.numnodes % 2 print("creating %d (%d local / %d remote) nodes with addresses from %s" % (options.numnodes, num_local, num_remote, prefix)) for i in range(1, num_local + 1): node = session.create_node(cls=core.nodes.base.CoreNode, name="n%d" % i, _id=i) node.newnetif(switch, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)]) node.cmd( [constants.SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"]) node.setposition(x=150 * i, y=150) n.append(node) flags = MessageFlags.ADD.value session.broker.handlerawmsg(switch.tonodemsg(flags=flags)) # create remote nodes via API for i in range(num_local + 1, options.numnodes + 1): node = core.nodes.base.CoreNode(session=session, _id=i, name="n%d" % i, start=False) node.setposition(x=150 * i, y=150) node.server = slave n.append(node) node_data = node.data(flags) node_message = dataconversion.convert_node(node_data) session.broker.handlerawmsg(node_message) # create remote links via API for i in range(num_local + 1, options.numnodes + 1): tlvdata = coreapi.CoreLinkTlv.pack(LinkTlvs.N1_NUMBER.value, switch.id) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.N2_NUMBER.value, i) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.TYPE.value, LinkTypes.WIRED.value) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_NUMBER.value, 0) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4.value, prefix.addr(i)) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4_MASK.value, prefix.prefixlen) msg = coreapi.CoreLinkMessage.pack(flags, tlvdata) session.broker.handlerawmsg(msg) session.instantiate() tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.INSTANTIATION_STATE.value) msg = coreapi.CoreEventMessage.pack(0, tlvdata) session.broker.handlerawmsg(msg) # start a shell on node 1 n[1].client.term("bash") print("elapsed time: %s" % (datetime.datetime.now() - start)) print("To stop this session, use the 'core-cleanup' script on this server") print("and on the remote slave server.")
def main(): usagestr = "usage: %prog [-n] number of nodes [-d] daemon address" parser = optparse.OptionParser(usage=usagestr) parser.set_defaults(numnodes=5, daemon="127.0.0.1:" + str(CORE_API_PORT)) parser.add_option("-n", "--numnodes", dest="numnodes", type=int, help="number of nodes") parser.add_option("-d", "--daemon-server", dest="daemon", type=str, help="daemon server IP address") def usage(msg=None, err=0): sys.stdout.write("\n") if msg: sys.stdout.write(msg + "\n\n") parser.print_help() sys.exit(err) # parse command line options (options, args) = parser.parse_args() if options.numnodes < 1: usage("invalid number of nodes: %s" % options.numnodes) if not options.daemon: usage("daemon server IP address (-d) is a required argument") for a in args: sys.stderr.write("ignoring command line argument: %s\n" % a) start = datetime.datetime.now() prefix = ipaddress.Ipv4Prefix("10.83.0.0/16") session = Session(1) if "server" in globals(): server.addsession(session) # distributed setup - connect to daemon server daemonport = options.daemon.split(":") daemonip = daemonport[0] # Localhost is already set in the session but we change it to be the remote daemon # This stops the remote daemon trying to build a tunnel back which would fail daemon = "localhost" if len(daemonport) > 1: port = int(daemonport[1]) else: port = CORE_API_PORT print("connecting to daemon at %s:%d" % (daemon, port)) session.broker.addserver(daemon, daemonip, port) # Set the local session id to match the port. # Not necessary but seems neater. session.broker.setupserver(daemon) # We do not want the recvloop running as we will deal ourselves session.broker.dorecvloop = False # Change to configuration state on both machines session.set_state(EventTypes.CONFIGURATION_STATE) tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.CONFIGURATION_STATE.value) session.broker.handlerawmsg(coreapi.CoreEventMessage.pack(0, tlvdata)) flags = MessageFlags.ADD.value switch = core.nodes.network.SwitchNode(session=session, name="switch", start=False) switch.setposition(x=80, y=50) switch.server = daemon switch_data = switch.data(flags) switch_message = dataconversion.convert_node(switch_data) session.broker.handlerawmsg(switch_message) number_of_nodes = options.numnodes print("creating %d remote nodes with addresses from %s" % (options.numnodes, prefix)) # create remote nodes via API for i in range(1, number_of_nodes + 1): node = core.nodes.base.CoreNode(session=session, _id=i, name="n%d" % i, start=False) node.setposition(x=150 * i, y=150) node.server = daemon node_data = node.data(flags) node_message = dataconversion.convert_node(node_data) session.broker.handlerawmsg(node_message) n.append(node) # create remote links via API for i in range(1, number_of_nodes + 1): tlvdata = coreapi.CoreLinkTlv.pack(LinkTlvs.N1_NUMBER.value, switch.id) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.N2_NUMBER.value, i) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.TYPE.value, LinkTypes.WIRED.value) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_NUMBER.value, 0) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4.value, prefix.addr(i)) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4_MASK.value, prefix.prefixlen) msg = coreapi.CoreLinkMessage.pack(flags, tlvdata) session.broker.handlerawmsg(msg) # We change the daemon to Instantiation state # We do not change the local session as it would try and build a tunnel and fail tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.INSTANTIATION_STATE.value) msg = coreapi.CoreEventMessage.pack(0, tlvdata) session.broker.handlerawmsg(msg) # Get the ip or last node and ping it from the first print("Pinging from the first to the last node") pingip = cmd(n[-1], "ip -4 -o addr show dev eth0").split()[3].split("/")[0] print(cmd(n[1], "ping -c 5 " + pingip)) print("elapsed time: %s" % (datetime.datetime.now() - start)) print( "To stop this session, use the core-cleanup script on the remote daemon server." ) raw_input("press enter to exit")