From 9fe57c6089b9c26abf59b5a22bf455f0424ab24c Mon Sep 17 00:00:00 2001 From: "Blake J. Harnden" Date: Tue, 17 Apr 2018 14:30:34 -0700 Subject: [PATCH] initial toy code for future core api changes/improvements --- daemon/core/future/__init__.py | 0 daemon/core/future/coreemu.py | 152 +++++++++++++++++++++++++++ daemon/examples/future/emane80211.py | 54 ++++++++++ daemon/examples/future/parser.py | 41 ++++++++ daemon/examples/future/switch.py | 59 +++++++++++ daemon/examples/future/wlan.py | 66 ++++++++++++ 6 files changed, 372 insertions(+) create mode 100644 daemon/core/future/__init__.py create mode 100644 daemon/core/future/coreemu.py create mode 100644 daemon/examples/future/emane80211.py create mode 100644 daemon/examples/future/parser.py create mode 100644 daemon/examples/future/switch.py create mode 100644 daemon/examples/future/wlan.py diff --git a/daemon/core/future/__init__.py b/daemon/core/future/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/daemon/core/future/coreemu.py b/daemon/core/future/coreemu.py new file mode 100644 index 00000000..971399fb --- /dev/null +++ b/daemon/core/future/coreemu.py @@ -0,0 +1,152 @@ +# import itertools + +from core import services +from core.emane.nodes import EmaneNode +from core.misc.ipaddress import Ipv4Prefix +from core.netns.nodes import CoreNode +from core.session import Session + + +class IdGen(object): + def __init__(self): + self.id = 0 + + def next(self): + self.id += 1 + return self.id + + +class FutureIpv4Prefix(Ipv4Prefix): + def get_address(self, node_id): + address = self.addr(node_id) + return "%s/%s" % (address, self.prefixlen) + + +class FutureSession(Session): + def __init__(self, session_id, config=None, persistent=True, mkdir=True): + super(FutureSession, self).__init__(session_id, config, persistent, mkdir) + + # set master + self.master = True + + # object management + self.object_id_gen = IdGen() + + # set default services + self.services.defaultservices = { + "mdr": ("zebra", "OSPFv3MDR", "IPForward"), + "PC": ("DefaultRoute",), + "prouter": ("zebra", "OSPFv2", "OSPFv3", "IPForward"), + "router": ("zebra", "OSPFv2", "OSPFv3", "IPForward"), + "host": ("DefaultRoute", "SSH"), + } + + def create_node(self, cls, name=None, model=None): + object_id = self.object_id_gen.next() + + if not name: + name = "%s%s" % (cls.__name__, object_id) + + node = self.add_object(cls=cls, name=name, objid=object_id) + node.type = model + if node.type: + self.services.addservicestonode(node, node.type, services_str=None) + + return node + + def create_emane_node(self, name=None): + return self.create_node(cls=CoreNode, name=name, model="mdr") + + def create_emane_network(self, model, geo_reference, geo_scale=None, name=None): + """ + Convenience method for creating an emane network. + + :param model: emane model to use for emane network + :param geo_reference: geo reference point to use for emane node locations + :param geo_scale: geo scale to use for emane node locations, defaults to 1.0 + :param name: name for emane network, defaults to node class name + :return: create emane network + """ + # required to be set for emane to function properly + self.location.setrefgeo(*geo_reference) + if geo_scale: + self.location.refscale = geo_scale + + # create and return network + emane_network = self.create_node(cls=EmaneNode, name=name) + self.set_emane_model(emane_network, model) + return emane_network + + def set_emane_model(self, emane_node, model): + """ + Set emane model for a given emane node. + + :param emane_node: emane node to set model for + :param model: emane model to set + :return: nothing + """ + values = list(model.getdefaultvalues()) + self.emane.setconfig(emane_node.objid, model.name, values) + + +class CoreEmu(object): + """ + Provides logic for creating and configuring CORE sessions and the nodes within them. + """ + + def __init__(self, config=None): + # configuration + self.config = config + + # session management + self.session_id_gen = IdGen() + self.sessions = {} + + # load default services + services.load() + + def create_session(self): + """ + Create a new CORE session. + + :return: created session + :rtype: FutureSession + """ + session_id = self.session_id_gen.next() + return FutureSession(session_id, config=self.config) + + def set_wireless_model(self, node, model): + """ + Convenience method for setting a wireless model. + + :param node: node to set wireless model for + :param core.mobility.WirelessModel model: wireless model to set node to + :return: nothing + """ + values = list(model.getdefaultvalues()) + node.setmodel(model, values) + + def wireless_link_all(self, network, nodes): + """ + Link all nodes to the provided wireless network. + + :param network: wireless network to link nodes to + :param nodes: nodes to link to wireless network + :return: nothing + """ + for node in nodes: + for common_network, interface_one, interface_two in node.commonnets(network): + common_network.link(interface_one, interface_two) + + def add_interface(self, network, node, prefix): + """ + Convenience method for adding an interface with a prefix based on node id. + + :param network: network to add interface with + :param node: node to add interface to + :param prefix: prefix to get address from for interface + :return: created interface + """ + address = prefix.get_address(node.objid) + interface_index = node.newnetif(network, [address]) + return node.netif(interface_index) diff --git a/daemon/examples/future/emane80211.py b/daemon/examples/future/emane80211.py new file mode 100644 index 00000000..66c9cd22 --- /dev/null +++ b/daemon/examples/future/emane80211.py @@ -0,0 +1,54 @@ +#!/usr/bin/python -i +# +# Example CORE Python script that attaches N nodes to an EMANE 802.11abg network. + +import datetime + +import parser +from core.emane.ieee80211abg import EmaneIeee80211abgModel +from core.future.coreemu import FutureIpv4Prefix, CoreEmu + + +def example(options): + # ip generator for example + prefix = FutureIpv4Prefix("10.83.0.0/16") + + # create emulator instance for creating sessions and utility methods + coreemu = CoreEmu() + session = coreemu.create_session() + + # create emane network node + emane_network = session.create_emane_network( + model=EmaneIeee80211abgModel, + geo_reference=(47.57917, -122.13232, 2.00000) + ) + emane_network.setposition(x=80, y=50) + + # create nodes + for i in xrange(options.nodes): + node = session.create_emane_node() + coreemu.add_interface(emane_network, node, prefix) + node.setposition(x=150 * (i + 1), y=150) + + # instantiate session + session.instantiate() + + # start a shell on the first node + node = session.get_object(2) + node.client.term("bash") + + # shutdown session + raw_input("press enter to exit...") + session.shutdown() + + +def main(): + options = parser.parse_options("emane80211") + start = datetime.datetime.now() + print "running emane 80211 example: nodes(%s) time(%s)" % (options.nodes, options.time) + example(options) + print "elapsed time: %s" % (datetime.datetime.now() - start) + + +if __name__ == "__main__" or __name__ == "__builtin__": + main() diff --git a/daemon/examples/future/parser.py b/daemon/examples/future/parser.py new file mode 100644 index 00000000..c6523ba1 --- /dev/null +++ b/daemon/examples/future/parser.py @@ -0,0 +1,41 @@ +import argparse + +DEFAULT_NODES = 2 +DEFAULT_TIME = 10 +DEFAULT_STEP = 1 + + +def parse_options(name): + parser = argparse.ArgumentParser(description="Run %s example" % name) + parser.add_argument("-n", "--nodes", type=int, default=DEFAULT_NODES, + help="number of nodes to create in this example") + parser.add_argument("-t", "--time", type=int, default=DEFAULT_TIME, + help="example iperf run time in seconds") + + options = parser.parse_args() + + # usagestr = "usage: %prog [-h] [options] [args]" + # parser = optparse.OptionParser(usage=usagestr) + # + # parser.add_option("-n", "--nodes", dest="nodes", type=int, default=DEFAULT_NODES, + # help="number of nodes to create in this example") + # + # parser.add_option("-t", "--time", dest="time", type=int, default=DEFAULT_TIME, + # help="example iperf run time in seconds") + + # def usage(msg=None, err=0): + # print + # if msg: + # print "%s\n" % msg + # parser.print_help() + # sys.exit(err) + + # parse command line options + # options, args = parser.parse_args() + + if options.nodes < 2: + parser.error("invalid min number of nodes: %s" % options.nodes) + if options.time < 1: + parser.error("invalid test time: %s" % options.time) + + return options diff --git a/daemon/examples/future/switch.py b/daemon/examples/future/switch.py new file mode 100644 index 00000000..7333d567 --- /dev/null +++ b/daemon/examples/future/switch.py @@ -0,0 +1,59 @@ +#!/usr/bin/python +# +# run iperf to measure the effective throughput between two nodes when +# n nodes are connected to a virtual wlan; run test for testsec +# and repeat for minnodes <= n <= maxnodes with a step size of +# nodestep + +import datetime + +import parser +from core.future.coreemu import FutureIpv4Prefix, CoreEmu +from core.netns.nodes import CoreNode, SwitchNode + + +def example(options): + # ip generator for example + prefix = FutureIpv4Prefix("10.83.0.0/16") + + # create emulator instance for creating sessions and utility methods + coreemu = CoreEmu() + session = coreemu.create_session() + + # create switch network node + switch_network = session.create_node(cls=SwitchNode) + + # create nodes + for _ in xrange(options.nodes): + node = session.create_node(cls=CoreNode) + coreemu.add_interface(switch_network, node, prefix) + + # instantiate session + session.instantiate() + + # get nodes to run example + first_node = session.get_object(2) + last_node = session.get_object(options.nodes + 1) + + print "starting iperf server on node: %s" % first_node.name + first_node.cmd(["iperf", "-s", "-D"]) + address = str(prefix.addr(first_node.objid)) + print "node %s connecting to %s" % (last_node.name, address) + last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address]) + first_node.cmd(["killall", "-9", "iperf"]) + + # shutdown session + session.shutdown() + + +def main(): + options = parser.parse_options("switch") + + start = datetime.datetime.now() + print "running switch example: nodes(%s) time(%s)" % (options.nodes, options.time) + example(options) + print "elapsed time: %s" % (datetime.datetime.now() - start) + + +if __name__ == "__main__": + main() diff --git a/daemon/examples/future/wlan.py b/daemon/examples/future/wlan.py new file mode 100644 index 00000000..efbd725c --- /dev/null +++ b/daemon/examples/future/wlan.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +# +# run iperf to measure the effective throughput between two nodes when +# n nodes are connected to a virtual wlan; run test for testsec +# and repeat for minnodes <= n <= maxnodes with a step size of +# nodestep + +import datetime + +import parser +from core.future.coreemu import FutureIpv4Prefix, CoreEmu +from core.mobility import BasicRangeModel +from core.netns.nodes import WlanNode, CoreNode + + +def example(options): + # ip generator for example + prefix = FutureIpv4Prefix("10.83.0.0/16") + + # create emulator instance for creating sessions and utility methods + coreemu = CoreEmu() + session = coreemu.create_session() + + # create wlan network node + wlan_network = session.create_node(cls=WlanNode) + coreemu.set_wireless_model(wlan_network, BasicRangeModel) + + # create nodes + wireless_nodes = [] + for _ in xrange(options.nodes): + node = session.create_node(cls=CoreNode) + coreemu.add_interface(wlan_network, node, prefix) + wireless_nodes.append(node) + + # link all created nodes with the wireless network + coreemu.wireless_link_all(wlan_network, wireless_nodes) + + # instantiate session + session.instantiate() + + # get nodes for example run + first_node = session.get_object(2) + last_node = session.get_object(options.nodes + 1) + + print "starting iperf server on node: %s" % first_node.name + first_node.cmd(["iperf", "-s", "-D"]) + address = str(prefix.addr(first_node.objid)) + print "node %s connecting to %s" % (last_node.name, address) + last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address]) + first_node.cmd(["killall", "-9", "iperf"]) + + # shutdown session + session.shutdown() + + +def main(): + options = parser.parse_options("wlan") + + start = datetime.datetime.now() + print "running wlan example: nodes(%s) time(%s)" % (options.nodes, options.time) + example(options) + print "elapsed time: %s" % (datetime.datetime.now() - start) + + +if __name__ == "__main__": + main()