merged cleanup branch with master

This commit is contained in:
Rod A Santiago 2017-06-19 18:09:28 -07:00
parent 0a91fe7a3e
commit 55a6e2dcef
81 changed files with 11596 additions and 15021 deletions

View file

@ -8,65 +8,83 @@
#
import optparse, sys, os, datetime, time
import datetime
import optparse
import sys
import time
from core import pycore
from core.misc import ipaddr
from core.misc.utils import mutecall
from core.misc import ipaddress, nodeutils
from core.misc import nodemaps
from core.mobility import BasicRangeModel
from core.netns.nodes import WlanNode
from core.netns.vnet import EbtablesQueue
from core.netns.vnode import LxcNode
from core.session import Session
# node list - global so you can play using 'python -i'
# e.g. >>> n[0].session.shutdown()
n = []
def test(options):
prefix = ipaddr.IPv4Prefix("10.83.0.0/16")
session = pycore.Session(persistent = True)
prefix = ipaddress.Ipv4Prefix("10.83.0.0/16")
session = Session(1, persistent=True)
if options.enablesdt:
session.location.setrefgeo(47.57917,-122.13232,50.0) # GUI default
# GUI default
session.location.setrefgeo(47.57917, -122.13232, 50.0)
session.location.refscale = 100.0
session.options.enablesdt = True
session.options.sdturl = options.sdturl
wlanid = options.numnodes + 1
net = session.addobj(cls = pycore.nodes.WlanNode, name = "wlan%d" % wlanid,
objid = wlanid, verbose = True)
net = session.add_object(
cls=WlanNode,
name="wlan%d" % wlanid,
objid=wlanid
)
values = list(BasicRangeModel.getdefaultvalues())
#values[0] = 5000000 # 5000km range
# values[0] = 5000000 # 5000km range
net.setmodel(BasicRangeModel, values)
for i in xrange(1, options.numnodes + 1):
tmp = session.addobj(cls = pycore.nodes.LxcNode, name = "n%d" % i,
objid = i)
tmp.newnetif(net, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
node = session.add_object(cls=LxcNode, name="n%d" % i, objid=i)
address = "%s/%s" % (prefix.addr(i), prefix.prefixlen)
print "setting node address: %s - %s" % (node.objid, address)
node.newnetif(net, [address])
# set increasing Z coordinates
tmp.setposition(10, 10, 100*i)
n.append(tmp)
node.setposition(10, 10, 100)
n.append(node)
# example setting node n2 to a high altitude
#n[1].setposition(10, 10, 2000000) # 2000km
#session.sdt.updatenode(n[1].objid, 0, 10, 10, 2000000)
# n[1].setposition(10, 10, 2000000) # 2000km
# session.sdt.updatenode(n[1].objid, 0, 10, 10, 2000000)
# launches terminal for the first node
# n[0].term("bash")
n[0].icmd(["ping", "-c", "5", "127.0.0.1"])
n[0].term("bash")
# wait for rate seconds to allow ebtables commands to commit
time.sleep(EbtablesQueue.rate)
#session.shutdown()
raw_input("press enter to exit")
session.shutdown()
def main():
usagestr = "usage: %prog [-h] [options] [args]"
parser = optparse.OptionParser(usage = usagestr)
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(numnodes = 2, enablesdt = False,
sdturl = "tcp://127.0.0.1:50000/")
parser.add_option("-n", "--numnodes", dest = "numnodes", type = int,
help = "number of nodes to test; default = %s" %
parser.defaults["numnodes"])
parser.add_option("-s", "--sdt", dest = "enablesdt", action = "store_true",
help = "enable SDT output")
parser.add_option("-u", "--sdturl", dest = "sdturl", type = "string",
help = "URL for SDT connection, default = %s" % \
parser.defaults["sdturl"])
parser.set_defaults(numnodes=2, enablesdt=False, sdturl="tcp://127.0.0.1:50000/")
parser.add_option(
"-n", "--numnodes", dest="numnodes", type=int,
help="number of nodes to test; default = %s" % parser.defaults["numnodes"]
)
parser.add_option("-s", "--sdt", dest="enablesdt", action="store_true", help="enable SDT output")
parser.add_option(
"-u", "--sdturl", dest="sdturl", type="string",
help="URL for SDT connection, default = %s" % parser.defaults["sdturl"]
)
def usage(msg = None, err = 0):
def usage(msg=None, err=0):
sys.stdout.write("\n")
if msg:
sys.stdout.write(msg + "\n\n")
@ -86,8 +104,12 @@ def main():
test(options)
print >> sys.stderr, \
"elapsed time: %s" % (datetime.datetime.now() - start)
print >> sys.stderr, "elapsed time: %s" % (datetime.datetime.now() - start)
if __name__ == "__main__":
# configure nodes to use
node_map = nodemaps.CLASSIC_NODES
nodeutils.set_node_map(node_map)
main()

View file

@ -5,71 +5,86 @@
# A distributed example where CORE API messaging is used to create a session
# on a daemon server. The daemon server defaults to 127.0.0.1:4038
# to target a remote machine specify '-d <ip address>' parameter, it needs to be
# to target a remote machine specify "-d <ip address>" parameter, it needs to be
# running the daemon with listenaddr=0.0.0.0 in the core.conf file.
# This script creates no nodes locally and therefore can be run as an
# unprivileged user.
import sys, datetime, optparse, time
import datetime
import optparse
import sys
from core import pycore
from core.misc import ipaddr
from core.constants import *
from core.api import coreapi
from core.api import dataconversion
from core.api.coreapi import CoreExecuteTlv
from core.enumerations import CORE_API_PORT
from core.enumerations import EventTlvs
from core.enumerations import EventTypes
from core.enumerations import ExecuteTlvs
from core.enumerations import LinkTlvs
from core.enumerations import LinkTypes
from core.enumerations import MessageFlags
from core.enumerations import MessageTypes
from core.misc import ipaddress, nodeutils, nodemaps
from core.netns import nodes
# declare classes for use with Broker
import select
coreapi.add_node_class("CORE_NODE_DEF",
coreapi.CORE_NODE_DEF, pycore.nodes.CoreNode)
coreapi.add_node_class("CORE_NODE_SWITCH",
coreapi.CORE_NODE_SWITCH, pycore.nodes.SwitchNode)
from core.session import Session
# node list (count from 1)
n = [None]
exec_num = 1
def cmd(node, exec_cmd):
'''
"""
:param node: The node the command should be issued too
:param exec_cmd: A string with the command to be run
:return: Returns the result of the command
'''
"""
global exec_num
# Set up the command api message
tlvdata = coreapi.CoreExecTlv.pack(coreapi.CORE_TLV_EXEC_NODE, node.objid)
tlvdata += coreapi.CoreExecTlv.pack(coreapi.CORE_TLV_EXEC_NUM, exec_num)
tlvdata += coreapi.CoreExecTlv.pack(coreapi.CORE_TLV_EXEC_CMD, exec_cmd)
msg = coreapi.CoreExecMessage.pack(coreapi.CORE_API_STR_FLAG | coreapi.CORE_API_TXT_FLAG, tlvdata)
tlvdata = CoreExecuteTlv.pack(ExecuteTlvs.NODE.value, node.objid)
tlvdata += CoreExecuteTlv.pack(ExecuteTlvs.NUMBER.value, exec_num)
tlvdata += CoreExecuteTlv.pack(ExecuteTlvs.COMMAND.value, exec_cmd)
msg = coreapi.CoreExecMessage.pack(MessageFlags.STRING.value | MessageFlags.TEXT.value, tlvdata)
node.session.broker.handlerawmsg(msg)
exec_num += 1
# Now wait for the response
(h, p, sock) = node.session.broker.servers['localhost']
sock.settimeout(50.0)
msghdr = sock.recv(coreapi.CoreMessage.hdrsiz)
msgtype, msgflags, msglen = coreapi.CoreMessage.unpackhdr(msghdr)
msgdata = sock.recv(msglen)
server = node.session.broker.servers["localhost"]
server.sock.settimeout(50.0)
# receive messages until we get our execute response
result = None
while True:
msghdr = server.sock.recv(coreapi.CoreMessage.header_len)
msgtype, msgflags, msglen = coreapi.CoreMessage.unpack_header(msghdr)
msgdata = server.sock.recv(msglen)
# If we get the right response return the results
print "received response message: %s" % MessageTypes(msgtype)
if msgtype == MessageTypes.EXECUTE.value:
msg = coreapi.CoreExecMessage(msgflags, msghdr, msgdata)
result = msg.get_tlv(ExecuteTlvs.RESULT.value)
break
return result
# If we get the right response return the results
if msgtype == coreapi.CORE_API_EXEC_MSG:
msg = coreapi.CoreExecMessage(msgflags, msghdr, msgdata)
return msg.gettlv(coreapi.CORE_TLV_EXEC_RESULT)
else:
return None
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(coreapi.CORE_API_PORT))
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")
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):
def usage(msg=None, err=0):
sys.stdout.write("\n")
if msg:
sys.stdout.write(msg + "\n\n")
@ -85,94 +100,95 @@ def main():
usage("daemon server IP address (-d) is a required argument")
for a in args:
sys.stderr.write("ignoring command line argument: '%s'\n" % a)
sys.stderr.write("ignoring command line argument: %s\n" % a)
start = datetime.datetime.now()
prefix = ipaddr.IPv4Prefix("10.83.0.0/16")
session = pycore.Session(persistent=True)
if 'server' in globals():
prefix = ipaddress.Ipv4Prefix("10.83.0.0/16")
session = Session(1, persistent=True)
if "server" in globals():
server.addsession(session)
# distributed setup - connect to daemon server
daemonport = options.daemon.split(':')
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'
daemon = "localhost"
if len(daemonport) > 1:
port = int(daemonport[1])
else:
port = coreapi.CORE_API_PORT
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.sessionid = session.broker.getserver('localhost')[2].getsockname()[1]
# session.sessionid = session.broker.getserver("localhost")[2].getsockname()[1]
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.setstate(coreapi.CORE_EVENT_CONFIGURATION_STATE)
tlvdata = coreapi.CoreEventTlv.pack(coreapi.CORE_TLV_EVENT_TYPE,
coreapi.CORE_EVENT_CONFIGURATION_STATE)
session.set_state(EventTypes.CONFIGURATION_STATE.value)
tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.CONFIGURATION_STATE.value)
session.broker.handlerawmsg(coreapi.CoreEventMessage.pack(0, tlvdata))
flags = coreapi.CORE_API_ADD_FLAG
switch = pycore.nodes.SwitchNode(session = session, name='switch', start=False)
switch.setposition(x=80,y=50)
flags = MessageFlags.ADD.value
switch = nodes.SwitchNode(session=session, name="switch", start=False)
switch.setposition(x=80, y=50)
switch.server = daemon
session.broker.handlerawmsg(switch.tonodemsg(flags=flags))
switch_data = switch.data(flags)
switch_message = dataconversion.convert_node(switch_data)
session.broker.handlerawmsg(switch_message)
numberOfNodes = options.numnodes
number_of_nodes = options.numnodes
print "creating %d remote nodes with addresses from %s" % \
(options.numnodes, prefix)
print "creating %d remote nodes with addresses from %s" % (options.numnodes, prefix)
# create remote nodes via API
for i in xrange(1, numberOfNodes + 1):
tmp = pycore.nodes.CoreNode(session = session, objid = i,
name = "n%d" % i, start=False)
tmp.setposition(x=150*i,y=150)
tmp.server = daemon
session.broker.handlerawmsg(tmp.tonodemsg(flags=flags))
n.append(tmp)
for i in xrange(1, number_of_nodes + 1):
node = nodes.CoreNode(session=session, objid=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 xrange(1, numberOfNodes + 1):
tlvdata = coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_N1NUMBER,
switch.objid)
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_N2NUMBER, i)
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_TYPE,
coreapi.CORE_LINK_WIRED)
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_IF2NUM, 0)
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_IF2IP4,
prefix.addr(i))
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_IF2IP4MASK,
prefix.prefixlen)
for i in xrange(1, number_of_nodes + 1):
tlvdata = coreapi.CoreLinkTlv.pack(LinkTlvs.N1_NUMBER.value, switch.objid)
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(coreapi.CORE_TLV_EVENT_TYPE,
coreapi.CORE_EVENT_INSTANTIATION_STATE)
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 "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."
print "To stop this session, use the core-cleanup script on the remote daemon server."
raw_input("press enter to exit")
if __name__ == "__main__" or __name__ == "__builtin__":
main()
# configure nodes to use
node_map = nodemaps.CLASSIC_NODES
nodeutils.set_node_map(node_map)
main()

View file

@ -9,33 +9,32 @@
# running the daemon with listenaddr=0.0.0.0 in the core.conf file.
#
import sys, datetime, optparse, time
import datetime
import optparse
import sys
from core import pycore
from core.misc import ipaddr
from core.constants import *
from core.api import coreapi
# declare classes for use with Broker
coreapi.add_node_class("CORE_NODE_DEF",
coreapi.CORE_NODE_DEF, pycore.nodes.CoreNode)
coreapi.add_node_class("CORE_NODE_SWITCH",
coreapi.CORE_NODE_SWITCH, pycore.nodes.SwitchNode)
from core import constants
from core.api import coreapi, dataconversion
from core.enumerations import CORE_API_PORT, EventTypes, EventTlvs, LinkTlvs, LinkTypes, MessageFlags
from core.misc import ipaddress, nodeutils, nodemaps
from core.netns import nodes
from core.session import Session
# node list (count from 1)
n = [None]
def main():
usagestr = "usage: %prog [-h] [options] [args]"
parser = optparse.OptionParser(usage = usagestr)
parser.set_defaults(numnodes = 5, slave = None)
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")
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):
def usage(msg=None, err=0):
sys.stdout.write("\n")
if msg:
sys.stdout.write(msg + "\n\n")
@ -55,8 +54,8 @@ def main():
start = datetime.datetime.now()
prefix = ipaddr.IPv4Prefix("10.83.0.0/16")
session = pycore.Session(persistent=True)
prefix = ipaddress.Ipv4Prefix("10.83.0.0/16")
session = Session(1, persistent=True)
if 'server' in globals():
server.addsession(session)
@ -66,59 +65,53 @@ def main():
if len(slaveport) > 1:
port = int(slaveport[1])
else:
port = coreapi.CORE_API_PORT
port = CORE_API_PORT
print "connecting to slave at %s:%d" % (slave, port)
session.broker.addserver(slave, slave, port)
session.broker.setupserver(slave)
session.setstate(coreapi.CORE_EVENT_CONFIGURATION_STATE)
tlvdata = coreapi.CoreEventTlv.pack(coreapi.CORE_TLV_EVENT_TYPE,
coreapi.CORE_EVENT_CONFIGURATION_STATE)
session.set_state(EventTypes.CONFIGURATION_STATE.value)
tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.CONFIGURATION_STATE.value)
session.broker.handlerawmsg(coreapi.CoreEventMessage.pack(0, tlvdata))
switch = session.addobj(cls = pycore.nodes.SwitchNode, name = "switch")
switch.setposition(x=80,y=50)
switch = session.add_object(cls=nodes.SwitchNode, name="switch")
switch.setposition(x=80, y=50)
num_local = options.numnodes / 2
num_remote = options.numnodes / 2 + 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 xrange(1, num_local + 1):
tmp = session.addobj(cls = pycore.nodes.CoreNode, name = "n%d" % i,
objid=i)
tmp.newnetif(switch, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
tmp.cmd([SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
tmp.setposition(x=150*i,y=150)
n.append(tmp)
node = session.add_object(cls=nodes.CoreNode, name="n%d" % i, objid=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 = coreapi.CORE_API_ADD_FLAG
flags = MessageFlags.ADD.value
session.broker.handlerawmsg(switch.tonodemsg(flags=flags))
# create remote nodes via API
for i in xrange(num_local + 1, options.numnodes + 1):
tmp = pycore.nodes.CoreNode(session = session, objid = i,
name = "n%d" % i, start=False)
tmp.setposition(x=150*i,y=150)
tmp.server = slave
n.append(tmp)
session.broker.handlerawmsg(tmp.tonodemsg(flags=flags))
node = nodes.CoreNode(session=session, objid=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 xrange(num_local + 1, options.numnodes + 1):
tlvdata = coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_N1NUMBER,
switch.objid)
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_N2NUMBER, i)
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_TYPE,
coreapi.CORE_LINK_WIRED)
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_IF2NUM, 0)
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_IF2IP4,
prefix.addr(i))
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_IF2IP4MASK,
prefix.prefixlen)
tlvdata = coreapi.CoreLinkTlv.pack(LinkTlvs.N1_NUMBER.value, switch.objid)
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(coreapi.CORE_TLV_EVENT_TYPE,
coreapi.CORE_EVENT_INSTANTIATION_STATE)
tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.INSTANTIATION_STATE.value)
msg = coreapi.CoreEventMessage.pack(0, tlvdata)
session.broker.handlerawmsg(msg)
@ -132,6 +125,10 @@ def main():
print "To stop this session, use the 'core-cleanup' script on this server"
print "and on the remote slave server."
if __name__ == "__main__" or __name__ == "__builtin__":
main()
if __name__ == "__main__" or __name__ == "__builtin__":
# configure nodes to use
node_map = nodemaps.CLASSIC_NODES
nodeutils.set_node_map(node_map)
main()

View file

@ -6,25 +6,31 @@
# Example CORE Python script that attaches N nodes to an EMANE 802.11abg
# network. One of the parameters is changed, the pathloss mode.
import sys, datetime, optparse
import datetime
import optparse
import sys
from core import pycore
from core.misc import ipaddr
from core.constants import *
from core import constants
from core.emane.ieee80211abg import EmaneIeee80211abgModel
from core.emane.nodes import EmaneNode
from core.misc import ipaddress, nodeutils, nodemaps
from core.netns import nodes
# node list (count from 1)
from core.session import Session
n = [None]
def main():
usagestr = "usage: %prog [-h] [options] [args]"
parser = optparse.OptionParser(usage = usagestr)
parser.set_defaults(numnodes = 5)
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(numnodes=5)
parser.add_option("-n", "--numnodes", dest = "numnodes", type = int,
help = "number of nodes")
parser.add_option("-n", "--numnodes", dest="numnodes", type=int,
help="number of nodes")
def usage(msg = None, err = 0):
def usage(msg=None, err=0):
sys.stdout.write("\n")
if msg:
sys.stdout.write(msg + "\n\n")
@ -43,44 +49,44 @@ def main():
start = datetime.datetime.now()
# IP subnet
prefix = ipaddr.IPv4Prefix("10.83.0.0/16")
prefix = ipaddress.Ipv4Prefix("10.83.0.0/16")
# session with some EMANE initialization
cfg = {'verbose': 'false'}
session = pycore.Session(cfg = cfg, persistent = True)
session = Session(1, config=cfg, persistent=True)
session.master = True
session.location.setrefgeo(47.57917,-122.13232,2.00000)
session.location.setrefgeo(47.57917, -122.13232, 2.00000)
session.location.refscale = 150.0
session.cfg['emane_models'] = "RfPipe, Ieee80211abg, Bypass"
session.config['emane_models'] = "RfPipe, Ieee80211abg, Bypass"
session.emane.loadmodels()
if 'server' in globals():
server.addsession(session)
# EMANE WLAN
print "creating EMANE WLAN wlan1"
wlan = session.addobj(cls = pycore.nodes.EmaneNode, name = "wlan1")
wlan.setposition(x=80,y=50)
wlan = session.add_object(cls=EmaneNode, name="wlan1")
wlan.setposition(x=80, y=50)
names = EmaneIeee80211abgModel.getnames()
values = list(EmaneIeee80211abgModel.getdefaultvalues())
# TODO: change any of the EMANE 802.11 parameter values here
for i in range(0, len(names)):
print "EMANE 80211 \"%s\" = \"%s\"" % (names[i], values[i])
try:
values[ names.index('pathlossmode') ] = '2ray'
values[names.index('pathlossmode')] = '2ray'
except ValueError:
values[ names.index('propagationmodel') ] = '2ray'
session.emane.setconfig(wlan.objid, EmaneIeee80211abgModel._name, values)
values[names.index('propagationmodel')] = '2ray'
session.emane.setconfig(wlan.objid, EmaneIeee80211abgModel.name, values)
services_str = "zebra|OSPFv3MDR|IPForward"
print "creating %d nodes with addresses from %s" % \
(options.numnodes, prefix)
for i in xrange(1, options.numnodes + 1):
tmp = session.addobj(cls = pycore.nodes.CoreNode, name = "n%d" % i,
objid=i)
tmp = session.add_object(cls=nodes.CoreNode, name="n%d" % i,
objid=i)
tmp.newnetif(wlan, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
tmp.cmd([SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
tmp.setposition(x=150*i,y=150)
session.services.addservicestonode(tmp, "", services_str, verbose=False)
tmp.cmd([constants.SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
tmp.setposition(x=150 * i, y=150)
session.services.addservicestonode(tmp, "", services_str)
n.append(tmp)
# this starts EMANE, etc.
@ -92,6 +98,10 @@ def main():
print "elapsed time: %s" % (datetime.datetime.now() - start)
if __name__ == "__main__" or __name__ == "__builtin__":
main()
if __name__ == "__main__" or __name__ == "__builtin__":
# configure nodes to use
node_map = nodemaps.CLASSIC_NODES
nodeutils.set_node_map(node_map)
main()

View file

@ -5,49 +5,48 @@
#
# author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
#
'''
"""
howmanynodes.py - This is a CORE script that creates network namespace nodes
having one virtual Ethernet interface connected to a bridge. It continues to
add nodes until an exception occurs. The number of nodes per bridge can be
specified.
'''
specified.
"""
import optparse, sys, os, datetime, time, shutil
try:
from core import pycore
except ImportError:
# hack for Fedora autoconf that uses the following pythondir:
if "/usr/lib/python2.6/site-packages" in sys.path:
sys.path.append("/usr/local/lib/python2.6/site-packages")
if "/usr/lib64/python2.6/site-packages" in sys.path:
sys.path.append("/usr/local/lib64/python2.6/site-packages")
if "/usr/lib/python2.7/site-packages" in sys.path:
sys.path.append("/usr/local/lib/python2.7/site-packages")
if "/usr/lib64/python2.7/site-packages" in sys.path:
sys.path.append("/usr/local/lib64/python2.7/site-packages")
from core import pycore
from core.misc import ipaddr
from core.constants import *
import datetime
import optparse
import shutil
import sys
import time
from core import constants
from core.misc import ipaddress, nodeutils, nodemaps
from core.netns import nodes
from core.session import Session
GBD = 1024.0 * 1024.0
def linuxversion():
''' Return a string having the Linux kernel version.
'''
f = open('/proc/version', 'r')
""" Return a string having the Linux kernel version.
"""
f = open("/proc/version", "r")
v = f.readline().split()
version_str = ' '.join(v[:3])
version_str = " ".join(v[:3])
f.close()
return version_str
MEMKEYS = ('total', 'free', 'buff', 'cached', 'stotal', 'sfree')
MEMKEYS = ("total", "free", "buff", "cached", "stotal", "sfree")
def memfree():
''' Returns kilobytes memory [total, free, buff, cached, stotal, sfree].
""" Returns kilobytes memory [total, free, buff, cached, stotal, sfree].
useful stats are:
free memory = free + buff + cached
swap used = stotal - sfree
'''
f = open('/proc/meminfo', 'r')
"""
f = open("/proc/meminfo", "r")
lines = f.readlines()
f.close()
kbs = {}
@ -55,20 +54,21 @@ def memfree():
kbs[k] = 0
for l in lines:
if l[:9] == "MemTotal:":
kbs['total'] = int(l.split()[1])
kbs["total"] = int(l.split()[1])
elif l[:8] == "MemFree:":
kbs['free'] = int(l.split()[1])
kbs["free"] = int(l.split()[1])
elif l[:8] == "Buffers:":
kbs['buff'] = int(l.split()[1])
kbs["buff"] = int(l.split()[1])
elif l[:8] == "Cached:":
kbs['cache'] = int(l.split()[1])
kbs["cache"] = int(l.split()[1])
elif l[:10] == "SwapTotal:":
kbs['stotal'] = int(l.split()[1])
kbs["stotal"] = int(l.split()[1])
elif l[:9] == "SwapFree:":
kbs['sfree'] = int(l.split()[1])
kbs["sfree"] = int(l.split()[1])
break
return kbs
# node list (count from 1)
nodelist = [None]
switchlist = []
@ -76,30 +76,30 @@ switchlist = []
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 = 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"])
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):
def usage(msg=None, err=0):
sys.stdout.write("\n")
if msg:
sys.stdout.write(msg + "\n\n")
@ -109,16 +109,16 @@ def main():
(options, args) = parser.parse_args()
for a in args:
sys.stderr.write("ignoring command line argument: '%s'\n" % a)
sys.stderr.write("ignoring command line argument: %s\n" % a)
start = datetime.datetime.now()
prefix = ipaddr.IPv4Prefix("10.83.0.0/16")
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)
(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
@ -132,11 +132,11 @@ def main():
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.write("# numnodes,%s\n" % ",".join(MEMKEYS))
lfp.flush()
session = pycore.Session(persistent=True)
switch = session.addobj(cls = pycore.nodes.SwitchNode)
session = Session(1, persistent=True)
switch = session.add_object(cls=nodes.SwitchNode)
switchlist.append(switch)
print "Added bridge %s (%d)." % (switch.brname, len(switchlist))
@ -147,33 +147,32 @@ def main():
# optionally add a bridge (options.bridges nodes per bridge)
try:
if options.bridges > 0 and switch.numnetif() >= options.bridges:
switch = session.addobj(cls = pycore.nodes.SwitchNode)
switch = session.add_object(cls=nodes.SwitchNode)
switchlist.append(switch)
print "\nAdded bridge %s (%d) for node %d." % \
(switch.brname, len(switchlist), i)
(switch.brname, len(switchlist), i)
except Exception, e:
print "At %d bridges (%d nodes) caught exception:\n%s\n" % \
(len(switchlist), i-1, e)
(len(switchlist), i - 1, e)
break
# create a node
try:
n = session.addobj(cls = pycore.nodes.LxcNode, name = "n%d" % i)
n = session.add_object(cls=nodes.LxcNode, name="n%d" % i)
n.newnetif(switch, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
n.cmd([SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
n.cmd([constants.SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
if options.services is not None:
session.services.addservicestonode(n, "", options.services,
verbose=False)
session.services.addservicestonode(n, "", options.services)
n.boot()
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),
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.write("%s\n" % ",".join(str(mem[x]) for x in MEMKEYS))
lfp.flush()
else:
sys.stdout.write(".")
@ -183,7 +182,7 @@ def main():
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)
shutil.rmtree(n.nodedir, ignore_errors=True)
retry_count -= 1
i -= 1
time.sleep(options.waittime)
@ -205,5 +204,10 @@ def main():
print "elapsed time: %s" % (datetime.datetime.now() - start)
print "Use the core-cleanup script to remove nodes and bridges."
if __name__ == "__main__":
# configure nodes to use
node_map = nodemaps.CLASSIC_NODES
nodeutils.set_node_map(node_map)
main()

View file

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python
# Copyright (c)2013 the Boeing Company.
# See the LICENSE file included in this distribution.
@ -14,24 +14,29 @@
# Use core-cleanup to clean up after this script as the session is left running.
#
import sys, datetime, optparse
import datetime
import optparse
import sys
from core import pycore
from core.misc import ipaddr
from core.constants import *
from core import constants
from core.misc import ipaddress, nodeutils, nodemaps
from core.netns import nodes
# node list (count from 1)
from core.session import Session
n = [None]
def main():
usagestr = "usage: %prog [-h] [options] [args]"
parser = optparse.OptionParser(usage = usagestr)
parser.set_defaults(numnodes = 5)
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(numnodes=5)
parser.add_option("-n", "--numnodes", dest = "numnodes", type = int,
help = "number of nodes")
parser.add_option("-n", "--numnodes", dest="numnodes", type=int,
help="number of nodes")
def usage(msg = None, err = 0):
def usage(msg=None, err=0):
sys.stdout.write("\n")
if msg:
sys.stdout.write(msg + "\n\n")
@ -52,48 +57,51 @@ def main():
start = datetime.datetime.now()
session = pycore.Session(persistent=True)
session = Session(1, persistent=True)
if 'server' in globals():
server.addsession(session)
print "creating %d nodes" % options.numnodes
print "creating %d nodes" % options.numnodes
left = None
prefix = None
for i in xrange(1, options.numnodes + 1):
tmp = session.addobj(cls = pycore.nodes.CoreNode, name = "n%d" % i,
objid=i)
tmp = session.add_object(cls=nodes.CoreNode, name="n%d" % i, objid=i)
if left:
tmp.newnetif(left, ["%s/%s" % (prefix.addr(2), prefix.prefixlen)])
prefix = ipaddr.IPv4Prefix("10.83.%d.0/24" % i) # limit: i < 255
right = session.addobj(cls = pycore.nodes.PtpNet)
# limit: i < 255
prefix = ipaddress.Ipv4Prefix("10.83.%d.0/24" % i)
right = session.add_object(cls=nodes.PtpNet)
tmp.newnetif(right, ["%s/%s" % (prefix.addr(1), prefix.prefixlen)])
tmp.cmd([SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
tmp.cmd([SYSCTL_BIN, "net.ipv4.conf.all.forwarding=1"])
tmp.cmd([SYSCTL_BIN, "net.ipv4.conf.default.rp_filter=0"])
tmp.setposition(x=100*i,y=150)
tmp.cmd([constants.SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
tmp.cmd([constants.SYSCTL_BIN, "net.ipv4.conf.all.forwarding=1"])
tmp.cmd([constants.SYSCTL_BIN, "net.ipv4.conf.default.rp_filter=0"])
tmp.setposition(x=100 * i, y=150)
n.append(tmp)
left = right
prefixes = map(lambda(x): ipaddr.IPv4Prefix("10.83.%d.0/24" % x),
prefixes = map(lambda (x): ipaddress.Ipv4Prefix("10.83.%d.0/24" % x),
xrange(1, options.numnodes + 1))
# set up static routing in the chain
for i in xrange(1, options.numnodes + 1):
for j in xrange(1, options.numnodes + 1):
if j < i - 1:
gw = prefixes[i-2].addr(1)
gw = prefixes[i - 2].addr(1)
elif j > i:
if i > len(prefixes) - 1:
continue
gw = prefixes[i-1].addr(2)
gw = prefixes[i - 1].addr(2)
else:
continue
net = prefixes[j-1]
n[i].cmd([IP_BIN, "route", "add", str(net), "via", str(gw)])
net = prefixes[j - 1]
n[i].cmd([constants.IP_BIN, "route", "add", str(net), "via", str(gw)])
print "elapsed time: %s" % (datetime.datetime.now() - start)
if __name__ == "__main__" or __name__ == "__builtin__":
main()
if __name__ == "__main__" or __name__ == "__builtin__":
# configure nodes to use
node_map = nodemaps.CLASSIC_NODES
nodeutils.set_node_map(node_map)
main()

View file

@ -7,26 +7,22 @@
# that all neighbor states are either full or two-way, and check the routes
# in zebra vs those installed in the kernel.
import os, sys, random, time, optparse, datetime
import datetime
import optparse
import os
import random
import sys
import time
from string import Template
try:
from core import pycore
except ImportError:
# hack for Fedora autoconf that uses the following pythondir:
if "/usr/lib/python2.6/site-packages" in sys.path:
sys.path.append("/usr/local/lib/python2.6/site-packages")
if "/usr/lib64/python2.6/site-packages" in sys.path:
sys.path.append("/usr/local/lib64/python2.6/site-packages")
if "/usr/lib/python2.7/site-packages" in sys.path:
sys.path.append("/usr/local/lib/python2.7/site-packages")
if "/usr/lib64/python2.7/site-packages" in sys.path:
sys.path.append("/usr/local/lib64/python2.7/site-packages")
from core import pycore
from core.misc import ipaddr
from core.misc.utils import mutecall
from core.constants import QUAGGA_STATE_DIR
from core.misc import ipaddress, nodeutils, nodemaps
from core.misc.utils import mutecall
from core.netns import nodes
# this is the /etc/core/core.conf default
from core.session import Session
quagga_sbin_search = ("/usr/local/sbin", "/usr/sbin", "/usr/lib/quagga")
quagga_path = "zebra"
@ -37,12 +33,13 @@ try:
quagga_path = p
break
mutecall([os.path.join(quagga_path, "zebra"),
"-u", "root", "-g", "root", "-v"])
"-u", "root", "-g", "root", "-v"])
except OSError:
sys.stderr.write("ERROR: running zebra failed\n")
sys.exit(1)
class ManetNode(pycore.nodes.LxcNode):
class ManetNode(nodes.LxcNode):
""" An Lxc namespace node configured for Quagga OSPFv3 MANET MDR
"""
conftemp = Template("""\
@ -66,19 +63,19 @@ ip forwarding
confdir = "/usr/local/etc/quagga"
def __init__(self, core, ipaddr, routerid = None,
objid = None, name = None, nodedir = None):
def __init__(self, core, ipaddr, routerid=None,
objid=None, name=None, nodedir=None):
if routerid is None:
routerid = ipaddr.split("/")[0]
self.ipaddr = ipaddr
self.routerid = routerid
pycore.nodes.LxcNode.__init__(self, core, objid, name, nodedir)
nodes.LxcNode.__init__(self, core, objid, name, nodedir)
self.privatedir(self.confdir)
self.privatedir(QUAGGA_STATE_DIR)
def qconf(self):
return self.conftemp.substitute(ipaddr = self.ipaddr,
routerid = self.routerid)
return self.conftemp.substitute(ipaddr=self.ipaddr,
routerid=self.routerid)
def config(self):
filename = os.path.join(self.confdir, "Quagga.conf")
@ -87,7 +84,7 @@ ip forwarding
f.close()
tmp = self.bootscript()
if tmp:
self.nodefile(self.bootsh, tmp, mode = 0755)
self.nodefile(self.bootsh, tmp, mode=0755)
def boot(self):
self.config()
@ -125,14 +122,16 @@ waitfile $STATEDIR/ospf6d.vty
vtysh -b
""" % (QUAGGA_STATE_DIR, quagga_path, quagga_path)
class Route(object):
""" Helper class for organzing routing table entries. """
def __init__(self, prefix = None, gw = None, metric = None):
try:
self.prefix = ipaddr.IPv4Prefix(prefix)
def __init__(self, prefix=None, gw=None, metric=None):
try:
self.prefix = ipaddress.Ipv4Prefix(prefix)
except Exception, e:
raise ValueError, "Invalid prefix given to Route object: %s\n%s" % \
(prefix, e)
(prefix, e)
self.gw = gw
self.metric = metric
@ -156,7 +155,8 @@ class Route(object):
class ManetExperiment(object):
""" A class for building an MDR network and checking and logging its state.
"""
def __init__(self, options, start):
def __init__(self, options, start):
""" Initialize with options and start time. """
self.session = None
# node list
@ -168,8 +168,8 @@ class ManetExperiment(object):
self.options = options
self.start = start
self.logbegin()
def info(self, msg):
def info(self, msg):
''' Utility method for writing output to stdout. '''
print msg
sys.stdout.flush()
@ -180,7 +180,7 @@ class ManetExperiment(object):
print >> sys.stderr, msg
sys.stderr.flush()
self.log(msg)
def logbegin(self):
""" Start logging. """
self.logfp = None
@ -188,32 +188,32 @@ class ManetExperiment(object):
return
self.logfp = open(self.options.logfile, "w")
self.log("ospfmanetmdrtest begin: %s\n" % self.start.ctime())
def logend(self):
""" End logging. """
if not self.logfp:
return
end = datetime.datetime.now()
self.log("ospfmanetmdrtest end: %s (%s)\n" % \
(end.ctime(), end - self.start))
(end.ctime(), end - self.start))
self.logfp.flush()
self.logfp.close()
self.logfp = None
def log(self, msg):
""" Write to the log file, if any. """
if not self.logfp:
return
print >> self.logfp, msg
def logdata(self, nbrs, mdrs, lsdbs, krs, zrs):
print >> self.logfp, msg
def logdata(self, nbrs, mdrs, lsdbs, krs, zrs):
""" Dump experiment parameters and data to the log file. """
self.log("ospfmantetmdrtest data:")
self.log("----- parameters -----")
self.log("%s" % self.options)
self.log("----- neighbors -----")
for rtrid in sorted(nbrs.keys()):
self.log("%s: %s" % (rtrid, nbrs[rtrid]))
self.log("%s: %s" % (rtrid, nbrs[rtrid]))
self.log("----- mdr levels -----")
self.log(mdrs)
self.log("----- link state databases -----")
@ -233,20 +233,20 @@ class ManetExperiment(object):
for rt in zrs[rtrid]:
msg += "%s" % rt
self.log(msg)
def topology(self, numnodes, linkprob, verbose = False):
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 = ipaddr.IPv4Prefix("10.14.0.0/16")
self.session = pycore.Session()
prefix = ipaddress.Ipv4Prefix("10.14.0.0/16")
self.session = Session(1)
# emulated network
self.net = self.session.addobj(cls = pycore.nodes.WlanNode)
self.net = self.session.add_object(cls=nodes.WlanNode)
for i in xrange(1, numnodes + 1):
addr = "%s/%s" % (prefix.addr(i), 32)
tmp = self.session.addobj(cls = ManetNode, ipaddr = addr, objid= "%d" % i, name = "n%d" % i)
tmp = self.session.add_object(cls=ManetNode, ipaddr=addr, objid="%d" % i, name="n%d" % i)
tmp.newnetif(self.net, [addr])
self.nodes.append(tmp)
# connect nodes with probability linkprob
@ -277,9 +277,9 @@ class ManetExperiment(object):
if kr != zr:
self.warn("kernel and zebra routes differ")
if self.verbose:
msg = "kernel: "
msg = "kernel: "
for r in kr:
msg += "%s " % r
msg += "%s " % r
msg += "\nzebra: "
for r in zr:
msg += "%s " % r
@ -317,15 +317,15 @@ class ManetExperiment(object):
if lsdbs[prev.routerid] != db:
msg = "LSDBs of all routers are not consistent"
self.warn("XXX LSDBs inconsistent for %s and %s" % \
(n.routerid, prev.routerid))
(n.routerid, prev.routerid))
i = 0
for entry in lsdbs[n.routerid].split("\n"):
preventries = lsdbs[prev.routerid].split("\n")
try:
preventry = preventries[i]
except IndexError:
preventry = None
if entry != preventry:
preventry = None
if entry != preventry:
self.warn("%s: %s" % (n.routerid, entry))
self.warn("%s: %s" % (prev.routerid, preventry))
i += 1
@ -343,19 +343,21 @@ class ManetExperiment(object):
v = self.verbose
for n in self.nodes:
self.info("checking %s" % n.name)
nbrs[n.routerid] = Ospf6NeighState(n, verbose=v).run()
krs[n.routerid] = KernelRoutes(n, verbose=v).run()
zrs[n.routerid] = ZebraRoutes(n, verbose=v).run()
nbrs[n.routerid] = Ospf6NeighState(n, verbose=v).run()
krs[n.routerid] = KernelRoutes(n, verbose=v).run()
zrs[n.routerid] = ZebraRoutes(n, verbose=v).run()
self.compareroutes(n, krs[n.routerid], zrs[n.routerid])
mdrs[n.routerid] = Ospf6MdrLevel(n, verbose=v).run()
lsdbs[n.routerid] = Ospf6Database(n, verbose=v).run()
mdrs[n.routerid] = Ospf6MdrLevel(n, verbose=v).run()
lsdbs[n.routerid] = Ospf6Database(n, verbose=v).run()
self.comparemdrlevels(nbrs, mdrs)
self.comparelsdbs(lsdbs)
self.logdata(nbrs, mdrs, lsdbs, krs, zrs)
self.logdata(nbrs, mdrs, lsdbs, krs, zrs)
class Cmd:
""" Helper class for running a command on a node and parsing the result. """
args = ""
def __init__(self, node, verbose=False):
""" Initialize with a CoreNode (LxcNode) """
self.id = None
@ -363,35 +365,35 @@ class Cmd:
self.out = None
self.node = node
self.verbose = verbose
def info(self, msg):
def info(self, msg):
''' Utility method for writing output to stdout.'''
print msg
sys.stdout.flush()
def warn(self, msg):
''' Utility method for writing output to stderr. '''
print >> sys.stderr, "XXX %s:" % self.node.routerid, msg
print >> sys.stderr, "XXX %s:" % self.node.routerid, msg
sys.stderr.flush()
def run(self):
""" This is the primary method used for running this command. """
self.open()
r = self.parse()
self.cleanup()
return r
def open(self):
""" Exceute call to node.popen(). """
self.id, self.stdin, self.out, self.err = \
self.node.popen((self.args))
self.node.popen(self.args)
def parse(self):
""" This method is overloaded by child classes and should return some
result.
"""
return None
def cleanup(self):
""" Close the Popen channels."""
self.stdin.close()
@ -401,18 +403,22 @@ class Cmd:
if tmp:
self.warn("nonzero exit status:", tmp)
class VtyshCmd(Cmd):
""" Runs a vtysh command. """
def open(self):
args = ("vtysh", "-c", self.args)
self.id, self.stdin, self.out, self.err = self.node.popen((args))
args = ("vtysh", "-c", self.args)
self.id, self.stdin, self.out, self.err = self.node.popen(args)
class Ospf6NeighState(VtyshCmd):
""" Check a node for OSPFv3 neighbors in the full/two-way states. """
args = "show ipv6 ospf6 neighbor"
def parse(self):
self.out.readline() # skip first line
# skip first line
self.out.readline()
nbrlist = []
for line in self.out:
field = line.split()
@ -428,13 +434,14 @@ class Ospf6NeighState(VtyshCmd):
self.info(" %s has %d neighbors" % (self.node.routerid, len(nbrlist)))
return nbrlist
class Ospf6MdrLevel(VtyshCmd):
""" Retrieve the OSPFv3 MDR level for a node. """
args = "show ipv6 ospf6 mdrlevel"
def parse(self):
line = self.out.readline()
# TODO: handle multiple interfaces
# TODO: handle multiple interfaces
field = line.split()
mdrlevel = field[4]
if not mdrlevel in ("MDR", "BMDR", "OTHER"):
@ -443,12 +450,13 @@ class Ospf6MdrLevel(VtyshCmd):
self.info(" %s is %s" % (self.node.routerid, mdrlevel))
return mdrlevel
class Ospf6Database(VtyshCmd):
""" Retrieve the OSPFv3 LSDB summary for a node. """
args = "show ipv6 ospf6 database"
def parse(self):
db = ""
db = ""
for line in self.out:
field = line.split()
if len(field) < 8:
@ -458,15 +466,17 @@ class Ospf6Database(VtyshCmd):
db += " ".join(filtered) + "\n"
return db
class ZebraRoutes(VtyshCmd):
""" Return a list of Route objects for a node based on its zebra
routing table.
"""
args = "show ip route"
def parse(self):
for i in xrange(0,3):
self.out.readline() # skip first three lines
for i in xrange(0, 3):
# skip first three lines
self.out.readline()
r = []
prefix = None
for line in self.out:
@ -497,12 +507,13 @@ class ZebraRoutes(VtyshCmd):
self.info(" %s has %d zebra routes" % (self.node.routerid, len(r)))
return r
class KernelRoutes(Cmd):
""" Return a list of Route objects for a node based on its kernel
""" Return a list of Route objects for a node based on its kernel
routing table.
"""
args = ("/sbin/ip", "route", "show")
args = ("/sbin/ip", "route", "show")
def parse(self):
r = []
prefix = None
@ -521,7 +532,8 @@ class KernelRoutes(Cmd):
if field[1] == "proto":
# nexthop entry is on the next line
continue
gw = field[2] # nexthop IP or interface
# nexthop IP or interface
gw = field[2]
r.append(Route(prefix, gw, metric))
prefix = None
@ -531,25 +543,26 @@ class KernelRoutes(Cmd):
self.info(" %s has %d kernel routes" % (self.node.routerid, len(r)))
return r
def main():
usagestr = "usage: %prog [-h] [options] [args]"
parser = optparse.OptionParser(usage = usagestr)
parser.set_defaults(numnodes = 10, linkprob = 0.35, delay = 20, seed = None)
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(numnodes=10, linkprob=0.35, delay=20, seed=None)
parser.add_option("-n", "--numnodes", dest = "numnodes", type = int,
help = "number of nodes")
parser.add_option("-p", "--linkprob", dest = "linkprob", type = float,
help = "link probabilty")
parser.add_option("-d", "--delay", dest = "delay", type = float,
help = "wait time before checking")
parser.add_option("-s", "--seed", dest = "seed", type = int,
help = "specify integer to use for random seed")
parser.add_option("-v", "--verbose", dest = "verbose",
action = "store_true", help = "be more verbose")
parser.add_option("-l", "--logfile", dest = "logfile", type = str,
help = "log detailed output to the specified file")
parser.add_option("-n", "--numnodes", dest="numnodes", type=int,
help="number of nodes")
parser.add_option("-p", "--linkprob", dest="linkprob", type=float,
help="link probabilty")
parser.add_option("-d", "--delay", dest="delay", type=float,
help="wait time before checking")
parser.add_option("-s", "--seed", dest="seed", type=int,
help="specify integer to use for random seed")
parser.add_option("-v", "--verbose", dest="verbose",
action="store_true", help="be more verbose")
parser.add_option("-l", "--logfile", dest="logfile", type=str,
help="log detailed output to the specified file")
def usage(msg = None, err = 0):
def usage(msg=None, err=0):
sys.stdout.write("\n")
if msg:
sys.stdout.write(msg + "\n\n")
@ -572,11 +585,11 @@ def main():
if options.seed:
random.seed(options.seed)
me = ManetExperiment(options = options, start=datetime.datetime.now())
me = ManetExperiment(options=options, start=datetime.datetime.now())
me.info("creating topology: numnodes = %s; linkprob = %s" % \
(options.numnodes, options.linkprob))
(options.numnodes, options.linkprob))
me.topology(options.numnodes, options.linkprob)
me.info("waiting %s sec" % options.delay)
time.sleep(options.delay)
me.info("checking neighbor state and routes")
@ -584,8 +597,13 @@ def main():
me.info("done")
me.info("elapsed time: %s" % (datetime.datetime.now() - me.start))
me.logend()
return me
if __name__ == "__main__":
# configure nodes to use
node_map = nodemaps.CLASSIC_NODES
nodeutils.set_node_map(node_map)
me = main()

View file

@ -5,24 +5,29 @@
# connect n nodes to a virtual switch/hub
import sys, datetime, optparse
import datetime
import optparse
import sys
from core import pycore
from core.misc import ipaddr
from core.constants import *
from core import constants
from core.misc import ipaddress, nodeutils, nodemaps
from core.netns import nodes
# node list (count from 1)
from core.session import Session
n = [None]
def main():
usagestr = "usage: %prog [-h] [options] [args]"
parser = optparse.OptionParser(usage = usagestr)
parser.set_defaults(numnodes = 5)
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(numnodes=5)
parser.add_option("-n", "--numnodes", dest = "numnodes", type = int,
help = "number of nodes")
parser.add_option("-n", "--numnodes", dest="numnodes", type=int,
help="number of nodes")
def usage(msg = None, err = 0):
def usage(msg=None, err=0):
sys.stdout.write("\n")
if msg:
sys.stdout.write(msg + "\n\n")
@ -41,30 +46,35 @@ def main():
start = datetime.datetime.now()
# IP subnet
prefix = ipaddr.IPv4Prefix("10.83.0.0/16")
session = pycore.Session(persistent=True)
prefix = ipaddress.Ipv4Prefix("10.83.0.0/16")
session = Session(1, persistent=True)
if 'server' in globals():
server.addsession(session)
# emulated Ethernet switch
switch = session.addobj(cls = pycore.nodes.SwitchNode, name = "switch")
switch.setposition(x=80,y=50)
print "creating %d nodes with addresses from %s" % \
(options.numnodes, prefix)
switch = session.add_object(cls=nodes.SwitchNode, name="switch")
switch.setposition(x=80, y=50)
print "creating %d nodes with addresses from %s" % (options.numnodes, prefix)
for i in xrange(1, options.numnodes + 1):
tmp = session.addobj(cls = pycore.nodes.CoreNode, name = "n%d" % i,
objid=i)
tmp = session.add_object(cls=nodes.CoreNode, name="n%d" % i, objid=i)
tmp.newnetif(switch, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
tmp.cmd([SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
tmp.setposition(x=150*i,y=150)
tmp.cmd([constants.SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
tmp.setposition(x=150 * i, y=150)
n.append(tmp)
session.node_count = str(options.numnodes + 1)
session.instantiate()
print "elapsed time: %s" % (datetime.datetime.now() - start)
# start a shell on node 1
n[1].term("bash")
print "elapsed time: %s" % (datetime.datetime.now() - start)
raw_input("press enter to exit")
session.shutdown()
if __name__ == "__main__" or __name__ == "__builtin__":
main()
# configure nodes to use
node_map = nodemaps.CLASSIC_NODES
nodeutils.set_node_map(node_map)
main()

View file

@ -8,11 +8,14 @@
# and repeat for minnodes <= n <= maxnodes with a step size of
# nodestep
import optparse, sys, os, datetime
import datetime
import optparse
import sys
from core import pycore
from core.misc import ipaddr
from core.misc import ipaddress, nodeutils, nodemaps
from core.misc.utils import mutecall
from core.netns import nodes
from core.session import Session
try:
mutecall(["iperf", "-v"])
@ -20,48 +23,52 @@ except OSError:
sys.stderr.write("ERROR: running iperf failed\n")
sys.exit(1)
def test(numnodes, testsec):
# node list
n = []
# IP subnet
prefix = ipaddr.IPv4Prefix("10.83.0.0/16")
session = pycore.Session()
prefix = ipaddress.Ipv4Prefix("10.83.0.0/16")
session = Session(1)
# emulated network
net = session.addobj(cls = pycore.nodes.SwitchNode)
net = session.add_object(cls=nodes.SwitchNode)
for i in xrange(1, numnodes + 1):
tmp = session.addobj(cls = pycore.nodes.LxcNode, name = "n%d" % i)
tmp = session.add_object(cls=nodes.LxcNode, name="n%d" % i)
tmp.newnetif(net, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
n.append(tmp)
n[0].cmd(["iperf", "-s", "-D"])
n[-1].icmd(["iperf", "-t", str(int(testsec)), "-c", str(prefix.addr(1))])
n[0].cmd(["killall", "-9", "iperf"])
raw_input("press enter to exit")
session.shutdown()
def main():
usagestr = "usage: %prog [-h] [options] [args]"
parser = optparse.OptionParser(usage = usagestr)
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(minnodes = 2)
parser.add_option("-m", "--minnodes", dest = "minnodes", type = int,
help = "min number of nodes to test; default = %s" %
parser.defaults["minnodes"])
parser.set_defaults(minnodes=2)
parser.add_option("-m", "--minnodes", dest="minnodes", type=int,
help="min number of nodes to test; default = %s" %
parser.defaults["minnodes"])
parser.set_defaults(maxnodes = 2)
parser.add_option("-n", "--maxnodes", dest = "maxnodes", type = int,
help = "max number of nodes to test; default = %s" %
parser.defaults["maxnodes"])
parser.set_defaults(maxnodes=2)
parser.add_option("-n", "--maxnodes", dest="maxnodes", type=int,
help="max number of nodes to test; default = %s" %
parser.defaults["maxnodes"])
parser.set_defaults(testsec = 10)
parser.add_option("-t", "--testsec", dest = "testsec", type = int,
help = "test time in seconds; default = %s" %
parser.defaults["testsec"])
parser.set_defaults(testsec=10)
parser.add_option("-t", "--testsec", dest="testsec", type=int,
help="test time in seconds; default = %s" %
parser.defaults["testsec"])
parser.set_defaults(nodestep = 1)
parser.add_option("-s", "--nodestep", dest = "nodestep", type = int,
help = "number of nodes step size; default = %s" %
parser.defaults["nodestep"])
parser.set_defaults(nodestep=1)
parser.add_option("-s", "--nodestep", dest="nodestep", type=int,
help="number of nodes step size; default = %s" %
parser.defaults["nodestep"])
def usage(msg = None, err = 0):
def usage(msg=None, err=0):
sys.stdout.write("\n")
if msg:
sys.stdout.write(msg + "\n\n")
@ -90,8 +97,12 @@ def main():
test(i, options.testsec)
print >> sys.stderr, ""
print >> sys.stderr, \
"elapsed time: %s" % (datetime.datetime.now() - start)
print >> sys.stderr, "elapsed time: %s" % (datetime.datetime.now() - start)
if __name__ == "__main__":
# configure nodes to use
node_map = nodemaps.CLASSIC_NODES
nodeutils.set_node_map(node_map)
main()

File diff suppressed because it is too large Load diff

View file

@ -8,11 +8,14 @@
# and repeat for minnodes <= n <= maxnodes with a step size of
# nodestep
import optparse, sys, os, datetime
import datetime
import optparse
import sys
from core import pycore
from core.misc import ipaddr
from core.misc import ipaddress, nodeutils, nodemaps
from core.misc.utils import mutecall
from core.netns import nodes
from core.session import Session
try:
mutecall(["iperf", "-v"])
@ -20,16 +23,17 @@ except OSError:
sys.stderr.write("ERROR: running iperf failed\n")
sys.exit(1)
def test(numnodes, testsec):
# node list
n = []
# IP subnet
prefix = ipaddr.IPv4Prefix("10.83.0.0/16")
session = pycore.Session()
prefix = ipaddress.Ipv4Prefix("10.83.0.0/16")
session = Session(1)
# emulated network
net = session.addobj(cls = pycore.nodes.WlanNode)
net = session.add_object(cls=nodes.WlanNode)
for i in xrange(1, numnodes + 1):
tmp = session.addobj(cls = pycore.nodes.LxcNode, objid= "%d" % i, name = "n%d" % i)
tmp = session.add_object(cls=nodes.LxcNode, objid="%d" % i, name="n%d" % i)
tmp.newnetif(net, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
n.append(tmp)
net.link(n[0].netif(0), n[-1].netif(0))
@ -38,31 +42,31 @@ def test(numnodes, testsec):
n[0].cmd(["killall", "-9", "iperf"])
session.shutdown()
def main():
usagestr = "usage: %prog [-h] [options] [args]"
parser = optparse.OptionParser(usage = usagestr)
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(minnodes = 2)
parser.add_option("-m", "--minnodes", dest = "minnodes", type = int,
help = "min number of nodes to test; default = %s" %
parser.defaults["minnodes"])
parser.set_defaults(minnodes=2)
parser.add_option("-m", "--minnodes", dest="minnodes", type=int,
help="min number of nodes to test; default = %s" % parser.defaults["minnodes"])
parser.set_defaults(maxnodes = 2)
parser.add_option("-n", "--maxnodes", dest = "maxnodes", type = int,
help = "max number of nodes to test; default = %s" %
parser.defaults["maxnodes"])
parser.set_defaults(maxnodes=2)
parser.add_option("-n", "--maxnodes", dest="maxnodes", type=int,
help="max number of nodes to test; default = %s" %
parser.defaults["maxnodes"])
parser.set_defaults(testsec = 10)
parser.add_option("-t", "--testsec", dest = "testsec", type = int,
help = "test time in seconds; default = %s" %
parser.defaults["testsec"])
parser.set_defaults(testsec=10)
parser.add_option("-t", "--testsec", dest="testsec", type=int,
help="test time in seconds; default = %s" %
parser.defaults["testsec"])
parser.set_defaults(nodestep = 1)
parser.add_option("-s", "--nodestep", dest = "nodestep", type = int,
help = "number of nodes step size; default = %s" %
parser.defaults["nodestep"])
parser.set_defaults(nodestep=1)
parser.add_option("-s", "--nodestep", dest="nodestep", type=int,
help="number of nodes step size; default = %s" %
parser.defaults["nodestep"])
def usage(msg = None, err = 0):
def usage(msg=None, err=0):
sys.stdout.write("\n")
if msg:
sys.stdout.write(msg + "\n\n")
@ -91,8 +95,12 @@ def main():
test(i, options.testsec)
print >> sys.stderr, ""
print >> sys.stderr, \
"elapsed time: %s" % (datetime.datetime.now() - start)
print >> sys.stderr, "elapsed time: %s" % (datetime.datetime.now() - start)
if __name__ == "__main__":
# configure nodes to use
node_map = nodemaps.CLASSIC_NODES
nodeutils.set_node_map(node_map)
main()