updates to layout core module packages in a more logical way, including renaming methods from objects to nodes and nodes.objid to nodes.id

This commit is contained in:
bharnden 2019-04-29 23:31:47 -07:00
parent 9517740704
commit 66e603906a
100 changed files with 10283 additions and 3489 deletions

View file

@ -1,3 +0,0 @@
"""
Contains code specific to the legacy TCP API for interacting with the TCL based GUI.
"""

View file

@ -10,9 +10,9 @@ from contextlib import contextmanager
import grpc
from core.grpc import core_pb2
from core.grpc import core_pb2_grpc
from core.misc.ipaddress import Ipv4Prefix, Ipv6Prefix, MacAddress
from core.api.grpc import core_pb2
from core.api.grpc import core_pb2_grpc
from core.nodes.ipaddress import Ipv4Prefix, Ipv6Prefix, MacAddress
class InterfaceHelper(object):

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,828 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpc
import core_pb2 as core__pb2
class CoreApiStub(object):
# missing associated documentation comment in .proto file
pass
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.CreateSession = channel.unary_unary(
'/core.CoreApi/CreateSession',
request_serializer=core__pb2.CreateSessionRequest.SerializeToString,
response_deserializer=core__pb2.CreateSessionResponse.FromString,
)
self.DeleteSession = channel.unary_unary(
'/core.CoreApi/DeleteSession',
request_serializer=core__pb2.DeleteSessionRequest.SerializeToString,
response_deserializer=core__pb2.DeleteSessionResponse.FromString,
)
self.GetSessions = channel.unary_unary(
'/core.CoreApi/GetSessions',
request_serializer=core__pb2.GetSessionsRequest.SerializeToString,
response_deserializer=core__pb2.GetSessionsResponse.FromString,
)
self.GetSession = channel.unary_unary(
'/core.CoreApi/GetSession',
request_serializer=core__pb2.GetSessionRequest.SerializeToString,
response_deserializer=core__pb2.GetSessionResponse.FromString,
)
self.GetSessionOptions = channel.unary_unary(
'/core.CoreApi/GetSessionOptions',
request_serializer=core__pb2.GetSessionOptionsRequest.SerializeToString,
response_deserializer=core__pb2.GetSessionOptionsResponse.FromString,
)
self.SetSessionOptions = channel.unary_unary(
'/core.CoreApi/SetSessionOptions',
request_serializer=core__pb2.SetSessionOptionsRequest.SerializeToString,
response_deserializer=core__pb2.SetSessionOptionsResponse.FromString,
)
self.GetSessionLocation = channel.unary_unary(
'/core.CoreApi/GetSessionLocation',
request_serializer=core__pb2.GetSessionLocationRequest.SerializeToString,
response_deserializer=core__pb2.GetSessionLocationResponse.FromString,
)
self.SetSessionLocation = channel.unary_unary(
'/core.CoreApi/SetSessionLocation',
request_serializer=core__pb2.SetSessionLocationRequest.SerializeToString,
response_deserializer=core__pb2.SetSessionLocationResponse.FromString,
)
self.SetSessionState = channel.unary_unary(
'/core.CoreApi/SetSessionState',
request_serializer=core__pb2.SetSessionStateRequest.SerializeToString,
response_deserializer=core__pb2.SetSessionStateResponse.FromString,
)
self.NodeEvents = channel.unary_stream(
'/core.CoreApi/NodeEvents',
request_serializer=core__pb2.NodeEventsRequest.SerializeToString,
response_deserializer=core__pb2.NodeEvent.FromString,
)
self.LinkEvents = channel.unary_stream(
'/core.CoreApi/LinkEvents',
request_serializer=core__pb2.LinkEventsRequest.SerializeToString,
response_deserializer=core__pb2.LinkEvent.FromString,
)
self.SessionEvents = channel.unary_stream(
'/core.CoreApi/SessionEvents',
request_serializer=core__pb2.SessionEventsRequest.SerializeToString,
response_deserializer=core__pb2.SessionEvent.FromString,
)
self.ConfigEvents = channel.unary_stream(
'/core.CoreApi/ConfigEvents',
request_serializer=core__pb2.ConfigEventsRequest.SerializeToString,
response_deserializer=core__pb2.ConfigEvent.FromString,
)
self.ExceptionEvents = channel.unary_stream(
'/core.CoreApi/ExceptionEvents',
request_serializer=core__pb2.ExceptionEventsRequest.SerializeToString,
response_deserializer=core__pb2.ExceptionEvent.FromString,
)
self.FileEvents = channel.unary_stream(
'/core.CoreApi/FileEvents',
request_serializer=core__pb2.FileEventsRequest.SerializeToString,
response_deserializer=core__pb2.FileEvent.FromString,
)
self.AddNode = channel.unary_unary(
'/core.CoreApi/AddNode',
request_serializer=core__pb2.AddNodeRequest.SerializeToString,
response_deserializer=core__pb2.AddNodeResponse.FromString,
)
self.GetNode = channel.unary_unary(
'/core.CoreApi/GetNode',
request_serializer=core__pb2.GetNodeRequest.SerializeToString,
response_deserializer=core__pb2.GetNodeResponse.FromString,
)
self.EditNode = channel.unary_unary(
'/core.CoreApi/EditNode',
request_serializer=core__pb2.EditNodeRequest.SerializeToString,
response_deserializer=core__pb2.EditNodeResponse.FromString,
)
self.DeleteNode = channel.unary_unary(
'/core.CoreApi/DeleteNode',
request_serializer=core__pb2.DeleteNodeRequest.SerializeToString,
response_deserializer=core__pb2.DeleteNodeResponse.FromString,
)
self.GetNodeLinks = channel.unary_unary(
'/core.CoreApi/GetNodeLinks',
request_serializer=core__pb2.GetNodeLinksRequest.SerializeToString,
response_deserializer=core__pb2.GetNodeLinksResponse.FromString,
)
self.AddLink = channel.unary_unary(
'/core.CoreApi/AddLink',
request_serializer=core__pb2.AddLinkRequest.SerializeToString,
response_deserializer=core__pb2.AddLinkResponse.FromString,
)
self.EditLink = channel.unary_unary(
'/core.CoreApi/EditLink',
request_serializer=core__pb2.EditLinkRequest.SerializeToString,
response_deserializer=core__pb2.EditLinkResponse.FromString,
)
self.DeleteLink = channel.unary_unary(
'/core.CoreApi/DeleteLink',
request_serializer=core__pb2.DeleteLinkRequest.SerializeToString,
response_deserializer=core__pb2.DeleteLinkResponse.FromString,
)
self.GetHooks = channel.unary_unary(
'/core.CoreApi/GetHooks',
request_serializer=core__pb2.GetHooksRequest.SerializeToString,
response_deserializer=core__pb2.GetHooksResponse.FromString,
)
self.AddHook = channel.unary_unary(
'/core.CoreApi/AddHook',
request_serializer=core__pb2.AddHookRequest.SerializeToString,
response_deserializer=core__pb2.AddHookResponse.FromString,
)
self.GetMobilityConfigs = channel.unary_unary(
'/core.CoreApi/GetMobilityConfigs',
request_serializer=core__pb2.GetMobilityConfigsRequest.SerializeToString,
response_deserializer=core__pb2.GetMobilityConfigsResponse.FromString,
)
self.GetMobilityConfig = channel.unary_unary(
'/core.CoreApi/GetMobilityConfig',
request_serializer=core__pb2.GetMobilityConfigRequest.SerializeToString,
response_deserializer=core__pb2.GetMobilityConfigResponse.FromString,
)
self.SetMobilityConfig = channel.unary_unary(
'/core.CoreApi/SetMobilityConfig',
request_serializer=core__pb2.SetMobilityConfigRequest.SerializeToString,
response_deserializer=core__pb2.SetMobilityConfigResponse.FromString,
)
self.MobilityAction = channel.unary_unary(
'/core.CoreApi/MobilityAction',
request_serializer=core__pb2.MobilityActionRequest.SerializeToString,
response_deserializer=core__pb2.MobilityActionResponse.FromString,
)
self.GetServices = channel.unary_unary(
'/core.CoreApi/GetServices',
request_serializer=core__pb2.GetServicesRequest.SerializeToString,
response_deserializer=core__pb2.GetServicesResponse.FromString,
)
self.GetServiceDefaults = channel.unary_unary(
'/core.CoreApi/GetServiceDefaults',
request_serializer=core__pb2.GetServiceDefaultsRequest.SerializeToString,
response_deserializer=core__pb2.GetServiceDefaultsResponse.FromString,
)
self.SetServiceDefaults = channel.unary_unary(
'/core.CoreApi/SetServiceDefaults',
request_serializer=core__pb2.SetServiceDefaultsRequest.SerializeToString,
response_deserializer=core__pb2.SetServiceDefaultsResponse.FromString,
)
self.GetNodeService = channel.unary_unary(
'/core.CoreApi/GetNodeService',
request_serializer=core__pb2.GetNodeServiceRequest.SerializeToString,
response_deserializer=core__pb2.GetNodeServiceResponse.FromString,
)
self.GetNodeServiceFile = channel.unary_unary(
'/core.CoreApi/GetNodeServiceFile',
request_serializer=core__pb2.GetNodeServiceFileRequest.SerializeToString,
response_deserializer=core__pb2.GetNodeServiceFileResponse.FromString,
)
self.SetNodeService = channel.unary_unary(
'/core.CoreApi/SetNodeService',
request_serializer=core__pb2.SetNodeServiceRequest.SerializeToString,
response_deserializer=core__pb2.SetNodeServiceResponse.FromString,
)
self.SetNodeServiceFile = channel.unary_unary(
'/core.CoreApi/SetNodeServiceFile',
request_serializer=core__pb2.SetNodeServiceFileRequest.SerializeToString,
response_deserializer=core__pb2.SetNodeServiceFileResponse.FromString,
)
self.ServiceAction = channel.unary_unary(
'/core.CoreApi/ServiceAction',
request_serializer=core__pb2.ServiceActionRequest.SerializeToString,
response_deserializer=core__pb2.ServiceActionResponse.FromString,
)
self.GetWlanConfig = channel.unary_unary(
'/core.CoreApi/GetWlanConfig',
request_serializer=core__pb2.GetWlanConfigRequest.SerializeToString,
response_deserializer=core__pb2.GetWlanConfigResponse.FromString,
)
self.SetWlanConfig = channel.unary_unary(
'/core.CoreApi/SetWlanConfig',
request_serializer=core__pb2.SetWlanConfigRequest.SerializeToString,
response_deserializer=core__pb2.SetWlanConfigResponse.FromString,
)
self.GetEmaneConfig = channel.unary_unary(
'/core.CoreApi/GetEmaneConfig',
request_serializer=core__pb2.GetEmaneConfigRequest.SerializeToString,
response_deserializer=core__pb2.GetEmaneConfigResponse.FromString,
)
self.SetEmaneConfig = channel.unary_unary(
'/core.CoreApi/SetEmaneConfig',
request_serializer=core__pb2.SetEmaneConfigRequest.SerializeToString,
response_deserializer=core__pb2.SetEmaneConfigResponse.FromString,
)
self.GetEmaneModels = channel.unary_unary(
'/core.CoreApi/GetEmaneModels',
request_serializer=core__pb2.GetEmaneModelsRequest.SerializeToString,
response_deserializer=core__pb2.GetEmaneModelsResponse.FromString,
)
self.GetEmaneModelConfig = channel.unary_unary(
'/core.CoreApi/GetEmaneModelConfig',
request_serializer=core__pb2.GetEmaneModelConfigRequest.SerializeToString,
response_deserializer=core__pb2.GetEmaneModelConfigResponse.FromString,
)
self.SetEmaneModelConfig = channel.unary_unary(
'/core.CoreApi/SetEmaneModelConfig',
request_serializer=core__pb2.SetEmaneModelConfigRequest.SerializeToString,
response_deserializer=core__pb2.SetEmaneModelConfigResponse.FromString,
)
self.GetEmaneModelConfigs = channel.unary_unary(
'/core.CoreApi/GetEmaneModelConfigs',
request_serializer=core__pb2.GetEmaneModelConfigsRequest.SerializeToString,
response_deserializer=core__pb2.GetEmaneModelConfigsResponse.FromString,
)
self.SaveXml = channel.unary_unary(
'/core.CoreApi/SaveXml',
request_serializer=core__pb2.SaveXmlRequest.SerializeToString,
response_deserializer=core__pb2.SaveXmlResponse.FromString,
)
self.OpenXml = channel.unary_unary(
'/core.CoreApi/OpenXml',
request_serializer=core__pb2.OpenXmlRequest.SerializeToString,
response_deserializer=core__pb2.OpenXmlResponse.FromString,
)
class CoreApiServicer(object):
# missing associated documentation comment in .proto file
pass
def CreateSession(self, request, context):
"""session rpc
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def DeleteSession(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSessions(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSession(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSessionOptions(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SetSessionOptions(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSessionLocation(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SetSessionLocation(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SetSessionState(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def NodeEvents(self, request, context):
"""event streams
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def LinkEvents(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SessionEvents(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def ConfigEvents(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def ExceptionEvents(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def FileEvents(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def AddNode(self, request, context):
"""node rpc
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetNode(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def EditNode(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def DeleteNode(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetNodeLinks(self, request, context):
"""link rpc
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def AddLink(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def EditLink(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def DeleteLink(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetHooks(self, request, context):
"""hook rpc
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def AddHook(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMobilityConfigs(self, request, context):
"""mobility rpc
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMobilityConfig(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SetMobilityConfig(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def MobilityAction(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetServices(self, request, context):
"""service rpc
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetServiceDefaults(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SetServiceDefaults(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetNodeService(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetNodeServiceFile(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SetNodeService(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SetNodeServiceFile(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def ServiceAction(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetWlanConfig(self, request, context):
"""wlan rpc
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SetWlanConfig(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetEmaneConfig(self, request, context):
"""emane rpc
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SetEmaneConfig(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetEmaneModels(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetEmaneModelConfig(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SetEmaneModelConfig(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetEmaneModelConfigs(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SaveXml(self, request, context):
"""xml rpc
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def OpenXml(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_CoreApiServicer_to_server(servicer, server):
rpc_method_handlers = {
'CreateSession': grpc.unary_unary_rpc_method_handler(
servicer.CreateSession,
request_deserializer=core__pb2.CreateSessionRequest.FromString,
response_serializer=core__pb2.CreateSessionResponse.SerializeToString,
),
'DeleteSession': grpc.unary_unary_rpc_method_handler(
servicer.DeleteSession,
request_deserializer=core__pb2.DeleteSessionRequest.FromString,
response_serializer=core__pb2.DeleteSessionResponse.SerializeToString,
),
'GetSessions': grpc.unary_unary_rpc_method_handler(
servicer.GetSessions,
request_deserializer=core__pb2.GetSessionsRequest.FromString,
response_serializer=core__pb2.GetSessionsResponse.SerializeToString,
),
'GetSession': grpc.unary_unary_rpc_method_handler(
servicer.GetSession,
request_deserializer=core__pb2.GetSessionRequest.FromString,
response_serializer=core__pb2.GetSessionResponse.SerializeToString,
),
'GetSessionOptions': grpc.unary_unary_rpc_method_handler(
servicer.GetSessionOptions,
request_deserializer=core__pb2.GetSessionOptionsRequest.FromString,
response_serializer=core__pb2.GetSessionOptionsResponse.SerializeToString,
),
'SetSessionOptions': grpc.unary_unary_rpc_method_handler(
servicer.SetSessionOptions,
request_deserializer=core__pb2.SetSessionOptionsRequest.FromString,
response_serializer=core__pb2.SetSessionOptionsResponse.SerializeToString,
),
'GetSessionLocation': grpc.unary_unary_rpc_method_handler(
servicer.GetSessionLocation,
request_deserializer=core__pb2.GetSessionLocationRequest.FromString,
response_serializer=core__pb2.GetSessionLocationResponse.SerializeToString,
),
'SetSessionLocation': grpc.unary_unary_rpc_method_handler(
servicer.SetSessionLocation,
request_deserializer=core__pb2.SetSessionLocationRequest.FromString,
response_serializer=core__pb2.SetSessionLocationResponse.SerializeToString,
),
'SetSessionState': grpc.unary_unary_rpc_method_handler(
servicer.SetSessionState,
request_deserializer=core__pb2.SetSessionStateRequest.FromString,
response_serializer=core__pb2.SetSessionStateResponse.SerializeToString,
),
'NodeEvents': grpc.unary_stream_rpc_method_handler(
servicer.NodeEvents,
request_deserializer=core__pb2.NodeEventsRequest.FromString,
response_serializer=core__pb2.NodeEvent.SerializeToString,
),
'LinkEvents': grpc.unary_stream_rpc_method_handler(
servicer.LinkEvents,
request_deserializer=core__pb2.LinkEventsRequest.FromString,
response_serializer=core__pb2.LinkEvent.SerializeToString,
),
'SessionEvents': grpc.unary_stream_rpc_method_handler(
servicer.SessionEvents,
request_deserializer=core__pb2.SessionEventsRequest.FromString,
response_serializer=core__pb2.SessionEvent.SerializeToString,
),
'ConfigEvents': grpc.unary_stream_rpc_method_handler(
servicer.ConfigEvents,
request_deserializer=core__pb2.ConfigEventsRequest.FromString,
response_serializer=core__pb2.ConfigEvent.SerializeToString,
),
'ExceptionEvents': grpc.unary_stream_rpc_method_handler(
servicer.ExceptionEvents,
request_deserializer=core__pb2.ExceptionEventsRequest.FromString,
response_serializer=core__pb2.ExceptionEvent.SerializeToString,
),
'FileEvents': grpc.unary_stream_rpc_method_handler(
servicer.FileEvents,
request_deserializer=core__pb2.FileEventsRequest.FromString,
response_serializer=core__pb2.FileEvent.SerializeToString,
),
'AddNode': grpc.unary_unary_rpc_method_handler(
servicer.AddNode,
request_deserializer=core__pb2.AddNodeRequest.FromString,
response_serializer=core__pb2.AddNodeResponse.SerializeToString,
),
'GetNode': grpc.unary_unary_rpc_method_handler(
servicer.GetNode,
request_deserializer=core__pb2.GetNodeRequest.FromString,
response_serializer=core__pb2.GetNodeResponse.SerializeToString,
),
'EditNode': grpc.unary_unary_rpc_method_handler(
servicer.EditNode,
request_deserializer=core__pb2.EditNodeRequest.FromString,
response_serializer=core__pb2.EditNodeResponse.SerializeToString,
),
'DeleteNode': grpc.unary_unary_rpc_method_handler(
servicer.DeleteNode,
request_deserializer=core__pb2.DeleteNodeRequest.FromString,
response_serializer=core__pb2.DeleteNodeResponse.SerializeToString,
),
'GetNodeLinks': grpc.unary_unary_rpc_method_handler(
servicer.GetNodeLinks,
request_deserializer=core__pb2.GetNodeLinksRequest.FromString,
response_serializer=core__pb2.GetNodeLinksResponse.SerializeToString,
),
'AddLink': grpc.unary_unary_rpc_method_handler(
servicer.AddLink,
request_deserializer=core__pb2.AddLinkRequest.FromString,
response_serializer=core__pb2.AddLinkResponse.SerializeToString,
),
'EditLink': grpc.unary_unary_rpc_method_handler(
servicer.EditLink,
request_deserializer=core__pb2.EditLinkRequest.FromString,
response_serializer=core__pb2.EditLinkResponse.SerializeToString,
),
'DeleteLink': grpc.unary_unary_rpc_method_handler(
servicer.DeleteLink,
request_deserializer=core__pb2.DeleteLinkRequest.FromString,
response_serializer=core__pb2.DeleteLinkResponse.SerializeToString,
),
'GetHooks': grpc.unary_unary_rpc_method_handler(
servicer.GetHooks,
request_deserializer=core__pb2.GetHooksRequest.FromString,
response_serializer=core__pb2.GetHooksResponse.SerializeToString,
),
'AddHook': grpc.unary_unary_rpc_method_handler(
servicer.AddHook,
request_deserializer=core__pb2.AddHookRequest.FromString,
response_serializer=core__pb2.AddHookResponse.SerializeToString,
),
'GetMobilityConfigs': grpc.unary_unary_rpc_method_handler(
servicer.GetMobilityConfigs,
request_deserializer=core__pb2.GetMobilityConfigsRequest.FromString,
response_serializer=core__pb2.GetMobilityConfigsResponse.SerializeToString,
),
'GetMobilityConfig': grpc.unary_unary_rpc_method_handler(
servicer.GetMobilityConfig,
request_deserializer=core__pb2.GetMobilityConfigRequest.FromString,
response_serializer=core__pb2.GetMobilityConfigResponse.SerializeToString,
),
'SetMobilityConfig': grpc.unary_unary_rpc_method_handler(
servicer.SetMobilityConfig,
request_deserializer=core__pb2.SetMobilityConfigRequest.FromString,
response_serializer=core__pb2.SetMobilityConfigResponse.SerializeToString,
),
'MobilityAction': grpc.unary_unary_rpc_method_handler(
servicer.MobilityAction,
request_deserializer=core__pb2.MobilityActionRequest.FromString,
response_serializer=core__pb2.MobilityActionResponse.SerializeToString,
),
'GetServices': grpc.unary_unary_rpc_method_handler(
servicer.GetServices,
request_deserializer=core__pb2.GetServicesRequest.FromString,
response_serializer=core__pb2.GetServicesResponse.SerializeToString,
),
'GetServiceDefaults': grpc.unary_unary_rpc_method_handler(
servicer.GetServiceDefaults,
request_deserializer=core__pb2.GetServiceDefaultsRequest.FromString,
response_serializer=core__pb2.GetServiceDefaultsResponse.SerializeToString,
),
'SetServiceDefaults': grpc.unary_unary_rpc_method_handler(
servicer.SetServiceDefaults,
request_deserializer=core__pb2.SetServiceDefaultsRequest.FromString,
response_serializer=core__pb2.SetServiceDefaultsResponse.SerializeToString,
),
'GetNodeService': grpc.unary_unary_rpc_method_handler(
servicer.GetNodeService,
request_deserializer=core__pb2.GetNodeServiceRequest.FromString,
response_serializer=core__pb2.GetNodeServiceResponse.SerializeToString,
),
'GetNodeServiceFile': grpc.unary_unary_rpc_method_handler(
servicer.GetNodeServiceFile,
request_deserializer=core__pb2.GetNodeServiceFileRequest.FromString,
response_serializer=core__pb2.GetNodeServiceFileResponse.SerializeToString,
),
'SetNodeService': grpc.unary_unary_rpc_method_handler(
servicer.SetNodeService,
request_deserializer=core__pb2.SetNodeServiceRequest.FromString,
response_serializer=core__pb2.SetNodeServiceResponse.SerializeToString,
),
'SetNodeServiceFile': grpc.unary_unary_rpc_method_handler(
servicer.SetNodeServiceFile,
request_deserializer=core__pb2.SetNodeServiceFileRequest.FromString,
response_serializer=core__pb2.SetNodeServiceFileResponse.SerializeToString,
),
'ServiceAction': grpc.unary_unary_rpc_method_handler(
servicer.ServiceAction,
request_deserializer=core__pb2.ServiceActionRequest.FromString,
response_serializer=core__pb2.ServiceActionResponse.SerializeToString,
),
'GetWlanConfig': grpc.unary_unary_rpc_method_handler(
servicer.GetWlanConfig,
request_deserializer=core__pb2.GetWlanConfigRequest.FromString,
response_serializer=core__pb2.GetWlanConfigResponse.SerializeToString,
),
'SetWlanConfig': grpc.unary_unary_rpc_method_handler(
servicer.SetWlanConfig,
request_deserializer=core__pb2.SetWlanConfigRequest.FromString,
response_serializer=core__pb2.SetWlanConfigResponse.SerializeToString,
),
'GetEmaneConfig': grpc.unary_unary_rpc_method_handler(
servicer.GetEmaneConfig,
request_deserializer=core__pb2.GetEmaneConfigRequest.FromString,
response_serializer=core__pb2.GetEmaneConfigResponse.SerializeToString,
),
'SetEmaneConfig': grpc.unary_unary_rpc_method_handler(
servicer.SetEmaneConfig,
request_deserializer=core__pb2.SetEmaneConfigRequest.FromString,
response_serializer=core__pb2.SetEmaneConfigResponse.SerializeToString,
),
'GetEmaneModels': grpc.unary_unary_rpc_method_handler(
servicer.GetEmaneModels,
request_deserializer=core__pb2.GetEmaneModelsRequest.FromString,
response_serializer=core__pb2.GetEmaneModelsResponse.SerializeToString,
),
'GetEmaneModelConfig': grpc.unary_unary_rpc_method_handler(
servicer.GetEmaneModelConfig,
request_deserializer=core__pb2.GetEmaneModelConfigRequest.FromString,
response_serializer=core__pb2.GetEmaneModelConfigResponse.SerializeToString,
),
'SetEmaneModelConfig': grpc.unary_unary_rpc_method_handler(
servicer.SetEmaneModelConfig,
request_deserializer=core__pb2.SetEmaneModelConfigRequest.FromString,
response_serializer=core__pb2.SetEmaneModelConfigResponse.SerializeToString,
),
'GetEmaneModelConfigs': grpc.unary_unary_rpc_method_handler(
servicer.GetEmaneModelConfigs,
request_deserializer=core__pb2.GetEmaneModelConfigsRequest.FromString,
response_serializer=core__pb2.GetEmaneModelConfigsResponse.SerializeToString,
),
'SaveXml': grpc.unary_unary_rpc_method_handler(
servicer.SaveXml,
request_deserializer=core__pb2.SaveXmlRequest.FromString,
response_serializer=core__pb2.SaveXmlResponse.SerializeToString,
),
'OpenXml': grpc.unary_unary_rpc_method_handler(
servicer.OpenXml,
request_deserializer=core__pb2.OpenXmlRequest.FromString,
response_serializer=core__pb2.OpenXmlResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'core.CoreApi', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))

View file

@ -9,13 +9,13 @@ import grpc
from concurrent import futures
from core.emulator.emudata import NodeOptions, InterfaceData, LinkOptions
from core.enumerations import NodeTypes, EventTypes, LinkTypes
from core.grpc import core_pb2
from core.grpc import core_pb2_grpc
from core.misc import nodeutils
from core.misc.ipaddress import MacAddress
from core.mobility import BasicRangeModel, Ns2ScriptedMobility
from core.service import ServiceManager
from core.emulator.enumerations import NodeTypes, EventTypes, LinkTypes
from core.api.grpc import core_pb2
from core.api.grpc import core_pb2_grpc
from core.nodes import nodeutils
from core.nodes.ipaddress import MacAddress
from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility
from core.services.coreservices import ServiceManager
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
@ -68,7 +68,7 @@ def get_emane_model_id(_id, interface):
def convert_link(session, link_data):
interface_one = None
if link_data.interface1_id is not None:
node = session.get_object(link_data.node1_id)
node = session.get_node(link_data.node1_id)
interface = node.netif(link_data.interface1_id)
interface_one = core_pb2.Interface(
id=link_data.interface1_id, name=interface.name, mac=convert_value(link_data.interface1_mac),
@ -77,7 +77,7 @@ def convert_link(session, link_data):
interface_two = None
if link_data.interface2_id is not None:
node = session.get_object(link_data.node2_id)
node = session.get_node(link_data.node2_id)
interface = node.netif(link_data.interface2_id)
interface_two = core_pb2.Interface(
id=link_data.interface2_id, name=interface.name, mac=convert_value(link_data.interface2_mac),
@ -143,7 +143,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def get_node(self, session, _id, context):
try:
return session.get_object(_id)
return session.get_node(_id)
except KeyError:
context.abort(grpc.StatusCode.NOT_FOUND, "node {} not found".format(_id))
@ -233,8 +233,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
links = []
nodes = []
for node_id in session.objects:
node = session.objects[node_id]
for _id in session.nodes:
node = session.nodes[_id]
if not isinstance(node.id, int):
continue

View file

@ -10,27 +10,26 @@ import select
import socket
import threading
from core.api import coreapi
from core.coreobj import PyCoreNet
from core.coreobj import PyCoreNode
from core.enumerations import ConfigDataTypes
from core.enumerations import ConfigFlags
from core.enumerations import ConfigTlvs
from core.enumerations import EventTlvs
from core.enumerations import EventTypes
from core.enumerations import ExecuteTlvs
from core.enumerations import FileTlvs
from core.enumerations import LinkTlvs
from core.enumerations import MessageFlags
from core.enumerations import MessageTypes
from core.enumerations import NodeTlvs
from core.enumerations import NodeTypes
from core.enumerations import RegisterTlvs
from core.misc import nodeutils
from core.misc.ipaddress import IpAddress
from core.netns.vif import GreTap
from core.netns.vnet import GreTapBridge
from core.phys.pnodes import PhysicalNode
from core.api.tlv import coreapi
from core.nodes.base import CoreNodeBase, CoreNetworkBase
from core.emulator.enumerations import ConfigDataTypes
from core.emulator.enumerations import ConfigFlags
from core.emulator.enumerations import ConfigTlvs
from core.emulator.enumerations import EventTlvs
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import ExecuteTlvs
from core.emulator.enumerations import FileTlvs
from core.emulator.enumerations import LinkTlvs
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.emulator.enumerations import NodeTlvs
from core.emulator.enumerations import NodeTypes
from core.emulator.enumerations import RegisterTlvs
from core.nodes import nodeutils
from core.nodes.ipaddress import IpAddress
from core.nodes.interface import GreTap
from core.nodes.network import GreTapBridge
from core.nodes.physical import PhysicalNode
class CoreDistributedServer(object):
@ -420,7 +419,7 @@ class CoreBroker(object):
gt = GreTap(node=None, name=None, session=self.session,
remoteip=remoteip, key=key)
else:
gt = self.session.add_object(cls=GreTapBridge, _id=_id, policy="ACCEPT", remoteip=remoteip, key=key)
gt = self.session.create_node(cls=GreTapBridge, _id=_id, policy="ACCEPT", remoteip=remoteip, key=key)
gt.localnum = localnum
gt.remotenum = remotenum
self.tunnels[key] = gt
@ -443,7 +442,7 @@ class CoreBroker(object):
:rtype: list
"""
try:
net = self.session.get_object(node_id)
net = self.session.get_node(node_id)
logging.info("adding net tunnel for: id(%s) %s", node_id, net)
except KeyError:
raise KeyError("network node %s not found" % node_id)
@ -517,7 +516,7 @@ class CoreBroker(object):
except KeyError:
gt = None
if gt:
self.session.delete_object(gt.id)
self.session.delete_node(gt.id)
del gt
def gettunnel(self, n1num, n2num):
@ -757,7 +756,7 @@ class CoreBroker(object):
if nodecls is None:
logging.warn("broker unimplemented node type %s", nodetype)
return handle_locally, servers
if issubclass(nodecls, PyCoreNet) and nodetype != NodeTypes.WIRELESS_LAN.value:
if issubclass(nodecls, CoreNetworkBase) and nodetype != NodeTypes.WIRELESS_LAN.value:
# network node replicated on all servers; could be optimized
# don"t replicate WLANs, because ebtables rules won"t work
servers = self.getservers()
@ -768,7 +767,7 @@ class CoreBroker(object):
# do not record server name for networks since network
# nodes are replicated across all server
return handle_locally, servers
elif issubclass(nodecls, PyCoreNode):
elif issubclass(nodecls, CoreNodeBase):
name = message.get_tlv(NodeTlvs.NAME.value)
if name:
serverfiletxt = "%s %s %s" % (n, name, nodecls)

View file

@ -10,22 +10,22 @@ import struct
from enum import Enum
from core.enumerations import ConfigTlvs
from core.enumerations import EventTlvs
from core.enumerations import EventTypes
from core.enumerations import ExceptionTlvs
from core.enumerations import ExecuteTlvs
from core.enumerations import FileTlvs
from core.enumerations import InterfaceTlvs
from core.enumerations import LinkTlvs
from core.enumerations import MessageFlags
from core.enumerations import MessageTypes
from core.enumerations import NodeTlvs
from core.enumerations import RegisterTlvs
from core.enumerations import SessionTlvs
from core.misc import structutils
from core.misc.ipaddress import IpAddress
from core.misc.ipaddress import MacAddress
from core.emulator.enumerations import ConfigTlvs
from core.emulator.enumerations import EventTlvs
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import ExceptionTlvs
from core.emulator.enumerations import ExecuteTlvs
from core.emulator.enumerations import FileTlvs
from core.emulator.enumerations import InterfaceTlvs
from core.emulator.enumerations import LinkTlvs
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.emulator.enumerations import NodeTlvs
from core.emulator.enumerations import RegisterTlvs
from core.emulator.enumerations import SessionTlvs
from core.api.tlv import structutils
from core.nodes.ipaddress import IpAddress
from core.nodes.ipaddress import MacAddress
class CoreTlvData(object):

View file

@ -13,36 +13,34 @@ import threading
import time
from itertools import repeat
from core.api import coreapi
from core.api import dataconversion
from core.conf import ConfigShim
from core.data import ConfigData, ExceptionData
from core.data import EventData
from core.data import FileData
from core.api.tlv import coreapi, dataconversion, structutils
from core.config import ConfigShim
from core.emulator.data import ConfigData, ExceptionData
from core.emulator.data import EventData
from core.emulator.data import FileData
from core.emulator.emudata import InterfaceData
from core.emulator.emudata import LinkOptions
from core.emulator.emudata import NodeOptions
from core.enumerations import ConfigDataTypes
from core.enumerations import ConfigFlags
from core.enumerations import ConfigTlvs
from core.enumerations import EventTlvs
from core.enumerations import EventTypes
from core.enumerations import ExceptionTlvs
from core.enumerations import ExecuteTlvs
from core.enumerations import FileTlvs
from core.enumerations import LinkTlvs
from core.enumerations import LinkTypes
from core.enumerations import MessageFlags
from core.enumerations import MessageTypes
from core.enumerations import NodeTlvs
from core.enumerations import NodeTypes
from core.enumerations import RegisterTlvs
from core.enumerations import SessionTlvs
from core.misc import nodeutils
from core.misc import structutils
from core.misc import utils
from core.service import ServiceManager
from core.service import ServiceShim
from core.emulator.enumerations import ConfigDataTypes
from core.emulator.enumerations import ConfigFlags
from core.emulator.enumerations import ConfigTlvs
from core.emulator.enumerations import EventTlvs
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import ExceptionTlvs
from core.emulator.enumerations import ExecuteTlvs
from core.emulator.enumerations import FileTlvs
from core.emulator.enumerations import LinkTlvs
from core.emulator.enumerations import LinkTypes
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.emulator.enumerations import NodeTlvs
from core.emulator.enumerations import NodeTypes
from core.emulator.enumerations import RegisterTlvs
from core.emulator.enumerations import SessionTlvs
from core.nodes import nodeutils
from core import utils
from core.services.coreservices import ServiceManager
from core.services.coreservices import ServiceShim
class CoreHandler(SocketServer.BaseRequestHandler):
@ -774,7 +772,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
return ()
try:
node = self.session.get_object(node_num)
node = self.session.get_node(node_num)
# build common TLV items for reply
tlv_data = ""
@ -1135,7 +1133,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
if not node_id:
return replies
node = self.session.get_object(node_id)
node = self.session.get_node(node_id)
if node is None:
logging.warn("request to configure service for unknown node %s", node_id)
return replies
@ -1418,7 +1416,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
if event_type.value <= EventTypes.SHUTDOWN_STATE.value:
if node_id is not None:
try:
node = self.session.get_object(node_id)
node = self.session.get_node(node_id)
except KeyError:
raise KeyError("Event message for unknown node %d" % node_id)
@ -1442,7 +1440,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
self.session.instantiate()
# after booting nodes attempt to send emulation id for nodes waiting on status
for _id in self.session.objects:
for _id in self.session.nodes:
self.send_node_emulation_id(_id)
elif event_type == EventTypes.RUNTIME_STATE:
if self.session.master:
@ -1508,7 +1506,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
name = event_data.name
try:
node = self.session.get_object(node_id)
node = self.session.get_node(node_id)
except KeyError:
logging.warn("ignoring event for service '%s', unknown node '%s'", name, node_id)
return
@ -1679,13 +1677,13 @@ class CoreHandler(SocketServer.BaseRequestHandler):
nodes_data = []
links_data = []
with self.session._objects_lock:
for obj in self.session.objects.itervalues():
node_data = obj.data(message_type=MessageFlags.ADD.value)
with self.session._nodes_lock:
for node in self.session.nodes.itervalues():
node_data = node.data(message_type=MessageFlags.ADD.value)
if node_data:
nodes_data.append(node_data)
node_links = obj.all_link_data(flags=MessageFlags.ADD.value)
node_links = node.all_link_data(flags=MessageFlags.ADD.value)
for link_data in node_links:
links_data.append(link_data)
@ -1717,7 +1715,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
for node_id, service in service_configs:
opaque = "service:%s" % service.name
data_types = tuple(repeat(ConfigDataTypes.STRING.value, len(ServiceShim.keys)))
node = self.session.get_object(node_id)
node = self.session.get_node(node_id)
values = ServiceShim.tovaluelist(node, service)
config_data = ConfigData(
message_type=0,

View file

@ -2,10 +2,9 @@
Converts CORE data objects into legacy API messages.
"""
from core.api import coreapi
from core.enumerations import ConfigTlvs
from core.enumerations import NodeTlvs
from core.misc import structutils
from core.api.tlv import coreapi, structutils
from core.emulator.enumerations import ConfigTlvs
from core.emulator.enumerations import NodeTlvs
def convert_node(node_data):

View file

@ -5,7 +5,7 @@ Common support for configurable CORE objects.
import logging
from collections import OrderedDict
from core.data import ConfigData
from core.emulator.data import ConfigData
class ConfigShim(object):

View file

@ -1,758 +0,0 @@
"""
Defines the basic objects for CORE emulation: the PyCoreObj base class, along with PyCoreNode,
PyCoreNet, and PyCoreNetIf.
"""
import os
import shutil
import socket
import threading
from socket import AF_INET
from socket import AF_INET6
from core.data import NodeData, LinkData
from core.enumerations import LinkTypes
from core.misc import ipaddress
class Position(object):
"""
Helper class for Cartesian coordinate position
"""
def __init__(self, x=None, y=None, z=None):
"""
Creates a Position instance.
:param x: x position
:param y: y position
:param z: z position
:return:
"""
self.x = x
self.y = y
self.z = z
def set(self, x=None, y=None, z=None):
"""
Returns True if the position has actually changed.
:param float x: x position
:param float y: y position
:param float z: z position
:return: True if position changed, False otherwise
:rtype: bool
"""
if self.x == x and self.y == y and self.z == z:
return False
self.x = x
self.y = y
self.z = z
return True
def get(self):
"""
Retrieve x,y,z position.
:return: x,y,z position tuple
:rtype: tuple
"""
return self.x, self.y, self.z
class PyCoreObj(object):
"""
Base class for CORE objects (nodes and networks)
"""
apitype = None
# TODO: appears start has no usage, verify and remove
def __init__(self, session, _id=None, name=None, start=True):
"""
Creates a PyCoreObj instance.
:param core.session.Session session: CORE session object
:param int _id: id
:param str name: object name
:param bool start: start value
:return:
"""
self.session = session
if _id is None:
_id = session.get_node_id()
self.id = _id
if name is None:
name = "o%s" % self.id
self.name = name
self.type = None
self.server = None
self.services = None
# ifindex is key, PyCoreNetIf instance is value
self._netif = {}
self.ifindex = 0
self.canvas = None
self.icon = None
self.opaque = None
self.position = Position()
def startup(self):
"""
Each object implements its own startup method.
:return: nothing
"""
raise NotImplementedError
def shutdown(self):
"""
Each object implements its own shutdown method.
:return: nothing
"""
raise NotImplementedError
def setposition(self, x=None, y=None, z=None):
"""
Set the (x,y,z) position of the object.
:param float x: x position
:param float y: y position
:param float z: z position
:return: True if position changed, False otherwise
:rtype: bool
"""
return self.position.set(x=x, y=y, z=z)
def getposition(self):
"""
Return an (x,y,z) tuple representing this object's position.
:return: x,y,z position tuple
:rtype: tuple
"""
return self.position.get()
def ifname(self, ifindex):
"""
Retrieve interface name for index.
:param int ifindex: interface index
:return: interface name
:rtype: str
"""
return self._netif[ifindex].name
def netifs(self, sort=False):
"""
Retrieve network interfaces, sorted if desired.
:param bool sort: boolean used to determine if interfaces should be sorted
:return: network interfaces
:rtype: list
"""
if sort:
return map(lambda k: self._netif[k], sorted(self._netif.keys()))
else:
return self._netif.itervalues()
def numnetif(self):
"""
Return the attached interface count.
:return: number of network interfaces
:rtype: int
"""
return len(self._netif)
def getifindex(self, netif):
"""
Retrieve index for an interface.
:param PyCoreNetIf netif: interface to get index for
:return: interface index if found, -1 otherwise
:rtype: int
"""
for ifindex in self._netif:
if self._netif[ifindex] is netif:
return ifindex
return -1
def newifindex(self):
"""
Create a new interface index.
:return: interface index
:rtype: int
"""
while self.ifindex in self._netif:
self.ifindex += 1
ifindex = self.ifindex
self.ifindex += 1
return ifindex
def data(self, message_type, lat=None, lon=None, alt=None):
"""
Build a data object for this node.
:param message_type: purpose for the data object we are creating
:param str lat: latitude
:param str lon: longitude
:param str alt: altitude
:return: node data object
:rtype: core.data.NodeData
"""
if self.apitype is None:
return None
x, y, _ = self.getposition()
model = self.type
emulation_server = self.server
services = self.services
if services is not None:
services = "|".join([service.name for service in services])
node_data = NodeData(
message_type=message_type,
id=self.id,
node_type=self.apitype,
name=self.name,
emulation_id=self.id,
canvas=self.canvas,
icon=self.icon,
opaque=self.opaque,
x_position=x,
y_position=y,
latitude=lat,
longitude=lon,
altitude=alt,
model=model,
emulation_server=emulation_server,
services=services
)
return node_data
def all_link_data(self, flags):
"""
Build CORE Link data for this object. There is no default
method for PyCoreObjs as PyCoreNodes do not implement this but
PyCoreNets do.
:param flags: message flags
:return: list of link data
:rtype: core.data.LinkData
"""
return []
class PyCoreNode(PyCoreObj):
"""
Base class for CORE nodes.
"""
def __init__(self, session, _id=None, name=None, start=True):
"""
Create a PyCoreNode instance.
:param core.session.Session session: CORE session object
:param int _id: object id
:param str name: object name
:param bool start: boolean for starting
"""
super(PyCoreNode, self).__init__(session, _id, name, start=start)
self.services = []
self.nodedir = None
self.tmpnodedir = False
def addservice(self, service):
"""
Add a services to the service list.
:param core.service.CoreService service: service to add
:return: nothing
"""
if service is not None:
self.services.append(service)
def makenodedir(self):
"""
Create the node directory.
:return: nothing
"""
if self.nodedir is None:
self.nodedir = os.path.join(self.session.session_dir, self.name + ".conf")
os.makedirs(self.nodedir)
self.tmpnodedir = True
else:
self.tmpnodedir = False
def rmnodedir(self):
"""
Remove the node directory, unless preserve directory has been set.
:return: nothing
"""
preserve = self.session.options.get_config("preservedir") == "1"
if preserve:
return
if self.tmpnodedir:
shutil.rmtree(self.nodedir, ignore_errors=True)
def addnetif(self, netif, ifindex):
"""
Add network interface to node and set the network interface index if successful.
:param PyCoreNetIf netif: network interface to add
:param int ifindex: interface index
:return: nothing
"""
if ifindex in self._netif:
raise ValueError("ifindex %s already exists" % ifindex)
self._netif[ifindex] = netif
# TODO: this should have probably been set ahead, seems bad to me, check for failure and fix
netif.netindex = ifindex
def delnetif(self, ifindex):
"""
Delete a network interface
:param int ifindex: interface index to delete
:return: nothing
"""
if ifindex not in self._netif:
raise ValueError("ifindex %s does not exist" % ifindex)
netif = self._netif.pop(ifindex)
netif.shutdown()
del netif
# TODO: net parameter is not used, remove
def netif(self, ifindex, net=None):
"""
Retrieve network interface.
:param int ifindex: index of interface to retrieve
:param PyCoreNetIf net: network node
:return: network interface, or None if not found
:rtype: PyCoreNetIf
"""
if ifindex in self._netif:
return self._netif[ifindex]
else:
return None
def attachnet(self, ifindex, net):
"""
Attach a network.
:param int ifindex: interface of index to attach
:param PyCoreNetIf net: network to attach
:return:
"""
if ifindex not in self._netif:
raise ValueError("ifindex %s does not exist" % ifindex)
self._netif[ifindex].attachnet(net)
def detachnet(self, ifindex):
"""
Detach network interface.
:param int ifindex: interface index to detach
:return: nothing
"""
if ifindex not in self._netif:
raise ValueError("ifindex %s does not exist" % ifindex)
self._netif[ifindex].detachnet()
def setposition(self, x=None, y=None, z=None):
"""
Set position.
:param x: x position
:param y: y position
:param z: z position
:return: nothing
"""
changed = super(PyCoreNode, self).setposition(x, y, z)
if changed:
for netif in self.netifs(sort=True):
netif.setposition(x, y, z)
def commonnets(self, obj, want_ctrl=False):
"""
Given another node or net object, return common networks between
this node and that object. A list of tuples is returned, with each tuple
consisting of (network, interface1, interface2).
:param obj: object to get common network with
:param want_ctrl: flag set to determine if control network are wanted
:return: tuples of common networks
:rtype: list
"""
common = []
for netif1 in self.netifs():
if not want_ctrl and hasattr(netif1, "control"):
continue
for netif2 in obj.netifs():
if netif1.net == netif2.net:
common.append((netif1.net, netif1, netif2))
return common
def check_cmd(self, args):
"""
Runs shell command on node.
:param list[str]|str args: command to run
:return: combined stdout and stderr
:rtype: str
:raises CoreCommandError: when a non-zero exit status occurs
"""
raise NotImplementedError
def cmd(self, args, wait=True):
"""
Runs shell command on node, with option to not wait for a result.
:param list[str]|str args: command to run
:param bool wait: wait for command to exit, defaults to True
:return: exit status for command
:rtype: int
"""
raise NotImplementedError
def cmd_output(self, args):
"""
Runs shell command on node and get exit status and output.
:param list[str]|str args: command to run
:return: exit status and combined stdout and stderr
:rtype: tuple[int, str]
"""
raise NotImplementedError
def termcmdstring(self, sh):
"""
Create a terminal command string.
:param str sh: shell to execute command in
:return: str
"""
raise NotImplementedError
class PyCoreNet(PyCoreObj):
"""
Base class for networks
"""
linktype = LinkTypes.WIRED.value
def __init__(self, session, _id, name, start=True):
"""
Create a PyCoreNet instance.
:param core.session.Session session: CORE session object
:param int _id: object id
:param str name: object name
:param bool start: should object start
"""
super(PyCoreNet, self).__init__(session, _id, name, start=start)
self._linked = {}
self._linked_lock = threading.Lock()
def startup(self):
"""
Each object implements its own startup method.
:return: nothing
"""
raise NotImplementedError
def shutdown(self):
"""
Each object implements its own shutdown method.
:return: nothing
"""
raise NotImplementedError
def attach(self, netif):
"""
Attach network interface.
:param PyCoreNetIf netif: network interface to attach
:return: nothing
"""
i = self.newifindex()
self._netif[i] = netif
netif.netifi = i
with self._linked_lock:
self._linked[netif] = {}
def detach(self, netif):
"""
Detach network interface.
:param PyCoreNetIf netif: network interface to detach
:return: nothing
"""
del self._netif[netif.netifi]
netif.netifi = None
with self._linked_lock:
del self._linked[netif]
def all_link_data(self, flags):
"""
Build link data objects for this network. Each link object describes a link
between this network and a node.
"""
all_links = []
# build a link message from this network node to each node having a
# connected interface
for netif in self.netifs(sort=True):
if not hasattr(netif, "node"):
continue
linked_node = netif.node
uni = False
if linked_node is None:
# two layer-2 switches/hubs linked together via linknet()
if not hasattr(netif, "othernet"):
continue
linked_node = netif.othernet
if linked_node.id == self.id:
continue
netif.swapparams('_params_up')
upstream_params = netif.getparams()
netif.swapparams('_params_up')
if netif.getparams() != upstream_params:
uni = True
unidirectional = 0
if uni:
unidirectional = 1
interface2_ip4 = None
interface2_ip4_mask = None
interface2_ip6 = None
interface2_ip6_mask = None
for address in netif.addrlist:
ip, _sep, mask = address.partition("/")
mask = int(mask)
if ipaddress.is_ipv4_address(ip):
family = AF_INET
ipl = socket.inet_pton(family, ip)
interface2_ip4 = ipaddress.IpAddress(af=family, address=ipl)
interface2_ip4_mask = mask
else:
family = AF_INET6
ipl = socket.inet_pton(family, ip)
interface2_ip6 = ipaddress.IpAddress(af=family, address=ipl)
interface2_ip6_mask = mask
link_data = LinkData(
message_type=flags,
node1_id=self.id,
node2_id=linked_node.id,
link_type=self.linktype,
unidirectional=unidirectional,
interface2_id=linked_node.getifindex(netif),
interface2_mac=netif.hwaddr,
interface2_ip4=interface2_ip4,
interface2_ip4_mask=interface2_ip4_mask,
interface2_ip6=interface2_ip6,
interface2_ip6_mask=interface2_ip6_mask,
delay=netif.getparam("delay"),
bandwidth=netif.getparam("bw"),
dup=netif.getparam("duplicate"),
jitter=netif.getparam("jitter"),
per=netif.getparam("loss")
)
all_links.append(link_data)
if not uni:
continue
netif.swapparams('_params_up')
link_data = LinkData(
message_type=0,
node1_id=linked_node.id,
node2_id=self.id,
unidirectional=1,
delay=netif.getparam("delay"),
bandwidth=netif.getparam("bw"),
dup=netif.getparam("duplicate"),
jitter=netif.getparam("jitter"),
per=netif.getparam("loss")
)
netif.swapparams('_params_up')
all_links.append(link_data)
return all_links
class PyCoreNetIf(object):
"""
Base class for network interfaces.
"""
def __init__(self, node, name, mtu):
"""
Creates a PyCoreNetIf instance.
:param core.coreobj.PyCoreNode node: node for interface
:param str name: interface name
:param mtu: mtu value
"""
self.node = node
self.name = name
if not isinstance(mtu, (int, long)):
raise ValueError
self.mtu = mtu
self.net = None
self._params = {}
self.addrlist = []
self.hwaddr = None
# placeholder position hook
self.poshook = lambda a, b, c, d: None
# used with EMANE
self.transport_type = None
# interface index on the network
self.netindex = None
# index used to find flow data
self.flow_id = None
def startup(self):
"""
Startup method for the interface.
:return: nothing
"""
pass
def shutdown(self):
"""
Shutdown method for the interface.
:return: nothing
"""
pass
def attachnet(self, net):
"""
Attach network.
:param core.coreobj.PyCoreNet net: network to attach
:return: nothing
"""
if self.net:
self.detachnet()
self.net = None
net.attach(self)
self.net = net
def detachnet(self):
"""
Detach from a network.
:return: nothing
"""
if self.net is not None:
self.net.detach(self)
def addaddr(self, addr):
"""
Add address.
:param str addr: address to add
:return: nothing
"""
self.addrlist.append(addr)
def deladdr(self, addr):
"""
Delete address.
:param str addr: address to delete
:return: nothing
"""
self.addrlist.remove(addr)
def sethwaddr(self, addr):
"""
Set hardware address.
:param core.misc.ipaddress.MacAddress addr: hardware address to set to.
:return: nothing
"""
self.hwaddr = addr
def getparam(self, key):
"""
Retrieve a parameter from the, or None if the parameter does not exist.
:param key: parameter to get value for
:return: parameter value
"""
return self._params.get(key)
def getparams(self):
"""
Return (key, value) pairs for parameters.
"""
parameters = []
for k in sorted(self._params.keys()):
parameters.append((k, self._params[k]))
return parameters
def setparam(self, key, value):
"""
Set a parameter value, returns True if the parameter has changed.
:param key: parameter name to set
:param value: parameter value
:return: True if parameter changed, False otherwise
"""
# treat None and 0 as unchanged values
current_value = self._params.get(key)
if current_value == value or current_value <= 0 and value <= 0:
return False
self._params[key] = value
return True
def swapparams(self, name):
"""
Swap out parameters dict for name. If name does not exist,
intialize it. This is for supporting separate upstream/downstream
parameters when two layer-2 nodes are linked together.
:param str name: name of parameter to swap
:return: nothing
"""
tmp = self._params
if not hasattr(self, name):
setattr(self, name, {})
self._params = getattr(self, name)
setattr(self, name, tmp)
def setposition(self, x, y, z):
"""
Dispatch position hook handler.
:param x: x position
:param y: y position
:param z: z position
:return: nothing
"""
self.poshook(self, x, y, z)

View file

@ -1,10 +1,10 @@
"""
EMANE Bypass model for CORE
"""
from core.conf import ConfigGroup
from core.conf import Configuration
from core.config import ConfigGroup
from core.config import Configuration
from core.emane import emanemodel
from core.enumerations import ConfigDataTypes
from core.emulator.enumerations import ConfigDataTypes
class EmaneBypassModel(emanemodel.EmaneModel):

View file

@ -7,7 +7,7 @@ import os
from lxml import etree
from core.conf import ConfigGroup
from core.config import ConfigGroup
from core.emane import emanemanifest
from core.emane import emanemodel
from core.xml import emanexml
@ -80,7 +80,7 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
transport_type = "virtual"
if interface and interface.transport_type == "raw":
transport_type = "raw"
transport_file = emanexml.transport_file_name(self.object_id, transport_type)
transport_file = emanexml.transport_file_name(self.id, transport_type)
etree.SubElement(nem_element, "transport", definition=transport_file)
# set shim configuration
@ -125,7 +125,7 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
# TODO: batch these into multiple events per transmission
# TODO: may want to split out seconds portion of delay and jitter
event = CommEffectEvent()
emane_node = self.session.get_object(self.object_id)
emane_node = self.session.get_node(self.id)
nemid = emane_node.getnemid(netif)
nemid2 = emane_node.getnemid(netif2)
mbw = bw

View file

@ -6,14 +6,13 @@ import logging
import os
import threading
from core import CoreCommandError
from core import CoreCommandError, utils
from core import constants
from core.api import coreapi
from core.api import dataconversion
from core.conf import ConfigGroup
from core.conf import ConfigShim
from core.conf import Configuration
from core.conf import ModelManager
from core.api.tlv import coreapi, dataconversion
from core.config import ConfigGroup
from core.config import ConfigShim
from core.config import Configuration
from core.config import ModelManager
from core.emane import emanemanifest
from core.emane.bypass import EmaneBypassModel
from core.emane.commeffect import EmaneCommEffectModel
@ -21,15 +20,14 @@ from core.emane.emanemodel import EmaneModel
from core.emane.ieee80211abg import EmaneIeee80211abgModel
from core.emane.rfpipe import EmaneRfPipeModel
from core.emane.tdma import EmaneTdmaModel
from core.enumerations import ConfigDataTypes
from core.enumerations import ConfigFlags
from core.enumerations import ConfigTlvs
from core.enumerations import MessageFlags
from core.enumerations import MessageTypes
from core.enumerations import NodeTypes
from core.enumerations import RegisterTlvs
from core.misc import nodeutils
from core.misc import utils
from core.emulator.enumerations import ConfigDataTypes
from core.emulator.enumerations import ConfigFlags
from core.emulator.enumerations import ConfigTlvs
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.emulator.enumerations import NodeTypes
from core.emulator.enumerations import RegisterTlvs
from core.nodes import nodeutils
from core.xml import emanexml
try:
@ -251,8 +249,8 @@ class EmaneManager(ModelManager):
logging.debug("emane setup")
# TODO: drive this from the session object
with self.session._objects_lock:
for node in self.session.objects.itervalues():
with self.session._nodes_lock:
for node in self.session.nodes.itervalues():
if nodeutils.is_node(node, NodeTypes.EMANE):
logging.debug("adding emane node: id(%s) name(%s)", node.id, node.name)
self.add_node(node)
@ -845,7 +843,7 @@ class EmaneManager(ModelManager):
# generate a node message for this location update
try:
node = self.session.get_object(n)
node = self.session.get_node(n)
except KeyError:
logging.exception("location event NEM %s has no corresponding node %s" % (nemid, n))
return False
@ -906,8 +904,8 @@ class EmaneGlobalModel(EmaneModel):
ConfigGroup("NEM Parameters", emulator_len + 1, config_len)
]
def __init__(self, session, object_id=None):
super(EmaneGlobalModel, self).__init__(session, object_id)
def __init__(self, session, _id=None):
super(EmaneGlobalModel, self).__init__(session, _id)
def build_xml_files(self, config, interface=None):
raise NotImplementedError

View file

@ -1,7 +1,7 @@
import logging
from core.conf import Configuration
from core.enumerations import ConfigDataTypes
from core.config import Configuration
from core.emulator.enumerations import ConfigDataTypes
manifest = None
try:

View file

@ -4,11 +4,11 @@ Defines Emane Models used within CORE.
import logging
import os
from core.conf import ConfigGroup
from core.conf import Configuration
from core.config import ConfigGroup
from core.config import Configuration
from core.emane import emanemanifest
from core.enumerations import ConfigDataTypes
from core.mobility import WirelessModel
from core.emulator.enumerations import ConfigDataTypes
from core.location.mobility import WirelessModel
from core.xml import emanexml
@ -105,7 +105,7 @@ class EmaneModel(WirelessModel):
transport_type = "virtual"
if interface and interface.transport_type == "raw":
transport_type = "raw"
transport_name = emanexml.transport_file_name(self.object_id, transport_type)
transport_name = emanexml.transport_file_name(self.id, transport_type)
# create nem xml file
nem_file = os.path.join(self.session.session_dir, nem_name)
@ -138,7 +138,7 @@ class EmaneModel(WirelessModel):
:return:
"""
try:
wlan = self.session.get_object(self.object_id)
wlan = self.session.get_node(self.id)
wlan.setnempositions(moved_netifs)
except KeyError:
logging.exception("error during update")

View file

@ -6,10 +6,10 @@ share the same MAC+PHY model.
import logging
from core.coreobj import PyCoreNet
from core.enumerations import LinkTypes
from core.enumerations import NodeTypes
from core.enumerations import RegisterTlvs
from core.nodes.base import CoreNetworkBase
from core.emulator.enumerations import LinkTypes
from core.emulator.enumerations import NodeTypes
from core.emulator.enumerations import RegisterTlvs
try:
from emane.events import LocationEvent
@ -20,7 +20,7 @@ except ImportError:
logging.debug("compatible emane python bindings not installed")
class EmaneNet(PyCoreNet):
class EmaneNet(CoreNetworkBase):
"""
EMANE network base class.
"""
@ -80,10 +80,10 @@ class EmaneNode(EmaneNet):
if model.config_type == RegisterTlvs.WIRELESS.value:
# EmaneModel really uses values from ConfigurableManager
# when buildnemxml() is called, not during init()
self.model = model(session=self.session, object_id=self.id)
self.model = model(session=self.session, _id=self.id)
self.model.update_config(config)
elif model.config_type == RegisterTlvs.MOBILITY.value:
self.mobility = model(session=self.session, object_id=self.id)
self.mobility = model(session=self.session, _id=self.id)
self.mobility.update_config(config)
def setnemid(self, netif, nemid):

View file

@ -5,11 +5,10 @@ tdma.py: EMANE TDMA model bindings for CORE
import logging
import os
from core import constants
from core.conf import Configuration
from core import constants, utils
from core.config import Configuration
from core.emane import emanemodel
from core.enumerations import ConfigDataTypes
from core.misc import utils
from core.emulator.enumerations import ConfigDataTypes
class EmaneTdmaModel(emanemodel.EmaneModel):
@ -49,7 +48,7 @@ class EmaneTdmaModel(emanemodel.EmaneModel):
:return: nothing
"""
# get configured schedule
config = self.session.emane.get_configs(node_id=self.object_id, config_type=self.name)
config = self.session.emane.get_configs(node_id=self.id, config_type=self.name)
if not config:
return
schedule = config[self.schedule_name]

View file

@ -5,18 +5,16 @@ import signal
import sys
import core.services
from core.coreobj import PyCoreNet
from core.coreobj import PyCoreNode
from core.data import NodeData
from core.nodes.base import CoreNodeBase, CoreNetworkBase
from core.emulator.data import NodeData
from core.emulator.emudata import LinkOptions
from core.emulator.emudata import NodeOptions
from core.enumerations import EventTypes
from core.enumerations import LinkTypes
from core.enumerations import NodeTypes
from core.misc import nodemaps
from core.misc import nodeutils
from core.service import ServiceManager
from core.session import Session
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import LinkTypes
from core.emulator.enumerations import NodeTypes
from core.nodes import nodeutils, nodemaps
from core.services.coreservices import ServiceManager
from core.emulator.session import Session
from core.xml.corexml import CoreXmlReader, CoreXmlWriter
@ -94,7 +92,7 @@ def is_net_node(node):
:return: True if object is an instance of a network node, False otherwise
:rtype: bool
"""
return isinstance(node, PyCoreNet)
return isinstance(node, CoreNetworkBase)
def is_core_node(node):
@ -105,7 +103,7 @@ def is_core_node(node):
:return: True if object is an instance of a core node, False otherwise
:rtype: bool
"""
return isinstance(node, PyCoreNode)
return isinstance(node, CoreNodeBase)
class IdGen(object):
@ -149,8 +147,8 @@ class EmuSession(Session):
net_two = None
# retrieve node one
node_one = self.get_object(node_one_id)
node_two = self.get_object(node_two_id)
node_one = self.get_node(node_one_id)
node_two = self.get_node(node_two_id)
# both node ids are provided
tunnel = self.broker.gettunnel(node_one_id, node_two_id)
@ -245,7 +243,7 @@ class EmuSession(Session):
logging.info("adding link for peer to peer nodes: %s - %s", node_one.name, node_two.name)
ptp_class = nodeutils.get_node_class(NodeTypes.PEER_TO_PEER)
start = self.state > EventTypes.DEFINITION_STATE.value
net_one = self.add_object(cls=ptp_class, start=start)
net_one = self.create_node(cls=ptp_class, start=start)
# node to network
if node_one and net_one:
@ -366,7 +364,7 @@ class EmuSession(Session):
interface_one.detachnet()
interface_two.detachnet()
if net_one.numnetif() == 0:
self.delete_object(net_one.id)
self.delete_node(net_one.id)
node_one.delnetif(interface_one.netindex)
node_two.delnetif(interface_two.netindex)
finally:
@ -483,7 +481,7 @@ class EmuSession(Session):
if not _id:
while True:
_id = self.node_id_gen.next()
if _id not in self.objects:
if _id not in self.nodes:
break
# generate name if not provided
@ -493,7 +491,7 @@ class EmuSession(Session):
# create node
logging.info("creating node(%s) id(%s) name(%s) start(%s)", node_class.__name__, _id, name, start)
node = self.add_object(cls=node_class, _id=_id, name=name, start=start)
node = self.create_node(cls=node_class, _id=_id, name=name, start=start)
# set node attributes
node.icon = node_options.icon
@ -510,9 +508,9 @@ class EmuSession(Session):
self.services.add_services(node, node.type, node_options.services)
# boot nodes if created after runtime, LcxNodes, Physical, and RJ45 are all PyCoreNodes
is_boot_node = isinstance(node, PyCoreNode) and not nodeutils.is_node(node, NodeTypes.RJ45)
is_boot_node = isinstance(node, CoreNodeBase) and not nodeutils.is_node(node, NodeTypes.RJ45)
if self.state == EventTypes.RUNTIME_STATE.value and is_boot_node:
self.write_objects()
self.write_nodes()
self.add_remove_control_interface(node=node, remove=False)
self.services.boot_services(node)
@ -530,7 +528,7 @@ class EmuSession(Session):
result = False
try:
# get node to update
node = self.get_object(node_id)
node = self.get_node(node_id)
# set node position and broadcast it
self.set_node_position(node, node_options)
@ -546,20 +544,6 @@ class EmuSession(Session):
return result
def delete_node(self, node_id):
"""
Delete a node from the session and check if session should shutdown, if no nodes are left.
:param int node_id: id of node to delete
:return: True if node deleted, False otherwise
:rtype: bool
"""
# delete node and check for session shutdown if a node was removed
result = self.custom_delete_object(node_id)
if result:
self.check_shutdown()
return result
def set_node_position(self, node, node_options):
"""
Set position for a node, use lat/lon/alt if needed.
@ -625,21 +609,6 @@ class EmuSession(Session):
self.set_state(EventTypes.SHUTDOWN_STATE, send_event=True)
super(EmuSession, self).shutdown()
def custom_delete_object(self, object_id):
"""
Remove an emulation object.
:param int object_id: object id to remove
:return: True if object deleted, False otherwise
"""
result = False
with self._objects_lock:
if object_id in self.objects:
obj = self.objects.pop(object_id)
obj.shutdown()
result = True
return result
def is_active(self):
"""
Determine if this session is considered to be active. (Runtime or Data collect states)
@ -704,7 +673,7 @@ class EmuSession(Session):
:return: nothing
"""
node = self.get_object(node_id)
node = self.get_node(node_id)
if source_name is not None:
node.addfile(source_name, file_name)
@ -717,7 +686,7 @@ class EmuSession(Session):
:return: nothing
"""
self.delete_objects()
self.delete_nodes()
self.del_hooks()
self.broker.reset()
self.emane.reset()

View file

@ -1,7 +1,7 @@
from core.enumerations import LinkTypes
from core.misc.ipaddress import Ipv4Prefix
from core.misc.ipaddress import Ipv6Prefix
from core.misc.ipaddress import MacAddress
from core.emulator.enumerations import LinkTypes
from core.nodes.ipaddress import Ipv4Prefix
from core.nodes.ipaddress import Ipv6Prefix
from core.nodes.ipaddress import MacAddress
class NodeOptions(object):

View file

@ -5,6 +5,7 @@ that manages a CORE session.
import logging
import os
import pwd
import random
import shutil
import subprocess
@ -13,31 +14,29 @@ import threading
import time
from multiprocessing.pool import ThreadPool
import pwd
from core import constants
from core.api import coreapi
from core.broker import CoreBroker
from core.conf import ConfigurableManager
from core.conf import ConfigurableOptions
from core.conf import Configuration
from core.data import EventData
from core.data import ExceptionData
import core.nodes.base
from core import constants, utils
from core.api.tlv import coreapi
from core.api.tlv.broker import CoreBroker
from core.config import ConfigurableManager
from core.config import ConfigurableOptions
from core.config import Configuration
from core.emane.emanemanager import EmaneManager
from core.enumerations import ConfigDataTypes
from core.enumerations import EventTypes
from core.enumerations import ExceptionLevels
from core.enumerations import NodeTypes
from core.enumerations import RegisterTlvs
from core.location import CoreLocation
from core.misc import nodeutils
from core.misc import utils
from core.misc.event import EventLoop
from core.misc.ipaddress import MacAddress
from core.mobility import MobilityManager
from core.netns import nodes
from core.sdt import Sdt
from core.service import CoreServices
from core.emulator.data import EventData
from core.emulator.data import ExceptionData
from core.emulator.enumerations import ConfigDataTypes
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import ExceptionLevels
from core.emulator.enumerations import NodeTypes
from core.emulator.enumerations import RegisterTlvs
from core.location.corelocation import CoreLocation
from core.location.event import EventLoop
from core.location.mobility import MobilityManager
from core.nodes import nodeutils
from core.nodes.base import CoreNodeBase
from core.nodes.ipaddress import MacAddress
from core.plugins.sdt import Sdt
from core.services.coreservices import CoreServices
from core.xml import corexml, corexmldeployment
@ -67,9 +66,9 @@ class Session(object):
self.user = None
self.event_loop = EventLoop()
# dict of objects: all nodes and nets
self.objects = {}
self._objects_lock = threading.Lock()
# dict of nodes: all nodes and nets
self.nodes = {}
self._nodes_lock = threading.Lock()
# TODO: should the default state be definition?
self.state = EventTypes.NONE.value
@ -110,15 +109,15 @@ class Session(object):
def shutdown(self):
"""
Shutdown all emulation objects and remove the session directory.
Shutdown all session nodes and remove the session directory.
"""
# shutdown/cleanup feature helpers
self.emane.shutdown()
self.broker.shutdown()
self.sdt.shutdown()
# delete all current objects
self.delete_objects()
# delete all current nodes
self.delete_nodes()
# remove this sessions working directory
preserve = self.options.get_config("preservedir") == "1"
@ -464,93 +463,87 @@ class Session(object):
"""
Return a unique, new node id.
"""
with self._objects_lock:
with self._nodes_lock:
while True:
object_id = random.randint(1, 0xFFFF)
if object_id not in self.objects:
node_id = random.randint(1, 0xFFFF)
if node_id not in self.nodes:
break
return object_id
return node_id
def add_object(self, cls, *clsargs, **clskwds):
def create_node(self, cls, *clsargs, **clskwds):
"""
Create an emulation node.
:param class cls: object class to add
:param class cls: node class to create
:param list clsargs: list of arguments for the class to create
:param dict clskwds: dictionary of arguments for the class to create
:return: the created class instance
:return: the created node instance
"""
node = cls(self, *clsargs, **clskwds)
with self._objects_lock:
if node.id in self.objects:
with self._nodes_lock:
if node.id in self.nodes:
node.shutdown()
raise KeyError("duplicate node id %s for %s" % (node.id, node.name))
self.objects[node.id] = node
self.nodes[node.id] = node
return node
def get_object(self, object_id):
def get_node(self, _id):
"""
Get an emulation object.
Get a session node.
:param int object_id: object id to retrieve
:return: object for the given id
:rtype: core.coreobj.PyCoreNode
:param int _id: node id to retrieve
:return: node for the given id
:rtype: core.nodes.base.CoreNode
"""
if object_id not in self.objects:
raise KeyError("unknown object id %s" % object_id)
return self.objects[object_id]
if _id not in self.nodes:
raise KeyError("unknown node id %s" % _id)
return self.nodes[_id]
def get_object_by_name(self, name):
def delete_node(self, _id):
"""
Get an emulation object using its name attribute.
Delete a node from the session and check if session should shutdown, if no nodes are left.
:param str name: name of object to retrieve
:return: object for the name given
:param int _id: id of node to delete
:return: True if node deleted, False otherwise
:rtype: bool
"""
with self._objects_lock:
for obj in self.objects.itervalues():
if hasattr(obj, "name") and obj.name == name:
return obj
raise KeyError("unknown object with name %s" % name)
# delete node and check for session shutdown if a node was removed
result = False
with self._nodes_lock:
if _id in self.nodes:
node = self.nodes.pop(_id)
node.shutdown()
result = True
def delete_object(self, object_id):
"""
Remove an emulation object.
if result:
self.check_shutdown()
:param int object_id: object id to remove
:return: nothing
"""
with self._objects_lock:
try:
obj = self.objects.pop(object_id)
obj.shutdown()
except KeyError:
logging.error("failed to remove object, object with id was not found: %s", object_id)
return result
def delete_objects(self):
def delete_nodes(self):
"""
Clear the objects dictionary, and call shutdown for each object.
Clear the nodes dictionary, and call shutdown for each node.
"""
with self._objects_lock:
while self.objects:
_, obj = self.objects.popitem()
obj.shutdown()
with self._nodes_lock:
while self.nodes:
_, node = self.nodes.popitem()
node.shutdown()
def write_objects(self):
def write_nodes(self):
"""
Write objects to a 'nodes' file in the session dir.
Write nodes to a 'nodes' file in the session dir.
The 'nodes' file lists: number, name, api-type, class-type
"""
try:
nodes_file = open(os.path.join(self.session_dir, "nodes"), "w")
with self._objects_lock:
for object_id in sorted(self.objects.keys()):
obj = self.objects[object_id]
nodes_file.write("%s %s %s %s\n" % (object_id, obj.name, obj.apitype, type(obj)))
nodes_file.close()
with self._nodes_lock:
file_path = os.path.join(self.session_dir, "nodes")
with open(file_path, "w") as f:
for _id in sorted(self.nodes.keys()):
node = self.nodes[_id]
f.write("%s %s %s %s\n" % (_id, node.name, node.apitype, type(node)))
except IOError:
logging.exception("error writing nodes file")
@ -560,21 +553,21 @@ class Session(object):
"""
logging.info("session id=%s name=%s state=%s", self.id, self.name, self.state)
logging.info("file=%s thumbnail=%s node_count=%s/%s",
self.file_name, self.thumbnail, self.get_node_count(), len(self.objects))
self.file_name, self.thumbnail, self.get_node_count(), len(self.nodes))
def exception(self, level, source, object_id, text):
def exception(self, level, source, node_id, text):
"""
Generate and broadcast an exception event.
:param str level: exception level
:param str source: source name
:param int object_id: object id
:param int node_id: node related to exception
:param str text: exception message
:return: nothing
"""
exception_data = ExceptionData(
node=object_id,
node=node_id,
session=str(self.id),
level=level,
source=source,
@ -591,8 +584,8 @@ class Session(object):
for transition to the runtime state.
"""
# write current objects out to session directory file
self.write_objects()
# write current nodes out to session directory file
self.write_nodes()
# controlnet may be needed by some EMANE models
self.add_remove_control_interface(node=None, remove=False)
@ -626,12 +619,12 @@ class Session(object):
that are not considered in the GUI's node count.
"""
with self._objects_lock:
count = len([x for x in self.objects.itervalues()
with self._nodes_lock:
count = len([x for x in self.nodes.itervalues()
if not nodeutils.is_node(x, (NodeTypes.PEER_TO_PEER, NodeTypes.CONTROL_NET))])
# on Linux, GreTapBridges are auto-created, not part of GUI's node count
count -= len([x for x in self.objects.itervalues()
count -= len([x for x in self.nodes.itervalues()
if nodeutils.is_node(x, NodeTypes.TAP_BRIDGE) and not nodeutils.is_node(x, NodeTypes.TUNNEL)])
return count
@ -668,10 +661,10 @@ class Session(object):
self.event_loop.stop()
# stop node services
with self._objects_lock:
for obj in self.objects.itervalues():
with self._nodes_lock:
for obj in self.nodes.itervalues():
# TODO: determine if checking for CoreNode alone is ok
if isinstance(obj, nodes.PyCoreNode):
if isinstance(obj, core.nodes.base.CoreNodeBase):
self.services.stop_services(obj)
# shutdown emane
@ -715,14 +708,14 @@ class Session(object):
messages to the GUI for node messages that had the status
request flag.
"""
with self._objects_lock:
with self._nodes_lock:
pool = ThreadPool()
results = []
start = time.time()
for obj in self.objects.itervalues():
for obj in self.nodes.itervalues():
# TODO: PyCoreNode is not the type to check
if isinstance(obj, nodes.PyCoreNode) and not nodeutils.is_node(obj, NodeTypes.RJ45):
if isinstance(obj, CoreNodeBase) and not nodeutils.is_node(obj, NodeTypes.RJ45):
# add a control interface if configured
logging.info("booting node: %s", obj.name)
self.add_remove_control_interface(node=obj, remove=False)
@ -786,10 +779,10 @@ class Session(object):
return index
return -1
def get_control_net_object(self, net_index):
def get_control_net(self, net_index):
# TODO: all nodes use an integer id and now this wants to use a string
object_id = "ctrl%dnet" % net_index
return self.get_object(object_id)
_id = "ctrl%dnet" % net_index
return self.get_node(_id)
def add_remove_control_net(self, net_index, remove=False, conf_required=True):
"""
@ -801,8 +794,8 @@ class Session(object):
:param int net_index: network index
:param bool remove: flag to check if it should be removed
:param bool conf_required: flag to check if conf is required
:return: control net object
:rtype: core.netns.nodes.CtrlNet
:return: control net node
:rtype: core.nodes.network.CtrlNet
"""
logging.debug("add/remove control net: index(%s) remove(%s) conf_required(%s)", net_index, remove, conf_required)
prefix_spec_list = self.get_control_net_prefixes()
@ -820,10 +813,10 @@ class Session(object):
# return any existing controlnet bridge
try:
control_net = self.get_control_net_object(net_index)
control_net = self.get_control_net(net_index)
if remove:
self.delete_object(control_net.id)
self.delete_node(control_net.id)
return None
return control_net
@ -832,7 +825,7 @@ class Session(object):
return None
# build a new controlnet bridge
object_id = "ctrl%dnet" % net_index
_id = "ctrl%dnet" % net_index
# use the updown script for control net 0 only.
updown_script = None
@ -887,16 +880,16 @@ class Session(object):
prefix = prefixes[0]
control_net_class = nodeutils.get_node_class(NodeTypes.CONTROL_NET)
control_net = self.add_object(cls=control_net_class, _id=object_id, prefix=prefix,
assign_address=assign_address,
updown_script=updown_script, serverintf=server_interface)
control_net = self.create_node(cls=control_net_class, _id=_id, prefix=prefix,
assign_address=assign_address,
updown_script=updown_script, serverintf=server_interface)
# tunnels between controlnets will be built with Broker.addnettunnels()
# TODO: potentially remove documentation saying object ids are ints
# TODO: potentially remove documentation saying node ids are ints
# TODO: need to move broker code out of the session object
self.broker.addnet(object_id)
self.broker.addnet(_id)
for server in self.broker.getservers():
self.broker.addnodemap(server, object_id)
self.broker.addnodemap(server, _id)
return control_net
@ -908,7 +901,7 @@ class Session(object):
If conf_reqd is False, the control network may be built even
when the user has not configured one (e.g. for EMANE.)
:param core.netns.nodes.CoreNode node: node to add or remove control interface
:param core.netns.vnode.CoreNode node: node to add or remove control interface
:param int net_index: network index
:param bool remove: flag to check if it should be removed
:param bool conf_required: flag to check if conf is required
@ -954,9 +947,9 @@ class Session(object):
return
try:
control_net = self.get_control_net_object(net_index)
control_net = self.get_control_net(net_index)
except KeyError:
logging.exception("error retrieving control net object")
logging.exception("error retrieving control net node")
return
header = "CORE session %s host entries" % self.id
@ -991,7 +984,7 @@ class Session(object):
start of the runtime state.
:param event_time: event time
:param core.netns.nodes.CoreNode node: node to add event for
:param core.netns.vnode.CoreNode node: node to add event for
:param str name: name of event
:param data: data for event
:return: nothing
@ -1029,13 +1022,13 @@ class Session(object):
if not node_id:
utils.mute_detach(data)
else:
node = self.get_object(node_id)
node = self.get_node(node_id)
node.cmd(data, wait=False)
class SessionConfig(ConfigurableManager, ConfigurableOptions):
"""
Session configuration object.
Provides session configuration.
"""
name = "session"
options = [

View file

@ -7,8 +7,8 @@ https://pypi.python.org/pypi/utm (version 0.3.0).
import logging
from core.enumerations import RegisterTlvs
from core.misc import utm
from core.emulator.enumerations import RegisterTlvs
from core.location import utm
class CoreLocation(object):

View file

@ -9,22 +9,22 @@ import os
import threading
import time
from core.conf import ConfigGroup
from core.conf import ConfigurableOptions
from core.conf import Configuration
from core.conf import ModelManager
from core.coreobj import PyCoreNode
from core.data import EventData
from core.data import LinkData
from core.enumerations import ConfigDataTypes
from core.enumerations import EventTypes
from core.enumerations import LinkTypes
from core.enumerations import MessageFlags
from core.enumerations import MessageTypes
from core.enumerations import NodeTlvs
from core.enumerations import RegisterTlvs
from core.misc import utils
from core.misc.ipaddress import IpAddress
from core.config import ConfigGroup
from core.config import ConfigurableOptions
from core.config import Configuration
from core.config import ModelManager
from core.nodes.base import CoreNodeBase
from core.emulator.data import EventData
from core.emulator.data import LinkData
from core.emulator.enumerations import ConfigDataTypes
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import LinkTypes
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.emulator.enumerations import NodeTlvs
from core.emulator.enumerations import RegisterTlvs
from core import utils
from core.nodes.ipaddress import IpAddress
class MobilityManager(ModelManager):
@ -67,7 +67,7 @@ class MobilityManager(ModelManager):
logging.info("node mobility configurations: %s", self.get_all_configs(node_id))
try:
node = self.session.get_object(node_id)
node = self.session.get_node(node_id)
except KeyError:
logging.warn("skipping mobility configuration for unknown node: %s", node_id)
continue
@ -98,7 +98,7 @@ class MobilityManager(ModelManager):
name = event_data.name
try:
node = self.session.get_object(node_id)
node = self.session.get_node(node_id)
except KeyError:
logging.exception("Ignoring event for model '%s', unknown node '%s'", name, node_id)
return
@ -152,7 +152,7 @@ class MobilityManager(ModelManager):
data += " end=%d" % int(model.endtime)
event_data = EventData(
node=model.object_id,
node=model.id,
event_type=event_type,
name="mobility:%s" % model.name,
data=data,
@ -173,7 +173,7 @@ class MobilityManager(ModelManager):
"""
for node_id in self.nodes():
try:
node = self.session.get_object(node_id)
node = self.session.get_node(node_id)
except KeyError:
continue
if node.model:
@ -213,7 +213,7 @@ class MobilityManager(ModelManager):
return
if nn[1] in self.session.broker.physical_nodes:
# record the fact that this PhysicalNode is linked to a net
dummy = PyCoreNode(session=self.session, _id=nn[1], name="n%d" % nn[1], start=False)
dummy = CoreNodeBase(session=self.session, _id=nn[1], name="n%d" % nn[1], start=False)
self.addphys(nn[0], dummy)
# TODO: remove need to handling old style messages
@ -265,15 +265,15 @@ class WirelessModel(ConfigurableOptions):
bitmap = None
position_callback = None
def __init__(self, session, object_id):
def __init__(self, session, _id):
"""
Create a WirelessModel instance.
:param core.session.Session session: core session we are tied to
:param int object_id: object id
:param int _id: object id
"""
self.session = session
self.object_id = object_id
self.id = _id
def all_link_data(self, flags):
"""
@ -329,17 +329,17 @@ class BasicRangeModel(WirelessModel):
ConfigGroup("Basic Range Parameters", 1, len(cls.configurations()))
]
def __init__(self, session, object_id):
def __init__(self, session, _id):
"""
Create a BasicRangeModel instance.
:param core.session.Session session: related core session
:param int object_id: object id
:param int _id: object id
:param dict config: values
"""
super(BasicRangeModel, self).__init__(session=session, object_id=object_id)
super(BasicRangeModel, self).__init__(session=session, _id=_id)
self.session = session
self.wlan = session.get_object(object_id)
self.wlan = session.get_node(_id)
self._netifs = {}
self._netifslock = threading.Lock()
@ -605,15 +605,15 @@ class WayPointMobility(WirelessModel):
STATE_RUNNING = 1
STATE_PAUSED = 2
def __init__(self, session, object_id):
def __init__(self, session, _id):
"""
Create a WayPointMobility instance.
:param core.session.Session session: CORE session instance
:param int object_id: object id
:param int _id: object id
:return:
"""
super(WayPointMobility, self).__init__(session=session, object_id=object_id)
super(WayPointMobility, self).__init__(session=session, _id=_id)
self.state = self.STATE_STOPPED
self.queue = []
@ -622,7 +622,7 @@ class WayPointMobility(WirelessModel):
self.initial = {}
self.lasttime = None
self.endtime = None
self.wlan = session.get_object(object_id)
self.wlan = session.get_node(_id)
# these are really set in child class via confmatrix
self.loop = False
self.refresh_ms = 50
@ -700,7 +700,7 @@ class WayPointMobility(WirelessModel):
Calculate next node location and update its coordinates.
Returns True if the node's position has changed.
:param core.netns.nodes.CoreNode node: node to move
:param core.netns.vnode.CoreNode node: node to move
:param dt: move factor
:return: True if node was moved, False otherwise
:rtype: bool
@ -830,7 +830,7 @@ class WayPointMobility(WirelessModel):
without invoking the interface poshook callback that may perform
range calculation.
:param core.netns.nodes.CoreNode node: node to set position for
:param core.netns.vnode.CoreNode node: node to set position for
:param x: x position
:param y: y position
:param z: z position
@ -923,15 +923,15 @@ class Ns2ScriptedMobility(WayPointMobility):
ConfigGroup("ns-2 Mobility Script Parameters", 1, len(cls.configurations()))
]
def __init__(self, session, object_id):
def __init__(self, session, _id):
"""
Creates a Ns2ScriptedMobility instance.
:param core.session.Session session: CORE session instance
:param int object_id: object id
:param int _id: object id
:param config: values
"""
super(Ns2ScriptedMobility, self).__init__(session=session, object_id=object_id)
super(Ns2ScriptedMobility, self).__init__(session=session, _id=_id)
self._netifs = {}
self._netifslock = threading.Lock()
@ -946,7 +946,7 @@ class Ns2ScriptedMobility(WayPointMobility):
def update_config(self, config):
self.file = config["file"]
logging.info("ns-2 scripted mobility configured for WLAN %d using file: %s", self.object_id, self.file)
logging.info("ns-2 scripted mobility configured for WLAN %d using file: %s", self.id, self.file)
self.refresh_ms = int(config["refresh_ms"])
self.loop = config["loop"].lower() == "on"
self.autostart = config["autostart"]

View file

@ -1,246 +0,0 @@
#!/usr/bin/env python
# this file is from http://pygps.org/
# Lat Long - UTM, UTM - Lat Long conversions
from math import pi, sin, cos, tan, sqrt
# LatLong- UTM conversion..h
# definitions for lat/long to UTM and UTM to lat/lng conversions
# include <string.h>
_deg2rad = pi / 180.0
_rad2deg = 180.0 / pi
_EquatorialRadius = 2
_eccentricitySquared = 3
_ellipsoid = [
# id, Ellipsoid name, Equatorial Radius, square of eccentricity
# first once is a placeholder only, To allow array indices to match id numbers
[-1, "Placeholder", 0, 0],
[1, "Airy", 6377563, 0.00667054],
[2, "Australian National", 6378160, 0.006694542],
[3, "Bessel 1841", 6377397, 0.006674372],
[4, "Bessel 1841 (Nambia] ", 6377484, 0.006674372],
[5, "Clarke 1866", 6378206, 0.006768658],
[6, "Clarke 1880", 6378249, 0.006803511],
[7, "Everest", 6377276, 0.006637847],
[8, "Fischer 1960 (Mercury] ", 6378166, 0.006693422],
[9, "Fischer 1968", 6378150, 0.006693422],
[10, "GRS 1967", 6378160, 0.006694605],
[11, "GRS 1980", 6378137, 0.00669438],
[12, "Helmert 1906", 6378200, 0.006693422],
[13, "Hough", 6378270, 0.00672267],
[14, "International", 6378388, 0.00672267],
[15, "Krassovsky", 6378245, 0.006693422],
[16, "Modified Airy", 6377340, 0.00667054],
[17, "Modified Everest", 6377304, 0.006637847],
[18, "Modified Fischer 1960", 6378155, 0.006693422],
[19, "South American 1969", 6378160, 0.006694542],
[20, "WGS 60", 6378165, 0.006693422],
[21, "WGS 66", 6378145, 0.006694542],
[22, "WGS-72", 6378135, 0.006694318],
[23, "WGS-84", 6378137, 0.00669438]
]
# Reference ellipsoids derived from Peter H. Dana's website-
# http://www.utexas.edu/depts/grg/gcraft/notes/datum/elist.html
# Department of Geography, University of Texas at Austin
# Internet: pdana@mail.utexas.edu
# 3/22/95
# Source
# Defense Mapping Agency. 1987b. DMA Technical Report: Supplement to Department of Defense World Geodetic System
# 1984 Technical Report. Part I and II. Washington, DC: Defense Mapping Agency
# def LLtoUTM(int ReferenceEllipsoid, const double Lat, const double Long,
# double &UTMNorthing, double &UTMEasting, char* UTMZone)
def LLtoUTM(ReferenceEllipsoid, Lat, Long, zone=None):
"""converts lat/long to UTM coords. Equations from USGS Bulletin 1532
East Longitudes are positive, West longitudes are negative.
North latitudes are positive, South latitudes are negative
Lat and Long are in decimal degrees
Written by Chuck Gantz- chuck.gantz@globalstar.com"""
a = _ellipsoid[ReferenceEllipsoid][_EquatorialRadius]
eccSquared = _ellipsoid[ReferenceEllipsoid][_eccentricitySquared]
k0 = 0.9996
# Make sure the longitude is between -180.00 .. 179.9
LongTemp = (Long + 180) - int((Long + 180) / 360) * 360 - 180 # -180.00 .. 179.9
LatRad = Lat * _deg2rad
LongRad = LongTemp * _deg2rad
if zone is None:
ZoneNumber = int((LongTemp + 180) / 6) + 1
else:
ZoneNumber = zone
if Lat >= 56.0 and Lat < 64.0 and LongTemp >= 3.0 and LongTemp < 12.0:
ZoneNumber = 32
# Special zones for Svalbard
if Lat >= 72.0 and Lat < 84.0:
if LongTemp >= 0.0 and LongTemp < 9.0:
ZoneNumber = 31
elif LongTemp >= 9.0 and LongTemp < 21.0:
ZoneNumber = 33
elif LongTemp >= 21.0 and LongTemp < 33.0:
ZoneNumber = 35
elif LongTemp >= 33.0 and LongTemp < 42.0:
ZoneNumber = 37
LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3 # +3 puts origin in middle of zone
LongOriginRad = LongOrigin * _deg2rad
# compute the UTM Zone from the latitude and longitude
UTMZone = "%d%c" % (ZoneNumber, _UTMLetterDesignator(Lat))
eccPrimeSquared = (eccSquared) / (1 - eccSquared)
N = a / sqrt(1 - eccSquared * sin(LatRad) * sin(LatRad))
T = tan(LatRad) * tan(LatRad)
C = eccPrimeSquared * cos(LatRad) * cos(LatRad)
A = cos(LatRad) * (LongRad - LongOriginRad)
M = a * ((1
- eccSquared / 4
- 3 * eccSquared * eccSquared / 64
- 5 * eccSquared * eccSquared * eccSquared / 256) * LatRad
- (3 * eccSquared / 8
+ 3 * eccSquared * eccSquared / 32
+ 45 * eccSquared * eccSquared * eccSquared / 1024) * sin(2 * LatRad)
+ (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * sin(4 * LatRad)
- (35 * eccSquared * eccSquared * eccSquared / 3072) * sin(6 * LatRad))
UTMEasting = (k0 * N * (A + (1 - T + C) * A * A * A / 6
+ (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120)
+ 500000.0)
UTMNorthing = (k0 * (M + N * tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24
+ (61
- 58 * T
+ T * T
+ 600 * C
- 330 * eccPrimeSquared) * A * A * A * A * A * A / 720)))
if Lat < 0:
UTMNorthing = UTMNorthing + 10000000.0; # 10000000 meter offset for southern hemisphere
return (UTMZone, UTMEasting, UTMNorthing)
def _UTMLetterDesignator(Lat):
"""This routine determines the correct UTM letter designator for the given
latitude returns 'Z' if latitude is outside the UTM limits of 84N to 80S
Written by Chuck Gantz- chuck.gantz@globalstar.com"""
if 84 >= Lat >= 72:
return 'X'
elif 72 > Lat >= 64:
return 'W'
elif 64 > Lat >= 56:
return 'V'
elif 56 > Lat >= 48:
return 'U'
elif 48 > Lat >= 40:
return 'T'
elif 40 > Lat >= 32:
return 'S'
elif 32 > Lat >= 24:
return 'R'
elif 24 > Lat >= 16:
return 'Q'
elif 16 > Lat >= 8:
return 'P'
elif 8 > Lat >= 0:
return 'N'
elif 0 > Lat >= -8:
return 'M'
elif -8 > Lat >= -16:
return 'L'
elif -16 > Lat >= -24:
return 'K'
elif -24 > Lat >= -32:
return 'J'
elif -32 > Lat >= -40:
return 'H'
elif -40 > Lat >= -48:
return 'G'
elif -48 > Lat >= -56:
return 'F'
elif -56 > Lat >= -64:
return 'E'
elif -64 > Lat >= -72:
return 'D'
elif -72 > Lat >= -80:
return 'C'
else:
return 'Z' # if the Latitude is outside the UTM limits
# void UTMtoLL(int ReferenceEllipsoid, const double UTMNorthing, const double UTMEasting, const char* UTMZone,
# double& Lat, double& Long )
def UTMtoLL(ReferenceEllipsoid, northing, easting, zone):
"""converts UTM coords to lat/long. Equations from USGS Bulletin 1532
East Longitudes are positive, West longitudes are negative.
North latitudes are positive, South latitudes are negative
Lat and Long are in decimal degrees.
Written by Chuck Gantz- chuck.gantz@globalstar.com
Converted to Python by Russ Nelson <nelson@crynwr.com>"""
k0 = 0.9996
a = _ellipsoid[ReferenceEllipsoid][_EquatorialRadius]
eccSquared = _ellipsoid[ReferenceEllipsoid][_eccentricitySquared]
e1 = (1 - sqrt(1 - eccSquared)) / (1 + sqrt(1 - eccSquared))
# NorthernHemisphere; //1 for northern hemispher, 0 for southern
x = easting - 500000.0 # remove 500,000 meter offset for longitude
y = northing
ZoneLetter = zone[-1]
ZoneNumber = int(zone[:-1])
if ZoneLetter >= 'N':
NorthernHemisphere = 1 # point is in northern hemisphere
else:
NorthernHemisphere = 0 # point is in southern hemisphere
y -= 10000000.0 # remove 10,000,000 meter offset used for southern hemisphere
LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3 # +3 puts origin in middle of zone
eccPrimeSquared = (eccSquared) / (1 - eccSquared)
M = y / k0
mu = M / (
a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256))
phi1Rad = (mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * sin(2 * mu)
+ (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * sin(4 * mu)
+ (151 * e1 * e1 * e1 / 96) * sin(6 * mu))
phi1 = phi1Rad * _rad2deg;
N1 = a / sqrt(1 - eccSquared * sin(phi1Rad) * sin(phi1Rad))
T1 = tan(phi1Rad) * tan(phi1Rad)
C1 = eccPrimeSquared * cos(phi1Rad) * cos(phi1Rad)
R1 = a * (1 - eccSquared) / pow(1 - eccSquared * sin(phi1Rad) * sin(phi1Rad), 1.5)
D = x / (N1 * k0)
Lat = phi1Rad - (N1 * tan(phi1Rad) / R1) * (
D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24
+ (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720)
Lat = Lat * _rad2deg
Long = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (
5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1)
* D * D * D * D * D / 120) / cos(phi1Rad)
Long = LongOrigin + Long * _rad2deg
return (Lat, Long)
if __name__ == '__main__':
(z, e, n) = LLtoUTM(23, 45.00, -75.00)
print z, e, n
print UTMtoLL(23, n, e, z)

View file

@ -1,28 +0,0 @@
"""
Provides default node maps that can be used to run core with.
"""
from core.emane.nodes import EmaneNet
from core.emane.nodes import EmaneNode
from core.enumerations import NodeTypes
from core.netns import nodes
from core.netns.vnet import GreTapBridge
from core.phys import pnodes
# legacy core nodes, that leverage linux bridges
NODES = {
NodeTypes.DEFAULT: nodes.CoreNode,
NodeTypes.PHYSICAL: pnodes.PhysicalNode,
NodeTypes.TBD: None,
NodeTypes.SWITCH: nodes.SwitchNode,
NodeTypes.HUB: nodes.HubNode,
NodeTypes.WIRELESS_LAN: nodes.WlanNode,
NodeTypes.RJ45: nodes.RJ45Node,
NodeTypes.TUNNEL: nodes.TunnelNode,
NodeTypes.KTUNNEL: None,
NodeTypes.EMANE: EmaneNode,
NodeTypes.EMANE_NET: EmaneNet,
NodeTypes.TAP_BRIDGE: GreTapBridge,
NodeTypes.PEER_TO_PEER: nodes.PtpNet,
NodeTypes.CONTROL_NET: nodes.CtrlNet
}

View file

@ -1,172 +0,0 @@
"""
quagga.py: helper class for generating Quagga configuration.
"""
from string import Template
from core.misc import utils
def addrstr(x):
if x.find(".") >= 0:
return "ip address %s" % x
elif x.find(":") >= 0:
return "ipv6 address %s" % x
else:
raise ValueError("invalid address: %s" % x)
class NetIf(object):
"""
Represents a network interface.
"""
def __init__(self, name, addrlist=None):
"""
Create a NetIf instance.
:param str name: interface name
:param addrlist: address list for the interface
"""
self.name = name
if addrlist:
self.addrlist = addrlist
else:
self.addrlist = []
class Conf(object):
"""
Provides a configuration object.
"""
template = Template("")
def __init__(self, **kwargs):
"""
Create a Conf instance.
:param dict kwargs: configuration keyword arguments
"""
self.kwargs = kwargs
def __str__(self):
"""
Provides a string representation of a configuration object.
:return: string representation
:rtype: str
"""
tmp = self.template.substitute(**self.kwargs)
if tmp[-1] == "\n":
tmp = tmp[:-1]
return tmp
class QuaggaOSPF6Interface(Conf):
"""
Provides quagga ospf6 interface functionality.
"""
AF_IPV6_ID = 0
AF_IPV4_ID = 65
template = Template("""\
interface $interface
$addr
ipv6 ospf6 instance-id $instanceid
ipv6 ospf6 hello-interval 2
ipv6 ospf6 dead-interval 11
ipv6 ospf6 retransmit-interval 5
ipv6 ospf6 network $network
ipv6 ospf6 diffhellos
ipv6 ospf6 adjacencyconnectivity uniconnected
ipv6 ospf6 lsafullness mincostlsa
""")
# ip address $ipaddr/32
# ipv6 ospf6 simhelloLLtoULRecv :$simhelloport
# !$ipaddr:$simhelloport
def __init__(self, netif, instanceid=AF_IPV4_ID, network="manet-designated-router", **kwargs):
"""
Create a QuaggaOSPF6Interface instance.
:param netif: network interface
:param int instanceid: instance id
:param network: network
:param dict kwargs: keyword arguments
"""
self.netif = netif
addr = "\n ".join(map(addrstr, netif.addrlist))
self.instanceid = instanceid
self.network = network
Conf.__init__(self, interface=netif.name, addr=addr,
instanceid=instanceid, network=network, **kwargs)
def name(self):
"""
Retrieve network interface name.
:return: network interface name
:rtype: str
"""
return self.netif.name
class QuaggaOSPF6(Conf):
"""
Provides quagga ospf6 functionality.
"""
template = Template("""\
$interfaces
!
router ospf6
router-id $routerid
$ospfifs
$redistribute
""")
def __init__(self, ospf6ifs, area, routerid, redistribute="! no redistribute"):
"""
Create a QuaggaOSPF6 instance.
:param list ospf6ifs: ospf6 interfaces
:param area: area
:param routerid: router id
:param str redistribute: redistribute value
"""
ospf6ifs = utils.make_tuple(ospf6ifs)
interfaces = "\n!\n".join(map(str, ospf6ifs))
ospfifs = "\n ".join(map(lambda x: "interface %s area %s" % (x.name(), area), ospf6ifs))
Conf.__init__(self, interfaces=interfaces, routerid=routerid, ospfifs=ospfifs, redistribute=redistribute)
class QuaggaConf(Conf):
"""
Provides quagga configuration functionality.
"""
template = Template("""\
log file $logfile
$debugs
!
$routers
!
$forwarding
""")
def __init__(self, routers, logfile, debugs=()):
"""
Create a QuaggaConf instance.
:param list routers: routers
:param str logfile: log file name
:param debugs: debug options
"""
routers = "\n!\n".join(map(str, utils.make_tuple(routers)))
if debugs:
debugs = "\n".join(utils.make_tuple(debugs))
else:
debugs = "! no debugs"
forwarding = "ip forwarding\nipv6 forwarding"
Conf.__init__(self, logfile=logfile, debugs=debugs, routers=routers, forwarding=forwarding)

View file

@ -1,739 +0,0 @@
"""
Definition of LxcNode, CoreNode, and other node classes that inherit from the CoreNode,
implementing specific node types.
"""
import logging
import socket
import threading
from socket import AF_INET
from socket import AF_INET6
from core import CoreCommandError
from core import constants
from core.coreobj import PyCoreNetIf
from core.coreobj import PyCoreNode
from core.coreobj import PyCoreObj
from core.data import LinkData
from core.enumerations import LinkTypes
from core.enumerations import NodeTypes
from core.enumerations import RegisterTlvs
from core.misc import ipaddress
from core.misc import utils
from core.netns.vnet import GreTapBridge
from core.netns.vnet import LxBrNet
from core.netns.vnode import LxcNode
class CtrlNet(LxBrNet):
"""
Control network functionality.
"""
policy = "ACCEPT"
# base control interface index
CTRLIF_IDX_BASE = 99
DEFAULT_PREFIX_LIST = [
"172.16.0.0/24 172.16.1.0/24 172.16.2.0/24 172.16.3.0/24 172.16.4.0/24",
"172.17.0.0/24 172.17.1.0/24 172.17.2.0/24 172.17.3.0/24 172.17.4.0/24",
"172.18.0.0/24 172.18.1.0/24 172.18.2.0/24 172.18.3.0/24 172.18.4.0/24",
"172.19.0.0/24 172.19.1.0/24 172.19.2.0/24 172.19.3.0/24 172.19.4.0/24"
]
def __init__(self, session, _id="ctrlnet", name=None, prefix=None,
hostid=None, start=True, assign_address=True,
updown_script=None, serverintf=None):
"""
Creates a CtrlNet instance.
:param core.session.Session session: core session instance
:param int _id: node id
:param str name: node namee
:param prefix: control network ipv4 prefix
:param hostid: host id
:param bool start: start flag
:param str assign_address: assigned address
:param str updown_script: updown script
:param serverintf: server interface
:return:
"""
self.prefix = ipaddress.Ipv4Prefix(prefix)
self.hostid = hostid
self.assign_address = assign_address
self.updown_script = updown_script
self.serverintf = serverintf
LxBrNet.__init__(self, session, _id=_id, name=name, start=start)
def startup(self):
"""
Startup functionality for the control network.
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
if self.detectoldbridge():
return
LxBrNet.startup(self)
if self.hostid:
addr = self.prefix.addr(self.hostid)
else:
addr = self.prefix.max_addr()
logging.info("added control network bridge: %s %s", self.brname, self.prefix)
if self.assign_address:
addrlist = ["%s/%s" % (addr, self.prefix.prefixlen)]
self.addrconfig(addrlist=addrlist)
logging.info("address %s", addr)
if self.updown_script:
logging.info("interface %s updown script (%s startup) called", self.brname, self.updown_script)
utils.check_cmd([self.updown_script, self.brname, "startup"])
if self.serverintf:
# sets the interface as a port of the bridge
utils.check_cmd([constants.BRCTL_BIN, "addif", self.brname, self.serverintf])
# bring interface up
utils.check_cmd([constants.IP_BIN, "link", "set", self.serverintf, "up"])
def detectoldbridge(self):
"""
Occassionally, control net bridges from previously closed sessions are not cleaned up.
Check if there are old control net bridges and delete them
:return: True if an old bridge was detected, False otherwise
:rtype: bool
"""
status, output = utils.cmd_output([constants.BRCTL_BIN, "show"])
if status != 0:
logging.error("Unable to retrieve list of installed bridges")
else:
lines = output.split("\n")
for line in lines[1:]:
cols = line.split("\t")
oldbr = cols[0]
flds = cols[0].split(".")
if len(flds) == 3:
if flds[0] == "b" and flds[1] == self.id:
logging.error(
"error: An active control net bridge (%s) found. "
"An older session might still be running. "
"Stop all sessions and, if needed, delete %s to continue.", oldbr, oldbr
)
return True
return False
def shutdown(self):
"""
Control network shutdown.
:return: nothing
"""
if self.serverintf is not None:
try:
utils.check_cmd([constants.BRCTL_BIN, "delif", self.brname, self.serverintf])
except CoreCommandError:
logging.exception("error deleting server interface %s from bridge %s", self.serverintf, self.brname)
if self.updown_script is not None:
try:
logging.info("interface %s updown script (%s shutdown) called", self.brname, self.updown_script)
utils.check_cmd([self.updown_script, self.brname, "shutdown"])
except CoreCommandError:
logging.exception("error issuing shutdown script shutdown")
LxBrNet.shutdown(self)
def all_link_data(self, flags):
"""
Do not include CtrlNet in link messages describing this session.
:param flags: message flags
:return: list of link data
:rtype: list[core.data.LinkData]
"""
return []
class CoreNode(LxcNode):
"""
Basic core node class for nodes to extend.
"""
apitype = NodeTypes.DEFAULT.value
class PtpNet(LxBrNet):
"""
Peer to peer network node.
"""
policy = "ACCEPT"
def attach(self, netif):
"""
Attach a network interface, but limit attachment to two interfaces.
:param core.netns.vif.VEth netif: network interface
:return: nothing
"""
if len(self._netif) >= 2:
raise ValueError("Point-to-point links support at most 2 network interfaces")
LxBrNet.attach(self, netif)
def data(self, message_type, lat=None, lon=None, alt=None):
"""
Do not generate a Node Message for point-to-point links. They are
built using a link message instead.
:param message_type: purpose for the data object we are creating
:param float lat: latitude
:param float lon: longitude
:param float alt: altitude
:return: node data object
:rtype: core.data.NodeData
"""
return None
def all_link_data(self, flags):
"""
Build CORE API TLVs for a point-to-point link. One Link message
describes this network.
:param flags: message flags
:return: list of link data
:rtype: list[core.data.LinkData]
"""
all_links = []
if len(self._netif) != 2:
return all_links
if1, if2 = self._netif.values()
unidirectional = 0
if if1.getparams() != if2.getparams():
unidirectional = 1
interface1_ip4 = None
interface1_ip4_mask = None
interface1_ip6 = None
interface1_ip6_mask = None
for address in if1.addrlist:
ip, _sep, mask = address.partition("/")
mask = int(mask)
if ipaddress.is_ipv4_address(ip):
family = AF_INET
ipl = socket.inet_pton(family, ip)
interface1_ip4 = ipaddress.IpAddress(af=family, address=ipl)
interface1_ip4_mask = mask
else:
family = AF_INET6
ipl = socket.inet_pton(family, ip)
interface1_ip6 = ipaddress.IpAddress(af=family, address=ipl)
interface1_ip6_mask = mask
interface2_ip4 = None
interface2_ip4_mask = None
interface2_ip6 = None
interface2_ip6_mask = None
for address in if2.addrlist:
ip, _sep, mask = address.partition("/")
mask = int(mask)
if ipaddress.is_ipv4_address(ip):
family = AF_INET
ipl = socket.inet_pton(family, ip)
interface2_ip4 = ipaddress.IpAddress(af=family, address=ipl)
interface2_ip4_mask = mask
else:
family = AF_INET6
ipl = socket.inet_pton(family, ip)
interface2_ip6 = ipaddress.IpAddress(af=family, address=ipl)
interface2_ip6_mask = mask
link_data = LinkData(
message_type=flags,
node1_id=if1.node.id,
node2_id=if2.node.id,
link_type=self.linktype,
unidirectional=unidirectional,
delay=if1.getparam("delay"),
bandwidth=if1.getparam("bw"),
dup=if1.getparam("duplicate"),
jitter=if1.getparam("jitter"),
interface1_id=if1.node.getifindex(if1),
interface1_mac=if1.hwaddr,
interface1_ip4=interface1_ip4,
interface1_ip4_mask=interface1_ip4_mask,
interface1_ip6=interface1_ip6,
interface1_ip6_mask=interface1_ip6_mask,
interface2_id=if2.node.getifindex(if2),
interface2_mac=if2.hwaddr,
interface2_ip4=interface2_ip4,
interface2_ip4_mask=interface2_ip4_mask,
interface2_ip6=interface2_ip6,
interface2_ip6_mask=interface2_ip6_mask,
)
all_links.append(link_data)
# build a 2nd link message for the upstream link parameters
# (swap if1 and if2)
if unidirectional:
link_data = LinkData(
message_type=0,
node1_id=if2.node.id,
node2_id=if1.node.id,
delay=if1.getparam("delay"),
bandwidth=if1.getparam("bw"),
dup=if1.getparam("duplicate"),
jitter=if1.getparam("jitter"),
unidirectional=1,
interface1_id=if2.node.getifindex(if2),
interface2_id=if1.node.getifindex(if1)
)
all_links.append(link_data)
return all_links
class SwitchNode(LxBrNet):
"""
Provides switch functionality within a core node.
"""
apitype = NodeTypes.SWITCH.value
policy = "ACCEPT"
type = "lanswitch"
class HubNode(LxBrNet):
"""
Provides hub functionality within a core node, forwards packets to all bridge
ports by turning off MAC address learning.
"""
apitype = NodeTypes.HUB.value
policy = "ACCEPT"
type = "hub"
def __init__(self, session, _id=None, name=None, start=True):
"""
Creates a HubNode instance.
:param core.session.Session session: core session instance
:param int _id: node id
:param str name: node namee
:param bool start: start flag
:raises CoreCommandError: when there is a command exception
"""
LxBrNet.__init__(self, session, _id, name, start)
# TODO: move to startup method
if start:
utils.check_cmd([constants.BRCTL_BIN, "setageing", self.brname, "0"])
class WlanNode(LxBrNet):
"""
Provides wireless lan functionality within a core node.
"""
apitype = NodeTypes.WIRELESS_LAN.value
linktype = LinkTypes.WIRELESS.value
policy = "DROP"
type = "wlan"
def __init__(self, session, _id=None, name=None, start=True, policy=None):
"""
Create a WlanNode instance.
:param core.session.Session session: core session instance
:param int _id: node id
:param str name: node name
:param bool start: start flag
:param policy: wlan policy
"""
LxBrNet.__init__(self, session, _id, name, start, policy)
# wireless model such as basic range
self.model = None
# mobility model such as scripted
self.mobility = None
def attach(self, netif):
"""
Attach a network interface.
:param core.netns.vif.VEth netif: network interface
:return: nothing
"""
LxBrNet.attach(self, netif)
if self.model:
netif.poshook = self.model.position_callback
if netif.node is None:
return
x, y, z = netif.node.position.get()
# invokes any netif.poshook
netif.setposition(x, y, z)
def setmodel(self, model, config):
"""
Sets the mobility and wireless model.
:param core.mobility.WirelessModel.cls model: wireless model to set to
:param dict config: configuration for model being set
:return: nothing
"""
logging.info("adding model: %s", model.name)
if model.config_type == RegisterTlvs.WIRELESS.value:
self.model = model(session=self.session, object_id=self.id)
self.model.update_config(config)
if self.model.position_callback:
for netif in self.netifs():
netif.poshook = self.model.position_callback
if netif.node is not None:
x, y, z = netif.node.position.get()
netif.poshook(netif, x, y, z)
self.model.setlinkparams()
elif model.config_type == RegisterTlvs.MOBILITY.value:
self.mobility = model(session=self.session, object_id=self.id)
self.mobility.update_config(config)
def update_mobility(self, config):
if not self.mobility:
raise ValueError("no mobility set to update for node(%s)", self.id)
self.mobility.set_configs(config, node_id=self.id)
def updatemodel(self, config):
if not self.model:
raise ValueError("no model set to update for node(%s)", self.id)
logging.info("node(%s) updating model(%s): %s", self.id, self.model.name, config)
self.model.set_configs(config, node_id=self.id)
if self.model.position_callback:
for netif in self.netifs():
netif.poshook = self.model.position_callback
if netif.node is not None:
x, y, z = netif.node.position.get()
netif.poshook(netif, x, y, z)
self.model.updateconfig()
def all_link_data(self, flags):
"""
Retrieve all link data.
:param flags: message flags
:return: list of link data
:rtype: list[core.data.LinkData]
"""
all_links = LxBrNet.all_link_data(self, flags)
if self.model:
all_links.extend(self.model.all_link_data(flags))
return all_links
class RJ45Node(PyCoreNode, PyCoreNetIf):
"""
RJ45Node is a physical interface on the host linked to the emulated
network.
"""
apitype = NodeTypes.RJ45.value
type = "rj45"
def __init__(self, session, _id=None, name=None, mtu=1500, start=True):
"""
Create an RJ45Node instance.
:param core.session.Session session: core session instance
:param int _id: node id
:param str name: node name
:param mtu: rj45 mtu
:param bool start: start flag
:return:
"""
PyCoreNode.__init__(self, session, _id, name, start=start)
PyCoreNetIf.__init__(self, node=self, name=name, mtu=mtu)
self.up = False
self.lock = threading.RLock()
self.ifindex = None
# the following are PyCoreNetIf attributes
self.transport_type = "raw"
self.localname = name
self.old_up = False
self.old_addrs = []
if start:
self.startup()
def startup(self):
"""
Set the interface in the up state.
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
# interface will also be marked up during net.attach()
self.savestate()
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"])
self.up = True
def shutdown(self):
"""
Bring the interface down. Remove any addresses and queuing
disciplines.
:return: nothing
"""
if not self.up:
return
try:
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "down"])
utils.check_cmd([constants.IP_BIN, "addr", "flush", "dev", self.localname])
utils.check_cmd([constants.TC_BIN, "qdisc", "del", "dev", self.localname, "root"])
except CoreCommandError:
logging.exception("error shutting down")
self.up = False
self.restorestate()
# TODO: issue in that both classes inherited from provide the same method with different signatures
def attachnet(self, net):
"""
Attach a network.
:param core.coreobj.PyCoreNet net: network to attach
:return: nothing
"""
PyCoreNetIf.attachnet(self, net)
# TODO: issue in that both classes inherited from provide the same method with different signatures
def detachnet(self):
"""
Detach a network.
:return: nothing
"""
PyCoreNetIf.detachnet(self)
def newnetif(self, net=None, addrlist=None, hwaddr=None, ifindex=None, ifname=None):
"""
This is called when linking with another node. Since this node
represents an interface, we do not create another object here,
but attach ourselves to the given network.
:param core.coreobj.PyCoreNet net: new network instance
:param list[str] addrlist: address list
:param str hwaddr: hardware address
:param int ifindex: interface index
:param str ifname: interface name
:return: interface index
:rtype: int
:raises ValueError: when an interface has already been created, one max
"""
with self.lock:
if ifindex is None:
ifindex = 0
if self.net is not None:
raise ValueError("RJ45 nodes support at most 1 network interface")
self._netif[ifindex] = self
# PyCoreNetIf.node is self
self.node = self
self.ifindex = ifindex
if net is not None:
self.attachnet(net)
if addrlist:
for addr in utils.make_tuple(addrlist):
self.addaddr(addr)
return ifindex
def delnetif(self, ifindex):
"""
Delete a network interface.
:param int ifindex: interface index to delete
:return: nothing
"""
if ifindex is None:
ifindex = 0
self._netif.pop(ifindex)
if ifindex == self.ifindex:
self.shutdown()
else:
raise ValueError("ifindex %s does not exist" % ifindex)
def netif(self, ifindex, net=None):
"""
This object is considered the network interface, so we only
return self here. This keeps the RJ45Node compatible with
real nodes.
:param int ifindex: interface index to retrieve
:param net: network to retrieve
:return: a network interface
:rtype: core.coreobj.PyCoreNetIf
"""
if net is not None and net == self.net:
return self
if ifindex is None:
ifindex = 0
if ifindex == self.ifindex:
return self
return None
def getifindex(self, netif):
"""
Retrieve network interface index.
:param core.coreobj.PyCoreNetIf netif: network interface to retrieve index for
:return: interface index, None otherwise
:rtype: int
"""
if netif != self:
return None
return self.ifindex
def addaddr(self, addr):
"""
Add address to to network interface.
:param str addr: address to add
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
if self.up:
utils.check_cmd([constants.IP_BIN, "addr", "add", str(addr), "dev", self.name])
PyCoreNetIf.addaddr(self, addr)
def deladdr(self, addr):
"""
Delete address from network interface.
:param str addr: address to delete
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
if self.up:
utils.check_cmd([constants.IP_BIN, "addr", "del", str(addr), "dev", self.name])
PyCoreNetIf.deladdr(self, addr)
def savestate(self):
"""
Save the addresses and other interface state before using the
interface for emulation purposes. TODO: save/restore the PROMISC flag
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
self.old_up = False
self.old_addrs = []
args = [constants.IP_BIN, "addr", "show", "dev", self.localname]
output = utils.check_cmd(args)
for line in output.split("\n"):
items = line.split()
if len(items) < 2:
continue
if items[1] == "%s:" % self.localname:
flags = items[2][1:-1].split(",")
if "UP" in flags:
self.old_up = True
elif items[0] == "inet":
self.old_addrs.append((items[1], items[3]))
elif items[0] == "inet6":
if items[1][:4] == "fe80":
continue
self.old_addrs.append((items[1], None))
def restorestate(self):
"""
Restore the addresses and other interface state after using it.
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
for addr in self.old_addrs:
if addr[1] is None:
utils.check_cmd([constants.IP_BIN, "addr", "add", addr[0], "dev", self.localname])
else:
utils.check_cmd([constants.IP_BIN, "addr", "add", addr[0], "brd", addr[1], "dev", self.localname])
if self.old_up:
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"])
def setposition(self, x=None, y=None, z=None):
"""
Uses setposition from both parent classes.
:param float x: x position
:param float y: y position
:param float z: z position
:return: True if position changed, False otherwise
:rtype: bool
"""
result = PyCoreObj.setposition(self, x, y, z)
PyCoreNetIf.setposition(self, x, y, z)
return result
def check_cmd(self, args):
"""
Runs shell command on node.
:param list[str]|str args: command to run
:return: exist status and combined stdout and stderr
:rtype: tuple[int, str]
:raises CoreCommandError: when a non-zero exit status occurs
"""
raise NotImplementedError
def cmd(self, args, wait=True):
"""
Runs shell command on node, with option to not wait for a result.
:param list[str]|str args: command to run
:param bool wait: wait for command to exit, defaults to True
:return: exit status for command
:rtype: int
"""
raise NotImplementedError
def cmd_output(self, args):
"""
Runs shell command on node and get exit status and output.
:param list[str]|str args: command to run
:return: exit status and combined stdout and stderr
:rtype: tuple[int, str]
"""
raise NotImplementedError
def termcmdstring(self, sh):
"""
Create a terminal command string.
:param str sh: shell to execute command in
:return: str
"""
raise NotImplementedError
class TunnelNode(GreTapBridge):
"""
Provides tunnel functionality in a core node.
"""
apitype = NodeTypes.TUNNEL.value
policy = "ACCEPT"
type = "tunnel"

View file

@ -1,609 +0,0 @@
"""
PyCoreNode and LxcNode classes that implement the network namespac virtual node.
"""
import errno
import logging
import os
import random
import shutil
import signal
import string
import threading
from core import CoreCommandError
from core import constants
from core.coreobj import PyCoreNetIf
from core.coreobj import PyCoreNode
from core.enumerations import NodeTypes
from core.misc import nodeutils
from core.misc import utils
from core.misc.ipaddress import MacAddress
from core.netns import vnodeclient
from core.netns.vif import TunTap
from core.netns.vif import VEth
_DEFAULT_MTU = 1500
utils.check_executables([constants.IP_BIN])
class SimpleLxcNode(PyCoreNode):
"""
Provides simple lxc functionality for core nodes.
:var nodedir: str
:var ctrlchnlname: str
:var client: core.netns.vnodeclient.VnodeClient
:var pid: int
:var up: bool
:var lock: threading.RLock
:var _mounts: list[tuple[str, str]]
"""
valid_address_types = {"inet", "inet6", "inet6link"}
def __init__(self, session, _id=None, name=None, nodedir=None, start=True):
"""
Create a SimpleLxcNode instance.
:param core.session.Session session: core session instance
:param int _id: object id
:param str name: object name
:param str nodedir: node directory
:param bool start: start flag
"""
PyCoreNode.__init__(self, session, _id, name, start=start)
self.nodedir = nodedir
self.ctrlchnlname = os.path.abspath(os.path.join(self.session.session_dir, self.name))
self.client = None
self.pid = None
self.up = False
self.lock = threading.RLock()
self._mounts = []
def alive(self):
"""
Check if the node is alive.
:return: True if node is alive, False otherwise
:rtype: bool
"""
try:
os.kill(self.pid, 0)
except OSError:
return False
return True
def startup(self):
"""
Start a new namespace node by invoking the vnoded process that
allocates a new namespace. Bring up the loopback device and set
the hostname.
:return: nothing
"""
if self.up:
raise ValueError("starting a node that is already up")
# create a new namespace for this node using vnoded
vnoded = [
constants.VNODED_BIN,
"-v",
"-c", self.ctrlchnlname,
"-l", self.ctrlchnlname + ".log",
"-p", self.ctrlchnlname + ".pid"
]
if self.nodedir:
vnoded += ["-C", self.nodedir]
env = self.session.get_environment(state=False)
env["NODE_NUMBER"] = str(self.id)
env["NODE_NAME"] = str(self.name)
output = utils.check_cmd(vnoded, env=env)
self.pid = int(output)
# create vnode client
self.client = vnodeclient.VnodeClient(self.name, self.ctrlchnlname)
# bring up the loopback interface
logging.debug("bringing up loopback interface")
self.check_cmd([constants.IP_BIN, "link", "set", "lo", "up"])
# set hostname for node
logging.debug("setting hostname: %s", self.name)
self.check_cmd(["hostname", self.name])
# mark node as up
self.up = True
def shutdown(self):
"""
Shutdown logic for simple lxc nodes.
:return: nothing
"""
# nothing to do if node is not up
if not self.up:
return
# unmount all targets (NOTE: non-persistent mount namespaces are
# removed by the kernel when last referencing process is killed)
self._mounts = []
# shutdown all interfaces
for netif in self.netifs():
netif.shutdown()
# attempt to kill node process and wait for termination of children
try:
os.kill(self.pid, signal.SIGTERM)
os.waitpid(self.pid, 0)
except OSError as e:
if e.errno != 10:
logging.exception("error killing process")
# remove node directory if present
try:
os.unlink(self.ctrlchnlname)
except OSError as e:
# no such file or directory
if e.errno != errno.ENOENT:
logging.exception("error removing node directory")
# clear interface data, close client, and mark self and not up
self._netif.clear()
self.client.close()
self.up = False
def cmd(self, args, wait=True):
"""
Runs shell command on node, with option to not wait for a result.
:param list[str]|str args: command to run
:param bool wait: wait for command to exit, defaults to True
:return: exit status for command
:rtype: int
"""
return self.client.cmd(args, wait)
def cmd_output(self, args):
"""
Runs shell command on node and get exit status and output.
:param list[str]|str args: command to run
:return: exit status and combined stdout and stderr
:rtype: tuple[int, str]
"""
return self.client.cmd_output(args)
def check_cmd(self, args):
"""
Runs shell command on node.
:param list[str]|str args: command to run
:return: combined stdout and stderr
:rtype: str
:raises CoreCommandError: when a non-zero exit status occurs
"""
return self.client.check_cmd(args)
def termcmdstring(self, sh="/bin/sh"):
"""
Create a terminal command string.
:param str sh: shell to execute command in
:return: str
"""
return self.client.termcmdstring(sh)
def mount(self, source, target):
"""
Create and mount a directory.
:param str source: source directory to mount
:param str target: target directory to create
:return: nothing
:raises CoreCommandError: when a non-zero exit status occurs
"""
source = os.path.abspath(source)
logging.info("node(%s) mounting: %s at %s", self.name, source, target)
cmd = 'mkdir -p "%s" && %s -n --bind "%s" "%s"' % (target, constants.MOUNT_BIN, source, target)
status, output = self.client.shcmd_result(cmd)
if status:
raise CoreCommandError(status, cmd, output)
self._mounts.append((source, target))
def newifindex(self):
"""
Retrieve a new interface index.
:return: new interface index
:rtype: int
"""
with self.lock:
return super(SimpleLxcNode, self).newifindex()
def newveth(self, ifindex=None, ifname=None, net=None):
"""
Create a new interface.
:param int ifindex: index for the new interface
:param str ifname: name for the new interface
:param net: network to associate interface with
:return: nothing
"""
with self.lock:
if ifindex is None:
ifindex = self.newifindex()
if ifname is None:
ifname = "eth%d" % ifindex
sessionid = self.session.short_session_id()
try:
suffix = "%x.%s.%s" % (self.id, ifindex, sessionid)
except TypeError:
suffix = "%s.%s.%s" % (self.id, ifindex, sessionid)
localname = "veth" + suffix
if len(localname) >= 16:
raise ValueError("interface local name (%s) too long" % localname)
name = localname + "p"
if len(name) >= 16:
raise ValueError("interface name (%s) too long" % name)
veth = VEth(node=self, name=name, localname=localname, net=net, start=self.up)
if self.up:
utils.check_cmd([constants.IP_BIN, "link", "set", veth.name, "netns", str(self.pid)])
self.check_cmd([constants.IP_BIN, "link", "set", veth.name, "name", ifname])
veth.name = ifname
if self.up:
# TODO: potentially find better way to query interface ID
# retrieve interface information
output = self.check_cmd(["ip", "link", "show", veth.name])
logging.debug("interface command output: %s", output)
output = output.split("\n")
veth.flow_id = int(output[0].strip().split(":")[0]) + 1
logging.debug("interface flow index: %s - %s", veth.name, veth.flow_id)
veth.hwaddr = MacAddress.from_string(output[1].strip().split()[1])
logging.debug("interface mac: %s - %s", veth.name, veth.hwaddr)
try:
self.addnetif(veth, ifindex)
except ValueError as e:
veth.shutdown()
del veth
raise e
return ifindex
def newtuntap(self, ifindex=None, ifname=None, net=None):
"""
Create a new tunnel tap.
:param int ifindex: interface index
:param str ifname: interface name
:param net: network to associate with
:return: interface index
:rtype: int
"""
with self.lock:
if ifindex is None:
ifindex = self.newifindex()
if ifname is None:
ifname = "eth%d" % ifindex
sessionid = self.session.short_session_id()
localname = "tap%s.%s.%s" % (self.id, ifindex, sessionid)
name = ifname
tuntap = TunTap(node=self, name=name, localname=localname, net=net, start=self.up)
try:
self.addnetif(tuntap, ifindex)
except ValueError as e:
tuntap.shutdown()
del tuntap
raise e
return ifindex
def sethwaddr(self, ifindex, addr):
"""
Set hardware addres for an interface.
:param int ifindex: index of interface to set hardware address for
:param core.misc.ipaddress.MacAddress addr: hardware address to set
:return: nothing
:raises CoreCommandError: when a non-zero exit status occurs
"""
self._netif[ifindex].sethwaddr(addr)
if self.up:
args = [constants.IP_BIN, "link", "set", "dev", self.ifname(ifindex), "address", str(addr)]
self.check_cmd(args)
def addaddr(self, ifindex, addr):
"""
Add interface address.
:param int ifindex: index of interface to add address to
:param str addr: address to add to interface
:return: nothing
"""
if self.up:
# check if addr is ipv6
if ":" in str(addr):
args = [constants.IP_BIN, "addr", "add", str(addr), "dev", self.ifname(ifindex)]
self.check_cmd(args)
else:
args = [constants.IP_BIN, "addr", "add", str(addr), "broadcast", "+", "dev", self.ifname(ifindex)]
self.check_cmd(args)
self._netif[ifindex].addaddr(addr)
def deladdr(self, ifindex, addr):
"""
Delete address from an interface.
:param int ifindex: index of interface to delete address from
:param str addr: address to delete from interface
:return: nothing
:raises CoreCommandError: when a non-zero exit status occurs
"""
try:
self._netif[ifindex].deladdr(addr)
except ValueError:
logging.exception("trying to delete unknown address: %s" % addr)
if self.up:
self.check_cmd([constants.IP_BIN, "addr", "del", str(addr), "dev", self.ifname(ifindex)])
def delalladdr(self, ifindex, address_types=None):
"""
Delete all addresses from an interface.
:param int ifindex: index of interface to delete address types from
:param tuple[str] address_types: address types to delete
:return: nothing
:raises CoreCommandError: when a non-zero exit status occurs
"""
if not address_types:
address_types = self.valid_address_types
interface_name = self.ifname(ifindex)
addresses = self.client.getaddr(interface_name, rescan=True)
for address_type in address_types:
if address_type not in self.valid_address_types:
raise ValueError("addr type must be in: %s" % " ".join(self.valid_address_types))
for address in addresses[address_type]:
self.deladdr(ifindex, address)
# update cached information
self.client.getaddr(interface_name, rescan=True)
def ifup(self, ifindex):
"""
Bring an interface up.
:param int ifindex: index of interface to bring up
:return: nothing
"""
if self.up:
self.check_cmd([constants.IP_BIN, "link", "set", self.ifname(ifindex), "up"])
def newnetif(self, net=None, addrlist=None, hwaddr=None, ifindex=None, ifname=None):
"""
Create a new network interface.
:param net: network to associate with
:param list addrlist: addresses to add on the interface
:param core.misc.ipaddress.MacAddress hwaddr: hardware address to set for interface
:param int ifindex: index of interface to create
:param str ifname: name for interface
:return: interface index
:rtype: int
"""
if not addrlist:
addrlist = []
with self.lock:
# TODO: see if you can move this to emane specific code
if nodeutils.is_node(net, NodeTypes.EMANE):
ifindex = self.newtuntap(ifindex=ifindex, ifname=ifname, net=net)
# TUN/TAP is not ready for addressing yet; the device may
# take some time to appear, and installing it into a
# namespace after it has been bound removes addressing;
# save addresses with the interface now
self.attachnet(ifindex, net)
netif = self.netif(ifindex)
netif.sethwaddr(hwaddr)
for address in utils.make_tuple(addrlist):
netif.addaddr(address)
return ifindex
else:
ifindex = self.newveth(ifindex=ifindex, ifname=ifname, net=net)
if net is not None:
self.attachnet(ifindex, net)
if hwaddr:
self.sethwaddr(ifindex, hwaddr)
for address in utils.make_tuple(addrlist):
self.addaddr(ifindex, address)
self.ifup(ifindex)
return ifindex
def connectnode(self, ifname, othernode, otherifname):
"""
Connect a node.
:param str ifname: name of interface to connect
:param core.netns.nodes.LxcNode othernode: node to connect to
:param str otherifname: interface name to connect to
:return: nothing
"""
tmplen = 8
tmp1 = "tmp." + "".join([random.choice(string.ascii_lowercase) for _ in xrange(tmplen)])
tmp2 = "tmp." + "".join([random.choice(string.ascii_lowercase) for _ in xrange(tmplen)])
utils.check_cmd([constants.IP_BIN, "link", "add", "name", tmp1, "type", "veth", "peer", "name", tmp2])
utils.check_cmd([constants.IP_BIN, "link", "set", tmp1, "netns", str(self.pid)])
self.check_cmd([constants.IP_BIN, "link", "set", tmp1, "name", ifname])
interface = PyCoreNetIf(node=self, name=ifname, mtu=_DEFAULT_MTU)
self.addnetif(interface, self.newifindex())
utils.check_cmd([constants.IP_BIN, "link", "set", tmp2, "netns", str(othernode.pid)])
othernode.check_cmd([constants.IP_BIN, "link", "set", tmp2, "name", otherifname])
other_interface = PyCoreNetIf(node=othernode, name=otherifname, mtu=_DEFAULT_MTU)
othernode.addnetif(other_interface, othernode.newifindex())
def addfile(self, srcname, filename):
"""
Add a file.
:param str srcname: source file name
:param str filename: file name to add
:return: nothing
:raises CoreCommandError: when a non-zero exit status occurs
"""
logging.info("adding file from %s to %s", srcname, filename)
directory = os.path.dirname(filename)
cmd = 'mkdir -p "%s" && mv "%s" "%s" && sync' % (directory, srcname, filename)
status, output = self.client.shcmd_result(cmd)
if status:
raise CoreCommandError(status, cmd, output)
class LxcNode(SimpleLxcNode):
"""
Provides lcx node functionality for core nodes.
"""
def __init__(self, session, _id=None, name=None, nodedir=None, bootsh="boot.sh", start=True):
"""
Create a LxcNode instance.
:param core.session.Session session: core session instance
:param int _id: object id
:param str name: object name
:param str nodedir: node directory
:param bootsh: boot shell
:param bool start: start flag
"""
super(LxcNode, self).__init__(session=session, _id=_id, name=name, nodedir=nodedir, start=start)
self.bootsh = bootsh
if start:
self.startup()
def startup(self):
"""
Startup logic for the node.
:return: nothing
"""
with self.lock:
self.makenodedir()
super(LxcNode, self).startup()
self.privatedir("/var/run")
self.privatedir("/var/log")
def shutdown(self):
"""
Shutdown logic for the node.
:return: nothing
"""
if not self.up:
return
with self.lock:
try:
super(LxcNode, self).shutdown()
except OSError:
logging.exception("error during shutdown")
finally:
self.rmnodedir()
def privatedir(self, path):
"""
Create a private directory.
:param str path: path to create
:return: nothing
"""
if path[0] != "/":
raise ValueError("path not fully qualified: %s" % path)
hostpath = os.path.join(self.nodedir, os.path.normpath(path).strip("/").replace("/", "."))
os.mkdir(hostpath)
self.mount(hostpath, path)
def hostfilename(self, filename):
"""
Return the name of a node"s file on the host filesystem.
:param str filename: host file name
:return: path to file
"""
dirname, basename = os.path.split(filename)
if not basename:
raise ValueError("no basename for filename: %s" % filename)
if dirname and dirname[0] == "/":
dirname = dirname[1:]
dirname = dirname.replace("/", ".")
dirname = os.path.join(self.nodedir, dirname)
return os.path.join(dirname, basename)
def opennodefile(self, filename, mode="w"):
"""
Open a node file, within it"s directory.
:param str filename: file name to open
:param str mode: mode to open file in
:return: open file
:rtype: file
"""
hostfilename = self.hostfilename(filename)
dirname, _basename = os.path.split(hostfilename)
if not os.path.isdir(dirname):
os.makedirs(dirname, mode=0755)
return open(hostfilename, mode)
def nodefile(self, filename, contents, mode=0644):
"""
Create a node file with a given mode.
:param str filename: name of file to create
:param contents: contents of file
:param int mode: mode for file
:return: nothing
"""
with self.opennodefile(filename, "w") as open_file:
open_file.write(contents)
os.chmod(open_file.name, mode)
logging.info("node(%s) added file: %s; mode: 0%o", self.name, open_file.name, mode)
def nodefilecopy(self, filename, srcfilename, mode=None):
"""
Copy a file to a node, following symlinks and preserving metadata.
Change file mode if specified.
:param str filename: file name to copy file to
:param str srcfilename: file to copy
:param int mode: mode to copy to
:return: nothing
"""
hostfilename = self.hostfilename(filename)
shutil.copy2(srcfilename, hostfilename)
if mode is not None:
os.chmod(hostfilename, mode)
logging.info("node(%s) copied file: %s; mode: %s", self.name, hostfilename, mode)

1158
daemon/core/nodes/base.py Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
"""
vnodeclient.py: implementation of the VnodeClient class for issuing commands
client.py: implementation of the VnodeClient class for issuing commands
over a control channel to the vnoded process running in a network namespace.
The control channel can be accessed via calls to the vcmd Python module or
by invoking the vcmd shell command.
@ -10,9 +10,8 @@ import os
import vcmd
from core import CoreCommandError
from core import CoreCommandError, utils
from core import constants
from core.misc import utils
class VnodeClient(object):

View file

@ -5,17 +5,175 @@ virtual ethernet classes that implement the interfaces available under Linux.
import logging
import time
from core import CoreCommandError
from core import CoreCommandError, utils
from core import constants
from core.coreobj import PyCoreNetIf
from core.enumerations import NodeTypes
from core.misc import nodeutils
from core.misc import utils
from core.emulator.enumerations import NodeTypes
from core.nodes import nodeutils
utils.check_executables([constants.IP_BIN])
class VEth(PyCoreNetIf):
class CoreInterface(object):
"""
Base class for network interfaces.
"""
def __init__(self, node, name, mtu):
"""
Creates a PyCoreNetIf instance.
:param core.coreobj.PyCoreNode node: node for interface
:param str name: interface name
:param mtu: mtu value
"""
self.node = node
self.name = name
if not isinstance(mtu, (int, long)):
raise ValueError
self.mtu = mtu
self.net = None
self._params = {}
self.addrlist = []
self.hwaddr = None
# placeholder position hook
self.poshook = lambda a, b, c, d: None
# used with EMANE
self.transport_type = None
# interface index on the network
self.netindex = None
# index used to find flow data
self.flow_id = None
def startup(self):
"""
Startup method for the interface.
:return: nothing
"""
pass
def shutdown(self):
"""
Shutdown method for the interface.
:return: nothing
"""
pass
def attachnet(self, net):
"""
Attach network.
:param core.coreobj.PyCoreNet net: network to attach
:return: nothing
"""
if self.net:
self.detachnet()
self.net = None
net.attach(self)
self.net = net
def detachnet(self):
"""
Detach from a network.
:return: nothing
"""
if self.net is not None:
self.net.detach(self)
def addaddr(self, addr):
"""
Add address.
:param str addr: address to add
:return: nothing
"""
self.addrlist.append(addr)
def deladdr(self, addr):
"""
Delete address.
:param str addr: address to delete
:return: nothing
"""
self.addrlist.remove(addr)
def sethwaddr(self, addr):
"""
Set hardware address.
:param core.misc.ipaddress.MacAddress addr: hardware address to set to.
:return: nothing
"""
self.hwaddr = addr
def getparam(self, key):
"""
Retrieve a parameter from the, or None if the parameter does not exist.
:param key: parameter to get value for
:return: parameter value
"""
return self._params.get(key)
def getparams(self):
"""
Return (key, value) pairs for parameters.
"""
parameters = []
for k in sorted(self._params.keys()):
parameters.append((k, self._params[k]))
return parameters
def setparam(self, key, value):
"""
Set a parameter value, returns True if the parameter has changed.
:param key: parameter name to set
:param value: parameter value
:return: True if parameter changed, False otherwise
"""
# treat None and 0 as unchanged values
current_value = self._params.get(key)
if current_value == value or current_value <= 0 and value <= 0:
return False
self._params[key] = value
return True
def swapparams(self, name):
"""
Swap out parameters dict for name. If name does not exist,
intialize it. This is for supporting separate upstream/downstream
parameters when two layer-2 nodes are linked together.
:param str name: name of parameter to swap
:return: nothing
"""
tmp = self._params
if not hasattr(self, name):
setattr(self, name, {})
self._params = getattr(self, name)
setattr(self, name, tmp)
def setposition(self, x, y, z):
"""
Dispatch position hook handler.
:param x: x position
:param y: y position
:param z: z position
:return: nothing
"""
self.poshook(self, x, y, z)
class Veth(CoreInterface):
"""
Provides virtual ethernet functionality for core nodes.
"""
@ -34,7 +192,7 @@ class VEth(PyCoreNetIf):
:raises CoreCommandError: when there is a command exception
"""
# note that net arg is ignored
PyCoreNetIf.__init__(self, node=node, name=name, mtu=mtu)
CoreInterface.__init__(self, node=node, name=name, mtu=mtu)
self.localname = localname
self.up = False
if start:
@ -76,7 +234,7 @@ class VEth(PyCoreNetIf):
self.up = False
class TunTap(PyCoreNetIf):
class TunTap(CoreInterface):
"""
TUN/TAP virtual device in TAP mode
"""
@ -93,7 +251,7 @@ class TunTap(PyCoreNetIf):
:param net: related network
:param bool start: start flag
"""
PyCoreNetIf.__init__(self, node=node, name=name, mtu=mtu)
CoreInterface.__init__(self, node=node, name=name, mtu=mtu)
self.localname = localname
self.up = False
self.transport_type = "virtual"
@ -233,7 +391,7 @@ class TunTap(PyCoreNetIf):
self.node.check_cmd([constants.IP_BIN, "addr", "add", str(addr), "dev", self.name])
class GreTap(PyCoreNetIf):
class GreTap(CoreInterface):
"""
GRE TAP device for tunneling between emulation servers.
Uses the "gretap" tunnel device type from Linux which is a GRE device
@ -258,7 +416,7 @@ class GreTap(PyCoreNetIf):
:param bool start: start flag
:raises CoreCommandError: when there is a command exception
"""
PyCoreNetIf.__init__(self, node=node, name=name, mtu=mtu)
CoreInterface.__init__(self, node=node, name=name, mtu=mtu)
self.session = session
if _id is None:
# from PyCoreObj

View file

@ -5,15 +5,19 @@ Linux Ethernet bridging and ebtables rules.
import logging
import os
import socket
import threading
import time
from socket import AF_INET, AF_INET6
from core import CoreCommandError
from core import CoreCommandError, utils
from core import constants
from core.coreobj import PyCoreNet
from core.misc import utils
from core.netns.vif import GreTap
from core.netns.vif import VEth
from core.nodes.base import CoreNetworkBase
from core.emulator.data import LinkData
from core.emulator.enumerations import NodeTypes, LinkTypes, RegisterTlvs
from core.nodes import ipaddress
from core.nodes.interface import GreTap
from core.nodes.interface import Veth
utils.check_executables([
constants.BRCTL_BIN,
@ -236,9 +240,9 @@ def ebtablescmds(call, cmds):
call(args)
class LxBrNet(PyCoreNet):
class CoreNetwork(CoreNetworkBase):
"""
Provides linux bridge network functionlity for core nodes.
Provides linux bridge network functionality for core nodes.
"""
policy = "DROP"
@ -252,7 +256,7 @@ class LxBrNet(PyCoreNet):
:param bool start: start flag
:param policy: network policy
"""
PyCoreNet.__init__(self, session, _id, name, start)
CoreNetworkBase.__init__(self, session, _id, name, start)
if name is None:
name = str(self.id)
if policy is not None:
@ -333,7 +337,7 @@ class LxBrNet(PyCoreNet):
utils.check_cmd([constants.BRCTL_BIN, "addif", self.brname, netif.localname])
utils.check_cmd([constants.IP_BIN, "link", "set", netif.localname, "up"])
PyCoreNet.attach(self, netif)
CoreNetworkBase.attach(self, netif)
def detach(self, netif):
"""
@ -345,7 +349,7 @@ class LxBrNet(PyCoreNet):
if self.up:
utils.check_cmd([constants.BRCTL_BIN, "delif", self.brname, netif.localname])
PyCoreNet.detach(self, netif)
CoreNetworkBase.detach(self, netif)
def linked(self, netif1, netif2):
"""
@ -520,7 +524,7 @@ class LxBrNet(PyCoreNet):
if len(name) >= 16:
raise ValueError("interface name %s too long" % name)
netif = VEth(node=None, name=name, localname=localname, mtu=1500, net=self, start=self.up)
netif = Veth(node=None, name=name, localname=localname, mtu=1500, net=self, start=self.up)
self.attach(netif)
if net.up:
# this is similar to net.attach() but uses netif.name instead
@ -564,7 +568,7 @@ class LxBrNet(PyCoreNet):
utils.check_cmd([constants.IP_BIN, "addr", "add", str(addr), "dev", self.brname])
class GreTapBridge(LxBrNet):
class GreTapBridge(CoreNetwork):
"""
A network consisting of a bridge with a gretap device for tunneling to
another system.
@ -586,7 +590,7 @@ class GreTapBridge(LxBrNet):
:param bool start: start flag
:return:
"""
LxBrNet.__init__(self, session=session, _id=_id, name=name, policy=policy, start=False)
CoreNetwork.__init__(self, session=session, _id=_id, name=name, policy=policy, start=False)
self.grekey = key
if self.grekey is None:
self.grekey = self.session.id ^ self.id
@ -609,7 +613,7 @@ class GreTapBridge(LxBrNet):
:return: nothing
"""
LxBrNet.startup(self)
CoreNetwork.startup(self)
if self.gretap:
self.attach(self.gretap)
@ -623,7 +627,7 @@ class GreTapBridge(LxBrNet):
self.detach(self.gretap)
self.gretap.shutdown()
self.gretap = None
LxBrNet.shutdown(self)
CoreNetwork.shutdown(self)
def addrconfig(self, addrlist):
"""
@ -654,3 +658,412 @@ class GreTapBridge(LxBrNet):
:return: nothing
"""
self.grekey = key
class CtrlNet(CoreNetwork):
"""
Control network functionality.
"""
policy = "ACCEPT"
# base control interface index
CTRLIF_IDX_BASE = 99
DEFAULT_PREFIX_LIST = [
"172.16.0.0/24 172.16.1.0/24 172.16.2.0/24 172.16.3.0/24 172.16.4.0/24",
"172.17.0.0/24 172.17.1.0/24 172.17.2.0/24 172.17.3.0/24 172.17.4.0/24",
"172.18.0.0/24 172.18.1.0/24 172.18.2.0/24 172.18.3.0/24 172.18.4.0/24",
"172.19.0.0/24 172.19.1.0/24 172.19.2.0/24 172.19.3.0/24 172.19.4.0/24"
]
def __init__(self, session, _id="ctrlnet", name=None, prefix=None,
hostid=None, start=True, assign_address=True,
updown_script=None, serverintf=None):
"""
Creates a CtrlNet instance.
:param core.session.Session session: core session instance
:param int _id: node id
:param str name: node namee
:param prefix: control network ipv4 prefix
:param hostid: host id
:param bool start: start flag
:param str assign_address: assigned address
:param str updown_script: updown script
:param serverintf: server interface
:return:
"""
self.prefix = ipaddress.Ipv4Prefix(prefix)
self.hostid = hostid
self.assign_address = assign_address
self.updown_script = updown_script
self.serverintf = serverintf
CoreNetwork.__init__(self, session, _id=_id, name=name, start=start)
def startup(self):
"""
Startup functionality for the control network.
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
if self.detectoldbridge():
return
CoreNetwork.startup(self)
if self.hostid:
addr = self.prefix.addr(self.hostid)
else:
addr = self.prefix.max_addr()
logging.info("added control network bridge: %s %s", self.brname, self.prefix)
if self.assign_address:
addrlist = ["%s/%s" % (addr, self.prefix.prefixlen)]
self.addrconfig(addrlist=addrlist)
logging.info("address %s", addr)
if self.updown_script:
logging.info("interface %s updown script (%s startup) called", self.brname, self.updown_script)
utils.check_cmd([self.updown_script, self.brname, "startup"])
if self.serverintf:
# sets the interface as a port of the bridge
utils.check_cmd([constants.BRCTL_BIN, "addif", self.brname, self.serverintf])
# bring interface up
utils.check_cmd([constants.IP_BIN, "link", "set", self.serverintf, "up"])
def detectoldbridge(self):
"""
Occassionally, control net bridges from previously closed sessions are not cleaned up.
Check if there are old control net bridges and delete them
:return: True if an old bridge was detected, False otherwise
:rtype: bool
"""
status, output = utils.cmd_output([constants.BRCTL_BIN, "show"])
if status != 0:
logging.error("Unable to retrieve list of installed bridges")
else:
lines = output.split("\n")
for line in lines[1:]:
cols = line.split("\t")
oldbr = cols[0]
flds = cols[0].split(".")
if len(flds) == 3:
if flds[0] == "b" and flds[1] == self.id:
logging.error(
"error: An active control net bridge (%s) found. "
"An older session might still be running. "
"Stop all sessions and, if needed, delete %s to continue.", oldbr, oldbr
)
return True
return False
def shutdown(self):
"""
Control network shutdown.
:return: nothing
"""
if self.serverintf is not None:
try:
utils.check_cmd([constants.BRCTL_BIN, "delif", self.brname, self.serverintf])
except CoreCommandError:
logging.exception("error deleting server interface %s from bridge %s", self.serverintf, self.brname)
if self.updown_script is not None:
try:
logging.info("interface %s updown script (%s shutdown) called", self.brname, self.updown_script)
utils.check_cmd([self.updown_script, self.brname, "shutdown"])
except CoreCommandError:
logging.exception("error issuing shutdown script shutdown")
CoreNetwork.shutdown(self)
def all_link_data(self, flags):
"""
Do not include CtrlNet in link messages describing this session.
:param flags: message flags
:return: list of link data
:rtype: list[core.data.LinkData]
"""
return []
class PtpNet(CoreNetwork):
"""
Peer to peer network node.
"""
policy = "ACCEPT"
def attach(self, netif):
"""
Attach a network interface, but limit attachment to two interfaces.
:param core.netns.vif.VEth netif: network interface
:return: nothing
"""
if len(self._netif) >= 2:
raise ValueError("Point-to-point links support at most 2 network interfaces")
CoreNetwork.attach(self, netif)
def data(self, message_type, lat=None, lon=None, alt=None):
"""
Do not generate a Node Message for point-to-point links. They are
built using a link message instead.
:param message_type: purpose for the data object we are creating
:param float lat: latitude
:param float lon: longitude
:param float alt: altitude
:return: node data object
:rtype: core.data.NodeData
"""
return None
def all_link_data(self, flags):
"""
Build CORE API TLVs for a point-to-point link. One Link message
describes this network.
:param flags: message flags
:return: list of link data
:rtype: list[core.data.LinkData]
"""
all_links = []
if len(self._netif) != 2:
return all_links
if1, if2 = self._netif.values()
unidirectional = 0
if if1.getparams() != if2.getparams():
unidirectional = 1
interface1_ip4 = None
interface1_ip4_mask = None
interface1_ip6 = None
interface1_ip6_mask = None
for address in if1.addrlist:
ip, _sep, mask = address.partition("/")
mask = int(mask)
if ipaddress.is_ipv4_address(ip):
family = AF_INET
ipl = socket.inet_pton(family, ip)
interface1_ip4 = ipaddress.IpAddress(af=family, address=ipl)
interface1_ip4_mask = mask
else:
family = AF_INET6
ipl = socket.inet_pton(family, ip)
interface1_ip6 = ipaddress.IpAddress(af=family, address=ipl)
interface1_ip6_mask = mask
interface2_ip4 = None
interface2_ip4_mask = None
interface2_ip6 = None
interface2_ip6_mask = None
for address in if2.addrlist:
ip, _sep, mask = address.partition("/")
mask = int(mask)
if ipaddress.is_ipv4_address(ip):
family = AF_INET
ipl = socket.inet_pton(family, ip)
interface2_ip4 = ipaddress.IpAddress(af=family, address=ipl)
interface2_ip4_mask = mask
else:
family = AF_INET6
ipl = socket.inet_pton(family, ip)
interface2_ip6 = ipaddress.IpAddress(af=family, address=ipl)
interface2_ip6_mask = mask
link_data = LinkData(
message_type=flags,
node1_id=if1.node.id,
node2_id=if2.node.id,
link_type=self.linktype,
unidirectional=unidirectional,
delay=if1.getparam("delay"),
bandwidth=if1.getparam("bw"),
dup=if1.getparam("duplicate"),
jitter=if1.getparam("jitter"),
interface1_id=if1.node.getifindex(if1),
interface1_mac=if1.hwaddr,
interface1_ip4=interface1_ip4,
interface1_ip4_mask=interface1_ip4_mask,
interface1_ip6=interface1_ip6,
interface1_ip6_mask=interface1_ip6_mask,
interface2_id=if2.node.getifindex(if2),
interface2_mac=if2.hwaddr,
interface2_ip4=interface2_ip4,
interface2_ip4_mask=interface2_ip4_mask,
interface2_ip6=interface2_ip6,
interface2_ip6_mask=interface2_ip6_mask,
)
all_links.append(link_data)
# build a 2nd link message for the upstream link parameters
# (swap if1 and if2)
if unidirectional:
link_data = LinkData(
message_type=0,
node1_id=if2.node.id,
node2_id=if1.node.id,
delay=if1.getparam("delay"),
bandwidth=if1.getparam("bw"),
dup=if1.getparam("duplicate"),
jitter=if1.getparam("jitter"),
unidirectional=1,
interface1_id=if2.node.getifindex(if2),
interface2_id=if1.node.getifindex(if1)
)
all_links.append(link_data)
return all_links
class SwitchNode(CoreNetwork):
"""
Provides switch functionality within a core node.
"""
apitype = NodeTypes.SWITCH.value
policy = "ACCEPT"
type = "lanswitch"
class HubNode(CoreNetwork):
"""
Provides hub functionality within a core node, forwards packets to all bridge
ports by turning off MAC address learning.
"""
apitype = NodeTypes.HUB.value
policy = "ACCEPT"
type = "hub"
def __init__(self, session, _id=None, name=None, start=True):
"""
Creates a HubNode instance.
:param core.session.Session session: core session instance
:param int _id: node id
:param str name: node namee
:param bool start: start flag
:raises CoreCommandError: when there is a command exception
"""
CoreNetwork.__init__(self, session, _id, name, start)
# TODO: move to startup method
if start:
utils.check_cmd([constants.BRCTL_BIN, "setageing", self.brname, "0"])
class WlanNode(CoreNetwork):
"""
Provides wireless lan functionality within a core node.
"""
apitype = NodeTypes.WIRELESS_LAN.value
linktype = LinkTypes.WIRELESS.value
policy = "DROP"
type = "wlan"
def __init__(self, session, _id=None, name=None, start=True, policy=None):
"""
Create a WlanNode instance.
:param core.session.Session session: core session instance
:param int _id: node id
:param str name: node name
:param bool start: start flag
:param policy: wlan policy
"""
CoreNetwork.__init__(self, session, _id, name, start, policy)
# wireless model such as basic range
self.model = None
# mobility model such as scripted
self.mobility = None
def attach(self, netif):
"""
Attach a network interface.
:param core.netns.vif.VEth netif: network interface
:return: nothing
"""
CoreNetwork.attach(self, netif)
if self.model:
netif.poshook = self.model.position_callback
if netif.node is None:
return
x, y, z = netif.node.position.get()
# invokes any netif.poshook
netif.setposition(x, y, z)
def setmodel(self, model, config):
"""
Sets the mobility and wireless model.
:param core.mobility.WirelessModel.cls model: wireless model to set to
:param dict config: configuration for model being set
:return: nothing
"""
logging.info("adding model: %s", model.name)
if model.config_type == RegisterTlvs.WIRELESS.value:
self.model = model(session=self.session, _id=self.id)
self.model.update_config(config)
if self.model.position_callback:
for netif in self.netifs():
netif.poshook = self.model.position_callback
if netif.node is not None:
x, y, z = netif.node.position.get()
netif.poshook(netif, x, y, z)
self.model.setlinkparams()
elif model.config_type == RegisterTlvs.MOBILITY.value:
self.mobility = model(session=self.session, _id=self.id)
self.mobility.update_config(config)
def update_mobility(self, config):
if not self.mobility:
raise ValueError("no mobility set to update for node(%s)", self.id)
self.mobility.set_configs(config, node_id=self.id)
def updatemodel(self, config):
if not self.model:
raise ValueError("no model set to update for node(%s)", self.id)
logging.info("node(%s) updating model(%s): %s", self.id, self.model.name, config)
self.model.set_configs(config, node_id=self.id)
if self.model.position_callback:
for netif in self.netifs():
netif.poshook = self.model.position_callback
if netif.node is not None:
x, y, z = netif.node.position.get()
netif.poshook(netif, x, y, z)
self.model.updateconfig()
def all_link_data(self, flags):
"""
Retrieve all link data.
:param flags: message flags
:return: list of link data
:rtype: list[core.data.LinkData]
"""
all_links = CoreNetwork.all_link_data(self, flags)
if self.model:
all_links.extend(self.model.all_link_data(flags))
return all_links
class TunnelNode(GreTapBridge):
"""
Provides tunnel functionality in a core node.
"""
apitype = NodeTypes.TUNNEL.value
policy = "ACCEPT"
type = "tunnel"

View file

@ -0,0 +1,29 @@
"""
Provides default node maps that can be used to run core with.
"""
import core.nodes.base
import core.nodes.network
import core.nodes.physical
from core.emane.nodes import EmaneNet
from core.emane.nodes import EmaneNode
from core.emulator.enumerations import NodeTypes
from core.nodes.network import GreTapBridge
from core.nodes import physical
# legacy core nodes, that leverage linux bridges
NODES = {
NodeTypes.DEFAULT: core.nodes.base.CoreNode,
NodeTypes.PHYSICAL: physical.PhysicalNode,
NodeTypes.TBD: None,
NodeTypes.SWITCH: core.nodes.network.SwitchNode,
NodeTypes.HUB: core.nodes.network.HubNode,
NodeTypes.WIRELESS_LAN: core.nodes.network.WlanNode,
NodeTypes.RJ45: core.nodes.physical.Rj45Node,
NodeTypes.TUNNEL: core.nodes.network.TunnelNode,
NodeTypes.KTUNNEL: None,
NodeTypes.EMANE: EmaneNode,
NodeTypes.EMANE_NET: EmaneNet,
NodeTypes.TAP_BRIDGE: GreTapBridge,
NodeTypes.PEER_TO_PEER: core.nodes.network.PtpNet,
NodeTypes.CONTROL_NET: core.nodes.network.CtrlNet
}

View file

@ -8,19 +8,18 @@ import threading
from socket import AF_INET
from socket import AF_INET6
from core import CoreCommandError
from core import CoreCommandError, utils
from core import constants
from core.coreobj import PyCoreNet
from core.data import LinkData
from core.enumerations import LinkTypes
from core.enumerations import NodeTypes
from core.enumerations import RegisterTlvs
from core.misc import ipaddress
from core.misc import utils
from core.netns.vif import GreTap
from core.netns.vif import VEth
from core.netns.vnet import EbtablesQueue
from core.netns.vnet import GreTapBridge
from core.nodes.base import CoreNetworkBase
from core.emulator.data import LinkData
from core.emulator.enumerations import LinkTypes
from core.emulator.enumerations import NodeTypes
from core.emulator.enumerations import RegisterTlvs
from core.nodes import ipaddress
from core.nodes.interface import GreTap
from core.nodes.interface import Veth
from core.nodes.network import EbtablesQueue
from core.nodes.network import GreTapBridge
# a global object because all WLANs share the same queue
# cannot have multiple threads invoking the ebtables commnd
@ -41,7 +40,7 @@ def ebtables_commands(call, commands):
call(command)
class OvsNet(PyCoreNet):
class OvsNet(CoreNetworkBase):
"""
Used to be LxBrNet.
@ -62,7 +61,7 @@ class OvsNet(PyCoreNet):
:return:
"""
PyCoreNet.__init__(self, session, _id, name, start)
CoreNetworkBase.__init__(self, session, _id, name, start)
if policy:
self.policy = policy
@ -129,13 +128,13 @@ class OvsNet(PyCoreNet):
utils.check_cmd([constants.OVS_BIN, "add-port", self.bridge_name, interface.localname])
utils.check_cmd([constants.IP_BIN, "link", "set", interface.localname, "up"])
PyCoreNet.attach(self, interface)
CoreNetworkBase.attach(self, interface)
def detach(self, interface):
if self.up:
utils.check_cmd([constants.OVS_BIN, "del-port", self.bridge_name, interface.localname])
PyCoreNet.detach(self, interface)
CoreNetworkBase.detach(self, interface)
def linked(self, interface_one, interface_two):
# check if the network interfaces are attached to this network
@ -297,7 +296,7 @@ class OvsNet(PyCoreNet):
if len(name) >= 16:
raise ValueError("interface name %s too long" % name)
interface = VEth(node=None, name=name, localname=localname, mtu=1500, net=self, start=self.up)
interface = Veth(node=None, name=name, localname=localname, mtu=1500, net=self, start=self.up)
self.attach(interface)
if network.up:
# this is similar to net.attach() but uses netif.name instead
@ -598,7 +597,7 @@ class OvsWlanNode(OvsNet):
logging.info("adding model %s", model.name)
if model.type == RegisterTlvs.WIRELESS.value:
self.model = model(session=self.session, object_id=self.id, config=config)
self.model = model(session=self.session, _id=self.id, config=config)
if self.model.position_callback:
for interface in self.netifs():
interface.poshook = self.model.position_callback
@ -607,7 +606,7 @@ class OvsWlanNode(OvsNet):
interface.poshook(interface, x, y, z)
self.model.setlinkparams()
elif model.type == RegisterTlvs.MOBILITY.value:
self.mobility = model(session=self.session, object_id=self.id, config=config)
self.mobility = model(session=self.session, _id=self.id, config=config)
def updatemodel(self, config):
if not self.model:

View file

@ -0,0 +1,544 @@
"""
PhysicalNode class for including real systems in the emulated network.
"""
import logging
import os
import subprocess
import threading
from core import CoreCommandError, utils
from core import constants
from core.nodes.base import CoreNodeBase
from core.nodes.interface import CoreInterface
from core.emulator.enumerations import NodeTypes
from core.nodes.network import GreTap
from core.nodes.network import CoreNetwork
class PhysicalNode(CoreNodeBase):
def __init__(self, session, _id=None, name=None, nodedir=None, start=True):
CoreNodeBase.__init__(self, session, _id, name, start=start)
self.nodedir = nodedir
self.up = start
self.lock = threading.RLock()
self._mounts = []
if start:
self.startup()
def startup(self):
with self.lock:
self.makenodedir()
def shutdown(self):
if not self.up:
return
with self.lock:
while self._mounts:
_source, target = self._mounts.pop(-1)
self.umount(target)
for netif in self.netifs():
netif.shutdown()
self.rmnodedir()
def termcmdstring(self, sh="/bin/sh"):
"""
Create a terminal command string.
:param str sh: shell to execute command in
:return: str
"""
return sh
def cmd(self, args, wait=True):
"""
Runs shell command on node, with option to not wait for a result.
:param list[str]|str args: command to run
:param bool wait: wait for command to exit, defaults to True
:return: exit status for command
:rtype: int
"""
os.chdir(self.nodedir)
status = utils.cmd(args, wait)
return status
def cmd_output(self, args):
"""
Runs shell command on node and get exit status and output.
:param list[str]|str args: command to run
:return: exit status and combined stdout and stderr
:rtype: tuple[int, str]
"""
os.chdir(self.nodedir)
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, _ = p.communicate()
status = p.wait()
return status, stdout.strip()
def check_cmd(self, args):
"""
Runs shell command on node.
:param list[str]|str args: command to run
:return: combined stdout and stderr
:rtype: str
:raises CoreCommandError: when a non-zero exit status occurs
"""
status, output = self.cmd_output(args)
if status:
raise CoreCommandError(status, args, output)
return output.strip()
def shcmd(self, cmdstr, sh="/bin/sh"):
return self.cmd([sh, "-c", cmdstr])
def sethwaddr(self, ifindex, addr):
"""
same as SimpleLxcNode.sethwaddr()
"""
self._netif[ifindex].sethwaddr(addr)
ifname = self.ifname(ifindex)
if self.up:
self.check_cmd([constants.IP_BIN, "link", "set", "dev", ifname, "address", str(addr)])
def addaddr(self, ifindex, addr):
"""
same as SimpleLxcNode.addaddr()
"""
if self.up:
self.check_cmd([constants.IP_BIN, "addr", "add", str(addr), "dev", self.ifname(ifindex)])
self._netif[ifindex].addaddr(addr)
def deladdr(self, ifindex, addr):
"""
same as SimpleLxcNode.deladdr()
"""
try:
self._netif[ifindex].deladdr(addr)
except ValueError:
logging.exception("trying to delete unknown address: %s", addr)
if self.up:
self.check_cmd([constants.IP_BIN, "addr", "del", str(addr), "dev", self.ifname(ifindex)])
def adoptnetif(self, netif, ifindex, hwaddr, addrlist):
"""
The broker builds a GreTap tunnel device to this physical node.
When a link message is received linking this node to another part of
the emulation, no new interface is created; instead, adopt the
GreTap netif as the node interface.
"""
netif.name = "gt%d" % ifindex
netif.node = self
self.addnetif(netif, ifindex)
# use a more reasonable name, e.g. "gt0" instead of "gt.56286.150"
if self.up:
self.check_cmd([constants.IP_BIN, "link", "set", "dev", netif.localname, "down"])
self.check_cmd([constants.IP_BIN, "link", "set", netif.localname, "name", netif.name])
netif.localname = netif.name
if hwaddr:
self.sethwaddr(ifindex, hwaddr)
for addr in utils.make_tuple(addrlist):
self.addaddr(ifindex, addr)
if self.up:
self.check_cmd([constants.IP_BIN, "link", "set", "dev", netif.localname, "up"])
def linkconfig(self, netif, bw=None, delay=None, loss=None, duplicate=None, jitter=None, netif2=None):
"""
Apply tc queing disciplines using LxBrNet.linkconfig()
"""
# borrow the tc qdisc commands from LxBrNet.linkconfig()
linux_bridge = CoreNetwork(session=self.session, start=False)
linux_bridge.up = True
linux_bridge.linkconfig(netif, bw=bw, delay=delay, loss=loss, duplicate=duplicate, jitter=jitter, netif2=netif2)
del linux_bridge
def newifindex(self):
with self.lock:
while self.ifindex in self._netif:
self.ifindex += 1
ifindex = self.ifindex
self.ifindex += 1
return ifindex
def newnetif(self, net=None, addrlist=None, hwaddr=None, ifindex=None, ifname=None):
logging.info("creating interface")
if not addrlist:
addrlist = []
if self.up and net is None:
raise NotImplementedError
if ifindex is None:
ifindex = self.newifindex()
if self.up:
# this is reached when this node is linked to a network node
# tunnel to net not built yet, so build it now and adopt it
gt = self.session.broker.addnettunnel(net.id)
if gt is None or len(gt) != 1:
raise ValueError("error building tunnel from adding a new network interface: %s" % gt)
gt = gt[0]
net.detach(gt)
self.adoptnetif(gt, ifindex, hwaddr, addrlist)
return ifindex
# this is reached when configuring services (self.up=False)
if ifname is None:
ifname = "gt%d" % ifindex
netif = GreTap(node=self, name=ifname, session=self.session, start=False)
self.adoptnetif(netif, ifindex, hwaddr, addrlist)
return ifindex
def privatedir(self, path):
if path[0] != "/":
raise ValueError("path not fully qualified: %s" % path)
hostpath = os.path.join(self.nodedir, os.path.normpath(path).strip('/').replace('/', '.'))
os.mkdir(hostpath)
self.mount(hostpath, path)
def mount(self, source, target):
source = os.path.abspath(source)
logging.info("mounting %s at %s", source, target)
os.makedirs(target)
self.check_cmd([constants.MOUNT_BIN, "--bind", source, target])
self._mounts.append((source, target))
def umount(self, target):
logging.info("unmounting '%s'" % target)
try:
self.check_cmd([constants.UMOUNT_BIN, "-l", target])
except CoreCommandError:
logging.exception("unmounting failed for %s", target)
def opennodefile(self, filename, mode="w"):
dirname, basename = os.path.split(filename)
if not basename:
raise ValueError("no basename for filename: " + filename)
if dirname and dirname[0] == "/":
dirname = dirname[1:]
dirname = dirname.replace("/", ".")
dirname = os.path.join(self.nodedir, dirname)
if not os.path.isdir(dirname):
os.makedirs(dirname, mode=0755)
hostfilename = os.path.join(dirname, basename)
return open(hostfilename, mode)
def nodefile(self, filename, contents, mode=0644):
with self.opennodefile(filename, "w") as node_file:
node_file.write(contents)
os.chmod(node_file.name, mode)
logging.info("created nodefile: '%s'; mode: 0%o", node_file.name, mode)
class Rj45Node(CoreNodeBase, CoreInterface):
"""
RJ45Node is a physical interface on the host linked to the emulated
network.
"""
apitype = NodeTypes.RJ45.value
type = "rj45"
def __init__(self, session, _id=None, name=None, mtu=1500, start=True):
"""
Create an RJ45Node instance.
:param core.session.Session session: core session instance
:param int _id: node id
:param str name: node name
:param mtu: rj45 mtu
:param bool start: start flag
:return:
"""
CoreNodeBase.__init__(self, session, _id, name, start=start)
CoreInterface.__init__(self, node=self, name=name, mtu=mtu)
self.up = False
self.lock = threading.RLock()
self.ifindex = None
# the following are PyCoreNetIf attributes
self.transport_type = "raw"
self.localname = name
self.old_up = False
self.old_addrs = []
if start:
self.startup()
def startup(self):
"""
Set the interface in the up state.
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
# interface will also be marked up during net.attach()
self.savestate()
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"])
self.up = True
def shutdown(self):
"""
Bring the interface down. Remove any addresses and queuing
disciplines.
:return: nothing
"""
if not self.up:
return
try:
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "down"])
utils.check_cmd([constants.IP_BIN, "addr", "flush", "dev", self.localname])
utils.check_cmd([constants.TC_BIN, "qdisc", "del", "dev", self.localname, "root"])
except CoreCommandError:
logging.exception("error shutting down")
self.up = False
self.restorestate()
# TODO: issue in that both classes inherited from provide the same method with different signatures
def attachnet(self, net):
"""
Attach a network.
:param core.coreobj.PyCoreNet net: network to attach
:return: nothing
"""
CoreInterface.attachnet(self, net)
# TODO: issue in that both classes inherited from provide the same method with different signatures
def detachnet(self):
"""
Detach a network.
:return: nothing
"""
CoreInterface.detachnet(self)
def newnetif(self, net=None, addrlist=None, hwaddr=None, ifindex=None, ifname=None):
"""
This is called when linking with another node. Since this node
represents an interface, we do not create another object here,
but attach ourselves to the given network.
:param core.coreobj.PyCoreNet net: new network instance
:param list[str] addrlist: address list
:param str hwaddr: hardware address
:param int ifindex: interface index
:param str ifname: interface name
:return: interface index
:rtype: int
:raises ValueError: when an interface has already been created, one max
"""
with self.lock:
if ifindex is None:
ifindex = 0
if self.net is not None:
raise ValueError("RJ45 nodes support at most 1 network interface")
self._netif[ifindex] = self
# PyCoreNetIf.node is self
self.node = self
self.ifindex = ifindex
if net is not None:
self.attachnet(net)
if addrlist:
for addr in utils.make_tuple(addrlist):
self.addaddr(addr)
return ifindex
def delnetif(self, ifindex):
"""
Delete a network interface.
:param int ifindex: interface index to delete
:return: nothing
"""
if ifindex is None:
ifindex = 0
self._netif.pop(ifindex)
if ifindex == self.ifindex:
self.shutdown()
else:
raise ValueError("ifindex %s does not exist" % ifindex)
def netif(self, ifindex, net=None):
"""
This object is considered the network interface, so we only
return self here. This keeps the RJ45Node compatible with
real nodes.
:param int ifindex: interface index to retrieve
:param net: network to retrieve
:return: a network interface
:rtype: core.coreobj.PyCoreNetIf
"""
if net is not None and net == self.net:
return self
if ifindex is None:
ifindex = 0
if ifindex == self.ifindex:
return self
return None
def getifindex(self, netif):
"""
Retrieve network interface index.
:param core.coreobj.PyCoreNetIf netif: network interface to retrieve index for
:return: interface index, None otherwise
:rtype: int
"""
if netif != self:
return None
return self.ifindex
def addaddr(self, addr):
"""
Add address to to network interface.
:param str addr: address to add
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
if self.up:
utils.check_cmd([constants.IP_BIN, "addr", "add", str(addr), "dev", self.name])
CoreInterface.addaddr(self, addr)
def deladdr(self, addr):
"""
Delete address from network interface.
:param str addr: address to delete
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
if self.up:
utils.check_cmd([constants.IP_BIN, "addr", "del", str(addr), "dev", self.name])
CoreInterface.deladdr(self, addr)
def savestate(self):
"""
Save the addresses and other interface state before using the
interface for emulation purposes. TODO: save/restore the PROMISC flag
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
self.old_up = False
self.old_addrs = []
args = [constants.IP_BIN, "addr", "show", "dev", self.localname]
output = utils.check_cmd(args)
for line in output.split("\n"):
items = line.split()
if len(items) < 2:
continue
if items[1] == "%s:" % self.localname:
flags = items[2][1:-1].split(",")
if "UP" in flags:
self.old_up = True
elif items[0] == "inet":
self.old_addrs.append((items[1], items[3]))
elif items[0] == "inet6":
if items[1][:4] == "fe80":
continue
self.old_addrs.append((items[1], None))
def restorestate(self):
"""
Restore the addresses and other interface state after using it.
:return: nothing
:raises CoreCommandError: when there is a command exception
"""
for addr in self.old_addrs:
if addr[1] is None:
utils.check_cmd([constants.IP_BIN, "addr", "add", addr[0], "dev", self.localname])
else:
utils.check_cmd([constants.IP_BIN, "addr", "add", addr[0], "brd", addr[1], "dev", self.localname])
if self.old_up:
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"])
def setposition(self, x=None, y=None, z=None):
"""
Uses setposition from both parent classes.
:param float x: x position
:param float y: y position
:param float z: z position
:return: True if position changed, False otherwise
:rtype: bool
"""
result = CoreNodeBase.setposition(self, x, y, z)
CoreInterface.setposition(self, x, y, z)
return result
def check_cmd(self, args):
"""
Runs shell command on node.
:param list[str]|str args: command to run
:return: exist status and combined stdout and stderr
:rtype: tuple[int, str]
:raises CoreCommandError: when a non-zero exit status occurs
"""
raise NotImplementedError
def cmd(self, args, wait=True):
"""
Runs shell command on node, with option to not wait for a result.
:param list[str]|str args: command to run
:param bool wait: wait for command to exit, defaults to True
:return: exit status for command
:rtype: int
"""
raise NotImplementedError
def cmd_output(self, args):
"""
Runs shell command on node and get exit status and output.
:param list[str]|str args: command to run
:return: exit status and combined stdout and stderr
:rtype: tuple[int, str]
"""
raise NotImplementedError
def termcmdstring(self, sh):
"""
Create a terminal command string.
:param str sh: shell to execute command in
:return: str
"""
raise NotImplementedError

View file

@ -1,245 +0,0 @@
"""
PhysicalNode class for including real systems in the emulated network.
"""
import logging
import os
import subprocess
import threading
from core import CoreCommandError
from core import constants
from core.coreobj import PyCoreNode
from core.misc import utils
from core.netns.vnet import GreTap
from core.netns.vnet import LxBrNet
class PhysicalNode(PyCoreNode):
def __init__(self, session, _id=None, name=None, nodedir=None, start=True):
PyCoreNode.__init__(self, session, _id, name, start=start)
self.nodedir = nodedir
self.up = start
self.lock = threading.RLock()
self._mounts = []
if start:
self.startup()
def startup(self):
with self.lock:
self.makenodedir()
def shutdown(self):
if not self.up:
return
with self.lock:
while self._mounts:
_source, target = self._mounts.pop(-1)
self.umount(target)
for netif in self.netifs():
netif.shutdown()
self.rmnodedir()
def termcmdstring(self, sh="/bin/sh"):
"""
Create a terminal command string.
:param str sh: shell to execute command in
:return: str
"""
return sh
def cmd(self, args, wait=True):
"""
Runs shell command on node, with option to not wait for a result.
:param list[str]|str args: command to run
:param bool wait: wait for command to exit, defaults to True
:return: exit status for command
:rtype: int
"""
os.chdir(self.nodedir)
status = utils.cmd(args, wait)
return status
def cmd_output(self, args):
"""
Runs shell command on node and get exit status and output.
:param list[str]|str args: command to run
:return: exit status and combined stdout and stderr
:rtype: tuple[int, str]
"""
os.chdir(self.nodedir)
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, _ = p.communicate()
status = p.wait()
return status, stdout.strip()
def check_cmd(self, args):
"""
Runs shell command on node.
:param list[str]|str args: command to run
:return: combined stdout and stderr
:rtype: str
:raises CoreCommandError: when a non-zero exit status occurs
"""
status, output = self.cmd_output(args)
if status:
raise CoreCommandError(status, args, output)
return output.strip()
def shcmd(self, cmdstr, sh="/bin/sh"):
return self.cmd([sh, "-c", cmdstr])
def sethwaddr(self, ifindex, addr):
"""
same as SimpleLxcNode.sethwaddr()
"""
self._netif[ifindex].sethwaddr(addr)
ifname = self.ifname(ifindex)
if self.up:
self.check_cmd([constants.IP_BIN, "link", "set", "dev", ifname, "address", str(addr)])
def addaddr(self, ifindex, addr):
"""
same as SimpleLxcNode.addaddr()
"""
if self.up:
self.check_cmd([constants.IP_BIN, "addr", "add", str(addr), "dev", self.ifname(ifindex)])
self._netif[ifindex].addaddr(addr)
def deladdr(self, ifindex, addr):
"""
same as SimpleLxcNode.deladdr()
"""
try:
self._netif[ifindex].deladdr(addr)
except ValueError:
logging.exception("trying to delete unknown address: %s", addr)
if self.up:
self.check_cmd([constants.IP_BIN, "addr", "del", str(addr), "dev", self.ifname(ifindex)])
def adoptnetif(self, netif, ifindex, hwaddr, addrlist):
"""
The broker builds a GreTap tunnel device to this physical node.
When a link message is received linking this node to another part of
the emulation, no new interface is created; instead, adopt the
GreTap netif as the node interface.
"""
netif.name = "gt%d" % ifindex
netif.node = self
self.addnetif(netif, ifindex)
# use a more reasonable name, e.g. "gt0" instead of "gt.56286.150"
if self.up:
self.check_cmd([constants.IP_BIN, "link", "set", "dev", netif.localname, "down"])
self.check_cmd([constants.IP_BIN, "link", "set", netif.localname, "name", netif.name])
netif.localname = netif.name
if hwaddr:
self.sethwaddr(ifindex, hwaddr)
for addr in utils.make_tuple(addrlist):
self.addaddr(ifindex, addr)
if self.up:
self.check_cmd([constants.IP_BIN, "link", "set", "dev", netif.localname, "up"])
def linkconfig(self, netif, bw=None, delay=None, loss=None, duplicate=None, jitter=None, netif2=None):
"""
Apply tc queing disciplines using LxBrNet.linkconfig()
"""
# borrow the tc qdisc commands from LxBrNet.linkconfig()
linux_bridge = LxBrNet(session=self.session, start=False)
linux_bridge.up = True
linux_bridge.linkconfig(netif, bw=bw, delay=delay, loss=loss, duplicate=duplicate, jitter=jitter, netif2=netif2)
del linux_bridge
def newifindex(self):
with self.lock:
while self.ifindex in self._netif:
self.ifindex += 1
ifindex = self.ifindex
self.ifindex += 1
return ifindex
def newnetif(self, net=None, addrlist=None, hwaddr=None, ifindex=None, ifname=None):
logging.info("creating interface")
if not addrlist:
addrlist = []
if self.up and net is None:
raise NotImplementedError
if ifindex is None:
ifindex = self.newifindex()
if self.up:
# this is reached when this node is linked to a network node
# tunnel to net not built yet, so build it now and adopt it
gt = self.session.broker.addnettunnel(net.id)
if gt is None or len(gt) != 1:
raise ValueError("error building tunnel from adding a new network interface: %s" % gt)
gt = gt[0]
net.detach(gt)
self.adoptnetif(gt, ifindex, hwaddr, addrlist)
return ifindex
# this is reached when configuring services (self.up=False)
if ifname is None:
ifname = "gt%d" % ifindex
netif = GreTap(node=self, name=ifname, session=self.session, start=False)
self.adoptnetif(netif, ifindex, hwaddr, addrlist)
return ifindex
def privatedir(self, path):
if path[0] != "/":
raise ValueError("path not fully qualified: %s" % path)
hostpath = os.path.join(self.nodedir, os.path.normpath(path).strip('/').replace('/', '.'))
os.mkdir(hostpath)
self.mount(hostpath, path)
def mount(self, source, target):
source = os.path.abspath(source)
logging.info("mounting %s at %s", source, target)
os.makedirs(target)
self.check_cmd([constants.MOUNT_BIN, "--bind", source, target])
self._mounts.append((source, target))
def umount(self, target):
logging.info("unmounting '%s'" % target)
try:
self.check_cmd([constants.UMOUNT_BIN, "-l", target])
except CoreCommandError:
logging.exception("unmounting failed for %s", target)
def opennodefile(self, filename, mode="w"):
dirname, basename = os.path.split(filename)
if not basename:
raise ValueError("no basename for filename: " + filename)
if dirname and dirname[0] == "/":
dirname = dirname[1:]
dirname = dirname.replace("/", ".")
dirname = os.path.join(self.nodedir, dirname)
if not os.path.isdir(dirname):
os.makedirs(dirname, mode=0755)
hostfilename = os.path.join(dirname, basename)
return open(hostfilename, mode)
def nodefile(self, filename, contents, mode=0644):
with self.opennodefile(filename, "w") as node_file:
node_file.write(contents)
os.chmod(node_file.name, mode)
logging.info("created nodefile: '%s'; mode: 0%o", node_file.name, mode)

View file

View file

@ -7,16 +7,15 @@ import socket
from urlparse import urlparse
from core import constants
from core.coreobj import PyCoreNet
from core.coreobj import PyCoreObj
from core.enumerations import EventTypes
from core.enumerations import LinkTlvs
from core.enumerations import LinkTypes
from core.enumerations import MessageFlags
from core.enumerations import MessageTypes
from core.enumerations import NodeTlvs
from core.enumerations import NodeTypes
from core.misc import nodeutils
from core.nodes.base import NodeBase, CoreNetworkBase
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import LinkTlvs
from core.emulator.enumerations import LinkTypes
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.emulator.enumerations import NodeTlvs
from core.emulator.enumerations import NodeTypes
from core.nodes import nodeutils
# TODO: A named tuple may be more appropriate, than abusing a class dict like this
@ -321,22 +320,20 @@ class Sdt(object):
:return: nothing
"""
nets = []
with self.session._objects_lock:
for obj in self.session.objects.itervalues():
if isinstance(obj, PyCoreNet):
nets.append(obj)
if not isinstance(obj, PyCoreObj):
with self.session._nodes_lock:
for node in self.session.nodes.itervalues():
if isinstance(node, CoreNetworkBase):
nets.append(node)
if not isinstance(node, NodeBase):
continue
(x, y, z) = obj.getposition()
(x, y, z) = node.getposition()
if x is None or y is None:
continue
self.updatenode(obj.id, MessageFlags.ADD.value, x, y, z,
obj.name, obj.type, obj.icon)
self.updatenode(node.id, MessageFlags.ADD.value, x, y, z, node.name, node.type, node.icon)
for nodenum in sorted(self.remotes.keys()):
r = self.remotes[nodenum]
x, y, z = r.pos
self.updatenode(nodenum, MessageFlags.ADD.value, x, y, z,
r.name, r.type, r.icon)
self.updatenode(nodenum, MessageFlags.ADD.value, x, y, z, r.name, r.type, r.icon)
for net in nets:
all_links = net.all_link_data(flags=MessageFlags.ADD.value)
@ -411,7 +408,7 @@ class Sdt(object):
nodetype = None
try:
node = self.session.get_object(nodenum)
node = self.session.get_node(nodenum)
except KeyError:
node = None
if node:
@ -472,7 +469,7 @@ class Sdt(object):
return True
else:
try:
n = self.session.get_object(nodenum)
n = self.session.get_node(nodenum)
except KeyError:
return False
if nodeutils.is_node(n, (NodeTypes.WIRELESS_LAN, NodeTypes.EMANE)):

View file

@ -6,7 +6,7 @@ __all__ is automatically loaded by the main core module.
"""
import os
from core.service import ServiceManager
from core.services.coreservices import ServiceManager
_PATH = os.path.abspath(os.path.dirname(__file__))

View file

@ -2,7 +2,7 @@
bird.py: defines routing services provided by the BIRD Internet Routing Daemon.
"""
from core.service import CoreService
from core.services.coreservices import CoreService
class Bird(CoreService):

View file

@ -14,11 +14,10 @@ from multiprocessing.pool import ThreadPool
import enum
from core.constants import which
from core import CoreCommandError
from core.data import FileData
from core.enumerations import MessageFlags
from core.enumerations import RegisterTlvs
from core.misc import utils
from core import CoreCommandError, utils
from core.emulator.data import FileData
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import RegisterTlvs
class ServiceBootError(Exception):
@ -58,7 +57,7 @@ class ServiceDependencies(object):
Generates the boot paths for the services provided to the class.
:return: list of services to boot, in order
:rtype: list[core.service.CoreService]
:rtype: list[core.coreservices.CoreService]
"""
paths = []
for service in self.node_services.itervalues():
@ -126,7 +125,7 @@ class ServiceShim(object):
Convert service properties into a string list of key=value pairs,
separated by "|".
:param core.netns.nodes.CoreNode node: node to get value list for
:param core.netns.vnode.CoreNode node: node to get value list for
:param CoreService service: service to get value list for
:return: value list string
:rtype: str
@ -556,7 +555,7 @@ class CoreServices(object):
"""
Stop all services on a node.
:param core.netns.nodes.CoreNode node: node to stop services on
:param core.netns.vnode.CoreNode node: node to stop services on
:return: nothing
"""
for service in node.services:

View file

@ -99,8 +99,8 @@ Limitations:
import logging
from core.service import CoreService
from core.service import ServiceManager
from core.services.coreservices import CoreService
from core.services.coreservices import ServiceManager
try:
from docker import Client

View file

@ -1,6 +1,6 @@
from core.enumerations import NodeTypes
from core.misc import nodeutils
from core.service import CoreService
from core.emulator.enumerations import NodeTypes
from core.nodes import nodeutils
from core.services.coreservices import CoreService
from core.xml import emanexml
@ -21,7 +21,7 @@ class EmaneTransportService(CoreService):
if filename == cls.configs[0]:
transport_commands = []
for interface in node.netifs(sort=True):
network_node = node.session.get_object(interface.net.id)
network_node = node.session.get_node(interface.net.id)
if nodeutils.is_node(network_node, NodeTypes.EMANE):
config = node.session.emane.get_configs(network_node.id, network_node.model.name)
if config and emanexml.is_external(config):

View file

@ -4,10 +4,9 @@ Assumes installation of FRR via https://deb.frrouting.org/
"""
from core import constants
from core.enumerations import LinkTypes, NodeTypes
from core.misc import ipaddress
from core.misc import nodeutils
from core.service import CoreService
from core.emulator.enumerations import LinkTypes, NodeTypes
from core.nodes import nodeutils, ipaddress
from core.services.coreservices import CoreService
class FRRZebra(CoreService):

View file

@ -3,9 +3,9 @@ nrl.py: defines services provided by NRL protolib tools hosted here:
http://www.nrl.navy.mil/itd/ncs/products
"""
from core.misc import utils
from core.misc.ipaddress import Ipv4Prefix
from core.service import CoreService
from core import utils
from core.nodes.ipaddress import Ipv4Prefix
from core.services.coreservices import CoreService
class NrlService(CoreService):

View file

@ -3,10 +3,9 @@ quagga.py: defines routing services provided by Quagga.
"""
from core import constants
from core.enumerations import LinkTypes, NodeTypes
from core.misc import ipaddress
from core.misc import nodeutils
from core.service import CoreService
from core.emulator.enumerations import LinkTypes, NodeTypes
from core.nodes import nodeutils, ipaddress
from core.services.coreservices import CoreService
class Zebra(CoreService):

View file

@ -4,7 +4,7 @@ sdn.py defines services to start Open vSwitch and the Ryu SDN Controller.
import re
from core.service import CoreService
from core.services.coreservices import CoreService
class SdnService(CoreService):

View file

@ -6,7 +6,7 @@ firewall)
import logging
from core import constants
from core.service import CoreService
from core.services.coreservices import CoreService
class VPNClient(CoreService):

View file

@ -2,7 +2,7 @@
ucarp.py: defines high-availability IP address controlled by ucarp
"""
from core.service import CoreService
from core.services.coreservices import CoreService
UCARP_ETC = "/usr/local/etc/ucarp"

View file

@ -4,12 +4,11 @@ utility.py: defines miscellaneous utility services.
import os
from core import CoreCommandError
from core import CoreCommandError, utils
from core import constants
from core.misc import utils
from core.misc.ipaddress import Ipv4Prefix
from core.misc.ipaddress import Ipv6Prefix
from core.service import CoreService
from core.nodes.ipaddress import Ipv4Prefix
from core.nodes.ipaddress import Ipv6Prefix
from core.services.coreservices import CoreService
class UtilService(CoreService):

View file

@ -4,7 +4,7 @@ xorp.py: defines routing services provided by the XORP routing suite.
import logging
from core.service import CoreService
from core.services.coreservices import CoreService
class XorpRtrmgr(CoreService):

View file

@ -1,15 +1,14 @@
import logging
from lxml import etree
from core import coreobj
import core.nodes.base
import core.nodes.physical
from core.emulator.emudata import InterfaceData
from core.emulator.emudata import LinkOptions
from core.emulator.emudata import NodeOptions
from core.enumerations import NodeTypes
from core.misc import nodeutils
from core.misc.ipaddress import MacAddress
from core.netns import nodes
from core.emulator.enumerations import NodeTypes
from core.nodes import nodeutils
from core.nodes.ipaddress import MacAddress
def write_xml_file(xml_element, file_path, doctype=None):
@ -377,12 +376,12 @@ class CoreXmlWriter(object):
self.devices = etree.SubElement(self.scenario, "devices")
links = []
for node in self.session.objects.itervalues():
for node in self.session.nodes.itervalues():
# network node
if isinstance(node, (coreobj.PyCoreNet, nodes.RJ45Node)) and not nodeutils.is_node(node, NodeTypes.CONTROL_NET):
if isinstance(node, (core.nodes.base.CoreNetworkBase, core.nodes.physical.Rj45Node)) and not nodeutils.is_node(node, NodeTypes.CONTROL_NET):
self.write_network(node)
# device node
elif isinstance(node, nodes.PyCoreNode):
elif isinstance(node, core.nodes.base.CoreNodeBase):
self.write_device(node)
# add known links
@ -432,7 +431,7 @@ class CoreXmlWriter(object):
# check for interface one
if link_data.interface1_id is not None:
interface_one = etree.Element("interface_one")
node = self.session.get_object(link_data.node1_id)
node = self.session.get_node(link_data.node1_id)
node_interface = node.netif(link_data.interface1_id)
add_attribute(interface_one, "id", link_data.interface1_id)
@ -453,7 +452,7 @@ class CoreXmlWriter(object):
# check for interface two
if link_data.interface2_id is not None:
interface_two = etree.Element("interface_two")
node = self.session.get_object(link_data.node2_id)
node = self.session.get_node(link_data.node2_id)
node_interface = node.netif(link_data.interface2_id)
add_attribute(interface_two, "id", link_data.interface2_id)

View file

@ -3,10 +3,10 @@ import socket
from lxml import etree
from core import constants
from core.coreobj import PyCoreNode
from core.enumerations import NodeTypes
from core.misc import utils, nodeutils, ipaddress
from core import constants, utils
from core.nodes.base import CoreNodeBase
from core.emulator.enumerations import NodeTypes
from core.nodes import nodeutils, ipaddress
def add_type(parent_element, name):
@ -100,8 +100,8 @@ class CoreXmlDeployment(object):
# servers = self.session.broker.getservernames()
# servers.remove("localhost")
for node in self.session.objects.itervalues():
if isinstance(node, PyCoreNode):
for node in self.session.nodes.itervalues():
if isinstance(node, CoreNodeBase):
self.add_virtual_host(physical_host, node)
def add_physical_host(self, name):
@ -119,7 +119,7 @@ class CoreXmlDeployment(object):
return host_element
def add_virtual_host(self, physical_host, node):
if not isinstance(node, PyCoreNode):
if not isinstance(node, CoreNodeBase):
raise TypeError("invalid node type: %s" % node)
# create virtual host element

View file

@ -3,8 +3,8 @@ import os
from lxml import etree
from core.misc import utils
from core.misc.ipaddress import MacAddress
from core import utils
from core.nodes.ipaddress import MacAddress
from core.xml import corexml
_hwaddr_prefix = "02:02"
@ -101,7 +101,7 @@ def build_node_platform_xml(emane_manager, control_net, node, nem_id, platform_x
Create platform xml for a specific node.
:param core.emane.emanemanager.EmaneManager emane_manager: emane manager with emane configurations
:param core.netns.nodes.CtrlNet control_net: control net node for this emane network
:param core.nodes.network.CtrlNet control_net: control net node for this emane network
:param core.emane.nodes.EmaneNode node: node to write platform xml for
:param int nem_id: nem id to use for interfaces for this node
:param dict platform_xmls: stores platform xml elements to append nem entries to
@ -121,7 +121,7 @@ def build_node_platform_xml(emane_manager, control_net, node, nem_id, platform_x
nem_element = etree.Element("nem", id=str(nem_id), name=netif.localname, definition=nem_definition)
# check if this is an external transport, get default config if an interface specific one does not exist
config = emane_manager.getifcconfig(node.model.object_id, netif, node.model.name)
config = emane_manager.getifcconfig(node.model.id, netif, node.model.name)
if is_external(config):
nem_element.set("transport", "external")
@ -214,7 +214,7 @@ def build_xml_files(emane_manager, node):
return
# get model configurations
config = emane_manager.get_configs(node.model.object_id, node.model.name)
config = emane_manager.get_configs(node.model.id, node.model.name)
if not config:
return
@ -229,7 +229,7 @@ def build_xml_files(emane_manager, node):
for netif in node.netifs():
# check for interface specific emane configuration and write xml files, if needed
config = emane_manager.getifcconfig(node.model.object_id, netif, node.model.name)
config = emane_manager.getifcconfig(node.model.id, netif, node.model.name)
if config:
node.model.build_xml_files(config, netif)
@ -379,7 +379,7 @@ def _basename(emane_model, interface=None):
:return: basename used for file creation
:rtype: str
"""
name = "n%s" % emane_model.object_id
name = "n%s" % emane_model.id
if interface:
node_id = interface.node.id

View file

@ -9,7 +9,7 @@ from core import load_logging_config
from core.emane.ieee80211abg import EmaneIeee80211abgModel
from core.emulator.coreemu import CoreEmu
from core.emulator.emudata import IpPrefixes
from core.enumerations import EventTypes
from core.emulator.enumerations import EventTypes
load_logging_config()
@ -43,7 +43,7 @@ def example(options):
session.instantiate()
# start a shell on the first node
node = session.get_object(2)
node = session.get_node(2)
node.client.term("bash")
# shutdown session

View file

@ -11,7 +11,7 @@ import parser
from core import load_logging_config
from core.emulator.coreemu import CoreEmu
from core.emulator.emudata import IpPrefixes
from core.enumerations import NodeTypes, EventTypes
from core.emulator.enumerations import NodeTypes, EventTypes
load_logging_config()
@ -40,8 +40,8 @@ def example(options):
session.instantiate()
# get nodes to run example
first_node = session.get_object(2)
last_node = session.get_object(options.nodes + 1)
first_node = session.get_node(2)
last_node = session.get_node(options.nodes + 1)
print "starting iperf server on node: %s" % first_node.name
first_node.cmd(["iperf", "-s", "-D"])

View file

@ -6,7 +6,7 @@
# nodestep
from core import load_logging_config
from core.emulator.emudata import IpPrefixes
from core.enumerations import NodeTypes, EventTypes
from core.emulator.enumerations import NodeTypes, EventTypes
load_logging_config()

View file

@ -11,8 +11,8 @@ import parser
from core import load_logging_config
from core.emulator.coreemu import CoreEmu
from core.emulator.emudata import IpPrefixes, NodeOptions
from core.enumerations import NodeTypes, EventTypes
from core.mobility import BasicRangeModel
from core.emulator.enumerations import NodeTypes, EventTypes
from core.location.mobility import BasicRangeModel
load_logging_config()
@ -44,8 +44,8 @@ def example(options):
session.instantiate()
# get nodes for example run
first_node = session.get_object(2)
last_node = session.get_object(options.nodes + 1)
first_node = session.get_node(2)
last_node = session.get_node(options.nodes + 1)
print "starting iperf server on node: %s" % first_node.name
first_node.cmd(["iperf", "-s", "-D"])

View file

@ -1,7 +1,7 @@
import logging
import time
from core.misc.event import EventLoop
from core.location.event import EventLoop
def main():

View file

@ -1,7 +1,6 @@
import logging
from core.grpc import client
from core.grpc import core_pb2
from core.api.grpc import client, core_pb2
def log_event(event):

View file

@ -2,8 +2,8 @@
Sample user-defined service.
"""
from core.service import CoreService
from core.service import ServiceMode
from core.services.coreservices import CoreService
from core.services.coreservices import ServiceMode
## Custom CORE Service

View file

@ -14,23 +14,23 @@ import datetime
import optparse
import sys
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
from core.netns import nodes
import core.nodes.base
import core.nodes.network
from core.api.tlv import coreapi, dataconversion
from core.api.tlv.coreapi import CoreExecuteTlv
from core.emulator.enumerations import CORE_API_PORT
from core.emulator.enumerations import EventTlvs
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import ExecuteTlvs
from core.emulator.enumerations import LinkTlvs
from core.emulator.enumerations import LinkTypes
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.nodes import ipaddress
# declare classes for use with Broker
from core.session import Session
from core.emulator.session import Session
# node list (count from 1)
n = [None]
@ -136,7 +136,7 @@ def main():
session.broker.handlerawmsg(coreapi.CoreEventMessage.pack(0, tlvdata))
flags = MessageFlags.ADD.value
switch = nodes.SwitchNode(session=session, name="switch", start=False)
switch = core.nodes.network.SwitchNode(session=session, name="switch", start=False)
switch.setposition(x=80, y=50)
switch.server = daemon
switch_data = switch.data(flags)
@ -149,7 +149,7 @@ def main():
# create remote nodes via API
for i in xrange(1, number_of_nodes + 1):
node = nodes.CoreNode(session=session, _id=i, name="n%d" % i, start=False)
node = core.nodes.base.CoreNode(session=session, _id=i, name="n%d" % i, start=False)
node.setposition(x=150 * i, y=150)
node.server = daemon
node_data = node.data(flags)

View file

@ -13,12 +13,13 @@ import datetime
import optparse
import sys
import core.nodes.base
import core.nodes.network
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
from core.netns import nodes
from core.session import Session
from core.api.tlv import coreapi, dataconversion
from core.emulator.enumerations import CORE_API_PORT, EventTypes, EventTlvs, LinkTlvs, LinkTypes, MessageFlags
from core.nodes import ipaddress
from core.emulator.session import Session
# node list (count from 1)
n = [None]
@ -73,14 +74,14 @@ def main():
tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.CONFIGURATION_STATE.value)
session.broker.handlerawmsg(coreapi.CoreEventMessage.pack(0, tlvdata))
switch = session.add_object(cls=nodes.SwitchNode, name="switch")
switch = session.create_node(cls=core.nodes.network.SwitchNode, name="switch")
switch.setposition(x=80, y=50)
num_local = options.numnodes / 2
num_remote = options.numnodes / 2 + options.numnodes % 2
print "creating %d (%d local / %d remote) nodes with addresses from %s" % \
(options.numnodes, num_local, num_remote, prefix)
for i in xrange(1, num_local + 1):
node = session.add_object(cls=nodes.CoreNode, name="n%d" % i, _id=i)
node = session.create_node(cls=core.nodes.base.CoreNode, name="n%d" % i, _id=i)
node.newnetif(switch, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
node.cmd([constants.SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
node.setposition(x=150 * i, y=150)
@ -91,7 +92,7 @@ def main():
# create remote nodes via API
for i in xrange(num_local + 1, options.numnodes + 1):
node = nodes.CoreNode(session=session, _id=i, name="n%d" % i, start=False)
node = core.nodes.base.CoreNode(session=session, _id=i, name="n%d" % i, start=False)
node.setposition(x=150 * i, y=150)
node.server = slave
n.append(node)

View file

@ -19,10 +19,11 @@ import shutil
import sys
import time
import core.nodes.base
import core.nodes.network
from core import constants
from core.misc import ipaddress
from core.netns import nodes
from core.session import Session
from core.nodes import ipaddress
from core.emulator.session import Session
GBD = 1024.0 * 1024.0
@ -135,7 +136,7 @@ def main():
lfp.flush()
session = Session(1)
switch = session.add_object(cls=nodes.SwitchNode)
switch = session.create_node(cls=core.nodes.network.SwitchNode)
switchlist.append(switch)
print "Added bridge %s (%d)." % (switch.brname, len(switchlist))
@ -146,7 +147,7 @@ def main():
# optionally add a bridge (options.bridges nodes per bridge)
try:
if 0 < options.bridges <= switch.numnetif():
switch = session.add_object(cls=nodes.SwitchNode)
switch = session.create_node(cls=core.nodes.network.SwitchNode)
switchlist.append(switch)
print "\nAdded bridge %s (%d) for node %d." % (switch.brname, len(switchlist), i)
except Exception, e:
@ -155,7 +156,7 @@ def main():
# create a node
try:
n = session.add_object(cls=nodes.LxcNode, name="n%d" % i)
n = session.create_node(cls=core.nodes.base.CoreNode, name="n%d" % i)
n.newnetif(switch, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
n.cmd([constants.SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
if options.services is not None:

View file

@ -15,14 +15,13 @@ import sys
import time
from string import Template
import core.nodes.base
import core.nodes.network
from core.constants import QUAGGA_STATE_DIR
from core.misc import ipaddress
from core.misc.utils import check_cmd
from core.netns import nodes
from core.nodes import ipaddress
from core.utils import check_cmd
# this is the /etc/core/core.conf default
from core.session import Session
from core.emulator.session import Session
quagga_sbin_search = ("/usr/local/sbin", "/usr/sbin", "/usr/lib/quagga")
quagga_path = "zebra"
@ -39,7 +38,7 @@ except OSError:
sys.exit(1)
class ManetNode(nodes.LxcNode):
class ManetNode(core.nodes.base.CoreNode):
""" An Lxc namespace node configured for Quagga OSPFv3 MANET MDR
"""
conftemp = Template("""\
@ -69,7 +68,7 @@ ip forwarding
routerid = ipaddr.split("/")[0]
self.ipaddr = ipaddr
self.routerid = routerid
nodes.LxcNode.__init__(self, core, _id, name, nodedir)
core.nodes.base.CoreBaseNode.__init__(self, core, _id, name, nodedir)
self.privatedir(self.confdir)
self.privatedir(QUAGGA_STATE_DIR)
@ -243,10 +242,10 @@ class ManetExperiment(object):
prefix = ipaddress.Ipv4Prefix("10.14.0.0/16")
self.session = Session(1)
# emulated network
self.net = self.session.add_object(cls=nodes.WlanNode)
self.net = self.session.create_node(cls=core.nodes.network.WlanNode)
for i in xrange(1, numnodes + 1):
addr = "%s/%s" % (prefix.addr(i), 32)
tmp = self.session.add_object(cls=ManetNode, ipaddr=addr, _id="%d" % i, name="n%d" % i)
tmp = self.session.create_node(cls=ManetNode, ipaddr=addr, _id="%d" % i, name="n%d" % i)
tmp.newnetif(self.net, [addr])
self.nodes.append(tmp)
# connect nodes with probability linkprob

View file

@ -37,13 +37,14 @@ import os
import sys
import time
import core.nodes.base
import core.nodes.network
from core import emane
from core.emane.bypass import EmaneBypassModel
from core.emane.nodes import EmaneNode
from core.emane.rfpipe import EmaneRfPipeModel
from core.misc import ipaddress
from core.netns import nodes
from core.session import Session
from core.nodes import ipaddress
from core.emulator.session import Session
try:
import emaneeventservice
@ -413,11 +414,11 @@ class Experiment(object):
prefix = ipaddress.Ipv4Prefix("10.0.0.0/16")
self.session = Session(1)
# emulated network
self.net = self.session.add_object(cls=nodes.WlanNode, name="wlan1")
self.net = self.session.create_node(cls=core.nodes.network.WlanNode, name="wlan1")
prev = None
for i in xrange(1, numnodes + 1):
addr = "%s/%s" % (prefix.addr(i), 32)
tmp = self.session.add_object(cls=nodes.CoreNode, _id=i, name="n%d" % i)
tmp = self.session.create_node(cls=core.nodes.base.CoreNode, _id=i, name="n%d" % i)
tmp.newnetif(self.net, [addr])
self.nodes.append(tmp)
self.session.services.add_services(tmp, "router", "IPForward")
@ -440,12 +441,12 @@ class Experiment(object):
self.session.location.setrefgeo(47.57917, -122.13232, 2.00000)
self.session.location.refscale = 150.0
self.session.emane.loadmodels()
self.net = self.session.add_object(cls=EmaneNode, _id=numnodes + 1, name="wlan1")
self.net = self.session.create_node(cls=EmaneNode, _id=numnodes + 1, name="wlan1")
self.net.verbose = verbose
# self.session.emane.addobj(self.net)
for i in xrange(1, numnodes + 1):
addr = "%s/%s" % (prefix.addr(i), 32)
tmp = self.session.add_object(cls=nodes.CoreNode, _id=i, name="n%d" % i)
tmp = self.session.create_node(cls=core.nodes.base.CoreNode, _id=i, name="n%d" % i)
# tmp.setposition(i * 20, 50, None)
tmp.setposition(50, 50, None)
tmp.newnetif(self.net, [addr])

View file

@ -8,8 +8,8 @@
import optparse
import socket
from core.api import coreapi
from core.enumerations import MessageFlags, SessionTlvs, CORE_API_PORT
from core.api.tlv import coreapi
from core.emulator.enumerations import MessageFlags, SessionTlvs, CORE_API_PORT
def main():

View file

@ -1,5 +1,5 @@
all:
$(PYTHON) -m grpc_tools.protoc -I . --python_out=../core/grpc --grpc_python_out=../core/grpc core.proto
$(PYTHON) -m grpc_tools.protoc -I . --python_out=../core/api/grpc --grpc_python_out=../core/api/grpc core.proto
clean:
-rm -f ../core/grpc/core_pb2*
-rm -f ../core/api/grpc/core_pb2*

View file

@ -14,11 +14,11 @@ import time
from core import load_logging_config
from core import constants
from core import enumerations
from core.corehandlers import CoreHandler
from core.coreserver import CoreServer
from core.grpc.server import CoreGrpcServer
from core.misc.utils import close_onexec
from core.emulator import enumerations
from core.api.tlv.corehandlers import CoreHandler
from core.api.tlv.coreserver import CoreServer
from core.api.grpc.server import CoreGrpcServer
from core.utils import close_onexec
load_logging_config()
@ -48,7 +48,7 @@ def cored(cfg):
try:
server = CoreServer((host, port), CoreHandler, cfg)
if cfg["ovs"] == "True":
from core.netns.openvswitch import OVS_NODES
from core.nodes.openvswitch import OVS_NODES
server.coreemu.update_nodes(OVS_NODES)
except:
logging.exception("error starting main server on: %s:%s", host, port)

View file

@ -8,11 +8,11 @@ import os
import socket
import sys
from core.api import coreapi
from core.enumerations import CORE_API_PORT
from core.enumerations import MessageFlags
from core.enumerations import MessageTypes
from core.enumerations import SessionTlvs
from core.api.tlv import coreapi
from core.emulator.enumerations import CORE_API_PORT
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.emulator.enumerations import SessionTlvs
def print_available_tlvs(t, tlv_class):

View file

@ -9,30 +9,30 @@ import time
import pytest
from mock.mock import MagicMock
from core.api.coreapi import CoreConfMessage
from core.api.coreapi import CoreEventMessage
from core.api.coreapi import CoreExecMessage
from core.api.coreapi import CoreLinkMessage
from core.api.coreapi import CoreNodeMessage
from core.corehandlers import CoreHandler
from core.coreserver import CoreServer
from core.api.tlv.coreapi import CoreConfMessage
from core.api.tlv.coreapi import CoreEventMessage
from core.api.tlv.coreapi import CoreExecMessage
from core.api.tlv.coreapi import CoreLinkMessage
from core.api.tlv.coreapi import CoreNodeMessage
from core.api.tlv.corehandlers import CoreHandler
from core.api.tlv.coreserver import CoreServer
from core.emulator.coreemu import CoreEmu
from core.emulator.emudata import IpPrefixes
from core.enumerations import CORE_API_PORT
from core.enumerations import ConfigTlvs
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 NodeTlvs
from core.enumerations import NodeTypes
from core.grpc.client import InterfaceHelper
from core.grpc.server import CoreGrpcServer
from core.misc import ipaddress
from core.misc.ipaddress import MacAddress
from core.service import ServiceManager
from core.emulator.enumerations import CORE_API_PORT
from core.emulator.enumerations import ConfigTlvs
from core.emulator.enumerations import EventTlvs
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import ExecuteTlvs
from core.emulator.enumerations import LinkTlvs
from core.emulator.enumerations import LinkTypes
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import NodeTlvs
from core.emulator.enumerations import NodeTypes
from core.api.grpc.client import InterfaceHelper
from core.api.grpc.server import CoreGrpcServer
from core.nodes import ipaddress
from core.nodes.ipaddress import MacAddress
from core.services.coreservices import ServiceManager
EMANE_SERVICES = "zebra|OSPFv3MDR|IPForward"

View file

@ -4,12 +4,12 @@ Unit tests for testing CORE with distributed networks.
import conftest
from core.api.coreapi import CoreExecMessage
from core.enumerations import EventTypes
from core.enumerations import ExecuteTlvs
from core.enumerations import MessageFlags
from core.enumerations import NodeTypes
from core.misc.ipaddress import IpAddress
from core.api.tlv.coreapi import CoreExecMessage
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import ExecuteTlvs
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import NodeTypes
from core.nodes.ipaddress import IpAddress
def validate_response(replies, _):
@ -89,7 +89,7 @@ class TestDistributed:
cored.request_handler.handle_message(message)
# test a ping command
node_one = cored.session.get_object(1)
node_one = cored.session.get_node(1)
message = conftest.command_message(node_one, "ping -c 5 %s" % ip4_address)
cored.request_handler.dispatch_replies = validate_response
cored.request_handler.handle_message(message)
@ -155,7 +155,7 @@ class TestDistributed:
cored.request_handler.handle_message(message)
# test a ping command
node_one = cored.session.get_object(1)
node_one = cored.session.get_node(1)
message = conftest.command_message(node_one, "ping -c 5 %s" % ip4_address)
cored.request_handler.dispatch_replies = validate_response
cored.request_handler.handle_message(message)

View file

@ -2,7 +2,7 @@
Sample user-defined services for testing.
"""
from core.service import CoreService
from core.services.coreservices import CoreService
class MyService(CoreService):

View file

@ -1,13 +1,13 @@
import pytest
from core.conf import ConfigurableManager
from core.conf import ConfigurableOptions
from core.conf import Configuration
from core.conf import ModelManager
from core.config import ConfigurableManager
from core.config import ConfigurableOptions
from core.config import Configuration
from core.config import ModelManager
from core.emane.ieee80211abg import EmaneIeee80211abgModel
from core.enumerations import ConfigDataTypes
from core.enumerations import NodeTypes
from core.mobility import BasicRangeModel
from core.emulator.enumerations import ConfigDataTypes
from core.emulator.enumerations import NodeTypes
from core.location.mobility import BasicRangeModel
class TestConfigurableOptions(ConfigurableOptions):

View file

@ -10,11 +10,11 @@ import pytest
from mock import MagicMock
from core.emulator.emudata import NodeOptions
from core.enumerations import MessageFlags
from core.enumerations import NodeTypes
from core.mobility import BasicRangeModel
from core.mobility import Ns2ScriptedMobility
from core.netns.vnodeclient import VnodeClient
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import NodeTypes
from core.location.mobility import BasicRangeModel
from core.location.mobility import Ns2ScriptedMobility
from core.nodes.client import VnodeClient
_PATH = os.path.abspath(os.path.dirname(__file__))
_MOBILITY_FILE = os.path.join(_PATH, "mobility.scen")

View file

@ -5,13 +5,13 @@ from Queue import Queue
import grpc
import pytest
from core.conf import ConfigShim
from core.data import EventData
from core.config import ConfigShim
from core.emulator.data import EventData
from core.emane.ieee80211abg import EmaneIeee80211abgModel
from core.enumerations import NodeTypes, EventTypes, ConfigFlags, ExceptionLevels
from core.grpc import core_pb2
from core.grpc.client import CoreGrpcClient
from core.mobility import BasicRangeModel, Ns2ScriptedMobility
from core.emulator.enumerations import NodeTypes, EventTypes, ConfigFlags, ExceptionLevels
from core.api.grpc import core_pb2
from core.api.grpc.client import CoreGrpcClient
from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility
class TestGrpc:
@ -182,7 +182,7 @@ class TestGrpc:
# then
assert response.id is not None
assert session.get_object(response.id) is not None
assert session.get_node(response.id) is not None
def test_get_node(self, grpc_server):
# given
@ -237,7 +237,7 @@ class TestGrpc:
assert response.result is expected
if expected is True:
with pytest.raises(KeyError):
assert session.get_object(node.id)
assert session.get_node(node.id)
def test_get_hooks(self, grpc_server):
# given
@ -390,8 +390,8 @@ class TestGrpc:
interface_two = ip_prefixes.create_interface(node_two)
session.add_link(node_one.id, node_two.id, interface_one, interface_two)
link_node = None
for node_id in session.objects:
node = session.objects[node_id]
for node_id in session.nodes:
node = session.nodes[node_id]
if node.id not in {node_one.id, node_two.id}:
link_node = node
break

View file

@ -4,17 +4,17 @@ Unit tests for testing with a CORE switch.
import threading
from core.api import coreapi, dataconversion
from core.api.coreapi import CoreExecuteTlv
from core.enumerations import CORE_API_PORT, NodeTypes
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
from core.api.tlv import coreapi, dataconversion
from core.api.tlv.coreapi import CoreExecuteTlv
from core.emulator.enumerations import CORE_API_PORT, NodeTypes
from core.emulator.enumerations import EventTlvs
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import ExecuteTlvs
from core.emulator.enumerations import LinkTlvs
from core.emulator.enumerations import LinkTypes
from core.emulator.enumerations import MessageFlags
from core.emulator.enumerations import MessageTypes
from core.nodes import ipaddress
def command_message(node, command):

View file

@ -1,6 +1,6 @@
from core.emulator.emudata import LinkOptions
from core.enumerations import NodeTypes
from core.misc import utils
from core.emulator.enumerations import NodeTypes
from core import utils
def create_ptp_network(session, ip_prefixes):

View file

@ -4,8 +4,8 @@ import time
import pytest
from core.emulator.emudata import NodeOptions
from core.enumerations import NodeTypes
from core.misc import utils
from core.emulator.enumerations import NodeTypes
from core import utils
MODELS = [
"router",
@ -63,7 +63,7 @@ class TestNodes:
# then
with pytest.raises(KeyError):
session.get_object(node.id)
session.get_node(node.id)
@pytest.mark.parametrize("net_type", NET_TYPES)
def test_net(self, session, net_type):

View file

@ -2,9 +2,9 @@ import os
import pytest
from core.service import CoreService
from core.service import ServiceDependencies
from core.service import ServiceManager
from core.services.coreservices import CoreService
from core.services.coreservices import ServiceDependencies
from core.services.coreservices import ServiceManager
_PATH = os.path.abspath(os.path.dirname(__file__))
_SERVICES_PATH = os.path.join(_PATH, "myservices")

View file

@ -1,4 +1,4 @@
from core.misc import utils
from core import utils
class TestUtils:

View file

@ -4,8 +4,8 @@ import pytest
from core.emane.ieee80211abg import EmaneIeee80211abgModel
from core.emulator.emudata import NodeOptions
from core.enumerations import NodeTypes
from core.mobility import BasicRangeModel
from core.emulator.enumerations import NodeTypes
from core.location.mobility import BasicRangeModel
from core.services.utility import SshService
@ -87,16 +87,16 @@ class TestXml:
# verify nodes have been removed from session
with pytest.raises(KeyError):
assert not session.get_object(n1_id)
assert not session.get_node(n1_id)
with pytest.raises(KeyError):
assert not session.get_object(n2_id)
assert not session.get_node(n2_id)
# load saved xml
session.open_xml(file_path, start=True)
# verify nodes have been recreated
assert session.get_object(n1_id)
assert session.get_object(n2_id)
assert session.get_node(n1_id)
assert session.get_node(n2_id)
def test_xml_ptp_services(self, session, tmpdir, ip_prefixes):
"""
@ -147,9 +147,9 @@ class TestXml:
# verify nodes have been removed from session
with pytest.raises(KeyError):
assert not session.get_object(n1_id)
assert not session.get_node(n1_id)
with pytest.raises(KeyError):
assert not session.get_object(n2_id)
assert not session.get_node(n2_id)
# load saved xml
session.open_xml(file_path, start=True)
@ -158,8 +158,8 @@ class TestXml:
service = session.services.get_service(node_one.id, SshService.name)
# verify nodes have been recreated
assert session.get_object(n1_id)
assert session.get_object(n2_id)
assert session.get_node(n1_id)
assert session.get_node(n2_id)
assert service.config_data.get(service_file) == file_data
def test_xml_mobility(self, session, tmpdir, ip_prefixes):
@ -208,9 +208,9 @@ class TestXml:
# verify nodes have been removed from session
with pytest.raises(KeyError):
assert not session.get_object(n1_id)
assert not session.get_node(n1_id)
with pytest.raises(KeyError):
assert not session.get_object(n2_id)
assert not session.get_node(n2_id)
# load saved xml
session.open_xml(file_path, start=True)
@ -219,9 +219,9 @@ class TestXml:
value = str(session.mobility.get_config("test", wlan_id, BasicRangeModel.name))
# verify nodes and configuration were restored
assert session.get_object(n1_id)
assert session.get_object(n2_id)
assert session.get_object(wlan_id)
assert session.get_node(n1_id)
assert session.get_node(n2_id)
assert session.get_node(wlan_id)
assert value == "1"
def test_xml_emane(self, session, tmpdir, ip_prefixes):
@ -275,9 +275,9 @@ class TestXml:
# verify nodes have been removed from session
with pytest.raises(KeyError):
assert not session.get_object(n1_id)
assert not session.get_node(n1_id)
with pytest.raises(KeyError):
assert not session.get_object(n2_id)
assert not session.get_node(n2_id)
# load saved xml
session.open_xml(file_path, start=True)
@ -286,7 +286,7 @@ class TestXml:
value = str(session.emane.get_config("test", emane_id, EmaneIeee80211abgModel.name))
# verify nodes and configuration were restored
assert session.get_object(n1_id)
assert session.get_object(n2_id)
assert session.get_object(emane_id)
assert session.get_node(n1_id)
assert session.get_node(n2_id)
assert session.get_node(emane_id)
assert value == "1"

View file

@ -17,14 +17,13 @@ import ns.wifi
import ns.wimax
from core import constants
from core.coreobj import PyCoreNet
from core.enumerations import EventTypes
from core.enumerations import LinkTypes
from core.enumerations import NodeTypes
from core.misc.utils import make_tuple
from core.mobility import WayPointMobility
from core.netns.nodes import CoreNode
from core.session import Session
from core.emulator.enumerations import EventTypes
from core.emulator.enumerations import LinkTypes
from core.emulator.enumerations import NodeTypes
from core.utils import make_tuple
from core.location.mobility import WayPointMobility
from core.nodes.base import CoreNode, CoreNetworkBase
from core.emulator.session import Session
ns.core.GlobalValue.Bind(
"SimulatorImplementationType",
@ -107,7 +106,7 @@ class CoreNs3Node(CoreNode, ns.network.Node):
self.warn("ns-3 mobility model not found, not setting position")
class CoreNs3Net(PyCoreNet):
class CoreNs3Net(CoreNetworkBase):
"""
The CoreNs3Net is a helper PyCoreNet object. Networks are represented
entirely in simulation with the TunTap device bridging the emulated and
@ -119,7 +118,7 @@ class CoreNs3Net(PyCoreNet):
type = "wlan"
def __init__(self, session, _id=None, name=None, start=True, policy=None):
PyCoreNet.__init__(self, session, _id, name)
CoreNetworkBase.__init__(self, session, _id, name)
self.tapbridge = ns.tap_bridge.TapBridgeHelper()
self._ns3devs = {}
self._tapdevs = {}
@ -402,7 +401,7 @@ class Ns3Session(Session):
A convenience helper for Session.addobj(), for adding CoreNs3Nodes
to this session. Keeps a NodeContainer for later use.
"""
n = self.add_object(cls=CoreNs3Node, name=name)
n = self.create_node(cls=CoreNs3Node, name=name)
self.nodes.Add(n)
return n
@ -488,7 +487,7 @@ class Ns3Session(Session):
Start a tracing thread using the ASCII output from the ns3
mobility helper.
"""
net.mobility = WayPointMobility(session=self, object_id=net.id)
net.mobility = WayPointMobility(session=self, _id=net.id)
net.mobility.setendtime()
net.mobility.refresh_ms = 300
net.mobility.empty_queue_stop = False

View file

@ -11,9 +11,7 @@ import sys
import ns.core
import ns.mobility
from core.misc import ipaddress
from core.misc import nodemaps
from core.misc import nodeutils
from core.nodes import nodeutils, nodemaps, ipaddress
from corens3.obj import Ns3LteNet
from corens3.obj import Ns3Session
@ -24,7 +22,7 @@ def ltesession(opt):
"""
nodeutils.set_node_map(nodemaps.NODES)
session = Ns3Session(1, persistent=True, duration=opt.duration)
lte = session.add_object(cls=Ns3LteNet, name="wlan1")
lte = session.create_node(cls=Ns3LteNet, name="wlan1")
lte.setsubchannels(range(25), range(50, 100))
if opt.verbose:
ascii_helper = ns.network.AsciiTraceHelper()

View file

@ -28,9 +28,7 @@ import sys
import ns.core
from core.misc import ipaddress
from core.misc import nodeutils
from core.misc import nodemaps
from core.nodes import nodeutils, nodemaps, ipaddress
from corens3.obj import Ns3Session
from corens3.obj import Ns3WifiNet
@ -59,7 +57,7 @@ def wifisession(opt):
session.node_count = str(opt.numnodes + 1)
add_to_server(session)
wifi = session.add_object(cls=Ns3WifiNet, name="wlan1")
wifi = session.create_node(cls=Ns3WifiNet, name="wlan1")
wifi.setposition(30, 30, 0)
wifi.phy.Set("RxGain", ns.core.DoubleValue(18.0))

View file

@ -20,9 +20,7 @@ import ns.network
from corens3.obj import Ns3Session
from corens3.obj import Ns3WifiNet
from core.misc import ipaddress
from core.misc import nodemaps
from core.misc import nodeutils
from core.nodes import nodeutils, nodemaps, ipaddress
def add_to_server(session):
@ -48,7 +46,7 @@ def wifisession(opt):
session.filename = session.name + ".py"
session.node_count = str(opt.numnodes + 1)
add_to_server(session)
wifi = session.add_object(cls=Ns3WifiNet, name="wlan1", rate="OfdmRate12Mbps")
wifi = session.create_node(cls=Ns3WifiNet, name="wlan1", rate="OfdmRate12Mbps")
wifi.setposition(30, 30, 0)
# for improved connectivity
wifi.phy.Set("RxGain", ns.core.DoubleValue(18.0))

View file

@ -13,9 +13,7 @@ import logging
import optparse
import sys
from core.misc import ipaddress
from core.misc import nodemaps
from core.misc import nodeutils
from core.nodes import nodeutils, nodemaps, ipaddress
from corens3.obj import Ns3Session
from corens3.obj import Ns3WimaxNet
@ -26,7 +24,7 @@ def wimaxsession(opt):
"""
nodeutils.set_node_map(nodemaps.NODES)
session = Ns3Session(1, persistent=True, duration=opt.duration)
wimax = session.add_object(cls=Ns3WimaxNet, name="wlan1")
wimax = session.create_node(cls=Ns3WimaxNet, name="wlan1")
# wimax.wimax.EnableLogComponents()
prefix = ipaddress.Ipv4Prefix("10.0.0.0/16")