refactored some future naming to be more consistent, added new data objects to pass into coreemu api to help make scripting easier, set sessions to master by default now
This commit is contained in:
parent
1404ca19c5
commit
3ea885e2eb
9 changed files with 550 additions and 449 deletions
|
@ -9,8 +9,8 @@ from core.coreobj import PyCoreNode, PyCoreNet
|
||||||
from core.data import NodeData
|
from core.data import NodeData
|
||||||
from core.emane.nodes import EmaneNode
|
from core.emane.nodes import EmaneNode
|
||||||
from core.enumerations import NodeTypes, EventTypes, LinkTypes
|
from core.enumerations import NodeTypes, EventTypes, LinkTypes
|
||||||
|
from core.future.futuredata import InterfaceData, LinkOptions
|
||||||
from core.misc import nodeutils
|
from core.misc import nodeutils
|
||||||
from core.misc.ipaddress import Ipv4Prefix
|
|
||||||
from core.netns.nodes import CoreNode
|
from core.netns.nodes import CoreNode
|
||||||
from core.session import Session
|
from core.session import Session
|
||||||
from core.xml.xmlparser import core_document_parser
|
from core.xml.xmlparser import core_document_parser
|
||||||
|
@ -36,62 +36,13 @@ signal.signal(signal.SIGUSR1, signal_handler)
|
||||||
signal.signal(signal.SIGUSR2, signal_handler)
|
signal.signal(signal.SIGUSR2, signal_handler)
|
||||||
|
|
||||||
|
|
||||||
class InterfaceData(object):
|
|
||||||
"""
|
|
||||||
Convenience class for storing interface data.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, _id, name, mac, ip4, ip4_mask, ip6, ip6_mask):
|
|
||||||
"""
|
|
||||||
Creates an InterfaceData object.
|
|
||||||
|
|
||||||
:param int _id:
|
|
||||||
:param str name:
|
|
||||||
:param str mac:
|
|
||||||
:param str ip4:
|
|
||||||
:param int ip4_mask:
|
|
||||||
:param str ip6:
|
|
||||||
:param int ip6_mask:
|
|
||||||
"""
|
|
||||||
self.id = _id
|
|
||||||
self.name = name
|
|
||||||
self.mac = mac
|
|
||||||
self.ip4 = ip4
|
|
||||||
self.ip4_mask = ip4_mask
|
|
||||||
self.ip6 = ip6
|
|
||||||
self.ip6_mask = ip6_mask
|
|
||||||
|
|
||||||
def has_ip4(self):
|
|
||||||
return all([self.ip4, self.ip4_mask])
|
|
||||||
|
|
||||||
def has_ip6(self):
|
|
||||||
return all([self.ip6, self.ip6_mask])
|
|
||||||
|
|
||||||
def ip4_address(self):
|
|
||||||
if self.has_ip4():
|
|
||||||
return "%s/%s" % (self.ip4, self.ip4_mask)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def ip6_address(self):
|
|
||||||
if self.has_ip6():
|
|
||||||
return "%s/%s" % (self.ip6, self.ip6_mask)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_addresses(self):
|
|
||||||
ip4 = self.ip4_address()
|
|
||||||
ip6 = self.ip6_address()
|
|
||||||
return [i for i in [ip4, ip6] if i]
|
|
||||||
|
|
||||||
|
|
||||||
def get_interfaces(link_data):
|
def get_interfaces(link_data):
|
||||||
"""
|
"""
|
||||||
Creates interface data objects for the interfaces defined within link data.
|
Creates interface data objects for the interfaces defined within link data.
|
||||||
|
|
||||||
:param core.data.LinkData link_data: data to create interface data from
|
:param core.data.LinkData link_data: data to create interface data from
|
||||||
:return: interface one and two data
|
:return: interface one and two data
|
||||||
:rtype: tuple[InterfaceData]
|
:rtype: tuple[core.future.futuredata.InterfaceData]
|
||||||
"""
|
"""
|
||||||
interface_one = InterfaceData(
|
interface_one = InterfaceData(
|
||||||
_id=link_data.interface1_id,
|
_id=link_data.interface1_id,
|
||||||
|
@ -120,7 +71,7 @@ def create_interface(node, network, interface_data):
|
||||||
|
|
||||||
:param node: node to create interface for
|
:param node: node to create interface for
|
||||||
:param network: network to associate interface with
|
:param network: network to associate interface with
|
||||||
:param InterfaceData interface_data: interface data
|
:param core.future.futuredata.InterfaceData interface_data: interface data
|
||||||
:return: created interface
|
:return: created interface
|
||||||
"""
|
"""
|
||||||
node.newnetif(
|
node.newnetif(
|
||||||
|
@ -133,24 +84,24 @@ def create_interface(node, network, interface_data):
|
||||||
return node.netif(interface_data.id, network)
|
return node.netif(interface_data.id, network)
|
||||||
|
|
||||||
|
|
||||||
def link_config(network, interface, link_data, devname=None, interface_two=None):
|
def link_config(network, interface, link_options, devname=None, interface_two=None):
|
||||||
"""
|
"""
|
||||||
Convenience method for configuring a link,
|
Convenience method for configuring a link,
|
||||||
|
|
||||||
:param network: network to configure link for
|
:param network: network to configure link for
|
||||||
:param interface: interface to configure
|
:param interface: interface to configure
|
||||||
:param core.data.LinkData link_data: data to configure link with
|
:param core.future.futuredata.LinkOptions link_options: data to configure link with
|
||||||
:param str devname: device name, default is None
|
:param str devname: device name, default is None
|
||||||
:param interface_two: other interface associated, default is None
|
:param interface_two: other interface associated, default is None
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
config = {
|
config = {
|
||||||
"netif": interface,
|
"netif": interface,
|
||||||
"bw": link_data.bandwidth,
|
"bw": link_options.bandwidth,
|
||||||
"delay": link_data.delay,
|
"delay": link_options.delay,
|
||||||
"loss": link_data.per,
|
"loss": link_options.per,
|
||||||
"duplicate": link_data.dup,
|
"duplicate": link_options.dup,
|
||||||
"jitter": link_data.jitter,
|
"jitter": link_options.jitter,
|
||||||
"netif2": interface_two
|
"netif2": interface_two
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,12 +143,6 @@ class IdGen(object):
|
||||||
return self.id
|
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):
|
class FutureSession(Session):
|
||||||
def __init__(self, session_id, config=None, persistent=True, mkdir=True):
|
def __init__(self, session_id, config=None, persistent=True, mkdir=True):
|
||||||
super(FutureSession, self).__init__(session_id, config, persistent, mkdir)
|
super(FutureSession, self).__init__(session_id, config, persistent, mkdir)
|
||||||
|
@ -214,39 +159,37 @@ class FutureSession(Session):
|
||||||
"host": ("DefaultRoute", "SSH"),
|
"host": ("DefaultRoute", "SSH"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def link_nodes(self, link_data):
|
def _link_nodes(self, node_one_id, node_two_id):
|
||||||
"""
|
"""
|
||||||
Convenience method for retrieving nodes within link data.
|
Convenience method for retrieving nodes within link data.
|
||||||
|
|
||||||
:param core.data.LinkData link_data: data to retrieve nodes from
|
:param int node_one_id: node one id
|
||||||
:return: nodes, network nodes if presetn, and tunnel
|
:param int node_two_id: node two id
|
||||||
|
:return: nodes, network nodes if present, and tunnel if present
|
||||||
:rtype: tuple
|
:rtype: tuple
|
||||||
"""
|
"""
|
||||||
logger.info("link message between node1(%s:%s) and node2(%s:%s)",
|
logger.info("link message between node1(%s) and node2(%s)", node_one_id, node_two_id)
|
||||||
link_data.node1_id, link_data.interface1_id, link_data.node2_id, link_data.interface2_id)
|
|
||||||
|
|
||||||
# values to fill
|
# values to fill
|
||||||
net_one = None
|
net_one = None
|
||||||
net_two = None
|
net_two = None
|
||||||
|
|
||||||
# retrieve node one
|
# retrieve node one
|
||||||
n1_id = link_data.node1_id
|
node_one = self.get_object(node_one_id)
|
||||||
n2_id = link_data.node2_id
|
node_two = self.get_object(node_two_id)
|
||||||
node_one = self.get_object(n1_id)
|
|
||||||
node_two = self.get_object(n2_id)
|
|
||||||
|
|
||||||
# both node ids are provided
|
# both node ids are provided
|
||||||
tunnel = self.broker.gettunnel(n1_id, n2_id)
|
tunnel = self.broker.gettunnel(node_one_id, node_two_id)
|
||||||
logger.info("tunnel between nodes: %s", tunnel)
|
logger.info("tunnel between nodes: %s", tunnel)
|
||||||
if nodeutils.is_node(tunnel, NodeTypes.TAP_BRIDGE):
|
if nodeutils.is_node(tunnel, NodeTypes.TAP_BRIDGE):
|
||||||
net_one = tunnel
|
net_one = tunnel
|
||||||
if tunnel.remotenum == n1_id:
|
if tunnel.remotenum == node_one_id:
|
||||||
node_one = None
|
node_one = None
|
||||||
else:
|
else:
|
||||||
node_two = None
|
node_two = None
|
||||||
# physical node connected via gre tap tunnel
|
# physical node connected via gre tap tunnel
|
||||||
elif tunnel:
|
elif tunnel:
|
||||||
if tunnel.remotenum == n1_id:
|
if tunnel.remotenum == node_one_id:
|
||||||
node_one = None
|
node_one = None
|
||||||
else:
|
else:
|
||||||
node_two = None
|
node_two = None
|
||||||
|
@ -296,18 +239,19 @@ class FutureSession(Session):
|
||||||
else:
|
else:
|
||||||
raise ValueError("no common network found for wireless link/unlink")
|
raise ValueError("no common network found for wireless link/unlink")
|
||||||
|
|
||||||
def link_add(self, link_data):
|
def add_link(self, node_one_id, node_two_id, interface_one=None, interface_two=None, link_options=LinkOptions()):
|
||||||
"""
|
"""
|
||||||
Add a link between nodes.
|
Add a link between nodes.
|
||||||
|
|
||||||
:param core.data.LinkData link_data: data to create a link with
|
:param int node_one_id: node one id
|
||||||
:return: nothing
|
:param int node_two_id: node two id
|
||||||
|
:param core.future.futuredata.InterfaceData interface_one: node one interface data, defaults to none
|
||||||
|
:param core.future.futuredata.InterfaceData interface_two: node two interface data, defaults to none
|
||||||
|
:param core.future.futuredata.LinkOptions link_options: data for creating link, defaults to no options
|
||||||
|
:return:
|
||||||
"""
|
"""
|
||||||
# interface data
|
|
||||||
interface_one_data, interface_two_data = get_interfaces(link_data)
|
|
||||||
|
|
||||||
# get node objects identified by link data
|
# get node objects identified by link data
|
||||||
node_one, node_two, net_one, net_two, tunnel = self.link_nodes(link_data)
|
node_one, node_two, net_one, net_two, tunnel = self._link_nodes(node_one_id, node_two_id)
|
||||||
|
|
||||||
if node_one:
|
if node_one:
|
||||||
node_one.lock.acquire()
|
node_one.lock.acquire()
|
||||||
|
@ -316,7 +260,7 @@ class FutureSession(Session):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# wireless link
|
# wireless link
|
||||||
if link_data.link_type == LinkTypes.WIRELESS.value:
|
if link_options.type == LinkTypes.WIRELESS:
|
||||||
objects = [node_one, node_two, net_one, net_two]
|
objects = [node_one, node_two, net_one, net_two]
|
||||||
self._link_wireless(objects, connect=True)
|
self._link_wireless(objects, connect=True)
|
||||||
# wired link
|
# wired link
|
||||||
|
@ -329,14 +273,14 @@ class FutureSession(Session):
|
||||||
|
|
||||||
# node to network
|
# node to network
|
||||||
if node_one and net_one:
|
if node_one and net_one:
|
||||||
interface = create_interface(node_one, net_one, interface_one_data)
|
interface = create_interface(node_one, net_one, interface_one)
|
||||||
link_config(net_one, interface, link_data)
|
link_config(net_one, interface, link_options)
|
||||||
|
|
||||||
# network to node
|
# network to node
|
||||||
if node_two and net_one:
|
if node_two and net_one:
|
||||||
interface = create_interface(node_two, net_one, interface_two_data)
|
interface = create_interface(node_two, net_one, interface_two)
|
||||||
if not link_data.unidirectional:
|
if not link_options.unidirectional:
|
||||||
link_config(net_one, interface, link_data)
|
link_config(net_one, interface, link_options)
|
||||||
|
|
||||||
# network to network
|
# network to network
|
||||||
if net_one and net_two:
|
if net_one and net_two:
|
||||||
|
@ -345,23 +289,23 @@ class FutureSession(Session):
|
||||||
else:
|
else:
|
||||||
interface = net_one.linknet(net_two)
|
interface = net_one.linknet(net_two)
|
||||||
|
|
||||||
link_config(net_one, interface, link_data)
|
link_config(net_one, interface, link_options)
|
||||||
|
|
||||||
if not link_data.unidirectional:
|
if not link_options.unidirectional:
|
||||||
interface.swapparams("_params_up")
|
interface.swapparams("_params_up")
|
||||||
link_config(net_two, interface, link_data, devname=interface.name)
|
link_config(net_two, interface, link_options, devname=interface.name)
|
||||||
interface.swapparams("_params_up")
|
interface.swapparams("_params_up")
|
||||||
|
|
||||||
# a tunnel node was found for the nodes
|
# a tunnel node was found for the nodes
|
||||||
addresses = []
|
addresses = []
|
||||||
if not node_one and net_one:
|
if not node_one and all([net_one, interface_one]):
|
||||||
addresses.extend(interface_one_data.get_addresses())
|
addresses.extend(interface_one.get_addresses())
|
||||||
|
|
||||||
if not node_two and net_two:
|
if not node_two and all([net_two, interface_two]):
|
||||||
addresses.extend(interface_two_data.get_addresses())
|
addresses.extend(interface_two.get_addresses())
|
||||||
|
|
||||||
# tunnel node logic
|
# tunnel node logic
|
||||||
key = link_data.key
|
key = link_options.key
|
||||||
if key and nodeutils.is_node(net_one, NodeTypes.TUNNEL):
|
if key and nodeutils.is_node(net_one, NodeTypes.TUNNEL):
|
||||||
net_one.setkey(key)
|
net_one.setkey(key)
|
||||||
if addresses:
|
if addresses:
|
||||||
|
@ -374,31 +318,35 @@ class FutureSession(Session):
|
||||||
# physical node connected with tunnel
|
# physical node connected with tunnel
|
||||||
if not net_one and not net_two and (node_one or node_two):
|
if not net_one and not net_two and (node_one or node_two):
|
||||||
if node_one and nodeutils.is_node(node_one, NodeTypes.PHYSICAL):
|
if node_one and nodeutils.is_node(node_one, NodeTypes.PHYSICAL):
|
||||||
addresses = interface_one_data.get_addresses()
|
addresses = interface_one.get_addresses()
|
||||||
node_one.adoptnetif(tunnel, link_data.interface1_id, link_data.interface1_mac, addresses)
|
node_one.adoptnetif(tunnel, interface_one.id, interface_one.mac, addresses)
|
||||||
link_config(node_one, tunnel, link_data)
|
link_config(node_one, tunnel, link_options)
|
||||||
elif node_two and nodeutils.is_node(node_two, NodeTypes.PHYSICAL):
|
elif node_two and nodeutils.is_node(node_two, NodeTypes.PHYSICAL):
|
||||||
addresses = interface_two_data.get_addresses()
|
addresses = interface_two.get_addresses()
|
||||||
node_two.adoptnetif(tunnel, link_data.interface2_id, link_data.interface2_mac, addresses)
|
node_two.adoptnetif(tunnel, interface_two.id, interface_two.mac, addresses)
|
||||||
link_config(node_two, tunnel, link_data)
|
link_config(node_two, tunnel, link_options)
|
||||||
finally:
|
finally:
|
||||||
if node_one:
|
if node_one:
|
||||||
node_one.lock.release()
|
node_one.lock.release()
|
||||||
if node_two:
|
if node_two:
|
||||||
node_two.lock.release()
|
node_two.lock.release()
|
||||||
|
|
||||||
def link_delete(self, link_data):
|
def delete_link(self, node_one_id, node_two_id, interface_one_id, interface_two_id, link_type=LinkTypes.WIRED):
|
||||||
"""
|
"""
|
||||||
Delete a link between nodes.
|
Delete a link between nodes.
|
||||||
|
|
||||||
:param core.data.LinkData link_data: data to delete link with
|
:param int node_one_id: node one id
|
||||||
|
:param int node_two_id: node two id
|
||||||
|
:param int interface_one_id: interface id for node one
|
||||||
|
:param int interface_two_id: interface id for node two
|
||||||
|
:param core.enumerations.LinkTypes link_type: link type to delete
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
# interface data
|
# interface data
|
||||||
interface_one_data, interface_two_data = get_interfaces(link_data)
|
# interface_one_data, interface_two_data = get_interfaces(link_data)
|
||||||
|
|
||||||
# get node objects identified by link data
|
# get node objects identified by link data
|
||||||
node_one, node_two, net_one, net_two, tunnel = self.link_nodes(link_data)
|
node_one, node_two, net_one, net_two, tunnel = self._link_nodes(node_one_id, node_two_id)
|
||||||
|
|
||||||
if node_one:
|
if node_one:
|
||||||
node_one.lock.acquire()
|
node_one.lock.acquire()
|
||||||
|
@ -407,7 +355,7 @@ class FutureSession(Session):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# wireless link
|
# wireless link
|
||||||
if link_data.link_type == LinkTypes.WIRELESS.value:
|
if link_type == LinkTypes.WIRELESS:
|
||||||
objects = [node_one, node_two, net_one, net_two]
|
objects = [node_one, node_two, net_one, net_two]
|
||||||
self._link_wireless(objects, connect=False)
|
self._link_wireless(objects, connect=False)
|
||||||
# wired link
|
# wired link
|
||||||
|
@ -415,8 +363,8 @@ class FutureSession(Session):
|
||||||
if all([node_one, node_two]):
|
if all([node_one, node_two]):
|
||||||
# TODO: fix this for the case where ifindex[1,2] are not specified
|
# TODO: fix this for the case where ifindex[1,2] are not specified
|
||||||
# a wired unlink event, delete the connecting bridge
|
# a wired unlink event, delete the connecting bridge
|
||||||
interface_one = node_one.netif(interface_one_data.id)
|
interface_one = node_one.netif(interface_one_id)
|
||||||
interface_two = node_two.netif(interface_two_data.id)
|
interface_two = node_two.netif(interface_two_id)
|
||||||
|
|
||||||
# get interfaces from common network, if no network node
|
# get interfaces from common network, if no network node
|
||||||
# otherwise get interfaces between a node and network
|
# otherwise get interfaces between a node and network
|
||||||
|
@ -446,18 +394,22 @@ class FutureSession(Session):
|
||||||
if node_two:
|
if node_two:
|
||||||
node_two.lock.release()
|
node_two.lock.release()
|
||||||
|
|
||||||
def link_update(self, link_data):
|
def update_link(self, node_one_id, node_two_id, link_options, interface_one_id=None, interface_two_id=None):
|
||||||
"""
|
"""
|
||||||
Update link information between nodes.
|
Update link information between nodes.
|
||||||
|
|
||||||
:param core.data.LinkData link_data: data to update link with
|
:param int node_one_id: node one id
|
||||||
|
:param int node_two_id: node two id
|
||||||
|
:param int interface_one_id: interface id for node one
|
||||||
|
:param int interface_two_id: interface id for node two
|
||||||
|
:param core.future.futuredata.LinkOptions link_options: data to update link with
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
# interface data
|
# interface data
|
||||||
interface_one_data, interface_two_data = get_interfaces(link_data)
|
# interface_one_data, interface_two_data = get_interfaces(link_data)
|
||||||
|
|
||||||
# get node objects identified by link data
|
# get node objects identified by link data
|
||||||
node_one, node_two, net_one, net_two, tunnel = self.link_nodes(link_data)
|
node_one, node_two, net_one, net_two, tunnel = self._link_nodes(node_one_id, node_two_id)
|
||||||
|
|
||||||
if node_one:
|
if node_one:
|
||||||
node_one.lock.acquire()
|
node_one.lock.acquire()
|
||||||
|
@ -466,7 +418,7 @@ class FutureSession(Session):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# wireless link
|
# wireless link
|
||||||
if link_data.link_type == LinkTypes.WIRELESS.value:
|
if link_options.type == LinkTypes.WIRELESS.value:
|
||||||
raise ValueError("cannot update wireless link")
|
raise ValueError("cannot update wireless link")
|
||||||
else:
|
else:
|
||||||
if not node_one and not node_two:
|
if not node_one and not node_two:
|
||||||
|
@ -484,37 +436,37 @@ class FutureSession(Session):
|
||||||
|
|
||||||
if upstream:
|
if upstream:
|
||||||
interface.swapparams("_params_up")
|
interface.swapparams("_params_up")
|
||||||
link_config(net_one, interface, link_data, devname=interface.name)
|
link_config(net_one, interface, link_options, devname=interface.name)
|
||||||
interface.swapparams("_params_up")
|
interface.swapparams("_params_up")
|
||||||
else:
|
else:
|
||||||
link_config(net_one, interface, link_data)
|
link_config(net_one, interface, link_options)
|
||||||
|
|
||||||
if not link_data.unidirectional:
|
if not link_options.unidirectional:
|
||||||
if upstream:
|
if upstream:
|
||||||
link_config(net_two, interface, link_data)
|
link_config(net_two, interface, link_options)
|
||||||
else:
|
else:
|
||||||
interface.swapparams("_params_up")
|
interface.swapparams("_params_up")
|
||||||
link_config(net_two, interface, link_data, devname=interface.name)
|
link_config(net_two, interface, link_options, devname=interface.name)
|
||||||
interface.swapparams("_params_up")
|
interface.swapparams("_params_up")
|
||||||
else:
|
else:
|
||||||
raise ValueError("modify link for unknown nodes")
|
raise ValueError("modify link for unknown nodes")
|
||||||
elif not node_one:
|
elif not node_one:
|
||||||
# node1 = layer 2node, node2 = layer3 node
|
# node1 = layer 2node, node2 = layer3 node
|
||||||
interface = node_two.netif(interface_two_data.id, net_one)
|
interface = node_two.netif(interface_two_id, net_one)
|
||||||
link_config(net_one, interface, link_data)
|
link_config(net_one, interface, link_options)
|
||||||
elif not node_two:
|
elif not node_two:
|
||||||
# node2 = layer 2node, node1 = layer3 node
|
# node2 = layer 2node, node1 = layer3 node
|
||||||
interface = node_one.netif(interface_one_data.id, net_one)
|
interface = node_one.netif(interface_one_id, net_one)
|
||||||
link_config(net_one, interface, link_data)
|
link_config(net_one, interface, link_options)
|
||||||
else:
|
else:
|
||||||
common_networks = node_one.commonnets(node_two)
|
common_networks = node_one.commonnets(node_two)
|
||||||
for net_one, interface_one, interface_two in common_networks:
|
for net_one, interface_one, interface_two in common_networks:
|
||||||
if interface_one_data.id and interface_one_data.id != node_one.getifindex(interface_one):
|
if interface_one_id and interface_one_id != node_one.getifindex(interface_one):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
link_config(net_one, interface_one, link_data, interface_two=interface_two)
|
link_config(net_one, interface_one, link_options, interface_two=interface_two)
|
||||||
if not link_data.unidirectional:
|
if not link_options.unidirectional:
|
||||||
link_config(net_one, interface_two, link_data, interface_two=interface_one)
|
link_config(net_one, interface_two, link_options, interface_two=interface_one)
|
||||||
else:
|
else:
|
||||||
raise ValueError("no common network found")
|
raise ValueError("no common network found")
|
||||||
finally:
|
finally:
|
||||||
|
@ -523,30 +475,29 @@ class FutureSession(Session):
|
||||||
if node_two:
|
if node_two:
|
||||||
node_two.lock.release()
|
node_two.lock.release()
|
||||||
|
|
||||||
def node_add(self, node_data):
|
def add_node(self, node_options):
|
||||||
"""
|
"""
|
||||||
Add a node to the session, based on the provided node data.
|
Add a node to the session, based on the provided node data.
|
||||||
|
|
||||||
:param core.data.NodeData node_data: data to create node with
|
:param core.future.futuredata.NodeOptions node_options: data to create node with
|
||||||
:return: nothing
|
:return: created node
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# retrieve node class for given node type
|
# retrieve node class for given node type
|
||||||
try:
|
try:
|
||||||
node_type = NodeTypes(node_data.node_type)
|
node_class = nodeutils.get_node_class(node_options.type)
|
||||||
node_class = nodeutils.get_node_class(node_type)
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logger.error("invalid node type to create: %s", node_data.node_type)
|
logger.error("invalid node type to create: %s", node_options.type)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# set node start based on current session state, override and check when rj45
|
# set node start based on current session state, override and check when rj45
|
||||||
start = self.state > EventTypes.DEFINITION_STATE.value
|
start = self.state > EventTypes.DEFINITION_STATE.value
|
||||||
enable_rj45 = getattr(self.options, "enablerj45", "0") == "1"
|
enable_rj45 = getattr(self.options, "enablerj45", "0") == "1"
|
||||||
if node_type == NodeTypes.RJ45 and not enable_rj45:
|
if node_options.type == NodeTypes.RJ45 and not enable_rj45:
|
||||||
start = False
|
start = False
|
||||||
|
|
||||||
# determine node id
|
# determine node id
|
||||||
node_id = node_data.id
|
node_id = node_options.id
|
||||||
if not node_id:
|
if not node_id:
|
||||||
while True:
|
while True:
|
||||||
node_id = self.node_id_gen.next()
|
node_id = self.node_id_gen.next()
|
||||||
|
@ -554,7 +505,7 @@ class FutureSession(Session):
|
||||||
break
|
break
|
||||||
|
|
||||||
# generate name if not provided
|
# generate name if not provided
|
||||||
name = node_data.name
|
name = node_options.name
|
||||||
if not name:
|
if not name:
|
||||||
name = "%s%s" % (node_class.__name__, node_id)
|
name = "%s%s" % (node_class.__name__, node_id)
|
||||||
|
|
||||||
|
@ -563,18 +514,18 @@ class FutureSession(Session):
|
||||||
node = self.add_object(cls=node_class, objid=node_id, name=name, start=start)
|
node = self.add_object(cls=node_class, objid=node_id, name=name, start=start)
|
||||||
|
|
||||||
# set node attributes
|
# set node attributes
|
||||||
node.type = node_data.model or "router"
|
node.type = node_options.model or "router"
|
||||||
node.icon = node_data.icon
|
node.icon = node_options.icon
|
||||||
node.canvas = node_data.canvas
|
node.canvas = node_options.canvas
|
||||||
node.opaque = node_data.opaque
|
node.opaque = node_options.opaque
|
||||||
|
|
||||||
# set node position and broadcast it
|
# set node position and broadcast it
|
||||||
self.node_set_position(node, node_data)
|
self.set_node_position(node, node_options)
|
||||||
|
|
||||||
# add services to default and physical nodes only
|
# add services to default and physical nodes only
|
||||||
services = node_data.services
|
if node_options.type in [NodeTypes.DEFAULT, NodeTypes.PHYSICAL]:
|
||||||
if node_type in [NodeTypes.DEFAULT, NodeTypes.PHYSICAL]:
|
logger.info("setting model (%s) with services (%s)", node.type, node_options.services)
|
||||||
logger.info("setting model (%s) with services (%s)", node.type, services)
|
services = "|".join(node_options.services) or None
|
||||||
self.services.addservicestonode(node, node.type, services)
|
self.services.addservicestonode(node, node.type, services)
|
||||||
|
|
||||||
# boot nodes if created after runtime, LcxNodes, Physical, and RJ45 are all PyCoreNodes
|
# boot nodes if created after runtime, LcxNodes, Physical, and RJ45 are all PyCoreNodes
|
||||||
|
@ -586,35 +537,35 @@ class FutureSession(Session):
|
||||||
# TODO: common method to both Physical and LxcNodes, but not the common PyCoreNode
|
# TODO: common method to both Physical and LxcNodes, but not the common PyCoreNode
|
||||||
node.boot()
|
node.boot()
|
||||||
|
|
||||||
# return node id, in case it was generated
|
return node
|
||||||
return node_id
|
|
||||||
|
|
||||||
def node_update(self, node_data):
|
def update_node(self, node_options):
|
||||||
"""
|
"""
|
||||||
Update node information.
|
Update node information.
|
||||||
|
|
||||||
:param core.data.NodeData node_data: data to update node with
|
:param core.future.futuredata.NodeOptions node_options: data to update node with
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# get node to update
|
# get node to update
|
||||||
node = self.get_object(node_data.id)
|
node = self.get_object(node_options.id)
|
||||||
|
|
||||||
# set node position and broadcast it
|
# set node position and broadcast it
|
||||||
self.node_set_position(node, node_data)
|
self.set_node_position(node, node_options)
|
||||||
|
|
||||||
# update attributes
|
# update attributes
|
||||||
node.canvas = node_data.canvas
|
node.canvas = node_options.canvas
|
||||||
node.icon = node_data.icon
|
node.icon = node_options.icon
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logger.error("failure to update node that does not exist: %s", node_data.id)
|
logger.error("failure to update node that does not exist: %s", node_options.id)
|
||||||
|
|
||||||
def node_delete(self, node_id):
|
def delete_node(self, node_id):
|
||||||
"""
|
"""
|
||||||
Delete a node from the session and check if session should shutdown, if no nodes are left.
|
Delete a node from the session and check if session should shutdown, if no nodes are left.
|
||||||
|
|
||||||
:param int node_id:
|
:param int node_id:
|
||||||
:return: True if node deleted, False otherwise
|
:return: True if node deleted, False otherwise
|
||||||
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
# delete node and check for session shutdown if a node was removed
|
# delete node and check for session shutdown if a node was removed
|
||||||
result = self.custom_delete_object(node_id)
|
result = self.custom_delete_object(node_id)
|
||||||
|
@ -622,20 +573,20 @@ class FutureSession(Session):
|
||||||
self.check_shutdown()
|
self.check_shutdown()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def node_set_position(self, node, node_data):
|
def set_node_position(self, node, node_options):
|
||||||
"""
|
"""
|
||||||
Set position for a node, use lat/lon/alt if needed.
|
Set position for a node, use lat/lon/alt if needed.
|
||||||
|
|
||||||
:param node: node to set position for
|
:param node: node to set position for
|
||||||
:param NodeData node_data: data for node
|
:param core.future.futuredata.NodeOptions node_options: data for node
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
# extract location values
|
# extract location values
|
||||||
x = node_data.x_position
|
x = node_options.x
|
||||||
y = node_data.y_position
|
y = node_options.y
|
||||||
lat = node_data.latitude
|
lat = node_options.lat
|
||||||
lon = node_data.longitude
|
lon = node_options.lon
|
||||||
alt = node_data.altitude
|
alt = node_options.alt
|
||||||
|
|
||||||
# check if we need to generate position from lat/lon/alt
|
# check if we need to generate position from lat/lon/alt
|
||||||
has_empty_position = all(i is None for i in [x, y])
|
has_empty_position = all(i is None for i in [x, y])
|
||||||
|
@ -741,7 +692,7 @@ class FutureSession(Session):
|
||||||
doc = core_document_writer(self, version)
|
doc = core_document_writer(self, version)
|
||||||
doc.writexml(file_name)
|
doc.writexml(file_name)
|
||||||
|
|
||||||
def hook_add(self, state, file_name, source_name, data):
|
def add_hook(self, state, file_name, source_name, data):
|
||||||
"""
|
"""
|
||||||
Store a hook from a received file message.
|
Store a hook from a received file message.
|
||||||
|
|
||||||
|
@ -755,7 +706,7 @@ class FutureSession(Session):
|
||||||
state = ":%s" % state
|
state = ":%s" % state
|
||||||
self.set_hook(state, file_name, source_name, data)
|
self.set_hook(state, file_name, source_name, data)
|
||||||
|
|
||||||
def node_service_file(self, node_id, service_name, file_name, source_name, data):
|
def add_node_service_file(self, node_id, service_name, file_name, source_name, data):
|
||||||
"""
|
"""
|
||||||
Add a service file for a node.
|
Add a service file for a node.
|
||||||
|
|
||||||
|
@ -770,7 +721,7 @@ class FutureSession(Session):
|
||||||
service_name = ":%s" % service_name
|
service_name = ":%s" % service_name
|
||||||
self.services.setservicefile(node_id, service_name, file_name, source_name, data)
|
self.services.setservicefile(node_id, service_name, file_name, source_name, data)
|
||||||
|
|
||||||
def node_file(self, node_id, source_name, file_name, data):
|
def add_node_file(self, node_id, source_name, file_name, data):
|
||||||
"""
|
"""
|
||||||
Add a file to a node.
|
Add a file to a node.
|
||||||
|
|
||||||
|
@ -874,16 +825,16 @@ class FutureSession(Session):
|
||||||
self.set_emane_model(emane_network, model)
|
self.set_emane_model(emane_network, model)
|
||||||
return emane_network
|
return emane_network
|
||||||
|
|
||||||
def set_emane_model(self, emane_node, model):
|
def set_emane_model(self, emane_node, emane_model):
|
||||||
"""
|
"""
|
||||||
Set emane model for a given emane node.
|
Set emane model for a given emane node.
|
||||||
|
|
||||||
:param emane_node: emane node to set model for
|
:param emane_node: emane node to set model for
|
||||||
:param model: emane model to set
|
:param emane_model: emane model to set
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
values = list(model.getdefaultvalues())
|
values = list(emane_model.getdefaultvalues())
|
||||||
self.emane.setconfig(emane_node.objid, model.name, values)
|
self.emane.setconfig(emane_node.objid, emane_model.name, values)
|
||||||
|
|
||||||
|
|
||||||
class CoreEmu(object):
|
class CoreEmu(object):
|
||||||
|
@ -921,7 +872,7 @@ class CoreEmu(object):
|
||||||
session.shutdown()
|
session.shutdown()
|
||||||
self.sessions.clear()
|
self.sessions.clear()
|
||||||
|
|
||||||
def create_session(self, _id=None, master=False):
|
def create_session(self, _id=None, master=True):
|
||||||
"""
|
"""
|
||||||
Create a new CORE session, set to master if running standalone.
|
Create a new CORE session, set to master if running standalone.
|
||||||
|
|
||||||
|
@ -981,15 +932,16 @@ class CoreEmu(object):
|
||||||
for common_network, interface_one, interface_two in node.commonnets(network):
|
for common_network, interface_one, interface_two in node.commonnets(network):
|
||||||
common_network.link(interface_one, interface_two)
|
common_network.link(interface_one, interface_two)
|
||||||
|
|
||||||
def add_interface(self, network, node, prefix):
|
def add_interface(self, network, node, prefixes):
|
||||||
"""
|
"""
|
||||||
Convenience method for adding an interface with a prefix based on node id.
|
Convenience method for adding an interface with a prefix based on node id.
|
||||||
|
|
||||||
:param network: network to add interface with
|
:param network: network to add interface with
|
||||||
:param node: node to add interface to
|
:param node: node to add interface to
|
||||||
:param prefix: prefix to get address from for interface
|
:param core.future.futuredata.IpPrefixes prefixes: to get address from for interface
|
||||||
:return: created interface
|
:return: created interface
|
||||||
"""
|
"""
|
||||||
address = prefix.get_address(node.objid)
|
interface_data = prefixes.create_interface(node)
|
||||||
interface_index = node.newnetif(network, [address])
|
logger.info("adding interface: %s", interface_data.get_addresses())
|
||||||
|
interface_index = node.newnetif(network, interface_data.get_addresses(), ifindex=interface_data.id)
|
||||||
return node.netif(interface_index)
|
return node.netif(interface_index)
|
||||||
|
|
225
daemon/core/future/futuredata.py
Normal file
225
daemon/core/future/futuredata.py
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
from core.enumerations import LinkTypes
|
||||||
|
from core.misc.ipaddress import Ipv4Prefix, Ipv6Prefix, MacAddress
|
||||||
|
|
||||||
|
|
||||||
|
class NodeOptions(object):
|
||||||
|
"""
|
||||||
|
Options for creating and updating nodes within core.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, _type=None, _id=None, name=None, model=None):
|
||||||
|
"""
|
||||||
|
Create a NodeOptions object.
|
||||||
|
|
||||||
|
:param core.enumerations.NodeType _type: type of node to create
|
||||||
|
:param int _id: id for node being created, defaults to generated id
|
||||||
|
:param str name: name of node, defaults to node class name postfix with its id
|
||||||
|
:param str model: model to use for this node, defines services
|
||||||
|
"""
|
||||||
|
self.id = _id
|
||||||
|
self.name = name
|
||||||
|
self.type = _type
|
||||||
|
self.model = model
|
||||||
|
self.canvas = None
|
||||||
|
self.icon = None
|
||||||
|
self.opaque = None
|
||||||
|
self.services = []
|
||||||
|
self.x = None
|
||||||
|
self.y = None
|
||||||
|
self.lat = None
|
||||||
|
self.lon = None
|
||||||
|
self.alt = None
|
||||||
|
self.emulation_id = None
|
||||||
|
self.emulation_server = None
|
||||||
|
|
||||||
|
def set_position(self, x, y):
|
||||||
|
"""
|
||||||
|
Convenience method for setting position.
|
||||||
|
|
||||||
|
:param int x: x position
|
||||||
|
:param int y: y position
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
|
||||||
|
def set_location(self, lat, lon, alt):
|
||||||
|
"""
|
||||||
|
Convenience method for setting location.
|
||||||
|
|
||||||
|
:param float lat: latitude
|
||||||
|
:param float lon: longitude
|
||||||
|
:param float alt: altitude
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
self.lat = lat
|
||||||
|
self.lon = lon
|
||||||
|
self.alt = alt
|
||||||
|
|
||||||
|
|
||||||
|
class LinkOptions(object):
|
||||||
|
"""
|
||||||
|
Options for creating and updating links within core.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, _type=LinkTypes.WIRED):
|
||||||
|
"""
|
||||||
|
Create a LinkOptions object.
|
||||||
|
|
||||||
|
:param core.enumerations.LinkTypes _type: type of link, defaults to wired
|
||||||
|
"""
|
||||||
|
self.type = _type
|
||||||
|
self.session = None
|
||||||
|
self.delay = None
|
||||||
|
self.bandwidth = None
|
||||||
|
self.per = None
|
||||||
|
self.dup = None
|
||||||
|
self.jitter = None
|
||||||
|
self.mer = None
|
||||||
|
self.burst = None
|
||||||
|
self.mburst = None
|
||||||
|
self.gui_attributes = None
|
||||||
|
self.unidirectional = None
|
||||||
|
self.emulation_id = None
|
||||||
|
self.network_id = None
|
||||||
|
self.key = None
|
||||||
|
self.opaque = None
|
||||||
|
|
||||||
|
|
||||||
|
class IpPrefixes(object):
|
||||||
|
"""
|
||||||
|
Convenience class to help generate IP4 and IP6 addresses for nodes within CORE.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, ip4_prefix=None, ip6_prefix=None):
|
||||||
|
"""
|
||||||
|
Creates an IpPrefixes object.
|
||||||
|
|
||||||
|
:param str ip4_prefix: ip4 prefix to use for generation
|
||||||
|
:param str ip6_prefix: ip6 prefix to use for generation
|
||||||
|
:raises ValueError: when both ip4 and ip6 prefixes have not been provided
|
||||||
|
"""
|
||||||
|
if not ip4_prefix and not ip6_prefix:
|
||||||
|
raise ValueError("ip4 or ip6 must be provided")
|
||||||
|
|
||||||
|
self.ip4 = None
|
||||||
|
if ip4_prefix:
|
||||||
|
self.ip4 = Ipv4Prefix(ip4_prefix)
|
||||||
|
self.ip6 = None
|
||||||
|
if ip6_prefix:
|
||||||
|
self.ip6 = Ipv6Prefix(ip6_prefix)
|
||||||
|
|
||||||
|
def ip4_address(self, node):
|
||||||
|
"""
|
||||||
|
Convenience method to return the IP4 address for a node.
|
||||||
|
|
||||||
|
:param node: node to get IP4 address for
|
||||||
|
:return: IP4 address or None
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
if not self.ip4:
|
||||||
|
raise ValueError("ip4 prefixes have not been set")
|
||||||
|
return str(self.ip4.addr(node.objid))
|
||||||
|
|
||||||
|
def ip6_address(self, node):
|
||||||
|
"""
|
||||||
|
Convenience method to return the IP6 address for a node.
|
||||||
|
|
||||||
|
:param node: node to get IP6 address for
|
||||||
|
:return: IP4 address or None
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
if not self.ip6:
|
||||||
|
raise ValueError("ip6 prefixes have not been set")
|
||||||
|
return str(self.ip6.addr(node.objid))
|
||||||
|
|
||||||
|
def create_interface(self, node, name=None, mac=None):
|
||||||
|
"""
|
||||||
|
Creates interface data for linking nodes, using the nodes unique id for generation, along with a random
|
||||||
|
mac address, unless provided.
|
||||||
|
|
||||||
|
:param core.coreobj.PyCoreNode node: node to create interface for
|
||||||
|
:param str name: name to set for interface, default is eth{id}
|
||||||
|
:param str mac: mac address to use for this interface, default is random generation
|
||||||
|
:return: new interface data for the provided node
|
||||||
|
:rtype: InterfaceData
|
||||||
|
"""
|
||||||
|
# interface id
|
||||||
|
inteface_id = node.newifindex()
|
||||||
|
|
||||||
|
# generate ip4 data
|
||||||
|
ip4 = None
|
||||||
|
ip4_mask = None
|
||||||
|
if self.ip4:
|
||||||
|
ip4 = str(self.ip4.addr(node.objid))
|
||||||
|
ip4_mask = self.ip4.prefixlen
|
||||||
|
|
||||||
|
# generate ip6 data
|
||||||
|
ip6 = None
|
||||||
|
ip6_mask = None
|
||||||
|
if self.ip6:
|
||||||
|
ip6 = str(self.ip6.addr(node.objid))
|
||||||
|
ip6_mask = self.ip6.prefixlen
|
||||||
|
|
||||||
|
# random mac
|
||||||
|
if not mac:
|
||||||
|
mac = str(MacAddress.random())
|
||||||
|
|
||||||
|
return InterfaceData(
|
||||||
|
_id=inteface_id,
|
||||||
|
name=name,
|
||||||
|
ip4=ip4,
|
||||||
|
ip4_mask=ip4_mask,
|
||||||
|
ip6=ip6,
|
||||||
|
ip6_mask=ip6_mask,
|
||||||
|
mac=mac
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class InterfaceData(object):
|
||||||
|
"""
|
||||||
|
Convenience class for storing interface data.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, _id, name, mac, ip4, ip4_mask, ip6, ip6_mask):
|
||||||
|
"""
|
||||||
|
Creates an InterfaceData object.
|
||||||
|
|
||||||
|
:param int _id:
|
||||||
|
:param str name:
|
||||||
|
:param str mac:
|
||||||
|
:param str ip4:
|
||||||
|
:param int ip4_mask:
|
||||||
|
:param str ip6:
|
||||||
|
:param int ip6_mask:
|
||||||
|
"""
|
||||||
|
self.id = _id
|
||||||
|
self.name = name
|
||||||
|
self.mac = mac
|
||||||
|
self.ip4 = ip4
|
||||||
|
self.ip4_mask = ip4_mask
|
||||||
|
self.ip6 = ip6
|
||||||
|
self.ip6_mask = ip6_mask
|
||||||
|
|
||||||
|
def has_ip4(self):
|
||||||
|
return all([self.ip4, self.ip4_mask])
|
||||||
|
|
||||||
|
def has_ip6(self):
|
||||||
|
return all([self.ip6, self.ip6_mask])
|
||||||
|
|
||||||
|
def ip4_address(self):
|
||||||
|
if self.has_ip4():
|
||||||
|
return "%s/%s" % (self.ip4, self.ip4_mask)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def ip6_address(self):
|
||||||
|
if self.has_ip6():
|
||||||
|
return "%s/%s" % (self.ip6, self.ip6_mask)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_addresses(self):
|
||||||
|
ip4 = self.ip4_address()
|
||||||
|
ip6 = self.ip6_address()
|
||||||
|
return [i for i in [ip4, ip6] if i]
|
|
@ -14,10 +14,9 @@ import time
|
||||||
from core import logger
|
from core import logger
|
||||||
from core.api import coreapi
|
from core.api import coreapi
|
||||||
from core.coreserver import CoreServer
|
from core.coreserver import CoreServer
|
||||||
from core.data import ConfigData, LinkData
|
from core.data import ConfigData
|
||||||
from core.data import EventData
|
from core.data import EventData
|
||||||
from core.data import NodeData
|
from core.enumerations import ConfigTlvs, LinkTypes
|
||||||
from core.enumerations import ConfigTlvs
|
|
||||||
from core.enumerations import EventTlvs
|
from core.enumerations import EventTlvs
|
||||||
from core.enumerations import EventTypes
|
from core.enumerations import EventTypes
|
||||||
from core.enumerations import ExceptionTlvs
|
from core.enumerations import ExceptionTlvs
|
||||||
|
@ -30,6 +29,7 @@ from core.enumerations import NodeTlvs
|
||||||
from core.enumerations import NodeTypes
|
from core.enumerations import NodeTypes
|
||||||
from core.enumerations import RegisterTlvs
|
from core.enumerations import RegisterTlvs
|
||||||
from core.enumerations import SessionTlvs
|
from core.enumerations import SessionTlvs
|
||||||
|
from core.future.futuredata import NodeOptions, LinkOptions, InterfaceData
|
||||||
from core.misc import nodeutils
|
from core.misc import nodeutils
|
||||||
from core.misc import structutils
|
from core.misc import structutils
|
||||||
from core.misc import utils
|
from core.misc import utils
|
||||||
|
@ -566,7 +566,7 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
||||||
port = self.request.getpeername()[1]
|
port = self.request.getpeername()[1]
|
||||||
|
|
||||||
# TODO: add shutdown handler for session
|
# TODO: add shutdown handler for session
|
||||||
self.session = self.coreemu.create_session(port)
|
self.session = self.coreemu.create_session(port, master=False)
|
||||||
# self.session.shutdown_handlers.append(self.session_shutdown)
|
# self.session.shutdown_handlers.append(self.session_shutdown)
|
||||||
logger.info("created new session for client: %s", self.session.session_id)
|
logger.info("created new session for client: %s", self.session.session_id)
|
||||||
|
|
||||||
|
@ -642,44 +642,58 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
||||||
logger.warn("ignoring invalid message: add and delete flag both set")
|
logger.warn("ignoring invalid message: add and delete flag both set")
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
# create node data from message data
|
node_type = None
|
||||||
node_data = NodeData(
|
node_type_value = message.get_tlv(NodeTlvs.TYPE.value)
|
||||||
id=message.get_tlv(NodeTlvs.NUMBER.value),
|
if node_type_value is not None:
|
||||||
x_position=message.get_tlv(NodeTlvs.X_POSITION.value),
|
node_type = NodeTypes(node_type_value)
|
||||||
y_position=message.get_tlv(NodeTlvs.Y_POSITION.value),
|
|
||||||
canvas=message.get_tlv(NodeTlvs.CANVAS.value),
|
node_options = NodeOptions(
|
||||||
icon=message.get_tlv(NodeTlvs.ICON.value),
|
_type=node_type,
|
||||||
latitude=message.get_tlv(NodeTlvs.LATITUDE.value),
|
_id=message.get_tlv(NodeTlvs.NUMBER.value),
|
||||||
longitude=message.get_tlv(NodeTlvs.LONGITUDE.value),
|
|
||||||
altitude=message.get_tlv(NodeTlvs.ALTITUDE.value),
|
|
||||||
node_type=message.get_tlv(NodeTlvs.TYPE.value),
|
|
||||||
name=message.get_tlv(NodeTlvs.NAME.value),
|
name=message.get_tlv(NodeTlvs.NAME.value),
|
||||||
model=message.get_tlv(NodeTlvs.MODEL.value),
|
model=message.get_tlv(NodeTlvs.MODEL.value)
|
||||||
opaque=message.get_tlv(NodeTlvs.OPAQUE.value),
|
|
||||||
services=message.get_tlv(NodeTlvs.SERVICES.value),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
node_options.set_position(
|
||||||
|
x=message.get_tlv(NodeTlvs.X_POSITION.value),
|
||||||
|
y=message.get_tlv(NodeTlvs.Y_POSITION.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
node_options.set_location(
|
||||||
|
lat=message.get_tlv(NodeTlvs.LATITUDE.value),
|
||||||
|
lon=message.get_tlv(NodeTlvs.LONGITUDE.value),
|
||||||
|
alt=message.get_tlv(NodeTlvs.ALTITUDE.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
node_options.icon = message.get_tlv(NodeTlvs.ICON.value)
|
||||||
|
node_options.canvas = message.get_tlv(NodeTlvs.CANVAS.value)
|
||||||
|
node_options.opaque = message.get_tlv(NodeTlvs.OPAQUE.value)
|
||||||
|
|
||||||
|
services = message.get_tlv(NodeTlvs.SERVICES.value)
|
||||||
|
if services:
|
||||||
|
node_options.services = services.split("|")
|
||||||
|
|
||||||
if message.flags & MessageFlags.ADD.value:
|
if message.flags & MessageFlags.ADD.value:
|
||||||
node_id = self.session.node_add(node_data)
|
node = self.session.add_node(node_options)
|
||||||
if node_id:
|
if node:
|
||||||
if message.flags & MessageFlags.STRING.value:
|
if message.flags & MessageFlags.STRING.value:
|
||||||
self.node_status_request[node_id] = True
|
self.node_status_request[node.objid] = True
|
||||||
|
|
||||||
if self.session.state == EventTypes.RUNTIME_STATE.value:
|
if self.session.state == EventTypes.RUNTIME_STATE.value:
|
||||||
self.send_node_emulation_id(node_id)
|
self.send_node_emulation_id(node.objid)
|
||||||
elif message.flags & MessageFlags.DELETE.value:
|
elif message.flags & MessageFlags.DELETE.value:
|
||||||
with self._shutdown_lock:
|
with self._shutdown_lock:
|
||||||
result = self.session.node_delete(node_data.id)
|
result = self.session.delete_node(node_options.id)
|
||||||
|
|
||||||
# if we deleted a node broadcast out its removal
|
# if we deleted a node broadcast out its removal
|
||||||
if result and message.flags & MessageFlags.STRING.value:
|
if result and message.flags & MessageFlags.STRING.value:
|
||||||
tlvdata = ""
|
tlvdata = ""
|
||||||
tlvdata += coreapi.CoreNodeTlv.pack(NodeTlvs.NUMBER.value, node_data.id)
|
tlvdata += coreapi.CoreNodeTlv.pack(NodeTlvs.NUMBER.value, node_options.id)
|
||||||
flags = MessageFlags.DELETE.value | MessageFlags.LOCAL.value
|
flags = MessageFlags.DELETE.value | MessageFlags.LOCAL.value
|
||||||
replies.append(coreapi.CoreNodeMessage.pack(flags, tlvdata))
|
replies.append(coreapi.CoreNodeMessage.pack(flags, tlvdata))
|
||||||
# node update
|
# node update
|
||||||
else:
|
else:
|
||||||
self.session.node_update(node_data)
|
self.session.update_node(node_options)
|
||||||
|
|
||||||
return replies
|
return replies
|
||||||
|
|
||||||
|
@ -690,47 +704,56 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
||||||
:param coreapi.CoreLinkMessage message: link message to handle
|
:param coreapi.CoreLinkMessage message: link message to handle
|
||||||
:return: link message replies
|
:return: link message replies
|
||||||
"""
|
"""
|
||||||
link_data = LinkData(
|
node_one_id = message.get_tlv(LinkTlvs.N1_NUMBER.value)
|
||||||
session=message.get_tlv(LinkTlvs.SESSION.value),
|
node_two_id = message.get_tlv(LinkTlvs.N2_NUMBER.value)
|
||||||
link_type=message.get_tlv(LinkTlvs.TYPE.value),
|
|
||||||
node1_id=message.get_tlv(LinkTlvs.N1_NUMBER.value),
|
interface_one = InterfaceData(
|
||||||
node2_id=message.get_tlv(LinkTlvs.N2_NUMBER.value),
|
_id=message.get_tlv(LinkTlvs.INTERFACE1_NUMBER.value),
|
||||||
delay=message.get_tlv(LinkTlvs.DELAY.value),
|
name=message.get_tlv(LinkTlvs.INTERFACE1_NAME.value),
|
||||||
bandwidth=message.get_tlv(LinkTlvs.BANDWIDTH.value),
|
mac=message.get_tlv(LinkTlvs.INTERFACE1_MAC.value),
|
||||||
per=message.get_tlv(LinkTlvs.PER.value),
|
ip4=message.get_tlv(LinkTlvs.INTERFACE1_IP4.value),
|
||||||
dup=message.get_tlv(LinkTlvs.DUP.value),
|
ip4_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP4_MASK.value),
|
||||||
jitter=message.get_tlv(LinkTlvs.JITTER.value),
|
ip6=message.get_tlv(LinkTlvs.INTERFACE1_IP6.value),
|
||||||
mer=message.get_tlv(LinkTlvs.MER.value),
|
ip6_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP6_MASK.value),
|
||||||
burst=message.get_tlv(LinkTlvs.BURST.value),
|
)
|
||||||
mburst=message.get_tlv(LinkTlvs.MBURST.value),
|
interface_two = InterfaceData(
|
||||||
gui_attributes=message.get_tlv(LinkTlvs.GUI_ATTRIBUTES.value),
|
_id=message.get_tlv(LinkTlvs.INTERFACE2_NUMBER.value),
|
||||||
unidirectional=message.get_tlv(LinkTlvs.UNIDIRECTIONAL.value),
|
name=message.get_tlv(LinkTlvs.INTERFACE2_NAME.value),
|
||||||
emulation_id=message.get_tlv(LinkTlvs.EMULATION_ID.value),
|
mac=message.get_tlv(LinkTlvs.INTERFACE2_MAC.value),
|
||||||
network_id=message.get_tlv(LinkTlvs.NETWORK_ID.value),
|
ip4=message.get_tlv(LinkTlvs.INTERFACE2_IP4.value),
|
||||||
key=message.get_tlv(LinkTlvs.KEY.value),
|
ip4_mask=message.get_tlv(LinkTlvs.INTERFACE2_IP4_MASK.value),
|
||||||
opaque=message.get_tlv(LinkTlvs.OPAQUE.value),
|
ip6=message.get_tlv(LinkTlvs.INTERFACE2_IP6.value),
|
||||||
interface1_id=message.get_tlv(LinkTlvs.INTERFACE1_NUMBER.value),
|
ip6_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP6_MASK.value),
|
||||||
interface1_name=message.get_tlv(LinkTlvs.INTERFACE1_NAME.value),
|
|
||||||
interface1_ip4=message.get_tlv(LinkTlvs.INTERFACE1_IP4.value),
|
|
||||||
interface1_ip4_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP4_MASK.value),
|
|
||||||
interface1_mac=message.get_tlv(LinkTlvs.INTERFACE1_MAC.value),
|
|
||||||
interface1_ip6=message.get_tlv(LinkTlvs.INTERFACE1_IP6.value),
|
|
||||||
interface1_ip6_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP6_MASK.value),
|
|
||||||
interface2_id=message.get_tlv(LinkTlvs.INTERFACE2_NUMBER.value),
|
|
||||||
interface2_name=message.get_tlv(LinkTlvs.INTERFACE2_NAME.value),
|
|
||||||
interface2_ip4=message.get_tlv(LinkTlvs.INTERFACE2_IP4.value),
|
|
||||||
interface2_ip4_mask=message.get_tlv(LinkTlvs.INTERFACE2_IP4_MASK.value),
|
|
||||||
interface2_mac=message.get_tlv(LinkTlvs.INTERFACE2_MAC.value),
|
|
||||||
interface2_ip6=message.get_tlv(LinkTlvs.INTERFACE2_IP6.value),
|
|
||||||
interface2_ip6_mask=message.get_tlv(LinkTlvs.INTERFACE2_IP6_MASK.value),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
link_type = None
|
||||||
|
link_type_value = message.get_tlv(LinkTlvs.TYPE.value)
|
||||||
|
if link_type_value is not None:
|
||||||
|
link_type = LinkTypes(link_type_value)
|
||||||
|
|
||||||
|
link_options = LinkOptions(_type=link_type)
|
||||||
|
link_options.delay = message.get_tlv(LinkTlvs.DELAY.value)
|
||||||
|
link_options.bandwidth = message.get_tlv(LinkTlvs.BANDWIDTH.value)
|
||||||
|
link_options.session = message.get_tlv(LinkTlvs.SESSION.value)
|
||||||
|
link_options.per = message.get_tlv(LinkTlvs.PER.value)
|
||||||
|
link_options.dup = message.get_tlv(LinkTlvs.DUP.value)
|
||||||
|
link_options.jitter = message.get_tlv(LinkTlvs.JITTER.value)
|
||||||
|
link_options.mer = message.get_tlv(LinkTlvs.MER.value)
|
||||||
|
link_options.burst = message.get_tlv(LinkTlvs.BURST.value)
|
||||||
|
link_options.mburst = message.get_tlv(LinkTlvs.MBURST.value)
|
||||||
|
link_options.gui_attributes = message.get_tlv(LinkTlvs.GUI_ATTRIBUTES.value)
|
||||||
|
link_options.unidirectional = message.get_tlv(LinkTlvs.UNIDIRECTIONAL.value)
|
||||||
|
link_options.emulation_id = message.get_tlv(LinkTlvs.EMULATION_ID.value)
|
||||||
|
link_options.network_id = message.get_tlv(LinkTlvs.NETWORK_ID.value)
|
||||||
|
link_options.key = message.get_tlv(LinkTlvs.KEY.value)
|
||||||
|
link_options.opaque = message.get_tlv(LinkTlvs.OPAQUE.value)
|
||||||
|
|
||||||
if message.flags & MessageFlags.ADD.value:
|
if message.flags & MessageFlags.ADD.value:
|
||||||
self.session.link_add(link_data)
|
self.session.add_link(node_one_id, node_two_id, interface_one, interface_two, link_options)
|
||||||
elif message.flags & MessageFlags.DELETE.value:
|
elif message.flags & MessageFlags.DELETE.value:
|
||||||
self.session.link_delete(link_data)
|
self.session.delete_link(node_one_id, node_two_id, interface_one.id, interface_two.id)
|
||||||
else:
|
else:
|
||||||
self.session.link_update(link_data)
|
self.session.update_link(node_one_id, node_two_id, interface_one.id, interface_two.id, link_options)
|
||||||
|
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
@ -829,7 +852,7 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
||||||
file_name = sys.argv[0]
|
file_name = sys.argv[0]
|
||||||
|
|
||||||
if os.path.splitext(file_name)[1].lower() == ".xml":
|
if os.path.splitext(file_name)[1].lower() == ".xml":
|
||||||
session = self.coreemu.create_session()
|
session = self.coreemu.create_session(master=False)
|
||||||
try:
|
try:
|
||||||
session.open_xml(file_name, start=True)
|
session.open_xml(file_name, start=True)
|
||||||
except:
|
except:
|
||||||
|
@ -962,7 +985,7 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
||||||
if file_type is not None:
|
if file_type is not None:
|
||||||
if file_type.startswith("service:"):
|
if file_type.startswith("service:"):
|
||||||
_, service_name = file_type.split(':')[:2]
|
_, service_name = file_type.split(':')[:2]
|
||||||
self.session.node_service_file(node_num, service_name, file_name, source_name, data)
|
self.session.add_node_service_file(node_num, service_name, file_name, source_name, data)
|
||||||
return ()
|
return ()
|
||||||
elif file_type.startswith("hook:"):
|
elif file_type.startswith("hook:"):
|
||||||
_, state = file_type.split(':')[:2]
|
_, state = file_type.split(':')[:2]
|
||||||
|
@ -970,7 +993,7 @@ class FutureHandler(SocketServer.BaseRequestHandler):
|
||||||
logger.error("error setting hook having state '%s'", state)
|
logger.error("error setting hook having state '%s'", state)
|
||||||
return ()
|
return ()
|
||||||
state = int(state)
|
state = int(state)
|
||||||
self.session.hook_add(state, file_name, source_name, data)
|
self.session.add_hook(state, file_name, source_name, data)
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
# writing a file to the host
|
# writing a file to the host
|
||||||
|
|
|
@ -6,12 +6,13 @@ import datetime
|
||||||
|
|
||||||
import parser
|
import parser
|
||||||
from core.emane.ieee80211abg import EmaneIeee80211abgModel
|
from core.emane.ieee80211abg import EmaneIeee80211abgModel
|
||||||
from core.future.coreemu import FutureIpv4Prefix, CoreEmu
|
from core.future.coreemu import CoreEmu
|
||||||
|
from core.future.futuredata import IpPrefixes
|
||||||
|
|
||||||
|
|
||||||
def example(options):
|
def example(options):
|
||||||
# ip generator for example
|
# ip generator for example
|
||||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||||
|
|
||||||
# create emulator instance for creating sessions and utility methods
|
# create emulator instance for creating sessions and utility methods
|
||||||
coreemu = CoreEmu()
|
coreemu = CoreEmu()
|
||||||
|
@ -27,8 +28,8 @@ def example(options):
|
||||||
# create nodes
|
# create nodes
|
||||||
for i in xrange(options.nodes):
|
for i in xrange(options.nodes):
|
||||||
node = session.create_emane_node()
|
node = session.create_emane_node()
|
||||||
coreemu.add_interface(emane_network, node, prefix)
|
|
||||||
node.setposition(x=150 * (i + 1), y=150)
|
node.setposition(x=150 * (i + 1), y=150)
|
||||||
|
coreemu.add_interface(emane_network, node, prefixes)
|
||||||
|
|
||||||
# instantiate session
|
# instantiate session
|
||||||
session.instantiate()
|
session.instantiate()
|
||||||
|
@ -39,7 +40,7 @@ def example(options):
|
||||||
|
|
||||||
# shutdown session
|
# shutdown session
|
||||||
raw_input("press enter to exit...")
|
raw_input("press enter to exit...")
|
||||||
session.shutdown()
|
coreemu.shutdown()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -8,13 +8,14 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
import parser
|
import parser
|
||||||
from core.future.coreemu import FutureIpv4Prefix, CoreEmu
|
from core.future.coreemu import CoreEmu
|
||||||
|
from core.future.futuredata import IpPrefixes
|
||||||
from core.netns.nodes import CoreNode, SwitchNode
|
from core.netns.nodes import CoreNode, SwitchNode
|
||||||
|
|
||||||
|
|
||||||
def example(options):
|
def example(options):
|
||||||
# ip generator for example
|
# ip generator for example
|
||||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
prefixes = IpPrefixes("10.83.0.0/16")
|
||||||
|
|
||||||
# create emulator instance for creating sessions and utility methods
|
# create emulator instance for creating sessions and utility methods
|
||||||
coreemu = CoreEmu()
|
coreemu = CoreEmu()
|
||||||
|
@ -26,7 +27,7 @@ def example(options):
|
||||||
# create nodes
|
# create nodes
|
||||||
for _ in xrange(options.nodes):
|
for _ in xrange(options.nodes):
|
||||||
node = session.create_node(cls=CoreNode)
|
node = session.create_node(cls=CoreNode)
|
||||||
coreemu.add_interface(switch_network, node, prefix)
|
coreemu.add_interface(switch_network, node, prefixes)
|
||||||
|
|
||||||
# instantiate session
|
# instantiate session
|
||||||
session.instantiate()
|
session.instantiate()
|
||||||
|
@ -37,13 +38,13 @@ def example(options):
|
||||||
|
|
||||||
print "starting iperf server on node: %s" % first_node.name
|
print "starting iperf server on node: %s" % first_node.name
|
||||||
first_node.cmd(["iperf", "-s", "-D"])
|
first_node.cmd(["iperf", "-s", "-D"])
|
||||||
address = str(prefix.addr(first_node.objid))
|
address = prefixes.ip4_address(first_node)
|
||||||
print "node %s connecting to %s" % (last_node.name, address)
|
print "node %s connecting to %s" % (last_node.name, address)
|
||||||
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address])
|
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address])
|
||||||
first_node.cmd(["killall", "-9", "iperf"])
|
first_node.cmd(["killall", "-9", "iperf"])
|
||||||
|
|
||||||
# shutdown session
|
# shutdown session
|
||||||
session.shutdown()
|
coreemu.shutdown()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -8,41 +8,32 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
import parser
|
import parser
|
||||||
from core.data import NodeData, LinkData
|
|
||||||
from core.enumerations import NodeTypes, EventTypes
|
from core.enumerations import NodeTypes, EventTypes
|
||||||
from core.future.coreemu import FutureIpv4Prefix, CoreEmu
|
from core.future.coreemu import CoreEmu
|
||||||
|
from core.future.futuredata import IpPrefixes, NodeOptions
|
||||||
|
|
||||||
|
|
||||||
def example(options):
|
def example(options):
|
||||||
# ip generator for example
|
# ip generator for example
|
||||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||||
|
|
||||||
# create emulator instance for creating sessions and utility methods
|
# create emulator instance for creating sessions and utility methods
|
||||||
coreemu = CoreEmu()
|
coreemu = CoreEmu()
|
||||||
session = coreemu.create_session(master=True)
|
session = coreemu.create_session()
|
||||||
|
|
||||||
# must be in configuration state for nodes to start, when using "node_add" below
|
# must be in configuration state for nodes to start, when using "node_add" below
|
||||||
session.set_state(EventTypes.CONFIGURATION_STATE.value)
|
session.set_state(EventTypes.CONFIGURATION_STATE.value)
|
||||||
|
|
||||||
# create switch network node
|
# create switch network node
|
||||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||||
switch_id = session.node_add(node_data)
|
switch = session.add_node(node_options)
|
||||||
|
|
||||||
# create nodes
|
# create nodes
|
||||||
for _ in xrange(options.nodes):
|
for _ in xrange(options.nodes):
|
||||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||||
node_id = session.node_add(node_data)
|
node = session.add_node(node_options)
|
||||||
node = session.get_object(node_id)
|
interface = prefixes.create_interface(node)
|
||||||
inteface_index = node.newifindex()
|
session.add_link(node.objid, switch.objid, interface_one=interface)
|
||||||
address = prefix.addr(node_id)
|
|
||||||
link_data = LinkData(
|
|
||||||
node1_id=node_id,
|
|
||||||
node2_id=switch_id,
|
|
||||||
interface1_id=inteface_index,
|
|
||||||
interface1_ip4=str(address),
|
|
||||||
interface1_ip4_mask=prefix.prefixlen,
|
|
||||||
)
|
|
||||||
session.link_add(link_data)
|
|
||||||
|
|
||||||
# instantiate session
|
# instantiate session
|
||||||
session.instantiate()
|
session.instantiate()
|
||||||
|
@ -53,9 +44,9 @@ def example(options):
|
||||||
|
|
||||||
print "starting iperf server on node: %s" % first_node.name
|
print "starting iperf server on node: %s" % first_node.name
|
||||||
first_node.cmd(["iperf", "-s", "-D"])
|
first_node.cmd(["iperf", "-s", "-D"])
|
||||||
address = str(prefix.addr(first_node.objid))
|
first_node_address = prefixes.ip4_address(first_node)
|
||||||
print "node %s connecting to %s" % (last_node.name, address)
|
print "node %s connecting to %s" % (last_node.name, first_node_address)
|
||||||
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address])
|
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", first_node_address])
|
||||||
first_node.cmd(["killall", "-9", "iperf"])
|
first_node.cmd(["killall", "-9", "iperf"])
|
||||||
|
|
||||||
# shutdown session
|
# shutdown session
|
||||||
|
|
|
@ -5,17 +5,13 @@
|
||||||
# and repeat for minnodes <= n <= maxnodes with a step size of
|
# and repeat for minnodes <= n <= maxnodes with a step size of
|
||||||
# nodestep
|
# nodestep
|
||||||
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
import parser
|
|
||||||
from core.data import NodeData, LinkData
|
|
||||||
from core.enumerations import NodeTypes, EventTypes
|
from core.enumerations import NodeTypes, EventTypes
|
||||||
from core.future.coreemu import FutureIpv4Prefix, CoreEmu
|
from core.future.futuredata import IpPrefixes, NodeOptions
|
||||||
|
|
||||||
|
|
||||||
def example(nodes):
|
def example(nodes):
|
||||||
# ip generator for example
|
# ip generator for example
|
||||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
prefixes = IpPrefixes("10.83.0.0/16")
|
||||||
|
|
||||||
# create emulator instance for creating sessions and utility methods
|
# create emulator instance for creating sessions and utility methods
|
||||||
coreemu = globals()["coreemu"]
|
coreemu = globals()["coreemu"]
|
||||||
|
@ -25,24 +21,15 @@ def example(nodes):
|
||||||
session.set_state(EventTypes.CONFIGURATION_STATE.value)
|
session.set_state(EventTypes.CONFIGURATION_STATE.value)
|
||||||
|
|
||||||
# create switch network node
|
# create switch network node
|
||||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||||
switch_id = session.node_add(node_data)
|
switch = session.add_node(node_options)
|
||||||
|
|
||||||
# create nodes
|
# create nodes
|
||||||
for _ in xrange(nodes):
|
for _ in xrange(nodes):
|
||||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
node_options = NodeOptions(_type=NodeTypes.DEFAULT.value)
|
||||||
node_id = session.node_add(node_data)
|
node = session.add_node(node_options)
|
||||||
node = session.get_object(node_id)
|
interface = prefixes.create_interface(node)
|
||||||
inteface_index = node.newifindex()
|
session.add_link(node.objid, switch.objid, interface_one=interface)
|
||||||
address = prefix.addr(node_id)
|
|
||||||
link_data = LinkData(
|
|
||||||
node1_id=node_id,
|
|
||||||
node2_id=switch_id,
|
|
||||||
interface1_id=inteface_index,
|
|
||||||
interface1_ip4=str(address),
|
|
||||||
interface1_ip4_mask=prefix.prefixlen,
|
|
||||||
)
|
|
||||||
session.link_add(link_data)
|
|
||||||
|
|
||||||
# instantiate session
|
# instantiate session
|
||||||
session.instantiate()
|
session.instantiate()
|
||||||
|
|
|
@ -8,14 +8,15 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
import parser
|
import parser
|
||||||
from core.future.coreemu import FutureIpv4Prefix, CoreEmu
|
from core.future.coreemu import CoreEmu
|
||||||
|
from core.future.futuredata import IpPrefixes
|
||||||
from core.mobility import BasicRangeModel
|
from core.mobility import BasicRangeModel
|
||||||
from core.netns.nodes import WlanNode, CoreNode
|
from core.netns.nodes import WlanNode, CoreNode
|
||||||
|
|
||||||
|
|
||||||
def example(options):
|
def example(options):
|
||||||
# ip generator for example
|
# ip generator for example
|
||||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
prefixes = IpPrefixes("10.83.0.0/16")
|
||||||
|
|
||||||
# create emulator instance for creating sessions and utility methods
|
# create emulator instance for creating sessions and utility methods
|
||||||
coreemu = CoreEmu()
|
coreemu = CoreEmu()
|
||||||
|
@ -29,7 +30,7 @@ def example(options):
|
||||||
wireless_nodes = []
|
wireless_nodes = []
|
||||||
for _ in xrange(options.nodes):
|
for _ in xrange(options.nodes):
|
||||||
node = session.create_node(cls=CoreNode)
|
node = session.create_node(cls=CoreNode)
|
||||||
coreemu.add_interface(wlan_network, node, prefix)
|
coreemu.add_interface(wlan_network, node, prefixes)
|
||||||
wireless_nodes.append(node)
|
wireless_nodes.append(node)
|
||||||
|
|
||||||
# link all created nodes with the wireless network
|
# link all created nodes with the wireless network
|
||||||
|
@ -44,13 +45,13 @@ def example(options):
|
||||||
|
|
||||||
print "starting iperf server on node: %s" % first_node.name
|
print "starting iperf server on node: %s" % first_node.name
|
||||||
first_node.cmd(["iperf", "-s", "-D"])
|
first_node.cmd(["iperf", "-s", "-D"])
|
||||||
address = str(prefix.addr(first_node.objid))
|
address = prefixes.ip4_address(first_node)
|
||||||
print "node %s connecting to %s" % (last_node.name, address)
|
print "node %s connecting to %s" % (last_node.name, address)
|
||||||
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address])
|
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address])
|
||||||
first_node.cmd(["killall", "-9", "iperf"])
|
first_node.cmd(["killall", "-9", "iperf"])
|
||||||
|
|
||||||
# shutdown session
|
# shutdown session
|
||||||
session.shutdown()
|
coreemu.shutdown()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -3,9 +3,9 @@ import time
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from core.data import NodeData, LinkData
|
|
||||||
from core.enumerations import NodeTypes, EventTypes
|
from core.enumerations import NodeTypes, EventTypes
|
||||||
from core.future.coreemu import CoreEmu, FutureIpv4Prefix
|
from core.future.coreemu import CoreEmu
|
||||||
|
from core.future.futuredata import IpPrefixes, NodeOptions, LinkOptions
|
||||||
from core.misc import utils
|
from core.misc import utils
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ from core.misc import utils
|
||||||
def future_session():
|
def future_session():
|
||||||
# use coreemu and create a session
|
# use coreemu and create a session
|
||||||
coreemu = CoreEmu()
|
coreemu = CoreEmu()
|
||||||
session = coreemu.create_session(master=True)
|
session = coreemu.create_session()
|
||||||
session.set_state(EventTypes.CONFIGURATION_STATE.value)
|
session.set_state(EventTypes.CONFIGURATION_STATE.value)
|
||||||
|
|
||||||
# return created session
|
# return created session
|
||||||
|
@ -41,16 +41,15 @@ class TestFuture:
|
||||||
@pytest.mark.parametrize("model", MODELS)
|
@pytest.mark.parametrize("model", MODELS)
|
||||||
def test_node_add(self, future_session, model):
|
def test_node_add(self, future_session, model):
|
||||||
# given
|
# given
|
||||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value, model=model)
|
node_options = NodeOptions(_type=NodeTypes.DEFAULT, model=model)
|
||||||
|
|
||||||
# when
|
# when
|
||||||
node_id = future_session.node_add(node_data)
|
node = future_session.add_node(node_options)
|
||||||
|
|
||||||
# give time for node services to boot
|
# give time for node services to boot
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
node = future_session.get_object(node_id)
|
|
||||||
assert node
|
assert node
|
||||||
assert os.path.exists(node.nodedir)
|
assert os.path.exists(node.nodedir)
|
||||||
assert node.alive()
|
assert node.alive()
|
||||||
|
@ -60,187 +59,116 @@ class TestFuture:
|
||||||
|
|
||||||
def test_node_update(self, future_session):
|
def test_node_update(self, future_session):
|
||||||
# given
|
# given
|
||||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||||
node_id = future_session.node_add(node_data)
|
node = future_session.add_node(node_options)
|
||||||
position_value = 100
|
position_value = 100
|
||||||
update_data = NodeData(
|
update_options = NodeOptions(_id=node.objid)
|
||||||
id=node_id,
|
update_options.set_position(x=position_value, y=position_value)
|
||||||
x_position=position_value,
|
|
||||||
y_position=position_value
|
|
||||||
)
|
|
||||||
|
|
||||||
# when
|
# when
|
||||||
future_session.node_update(update_data)
|
future_session.update_node(update_options)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
node = future_session.get_object(node_id)
|
|
||||||
assert node.position.x == position_value
|
assert node.position.x == position_value
|
||||||
assert node.position.y == position_value
|
assert node.position.y == position_value
|
||||||
|
|
||||||
def test_node_delete(self, future_session):
|
def test_node_delete(self, future_session):
|
||||||
# given
|
# given
|
||||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||||
node_id = future_session.node_add(node_data)
|
node = future_session.add_node(node_options)
|
||||||
|
|
||||||
# when
|
# when
|
||||||
future_session.node_delete(node_id)
|
future_session.delete_node(node.objid)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(KeyError):
|
||||||
future_session.get_object(node_id)
|
future_session.get_object(node.objid)
|
||||||
|
|
||||||
@pytest.mark.parametrize("net_type", NET_TYPES)
|
@pytest.mark.parametrize("net_type", NET_TYPES)
|
||||||
def test_net(self, future_session, net_type):
|
def test_net(self, future_session, net_type):
|
||||||
# given
|
# given
|
||||||
node_data = NodeData(node_type=net_type.value)
|
node_options = NodeOptions(_type=net_type)
|
||||||
|
|
||||||
# when
|
# when
|
||||||
node_id = future_session.node_add(node_data)
|
node = future_session.add_node(node_options)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
node = future_session.get_object(node_id)
|
|
||||||
assert node
|
assert node
|
||||||
assert node.up
|
assert node.up
|
||||||
assert utils.check_cmd(["brctl", "show", node.brname])
|
assert utils.check_cmd(["brctl", "show", node.brname])
|
||||||
|
|
||||||
def test_ptp(self, future_session):
|
def test_ptp(self, future_session):
|
||||||
# given
|
# given
|
||||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||||
node_one_id = future_session.node_add(node_data)
|
node_one = future_session.add_node(node_options)
|
||||||
node_two_id = future_session.node_add(node_data)
|
node_two = future_session.add_node(node_options)
|
||||||
|
interface_one = prefixes.create_interface(node_one)
|
||||||
node_one = future_session.get_object(node_one_id)
|
inteface_two = prefixes.create_interface(node_two)
|
||||||
inteface_one_index = node_one.newifindex()
|
|
||||||
address_one = prefix.addr(node_one_id)
|
|
||||||
|
|
||||||
node_two = future_session.get_object(node_two_id)
|
|
||||||
inteface_two_index = node_two.newifindex()
|
|
||||||
address_two = prefix.addr(node_two_id)
|
|
||||||
|
|
||||||
link_data = LinkData(
|
|
||||||
node1_id=node_one_id,
|
|
||||||
node2_id=node_two_id,
|
|
||||||
interface1_id=inteface_one_index,
|
|
||||||
interface1_ip4=str(address_one),
|
|
||||||
interface1_ip4_mask=prefix.prefixlen,
|
|
||||||
interface2_id=inteface_two_index,
|
|
||||||
interface2_ip4=str(address_two),
|
|
||||||
interface2_ip4_mask=prefix.prefixlen,
|
|
||||||
)
|
|
||||||
|
|
||||||
# when
|
# when
|
||||||
future_session.link_add(link_data)
|
future_session.add_link(node_one.objid, node_two.objid, interface_one, inteface_two)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
assert node_one.netif(inteface_one_index)
|
assert node_one.netif(interface_one.id)
|
||||||
assert node_two.netif(inteface_two_index)
|
assert node_two.netif(inteface_two.id)
|
||||||
|
|
||||||
def test_node_to_net(self, future_session):
|
def test_node_to_net(self, future_session):
|
||||||
# given
|
# given
|
||||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||||
|
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
node_one = future_session.add_node(node_options)
|
||||||
node_one = future_session.node_add(node_data)
|
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
node_two = future_session.add_node(node_options)
|
||||||
node_two = future_session.node_add(node_data)
|
interface_one = prefixes.create_interface(node_one)
|
||||||
|
|
||||||
node = future_session.get_object(node_one)
|
|
||||||
inteface_index = node.newifindex()
|
|
||||||
address = prefix.addr(node_one)
|
|
||||||
|
|
||||||
link_data = LinkData(
|
|
||||||
node1_id=node_one,
|
|
||||||
node2_id=node_two,
|
|
||||||
interface1_id=inteface_index,
|
|
||||||
interface1_ip4=str(address),
|
|
||||||
interface1_ip4_mask=prefix.prefixlen,
|
|
||||||
)
|
|
||||||
|
|
||||||
# when
|
# when
|
||||||
future_session.link_add(link_data)
|
future_session.add_link(node_one.objid, node_two.objid, interface_one)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
node_two = future_session.get_object(node_two)
|
|
||||||
assert node_two.all_link_data(0)
|
assert node_two.all_link_data(0)
|
||||||
assert node.netif(inteface_index)
|
assert node_one.netif(interface_one.id)
|
||||||
|
|
||||||
def test_net_to_node(self, future_session):
|
def test_net_to_node(self, future_session):
|
||||||
# given
|
# given
|
||||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||||
|
|
||||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||||
node_one = future_session.node_add(node_data)
|
node_one = future_session.add_node(node_options)
|
||||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||||
node_two = future_session.node_add(node_data)
|
node_two = future_session.add_node(node_options)
|
||||||
|
interface_two = prefixes.create_interface(node_two)
|
||||||
node = future_session.get_object(node_two)
|
|
||||||
inteface_index = node.newifindex()
|
|
||||||
address = prefix.addr(node_two)
|
|
||||||
|
|
||||||
link_data = LinkData(
|
|
||||||
node1_id=node_one,
|
|
||||||
node2_id=node_two,
|
|
||||||
interface2_id=inteface_index,
|
|
||||||
interface2_ip4=str(address),
|
|
||||||
interface2_ip4_mask=prefix.prefixlen,
|
|
||||||
)
|
|
||||||
|
|
||||||
# when
|
# when
|
||||||
future_session.link_add(link_data)
|
future_session.add_link(node_one.objid, node_two.objid, interface_two=interface_two)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
node_one = future_session.get_object(node_one)
|
|
||||||
assert node_one.all_link_data(0)
|
assert node_one.all_link_data(0)
|
||||||
assert node.netif(inteface_index)
|
assert node_two.netif(interface_two.id)
|
||||||
|
|
||||||
def test_net_to_net(self, future_session):
|
def test_net_to_net(self, future_session):
|
||||||
# given
|
# given
|
||||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||||
node_one = future_session.node_add(node_data)
|
node_one = future_session.add_node(node_options)
|
||||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||||
node_two = future_session.node_add(node_data)
|
node_two = future_session.add_node(node_options)
|
||||||
|
|
||||||
link_data = LinkData(
|
|
||||||
node1_id=node_one,
|
|
||||||
node2_id=node_two,
|
|
||||||
)
|
|
||||||
|
|
||||||
# when
|
# when
|
||||||
future_session.link_add(link_data)
|
future_session.add_link(node_one.objid, node_two.objid)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
node_one = future_session.get_object(node_one)
|
|
||||||
assert node_one.all_link_data(0)
|
assert node_one.all_link_data(0)
|
||||||
|
|
||||||
def test_link_update(self, future_session):
|
def test_link_update(self, future_session):
|
||||||
# given
|
# given
|
||||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||||
node_one = future_session.node_add(node_data)
|
node_one = future_session.add_node(node_options)
|
||||||
node_data = NodeData(node_type=NodeTypes.SWITCH.value)
|
node_options = NodeOptions(_type=NodeTypes.SWITCH)
|
||||||
node_two = future_session.node_add(node_data)
|
node_two = future_session.add_node(node_options)
|
||||||
node = future_session.get_object(node_one)
|
interface_one = prefixes.create_interface(node_one)
|
||||||
inteface_index = node.newifindex()
|
future_session.add_link(node_one.objid, node_two.objid, interface_one)
|
||||||
address = prefix.addr(node_one)
|
interface = node_one.netif(interface_one.id)
|
||||||
link_data = LinkData(
|
|
||||||
node1_id=node_one,
|
|
||||||
node2_id=node_two,
|
|
||||||
interface1_id=inteface_index,
|
|
||||||
interface1_ip4=str(address),
|
|
||||||
interface1_ip4_mask=prefix.prefixlen,
|
|
||||||
)
|
|
||||||
future_session.link_add(link_data)
|
|
||||||
update_data = LinkData(
|
|
||||||
node1_id=node_one,
|
|
||||||
node2_id=node_two,
|
|
||||||
interface1_id=inteface_index,
|
|
||||||
delay=50,
|
|
||||||
bandwidth=5000000,
|
|
||||||
per=25,
|
|
||||||
dup=25
|
|
||||||
)
|
|
||||||
interface = node.netif(inteface_index)
|
|
||||||
output = utils.check_cmd(["tc", "qdisc", "show", "dev", interface.localname])
|
output = utils.check_cmd(["tc", "qdisc", "show", "dev", interface.localname])
|
||||||
assert "delay" not in output
|
assert "delay" not in output
|
||||||
assert "rate" not in output
|
assert "rate" not in output
|
||||||
|
@ -248,7 +176,13 @@ class TestFuture:
|
||||||
assert "duplicate" not in output
|
assert "duplicate" not in output
|
||||||
|
|
||||||
# when
|
# when
|
||||||
future_session.link_update(update_data)
|
link_options = LinkOptions()
|
||||||
|
link_options.delay = 50
|
||||||
|
link_options.bandwidth = 5000000
|
||||||
|
link_options.per = 25
|
||||||
|
link_options.dup = 25
|
||||||
|
future_session.update_link(node_one.objid, node_two.objid,
|
||||||
|
interface_one_id=interface_one.id, link_options=link_options)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
output = utils.check_cmd(["tc", "qdisc", "show", "dev", interface.localname])
|
output = utils.check_cmd(["tc", "qdisc", "show", "dev", interface.localname])
|
||||||
|
@ -259,35 +193,21 @@ class TestFuture:
|
||||||
|
|
||||||
def test_link_delete(self, future_session):
|
def test_link_delete(self, future_session):
|
||||||
# given
|
# given
|
||||||
prefix = FutureIpv4Prefix("10.83.0.0/16")
|
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||||
node_data = NodeData(node_type=NodeTypes.DEFAULT.value)
|
node_options = NodeOptions(_type=NodeTypes.DEFAULT)
|
||||||
node_one_id = future_session.node_add(node_data)
|
node_one = future_session.add_node(node_options)
|
||||||
node_two_id = future_session.node_add(node_data)
|
node_two = future_session.add_node(node_options)
|
||||||
node_one = future_session.get_object(node_one_id)
|
interface_one = prefixes.create_interface(node_one)
|
||||||
inteface_one_index = node_one.newifindex()
|
interface_two = prefixes.create_interface(node_two)
|
||||||
address_one = prefix.addr(node_one_id)
|
future_session.add_link(node_one.objid, node_two.objid, interface_one, interface_two)
|
||||||
node_two = future_session.get_object(node_two_id)
|
assert node_one.netif(interface_one.id)
|
||||||
inteface_two_index = node_two.newifindex()
|
assert node_two.netif(interface_two.id)
|
||||||
address_two = prefix.addr(node_two_id)
|
|
||||||
link_data = LinkData(
|
|
||||||
node1_id=node_one_id,
|
|
||||||
node2_id=node_two_id,
|
|
||||||
interface1_id=inteface_one_index,
|
|
||||||
interface1_ip4=str(address_one),
|
|
||||||
interface1_ip4_mask=prefix.prefixlen,
|
|
||||||
interface2_id=inteface_two_index,
|
|
||||||
interface2_ip4=str(address_two),
|
|
||||||
interface2_ip4_mask=prefix.prefixlen,
|
|
||||||
)
|
|
||||||
future_session.link_add(link_data)
|
|
||||||
assert node_one.netif(inteface_one_index)
|
|
||||||
assert node_two.netif(inteface_two_index)
|
|
||||||
assert future_session.get_node_count() == 3
|
assert future_session.get_node_count() == 3
|
||||||
|
|
||||||
# when
|
# when
|
||||||
future_session.link_delete(link_data)
|
future_session.delete_link(node_one.objid, node_two.objid, interface_one.id, interface_two.id)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
assert not node_one.netif(inteface_one_index)
|
assert not node_one.netif(interface_one.id)
|
||||||
assert not node_two.netif(inteface_two_index)
|
assert not node_two.netif(interface_two.id)
|
||||||
assert future_session.get_node_count() == 2
|
assert future_session.get_node_count() == 2
|
||||||
|
|
Loading…
Reference in a new issue