initial sweeping changes to call all usages of various interface related variables and functions (netif, interface, if, ifc, etc) to use a consistent name iface
This commit is contained in:
parent
0462c1b084
commit
0725199d6d
93 changed files with 1955 additions and 2156 deletions
|
@ -110,27 +110,27 @@ class InterfaceHelper:
|
|||
"""
|
||||
self.prefixes: IpPrefixes = IpPrefixes(ip4_prefix, ip6_prefix)
|
||||
|
||||
def create_interface(
|
||||
self, node_id: int, interface_id: int, name: str = None, mac: str = None
|
||||
def create_iface(
|
||||
self, node_id: int, iface_id: int, name: str = None, mac: str = None
|
||||
) -> core_pb2.Interface:
|
||||
"""
|
||||
Create an interface protobuf object.
|
||||
|
||||
:param node_id: node id to create interface for
|
||||
:param interface_id: interface id
|
||||
:param iface_id: interface id
|
||||
:param name: name of interface
|
||||
:param mac: mac address for interface
|
||||
:return: interface protobuf
|
||||
"""
|
||||
interface_data = self.prefixes.gen_interface(node_id, name, mac)
|
||||
iface_data = self.prefixes.gen_iface(node_id, name, mac)
|
||||
return core_pb2.Interface(
|
||||
id=interface_id,
|
||||
name=interface_data.name,
|
||||
ip4=interface_data.ip4,
|
||||
ip4mask=interface_data.ip4_mask,
|
||||
ip6=interface_data.ip6,
|
||||
ip6mask=interface_data.ip6_mask,
|
||||
mac=interface_data.mac,
|
||||
id=iface_id,
|
||||
name=iface_data.name,
|
||||
ip4=iface_data.ip4,
|
||||
ip4mask=iface_data.ip4_mask,
|
||||
ip6=iface_data.ip6,
|
||||
ip6mask=iface_data.ip6_mask,
|
||||
mac=iface_data.mac,
|
||||
)
|
||||
|
||||
|
||||
|
@ -611,8 +611,8 @@ class CoreGrpcClient:
|
|||
session_id: int,
|
||||
node1_id: int,
|
||||
node2_id: int,
|
||||
interface1: core_pb2.Interface = None,
|
||||
interface2: core_pb2.Interface = None,
|
||||
iface1: core_pb2.Interface = None,
|
||||
iface2: core_pb2.Interface = None,
|
||||
options: core_pb2.LinkOptions = None,
|
||||
) -> core_pb2.AddLinkResponse:
|
||||
"""
|
||||
|
@ -621,8 +621,8 @@ class CoreGrpcClient:
|
|||
:param session_id: session id
|
||||
:param node1_id: node one id
|
||||
:param node2_id: node two id
|
||||
:param interface1: node one interface data
|
||||
:param interface2: node two interface data
|
||||
:param iface1: node one interface data
|
||||
:param iface2: node two interface data
|
||||
:param options: options for link (jitter, bandwidth, etc)
|
||||
:return: response with result of success or failure
|
||||
:raises grpc.RpcError: when session or one of the nodes don't exist
|
||||
|
@ -631,8 +631,8 @@ class CoreGrpcClient:
|
|||
node1_id=node1_id,
|
||||
node2_id=node2_id,
|
||||
type=core_pb2.LinkType.WIRED,
|
||||
interface1=interface1,
|
||||
interface2=interface2,
|
||||
iface1=iface1,
|
||||
iface2=iface2,
|
||||
options=options,
|
||||
)
|
||||
request = core_pb2.AddLinkRequest(session_id=session_id, link=link)
|
||||
|
@ -644,8 +644,8 @@ class CoreGrpcClient:
|
|||
node1_id: int,
|
||||
node2_id: int,
|
||||
options: core_pb2.LinkOptions,
|
||||
interface1_id: int = None,
|
||||
interface2_id: int = None,
|
||||
iface1_id: int = None,
|
||||
iface2_id: int = None,
|
||||
) -> core_pb2.EditLinkResponse:
|
||||
"""
|
||||
Edit a link between nodes.
|
||||
|
@ -654,8 +654,8 @@ class CoreGrpcClient:
|
|||
:param node1_id: node one id
|
||||
:param node2_id: node two id
|
||||
:param options: options for link (jitter, bandwidth, etc)
|
||||
:param interface1_id: node one interface id
|
||||
:param interface2_id: node two interface id
|
||||
:param iface1_id: node one interface id
|
||||
:param iface2_id: node two interface id
|
||||
:return: response with result of success or failure
|
||||
:raises grpc.RpcError: when session or one of the nodes don't exist
|
||||
"""
|
||||
|
@ -664,8 +664,8 @@ class CoreGrpcClient:
|
|||
node1_id=node1_id,
|
||||
node2_id=node2_id,
|
||||
options=options,
|
||||
interface1_id=interface1_id,
|
||||
interface2_id=interface2_id,
|
||||
iface1_id=iface1_id,
|
||||
iface2_id=iface2_id,
|
||||
)
|
||||
return self.stub.EditLink(request)
|
||||
|
||||
|
@ -674,8 +674,8 @@ class CoreGrpcClient:
|
|||
session_id: int,
|
||||
node1_id: int,
|
||||
node2_id: int,
|
||||
interface1_id: int = None,
|
||||
interface2_id: int = None,
|
||||
iface1_id: int = None,
|
||||
iface2_id: int = None,
|
||||
) -> core_pb2.DeleteLinkResponse:
|
||||
"""
|
||||
Delete a link between nodes.
|
||||
|
@ -683,8 +683,8 @@ class CoreGrpcClient:
|
|||
:param session_id: session id
|
||||
:param node1_id: node one id
|
||||
:param node2_id: node two id
|
||||
:param interface1_id: node one interface id
|
||||
:param interface2_id: node two interface id
|
||||
:param iface1_id: node one interface id
|
||||
:param iface2_id: node two interface id
|
||||
:return: response with result of success or failure
|
||||
:raises grpc.RpcError: when session doesn't exist
|
||||
"""
|
||||
|
@ -692,8 +692,8 @@ class CoreGrpcClient:
|
|||
session_id=session_id,
|
||||
node1_id=node1_id,
|
||||
node2_id=node2_id,
|
||||
interface1_id=interface1_id,
|
||||
interface2_id=interface2_id,
|
||||
iface1_id=iface1_id,
|
||||
iface2_id=iface2_id,
|
||||
)
|
||||
return self.stub.DeleteLink(request)
|
||||
|
||||
|
@ -1028,7 +1028,7 @@ class CoreGrpcClient:
|
|||
return self.stub.GetEmaneModels(request)
|
||||
|
||||
def get_emane_model_config(
|
||||
self, session_id: int, node_id: int, model: str, interface_id: int = -1
|
||||
self, session_id: int, node_id: int, model: str, iface_id: int = -1
|
||||
) -> GetEmaneModelConfigResponse:
|
||||
"""
|
||||
Get emane model configuration for a node or a node's interface.
|
||||
|
@ -1036,12 +1036,12 @@ class CoreGrpcClient:
|
|||
:param session_id: session id
|
||||
:param node_id: node id
|
||||
:param model: emane model name
|
||||
:param interface_id: node interface id
|
||||
:param iface_id: node interface id
|
||||
:return: response with a list of configuration groups
|
||||
:raises grpc.RpcError: when session doesn't exist
|
||||
"""
|
||||
request = GetEmaneModelConfigRequest(
|
||||
session_id=session_id, node_id=node_id, model=model, interface=interface_id
|
||||
session_id=session_id, node_id=node_id, model=model, iface_id=iface_id
|
||||
)
|
||||
return self.stub.GetEmaneModelConfig(request)
|
||||
|
||||
|
@ -1051,7 +1051,7 @@ class CoreGrpcClient:
|
|||
node_id: int,
|
||||
model: str,
|
||||
config: Dict[str, str] = None,
|
||||
interface_id: int = -1,
|
||||
iface_id: int = -1,
|
||||
) -> SetEmaneModelConfigResponse:
|
||||
"""
|
||||
Set emane model configuration for a node or a node's interface.
|
||||
|
@ -1060,12 +1060,12 @@ class CoreGrpcClient:
|
|||
:param node_id: node id
|
||||
:param model: emane model name
|
||||
:param config: emane model configuration
|
||||
:param interface_id: node interface id
|
||||
:param iface_id: node interface id
|
||||
:return: response with result of success or failure
|
||||
:raises grpc.RpcError: when session doesn't exist
|
||||
"""
|
||||
model_config = EmaneModelConfig(
|
||||
node_id=node_id, model=model, config=config, interface_id=interface_id
|
||||
node_id=node_id, model=model, config=config, iface_id=iface_id
|
||||
)
|
||||
request = SetEmaneModelConfigRequest(
|
||||
session_id=session_id, emane_model_config=model_config
|
||||
|
@ -1128,7 +1128,7 @@ class CoreGrpcClient:
|
|||
)
|
||||
return self.stub.EmaneLink(request)
|
||||
|
||||
def get_interfaces(self) -> core_pb2.GetInterfacesResponse:
|
||||
def get_ifaces(self) -> core_pb2.GetInterfacesResponse:
|
||||
"""
|
||||
Retrieves a list of interfaces available on the host machine that are not
|
||||
a part of a CORE session.
|
||||
|
|
|
@ -82,7 +82,7 @@ def handle_config_event(event: ConfigData) -> core_pb2.ConfigEvent:
|
|||
data_values=event.data_values,
|
||||
possible_values=event.possible_values,
|
||||
groups=event.groups,
|
||||
interface=event.interface_number,
|
||||
iface_id=event.iface_id,
|
||||
network_id=event.network_id,
|
||||
opaque=event.opaque,
|
||||
data_types=event.data_types,
|
||||
|
|
|
@ -52,29 +52,29 @@ def add_node_data(node_proto: core_pb2.Node) -> Tuple[NodeTypes, int, NodeOption
|
|||
return _type, _id, options
|
||||
|
||||
|
||||
def link_interface(interface_proto: core_pb2.Interface) -> InterfaceData:
|
||||
def link_iface(iface_proto: core_pb2.Interface) -> InterfaceData:
|
||||
"""
|
||||
Create interface data from interface proto.
|
||||
|
||||
:param interface_proto: interface proto
|
||||
:param iface_proto: interface proto
|
||||
:return: interface data
|
||||
"""
|
||||
interface_data = None
|
||||
if interface_proto:
|
||||
name = interface_proto.name if interface_proto.name else None
|
||||
mac = interface_proto.mac if interface_proto.mac else None
|
||||
ip4 = interface_proto.ip4 if interface_proto.ip4 else None
|
||||
ip6 = interface_proto.ip6 if interface_proto.ip6 else None
|
||||
interface_data = InterfaceData(
|
||||
id=interface_proto.id,
|
||||
iface_data = None
|
||||
if iface_proto:
|
||||
name = iface_proto.name if iface_proto.name else None
|
||||
mac = iface_proto.mac if iface_proto.mac else None
|
||||
ip4 = iface_proto.ip4 if iface_proto.ip4 else None
|
||||
ip6 = iface_proto.ip6 if iface_proto.ip6 else None
|
||||
iface_data = InterfaceData(
|
||||
id=iface_proto.id,
|
||||
name=name,
|
||||
mac=mac,
|
||||
ip4=ip4,
|
||||
ip4_mask=interface_proto.ip4mask,
|
||||
ip4_mask=iface_proto.ip4mask,
|
||||
ip6=ip6,
|
||||
ip6_mask=interface_proto.ip6mask,
|
||||
ip6_mask=iface_proto.ip6mask,
|
||||
)
|
||||
return interface_data
|
||||
return iface_data
|
||||
|
||||
|
||||
def add_link_data(
|
||||
|
@ -86,8 +86,8 @@ def add_link_data(
|
|||
:param link_proto: link proto
|
||||
:return: link interfaces and options
|
||||
"""
|
||||
interface1_data = link_interface(link_proto.interface1)
|
||||
interface2_data = link_interface(link_proto.interface2)
|
||||
iface1_data = link_iface(link_proto.iface1)
|
||||
iface2_data = link_iface(link_proto.iface2)
|
||||
link_type = LinkTypes(link_proto.type)
|
||||
options = LinkOptions(type=link_type)
|
||||
options_data = link_proto.options
|
||||
|
@ -103,7 +103,7 @@ def add_link_data(
|
|||
options.unidirectional = options_data.unidirectional
|
||||
options.key = options_data.key
|
||||
options.opaque = options_data.opaque
|
||||
return interface1_data, interface2_data, options
|
||||
return iface1_data, iface2_data, options
|
||||
|
||||
|
||||
def create_nodes(
|
||||
|
@ -143,8 +143,8 @@ def create_links(
|
|||
for link_proto in link_protos:
|
||||
node1_id = link_proto.node1_id
|
||||
node2_id = link_proto.node2_id
|
||||
interface1, interface2, options = add_link_data(link_proto)
|
||||
args = (node1_id, node2_id, interface1, interface2, options)
|
||||
iface1, iface2, options = add_link_data(link_proto)
|
||||
args = (node1_id, node2_id, iface1, iface2, options)
|
||||
funcs.append((session.add_link, args, {}))
|
||||
start = time.monotonic()
|
||||
results, exceptions = utils.threadpool(funcs)
|
||||
|
@ -167,8 +167,8 @@ def edit_links(
|
|||
for link_proto in link_protos:
|
||||
node1_id = link_proto.node1_id
|
||||
node2_id = link_proto.node2_id
|
||||
interface1, interface2, options = add_link_data(link_proto)
|
||||
args = (node1_id, node2_id, interface1.id, interface2.id, options)
|
||||
iface1, iface2, options = add_link_data(link_proto)
|
||||
args = (node1_id, node2_id, iface1.id, iface2.id, options)
|
||||
funcs.append((session.update_link, args, {}))
|
||||
start = time.monotonic()
|
||||
results, exceptions = utils.threadpool(funcs)
|
||||
|
@ -279,16 +279,16 @@ def get_links(node: NodeBase):
|
|||
return links
|
||||
|
||||
|
||||
def get_emane_model_id(node_id: int, interface_id: int) -> int:
|
||||
def get_emane_model_id(node_id: int, iface_id: int) -> int:
|
||||
"""
|
||||
Get EMANE model id
|
||||
|
||||
:param node_id: node id
|
||||
:param interface_id: interface id
|
||||
:param iface_id: interface id
|
||||
:return: EMANE model id
|
||||
"""
|
||||
if interface_id >= 0:
|
||||
return node_id * 1000 + interface_id
|
||||
if iface_id >= 0:
|
||||
return node_id * 1000 + iface_id
|
||||
else:
|
||||
return node_id
|
||||
|
||||
|
@ -300,12 +300,12 @@ def parse_emane_model_id(_id: int) -> Tuple[int, int]:
|
|||
:param _id: id to parse
|
||||
:return: node id and interface id
|
||||
"""
|
||||
interface = -1
|
||||
iface_id = -1
|
||||
node_id = _id
|
||||
if _id >= 1000:
|
||||
interface = _id % 1000
|
||||
iface_id = _id % 1000
|
||||
node_id = int(_id / 1000)
|
||||
return node_id, interface
|
||||
return node_id, iface_id
|
||||
|
||||
|
||||
def convert_link(link_data: LinkData) -> core_pb2.Link:
|
||||
|
@ -315,27 +315,27 @@ def convert_link(link_data: LinkData) -> core_pb2.Link:
|
|||
:param link_data: link to convert
|
||||
:return: core protobuf Link
|
||||
"""
|
||||
interface1 = None
|
||||
if link_data.interface1_id is not None:
|
||||
interface1 = core_pb2.Interface(
|
||||
id=link_data.interface1_id,
|
||||
name=link_data.interface1_name,
|
||||
mac=convert_value(link_data.interface1_mac),
|
||||
ip4=convert_value(link_data.interface1_ip4),
|
||||
ip4mask=link_data.interface1_ip4_mask,
|
||||
ip6=convert_value(link_data.interface1_ip6),
|
||||
ip6mask=link_data.interface1_ip6_mask,
|
||||
iface1 = None
|
||||
if link_data.iface1_id is not None:
|
||||
iface1 = core_pb2.Interface(
|
||||
id=link_data.iface1_id,
|
||||
name=link_data.iface1_name,
|
||||
mac=convert_value(link_data.iface1_mac),
|
||||
ip4=convert_value(link_data.iface1_ip4),
|
||||
ip4mask=link_data.iface1_ip4_mask,
|
||||
ip6=convert_value(link_data.iface1_ip6),
|
||||
ip6mask=link_data.iface1_ip6_mask,
|
||||
)
|
||||
interface2 = None
|
||||
if link_data.interface2_id is not None:
|
||||
interface2 = core_pb2.Interface(
|
||||
id=link_data.interface2_id,
|
||||
name=link_data.interface2_name,
|
||||
mac=convert_value(link_data.interface2_mac),
|
||||
ip4=convert_value(link_data.interface2_ip4),
|
||||
ip4mask=link_data.interface2_ip4_mask,
|
||||
ip6=convert_value(link_data.interface2_ip6),
|
||||
ip6mask=link_data.interface2_ip6_mask,
|
||||
iface2 = None
|
||||
if link_data.iface2_id is not None:
|
||||
iface2 = core_pb2.Interface(
|
||||
id=link_data.iface2_id,
|
||||
name=link_data.iface2_name,
|
||||
mac=convert_value(link_data.iface2_mac),
|
||||
ip4=convert_value(link_data.iface2_ip4),
|
||||
ip4mask=link_data.iface2_ip4_mask,
|
||||
ip6=convert_value(link_data.iface2_ip6),
|
||||
ip6mask=link_data.iface2_ip6_mask,
|
||||
)
|
||||
options = core_pb2.LinkOptions(
|
||||
opaque=link_data.opaque,
|
||||
|
@ -354,8 +354,8 @@ def convert_link(link_data: LinkData) -> core_pb2.Link:
|
|||
type=link_data.link_type.value,
|
||||
node1_id=link_data.node1_id,
|
||||
node2_id=link_data.node2_id,
|
||||
interface1=interface1,
|
||||
interface2=interface2,
|
||||
iface1=iface1,
|
||||
iface2=iface2,
|
||||
options=options,
|
||||
network_id=link_data.network_id,
|
||||
label=link_data.label,
|
||||
|
@ -440,20 +440,20 @@ def get_service_configuration(service: CoreService) -> NodeServiceData:
|
|||
)
|
||||
|
||||
|
||||
def interface_to_proto(interface: CoreInterface) -> core_pb2.Interface:
|
||||
def iface_to_proto(iface: CoreInterface) -> core_pb2.Interface:
|
||||
"""
|
||||
Convenience for converting a core interface to the protobuf representation.
|
||||
:param interface: interface to convert
|
||||
:param iface: interface to convert
|
||||
:return: interface proto
|
||||
"""
|
||||
net_id = None
|
||||
if interface.net:
|
||||
net_id = interface.net.id
|
||||
if iface.net:
|
||||
net_id = iface.net.id
|
||||
ip4 = None
|
||||
ip4mask = None
|
||||
ip6 = None
|
||||
ip6mask = None
|
||||
for addr in interface.addrlist:
|
||||
for addr in iface.addrlist:
|
||||
network = netaddr.IPNetwork(addr)
|
||||
mask = network.prefixlen
|
||||
ip = str(network.ip)
|
||||
|
@ -464,12 +464,12 @@ def interface_to_proto(interface: CoreInterface) -> core_pb2.Interface:
|
|||
ip6 = ip
|
||||
ip6mask = mask
|
||||
return core_pb2.Interface(
|
||||
id=interface.netindex,
|
||||
id=iface.node_id,
|
||||
netid=net_id,
|
||||
name=interface.name,
|
||||
mac=str(interface.hwaddr),
|
||||
mtu=interface.mtu,
|
||||
flowid=interface.flow_id,
|
||||
name=iface.name,
|
||||
mac=str(iface.hwaddr),
|
||||
mtu=iface.mtu,
|
||||
flowid=iface.flow_id,
|
||||
ip4=ip4,
|
||||
ip4mask=ip4mask,
|
||||
ip6=ip6,
|
||||
|
@ -477,21 +477,21 @@ def interface_to_proto(interface: CoreInterface) -> core_pb2.Interface:
|
|||
)
|
||||
|
||||
|
||||
def get_nem_id(node: CoreNode, netif_id: int, context: ServicerContext) -> int:
|
||||
def get_nem_id(node: CoreNode, iface_id: int, context: ServicerContext) -> int:
|
||||
"""
|
||||
Get nem id for a given node and interface id.
|
||||
|
||||
:param node: node to get nem id for
|
||||
:param netif_id: id of interface on node to get nem id for
|
||||
:param iface_id: id of interface on node to get nem id for
|
||||
:param context: request context
|
||||
:return: nem id
|
||||
"""
|
||||
netif = node.netif(netif_id)
|
||||
if not netif:
|
||||
message = f"{node.name} missing interface {netif_id}"
|
||||
iface = node.ifaces.get(iface_id)
|
||||
if not iface:
|
||||
message = f"{node.name} missing interface {iface_id}"
|
||||
context.abort(grpc.StatusCode.NOT_FOUND, message)
|
||||
net = netif.net
|
||||
net = iface.net
|
||||
if not isinstance(net, EmaneNet):
|
||||
message = f"{node.name} interface {netif_id} is not an EMANE network"
|
||||
message = f"{node.name} interface {iface_id} is not an EMANE network"
|
||||
context.abort(grpc.StatusCode.INVALID_ARGUMENT, message)
|
||||
return net.getnemid(netif)
|
||||
return net.getnemid(iface)
|
||||
|
|
|
@ -246,7 +246,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
config = session.emane.get_configs()
|
||||
config.update(request.emane_config)
|
||||
for config in request.emane_model_configs:
|
||||
_id = get_emane_model_id(config.node_id, config.interface_id)
|
||||
_id = get_emane_model_id(config.node_id, config.iface_id)
|
||||
session.emane.set_model_config(_id, config.model, config.config)
|
||||
|
||||
# wlan configs
|
||||
|
@ -625,16 +625,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
key = key.split(".")
|
||||
node_id = _INTERFACE_REGEX.search(key[0]).group("node")
|
||||
node_id = int(node_id, base=16)
|
||||
interface_id = int(key[1], base=16)
|
||||
iface_id = int(key[1], base=16)
|
||||
session_id = int(key[2], base=16)
|
||||
if session.id != session_id:
|
||||
continue
|
||||
interface_throughput = (
|
||||
throughputs_event.interface_throughputs.add()
|
||||
)
|
||||
interface_throughput.node_id = node_id
|
||||
interface_throughput.interface_id = interface_id
|
||||
interface_throughput.throughput = throughput
|
||||
iface_throughput = throughputs_event.iface_throughputs.add()
|
||||
iface_throughput.node_id = node_id
|
||||
iface_throughput.iface_id = iface_id
|
||||
iface_throughput.throughput = throughput
|
||||
elif key.startswith("b."):
|
||||
try:
|
||||
key = key.split(".")
|
||||
|
@ -686,13 +684,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
logging.debug("get node: %s", request)
|
||||
session = self.get_session(request.session_id, context)
|
||||
node = self.get_node(session, request.node_id, context, NodeBase)
|
||||
interfaces = []
|
||||
for interface_id in node._netif:
|
||||
interface = node._netif[interface_id]
|
||||
interface_proto = grpcutils.interface_to_proto(interface)
|
||||
interfaces.append(interface_proto)
|
||||
ifaces = []
|
||||
for iface_id in node.ifaces:
|
||||
iface = node.ifaces[iface_id]
|
||||
iface_proto = grpcutils.iface_to_proto(iface)
|
||||
ifaces.append(iface_proto)
|
||||
node_proto = grpcutils.get_node_proto(session, node)
|
||||
return core_pb2.GetNodeResponse(node=node_proto, interfaces=interfaces)
|
||||
return core_pb2.GetNodeResponse(node=node_proto, ifaces=ifaces)
|
||||
|
||||
def MoveNodes(
|
||||
self,
|
||||
|
@ -850,18 +848,18 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
node2_id = request.link.node2_id
|
||||
self.get_node(session, node1_id, context, NodeBase)
|
||||
self.get_node(session, node2_id, context, NodeBase)
|
||||
interface1, interface2, options = grpcutils.add_link_data(request.link)
|
||||
node1_interface, node2_interface = session.add_link(
|
||||
node1_id, node2_id, interface1, interface2, options=options
|
||||
iface1_data, iface2_data, options = grpcutils.add_link_data(request.link)
|
||||
node1_iface, node2_iface = session.add_link(
|
||||
node1_id, node2_id, iface1_data, iface2_data, options=options
|
||||
)
|
||||
interface1_proto = None
|
||||
interface2_proto = None
|
||||
if node1_interface:
|
||||
interface1_proto = grpcutils.interface_to_proto(node1_interface)
|
||||
if node2_interface:
|
||||
interface2_proto = grpcutils.interface_to_proto(node2_interface)
|
||||
iface1_proto = None
|
||||
iface2_proto = None
|
||||
if node1_iface:
|
||||
iface1_proto = grpcutils.iface_to_proto(node1_iface)
|
||||
if node2_iface:
|
||||
iface2_proto = grpcutils.iface_to_proto(node2_iface)
|
||||
return core_pb2.AddLinkResponse(
|
||||
result=True, interface1=interface1_proto, interface2=interface2_proto
|
||||
result=True, iface1=iface1_proto, iface2=iface2_proto
|
||||
)
|
||||
|
||||
def EditLink(
|
||||
|
@ -878,8 +876,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
session = self.get_session(request.session_id, context)
|
||||
node1_id = request.node1_id
|
||||
node2_id = request.node2_id
|
||||
interface1_id = request.interface1_id
|
||||
interface2_id = request.interface2_id
|
||||
iface1_id = request.iface1_id
|
||||
iface2_id = request.iface2_id
|
||||
options_data = request.options
|
||||
options = LinkOptions(
|
||||
delay=options_data.delay,
|
||||
|
@ -894,7 +892,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
key=options_data.key,
|
||||
opaque=options_data.opaque,
|
||||
)
|
||||
session.update_link(node1_id, node2_id, interface1_id, interface2_id, options)
|
||||
session.update_link(node1_id, node2_id, iface1_id, iface2_id, options)
|
||||
return core_pb2.EditLinkResponse(result=True)
|
||||
|
||||
def DeleteLink(
|
||||
|
@ -911,9 +909,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
session = self.get_session(request.session_id, context)
|
||||
node1_id = request.node1_id
|
||||
node2_id = request.node2_id
|
||||
interface1_id = request.interface1_id
|
||||
interface2_id = request.interface2_id
|
||||
session.delete_link(node1_id, node2_id, interface1_id, interface2_id)
|
||||
iface1_id = request.iface1_id
|
||||
iface2_id = request.iface2_id
|
||||
session.delete_link(node1_id, node2_id, iface1_id, iface2_id)
|
||||
return core_pb2.DeleteLinkResponse(result=True)
|
||||
|
||||
def GetHooks(
|
||||
|
@ -1371,7 +1369,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
logging.debug("get emane model config: %s", request)
|
||||
session = self.get_session(request.session_id, context)
|
||||
model = session.emane.models[request.model]
|
||||
_id = get_emane_model_id(request.node_id, request.interface)
|
||||
_id = get_emane_model_id(request.node_id, request.iface_id)
|
||||
current_config = session.emane.get_model_config(_id, request.model)
|
||||
config = get_config_options(current_config, model)
|
||||
return GetEmaneModelConfigResponse(config=config)
|
||||
|
@ -1390,7 +1388,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
logging.debug("set emane model config: %s", request)
|
||||
session = self.get_session(request.session_id, context)
|
||||
model_config = request.emane_model_config
|
||||
_id = get_emane_model_id(model_config.node_id, model_config.interface_id)
|
||||
_id = get_emane_model_id(model_config.node_id, model_config.iface_id)
|
||||
session.emane.set_model_config(_id, model_config.model, model_config.config)
|
||||
return SetEmaneModelConfigResponse(result=True)
|
||||
|
||||
|
@ -1419,12 +1417,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
model = session.emane.models[model_name]
|
||||
current_config = session.emane.get_model_config(_id, model_name)
|
||||
config = get_config_options(current_config, model)
|
||||
node_id, interface = grpcutils.parse_emane_model_id(_id)
|
||||
node_id, iface_id = grpcutils.parse_emane_model_id(_id)
|
||||
model_config = GetEmaneModelConfigsResponse.ModelConfig(
|
||||
node_id=node_id,
|
||||
model=model_name,
|
||||
interface=interface,
|
||||
config=config,
|
||||
node_id=node_id, model=model_name, iface_id=iface_id, config=config
|
||||
)
|
||||
configs.append(model_config)
|
||||
return GetEmaneModelConfigsResponse(configs=configs)
|
||||
|
@ -1489,16 +1484,12 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
:param context: context object
|
||||
:return: get-interfaces response that has all the system's interfaces
|
||||
"""
|
||||
interfaces = []
|
||||
for interface in os.listdir("/sys/class/net"):
|
||||
if (
|
||||
interface.startswith("b.")
|
||||
or interface.startswith("veth")
|
||||
or interface == "lo"
|
||||
):
|
||||
ifaces = []
|
||||
for iface in os.listdir("/sys/class/net"):
|
||||
if iface.startswith("b.") or iface.startswith("veth") or iface == "lo":
|
||||
continue
|
||||
interfaces.append(interface)
|
||||
return core_pb2.GetInterfacesResponse(interfaces=interfaces)
|
||||
ifaces.append(iface)
|
||||
return core_pb2.GetInterfacesResponse(ifaces=ifaces)
|
||||
|
||||
def EmaneLink(
|
||||
self, request: EmaneLinkRequest, context: ServicerContext
|
||||
|
@ -1513,16 +1504,16 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
logging.debug("emane link: %s", request)
|
||||
session = self.get_session(request.session_id, context)
|
||||
nem1 = request.nem1
|
||||
emane1, netif = session.emane.nemlookup(nem1)
|
||||
if not emane1 or not netif:
|
||||
emane1, iface = session.emane.nemlookup(nem1)
|
||||
if not emane1 or not iface:
|
||||
context.abort(grpc.StatusCode.NOT_FOUND, f"nem one {nem1} not found")
|
||||
node1 = netif.node
|
||||
node1 = iface.node
|
||||
|
||||
nem2 = request.nem2
|
||||
emane2, netif = session.emane.nemlookup(nem2)
|
||||
if not emane2 or not netif:
|
||||
emane2, iface = session.emane.nemlookup(nem2)
|
||||
if not emane2 or not iface:
|
||||
context.abort(grpc.StatusCode.NOT_FOUND, f"nem two {nem2} not found")
|
||||
node2 = netif.node
|
||||
node2 = iface.node
|
||||
|
||||
if emane1.id == emane2.id:
|
||||
if request.linked:
|
||||
|
@ -1734,21 +1725,19 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
)
|
||||
node1 = self.get_node(session, request.node1_id, context, CoreNode)
|
||||
node2 = self.get_node(session, request.node2_id, context, CoreNode)
|
||||
node1_interface, node2_interface = None, None
|
||||
for net, interface1, interface2 in node1.commonnets(node2):
|
||||
node1_iface, node2_iface = None, None
|
||||
for net, iface1, iface2 in node1.commonnets(node2):
|
||||
if net == wlan:
|
||||
node1_interface = interface1
|
||||
node2_interface = interface2
|
||||
node1_iface = iface1
|
||||
node2_iface = iface2
|
||||
break
|
||||
result = False
|
||||
if node1_interface and node2_interface:
|
||||
if node1_iface and node2_iface:
|
||||
if request.linked:
|
||||
wlan.link(node1_interface, node2_interface)
|
||||
wlan.link(node1_iface, node2_iface)
|
||||
else:
|
||||
wlan.unlink(node1_interface, node2_interface)
|
||||
wlan.model.sendlinkmsg(
|
||||
node1_interface, node2_interface, unlink=not request.linked
|
||||
)
|
||||
wlan.unlink(node1_iface, node2_iface)
|
||||
wlan.model.sendlinkmsg(node1_iface, node2_iface, unlink=not request.linked)
|
||||
result = True
|
||||
return WlanLinkResponse(result=result)
|
||||
|
||||
|
@ -1760,8 +1749,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
for request in request_iterator:
|
||||
session = self.get_session(request.session_id, context)
|
||||
node1 = self.get_node(session, request.node1_id, context, CoreNode)
|
||||
nem1 = grpcutils.get_nem_id(node1, request.interface1_id, context)
|
||||
nem1 = grpcutils.get_nem_id(node1, request.iface1_id, context)
|
||||
node2 = self.get_node(session, request.node2_id, context, CoreNode)
|
||||
nem2 = grpcutils.get_nem_id(node2, request.interface2_id, context)
|
||||
nem2 = grpcutils.get_nem_id(node2, request.iface2_id, context)
|
||||
session.emane.publish_pathloss(nem1, nem2, request.rx1, request.rx2)
|
||||
return EmanePathlossesResponse()
|
||||
|
|
|
@ -508,18 +508,18 @@ class CoreLinkTlv(CoreTlv):
|
|||
LinkTlvs.EMULATION_ID.value: CoreTlvDataUint32,
|
||||
LinkTlvs.NETWORK_ID.value: CoreTlvDataUint32,
|
||||
LinkTlvs.KEY.value: CoreTlvDataUint32,
|
||||
LinkTlvs.INTERFACE1_NUMBER.value: CoreTlvDataUint16,
|
||||
LinkTlvs.INTERFACE1_IP4.value: CoreTlvDataIpv4Addr,
|
||||
LinkTlvs.INTERFACE1_IP4_MASK.value: CoreTlvDataUint16,
|
||||
LinkTlvs.INTERFACE1_MAC.value: CoreTlvDataMacAddr,
|
||||
LinkTlvs.INTERFACE1_IP6.value: CoreTlvDataIPv6Addr,
|
||||
LinkTlvs.INTERFACE1_IP6_MASK.value: CoreTlvDataUint16,
|
||||
LinkTlvs.INTERFACE2_NUMBER.value: CoreTlvDataUint16,
|
||||
LinkTlvs.INTERFACE2_IP4.value: CoreTlvDataIpv4Addr,
|
||||
LinkTlvs.INTERFACE2_IP4_MASK.value: CoreTlvDataUint16,
|
||||
LinkTlvs.INTERFACE2_MAC.value: CoreTlvDataMacAddr,
|
||||
LinkTlvs.INTERFACE2_IP6.value: CoreTlvDataIPv6Addr,
|
||||
LinkTlvs.INTERFACE2_IP6_MASK.value: CoreTlvDataUint16,
|
||||
LinkTlvs.IFACE1_NUMBER.value: CoreTlvDataUint16,
|
||||
LinkTlvs.IFACE1_IP4.value: CoreTlvDataIpv4Addr,
|
||||
LinkTlvs.IFACE1_IP4_MASK.value: CoreTlvDataUint16,
|
||||
LinkTlvs.IFACE1_MAC.value: CoreTlvDataMacAddr,
|
||||
LinkTlvs.IFACE1_IP6.value: CoreTlvDataIPv6Addr,
|
||||
LinkTlvs.IFACE1_IP6_MASK.value: CoreTlvDataUint16,
|
||||
LinkTlvs.IFACE2_NUMBER.value: CoreTlvDataUint16,
|
||||
LinkTlvs.IFACE2_IP4.value: CoreTlvDataIpv4Addr,
|
||||
LinkTlvs.IFACE2_IP4_MASK.value: CoreTlvDataUint16,
|
||||
LinkTlvs.IFACE2_MAC.value: CoreTlvDataMacAddr,
|
||||
LinkTlvs.IFACE2_IP6.value: CoreTlvDataIPv6Addr,
|
||||
LinkTlvs.IFACE2_IP6_MASK.value: CoreTlvDataUint16,
|
||||
LinkTlvs.INTERFACE1_NAME.value: CoreTlvDataString,
|
||||
LinkTlvs.INTERFACE2_NAME.value: CoreTlvDataString,
|
||||
LinkTlvs.OPAQUE.value: CoreTlvDataString,
|
||||
|
@ -577,7 +577,7 @@ class CoreConfigTlv(CoreTlv):
|
|||
ConfigTlvs.POSSIBLE_VALUES.value: CoreTlvDataString,
|
||||
ConfigTlvs.GROUPS.value: CoreTlvDataString,
|
||||
ConfigTlvs.SESSION.value: CoreTlvDataString,
|
||||
ConfigTlvs.INTERFACE_NUMBER.value: CoreTlvDataUint16,
|
||||
ConfigTlvs.IFACE_ID.value: CoreTlvDataUint16,
|
||||
ConfigTlvs.NETWORK_ID.value: CoreTlvDataUint32,
|
||||
ConfigTlvs.OPAQUE.value: CoreTlvDataString,
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
MessageTypes.REGISTER.value: self.handle_register_message,
|
||||
MessageTypes.CONFIG.value: self.handle_config_message,
|
||||
MessageTypes.FILE.value: self.handle_file_message,
|
||||
MessageTypes.INTERFACE.value: self.handle_interface_message,
|
||||
MessageTypes.INTERFACE.value: self.handle_iface_message,
|
||||
MessageTypes.EVENT.value: self.handle_event_message,
|
||||
MessageTypes.SESSION.value: self.handle_session_message,
|
||||
}
|
||||
|
@ -363,18 +363,18 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
(LinkTlvs.EMULATION_ID, link_data.emulation_id),
|
||||
(LinkTlvs.NETWORK_ID, link_data.network_id),
|
||||
(LinkTlvs.KEY, link_data.key),
|
||||
(LinkTlvs.INTERFACE1_NUMBER, link_data.interface1_id),
|
||||
(LinkTlvs.INTERFACE1_IP4, link_data.interface1_ip4),
|
||||
(LinkTlvs.INTERFACE1_IP4_MASK, link_data.interface1_ip4_mask),
|
||||
(LinkTlvs.INTERFACE1_MAC, link_data.interface1_mac),
|
||||
(LinkTlvs.INTERFACE1_IP6, link_data.interface1_ip6),
|
||||
(LinkTlvs.INTERFACE1_IP6_MASK, link_data.interface1_ip6_mask),
|
||||
(LinkTlvs.INTERFACE2_NUMBER, link_data.interface2_id),
|
||||
(LinkTlvs.INTERFACE2_IP4, link_data.interface2_ip4),
|
||||
(LinkTlvs.INTERFACE2_IP4_MASK, link_data.interface2_ip4_mask),
|
||||
(LinkTlvs.INTERFACE2_MAC, link_data.interface2_mac),
|
||||
(LinkTlvs.INTERFACE2_IP6, link_data.interface2_ip6),
|
||||
(LinkTlvs.INTERFACE2_IP6_MASK, link_data.interface2_ip6_mask),
|
||||
(LinkTlvs.IFACE1_NUMBER, link_data.iface1_id),
|
||||
(LinkTlvs.IFACE1_IP4, link_data.iface1_ip4),
|
||||
(LinkTlvs.IFACE1_IP4_MASK, link_data.iface1_ip4_mask),
|
||||
(LinkTlvs.IFACE1_MAC, link_data.iface1_mac),
|
||||
(LinkTlvs.IFACE1_IP6, link_data.iface1_ip6),
|
||||
(LinkTlvs.IFACE1_IP6_MASK, link_data.iface1_ip6_mask),
|
||||
(LinkTlvs.IFACE2_NUMBER, link_data.iface2_id),
|
||||
(LinkTlvs.IFACE2_IP4, link_data.iface2_ip4),
|
||||
(LinkTlvs.IFACE2_IP4_MASK, link_data.iface2_ip4_mask),
|
||||
(LinkTlvs.IFACE2_MAC, link_data.iface2_mac),
|
||||
(LinkTlvs.IFACE2_IP6, link_data.iface2_ip6),
|
||||
(LinkTlvs.IFACE2_IP6_MASK, link_data.iface2_ip6_mask),
|
||||
(LinkTlvs.OPAQUE, link_data.opaque),
|
||||
],
|
||||
)
|
||||
|
@ -749,23 +749,23 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
"""
|
||||
node1_id = message.get_tlv(LinkTlvs.N1_NUMBER.value)
|
||||
node2_id = message.get_tlv(LinkTlvs.N2_NUMBER.value)
|
||||
interface1_data = InterfaceData(
|
||||
id=message.get_tlv(LinkTlvs.INTERFACE1_NUMBER.value),
|
||||
iface1_data = InterfaceData(
|
||||
id=message.get_tlv(LinkTlvs.IFACE1_NUMBER.value),
|
||||
name=message.get_tlv(LinkTlvs.INTERFACE1_NAME.value),
|
||||
mac=message.get_tlv(LinkTlvs.INTERFACE1_MAC.value),
|
||||
ip4=message.get_tlv(LinkTlvs.INTERFACE1_IP4.value),
|
||||
ip4_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP4_MASK.value),
|
||||
ip6=message.get_tlv(LinkTlvs.INTERFACE1_IP6.value),
|
||||
ip6_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP6_MASK.value),
|
||||
mac=message.get_tlv(LinkTlvs.IFACE1_MAC.value),
|
||||
ip4=message.get_tlv(LinkTlvs.IFACE1_IP4.value),
|
||||
ip4_mask=message.get_tlv(LinkTlvs.IFACE1_IP4_MASK.value),
|
||||
ip6=message.get_tlv(LinkTlvs.IFACE1_IP6.value),
|
||||
ip6_mask=message.get_tlv(LinkTlvs.IFACE1_IP6_MASK.value),
|
||||
)
|
||||
interface2_data = InterfaceData(
|
||||
id=message.get_tlv(LinkTlvs.INTERFACE2_NUMBER.value),
|
||||
iface2_data = InterfaceData(
|
||||
id=message.get_tlv(LinkTlvs.IFACE2_NUMBER.value),
|
||||
name=message.get_tlv(LinkTlvs.INTERFACE2_NAME.value),
|
||||
mac=message.get_tlv(LinkTlvs.INTERFACE2_MAC.value),
|
||||
ip4=message.get_tlv(LinkTlvs.INTERFACE2_IP4.value),
|
||||
ip4_mask=message.get_tlv(LinkTlvs.INTERFACE2_IP4_MASK.value),
|
||||
ip6=message.get_tlv(LinkTlvs.INTERFACE2_IP6.value),
|
||||
ip6_mask=message.get_tlv(LinkTlvs.INTERFACE2_IP6_MASK.value),
|
||||
mac=message.get_tlv(LinkTlvs.IFACE2_MAC.value),
|
||||
ip4=message.get_tlv(LinkTlvs.IFACE2_IP4.value),
|
||||
ip4_mask=message.get_tlv(LinkTlvs.IFACE2_IP4_MASK.value),
|
||||
ip6=message.get_tlv(LinkTlvs.IFACE2_IP6.value),
|
||||
ip6_mask=message.get_tlv(LinkTlvs.IFACE2_IP6_MASK.value),
|
||||
)
|
||||
link_type = LinkTypes.WIRED
|
||||
link_type_value = message.get_tlv(LinkTlvs.TYPE.value)
|
||||
|
@ -789,16 +789,12 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
options.opaque = message.get_tlv(LinkTlvs.OPAQUE.value)
|
||||
|
||||
if message.flags & MessageFlags.ADD.value:
|
||||
self.session.add_link(
|
||||
node1_id, node2_id, interface1_data, interface2_data, options
|
||||
)
|
||||
self.session.add_link(node1_id, node2_id, iface1_data, iface2_data, options)
|
||||
elif message.flags & MessageFlags.DELETE.value:
|
||||
self.session.delete_link(
|
||||
node1_id, node2_id, interface1_data.id, interface2_data.id
|
||||
)
|
||||
self.session.delete_link(node1_id, node2_id, iface1_data.id, iface2_data.id)
|
||||
else:
|
||||
self.session.update_link(
|
||||
node1_id, node2_id, interface1_data.id, interface2_data.id, options
|
||||
node1_id, node2_id, iface1_data.id, iface2_data.id, options
|
||||
)
|
||||
return ()
|
||||
|
||||
|
@ -1008,7 +1004,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
possible_values=message.get_tlv(ConfigTlvs.POSSIBLE_VALUES.value),
|
||||
groups=message.get_tlv(ConfigTlvs.GROUPS.value),
|
||||
session=message.get_tlv(ConfigTlvs.SESSION.value),
|
||||
interface_number=message.get_tlv(ConfigTlvs.INTERFACE_NUMBER.value),
|
||||
iface_id=message.get_tlv(ConfigTlvs.IFACE_ID.value),
|
||||
network_id=message.get_tlv(ConfigTlvs.NETWORK_ID.value),
|
||||
opaque=message.get_tlv(ConfigTlvs.OPAQUE.value),
|
||||
)
|
||||
|
@ -1325,11 +1321,11 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
replies = []
|
||||
node_id = config_data.node
|
||||
object_name = config_data.object
|
||||
interface_id = config_data.interface_number
|
||||
iface_id = config_data.iface_id
|
||||
values_str = config_data.data_values
|
||||
|
||||
if interface_id is not None:
|
||||
node_id = node_id * 1000 + interface_id
|
||||
if iface_id is not None:
|
||||
node_id = node_id * 1000 + iface_id
|
||||
|
||||
logging.debug(
|
||||
"received configure message for %s nodenum: %s", object_name, node_id
|
||||
|
@ -1375,11 +1371,11 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
replies = []
|
||||
node_id = config_data.node
|
||||
object_name = config_data.object
|
||||
interface_id = config_data.interface_number
|
||||
iface_id = config_data.iface_id
|
||||
values_str = config_data.data_values
|
||||
|
||||
if interface_id is not None:
|
||||
node_id = node_id * 1000 + interface_id
|
||||
if iface_id is not None:
|
||||
node_id = node_id * 1000 + iface_id
|
||||
|
||||
logging.debug(
|
||||
"received configure message for %s nodenum: %s", object_name, node_id
|
||||
|
@ -1407,11 +1403,11 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
replies = []
|
||||
node_id = config_data.node
|
||||
object_name = config_data.object
|
||||
interface_id = config_data.interface_number
|
||||
iface_id = config_data.iface_id
|
||||
values_str = config_data.data_values
|
||||
|
||||
if interface_id is not None:
|
||||
node_id = node_id * 1000 + interface_id
|
||||
if iface_id is not None:
|
||||
node_id = node_id * 1000 + iface_id
|
||||
|
||||
logging.debug(
|
||||
"received configure message for %s nodenum: %s", object_name, node_id
|
||||
|
@ -1505,7 +1501,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
|
||||
return ()
|
||||
|
||||
def handle_interface_message(self, message):
|
||||
def handle_iface_message(self, message):
|
||||
"""
|
||||
Interface Message handler.
|
||||
|
||||
|
@ -1950,7 +1946,7 @@ class CoreUdpHandler(CoreHandler):
|
|||
MessageTypes.REGISTER.value: self.handle_register_message,
|
||||
MessageTypes.CONFIG.value: self.handle_config_message,
|
||||
MessageTypes.FILE.value: self.handle_file_message,
|
||||
MessageTypes.INTERFACE.value: self.handle_interface_message,
|
||||
MessageTypes.INTERFACE.value: self.handle_iface_message,
|
||||
MessageTypes.EVENT.value: self.handle_event_message,
|
||||
MessageTypes.SESSION.value: self.handle_session_message,
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ def convert_config(config_data):
|
|||
(ConfigTlvs.POSSIBLE_VALUES, config_data.possible_values),
|
||||
(ConfigTlvs.GROUPS, config_data.groups),
|
||||
(ConfigTlvs.SESSION, session),
|
||||
(ConfigTlvs.INTERFACE_NUMBER, config_data.interface_number),
|
||||
(ConfigTlvs.IFACE_ID, config_data.iface_id),
|
||||
(ConfigTlvs.NETWORK_ID, config_data.network_id),
|
||||
(ConfigTlvs.OPAQUE, config_data.opaque),
|
||||
],
|
||||
|
|
|
@ -72,18 +72,18 @@ class LinkTlvs(Enum):
|
|||
EMULATION_ID = 0x23
|
||||
NETWORK_ID = 0x24
|
||||
KEY = 0x25
|
||||
INTERFACE1_NUMBER = 0x30
|
||||
INTERFACE1_IP4 = 0x31
|
||||
INTERFACE1_IP4_MASK = 0x32
|
||||
INTERFACE1_MAC = 0x33
|
||||
INTERFACE1_IP6 = 0x34
|
||||
INTERFACE1_IP6_MASK = 0x35
|
||||
INTERFACE2_NUMBER = 0x36
|
||||
INTERFACE2_IP4 = 0x37
|
||||
INTERFACE2_IP4_MASK = 0x38
|
||||
INTERFACE2_MAC = 0x39
|
||||
INTERFACE2_IP6 = 0x40
|
||||
INTERFACE2_IP6_MASK = 0x41
|
||||
IFACE1_NUMBER = 0x30
|
||||
IFACE1_IP4 = 0x31
|
||||
IFACE1_IP4_MASK = 0x32
|
||||
IFACE1_MAC = 0x33
|
||||
IFACE1_IP6 = 0x34
|
||||
IFACE1_IP6_MASK = 0x35
|
||||
IFACE2_NUMBER = 0x36
|
||||
IFACE2_IP4 = 0x37
|
||||
IFACE2_IP4_MASK = 0x38
|
||||
IFACE2_MAC = 0x39
|
||||
IFACE2_IP6 = 0x40
|
||||
IFACE2_IP6_MASK = 0x41
|
||||
INTERFACE1_NAME = 0x42
|
||||
INTERFACE2_NAME = 0x43
|
||||
OPAQUE = 0x50
|
||||
|
@ -118,7 +118,7 @@ class ConfigTlvs(Enum):
|
|||
POSSIBLE_VALUES = 0x08
|
||||
GROUPS = 0x09
|
||||
SESSION = 0x0A
|
||||
INTERFACE_NUMBER = 0x0B
|
||||
IFACE_ID = 0x0B
|
||||
NETWORK_ID = 0x24
|
||||
OPAQUE = 0x50
|
||||
|
||||
|
|
|
@ -13,33 +13,33 @@ from core.nodes.network import WlanNode
|
|||
GROUP = "FRR"
|
||||
|
||||
|
||||
def has_mtu_mismatch(ifc: CoreInterface) -> bool:
|
||||
def has_mtu_mismatch(iface: CoreInterface) -> bool:
|
||||
"""
|
||||
Helper to detect MTU mismatch and add the appropriate FRR
|
||||
mtu-ignore command. This is needed when e.g. a node is linked via a
|
||||
GreTap device.
|
||||
"""
|
||||
if ifc.mtu != 1500:
|
||||
if iface.mtu != 1500:
|
||||
return True
|
||||
if not ifc.net:
|
||||
if not iface.net:
|
||||
return False
|
||||
for i in ifc.net.netifs():
|
||||
if i.mtu != ifc.mtu:
|
||||
for iface in iface.net.get_ifaces():
|
||||
if iface.mtu != iface.mtu:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_min_mtu(ifc):
|
||||
def get_min_mtu(iface):
|
||||
"""
|
||||
Helper to discover the minimum MTU of interfaces linked with the
|
||||
given interface.
|
||||
"""
|
||||
mtu = ifc.mtu
|
||||
if not ifc.net:
|
||||
mtu = iface.mtu
|
||||
if not iface.net:
|
||||
return mtu
|
||||
for i in ifc.net.netifs():
|
||||
if i.mtu < mtu:
|
||||
mtu = i.mtu
|
||||
for iface in iface.net.get_ifaces():
|
||||
if iface.mtu < mtu:
|
||||
mtu = iface.mtu
|
||||
return mtu
|
||||
|
||||
|
||||
|
@ -47,10 +47,8 @@ def get_router_id(node: CoreNodeBase) -> str:
|
|||
"""
|
||||
Helper to return the first IPv4 address of a node as its router ID.
|
||||
"""
|
||||
for ifc in node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
for a in iface.addrlist:
|
||||
a = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(a):
|
||||
return a
|
||||
|
@ -97,25 +95,25 @@ class FRRZebra(ConfigService):
|
|||
want_ip6 = True
|
||||
services.append(service)
|
||||
|
||||
interfaces = []
|
||||
for ifc in self.node.netifs():
|
||||
ifaces = []
|
||||
for iface in self.node.get_ifaces():
|
||||
ip4s = []
|
||||
ip6s = []
|
||||
for x in ifc.addrlist:
|
||||
for x in iface.addrlist:
|
||||
addr = x.split("/")[0]
|
||||
if netaddr.valid_ipv4(addr):
|
||||
ip4s.append(x)
|
||||
else:
|
||||
ip6s.append(x)
|
||||
is_control = getattr(ifc, "control", False)
|
||||
interfaces.append((ifc, ip4s, ip6s, is_control))
|
||||
is_control = getattr(iface, "control", False)
|
||||
ifaces.append((iface, ip4s, ip6s, is_control))
|
||||
|
||||
return dict(
|
||||
frr_conf=frr_conf,
|
||||
frr_sbin_search=frr_sbin_search,
|
||||
frr_bin_search=frr_bin_search,
|
||||
frr_state_dir=constants.FRR_STATE_DIR,
|
||||
interfaces=interfaces,
|
||||
ifaces=ifaces,
|
||||
want_ip4=want_ip4,
|
||||
want_ip6=want_ip6,
|
||||
services=services,
|
||||
|
@ -138,7 +136,7 @@ class FrrService(abc.ABC):
|
|||
ipv6_routing = False
|
||||
|
||||
@abc.abstractmethod
|
||||
def frr_interface_config(self, ifc: CoreInterface) -> str:
|
||||
def frr_iface_config(self, iface: CoreInterface) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
|
@ -162,10 +160,8 @@ class FRROspfv2(FrrService, ConfigService):
|
|||
def frr_config(self) -> str:
|
||||
router_id = get_router_id(self.node)
|
||||
addresses = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
for a in iface.addrlist:
|
||||
addr = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(addr):
|
||||
addresses.append(a)
|
||||
|
@ -180,8 +176,8 @@ class FRROspfv2(FrrService, ConfigService):
|
|||
"""
|
||||
return self.render_text(text, data)
|
||||
|
||||
def frr_interface_config(self, ifc: CoreInterface) -> str:
|
||||
if has_mtu_mismatch(ifc):
|
||||
def frr_iface_config(self, iface: CoreInterface) -> str:
|
||||
if has_mtu_mismatch(iface):
|
||||
return "ip ospf mtu-ignore"
|
||||
else:
|
||||
return ""
|
||||
|
@ -203,10 +199,8 @@ class FRROspfv3(FrrService, ConfigService):
|
|||
def frr_config(self) -> str:
|
||||
router_id = get_router_id(self.node)
|
||||
ifnames = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifnames.append(ifc.name)
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifnames.append(iface.name)
|
||||
data = dict(router_id=router_id, ifnames=ifnames)
|
||||
text = """
|
||||
router ospf6
|
||||
|
@ -218,9 +212,9 @@ class FRROspfv3(FrrService, ConfigService):
|
|||
"""
|
||||
return self.render_text(text, data)
|
||||
|
||||
def frr_interface_config(self, ifc: CoreInterface) -> str:
|
||||
mtu = get_min_mtu(ifc)
|
||||
if mtu < ifc.mtu:
|
||||
def frr_iface_config(self, iface: CoreInterface) -> str:
|
||||
mtu = get_min_mtu(iface)
|
||||
if mtu < iface.mtu:
|
||||
return f"ipv6 ospf6 ifmtu {mtu}"
|
||||
else:
|
||||
return ""
|
||||
|
@ -254,7 +248,7 @@ class FRRBgp(FrrService, ConfigService):
|
|||
"""
|
||||
return self.clean_text(text)
|
||||
|
||||
def frr_interface_config(self, ifc: CoreInterface) -> str:
|
||||
def frr_iface_config(self, iface: CoreInterface) -> str:
|
||||
return ""
|
||||
|
||||
|
||||
|
@ -279,7 +273,7 @@ class FRRRip(FrrService, ConfigService):
|
|||
"""
|
||||
return self.clean_text(text)
|
||||
|
||||
def frr_interface_config(self, ifc: CoreInterface) -> str:
|
||||
def frr_iface_config(self, iface: CoreInterface) -> str:
|
||||
return ""
|
||||
|
||||
|
||||
|
@ -304,7 +298,7 @@ class FRRRipng(FrrService, ConfigService):
|
|||
"""
|
||||
return self.clean_text(text)
|
||||
|
||||
def frr_interface_config(self, ifc: CoreInterface) -> str:
|
||||
def frr_iface_config(self, iface: CoreInterface) -> str:
|
||||
return ""
|
||||
|
||||
|
||||
|
@ -321,10 +315,8 @@ class FRRBabel(FrrService, ConfigService):
|
|||
|
||||
def frr_config(self) -> str:
|
||||
ifnames = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifnames.append(ifc.name)
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifnames.append(iface.name)
|
||||
text = """
|
||||
router babel
|
||||
% for ifname in ifnames:
|
||||
|
@ -337,8 +329,8 @@ class FRRBabel(FrrService, ConfigService):
|
|||
data = dict(ifnames=ifnames)
|
||||
return self.render_text(text, data)
|
||||
|
||||
def frr_interface_config(self, ifc: CoreInterface) -> str:
|
||||
if isinstance(ifc.net, (WlanNode, EmaneNet)):
|
||||
def frr_iface_config(self, iface: CoreInterface) -> str:
|
||||
if isinstance(iface.net, (WlanNode, EmaneNet)):
|
||||
text = """
|
||||
babel wireless
|
||||
no babel split-horizon
|
||||
|
@ -363,9 +355,9 @@ class FRRpimd(FrrService, ConfigService):
|
|||
|
||||
def frr_config(self) -> str:
|
||||
ifname = "eth0"
|
||||
for ifc in self.node.netifs():
|
||||
if ifc.name != "lo":
|
||||
ifname = ifc.name
|
||||
for iface in self.node.get_ifaces():
|
||||
if iface.name != "lo":
|
||||
ifname = iface.name
|
||||
break
|
||||
|
||||
text = f"""
|
||||
|
@ -382,7 +374,7 @@ class FRRpimd(FrrService, ConfigService):
|
|||
"""
|
||||
return self.clean_text(text)
|
||||
|
||||
def frr_interface_config(self, ifc: CoreInterface) -> str:
|
||||
def frr_iface_config(self, iface: CoreInterface) -> str:
|
||||
text = """
|
||||
ip mfea
|
||||
ip igmp
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
% for ifc, ip4s, ip6s, is_control in interfaces:
|
||||
interface ${ifc.name}
|
||||
% for iface, ip4s, ip6s, is_control in ifaces:
|
||||
interface ${iface.name}
|
||||
% if want_ip4:
|
||||
% for addr in ip4s:
|
||||
ip address ${addr}
|
||||
|
@ -12,7 +12,7 @@ interface ${ifc.name}
|
|||
% endif
|
||||
% if not is_control:
|
||||
% for service in services:
|
||||
% for line in service.frr_interface_config(ifc).split("\n"):
|
||||
% for line in service.frr_iface_config(iface).split("\n"):
|
||||
${line}
|
||||
% endfor
|
||||
% endfor
|
||||
|
|
|
@ -98,8 +98,8 @@ confcheck
|
|||
bootfrr
|
||||
|
||||
# reset interfaces
|
||||
% for ifc, _, _ , _ in interfaces:
|
||||
ip link set dev ${ifc.name} down
|
||||
% for iface, _, _ , _ in ifaces:
|
||||
ip link set dev ${iface.name} down
|
||||
sleep 1
|
||||
ip link set dev ${ifc.name} up
|
||||
ip link set dev ${iface.name} up
|
||||
% endfor
|
||||
|
|
|
@ -24,8 +24,8 @@ class MgenSinkService(ConfigService):
|
|||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
ifnames = []
|
||||
for ifc in self.node.netifs():
|
||||
name = utils.sysctl_devname(ifc.name)
|
||||
for iface in self.node.get_ifaces():
|
||||
name = utils.sysctl_devname(iface.name)
|
||||
ifnames.append(name)
|
||||
return dict(ifnames=ifnames)
|
||||
|
||||
|
@ -47,10 +47,8 @@ class NrlNhdp(ConfigService):
|
|||
def data(self) -> Dict[str, Any]:
|
||||
has_smf = "SMF" in self.node.config_services
|
||||
ifnames = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifnames.append(ifc.name)
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifnames.append(iface.name)
|
||||
return dict(has_smf=has_smf, ifnames=ifnames)
|
||||
|
||||
|
||||
|
@ -74,13 +72,11 @@ class NrlSmf(ConfigService):
|
|||
has_olsr = "OLSR" in self.node.config_services
|
||||
ifnames = []
|
||||
ip4_prefix = None
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifnames.append(ifc.name)
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifnames.append(iface.name)
|
||||
if ip4_prefix:
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for a in iface.addrlist:
|
||||
a = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(a):
|
||||
ip4_prefix = f"{a}/{24}"
|
||||
|
@ -112,10 +108,8 @@ class NrlOlsr(ConfigService):
|
|||
has_smf = "SMF" in self.node.config_services
|
||||
has_zebra = "zebra" in self.node.config_services
|
||||
ifname = None
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifname = ifc.name
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifname = iface.name
|
||||
break
|
||||
return dict(has_smf=has_smf, has_zebra=has_zebra, ifname=ifname)
|
||||
|
||||
|
@ -137,10 +131,8 @@ class NrlOlsrv2(ConfigService):
|
|||
def data(self) -> Dict[str, Any]:
|
||||
has_smf = "SMF" in self.node.config_services
|
||||
ifnames = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifnames.append(ifc.name)
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifnames.append(iface.name)
|
||||
return dict(has_smf=has_smf, ifnames=ifnames)
|
||||
|
||||
|
||||
|
@ -161,10 +153,8 @@ class OlsrOrg(ConfigService):
|
|||
def data(self) -> Dict[str, Any]:
|
||||
has_smf = "SMF" in self.node.config_services
|
||||
ifnames = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifnames.append(ifc.name)
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifnames.append(iface.name)
|
||||
return dict(has_smf=has_smf, ifnames=ifnames)
|
||||
|
||||
|
||||
|
@ -199,12 +189,10 @@ class Arouted(ConfigService):
|
|||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
ip4_prefix = None
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
if ip4_prefix:
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for a in iface.addrlist:
|
||||
a = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(a):
|
||||
ip4_prefix = f"{a}/{24}"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<%
|
||||
interfaces = "-i " + " -i ".join(ifnames)
|
||||
ifaces = "-i " + " -i ".join(ifnames)
|
||||
smf = ""
|
||||
if has_smf:
|
||||
smf = "-flooding ecds -smfClient %s_smf" % node.name
|
||||
%>
|
||||
nrlnhdp -l /var/log/nrlnhdp.log -rpipe ${node.name}_nhdp ${smf} ${interfaces}
|
||||
nrlnhdp -l /var/log/nrlnhdp.log -rpipe ${node.name}_nhdp ${smf} ${ifaces}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<%
|
||||
interfaces = "-i " + " -i ".join(ifnames)
|
||||
ifaces = "-i " + " -i ".join(ifnames)
|
||||
smf = ""
|
||||
if has_smf:
|
||||
smf = "-flooding ecds -smfClient %s_smf" % node.name
|
||||
%>
|
||||
nrlolsrv2 -l /var/log/nrlolsrv2.log -rpipe ${node.name}_olsrv2 -p olsr ${smf} ${interfaces}
|
||||
nrlolsrv2 -l /var/log/nrlolsrv2.log -rpipe ${node.name}_olsrv2 -p olsr ${smf} ${ifaces}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<%
|
||||
interfaces = "-i " + " -i ".join(ifnames)
|
||||
ifaces = "-i " + " -i ".join(ifnames)
|
||||
%>
|
||||
olsrd ${interfaces}
|
||||
olsrd ${ifaces}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<%
|
||||
interfaces = ",".join(ifnames)
|
||||
ifaces = ",".join(ifnames)
|
||||
arouted = ""
|
||||
if has_arouted:
|
||||
arouted = "tap %s_tap unicast %s push lo,%s resequence on" % (node.name, ip4_prefix, ifnames[0])
|
||||
|
@ -12,4 +12,4 @@
|
|||
%>
|
||||
#!/bin/sh
|
||||
# auto-generated by NrlSmf service
|
||||
nrlsmf instance ${node.name}_smf ${interfaces} ${arouted} ${flood} hash MD5 log /var/log/nrlsmf.log < /dev/null > /dev/null 2>&1 &
|
||||
nrlsmf instance ${node.name}_smf ${ifaces} ${arouted} ${flood} hash MD5 log /var/log/nrlsmf.log < /dev/null > /dev/null 2>&1 &
|
||||
|
|
|
@ -14,33 +14,33 @@ from core.nodes.network import WlanNode
|
|||
GROUP = "Quagga"
|
||||
|
||||
|
||||
def has_mtu_mismatch(ifc: CoreInterface) -> bool:
|
||||
def has_mtu_mismatch(iface: CoreInterface) -> bool:
|
||||
"""
|
||||
Helper to detect MTU mismatch and add the appropriate OSPF
|
||||
mtu-ignore command. This is needed when e.g. a node is linked via a
|
||||
GreTap device.
|
||||
"""
|
||||
if ifc.mtu != 1500:
|
||||
if iface.mtu != 1500:
|
||||
return True
|
||||
if not ifc.net:
|
||||
if not iface.net:
|
||||
return False
|
||||
for i in ifc.net.netifs():
|
||||
if i.mtu != ifc.mtu:
|
||||
for iface in iface.net.get_ifaces():
|
||||
if iface.mtu != iface.mtu:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_min_mtu(ifc):
|
||||
def get_min_mtu(iface: CoreInterface):
|
||||
"""
|
||||
Helper to discover the minimum MTU of interfaces linked with the
|
||||
given interface.
|
||||
"""
|
||||
mtu = ifc.mtu
|
||||
if not ifc.net:
|
||||
mtu = iface.mtu
|
||||
if not iface.net:
|
||||
return mtu
|
||||
for i in ifc.net.netifs():
|
||||
if i.mtu < mtu:
|
||||
mtu = i.mtu
|
||||
for iface in iface.net.get_ifaces():
|
||||
if iface.mtu < mtu:
|
||||
mtu = iface.mtu
|
||||
return mtu
|
||||
|
||||
|
||||
|
@ -48,10 +48,8 @@ def get_router_id(node: CoreNodeBase) -> str:
|
|||
"""
|
||||
Helper to return the first IPv4 address of a node as its router ID.
|
||||
"""
|
||||
for ifc in node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
for a in iface.addrlist:
|
||||
a = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(a):
|
||||
return a
|
||||
|
@ -98,25 +96,25 @@ class Zebra(ConfigService):
|
|||
want_ip6 = True
|
||||
services.append(service)
|
||||
|
||||
interfaces = []
|
||||
for ifc in self.node.netifs():
|
||||
ifaces = []
|
||||
for iface in self.node.get_ifaces():
|
||||
ip4s = []
|
||||
ip6s = []
|
||||
for x in ifc.addrlist:
|
||||
for x in iface.addrlist:
|
||||
addr = x.split("/")[0]
|
||||
if netaddr.valid_ipv4(addr):
|
||||
ip4s.append(x)
|
||||
else:
|
||||
ip6s.append(x)
|
||||
is_control = getattr(ifc, "control", False)
|
||||
interfaces.append((ifc, ip4s, ip6s, is_control))
|
||||
is_control = getattr(iface, "control", False)
|
||||
ifaces.append((iface, ip4s, ip6s, is_control))
|
||||
|
||||
return dict(
|
||||
quagga_bin_search=quagga_bin_search,
|
||||
quagga_sbin_search=quagga_sbin_search,
|
||||
quagga_state_dir=quagga_state_dir,
|
||||
quagga_conf=quagga_conf,
|
||||
interfaces=interfaces,
|
||||
ifaces=ifaces,
|
||||
want_ip4=want_ip4,
|
||||
want_ip6=want_ip6,
|
||||
services=services,
|
||||
|
@ -139,7 +137,7 @@ class QuaggaService(abc.ABC):
|
|||
ipv6_routing = False
|
||||
|
||||
@abc.abstractmethod
|
||||
def quagga_interface_config(self, ifc: CoreInterface) -> str:
|
||||
def quagga_iface_config(self, iface: CoreInterface) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
|
@ -159,8 +157,8 @@ class Ospfv2(QuaggaService, ConfigService):
|
|||
shutdown = ["killall ospfd"]
|
||||
ipv4_routing = True
|
||||
|
||||
def quagga_interface_config(self, ifc: CoreInterface) -> str:
|
||||
if has_mtu_mismatch(ifc):
|
||||
def quagga_iface_config(self, iface: CoreInterface) -> str:
|
||||
if has_mtu_mismatch(iface):
|
||||
return "ip ospf mtu-ignore"
|
||||
else:
|
||||
return ""
|
||||
|
@ -168,10 +166,8 @@ class Ospfv2(QuaggaService, ConfigService):
|
|||
def quagga_config(self) -> str:
|
||||
router_id = get_router_id(self.node)
|
||||
addresses = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
for a in iface.addrlist:
|
||||
addr = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(addr):
|
||||
addresses.append(a)
|
||||
|
@ -200,9 +196,9 @@ class Ospfv3(QuaggaService, ConfigService):
|
|||
ipv4_routing = True
|
||||
ipv6_routing = True
|
||||
|
||||
def quagga_interface_config(self, ifc: CoreInterface) -> str:
|
||||
mtu = get_min_mtu(ifc)
|
||||
if mtu < ifc.mtu:
|
||||
def quagga_iface_config(self, iface: CoreInterface) -> str:
|
||||
mtu = get_min_mtu(iface)
|
||||
if mtu < iface.mtu:
|
||||
return f"ipv6 ospf6 ifmtu {mtu}"
|
||||
else:
|
||||
return ""
|
||||
|
@ -210,10 +206,8 @@ class Ospfv3(QuaggaService, ConfigService):
|
|||
def quagga_config(self) -> str:
|
||||
router_id = get_router_id(self.node)
|
||||
ifnames = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifnames.append(ifc.name)
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifnames.append(iface.name)
|
||||
data = dict(router_id=router_id, ifnames=ifnames)
|
||||
text = """
|
||||
router ospf6
|
||||
|
@ -238,14 +232,14 @@ class Ospfv3mdr(Ospfv3):
|
|||
name = "OSPFv3MDR"
|
||||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
for ifc in self.node.netifs():
|
||||
is_wireless = isinstance(ifc.net, (WlanNode, EmaneNet))
|
||||
for iface in self.node.get_ifaces():
|
||||
is_wireless = isinstance(iface.net, (WlanNode, EmaneNet))
|
||||
logging.info("MDR wireless: %s", is_wireless)
|
||||
return dict()
|
||||
|
||||
def quagga_interface_config(self, ifc: CoreInterface) -> str:
|
||||
config = super().quagga_interface_config(ifc)
|
||||
if isinstance(ifc.net, (WlanNode, EmaneNet)):
|
||||
def quagga_iface_config(self, iface: CoreInterface) -> str:
|
||||
config = super().quagga_iface_config(iface)
|
||||
if isinstance(iface.net, (WlanNode, EmaneNet)):
|
||||
config = self.clean_text(
|
||||
f"""
|
||||
{config}
|
||||
|
@ -277,7 +271,7 @@ class Bgp(QuaggaService, ConfigService):
|
|||
def quagga_config(self) -> str:
|
||||
return ""
|
||||
|
||||
def quagga_interface_config(self, ifc: CoreInterface) -> str:
|
||||
def quagga_iface_config(self, iface: CoreInterface) -> str:
|
||||
router_id = get_router_id(self.node)
|
||||
text = f"""
|
||||
! BGP configuration
|
||||
|
@ -313,7 +307,7 @@ class Rip(QuaggaService, ConfigService):
|
|||
"""
|
||||
return self.clean_text(text)
|
||||
|
||||
def quagga_interface_config(self, ifc: CoreInterface) -> str:
|
||||
def quagga_iface_config(self, iface: CoreInterface) -> str:
|
||||
return ""
|
||||
|
||||
|
||||
|
@ -338,7 +332,7 @@ class Ripng(QuaggaService, ConfigService):
|
|||
"""
|
||||
return self.clean_text(text)
|
||||
|
||||
def quagga_interface_config(self, ifc: CoreInterface) -> str:
|
||||
def quagga_iface_config(self, iface: CoreInterface) -> str:
|
||||
return ""
|
||||
|
||||
|
||||
|
@ -355,10 +349,8 @@ class Babel(QuaggaService, ConfigService):
|
|||
|
||||
def quagga_config(self) -> str:
|
||||
ifnames = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifnames.append(ifc.name)
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifnames.append(iface.name)
|
||||
text = """
|
||||
router babel
|
||||
% for ifname in ifnames:
|
||||
|
@ -371,8 +363,8 @@ class Babel(QuaggaService, ConfigService):
|
|||
data = dict(ifnames=ifnames)
|
||||
return self.render_text(text, data)
|
||||
|
||||
def quagga_interface_config(self, ifc: CoreInterface) -> str:
|
||||
if isinstance(ifc.net, (WlanNode, EmaneNet)):
|
||||
def quagga_iface_config(self, iface: CoreInterface) -> str:
|
||||
if isinstance(iface.net, (WlanNode, EmaneNet)):
|
||||
text = """
|
||||
babel wireless
|
||||
no babel split-horizon
|
||||
|
@ -397,9 +389,9 @@ class Xpimd(QuaggaService, ConfigService):
|
|||
|
||||
def quagga_config(self) -> str:
|
||||
ifname = "eth0"
|
||||
for ifc in self.node.netifs():
|
||||
if ifc.name != "lo":
|
||||
ifname = ifc.name
|
||||
for iface in self.node.get_ifaces():
|
||||
if iface.name != "lo":
|
||||
ifname = iface.name
|
||||
break
|
||||
|
||||
text = f"""
|
||||
|
@ -416,7 +408,7 @@ class Xpimd(QuaggaService, ConfigService):
|
|||
"""
|
||||
return self.clean_text(text)
|
||||
|
||||
def quagga_interface_config(self, ifc: CoreInterface) -> str:
|
||||
def quagga_iface_config(self, iface: CoreInterface) -> str:
|
||||
text = """
|
||||
ip mfea
|
||||
ip pim
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
% for ifc, ip4s, ip6s, is_control in interfaces:
|
||||
interface ${ifc.name}
|
||||
% for iface, ip4s, ip6s, is_control in ifaces:
|
||||
interface ${iface.name}
|
||||
% if want_ip4:
|
||||
% for addr in ip4s:
|
||||
ip address ${addr}
|
||||
|
@ -12,7 +12,7 @@ interface ${ifc.name}
|
|||
% endif
|
||||
% if not is_control:
|
||||
% for service in services:
|
||||
% for line in service.quagga_interface_config(ifc).split("\n"):
|
||||
% for line in service.quagga_iface_config(iface).split("\n"):
|
||||
${line}
|
||||
% endfor
|
||||
% endfor
|
||||
|
|
|
@ -78,10 +78,8 @@ class VpnServer(ConfigService):
|
|||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
address = None
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
for x in ifc.addrlist:
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
for x in iface.addrlist:
|
||||
addr = x.split("/")[0]
|
||||
if netaddr.valid_ipv4(addr):
|
||||
address = addr
|
||||
|
@ -134,8 +132,6 @@ class Nat(ConfigService):
|
|||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
ifnames = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifnames.append(ifc.name)
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifnames.append(iface.name)
|
||||
return dict(ifnames=ifnames)
|
||||
|
|
|
@ -25,10 +25,10 @@ class DefaultRouteService(ConfigService):
|
|||
def data(self) -> Dict[str, Any]:
|
||||
# only add default routes for linked routing nodes
|
||||
routes = []
|
||||
netifs = self.node.netifs(sort=True)
|
||||
if netifs:
|
||||
netif = netifs[0]
|
||||
for x in netif.addrlist:
|
||||
ifaces = self.node.get_ifaces()
|
||||
if ifaces:
|
||||
iface = ifaces[0]
|
||||
for x in iface.addrlist:
|
||||
net = netaddr.IPNetwork(x).cidr
|
||||
if net.size > 1:
|
||||
router = net[1]
|
||||
|
@ -52,10 +52,8 @@ class DefaultMulticastRouteService(ConfigService):
|
|||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
ifname = None
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifname = ifc.name
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifname = iface.name
|
||||
break
|
||||
return dict(ifname=ifname)
|
||||
|
||||
|
@ -76,10 +74,8 @@ class StaticRouteService(ConfigService):
|
|||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
routes = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
for x in ifc.addrlist:
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
for x in iface.addrlist:
|
||||
addr = x.split("/")[0]
|
||||
if netaddr.valid_ipv6(addr):
|
||||
dst = "3ffe:4::/64"
|
||||
|
@ -107,8 +103,8 @@ class IpForwardService(ConfigService):
|
|||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
devnames = []
|
||||
for ifc in self.node.netifs():
|
||||
devname = utils.sysctl_devname(ifc.name)
|
||||
for iface in self.node.get_ifaces():
|
||||
devname = utils.sysctl_devname(iface.name)
|
||||
devnames.append(devname)
|
||||
return dict(devnames=devnames)
|
||||
|
||||
|
@ -151,10 +147,8 @@ class DhcpService(ConfigService):
|
|||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
subnets = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
for x in ifc.addrlist:
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
for x in iface.addrlist:
|
||||
addr = x.split("/")[0]
|
||||
if netaddr.valid_ipv4(addr):
|
||||
net = netaddr.IPNetwork(x)
|
||||
|
@ -182,10 +176,8 @@ class DhcpClientService(ConfigService):
|
|||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
ifnames = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifnames.append(ifc.name)
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifnames.append(iface.name)
|
||||
return dict(ifnames=ifnames)
|
||||
|
||||
|
||||
|
@ -220,10 +212,8 @@ class PcapService(ConfigService):
|
|||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
ifnames = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifnames.append(ifc.name)
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifnames.append(iface.name)
|
||||
return dict()
|
||||
|
||||
|
||||
|
@ -242,19 +232,17 @@ class RadvdService(ConfigService):
|
|||
modes = {}
|
||||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
interfaces = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
ifaces = []
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
prefixes = []
|
||||
for x in ifc.addrlist:
|
||||
for x in iface.addrlist:
|
||||
addr = x.split("/")[0]
|
||||
if netaddr.valid_ipv6(addr):
|
||||
prefixes.append(x)
|
||||
if not prefixes:
|
||||
continue
|
||||
interfaces.append((ifc.name, prefixes))
|
||||
return dict(interfaces=interfaces)
|
||||
ifaces.append((iface.name, prefixes))
|
||||
return dict(ifaces=ifaces)
|
||||
|
||||
|
||||
class AtdService(ConfigService):
|
||||
|
@ -294,9 +282,7 @@ class HttpService(ConfigService):
|
|||
modes = {}
|
||||
|
||||
def data(self) -> Dict[str, Any]:
|
||||
interfaces = []
|
||||
for ifc in self.node.netifs():
|
||||
if getattr(ifc, "control", False):
|
||||
continue
|
||||
interfaces.append(ifc)
|
||||
return dict(interfaces=interfaces)
|
||||
ifaces = []
|
||||
for iface in self.node.get_ifaces(control=False):
|
||||
ifaces.append(iface)
|
||||
return dict(ifaces=ifaces)
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<p>This is the default web page for this server.</p>
|
||||
<p>The web server software is running but no content has been added, yet.</p>
|
||||
<ul>
|
||||
% for ifc in interfaces:
|
||||
<li>${ifc.name} - ${ifc.addrlist}</li>
|
||||
% for iface in ifaces:
|
||||
<li>${iface.name} - ${iface.addrlist}</li>
|
||||
% endfor
|
||||
</ul>
|
||||
</body>
|
||||
|
|
|
@ -63,7 +63,7 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
|
|||
return [ConfigGroup("CommEffect SHIM Parameters", 1, len(cls.configurations()))]
|
||||
|
||||
def build_xml_files(
|
||||
self, config: Dict[str, str], interface: CoreInterface = None
|
||||
self, config: Dict[str, str], iface: CoreInterface = None
|
||||
) -> None:
|
||||
"""
|
||||
Build the necessary nem and commeffect XMLs in the given path.
|
||||
|
@ -72,17 +72,17 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
|
|||
nXXemane_commeffectnem.xml, nXXemane_commeffectshim.xml are used.
|
||||
|
||||
:param config: emane model configuration for the node and interface
|
||||
:param interface: interface for the emane node
|
||||
:param iface: interface for the emane node
|
||||
:return: nothing
|
||||
"""
|
||||
# retrieve xml names
|
||||
nem_name = emanexml.nem_file_name(self, interface)
|
||||
shim_name = emanexml.shim_file_name(self, interface)
|
||||
nem_name = emanexml.nem_file_name(self, iface)
|
||||
shim_name = emanexml.shim_file_name(self, iface)
|
||||
|
||||
# create and write nem document
|
||||
nem_element = etree.Element("nem", name=f"{self.name} NEM", type="unstructured")
|
||||
transport_type = TransportType.VIRTUAL
|
||||
if interface and interface.transport_type == TransportType.RAW:
|
||||
if iface and iface.transport_type == TransportType.RAW:
|
||||
transport_type = TransportType.RAW
|
||||
transport_file = emanexml.transport_file_name(self.id, transport_type)
|
||||
etree.SubElement(nem_element, "transport", definition=transport_file)
|
||||
|
@ -115,7 +115,7 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
|
|||
emanexml.create_file(shim_element, "shim", shim_file)
|
||||
|
||||
def linkconfig(
|
||||
self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
|
||||
self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None
|
||||
) -> None:
|
||||
"""
|
||||
Generate CommEffect events when a Link Message is received having
|
||||
|
@ -126,7 +126,7 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
|
|||
logging.warning("%s: EMANE event service unavailable", self.name)
|
||||
return
|
||||
|
||||
if netif is None or netif2 is None:
|
||||
if iface is None or iface2 is None:
|
||||
logging.warning("%s: missing NEM information", self.name)
|
||||
return
|
||||
|
||||
|
@ -134,8 +134,8 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
|
|||
# TODO: may want to split out seconds portion of delay and jitter
|
||||
event = CommEffectEvent()
|
||||
emane_node = self.session.get_node(self.id, EmaneNet)
|
||||
nemid = emane_node.getnemid(netif)
|
||||
nemid2 = emane_node.getnemid(netif2)
|
||||
nemid = emane_node.getnemid(iface)
|
||||
nemid2 = emane_node.getnemid(iface2)
|
||||
logging.info("sending comm effect event")
|
||||
event.append(
|
||||
nemid,
|
||||
|
|
|
@ -111,41 +111,39 @@ class EmaneManager(ModelManager):
|
|||
self.event_device: Optional[str] = None
|
||||
self.emane_check()
|
||||
|
||||
def getifcconfig(
|
||||
self, node_id: int, interface: CoreInterface, model_name: str
|
||||
def get_iface_config(
|
||||
self, node_id: int, iface: CoreInterface, model_name: str
|
||||
) -> Dict[str, str]:
|
||||
"""
|
||||
Retrieve interface configuration or node configuration if not provided.
|
||||
|
||||
:param node_id: node id
|
||||
:param interface: node interface
|
||||
:param iface: node interface
|
||||
:param model_name: model to get configuration for
|
||||
:return: node/interface model configuration
|
||||
"""
|
||||
# use the network-wide config values or interface(NEM)-specific values?
|
||||
if interface is None:
|
||||
if iface is None:
|
||||
return self.get_configs(node_id=node_id, config_type=model_name)
|
||||
else:
|
||||
# don"t use default values when interface config is the same as net
|
||||
# note here that using ifc.node.id as key allows for only one type
|
||||
# note here that using iface.node.id as key allows for only one type
|
||||
# of each model per node;
|
||||
# TODO: use both node and interface as key
|
||||
|
||||
# Adamson change: first check for iface config keyed by "node:ifc.name"
|
||||
# Adamson change: first check for iface config keyed by "node:iface.name"
|
||||
# (so that nodes w/ multiple interfaces of same conftype can have
|
||||
# different configs for each separate interface)
|
||||
key = 1000 * interface.node.id
|
||||
if interface.netindex is not None:
|
||||
key += interface.netindex
|
||||
key = 1000 * iface.node.id
|
||||
if iface.node_id is not None:
|
||||
key += iface.node_id
|
||||
|
||||
# try retrieve interface specific configuration, avoid getting defaults
|
||||
config = self.get_configs(node_id=key, config_type=model_name)
|
||||
|
||||
# otherwise retrieve the interfaces node configuration, avoid using defaults
|
||||
if not config:
|
||||
config = self.get_configs(
|
||||
node_id=interface.node.id, config_type=model_name
|
||||
)
|
||||
config = self.get_configs(node_id=iface.node.id, config_type=model_name)
|
||||
|
||||
# get non interface config, when none found
|
||||
if not config:
|
||||
|
@ -265,8 +263,8 @@ class EmaneManager(ModelManager):
|
|||
# assumes self._objslock already held
|
||||
nodes = set()
|
||||
for emane_net in self._emane_nets.values():
|
||||
for netif in emane_net.netifs():
|
||||
nodes.add(netif.node)
|
||||
for iface in emane_net.get_ifaces():
|
||||
nodes.add(iface.node)
|
||||
return nodes
|
||||
|
||||
def setup(self) -> int:
|
||||
|
@ -352,13 +350,13 @@ class EmaneManager(ModelManager):
|
|||
|
||||
if self.numnems() > 0:
|
||||
self.startdaemons()
|
||||
self.installnetifs()
|
||||
self.install_ifaces()
|
||||
|
||||
for node_id in self._emane_nets:
|
||||
emane_node = self._emane_nets[node_id]
|
||||
for netif in emane_node.netifs():
|
||||
for iface in emane_node.get_ifaces():
|
||||
nems.append(
|
||||
(netif.node.name, netif.name, emane_node.getnemid(netif))
|
||||
(iface.node.name, iface.name, emane_node.getnemid(iface))
|
||||
)
|
||||
|
||||
if nems:
|
||||
|
@ -392,8 +390,8 @@ class EmaneManager(ModelManager):
|
|||
emane_node.name,
|
||||
)
|
||||
emane_node.model.post_startup()
|
||||
for netif in emane_node.netifs():
|
||||
netif.setposition()
|
||||
for iface in emane_node.get_ifaces():
|
||||
iface.setposition()
|
||||
|
||||
def reset(self) -> None:
|
||||
"""
|
||||
|
@ -420,7 +418,7 @@ class EmaneManager(ModelManager):
|
|||
logging.info("stopping EMANE daemons")
|
||||
if self.links_enabled():
|
||||
self.link_monitor.stop()
|
||||
self.deinstallnetifs()
|
||||
self.deinstall_ifaces()
|
||||
self.stopdaemons()
|
||||
self.stopeventmonitor()
|
||||
|
||||
|
@ -474,31 +472,31 @@ class EmaneManager(ModelManager):
|
|||
EMANE network and NEM interface.
|
||||
"""
|
||||
emane_node = None
|
||||
netif = None
|
||||
iface = None
|
||||
|
||||
for node_id in self._emane_nets:
|
||||
emane_node = self._emane_nets[node_id]
|
||||
netif = emane_node.getnemnetif(nemid)
|
||||
if netif is not None:
|
||||
iface = emane_node.get_nem_iface(nemid)
|
||||
if iface is not None:
|
||||
break
|
||||
else:
|
||||
emane_node = None
|
||||
|
||||
return emane_node, netif
|
||||
return emane_node, iface
|
||||
|
||||
def get_nem_link(
|
||||
self, nem1: int, nem2: int, flags: MessageFlags = MessageFlags.NONE
|
||||
) -> Optional[LinkData]:
|
||||
emane1, netif = self.nemlookup(nem1)
|
||||
if not emane1 or not netif:
|
||||
emane1, iface = self.nemlookup(nem1)
|
||||
if not emane1 or not iface:
|
||||
logging.error("invalid nem: %s", nem1)
|
||||
return None
|
||||
node1 = netif.node
|
||||
emane2, netif = self.nemlookup(nem2)
|
||||
if not emane2 or not netif:
|
||||
node1 = iface.node
|
||||
emane2, iface = self.nemlookup(nem2)
|
||||
if not emane2 or not iface:
|
||||
logging.error("invalid nem: %s", nem2)
|
||||
return None
|
||||
node2 = netif.node
|
||||
node2 = iface.node
|
||||
color = self.session.get_link_color(emane1.id)
|
||||
return LinkData(
|
||||
message_type=flags,
|
||||
|
@ -516,7 +514,7 @@ class EmaneManager(ModelManager):
|
|||
count = 0
|
||||
for node_id in self._emane_nets:
|
||||
emane_node = self._emane_nets[node_id]
|
||||
count += len(emane_node.netifs())
|
||||
count += len(emane_node.ifaces)
|
||||
return count
|
||||
|
||||
def buildplatformxml(self, ctrlnet: CtrlNet) -> None:
|
||||
|
@ -607,19 +605,19 @@ class EmaneManager(ModelManager):
|
|||
n = node.id
|
||||
|
||||
# control network not yet started here
|
||||
self.session.add_remove_control_interface(
|
||||
self.session.add_remove_control_iface(
|
||||
node, 0, remove=False, conf_required=False
|
||||
)
|
||||
|
||||
if otanetidx > 0:
|
||||
logging.info("adding ota device ctrl%d", otanetidx)
|
||||
self.session.add_remove_control_interface(
|
||||
self.session.add_remove_control_iface(
|
||||
node, otanetidx, remove=False, conf_required=False
|
||||
)
|
||||
|
||||
if eventservicenetidx >= 0:
|
||||
logging.info("adding event service device ctrl%d", eventservicenetidx)
|
||||
self.session.add_remove_control_interface(
|
||||
self.session.add_remove_control_iface(
|
||||
node, eventservicenetidx, remove=False, conf_required=False
|
||||
)
|
||||
|
||||
|
@ -676,23 +674,23 @@ class EmaneManager(ModelManager):
|
|||
except CoreCommandError:
|
||||
logging.exception("error shutting down emane daemons")
|
||||
|
||||
def installnetifs(self) -> None:
|
||||
def install_ifaces(self) -> None:
|
||||
"""
|
||||
Install TUN/TAP virtual interfaces into their proper namespaces
|
||||
now that the EMANE daemons are running.
|
||||
"""
|
||||
for key in sorted(self._emane_nets.keys()):
|
||||
emane_node = self._emane_nets[key]
|
||||
logging.info("emane install netifs for node: %d", key)
|
||||
emane_node.installnetifs()
|
||||
node = self._emane_nets[key]
|
||||
logging.info("emane install interface for node(%s): %d", node.name, key)
|
||||
node.install_ifaces()
|
||||
|
||||
def deinstallnetifs(self) -> None:
|
||||
def deinstall_ifaces(self) -> None:
|
||||
"""
|
||||
Uninstall TUN/TAP virtual interfaces.
|
||||
"""
|
||||
for key in sorted(self._emane_nets.keys()):
|
||||
emane_node = self._emane_nets[key]
|
||||
emane_node.deinstallnetifs()
|
||||
emane_node.deinstall_ifaces()
|
||||
|
||||
def doeventmonitor(self) -> bool:
|
||||
"""
|
||||
|
@ -808,12 +806,12 @@ class EmaneManager(ModelManager):
|
|||
Returns True if successfully parsed and a Node Message was sent.
|
||||
"""
|
||||
# convert nemid to node number
|
||||
_emanenode, netif = self.nemlookup(nemid)
|
||||
if netif is None:
|
||||
_emanenode, iface = self.nemlookup(nemid)
|
||||
if iface is None:
|
||||
logging.info("location event for unknown NEM %s", nemid)
|
||||
return False
|
||||
|
||||
n = netif.node.id
|
||||
n = iface.node.id
|
||||
# convert from lat/long/alt to x,y,z coordinates
|
||||
x, y, z = self.session.location.getxyz(lat, lon, alt)
|
||||
x = int(x)
|
||||
|
|
|
@ -97,28 +97,28 @@ class EmaneModel(WirelessModel):
|
|||
]
|
||||
|
||||
def build_xml_files(
|
||||
self, config: Dict[str, str], interface: CoreInterface = None
|
||||
self, config: Dict[str, str], iface: CoreInterface = None
|
||||
) -> None:
|
||||
"""
|
||||
Builds xml files for this emane model. Creates a nem.xml file that points to
|
||||
both mac.xml and phy.xml definitions.
|
||||
|
||||
:param config: emane model configuration for the node and interface
|
||||
:param interface: interface for the emane node
|
||||
:param iface: interface for the emane node
|
||||
:return: nothing
|
||||
"""
|
||||
nem_name = emanexml.nem_file_name(self, interface)
|
||||
mac_name = emanexml.mac_file_name(self, interface)
|
||||
phy_name = emanexml.phy_file_name(self, interface)
|
||||
nem_name = emanexml.nem_file_name(self, iface)
|
||||
mac_name = emanexml.mac_file_name(self, iface)
|
||||
phy_name = emanexml.phy_file_name(self, iface)
|
||||
|
||||
# remote server for file
|
||||
server = None
|
||||
if interface is not None:
|
||||
server = interface.node.server
|
||||
if iface is not None:
|
||||
server = iface.node.server
|
||||
|
||||
# check if this is external
|
||||
transport_type = TransportType.VIRTUAL
|
||||
if interface and interface.transport_type == TransportType.RAW:
|
||||
if iface and iface.transport_type == TransportType.RAW:
|
||||
transport_type = TransportType.RAW
|
||||
transport_name = emanexml.transport_file_name(self.id, transport_type)
|
||||
|
||||
|
@ -144,31 +144,31 @@ class EmaneModel(WirelessModel):
|
|||
"""
|
||||
logging.debug("emane model(%s) has no post setup tasks", self.name)
|
||||
|
||||
def update(self, moved: List[CoreNode], moved_netifs: List[CoreInterface]) -> None:
|
||||
def update(self, moved: List[CoreNode], moved_ifaces: List[CoreInterface]) -> None:
|
||||
"""
|
||||
Invoked from MobilityModel when nodes are moved; this causes
|
||||
emane location events to be generated for the nodes in the moved
|
||||
list, making EmaneModels compatible with Ns2ScriptedMobility.
|
||||
|
||||
:param moved: moved nodes
|
||||
:param moved_netifs: interfaces that were moved
|
||||
:param moved_ifaces: interfaces that were moved
|
||||
:return: nothing
|
||||
"""
|
||||
try:
|
||||
wlan = self.session.get_node(self.id, EmaneNet)
|
||||
wlan.setnempositions(moved_netifs)
|
||||
wlan.setnempositions(moved_ifaces)
|
||||
except CoreError:
|
||||
logging.exception("error during update")
|
||||
|
||||
def linkconfig(
|
||||
self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
|
||||
self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None
|
||||
) -> None:
|
||||
"""
|
||||
Invoked when a Link Message is received. Default is unimplemented.
|
||||
|
||||
:param netif: interface one
|
||||
:param iface: interface one
|
||||
:param options: options for configuring link
|
||||
:param netif2: interface two
|
||||
:param iface2: interface two
|
||||
:return: nothing
|
||||
"""
|
||||
logging.warning("emane model(%s) does not support link config", self.name)
|
||||
|
|
|
@ -212,10 +212,10 @@ class EmaneLinkMonitor:
|
|||
addresses = []
|
||||
nodes = self.emane_manager.getnodes()
|
||||
for node in nodes:
|
||||
for netif in node.netifs():
|
||||
if isinstance(netif.net, CtrlNet):
|
||||
for iface in node.get_ifaces():
|
||||
if isinstance(iface.net, CtrlNet):
|
||||
ip4 = None
|
||||
for x in netif.addrlist:
|
||||
for x in iface.addrlist:
|
||||
address, prefix = x.split("/")
|
||||
if netaddr.valid_ipv4(address):
|
||||
ip4 = address
|
||||
|
|
|
@ -64,14 +64,14 @@ class EmaneNet(CoreNetworkBase):
|
|||
self.mobility: Optional[WayPointMobility] = None
|
||||
|
||||
def linkconfig(
|
||||
self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
|
||||
self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None
|
||||
) -> None:
|
||||
"""
|
||||
The CommEffect model supports link configuration.
|
||||
"""
|
||||
if not self.model:
|
||||
return
|
||||
self.model.linkconfig(netif, options, netif2)
|
||||
self.model.linkconfig(iface, options, iface2)
|
||||
|
||||
def config(self, conf: str) -> None:
|
||||
self.conf = conf
|
||||
|
@ -82,10 +82,10 @@ class EmaneNet(CoreNetworkBase):
|
|||
def shutdown(self) -> None:
|
||||
pass
|
||||
|
||||
def link(self, netif1: CoreInterface, netif2: CoreInterface) -> None:
|
||||
def link(self, iface1: CoreInterface, iface2: CoreInterface) -> None:
|
||||
pass
|
||||
|
||||
def unlink(self, netif1: CoreInterface, netif2: CoreInterface) -> None:
|
||||
def unlink(self, iface1: CoreInterface, iface2: CoreInterface) -> None:
|
||||
pass
|
||||
|
||||
def linknet(self, net: "CoreNetworkBase") -> CoreInterface:
|
||||
|
@ -113,39 +113,33 @@ class EmaneNet(CoreNetworkBase):
|
|||
self.mobility = model(session=self.session, _id=self.id)
|
||||
self.mobility.update_config(config)
|
||||
|
||||
def setnemid(self, netif: CoreInterface, nemid: int) -> None:
|
||||
def setnemid(self, iface: CoreInterface, nemid: int) -> None:
|
||||
"""
|
||||
Record an interface to numerical ID mapping. The Emane controller
|
||||
object manages and assigns these IDs for all NEMs.
|
||||
"""
|
||||
self.nemidmap[netif] = nemid
|
||||
self.nemidmap[iface] = nemid
|
||||
|
||||
def getnemid(self, netif: CoreInterface) -> Optional[int]:
|
||||
def getnemid(self, iface: CoreInterface) -> Optional[int]:
|
||||
"""
|
||||
Given an interface, return its numerical ID.
|
||||
"""
|
||||
if netif not in self.nemidmap:
|
||||
if iface not in self.nemidmap:
|
||||
return None
|
||||
else:
|
||||
return self.nemidmap[netif]
|
||||
return self.nemidmap[iface]
|
||||
|
||||
def getnemnetif(self, nemid: int) -> Optional[CoreInterface]:
|
||||
def get_nem_iface(self, nemid: int) -> Optional[CoreInterface]:
|
||||
"""
|
||||
Given a numerical NEM ID, return its interface. This returns the
|
||||
first interface that matches the given NEM ID.
|
||||
"""
|
||||
for netif in self.nemidmap:
|
||||
if self.nemidmap[netif] == nemid:
|
||||
return netif
|
||||
for iface in self.nemidmap:
|
||||
if self.nemidmap[iface] == nemid:
|
||||
return iface
|
||||
return None
|
||||
|
||||
def netifs(self, sort: bool = True) -> List[CoreInterface]:
|
||||
"""
|
||||
Retrieve list of linked interfaces sorted by node number.
|
||||
"""
|
||||
return sorted(self._netif.values(), key=lambda ifc: ifc.node.id)
|
||||
|
||||
def installnetifs(self) -> None:
|
||||
def install_ifaces(self) -> None:
|
||||
"""
|
||||
Install TAP devices into their namespaces. This is done after
|
||||
EMANE daemons have been started, because that is their only chance
|
||||
|
@ -159,48 +153,48 @@ class EmaneNet(CoreNetworkBase):
|
|||
warntxt += "Python bindings failed to load"
|
||||
logging.error(warntxt)
|
||||
|
||||
for netif in self.netifs():
|
||||
for iface in self.get_ifaces():
|
||||
external = self.session.emane.get_config(
|
||||
"external", self.id, self.model.name
|
||||
)
|
||||
if external == "0":
|
||||
netif.setaddrs()
|
||||
iface.setaddrs()
|
||||
|
||||
if not self.session.emane.genlocationevents():
|
||||
netif.poshook = None
|
||||
iface.poshook = None
|
||||
continue
|
||||
|
||||
# at this point we register location handlers for generating
|
||||
# EMANE location events
|
||||
netif.poshook = self.setnemposition
|
||||
netif.setposition()
|
||||
iface.poshook = self.setnemposition
|
||||
iface.setposition()
|
||||
|
||||
def deinstallnetifs(self) -> None:
|
||||
def deinstall_ifaces(self) -> None:
|
||||
"""
|
||||
Uninstall TAP devices. This invokes their shutdown method for
|
||||
any required cleanup; the device may be actually removed when
|
||||
emanetransportd terminates.
|
||||
"""
|
||||
for netif in self.netifs():
|
||||
if netif.transport_type == TransportType.VIRTUAL:
|
||||
netif.shutdown()
|
||||
netif.poshook = None
|
||||
for iface in self.get_ifaces():
|
||||
if iface.transport_type == TransportType.VIRTUAL:
|
||||
iface.shutdown()
|
||||
iface.poshook = None
|
||||
|
||||
def _nem_position(
|
||||
self, netif: CoreInterface
|
||||
self, iface: CoreInterface
|
||||
) -> Optional[Tuple[int, float, float, float]]:
|
||||
"""
|
||||
Creates nem position for emane event for a given interface.
|
||||
|
||||
:param netif: interface to get nem emane position for
|
||||
:param iface: interface to get nem emane position for
|
||||
:return: nem position tuple, None otherwise
|
||||
"""
|
||||
nemid = self.getnemid(netif)
|
||||
ifname = netif.localname
|
||||
nemid = self.getnemid(iface)
|
||||
ifname = iface.localname
|
||||
if nemid is None:
|
||||
logging.info("nemid for %s is unknown", ifname)
|
||||
return
|
||||
node = netif.node
|
||||
node = iface.node
|
||||
x, y, z = node.getposition()
|
||||
lat, lon, alt = self.session.location.getgeo(x, y, z)
|
||||
if node.position.alt is not None:
|
||||
|
@ -210,30 +204,30 @@ class EmaneNet(CoreNetworkBase):
|
|||
alt = int(round(alt))
|
||||
return nemid, lon, lat, alt
|
||||
|
||||
def setnemposition(self, netif: CoreInterface) -> None:
|
||||
def setnemposition(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Publish a NEM location change event using the EMANE event service.
|
||||
|
||||
:param netif: interface to set nem position for
|
||||
:param iface: interface to set nem position for
|
||||
"""
|
||||
if self.session.emane.service is None:
|
||||
logging.info("position service not available")
|
||||
return
|
||||
|
||||
position = self._nem_position(netif)
|
||||
position = self._nem_position(iface)
|
||||
if position:
|
||||
nemid, lon, lat, alt = position
|
||||
event = LocationEvent()
|
||||
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
|
||||
self.session.emane.service.publish(0, event)
|
||||
|
||||
def setnempositions(self, moved_netifs: List[CoreInterface]) -> None:
|
||||
def setnempositions(self, moved_ifaces: List[CoreInterface]) -> None:
|
||||
"""
|
||||
Several NEMs have moved, from e.g. a WaypointMobilityModel
|
||||
calculation. Generate an EMANE Location Event having several
|
||||
entries for each netif that has moved.
|
||||
entries for each interface that has moved.
|
||||
"""
|
||||
if len(moved_netifs) == 0:
|
||||
if len(moved_ifaces) == 0:
|
||||
return
|
||||
|
||||
if self.session.emane.service is None:
|
||||
|
@ -241,8 +235,8 @@ class EmaneNet(CoreNetworkBase):
|
|||
return
|
||||
|
||||
event = LocationEvent()
|
||||
for netif in moved_netifs:
|
||||
position = self._nem_position(netif)
|
||||
for iface in moved_ifaces:
|
||||
position = self._nem_position(iface)
|
||||
if position:
|
||||
nemid, lon, lat, alt = position
|
||||
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
|
||||
|
|
|
@ -27,7 +27,7 @@ class ConfigData:
|
|||
possible_values: str = None
|
||||
groups: str = None
|
||||
session: int = None
|
||||
interface_number: int = None
|
||||
iface_id: int = None
|
||||
network_id: int = None
|
||||
opaque: str = None
|
||||
|
||||
|
@ -114,19 +114,19 @@ class LinkData:
|
|||
emulation_id: int = None
|
||||
network_id: int = None
|
||||
key: int = None
|
||||
interface1_id: int = None
|
||||
interface1_name: str = None
|
||||
interface1_ip4: str = None
|
||||
interface1_ip4_mask: int = None
|
||||
interface1_mac: str = None
|
||||
interface1_ip6: str = None
|
||||
interface1_ip6_mask: int = None
|
||||
interface2_id: int = None
|
||||
interface2_name: str = None
|
||||
interface2_ip4: str = None
|
||||
interface2_ip4_mask: int = None
|
||||
interface2_mac: str = None
|
||||
interface2_ip6: str = None
|
||||
interface2_ip6_mask: int = None
|
||||
iface1_id: int = None
|
||||
iface1_name: str = None
|
||||
iface1_ip4: str = None
|
||||
iface1_ip4_mask: int = None
|
||||
iface1_mac: str = None
|
||||
iface1_ip6: str = None
|
||||
iface1_ip6_mask: int = None
|
||||
iface2_id: int = None
|
||||
iface2_name: str = None
|
||||
iface2_ip4: str = None
|
||||
iface2_ip4_mask: int = None
|
||||
iface2_mac: str = None
|
||||
iface2_ip6: str = None
|
||||
iface2_ip6_mask: int = None
|
||||
opaque: str = None
|
||||
color: str = None
|
||||
|
|
|
@ -208,7 +208,7 @@ class DistributedController:
|
|||
"local tunnel node(%s) to remote(%s) key(%s)", node.name, host, key
|
||||
)
|
||||
local_tap = GreTap(session=self.session, remoteip=host, key=key)
|
||||
local_tap.net_client.set_interface_master(node.brname, local_tap.localname)
|
||||
local_tap.net_client.set_iface_master(node.brname, local_tap.localname)
|
||||
|
||||
# server to local
|
||||
logging.info(
|
||||
|
@ -217,7 +217,7 @@ class DistributedController:
|
|||
remote_tap = GreTap(
|
||||
session=self.session, remoteip=self.address, key=key, server=server
|
||||
)
|
||||
remote_tap.net_client.set_interface_master(node.brname, remote_tap.localname)
|
||||
remote_tap.net_client.set_iface_master(node.brname, remote_tap.localname)
|
||||
|
||||
# save tunnels for shutdown
|
||||
tunnel = (local_tap, remote_tap)
|
||||
|
|
|
@ -155,7 +155,7 @@ class IpPrefixes:
|
|||
raise ValueError("ip6 prefixes have not been set")
|
||||
return str(self.ip6[node_id])
|
||||
|
||||
def gen_interface(self, node_id: int, name: str = None, mac: str = None):
|
||||
def gen_iface(self, node_id: int, name: str = None, mac: str = None):
|
||||
"""
|
||||
Creates interface data for linking nodes, using the nodes unique id for
|
||||
generation, along with a random mac address, unless provided.
|
||||
|
@ -188,7 +188,7 @@ class IpPrefixes:
|
|||
name=name, ip4=ip4, ip4_mask=ip4_mask, ip6=ip6, ip6_mask=ip6_mask, mac=mac
|
||||
)
|
||||
|
||||
def create_interface(
|
||||
def create_iface(
|
||||
self, node: "CoreNode", name: str = None, mac: str = None
|
||||
) -> InterfaceData:
|
||||
"""
|
||||
|
@ -201,6 +201,6 @@ class IpPrefixes:
|
|||
generation
|
||||
:return: new interface data for the provided node
|
||||
"""
|
||||
interface_data = self.gen_interface(node.id, name, mac)
|
||||
interface_data.id = node.newifindex()
|
||||
return interface_data
|
||||
iface_data = self.gen_iface(node.id, name, mac)
|
||||
iface_data.id = node.next_iface_id()
|
||||
return iface_data
|
||||
|
|
|
@ -203,7 +203,7 @@ class Session:
|
|||
common_networks = node1.commonnets(node1)
|
||||
if not common_networks:
|
||||
raise CoreError("no common network found for wireless link/unlink")
|
||||
for common_network, interface1, interface2 in common_networks:
|
||||
for common_network, iface1, iface2 in common_networks:
|
||||
if not isinstance(common_network, (WlanNode, EmaneNet)):
|
||||
logging.info(
|
||||
"skipping common network that is not wireless/emane: %s",
|
||||
|
@ -211,16 +211,16 @@ class Session:
|
|||
)
|
||||
continue
|
||||
if connect:
|
||||
common_network.link(interface1, interface2)
|
||||
common_network.link(iface1, iface2)
|
||||
else:
|
||||
common_network.unlink(interface1, interface2)
|
||||
common_network.unlink(iface1, iface2)
|
||||
|
||||
def add_link(
|
||||
self,
|
||||
node1_id: int,
|
||||
node2_id: int,
|
||||
interface1_data: InterfaceData = None,
|
||||
interface2_data: InterfaceData = None,
|
||||
iface1_data: InterfaceData = None,
|
||||
iface2_data: InterfaceData = None,
|
||||
options: LinkOptions = None,
|
||||
) -> Tuple[CoreInterface, CoreInterface]:
|
||||
"""
|
||||
|
@ -228,9 +228,9 @@ class Session:
|
|||
|
||||
:param node1_id: node one id
|
||||
:param node2_id: node two id
|
||||
:param interface1_data: node one interface
|
||||
:param iface1_data: node one interface
|
||||
data, defaults to none
|
||||
:param interface2_data: node two interface
|
||||
:param iface2_data: node two interface
|
||||
data, defaults to none
|
||||
:param options: data for creating link,
|
||||
defaults to no options
|
||||
|
@ -240,8 +240,8 @@ class Session:
|
|||
options = LinkOptions()
|
||||
node1 = self.get_node(node1_id, NodeBase)
|
||||
node2 = self.get_node(node2_id, NodeBase)
|
||||
interface1 = None
|
||||
interface2 = None
|
||||
iface1 = None
|
||||
iface2 = None
|
||||
|
||||
# wireless link
|
||||
if options.type == LinkTypes.WIRELESS:
|
||||
|
@ -258,22 +258,22 @@ class Session:
|
|||
logging.info("linking ptp: %s - %s", node1.name, node2.name)
|
||||
start = self.state.should_start()
|
||||
ptp = self.create_node(PtpNet, start)
|
||||
interface1 = node1.newnetif(ptp, interface1_data)
|
||||
interface2 = node2.newnetif(ptp, interface2_data)
|
||||
ptp.linkconfig(interface1, options)
|
||||
iface1 = node1.new_iface(ptp, iface1_data)
|
||||
iface2 = node2.new_iface(ptp, iface2_data)
|
||||
ptp.linkconfig(iface1, options)
|
||||
if not options.unidirectional:
|
||||
ptp.linkconfig(interface2, options)
|
||||
ptp.linkconfig(iface2, options)
|
||||
# link node to net
|
||||
elif isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNetworkBase):
|
||||
interface1 = node1.newnetif(node2, interface1_data)
|
||||
iface1 = node1.new_iface(node2, iface1_data)
|
||||
if not isinstance(node2, (EmaneNet, WlanNode)):
|
||||
node2.linkconfig(interface1, options)
|
||||
node2.linkconfig(iface1, options)
|
||||
# link net to node
|
||||
elif isinstance(node2, CoreNodeBase) and isinstance(node1, CoreNetworkBase):
|
||||
interface2 = node2.newnetif(node1, interface2_data)
|
||||
iface2 = node2.new_iface(node1, iface2_data)
|
||||
wireless_net = isinstance(node1, (EmaneNet, WlanNode))
|
||||
if not options.unidirectional and not wireless_net:
|
||||
node1.linkconfig(interface2, options)
|
||||
node1.linkconfig(iface2, options)
|
||||
# network to network
|
||||
elif isinstance(node1, CoreNetworkBase) and isinstance(
|
||||
node2, CoreNetworkBase
|
||||
|
@ -281,12 +281,12 @@ class Session:
|
|||
logging.info(
|
||||
"linking network to network: %s - %s", node1.name, node2.name
|
||||
)
|
||||
interface1 = node1.linknet(node2)
|
||||
node1.linkconfig(interface1, options)
|
||||
iface1 = node1.linknet(node2)
|
||||
node1.linkconfig(iface1, options)
|
||||
if not options.unidirectional:
|
||||
interface1.swapparams("_params_up")
|
||||
node2.linkconfig(interface1, options)
|
||||
interface1.swapparams("_params_up")
|
||||
iface1.swapparams("_params_up")
|
||||
node2.linkconfig(iface1, options)
|
||||
iface1.swapparams("_params_up")
|
||||
else:
|
||||
raise CoreError(
|
||||
f"cannot link node1({type(node1)}) node2({type(node2)})"
|
||||
|
@ -296,19 +296,19 @@ class Session:
|
|||
key = options.key
|
||||
if isinstance(node1, TunnelNode):
|
||||
logging.info("setting tunnel key for: %s", node1.name)
|
||||
node1.setkey(key, interface1_data)
|
||||
node1.setkey(key, iface1_data)
|
||||
if isinstance(node2, TunnelNode):
|
||||
logging.info("setting tunnel key for: %s", node2.name)
|
||||
node2.setkey(key, interface2_data)
|
||||
node2.setkey(key, iface2_data)
|
||||
self.sdt.add_link(node1_id, node2_id)
|
||||
return interface1, interface2
|
||||
return iface1, iface2
|
||||
|
||||
def delete_link(
|
||||
self,
|
||||
node1_id: int,
|
||||
node2_id: int,
|
||||
interface1_id: int = None,
|
||||
interface2_id: int = None,
|
||||
iface1_id: int = None,
|
||||
iface2_id: int = None,
|
||||
link_type: LinkTypes = LinkTypes.WIRED,
|
||||
) -> None:
|
||||
"""
|
||||
|
@ -316,8 +316,8 @@ class Session:
|
|||
|
||||
:param node1_id: node one id
|
||||
:param node2_id: node two id
|
||||
:param interface1_id: interface id for node one
|
||||
:param interface2_id: interface id for node two
|
||||
:param iface1_id: interface id for node one
|
||||
:param iface2_id: interface id for node two
|
||||
:param link_type: link type to delete
|
||||
:return: nothing
|
||||
:raises core.CoreError: when no common network is found for link being deleted
|
||||
|
@ -328,9 +328,9 @@ class Session:
|
|||
"deleting link(%s) node(%s):interface(%s) node(%s):interface(%s)",
|
||||
link_type.name,
|
||||
node1.name,
|
||||
interface1_id,
|
||||
iface1_id,
|
||||
node2.name,
|
||||
interface2_id,
|
||||
iface2_id,
|
||||
)
|
||||
|
||||
# wireless link
|
||||
|
@ -345,37 +345,29 @@ class Session:
|
|||
# wired link
|
||||
else:
|
||||
if isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNodeBase):
|
||||
interface1 = node1.netif(interface1_id)
|
||||
interface2 = node2.netif(interface2_id)
|
||||
if not interface1:
|
||||
raise CoreError(
|
||||
f"node({node1.name}) missing interface({interface1_id})"
|
||||
)
|
||||
if not interface2:
|
||||
raise CoreError(
|
||||
f"node({node2.name}) missing interface({interface2_id})"
|
||||
)
|
||||
if interface1.net != interface2.net:
|
||||
iface1 = node1.get_iface(iface1_id)
|
||||
iface2 = node2.get_iface(iface2_id)
|
||||
if iface1.net != iface2.net:
|
||||
raise CoreError(
|
||||
f"node1({node1.name}) node2({node2.name}) "
|
||||
"not connected to same net"
|
||||
)
|
||||
ptp = interface1.net
|
||||
node1.delnetif(interface1_id)
|
||||
node2.delnetif(interface2_id)
|
||||
ptp = iface1.net
|
||||
node1.delete_iface(iface1_id)
|
||||
node2.delete_iface(iface2_id)
|
||||
self.delete_node(ptp.id)
|
||||
elif isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNetworkBase):
|
||||
node1.delnetif(interface1_id)
|
||||
node1.delete_iface(iface1_id)
|
||||
elif isinstance(node2, CoreNodeBase) and isinstance(node1, CoreNetworkBase):
|
||||
node2.delnetif(interface2_id)
|
||||
node2.delete_iface(iface2_id)
|
||||
self.sdt.delete_link(node1_id, node2_id)
|
||||
|
||||
def update_link(
|
||||
self,
|
||||
node1_id: int,
|
||||
node2_id: int,
|
||||
interface1_id: int = None,
|
||||
interface2_id: int = None,
|
||||
iface1_id: int = None,
|
||||
iface2_id: int = None,
|
||||
options: LinkOptions = None,
|
||||
) -> None:
|
||||
"""
|
||||
|
@ -383,8 +375,8 @@ class Session:
|
|||
|
||||
:param node1_id: node one id
|
||||
:param node2_id: node two id
|
||||
:param interface1_id: interface id for node one
|
||||
:param interface2_id: interface id for node two
|
||||
:param iface1_id: interface id for node one
|
||||
:param iface2_id: interface id for node two
|
||||
:param options: data to update link with
|
||||
:return: nothing
|
||||
:raises core.CoreError: when updating a wireless type link, when there is a
|
||||
|
@ -398,9 +390,9 @@ class Session:
|
|||
"update link(%s) node(%s):interface(%s) node(%s):interface(%s)",
|
||||
options.type.name,
|
||||
node1.name,
|
||||
interface1_id,
|
||||
iface1_id,
|
||||
node2.name,
|
||||
interface2_id,
|
||||
iface2_id,
|
||||
)
|
||||
|
||||
# wireless link
|
||||
|
@ -408,54 +400,54 @@ class Session:
|
|||
raise CoreError("cannot update wireless link")
|
||||
else:
|
||||
if isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNodeBase):
|
||||
interface1 = node1.netif(interface1_id)
|
||||
interface2 = node2.netif(interface2_id)
|
||||
if not interface1:
|
||||
iface1 = node1.ifaces.get(iface1_id)
|
||||
iface2 = node2.ifaces.get(iface2_id)
|
||||
if not iface1:
|
||||
raise CoreError(
|
||||
f"node({node1.name}) missing interface({interface1_id})"
|
||||
f"node({node1.name}) missing interface({iface1_id})"
|
||||
)
|
||||
if not interface2:
|
||||
if not iface2:
|
||||
raise CoreError(
|
||||
f"node({node2.name}) missing interface({interface2_id})"
|
||||
f"node({node2.name}) missing interface({iface2_id})"
|
||||
)
|
||||
if interface1.net != interface2.net:
|
||||
if iface1.net != iface2.net:
|
||||
raise CoreError(
|
||||
f"node1({node1.name}) node2({node2.name}) "
|
||||
"not connected to same net"
|
||||
)
|
||||
ptp = interface1.net
|
||||
ptp.linkconfig(interface1, options, interface2)
|
||||
ptp = iface1.net
|
||||
ptp.linkconfig(iface1, options, iface2)
|
||||
if not options.unidirectional:
|
||||
ptp.linkconfig(interface2, options, interface1)
|
||||
ptp.linkconfig(iface2, options, iface1)
|
||||
elif isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNetworkBase):
|
||||
interface = node1.netif(interface1_id)
|
||||
node2.linkconfig(interface, options)
|
||||
iface = node1.get_iface(iface1_id)
|
||||
node2.linkconfig(iface, options)
|
||||
elif isinstance(node2, CoreNodeBase) and isinstance(node1, CoreNetworkBase):
|
||||
interface = node2.netif(interface2_id)
|
||||
node1.linkconfig(interface, options)
|
||||
iface = node2.get_iface(iface2_id)
|
||||
node1.linkconfig(iface, options)
|
||||
elif isinstance(node1, CoreNetworkBase) and isinstance(
|
||||
node2, CoreNetworkBase
|
||||
):
|
||||
interface = node1.getlinknetif(node2)
|
||||
iface = node1.get_linked_iface(node2)
|
||||
upstream = False
|
||||
if not interface:
|
||||
if not iface:
|
||||
upstream = True
|
||||
interface = node2.getlinknetif(node1)
|
||||
if not interface:
|
||||
iface = node2.get_linked_iface(node1)
|
||||
if not iface:
|
||||
raise CoreError("modify unknown link between nets")
|
||||
if upstream:
|
||||
interface.swapparams("_params_up")
|
||||
node1.linkconfig(interface, options)
|
||||
interface.swapparams("_params_up")
|
||||
iface.swapparams("_params_up")
|
||||
node1.linkconfig(iface, options)
|
||||
iface.swapparams("_params_up")
|
||||
else:
|
||||
node1.linkconfig(interface, options)
|
||||
node1.linkconfig(iface, options)
|
||||
if not options.unidirectional:
|
||||
if upstream:
|
||||
node2.linkconfig(interface, options)
|
||||
node2.linkconfig(iface, options)
|
||||
else:
|
||||
interface.swapparams("_params_up")
|
||||
node2.linkconfig(interface, options)
|
||||
interface.swapparams("_params_up")
|
||||
iface.swapparams("_params_up")
|
||||
node2.linkconfig(iface, options)
|
||||
iface.swapparams("_params_up")
|
||||
else:
|
||||
raise CoreError(
|
||||
f"cannot update link node1({type(node1)}) node2({type(node2)})"
|
||||
|
@ -553,7 +545,7 @@ class Session:
|
|||
is_boot_node = isinstance(node, CoreNodeBase) and not isinstance(node, Rj45Node)
|
||||
if self.state == EventTypes.RUNTIME_STATE and is_boot_node:
|
||||
self.write_nodes()
|
||||
self.add_remove_control_interface(node=node, remove=False)
|
||||
self.add_remove_control_iface(node=node, remove=False)
|
||||
self.services.boot_services(node)
|
||||
|
||||
self.sdt.add_node(node)
|
||||
|
@ -1268,7 +1260,7 @@ class Session:
|
|||
self.emane.shutdown()
|
||||
|
||||
# update control interface hosts
|
||||
self.update_control_interface_hosts(remove=True)
|
||||
self.update_control_iface_hosts(remove=True)
|
||||
|
||||
# remove all four possible control networks
|
||||
self.add_remove_control_net(0, remove=True)
|
||||
|
@ -1314,7 +1306,7 @@ class Session:
|
|||
:return: nothing
|
||||
"""
|
||||
logging.info("booting node(%s): %s", node.name, [x.name for x in node.services])
|
||||
self.add_remove_control_interface(node=node, remove=False)
|
||||
self.add_remove_control_iface(node=node, remove=False)
|
||||
self.services.boot_services(node)
|
||||
node.start_config_services()
|
||||
|
||||
|
@ -1338,7 +1330,7 @@ class Session:
|
|||
total = time.monotonic() - start
|
||||
logging.debug("boot run time: %s", total)
|
||||
if not exceptions:
|
||||
self.update_control_interface_hosts()
|
||||
self.update_control_iface_hosts()
|
||||
return exceptions
|
||||
|
||||
def get_control_net_prefixes(self) -> List[str]:
|
||||
|
@ -1356,7 +1348,7 @@ class Session:
|
|||
p0 = p
|
||||
return [p0, p1, p2, p3]
|
||||
|
||||
def get_control_net_server_interfaces(self) -> List[str]:
|
||||
def get_control_net_server_ifaces(self) -> List[str]:
|
||||
"""
|
||||
Retrieve control net server interfaces.
|
||||
|
||||
|
@ -1424,7 +1416,7 @@ class Session:
|
|||
else:
|
||||
prefix_spec = CtrlNet.DEFAULT_PREFIX_LIST[net_index]
|
||||
logging.debug("prefix spec: %s", prefix_spec)
|
||||
server_interface = self.get_control_net_server_interfaces()[net_index]
|
||||
server_iface = self.get_control_net_server_ifaces()[net_index]
|
||||
|
||||
# return any existing controlnet bridge
|
||||
try:
|
||||
|
@ -1465,7 +1457,7 @@ class Session:
|
|||
_id,
|
||||
prefix,
|
||||
updown_script,
|
||||
server_interface,
|
||||
server_iface,
|
||||
)
|
||||
control_net = self.create_node(
|
||||
CtrlNet,
|
||||
|
@ -1473,11 +1465,11 @@ class Session:
|
|||
prefix,
|
||||
_id=_id,
|
||||
updown_script=updown_script,
|
||||
serverintf=server_interface,
|
||||
serverintf=server_iface,
|
||||
)
|
||||
return control_net
|
||||
|
||||
def add_remove_control_interface(
|
||||
def add_remove_control_iface(
|
||||
self,
|
||||
node: CoreNode,
|
||||
net_index: int = 0,
|
||||
|
@ -1503,27 +1495,27 @@ class Session:
|
|||
if not node:
|
||||
return
|
||||
# ctrl# already exists
|
||||
if node.netif(control_net.CTRLIF_IDX_BASE + net_index):
|
||||
if node.ifaces.get(control_net.CTRLIF_IDX_BASE + net_index):
|
||||
return
|
||||
try:
|
||||
ip4 = control_net.prefix[node.id]
|
||||
ip4_mask = control_net.prefix.prefixlen
|
||||
interface_data = InterfaceData(
|
||||
iface_data = InterfaceData(
|
||||
id=control_net.CTRLIF_IDX_BASE + net_index,
|
||||
name=f"ctrl{net_index}",
|
||||
mac=utils.random_mac(),
|
||||
ip4=ip4,
|
||||
ip4_mask=ip4_mask,
|
||||
)
|
||||
interface = node.newnetif(control_net, interface_data)
|
||||
interface.control = True
|
||||
iface = node.new_iface(control_net, iface_data)
|
||||
iface.control = True
|
||||
except ValueError:
|
||||
msg = f"Control interface not added to node {node.id}. "
|
||||
msg += f"Invalid control network prefix ({control_net.prefix}). "
|
||||
msg += "A longer prefix length may be required for this many nodes."
|
||||
logging.exception(msg)
|
||||
|
||||
def update_control_interface_hosts(
|
||||
def update_control_iface_hosts(
|
||||
self, net_index: int = 0, remove: bool = False
|
||||
) -> None:
|
||||
"""
|
||||
|
@ -1549,9 +1541,9 @@ class Session:
|
|||
return
|
||||
|
||||
entries = []
|
||||
for interface in control_net.netifs():
|
||||
name = interface.node.name
|
||||
for address in interface.addrlist:
|
||||
for iface in control_net.get_ifaces():
|
||||
name = iface.node.name
|
||||
for address in iface.addrlist:
|
||||
address = address.split("/")[0]
|
||||
entries.append(f"{address} {name}")
|
||||
|
||||
|
|
|
@ -57,8 +57,8 @@ class CoreClient:
|
|||
self.read_config()
|
||||
|
||||
# helpers
|
||||
self.interface_to_edge = {}
|
||||
self.interfaces_manager = InterfaceManager(self.app)
|
||||
self.iface_to_edge = {}
|
||||
self.ifaces_manager = InterfaceManager(self.app)
|
||||
|
||||
# session data
|
||||
self.state = None
|
||||
|
@ -91,8 +91,8 @@ class CoreClient:
|
|||
|
||||
def reset(self):
|
||||
# helpers
|
||||
self.interfaces_manager.reset()
|
||||
self.interface_to_edge.clear()
|
||||
self.ifaces_manager.reset()
|
||||
self.iface_to_edge.clear()
|
||||
# session data
|
||||
self.canvas_nodes.clear()
|
||||
self.links.clear()
|
||||
|
@ -263,7 +263,7 @@ class CoreClient:
|
|||
self.emane_config = response.config
|
||||
|
||||
# update interface manager
|
||||
self.interfaces_manager.joined(session.links)
|
||||
self.ifaces_manager.joined(session.links)
|
||||
|
||||
# draw session
|
||||
self.app.canvas.reset_and_redraw(session)
|
||||
|
@ -278,11 +278,11 @@ class CoreClient:
|
|||
# get emane model config
|
||||
response = self.client.get_emane_model_configs(self.session_id)
|
||||
for config in response.configs:
|
||||
interface = None
|
||||
if config.interface != -1:
|
||||
interface = config.interface
|
||||
iface_id = None
|
||||
if config.iface_id != -1:
|
||||
iface_id = config.iface_id
|
||||
canvas_node = self.canvas_nodes[config.node_id]
|
||||
canvas_node.emane_model_configs[(config.model, interface)] = dict(
|
||||
canvas_node.emane_model_configs[(config.model, iface_id)] = dict(
|
||||
config.config
|
||||
)
|
||||
|
||||
|
@ -460,16 +460,16 @@ class CoreClient:
|
|||
self.app.show_grpc_exception("Edit Node Error", e)
|
||||
|
||||
def start_session(self) -> core_pb2.StartSessionResponse:
|
||||
self.interfaces_manager.reset_mac()
|
||||
self.ifaces_manager.reset_mac()
|
||||
nodes = [x.core_node for x in self.canvas_nodes.values()]
|
||||
links = []
|
||||
for edge in self.links.values():
|
||||
link = core_pb2.Link()
|
||||
link.CopyFrom(edge.link)
|
||||
if link.HasField("interface1") and not link.interface1.mac:
|
||||
link.interface1.mac = self.interfaces_manager.next_mac()
|
||||
if link.HasField("interface2") and not link.interface2.mac:
|
||||
link.interface2.mac = self.interfaces_manager.next_mac()
|
||||
if link.HasField("iface1") and not link.iface1.mac:
|
||||
link.iface1.mac = self.ifaces_manager.next_mac()
|
||||
if link.HasField("iface2") and not link.iface2.mac:
|
||||
link.iface2.mac = self.ifaces_manager.next_mac()
|
||||
links.append(link)
|
||||
wlan_configs = self.get_wlan_configs_proto()
|
||||
mobility_configs = self.get_mobility_configs_proto()
|
||||
|
@ -689,8 +689,8 @@ class CoreClient:
|
|||
self.session_id,
|
||||
link_proto.node1_id,
|
||||
link_proto.node2_id,
|
||||
link_proto.interface1,
|
||||
link_proto.interface2,
|
||||
link_proto.iface1,
|
||||
link_proto.iface2,
|
||||
link_proto.options,
|
||||
)
|
||||
logging.debug("create link: %s", response)
|
||||
|
@ -733,7 +733,7 @@ class CoreClient:
|
|||
config_proto.node_id,
|
||||
config_proto.model,
|
||||
config_proto.config,
|
||||
config_proto.interface_id,
|
||||
config_proto.iface_id,
|
||||
)
|
||||
if self.emane_config:
|
||||
config = {x: self.emane_config[x].value for x in self.emane_config}
|
||||
|
@ -824,31 +824,26 @@ class CoreClient:
|
|||
for edge in edges:
|
||||
del self.links[edge.token]
|
||||
links.append(edge.link)
|
||||
self.interfaces_manager.removed(links)
|
||||
self.ifaces_manager.removed(links)
|
||||
|
||||
def create_interface(self, canvas_node: CanvasNode) -> core_pb2.Interface:
|
||||
def create_iface(self, canvas_node: CanvasNode) -> core_pb2.Interface:
|
||||
node = canvas_node.core_node
|
||||
ip4, ip6 = self.interfaces_manager.get_ips(node)
|
||||
ip4_mask = self.interfaces_manager.ip4_mask
|
||||
ip6_mask = self.interfaces_manager.ip6_mask
|
||||
interface_id = canvas_node.next_interface_id()
|
||||
name = f"eth{interface_id}"
|
||||
interface = core_pb2.Interface(
|
||||
id=interface_id,
|
||||
name=name,
|
||||
ip4=ip4,
|
||||
ip4mask=ip4_mask,
|
||||
ip6=ip6,
|
||||
ip6mask=ip6_mask,
|
||||
ip4, ip6 = self.ifaces_manager.get_ips(node)
|
||||
ip4_mask = self.ifaces_manager.ip4_mask
|
||||
ip6_mask = self.ifaces_manager.ip6_mask
|
||||
iface_id = canvas_node.next_iface_id()
|
||||
name = f"eth{iface_id}"
|
||||
iface = core_pb2.Interface(
|
||||
id=iface_id, name=name, ip4=ip4, ip4mask=ip4_mask, ip6=ip6, ip6mask=ip6_mask
|
||||
)
|
||||
logging.info(
|
||||
"create node(%s) interface(%s) IPv4(%s) IPv6(%s)",
|
||||
node.name,
|
||||
interface.name,
|
||||
interface.ip4,
|
||||
interface.ip6,
|
||||
iface.name,
|
||||
iface.ip4,
|
||||
iface.ip6,
|
||||
)
|
||||
return interface
|
||||
return iface
|
||||
|
||||
def create_link(
|
||||
self, edge: CanvasEdge, canvas_src_node: CanvasNode, canvas_dst_node: CanvasNode
|
||||
|
@ -861,34 +856,34 @@ class CoreClient:
|
|||
dst_node = canvas_dst_node.core_node
|
||||
|
||||
# determine subnet
|
||||
self.interfaces_manager.determine_subnets(canvas_src_node, canvas_dst_node)
|
||||
self.ifaces_manager.determine_subnets(canvas_src_node, canvas_dst_node)
|
||||
|
||||
src_interface = None
|
||||
src_iface = None
|
||||
if NodeUtils.is_container_node(src_node.type):
|
||||
src_interface = self.create_interface(canvas_src_node)
|
||||
self.interface_to_edge[(src_node.id, src_interface.id)] = edge.token
|
||||
src_iface = self.create_iface(canvas_src_node)
|
||||
self.iface_to_edge[(src_node.id, src_iface.id)] = edge.token
|
||||
|
||||
dst_interface = None
|
||||
dst_iface = None
|
||||
if NodeUtils.is_container_node(dst_node.type):
|
||||
dst_interface = self.create_interface(canvas_dst_node)
|
||||
self.interface_to_edge[(dst_node.id, dst_interface.id)] = edge.token
|
||||
dst_iface = self.create_iface(canvas_dst_node)
|
||||
self.iface_to_edge[(dst_node.id, dst_iface.id)] = edge.token
|
||||
|
||||
link = core_pb2.Link(
|
||||
type=core_pb2.LinkType.WIRED,
|
||||
node1_id=src_node.id,
|
||||
node2_id=dst_node.id,
|
||||
interface1=src_interface,
|
||||
interface2=dst_interface,
|
||||
iface1=src_iface,
|
||||
iface2=dst_iface,
|
||||
)
|
||||
# assign after creating link proto, since interfaces are copied
|
||||
if src_interface:
|
||||
interface1 = link.interface1
|
||||
edge.src_interface = interface1
|
||||
canvas_src_node.interfaces[interface1.id] = interface1
|
||||
if dst_interface:
|
||||
interface2 = link.interface2
|
||||
edge.dst_interface = interface2
|
||||
canvas_dst_node.interfaces[interface2.id] = interface2
|
||||
if src_iface:
|
||||
iface1 = link.iface1
|
||||
edge.src_iface = iface1
|
||||
canvas_src_node.ifaces[iface1.id] = iface1
|
||||
if dst_iface:
|
||||
iface2 = link.iface2
|
||||
edge.dst_iface = iface2
|
||||
canvas_dst_node.ifaces[iface2.id] = iface2
|
||||
edge.set_link(link)
|
||||
self.links[edge.token] = edge
|
||||
logging.info("Add link between %s and %s", src_node.name, dst_node.name)
|
||||
|
@ -928,12 +923,12 @@ class CoreClient:
|
|||
continue
|
||||
node_id = canvas_node.core_node.id
|
||||
for key, config in canvas_node.emane_model_configs.items():
|
||||
model, interface = key
|
||||
model, iface_id = key
|
||||
config = {x: config[x].value for x in config}
|
||||
if interface is None:
|
||||
interface = -1
|
||||
if iface_id is None:
|
||||
iface_id = -1
|
||||
config_proto = EmaneModelConfig(
|
||||
node_id=node_id, interface_id=interface, model=model, config=config
|
||||
node_id=node_id, iface_id=iface_id, model=model, config=config
|
||||
)
|
||||
configs.append(config_proto)
|
||||
return configs
|
||||
|
@ -1021,19 +1016,19 @@ class CoreClient:
|
|||
return dict(config)
|
||||
|
||||
def get_emane_model_config(
|
||||
self, node_id: int, model: str, interface: int = None
|
||||
self, node_id: int, model: str, iface_id: int = None
|
||||
) -> Dict[str, common_pb2.ConfigOption]:
|
||||
if interface is None:
|
||||
interface = -1
|
||||
if iface_id is None:
|
||||
iface_id = -1
|
||||
response = self.client.get_emane_model_config(
|
||||
self.session_id, node_id, model, interface
|
||||
self.session_id, node_id, model, iface_id
|
||||
)
|
||||
config = response.config
|
||||
logging.debug(
|
||||
"get emane model config: node id: %s, EMANE model: %s, interface: %s, config: %s",
|
||||
node_id,
|
||||
model,
|
||||
interface,
|
||||
iface_id,
|
||||
config,
|
||||
)
|
||||
return dict(config)
|
||||
|
|
|
@ -56,7 +56,7 @@ class EmaneModelDialog(Dialog):
|
|||
app: "Application",
|
||||
canvas_node: "CanvasNode",
|
||||
model: str,
|
||||
interface: int = None,
|
||||
iface_id: int = None,
|
||||
):
|
||||
super().__init__(
|
||||
app, f"{canvas_node.core_node.name} {model} Configuration", master=master
|
||||
|
@ -64,16 +64,16 @@ class EmaneModelDialog(Dialog):
|
|||
self.canvas_node = canvas_node
|
||||
self.node = canvas_node.core_node
|
||||
self.model = f"emane_{model}"
|
||||
self.interface = interface
|
||||
self.iface_id = iface_id
|
||||
self.config_frame = None
|
||||
self.has_error = False
|
||||
try:
|
||||
self.config = self.canvas_node.emane_model_configs.get(
|
||||
(self.model, self.interface)
|
||||
(self.model, self.iface_id)
|
||||
)
|
||||
if not self.config:
|
||||
self.config = self.app.core.get_emane_model_config(
|
||||
self.node.id, self.model, self.interface
|
||||
self.node.id, self.model, self.iface_id
|
||||
)
|
||||
self.draw()
|
||||
except grpc.RpcError as e:
|
||||
|
@ -103,7 +103,7 @@ class EmaneModelDialog(Dialog):
|
|||
|
||||
def click_apply(self):
|
||||
self.config_frame.parse_config()
|
||||
key = (self.model, self.interface)
|
||||
key = (self.model, self.iface_id)
|
||||
self.canvas_node.emane_model_configs[key] = self.config
|
||||
self.destroy()
|
||||
|
||||
|
|
|
@ -146,6 +146,6 @@ class IpConfigDialog(Dialog):
|
|||
ip_config.ip6 = self.ip6
|
||||
ip_config.ip4s = ip4s
|
||||
ip_config.ip6s = ip6s
|
||||
self.app.core.interfaces_manager.update_ips(self.ip4, self.ip6)
|
||||
self.app.core.ifaces_manager.update_ips(self.ip4, self.ip6)
|
||||
self.app.save_config()
|
||||
self.destroy()
|
||||
|
|
|
@ -227,21 +227,21 @@ class LinkConfigurationDialog(Dialog):
|
|||
)
|
||||
link.options.CopyFrom(options)
|
||||
|
||||
interface1_id = None
|
||||
if link.HasField("interface1"):
|
||||
interface1_id = link.interface1.id
|
||||
interface2_id = None
|
||||
if link.HasField("interface2"):
|
||||
interface2_id = link.interface2.id
|
||||
iface1_id = None
|
||||
if link.HasField("iface1"):
|
||||
iface1_id = link.iface1.id
|
||||
iface2_id = None
|
||||
if link.HasField("iface2"):
|
||||
iface2_id = link.iface2.id
|
||||
|
||||
if not self.is_symmetric:
|
||||
link.options.unidirectional = True
|
||||
asym_interface1 = None
|
||||
if interface1_id:
|
||||
asym_interface1 = core_pb2.Interface(id=interface1_id)
|
||||
asym_interface2 = None
|
||||
if interface2_id:
|
||||
asym_interface2 = core_pb2.Interface(id=interface2_id)
|
||||
asym_iface1 = None
|
||||
if iface1_id:
|
||||
asym_iface1 = core_pb2.Interface(id=iface1_id)
|
||||
asym_iface2 = None
|
||||
if iface2_id:
|
||||
asym_iface2 = core_pb2.Interface(id=iface2_id)
|
||||
down_bandwidth = get_int(self.down_bandwidth)
|
||||
down_jitter = get_int(self.down_jitter)
|
||||
down_delay = get_int(self.down_delay)
|
||||
|
@ -258,8 +258,8 @@ class LinkConfigurationDialog(Dialog):
|
|||
self.edge.asymmetric_link = core_pb2.Link(
|
||||
node1_id=link.node2_id,
|
||||
node2_id=link.node1_id,
|
||||
interface1=asym_interface1,
|
||||
interface2=asym_interface2,
|
||||
iface1=asym_iface1,
|
||||
iface2=asym_iface2,
|
||||
options=options,
|
||||
)
|
||||
else:
|
||||
|
@ -273,8 +273,8 @@ class LinkConfigurationDialog(Dialog):
|
|||
link.node1_id,
|
||||
link.node2_id,
|
||||
link.options,
|
||||
interface1_id,
|
||||
interface2_id,
|
||||
iface1_id,
|
||||
iface2_id,
|
||||
)
|
||||
if self.edge.asymmetric_link:
|
||||
self.app.core.client.edit_link(
|
||||
|
@ -282,8 +282,8 @@ class LinkConfigurationDialog(Dialog):
|
|||
link.node2_id,
|
||||
link.node1_id,
|
||||
self.edge.asymmetric_link.options,
|
||||
interface1_id,
|
||||
interface2_id,
|
||||
iface1_id,
|
||||
iface2_id,
|
||||
)
|
||||
|
||||
self.destroy()
|
||||
|
|
|
@ -55,7 +55,7 @@ class MacConfigDialog(Dialog):
|
|||
if not netaddr.valid_mac(mac):
|
||||
messagebox.showerror("MAC Error", f"{mac} is an invalid mac")
|
||||
else:
|
||||
self.app.core.interfaces_manager.mac = netaddr.EUI(mac)
|
||||
self.app.core.ifaces_manager.mac = netaddr.EUI(mac)
|
||||
self.app.guiconfig.mac = mac
|
||||
self.app.save_config()
|
||||
self.destroy()
|
||||
|
|
|
@ -111,7 +111,7 @@ class NodeConfigDialog(Dialog):
|
|||
if self.node.server:
|
||||
server = self.node.server
|
||||
self.server = tk.StringVar(value=server)
|
||||
self.interfaces = {}
|
||||
self.ifaces = {}
|
||||
self.draw()
|
||||
|
||||
def draw(self):
|
||||
|
@ -183,53 +183,53 @@ class NodeConfigDialog(Dialog):
|
|||
row += 1
|
||||
|
||||
if NodeUtils.is_rj45_node(self.node.type):
|
||||
response = self.app.core.client.get_interfaces()
|
||||
response = self.app.core.client.get_ifaces()
|
||||
logging.debug("host machine available interfaces: %s", response)
|
||||
interfaces = ListboxScroll(frame)
|
||||
interfaces.listbox.config(state=state)
|
||||
interfaces.grid(
|
||||
ifaces = ListboxScroll(frame)
|
||||
ifaces.listbox.config(state=state)
|
||||
ifaces.grid(
|
||||
row=row, column=0, columnspan=2, sticky="ew", padx=PADX, pady=PADY
|
||||
)
|
||||
for inf in sorted(response.interfaces[:]):
|
||||
interfaces.listbox.insert(tk.END, inf)
|
||||
for inf in sorted(response.ifaces[:]):
|
||||
ifaces.listbox.insert(tk.END, inf)
|
||||
row += 1
|
||||
interfaces.listbox.bind("<<ListboxSelect>>", self.interface_select)
|
||||
ifaces.listbox.bind("<<ListboxSelect>>", self.iface_select)
|
||||
|
||||
# interfaces
|
||||
if self.canvas_node.interfaces:
|
||||
self.draw_interfaces()
|
||||
if self.canvas_node.ifaces:
|
||||
self.draw_ifaces()
|
||||
|
||||
self.draw_spacer()
|
||||
self.draw_buttons()
|
||||
|
||||
def draw_interfaces(self):
|
||||
def draw_ifaces(self):
|
||||
notebook = ttk.Notebook(self.top)
|
||||
notebook.grid(sticky="nsew", pady=PADY)
|
||||
self.top.rowconfigure(notebook.grid_info()["row"], weight=1)
|
||||
state = tk.DISABLED if self.app.core.is_runtime() else tk.NORMAL
|
||||
for interface_id in sorted(self.canvas_node.interfaces):
|
||||
interface = self.canvas_node.interfaces[interface_id]
|
||||
for iface_id in sorted(self.canvas_node.ifaces):
|
||||
iface = self.canvas_node.ifaces[iface_id]
|
||||
tab = ttk.Frame(notebook, padding=FRAME_PAD)
|
||||
tab.grid(sticky="nsew", pady=PADY)
|
||||
tab.columnconfigure(1, weight=1)
|
||||
tab.columnconfigure(2, weight=1)
|
||||
notebook.add(tab, text=interface.name)
|
||||
notebook.add(tab, text=iface.name)
|
||||
|
||||
row = 0
|
||||
emane_node = self.canvas_node.has_emane_link(interface.id)
|
||||
emane_node = self.canvas_node.has_emane_link(iface.id)
|
||||
if emane_node:
|
||||
emane_model = emane_node.emane.split("_")[1]
|
||||
button = ttk.Button(
|
||||
tab,
|
||||
text=f"Configure EMANE {emane_model}",
|
||||
command=lambda: self.click_emane_config(emane_model, interface.id),
|
||||
command=lambda: self.click_emane_config(emane_model, iface.id),
|
||||
)
|
||||
button.grid(row=row, sticky="ew", columnspan=3, pady=PADY)
|
||||
row += 1
|
||||
|
||||
label = ttk.Label(tab, text="MAC")
|
||||
label.grid(row=row, column=0, padx=PADX, pady=PADY)
|
||||
auto_set = not interface.mac
|
||||
auto_set = not iface.mac
|
||||
mac_state = tk.DISABLED if auto_set else tk.NORMAL
|
||||
is_auto = tk.BooleanVar(value=auto_set)
|
||||
checkbutton = ttk.Checkbutton(
|
||||
|
@ -237,7 +237,7 @@ class NodeConfigDialog(Dialog):
|
|||
)
|
||||
checkbutton.var = is_auto
|
||||
checkbutton.grid(row=row, column=1, padx=PADX)
|
||||
mac = tk.StringVar(value=interface.mac)
|
||||
mac = tk.StringVar(value=iface.mac)
|
||||
entry = ttk.Entry(tab, textvariable=mac, state=mac_state)
|
||||
entry.grid(row=row, column=2, sticky="ew")
|
||||
func = partial(mac_auto, is_auto, entry, mac)
|
||||
|
@ -247,8 +247,8 @@ class NodeConfigDialog(Dialog):
|
|||
label = ttk.Label(tab, text="IPv4")
|
||||
label.grid(row=row, column=0, padx=PADX, pady=PADY)
|
||||
ip4_net = ""
|
||||
if interface.ip4:
|
||||
ip4_net = f"{interface.ip4}/{interface.ip4mask}"
|
||||
if iface.ip4:
|
||||
ip4_net = f"{iface.ip4}/{iface.ip4mask}"
|
||||
ip4 = tk.StringVar(value=ip4_net)
|
||||
entry = ttk.Entry(tab, textvariable=ip4, state=state)
|
||||
entry.grid(row=row, column=1, columnspan=2, sticky="ew")
|
||||
|
@ -257,13 +257,13 @@ class NodeConfigDialog(Dialog):
|
|||
label = ttk.Label(tab, text="IPv6")
|
||||
label.grid(row=row, column=0, padx=PADX, pady=PADY)
|
||||
ip6_net = ""
|
||||
if interface.ip6:
|
||||
ip6_net = f"{interface.ip6}/{interface.ip6mask}"
|
||||
if iface.ip6:
|
||||
ip6_net = f"{iface.ip6}/{iface.ip6mask}"
|
||||
ip6 = tk.StringVar(value=ip6_net)
|
||||
entry = ttk.Entry(tab, textvariable=ip6, state=state)
|
||||
entry.grid(row=row, column=1, columnspan=2, sticky="ew")
|
||||
|
||||
self.interfaces[interface.id] = InterfaceData(is_auto, mac, ip4, ip6)
|
||||
self.ifaces[iface.id] = InterfaceData(is_auto, mac, ip4, ip6)
|
||||
|
||||
def draw_buttons(self):
|
||||
frame = ttk.Frame(self.top)
|
||||
|
@ -277,9 +277,9 @@ class NodeConfigDialog(Dialog):
|
|||
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
||||
button.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
def click_emane_config(self, emane_model: str, interface_id: int):
|
||||
def click_emane_config(self, emane_model: str, iface_id: int):
|
||||
dialog = EmaneModelDialog(
|
||||
self, self.app, self.canvas_node, emane_model, interface_id
|
||||
self, self.app, self.canvas_node, emane_model, iface_id
|
||||
)
|
||||
dialog.show()
|
||||
|
||||
|
@ -309,12 +309,12 @@ class NodeConfigDialog(Dialog):
|
|||
self.canvas_node.image = self.image
|
||||
|
||||
# update node interface data
|
||||
for interface in self.canvas_node.interfaces.values():
|
||||
data = self.interfaces[interface.id]
|
||||
for iface in self.canvas_node.ifaces.values():
|
||||
data = self.ifaces[iface.id]
|
||||
|
||||
# validate ip4
|
||||
ip4_net = data.ip4.get()
|
||||
if not check_ip4(self, interface.name, ip4_net):
|
||||
if not check_ip4(self, iface.name, ip4_net):
|
||||
error = True
|
||||
break
|
||||
if ip4_net:
|
||||
|
@ -322,12 +322,12 @@ class NodeConfigDialog(Dialog):
|
|||
ip4mask = int(ip4mask)
|
||||
else:
|
||||
ip4, ip4mask = "", 0
|
||||
interface.ip4 = ip4
|
||||
interface.ip4mask = ip4mask
|
||||
iface.ip4 = ip4
|
||||
iface.ip4mask = ip4mask
|
||||
|
||||
# validate ip6
|
||||
ip6_net = data.ip6.get()
|
||||
if not check_ip6(self, interface.name, ip6_net):
|
||||
if not check_ip6(self, iface.name, ip6_net):
|
||||
error = True
|
||||
break
|
||||
if ip6_net:
|
||||
|
@ -335,28 +335,28 @@ class NodeConfigDialog(Dialog):
|
|||
ip6mask = int(ip6mask)
|
||||
else:
|
||||
ip6, ip6mask = "", 0
|
||||
interface.ip6 = ip6
|
||||
interface.ip6mask = ip6mask
|
||||
iface.ip6 = ip6
|
||||
iface.ip6mask = ip6mask
|
||||
|
||||
mac = data.mac.get()
|
||||
auto_mac = data.is_auto.get()
|
||||
if not auto_mac and not netaddr.valid_mac(mac):
|
||||
title = f"MAC Error for {interface.name}"
|
||||
title = f"MAC Error for {iface.name}"
|
||||
messagebox.showerror(title, "Invalid MAC Address")
|
||||
error = True
|
||||
break
|
||||
elif not auto_mac:
|
||||
mac = netaddr.EUI(mac, dialect=netaddr.mac_unix_expanded)
|
||||
interface.mac = str(mac)
|
||||
iface.mac = str(mac)
|
||||
|
||||
# redraw
|
||||
if not error:
|
||||
self.canvas_node.redraw()
|
||||
self.destroy()
|
||||
|
||||
def interface_select(self, event: tk.Event):
|
||||
def iface_select(self, event: tk.Event):
|
||||
listbox = event.widget
|
||||
cur = listbox.curselection()
|
||||
if cur:
|
||||
interface = listbox.get(cur[0])
|
||||
self.name.set(interface)
|
||||
iface = listbox.get(cur[0])
|
||||
self.name.set(iface)
|
||||
|
|
|
@ -259,8 +259,8 @@ class CanvasEdge(Edge):
|
|||
Create an instance of canvas edge object
|
||||
"""
|
||||
super().__init__(canvas, src)
|
||||
self.src_interface = None
|
||||
self.dst_interface = None
|
||||
self.src_iface = None
|
||||
self.dst_iface = None
|
||||
self.text_src = None
|
||||
self.text_dst = None
|
||||
self.link = None
|
||||
|
@ -283,25 +283,25 @@ class CanvasEdge(Edge):
|
|||
self.link = link
|
||||
self.draw_labels()
|
||||
|
||||
def interface_label(self, interface: core_pb2.Interface) -> str:
|
||||
def iface_label(self, iface: core_pb2.Interface) -> str:
|
||||
label = ""
|
||||
if interface.name and self.canvas.show_interface_names.get():
|
||||
label = f"{interface.name}"
|
||||
if interface.ip4 and self.canvas.show_ip4s.get():
|
||||
if iface.name and self.canvas.show_iface_names.get():
|
||||
label = f"{iface.name}"
|
||||
if iface.ip4 and self.canvas.show_ip4s.get():
|
||||
label = f"{label}\n" if label else ""
|
||||
label += f"{interface.ip4}/{interface.ip4mask}"
|
||||
if interface.ip6 and self.canvas.show_ip6s.get():
|
||||
label += f"{iface.ip4}/{iface.ip4mask}"
|
||||
if iface.ip6 and self.canvas.show_ip6s.get():
|
||||
label = f"{label}\n" if label else ""
|
||||
label += f"{interface.ip6}/{interface.ip6mask}"
|
||||
label += f"{iface.ip6}/{iface.ip6mask}"
|
||||
return label
|
||||
|
||||
def create_node_labels(self) -> Tuple[str, str]:
|
||||
label1 = None
|
||||
if self.link.HasField("interface1"):
|
||||
label1 = self.interface_label(self.link.interface1)
|
||||
if self.link.HasField("iface1"):
|
||||
label1 = self.iface_label(self.link.iface1)
|
||||
label2 = None
|
||||
if self.link.HasField("interface2"):
|
||||
label2 = self.interface_label(self.link.interface2)
|
||||
if self.link.HasField("iface2"):
|
||||
label2 = self.iface_label(self.link.iface2)
|
||||
return label1, label2
|
||||
|
||||
def draw_labels(self) -> None:
|
||||
|
|
|
@ -97,7 +97,7 @@ class CanvasGraph(tk.Canvas):
|
|||
self.show_link_labels = ShowVar(self, tags.LINK_LABEL, value=True)
|
||||
self.show_grid = ShowVar(self, tags.GRIDLINE, value=True)
|
||||
self.show_annotations = ShowVar(self, tags.ANNOTATION, value=True)
|
||||
self.show_interface_names = BooleanVar(value=False)
|
||||
self.show_iface_names = BooleanVar(value=False)
|
||||
self.show_ip4s = BooleanVar(value=True)
|
||||
self.show_ip6s = BooleanVar(value=True)
|
||||
|
||||
|
@ -136,7 +136,7 @@ class CanvasGraph(tk.Canvas):
|
|||
self.show_link_labels.set(True)
|
||||
self.show_grid.set(True)
|
||||
self.show_annotations.set(True)
|
||||
self.show_interface_names.set(False)
|
||||
self.show_iface_names.set(False)
|
||||
self.show_ip4s.set(True)
|
||||
self.show_ip6s.set(True)
|
||||
|
||||
|
@ -195,19 +195,19 @@ class CanvasGraph(tk.Canvas):
|
|||
return valid_topleft and valid_bottomright
|
||||
|
||||
def set_throughputs(self, throughputs_event: core_pb2.ThroughputsEvent):
|
||||
for interface_throughput in throughputs_event.interface_throughputs:
|
||||
node_id = interface_throughput.node_id
|
||||
interface_id = interface_throughput.interface_id
|
||||
throughput = interface_throughput.throughput
|
||||
interface_to_edge_id = (node_id, interface_id)
|
||||
token = self.core.interface_to_edge.get(interface_to_edge_id)
|
||||
for iface_throughput in throughputs_event.iface_throughputs:
|
||||
node_id = iface_throughput.node_id
|
||||
iface_id = iface_throughput.iface_id
|
||||
throughput = iface_throughput.throughput
|
||||
iface_to_edge_id = (node_id, iface_id)
|
||||
token = self.core.iface_to_edge.get(iface_to_edge_id)
|
||||
if not token:
|
||||
continue
|
||||
edge = self.edges.get(token)
|
||||
if edge:
|
||||
edge.set_throughput(throughput)
|
||||
else:
|
||||
del self.core.interface_to_edge[interface_to_edge_id]
|
||||
del self.core.iface_to_edge[iface_to_edge_id]
|
||||
|
||||
def draw_grid(self):
|
||||
"""
|
||||
|
@ -321,18 +321,16 @@ class CanvasGraph(tk.Canvas):
|
|||
canvas_node2.edges.add(edge)
|
||||
self.edges[edge.token] = edge
|
||||
self.core.links[edge.token] = edge
|
||||
if link.HasField("interface1"):
|
||||
interface1 = link.interface1
|
||||
self.core.interface_to_edge[(node1.id, interface1.id)] = token
|
||||
canvas_node1.interfaces[interface1.id] = interface1
|
||||
edge.src_interface = interface1
|
||||
if link.HasField("interface2"):
|
||||
interface2 = link.interface2
|
||||
self.core.interface_to_edge[
|
||||
(node2.id, interface2.id)
|
||||
] = edge.token
|
||||
canvas_node2.interfaces[interface2.id] = interface2
|
||||
edge.dst_interface = interface2
|
||||
if link.HasField("iface1"):
|
||||
iface1 = link.iface1
|
||||
self.core.iface_to_edge[(node1.id, iface1.id)] = token
|
||||
canvas_node1.ifaces[iface1.id] = iface1
|
||||
edge.src_iface = iface1
|
||||
if link.HasField("iface2"):
|
||||
iface2 = link.iface2
|
||||
self.core.iface_to_edge[(node2.id, iface2.id)] = edge.token
|
||||
canvas_node2.ifaces[iface2.id] = iface2
|
||||
edge.dst_iface = iface2
|
||||
elif link.options.unidirectional:
|
||||
edge = self.edges[token]
|
||||
edge.asymmetric_link = link
|
||||
|
@ -513,14 +511,14 @@ class CanvasGraph(tk.Canvas):
|
|||
edge.delete()
|
||||
# update node connected to edge being deleted
|
||||
other_id = edge.src
|
||||
other_interface = edge.src_interface
|
||||
other_iface = edge.src_iface
|
||||
if edge.src == object_id:
|
||||
other_id = edge.dst
|
||||
other_interface = edge.dst_interface
|
||||
other_iface = edge.dst_iface
|
||||
other_node = self.nodes[other_id]
|
||||
other_node.edges.remove(edge)
|
||||
if other_interface:
|
||||
del other_node.interfaces[other_interface.id]
|
||||
if other_iface:
|
||||
del other_node.ifaces[other_iface.id]
|
||||
if is_wireless:
|
||||
other_node.delete_antenna()
|
||||
|
||||
|
@ -538,12 +536,12 @@ class CanvasGraph(tk.Canvas):
|
|||
del self.edges[edge.token]
|
||||
src_node = self.nodes[edge.src]
|
||||
src_node.edges.discard(edge)
|
||||
if edge.src_interface:
|
||||
del src_node.interfaces[edge.src_interface.id]
|
||||
if edge.src_iface:
|
||||
del src_node.ifaces[edge.src_iface.id]
|
||||
dst_node = self.nodes[edge.dst]
|
||||
dst_node.edges.discard(edge)
|
||||
if edge.dst_interface:
|
||||
del dst_node.interfaces[edge.dst_interface.id]
|
||||
if edge.dst_iface:
|
||||
del dst_node.ifaces[edge.dst_iface.id]
|
||||
src_wireless = NodeUtils.is_wireless_node(src_node.core_node.type)
|
||||
if src_wireless:
|
||||
dst_node.delete_antenna()
|
||||
|
@ -963,26 +961,26 @@ class CanvasGraph(tk.Canvas):
|
|||
copy_link = copy_edge.link
|
||||
options = edge.link.options
|
||||
copy_link.options.CopyFrom(options)
|
||||
interface1_id = None
|
||||
if copy_link.HasField("interface1"):
|
||||
interface1_id = copy_link.interface1.id
|
||||
interface2_id = None
|
||||
if copy_link.HasField("interface2"):
|
||||
interface2_id = copy_link.interface2.id
|
||||
iface1_id = None
|
||||
if copy_link.HasField("iface1"):
|
||||
iface1_id = copy_link.iface1.id
|
||||
iface2_id = None
|
||||
if copy_link.HasField("iface2"):
|
||||
iface2_id = copy_link.iface2.id
|
||||
if not options.unidirectional:
|
||||
copy_edge.asymmetric_link = None
|
||||
else:
|
||||
asym_interface1 = None
|
||||
if interface1_id:
|
||||
asym_interface1 = core_pb2.Interface(id=interface1_id)
|
||||
asym_interface2 = None
|
||||
if interface2_id:
|
||||
asym_interface2 = core_pb2.Interface(id=interface2_id)
|
||||
asym_iface1 = None
|
||||
if iface1_id:
|
||||
asym_iface1 = core_pb2.Interface(id=iface1_id)
|
||||
asym_iface2 = None
|
||||
if iface2_id:
|
||||
asym_iface2 = core_pb2.Interface(id=iface2_id)
|
||||
copy_edge.asymmetric_link = core_pb2.Link(
|
||||
node1_id=copy_link.node2_id,
|
||||
node2_id=copy_link.node1_id,
|
||||
interface1=asym_interface1,
|
||||
interface2=asym_interface2,
|
||||
iface1=asym_iface1,
|
||||
iface2=asym_iface2,
|
||||
options=edge.asymmetric_link.options,
|
||||
)
|
||||
self.itemconfig(
|
||||
|
|
|
@ -55,7 +55,7 @@ class CanvasNode:
|
|||
)
|
||||
self.tooltip = CanvasTooltip(self.canvas)
|
||||
self.edges = set()
|
||||
self.interfaces = {}
|
||||
self.ifaces = {}
|
||||
self.wireless_edges = set()
|
||||
self.antennas = []
|
||||
self.antenna_images = {}
|
||||
|
@ -70,9 +70,9 @@ class CanvasNode:
|
|||
self.context = tk.Menu(self.canvas)
|
||||
themes.style_menu(self.context)
|
||||
|
||||
def next_interface_id(self) -> int:
|
||||
def next_iface_id(self) -> int:
|
||||
i = 0
|
||||
while i in self.interfaces:
|
||||
while i in self.ifaces:
|
||||
i += 1
|
||||
return i
|
||||
|
||||
|
@ -300,16 +300,16 @@ class CanvasNode:
|
|||
dialog = NodeConfigServiceDialog(self.app, self)
|
||||
dialog.show()
|
||||
|
||||
def has_emane_link(self, interface_id: int) -> core_pb2.Node:
|
||||
def has_emane_link(self, iface_id: int) -> core_pb2.Node:
|
||||
result = None
|
||||
for edge in self.edges:
|
||||
if self.id == edge.src:
|
||||
other_id = edge.dst
|
||||
edge_interface_id = edge.src_interface.id
|
||||
edge_iface_id = edge.src_iface.id
|
||||
else:
|
||||
other_id = edge.src
|
||||
edge_interface_id = edge.dst_interface.id
|
||||
if edge_interface_id != interface_id:
|
||||
edge_iface_id = edge.dst_iface.id
|
||||
if edge_iface_id != iface_id:
|
||||
continue
|
||||
other_node = self.canvas.nodes[other_id]
|
||||
if other_node.core_node.type == NodeType.EMANE:
|
||||
|
|
|
@ -12,10 +12,10 @@ if TYPE_CHECKING:
|
|||
from core.gui.graph.node import CanvasNode
|
||||
|
||||
|
||||
def get_index(interface: "core_pb2.Interface") -> Optional[int]:
|
||||
if not interface.ip4:
|
||||
def get_index(iface: "core_pb2.Interface") -> Optional[int]:
|
||||
if not iface.ip4:
|
||||
return None
|
||||
net = netaddr.IPNetwork(f"{interface.ip4}/{interface.ip4mask}")
|
||||
net = netaddr.IPNetwork(f"{iface.ip4}/{iface.ip4mask}")
|
||||
ip_value = net.value
|
||||
cidr_value = net.cidr.value
|
||||
return ip_value - cidr_value
|
||||
|
@ -89,43 +89,43 @@ class InterfaceManager:
|
|||
remaining_subnets = set()
|
||||
for edge in self.app.core.links.values():
|
||||
link = edge.link
|
||||
if link.HasField("interface1"):
|
||||
subnets = self.get_subnets(link.interface1)
|
||||
if link.HasField("iface1"):
|
||||
subnets = self.get_subnets(link.iface1)
|
||||
remaining_subnets.add(subnets)
|
||||
if link.HasField("interface2"):
|
||||
subnets = self.get_subnets(link.interface2)
|
||||
if link.HasField("iface2"):
|
||||
subnets = self.get_subnets(link.iface2)
|
||||
remaining_subnets.add(subnets)
|
||||
|
||||
# remove all subnets from used subnets when no longer present
|
||||
# or remove used indexes from subnet
|
||||
interfaces = []
|
||||
ifaces = []
|
||||
for link in links:
|
||||
if link.HasField("interface1"):
|
||||
interfaces.append(link.interface1)
|
||||
if link.HasField("interface2"):
|
||||
interfaces.append(link.interface2)
|
||||
for interface in interfaces:
|
||||
subnets = self.get_subnets(interface)
|
||||
if link.HasField("iface1"):
|
||||
ifaces.append(link.iface1)
|
||||
if link.HasField("iface2"):
|
||||
ifaces.append(link.iface2)
|
||||
for iface in ifaces:
|
||||
subnets = self.get_subnets(iface)
|
||||
if subnets not in remaining_subnets:
|
||||
self.used_subnets.pop(subnets.key(), None)
|
||||
else:
|
||||
index = get_index(interface)
|
||||
index = get_index(iface)
|
||||
if index is not None:
|
||||
subnets.used_indexes.discard(index)
|
||||
self.current_subnets = None
|
||||
|
||||
def joined(self, links: List["core_pb2.Link"]) -> None:
|
||||
interfaces = []
|
||||
ifaces = []
|
||||
for link in links:
|
||||
if link.HasField("interface1"):
|
||||
interfaces.append(link.interface1)
|
||||
if link.HasField("interface2"):
|
||||
interfaces.append(link.interface2)
|
||||
if link.HasField("iface1"):
|
||||
ifaces.append(link.iface1)
|
||||
if link.HasField("iface2"):
|
||||
ifaces.append(link.iface2)
|
||||
|
||||
# add to used subnets and mark used indexes
|
||||
for interface in interfaces:
|
||||
subnets = self.get_subnets(interface)
|
||||
index = get_index(interface)
|
||||
for iface in ifaces:
|
||||
subnets = self.get_subnets(iface)
|
||||
index = get_index(iface)
|
||||
if index is None:
|
||||
continue
|
||||
subnets.used_indexes.add(index)
|
||||
|
@ -150,13 +150,13 @@ class InterfaceManager:
|
|||
ip6 = self.current_subnets.ip6[index]
|
||||
return str(ip4), str(ip6)
|
||||
|
||||
def get_subnets(self, interface: "core_pb2.Interface") -> Subnets:
|
||||
def get_subnets(self, iface: "core_pb2.Interface") -> Subnets:
|
||||
ip4_subnet = self.ip4_subnets
|
||||
if interface.ip4:
|
||||
ip4_subnet = IPNetwork(f"{interface.ip4}/{interface.ip4mask}").cidr
|
||||
if iface.ip4:
|
||||
ip4_subnet = IPNetwork(f"{iface.ip4}/{iface.ip4mask}").cidr
|
||||
ip6_subnet = self.ip6_subnets
|
||||
if interface.ip6:
|
||||
ip6_subnet = IPNetwork(f"{interface.ip6}/{interface.ip6mask}").cidr
|
||||
if iface.ip6:
|
||||
ip6_subnet = IPNetwork(f"{iface.ip6}/{iface.ip6mask}").cidr
|
||||
subnets = Subnets(ip4_subnet, ip6_subnet)
|
||||
return self.used_subnets.get(subnets.key(), subnets)
|
||||
|
||||
|
@ -196,16 +196,16 @@ class InterfaceManager:
|
|||
for edge in canvas_node.edges:
|
||||
src_node = canvas.nodes[edge.src]
|
||||
dst_node = canvas.nodes[edge.dst]
|
||||
interface = edge.src_interface
|
||||
iface = edge.src_iface
|
||||
check_node = src_node
|
||||
if src_node == canvas_node:
|
||||
interface = edge.dst_interface
|
||||
iface = edge.dst_iface
|
||||
check_node = dst_node
|
||||
if check_node.core_node.id in visited:
|
||||
continue
|
||||
visited.add(check_node.core_node.id)
|
||||
if interface:
|
||||
subnets = self.get_subnets(interface)
|
||||
if iface:
|
||||
subnets = self.get_subnets(iface)
|
||||
else:
|
||||
subnets = self.find_subnets(check_node, visited)
|
||||
if subnets:
|
||||
|
|
|
@ -139,7 +139,7 @@ class Menubar(tk.Menu):
|
|||
menu.add_checkbutton(
|
||||
label="Interface Names",
|
||||
command=self.click_edge_label_change,
|
||||
variable=self.canvas.show_interface_names,
|
||||
variable=self.canvas.show_iface_names,
|
||||
)
|
||||
menu.add_checkbutton(
|
||||
label="IPv4 Addresses",
|
||||
|
|
|
@ -178,7 +178,7 @@ class MobilityManager(ModelManager):
|
|||
self.session.broadcast_event(event_data)
|
||||
|
||||
def updatewlans(
|
||||
self, moved: List[CoreNode], moved_netifs: List[CoreInterface]
|
||||
self, moved: List[CoreNode], moved_ifaces: List[CoreInterface]
|
||||
) -> None:
|
||||
"""
|
||||
A mobility script has caused nodes in the 'moved' list to move.
|
||||
|
@ -186,7 +186,7 @@ class MobilityManager(ModelManager):
|
|||
were to recalculate for each individual node movement.
|
||||
|
||||
:param moved: moved nodes
|
||||
:param moved_netifs: moved network interfaces
|
||||
:param moved_ifaces: moved network interfaces
|
||||
:return: nothing
|
||||
"""
|
||||
for node_id in self.nodes():
|
||||
|
@ -195,7 +195,7 @@ class MobilityManager(ModelManager):
|
|||
except CoreError:
|
||||
continue
|
||||
if node.model:
|
||||
node.model.update(moved, moved_netifs)
|
||||
node.model.update(moved, moved_ifaces)
|
||||
|
||||
|
||||
class WirelessModel(ConfigurableOptions):
|
||||
|
@ -228,12 +228,12 @@ class WirelessModel(ConfigurableOptions):
|
|||
"""
|
||||
return []
|
||||
|
||||
def update(self, moved: List[CoreNode], moved_netifs: List[CoreInterface]) -> None:
|
||||
def update(self, moved: List[CoreNode], moved_ifaces: List[CoreInterface]) -> None:
|
||||
"""
|
||||
Update this wireless model.
|
||||
|
||||
:param moved: moved nodes
|
||||
:param moved_netifs: moved network interfaces
|
||||
:param moved_ifaces: moved network interfaces
|
||||
:return: nothing
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
@ -301,8 +301,8 @@ class BasicRangeModel(WirelessModel):
|
|||
super().__init__(session, _id)
|
||||
self.session: "Session" = session
|
||||
self.wlan: WlanNode = session.get_node(_id, WlanNode)
|
||||
self._netifs: Dict[CoreInterface, Tuple[float, float, float]] = {}
|
||||
self._netifslock: threading.Lock = threading.Lock()
|
||||
self.iface_to_pos: Dict[CoreInterface, Tuple[float, float, float]] = {}
|
||||
self.iface_lock: threading.Lock = threading.Lock()
|
||||
self.range: int = 0
|
||||
self.bw: Optional[int] = None
|
||||
self.delay: Optional[int] = None
|
||||
|
@ -333,48 +333,48 @@ class BasicRangeModel(WirelessModel):
|
|||
Apply link parameters to all interfaces. This is invoked from
|
||||
WlanNode.setmodel() after the position callback has been set.
|
||||
"""
|
||||
with self._netifslock:
|
||||
for netif in self._netifs:
|
||||
with self.iface_lock:
|
||||
for iface in self.iface_to_pos:
|
||||
options = LinkOptions(
|
||||
bandwidth=self.bw,
|
||||
delay=self.delay,
|
||||
loss=self.loss,
|
||||
jitter=self.jitter,
|
||||
)
|
||||
self.wlan.linkconfig(netif, options)
|
||||
self.wlan.linkconfig(iface, options)
|
||||
|
||||
def get_position(self, netif: CoreInterface) -> Tuple[float, float, float]:
|
||||
def get_position(self, iface: CoreInterface) -> Tuple[float, float, float]:
|
||||
"""
|
||||
Retrieve network interface position.
|
||||
|
||||
:param netif: network interface position to retrieve
|
||||
:param iface: network interface position to retrieve
|
||||
:return: network interface position
|
||||
"""
|
||||
with self._netifslock:
|
||||
return self._netifs[netif]
|
||||
with self.iface_lock:
|
||||
return self.iface_to_pos[iface]
|
||||
|
||||
def set_position(self, netif: CoreInterface) -> None:
|
||||
def set_position(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
A node has moved; given an interface, a new (x,y,z) position has
|
||||
been set; calculate the new distance between other nodes and link or
|
||||
unlink node pairs based on the configured range.
|
||||
|
||||
:param netif: network interface to set position for
|
||||
:param iface: network interface to set position for
|
||||
:return: nothing
|
||||
"""
|
||||
x, y, z = netif.node.position.get()
|
||||
self._netifslock.acquire()
|
||||
self._netifs[netif] = (x, y, z)
|
||||
x, y, z = iface.node.position.get()
|
||||
self.iface_lock.acquire()
|
||||
self.iface_to_pos[iface] = (x, y, z)
|
||||
if x is None or y is None:
|
||||
self._netifslock.release()
|
||||
self.iface_lock.release()
|
||||
return
|
||||
for netif2 in self._netifs:
|
||||
self.calclink(netif, netif2)
|
||||
self._netifslock.release()
|
||||
for iface2 in self.iface_to_pos:
|
||||
self.calclink(iface, iface2)
|
||||
self.iface_lock.release()
|
||||
|
||||
position_callback = set_position
|
||||
|
||||
def update(self, moved: List[CoreNode], moved_netifs: List[CoreInterface]) -> None:
|
||||
def update(self, moved: List[CoreNode], moved_ifaces: List[CoreInterface]) -> None:
|
||||
"""
|
||||
Node positions have changed without recalc. Update positions from
|
||||
node.position, then re-calculate links for those that have moved.
|
||||
|
@ -382,37 +382,37 @@ class BasicRangeModel(WirelessModel):
|
|||
one of the nodes has moved.
|
||||
|
||||
:param moved: moved nodes
|
||||
:param moved_netifs: moved network interfaces
|
||||
:param moved_ifaces: moved network interfaces
|
||||
:return: nothing
|
||||
"""
|
||||
with self._netifslock:
|
||||
while len(moved_netifs):
|
||||
netif = moved_netifs.pop()
|
||||
nx, ny, nz = netif.node.getposition()
|
||||
if netif in self._netifs:
|
||||
self._netifs[netif] = (nx, ny, nz)
|
||||
for netif2 in self._netifs:
|
||||
if netif2 in moved_netifs:
|
||||
with self.iface_lock:
|
||||
while len(moved_ifaces):
|
||||
iface = moved_ifaces.pop()
|
||||
nx, ny, nz = iface.node.getposition()
|
||||
if iface in self.iface_to_pos:
|
||||
self.iface_to_pos[iface] = (nx, ny, nz)
|
||||
for iface2 in self.iface_to_pos:
|
||||
if iface2 in moved_ifaces:
|
||||
continue
|
||||
self.calclink(netif, netif2)
|
||||
self.calclink(iface, iface2)
|
||||
|
||||
def calclink(self, netif: CoreInterface, netif2: CoreInterface) -> None:
|
||||
def calclink(self, iface: CoreInterface, iface2: CoreInterface) -> None:
|
||||
"""
|
||||
Helper used by set_position() and update() to
|
||||
calculate distance between two interfaces and perform
|
||||
linking/unlinking. Sends link/unlink messages and updates the
|
||||
WlanNode's linked dict.
|
||||
|
||||
:param netif: interface one
|
||||
:param netif2: interface two
|
||||
:param iface: interface one
|
||||
:param iface2: interface two
|
||||
:return: nothing
|
||||
"""
|
||||
if netif == netif2:
|
||||
if iface == iface2:
|
||||
return
|
||||
|
||||
try:
|
||||
x, y, z = self._netifs[netif]
|
||||
x2, y2, z2 = self._netifs[netif2]
|
||||
x, y, z = self.iface_to_pos[iface]
|
||||
x2, y2, z2 = self.iface_to_pos[iface2]
|
||||
|
||||
if x2 is None or y2 is None:
|
||||
return
|
||||
|
@ -420,8 +420,8 @@ class BasicRangeModel(WirelessModel):
|
|||
d = self.calcdistance((x, y, z), (x2, y2, z2))
|
||||
|
||||
# ordering is important, to keep the wlan._linked dict organized
|
||||
a = min(netif, netif2)
|
||||
b = max(netif, netif2)
|
||||
a = min(iface, iface2)
|
||||
b = max(iface, iface2)
|
||||
|
||||
with self.wlan._linked_lock:
|
||||
linked = self.wlan.linked(a, b)
|
||||
|
@ -475,42 +475,39 @@ class BasicRangeModel(WirelessModel):
|
|||
self.setlinkparams()
|
||||
|
||||
def create_link_data(
|
||||
self,
|
||||
interface1: CoreInterface,
|
||||
interface2: CoreInterface,
|
||||
message_type: MessageFlags,
|
||||
self, iface1: CoreInterface, iface2: CoreInterface, message_type: MessageFlags
|
||||
) -> LinkData:
|
||||
"""
|
||||
Create a wireless link/unlink data message.
|
||||
|
||||
:param interface1: interface one
|
||||
:param interface2: interface two
|
||||
:param iface1: interface one
|
||||
:param iface2: interface two
|
||||
:param message_type: link message type
|
||||
:return: link data
|
||||
"""
|
||||
color = self.session.get_link_color(self.wlan.id)
|
||||
return LinkData(
|
||||
message_type=message_type,
|
||||
node1_id=interface1.node.id,
|
||||
node2_id=interface2.node.id,
|
||||
node1_id=iface1.node.id,
|
||||
node2_id=iface2.node.id,
|
||||
network_id=self.wlan.id,
|
||||
link_type=LinkTypes.WIRELESS,
|
||||
color=color,
|
||||
)
|
||||
|
||||
def sendlinkmsg(
|
||||
self, netif: CoreInterface, netif2: CoreInterface, unlink: bool = False
|
||||
self, iface: CoreInterface, iface2: CoreInterface, unlink: bool = False
|
||||
) -> None:
|
||||
"""
|
||||
Send a wireless link/unlink API message to the GUI.
|
||||
|
||||
:param netif: interface one
|
||||
:param netif2: interface two
|
||||
:param iface: interface one
|
||||
:param iface2: interface two
|
||||
:param unlink: unlink or not
|
||||
:return: nothing
|
||||
"""
|
||||
message_type = MessageFlags.DELETE if unlink else MessageFlags.ADD
|
||||
link_data = self.create_link_data(netif, netif2, message_type)
|
||||
link_data = self.create_link_data(iface, iface2, message_type)
|
||||
self.session.broadcast_link(link_data)
|
||||
|
||||
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
||||
|
@ -643,17 +640,17 @@ class WayPointMobility(WirelessModel):
|
|||
return
|
||||
return self.run()
|
||||
|
||||
# only move netifs attached to self.wlan, or all nodenum in script?
|
||||
# only move interfaces attached to self.wlan, or all nodenum in script?
|
||||
moved = []
|
||||
moved_netifs = []
|
||||
for netif in self.wlan.netifs():
|
||||
node = netif.node
|
||||
moved_ifaces = []
|
||||
for iface in self.wlan.get_ifaces():
|
||||
node = iface.node
|
||||
if self.movenode(node, dt):
|
||||
moved.append(node)
|
||||
moved_netifs.append(netif)
|
||||
moved_ifaces.append(iface)
|
||||
|
||||
# calculate all ranges after moving nodes; this saves calculations
|
||||
self.session.mobility.updatewlans(moved, moved_netifs)
|
||||
self.session.mobility.updatewlans(moved, moved_ifaces)
|
||||
|
||||
# TODO: check session state
|
||||
self.session.event_loop.add_event(0.001 * self.refresh_ms, self.runround)
|
||||
|
@ -725,16 +722,16 @@ class WayPointMobility(WirelessModel):
|
|||
:return: nothing
|
||||
"""
|
||||
moved = []
|
||||
moved_netifs = []
|
||||
for netif in self.wlan.netifs():
|
||||
node = netif.node
|
||||
moved_ifaces = []
|
||||
for iface in self.wlan.get_ifaces():
|
||||
node = iface.node
|
||||
if node.id not in self.initial:
|
||||
continue
|
||||
x, y, z = self.initial[node.id].coords
|
||||
self.setnodeposition(node, x, y, z)
|
||||
moved.append(node)
|
||||
moved_netifs.append(netif)
|
||||
self.session.mobility.updatewlans(moved, moved_netifs)
|
||||
moved_ifaces.append(iface)
|
||||
self.session.mobility.updatewlans(moved, moved_ifaces)
|
||||
|
||||
def addwaypoint(
|
||||
self,
|
||||
|
|
|
@ -68,8 +68,8 @@ class NodeBase(abc.ABC):
|
|||
self.server: "DistributedServer" = server
|
||||
self.type: Optional[str] = None
|
||||
self.services: CoreServices = []
|
||||
self._netif: Dict[int, CoreInterface] = {}
|
||||
self.ifindex: int = 0
|
||||
self.ifaces: Dict[int, CoreInterface] = {}
|
||||
self.iface_id: int = 0
|
||||
self.canvas: Optional[int] = None
|
||||
self.icon: Optional[str] = None
|
||||
self.opaque: Optional[str] = None
|
||||
|
@ -139,58 +139,50 @@ class NodeBase(abc.ABC):
|
|||
"""
|
||||
return self.position.get()
|
||||
|
||||
def ifname(self, ifindex: int) -> str:
|
||||
"""
|
||||
Retrieve interface name for index.
|
||||
def get_iface(self, iface_id: int) -> CoreInterface:
|
||||
if iface_id not in self.ifaces:
|
||||
raise CoreError(f"node({self.name}) does not have interface({iface_id})")
|
||||
return self.ifaces[iface_id]
|
||||
|
||||
:param ifindex: interface index
|
||||
:return: interface name
|
||||
def get_ifaces(self, control: bool = True) -> List[CoreInterface]:
|
||||
"""
|
||||
return self._netif[ifindex].name
|
||||
Retrieve sorted list of interfaces, optionally do not include control
|
||||
interfaces.
|
||||
|
||||
def netifs(self, sort: bool = False) -> List[CoreInterface]:
|
||||
:param control: False to exclude control interfaces, included otherwise
|
||||
:return: list of interfaces
|
||||
"""
|
||||
Retrieve network interfaces, sorted if desired.
|
||||
ifaces = []
|
||||
for iface_id in sorted(self.ifaces):
|
||||
iface = self.ifaces[iface_id]
|
||||
if not control and getattr(iface, "control", False):
|
||||
continue
|
||||
ifaces.append(iface)
|
||||
return ifaces
|
||||
|
||||
:param sort: boolean used to determine if interfaces should be sorted
|
||||
:return: network interfaces
|
||||
def get_iface_id(self, iface: CoreInterface) -> int:
|
||||
"""
|
||||
if sort:
|
||||
return [self._netif[x] for x in sorted(self._netif)]
|
||||
else:
|
||||
return list(self._netif.values())
|
||||
Retrieve id for an interface.
|
||||
|
||||
def numnetif(self) -> int:
|
||||
"""
|
||||
Return the attached interface count.
|
||||
|
||||
:return: number of network interfaces
|
||||
"""
|
||||
return len(self._netif)
|
||||
|
||||
def getifindex(self, netif: CoreInterface) -> int:
|
||||
"""
|
||||
Retrieve index for an interface.
|
||||
|
||||
:param netif: interface to get index for
|
||||
:param iface: interface to get id for
|
||||
:return: interface index if found, -1 otherwise
|
||||
"""
|
||||
for ifindex in self._netif:
|
||||
if self._netif[ifindex] is netif:
|
||||
return ifindex
|
||||
return -1
|
||||
for iface_id, local_iface in self.ifaces.items():
|
||||
if local_iface is iface:
|
||||
return iface_id
|
||||
raise CoreError(f"node({self.name}) does not have interface({iface.name})")
|
||||
|
||||
def newifindex(self) -> int:
|
||||
def next_iface_id(self) -> int:
|
||||
"""
|
||||
Create a new interface index.
|
||||
|
||||
:return: interface index
|
||||
"""
|
||||
while self.ifindex in self._netif:
|
||||
self.ifindex += 1
|
||||
ifindex = self.ifindex
|
||||
self.ifindex += 1
|
||||
return ifindex
|
||||
while self.iface_id in self.ifaces:
|
||||
self.iface_id += 1
|
||||
iface_id = self.iface_id
|
||||
self.iface_id += 1
|
||||
return iface_id
|
||||
|
||||
def data(
|
||||
self, message_type: MessageFlags = MessageFlags.NONE, source: str = None
|
||||
|
@ -325,14 +317,14 @@ class CoreNodeBase(NodeBase):
|
|||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def newnetif(
|
||||
self, net: "CoreNetworkBase", interface_data: InterfaceData
|
||||
def new_iface(
|
||||
self, net: "CoreNetworkBase", iface_data: InterfaceData
|
||||
) -> CoreInterface:
|
||||
"""
|
||||
Create a new network interface.
|
||||
Create a new interface.
|
||||
|
||||
:param net: network to associate with
|
||||
:param interface_data: interface data for new interface
|
||||
:param iface_data: interface data for new interface
|
||||
:return: interface index
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
@ -399,67 +391,53 @@ class CoreNodeBase(NodeBase):
|
|||
if self.tmpnodedir:
|
||||
self.host_cmd(f"rm -rf {self.nodedir}")
|
||||
|
||||
def addnetif(self, netif: CoreInterface, ifindex: int) -> None:
|
||||
def add_iface(self, iface: CoreInterface, iface_id: int) -> None:
|
||||
"""
|
||||
Add network interface to node and set the network interface index if successful.
|
||||
|
||||
:param netif: network interface to add
|
||||
:param ifindex: interface index
|
||||
:param iface: network interface to add
|
||||
:param iface_id: interface id
|
||||
:return: nothing
|
||||
"""
|
||||
if ifindex in self._netif:
|
||||
raise ValueError(f"ifindex {ifindex} already exists")
|
||||
self._netif[ifindex] = netif
|
||||
netif.netindex = ifindex
|
||||
if iface_id in self.ifaces:
|
||||
raise CoreError(f"interface({iface_id}) already exists")
|
||||
self.ifaces[iface_id] = iface
|
||||
iface.node_id = iface_id
|
||||
|
||||
def delnetif(self, ifindex: int) -> None:
|
||||
def delete_iface(self, iface_id: int) -> None:
|
||||
"""
|
||||
Delete a network interface
|
||||
|
||||
:param ifindex: interface index to delete
|
||||
:param iface_id: interface index to delete
|
||||
:return: nothing
|
||||
"""
|
||||
if ifindex not in self._netif:
|
||||
raise CoreError(f"node({self.name}) ifindex({ifindex}) does not exist")
|
||||
netif = self._netif.pop(ifindex)
|
||||
logging.info("node(%s) removing interface(%s)", self.name, netif.name)
|
||||
netif.detachnet()
|
||||
netif.shutdown()
|
||||
if iface_id not in self.ifaces:
|
||||
raise CoreError(f"node({self.name}) interface({iface_id}) does not exist")
|
||||
iface = self.ifaces.pop(iface_id)
|
||||
logging.info("node(%s) removing interface(%s)", self.name, iface.name)
|
||||
iface.detachnet()
|
||||
iface.shutdown()
|
||||
|
||||
def netif(self, ifindex: int) -> Optional[CoreInterface]:
|
||||
"""
|
||||
Retrieve network interface.
|
||||
|
||||
:param ifindex: index of interface to retrieve
|
||||
:return: network interface, or None if not found
|
||||
"""
|
||||
if ifindex in self._netif:
|
||||
return self._netif[ifindex]
|
||||
else:
|
||||
return None
|
||||
|
||||
def attachnet(self, ifindex: int, net: "CoreNetworkBase") -> None:
|
||||
def attachnet(self, iface_id: int, net: "CoreNetworkBase") -> None:
|
||||
"""
|
||||
Attach a network.
|
||||
|
||||
:param ifindex: interface of index to attach
|
||||
:param iface_id: interface of index to attach
|
||||
:param net: network to attach
|
||||
:return: nothing
|
||||
"""
|
||||
if ifindex not in self._netif:
|
||||
raise ValueError(f"ifindex {ifindex} does not exist")
|
||||
self._netif[ifindex].attachnet(net)
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.attachnet(net)
|
||||
|
||||
def detachnet(self, ifindex: int) -> None:
|
||||
def detachnet(self, iface_id: int) -> None:
|
||||
"""
|
||||
Detach network interface.
|
||||
|
||||
:param ifindex: interface index to detach
|
||||
:param iface_id: interface id to detach
|
||||
:return: nothing
|
||||
"""
|
||||
if ifindex not in self._netif:
|
||||
raise ValueError(f"ifindex {ifindex} does not exist")
|
||||
self._netif[ifindex].detachnet()
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.detachnet()
|
||||
|
||||
def setposition(self, x: float = None, y: float = None, z: float = None) -> None:
|
||||
"""
|
||||
|
@ -472,8 +450,8 @@ class CoreNodeBase(NodeBase):
|
|||
"""
|
||||
changed = super().setposition(x, y, z)
|
||||
if changed:
|
||||
for netif in self.netifs(sort=True):
|
||||
netif.setposition()
|
||||
for iface in self.get_ifaces():
|
||||
iface.setposition()
|
||||
|
||||
def commonnets(
|
||||
self, node: "CoreNodeBase", want_ctrl: bool = False
|
||||
|
@ -488,12 +466,10 @@ class CoreNodeBase(NodeBase):
|
|||
:return: tuples of common networks
|
||||
"""
|
||||
common = []
|
||||
for netif1 in self.netifs():
|
||||
if not want_ctrl and hasattr(netif1, "control"):
|
||||
continue
|
||||
for netif2 in node.netifs():
|
||||
if netif1.net == netif2.net:
|
||||
common.append((netif1.net, netif1, netif2))
|
||||
for iface1 in self.get_ifaces(control=want_ctrl):
|
||||
for iface2 in node.get_ifaces():
|
||||
if iface1.net == iface2.net:
|
||||
common.append((iface1.net, iface1, iface2))
|
||||
return common
|
||||
|
||||
|
||||
|
@ -620,8 +596,8 @@ class CoreNode(CoreNodeBase):
|
|||
self._mounts = []
|
||||
|
||||
# shutdown all interfaces
|
||||
for netif in self.netifs():
|
||||
netif.shutdown()
|
||||
for iface in self.get_ifaces():
|
||||
iface.shutdown()
|
||||
|
||||
# kill node process if present
|
||||
try:
|
||||
|
@ -636,7 +612,7 @@ class CoreNode(CoreNodeBase):
|
|||
logging.exception("error removing node directory")
|
||||
|
||||
# clear interface data, close client, and mark self and not up
|
||||
self._netif.clear()
|
||||
self.ifaces.clear()
|
||||
self.client.close()
|
||||
self.up = False
|
||||
except OSError:
|
||||
|
@ -704,36 +680,36 @@ class CoreNode(CoreNodeBase):
|
|||
self.cmd(f"{MOUNT_BIN} -n --bind {source} {target}")
|
||||
self._mounts.append((source, target))
|
||||
|
||||
def newifindex(self) -> int:
|
||||
def next_iface_id(self) -> int:
|
||||
"""
|
||||
Retrieve a new interface index.
|
||||
|
||||
:return: new interface index
|
||||
"""
|
||||
with self.lock:
|
||||
return super().newifindex()
|
||||
return super().next_iface_id()
|
||||
|
||||
def newveth(self, ifindex: int = None, ifname: str = None) -> int:
|
||||
def newveth(self, iface_id: int = None, ifname: str = None) -> int:
|
||||
"""
|
||||
Create a new interface.
|
||||
|
||||
:param ifindex: index for the new interface
|
||||
:param iface_id: id for the new interface
|
||||
:param ifname: name for the new interface
|
||||
:return: nothing
|
||||
"""
|
||||
with self.lock:
|
||||
if ifindex is None:
|
||||
ifindex = self.newifindex()
|
||||
if iface_id is None:
|
||||
iface_id = self.next_iface_id()
|
||||
|
||||
if ifname is None:
|
||||
ifname = f"eth{ifindex}"
|
||||
ifname = f"eth{iface_id}"
|
||||
|
||||
sessionid = self.session.short_session_id()
|
||||
|
||||
try:
|
||||
suffix = f"{self.id:x}.{ifindex}.{sessionid}"
|
||||
suffix = f"{self.id:x}.{iface_id}.{sessionid}"
|
||||
except TypeError:
|
||||
suffix = f"{self.id}.{ifindex}.{sessionid}"
|
||||
suffix = f"{self.id}.{iface_id}.{sessionid}"
|
||||
|
||||
localname = f"veth{suffix}"
|
||||
if len(localname) >= 16:
|
||||
|
@ -765,140 +741,138 @@ class CoreNode(CoreNodeBase):
|
|||
try:
|
||||
# add network interface to the node. If unsuccessful, destroy the
|
||||
# network interface and raise exception.
|
||||
self.addnetif(veth, ifindex)
|
||||
self.add_iface(veth, iface_id)
|
||||
except ValueError as e:
|
||||
veth.shutdown()
|
||||
del veth
|
||||
raise e
|
||||
|
||||
return ifindex
|
||||
return iface_id
|
||||
|
||||
def newtuntap(self, ifindex: int = None, ifname: str = None) -> int:
|
||||
def newtuntap(self, iface_id: int = None, ifname: str = None) -> int:
|
||||
"""
|
||||
Create a new tunnel tap.
|
||||
|
||||
:param ifindex: interface index
|
||||
:param iface_id: interface id
|
||||
:param ifname: interface name
|
||||
:return: interface index
|
||||
"""
|
||||
with self.lock:
|
||||
if ifindex is None:
|
||||
ifindex = self.newifindex()
|
||||
if iface_id is None:
|
||||
iface_id = self.next_iface_id()
|
||||
|
||||
if ifname is None:
|
||||
ifname = f"eth{ifindex}"
|
||||
ifname = f"eth{iface_id}"
|
||||
|
||||
sessionid = self.session.short_session_id()
|
||||
localname = f"tap{self.id}.{ifindex}.{sessionid}"
|
||||
localname = f"tap{self.id}.{iface_id}.{sessionid}"
|
||||
name = ifname
|
||||
tuntap = TunTap(self.session, self, name, localname, start=self.up)
|
||||
|
||||
try:
|
||||
self.addnetif(tuntap, ifindex)
|
||||
self.add_iface(tuntap, iface_id)
|
||||
except ValueError as e:
|
||||
tuntap.shutdown()
|
||||
del tuntap
|
||||
raise e
|
||||
|
||||
return ifindex
|
||||
return iface_id
|
||||
|
||||
def sethwaddr(self, ifindex: int, addr: str) -> None:
|
||||
def sethwaddr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Set hardware addres for an interface.
|
||||
Set hardware address for an interface.
|
||||
|
||||
:param ifindex: index of interface to set hardware address for
|
||||
:param iface_id: id of interface to set hardware address for
|
||||
:param addr: hardware address to set
|
||||
:return: nothing
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
addr = utils.validate_mac(addr)
|
||||
interface = self._netif[ifindex]
|
||||
interface.sethwaddr(addr)
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.sethwaddr(addr)
|
||||
if self.up:
|
||||
self.node_net_client.device_mac(interface.name, addr)
|
||||
self.node_net_client.device_mac(iface.name, addr)
|
||||
|
||||
def addaddr(self, ifindex: int, addr: str) -> None:
|
||||
def addaddr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Add interface address.
|
||||
|
||||
:param ifindex: index of interface to add address to
|
||||
:param iface_id: id of interface to add address to
|
||||
:param addr: address to add to interface
|
||||
:return: nothing
|
||||
"""
|
||||
addr = utils.validate_ip(addr)
|
||||
interface = self._netif[ifindex]
|
||||
interface.addaddr(addr)
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.addaddr(addr)
|
||||
if self.up:
|
||||
# ipv4 check
|
||||
broadcast = None
|
||||
if netaddr.valid_ipv4(addr):
|
||||
broadcast = "+"
|
||||
self.node_net_client.create_address(interface.name, addr, broadcast)
|
||||
self.node_net_client.create_address(iface.name, addr, broadcast)
|
||||
|
||||
def deladdr(self, ifindex: int, addr: str) -> None:
|
||||
def deladdr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Delete address from an interface.
|
||||
|
||||
:param ifindex: index of interface to delete address from
|
||||
:param iface_id: id of interface to delete address from
|
||||
:param addr: address to delete from interface
|
||||
:return: nothing
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
interface = self._netif[ifindex]
|
||||
|
||||
iface = self.get_iface(iface_id)
|
||||
try:
|
||||
interface.deladdr(addr)
|
||||
iface.deladdr(addr)
|
||||
except ValueError:
|
||||
logging.exception("trying to delete unknown address: %s", addr)
|
||||
|
||||
if self.up:
|
||||
self.node_net_client.delete_address(interface.name, addr)
|
||||
self.node_net_client.delete_address(iface.name, addr)
|
||||
|
||||
def ifup(self, ifindex: int) -> None:
|
||||
def ifup(self, iface_id: int) -> None:
|
||||
"""
|
||||
Bring an interface up.
|
||||
|
||||
:param ifindex: index of interface to bring up
|
||||
:param iface_id: index of interface to bring up
|
||||
:return: nothing
|
||||
"""
|
||||
if self.up:
|
||||
interface_name = self.ifname(ifindex)
|
||||
self.node_net_client.device_up(interface_name)
|
||||
iface = self.get_iface(iface_id)
|
||||
self.node_net_client.device_up(iface.name)
|
||||
|
||||
def newnetif(
|
||||
self, net: "CoreNetworkBase", interface_data: InterfaceData
|
||||
def new_iface(
|
||||
self, net: "CoreNetworkBase", iface_data: InterfaceData
|
||||
) -> CoreInterface:
|
||||
"""
|
||||
Create a new network interface.
|
||||
|
||||
:param net: network to associate with
|
||||
:param interface_data: interface data for new interface
|
||||
:param iface_data: interface data for new interface
|
||||
:return: interface index
|
||||
"""
|
||||
addresses = interface_data.get_addresses()
|
||||
addresses = iface_data.get_addresses()
|
||||
with self.lock:
|
||||
# TODO: emane specific code
|
||||
if net.is_emane is True:
|
||||
ifindex = self.newtuntap(interface_data.id, interface_data.name)
|
||||
iface_id = self.newtuntap(iface_data.id, iface_data.name)
|
||||
# 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(interface_data.mac)
|
||||
self.attachnet(iface_id, net)
|
||||
iface = self.get_iface(iface_id)
|
||||
iface.sethwaddr(iface_data.mac)
|
||||
for address in addresses:
|
||||
netif.addaddr(address)
|
||||
iface.addaddr(address)
|
||||
else:
|
||||
ifindex = self.newveth(interface_data.id, interface_data.name)
|
||||
self.attachnet(ifindex, net)
|
||||
if interface_data.mac:
|
||||
self.sethwaddr(ifindex, interface_data.mac)
|
||||
iface_id = self.newveth(iface_data.id, iface_data.name)
|
||||
self.attachnet(iface_id, net)
|
||||
if iface_data.mac:
|
||||
self.sethwaddr(iface_id, iface_data.mac)
|
||||
for address in addresses:
|
||||
self.addaddr(ifindex, address)
|
||||
self.ifup(ifindex)
|
||||
netif = self.netif(ifindex)
|
||||
return netif
|
||||
self.addaddr(iface_id, address)
|
||||
self.ifup(iface_id)
|
||||
iface = self.get_iface(iface_id)
|
||||
return iface
|
||||
|
||||
def addfile(self, srcname: str, filename: str) -> None:
|
||||
"""
|
||||
|
@ -1041,54 +1015,54 @@ class CoreNetworkBase(NodeBase):
|
|||
|
||||
@abc.abstractmethod
|
||||
def linkconfig(
|
||||
self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
|
||||
self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None
|
||||
) -> None:
|
||||
"""
|
||||
Configure link parameters by applying tc queuing disciplines on the interface.
|
||||
|
||||
:param netif: interface one
|
||||
:param iface: interface one
|
||||
:param options: options for configuring link
|
||||
:param netif2: interface two
|
||||
:param iface2: interface two
|
||||
:return: nothing
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def getlinknetif(self, net: "CoreNetworkBase") -> Optional[CoreInterface]:
|
||||
def get_linked_iface(self, net: "CoreNetworkBase") -> Optional[CoreInterface]:
|
||||
"""
|
||||
Return the interface of that links this net with another net.
|
||||
Return the interface that links this net with another net.
|
||||
|
||||
:param net: interface to get link for
|
||||
:return: interface the provided network is linked to
|
||||
"""
|
||||
for netif in self.netifs():
|
||||
if netif.othernet == net:
|
||||
return netif
|
||||
for iface in self.get_ifaces():
|
||||
if iface.othernet == net:
|
||||
return iface
|
||||
return None
|
||||
|
||||
def attach(self, netif: CoreInterface) -> None:
|
||||
def attach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Attach network interface.
|
||||
|
||||
:param netif: network interface to attach
|
||||
:param iface: network interface to attach
|
||||
:return: nothing
|
||||
"""
|
||||
i = self.newifindex()
|
||||
self._netif[i] = netif
|
||||
netif.netifi = i
|
||||
i = self.next_iface_id()
|
||||
self.ifaces[i] = iface
|
||||
iface.net_id = i
|
||||
with self._linked_lock:
|
||||
self._linked[netif] = {}
|
||||
self._linked[iface] = {}
|
||||
|
||||
def detach(self, netif: CoreInterface) -> None:
|
||||
def detach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Detach network interface.
|
||||
|
||||
:param netif: network interface to detach
|
||||
:param iface: network interface to detach
|
||||
:return: nothing
|
||||
"""
|
||||
del self._netif[netif.netifi]
|
||||
netif.netifi = None
|
||||
del self.ifaces[iface.net_id]
|
||||
iface.net_id = None
|
||||
with self._linked_lock:
|
||||
del self._linked[netif]
|
||||
del self._linked[iface]
|
||||
|
||||
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
||||
"""
|
||||
|
@ -1102,41 +1076,39 @@ class CoreNetworkBase(NodeBase):
|
|||
|
||||
# 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
|
||||
for iface in self.get_ifaces():
|
||||
uni = False
|
||||
linked_node = netif.node
|
||||
linked_node = iface.node
|
||||
if linked_node is None:
|
||||
# two layer-2 switches/hubs linked together via linknet()
|
||||
if not netif.othernet:
|
||||
if not iface.othernet:
|
||||
continue
|
||||
linked_node = netif.othernet
|
||||
linked_node = iface.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:
|
||||
iface.swapparams("_params_up")
|
||||
upstream_params = iface.getparams()
|
||||
iface.swapparams("_params_up")
|
||||
if iface.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:
|
||||
iface2_ip4 = None
|
||||
iface2_ip4_mask = None
|
||||
iface2_ip6 = None
|
||||
iface2_ip6_mask = None
|
||||
for address in iface.addrlist:
|
||||
ip, _sep, mask = address.partition("/")
|
||||
mask = int(mask)
|
||||
if netaddr.valid_ipv4(ip):
|
||||
interface2_ip4 = ip
|
||||
interface2_ip4_mask = mask
|
||||
iface2_ip4 = ip
|
||||
iface2_ip4_mask = mask
|
||||
else:
|
||||
interface2_ip6 = ip
|
||||
interface2_ip6_mask = mask
|
||||
iface2_ip6 = ip
|
||||
iface2_ip6_mask = mask
|
||||
|
||||
link_data = LinkData(
|
||||
message_type=flags,
|
||||
|
@ -1144,42 +1116,38 @@ class CoreNetworkBase(NodeBase):
|
|||
node2_id=linked_node.id,
|
||||
link_type=self.linktype,
|
||||
unidirectional=unidirectional,
|
||||
interface2_id=linked_node.getifindex(netif),
|
||||
interface2_name=netif.name,
|
||||
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"),
|
||||
loss=netif.getparam("loss"),
|
||||
iface2_id=linked_node.get_iface_id(iface),
|
||||
iface2_name=iface.name,
|
||||
iface2_mac=iface.hwaddr,
|
||||
iface2_ip4=iface2_ip4,
|
||||
iface2_ip4_mask=iface2_ip4_mask,
|
||||
iface2_ip6=iface2_ip6,
|
||||
iface2_ip6_mask=iface2_ip6_mask,
|
||||
delay=iface.getparam("delay"),
|
||||
bandwidth=iface.getparam("bw"),
|
||||
dup=iface.getparam("duplicate"),
|
||||
jitter=iface.getparam("jitter"),
|
||||
loss=iface.getparam("loss"),
|
||||
)
|
||||
|
||||
all_links.append(link_data)
|
||||
|
||||
if not uni:
|
||||
continue
|
||||
|
||||
netif.swapparams("_params_up")
|
||||
iface.swapparams("_params_up")
|
||||
link_data = LinkData(
|
||||
message_type=MessageFlags.NONE,
|
||||
node1_id=linked_node.id,
|
||||
node2_id=self.id,
|
||||
link_type=self.linktype,
|
||||
unidirectional=1,
|
||||
delay=netif.getparam("delay"),
|
||||
bandwidth=netif.getparam("bw"),
|
||||
dup=netif.getparam("duplicate"),
|
||||
jitter=netif.getparam("jitter"),
|
||||
loss=netif.getparam("loss"),
|
||||
delay=iface.getparam("delay"),
|
||||
bandwidth=iface.getparam("bw"),
|
||||
dup=iface.getparam("duplicate"),
|
||||
jitter=iface.getparam("jitter"),
|
||||
loss=iface.getparam("loss"),
|
||||
)
|
||||
netif.swapparams("_params_up")
|
||||
|
||||
iface.swapparams("_params_up")
|
||||
all_links.append(link_data)
|
||||
|
||||
return all_links
|
||||
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ class DockerNode(CoreNode):
|
|||
return
|
||||
|
||||
with self.lock:
|
||||
self._netif.clear()
|
||||
self.ifaces.clear()
|
||||
self.client.stop_container()
|
||||
self.up = False
|
||||
|
||||
|
|
|
@ -57,11 +57,11 @@ class CoreInterface:
|
|||
self.poshook: Callable[[CoreInterface], None] = lambda x: None
|
||||
# used with EMANE
|
||||
self.transport_type: Optional[TransportType] = None
|
||||
# node interface index
|
||||
self.netindex: Optional[int] = None
|
||||
# net interface index
|
||||
self.netifi: Optional[int] = None
|
||||
# index used to find flow data
|
||||
# id of interface for node
|
||||
self.node_id: Optional[int] = None
|
||||
# id of interface for network
|
||||
self.net_id: Optional[int] = None
|
||||
# id used to find flow data
|
||||
self.flow_id: Optional[int] = None
|
||||
self.server: Optional["DistributedServer"] = server
|
||||
use_ovs = session.options.get_config("ovs") == "True"
|
||||
|
@ -284,19 +284,16 @@ class Veth(CoreInterface):
|
|||
"""
|
||||
if not self.up:
|
||||
return
|
||||
|
||||
if self.node:
|
||||
try:
|
||||
self.node.node_net_client.device_flush(self.name)
|
||||
except CoreCommandError:
|
||||
logging.exception("error shutting down interface")
|
||||
|
||||
if self.localname:
|
||||
try:
|
||||
self.net_client.delete_device(self.localname)
|
||||
except CoreCommandError:
|
||||
logging.info("link already removed: %s", self.localname)
|
||||
|
||||
self.up = False
|
||||
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ class LxcNode(CoreNode):
|
|||
return
|
||||
|
||||
with self.lock:
|
||||
self._netif.clear()
|
||||
self.ifaces.clear()
|
||||
self.client.stop_container()
|
||||
self.up = False
|
||||
|
||||
|
@ -215,7 +215,7 @@ class LxcNode(CoreNode):
|
|||
self.client.copy_file(source, filename)
|
||||
self.cmd(f"chmod {mode:o} {filename}")
|
||||
|
||||
def addnetif(self, netif: CoreInterface, ifindex: int) -> None:
|
||||
super().addnetif(netif, ifindex)
|
||||
def add_iface(self, iface: CoreInterface, iface_id: int) -> None:
|
||||
super().add_iface(iface, iface_id)
|
||||
# adding small delay to allow time for adding addresses to work correctly
|
||||
time.sleep(0.5)
|
||||
|
|
|
@ -155,14 +155,14 @@ class LinuxNetClient:
|
|||
"""
|
||||
self.run(f"{TC_BIN} qdisc delete dev {device} root")
|
||||
|
||||
def checksums_off(self, interface_name: str) -> None:
|
||||
def checksums_off(self, iface_name: str) -> None:
|
||||
"""
|
||||
Turns interface checksums off.
|
||||
|
||||
:param interface_name: interface to update
|
||||
:param iface_name: interface to update
|
||||
:return: nothing
|
||||
"""
|
||||
self.run(f"{ETHTOOL_BIN} -K {interface_name} rx off tx off")
|
||||
self.run(f"{ETHTOOL_BIN} -K {iface_name} rx off tx off")
|
||||
|
||||
def create_address(self, device: str, address: str, broadcast: str = None) -> None:
|
||||
"""
|
||||
|
@ -250,26 +250,26 @@ class LinuxNetClient:
|
|||
self.device_down(name)
|
||||
self.run(f"{IP_BIN} link delete {name} type bridge")
|
||||
|
||||
def set_interface_master(self, bridge_name: str, interface_name: str) -> None:
|
||||
def set_iface_master(self, bridge_name: str, iface_name: str) -> None:
|
||||
"""
|
||||
Assign interface master to a Linux bridge.
|
||||
|
||||
:param bridge_name: bridge name
|
||||
:param interface_name: interface name
|
||||
:param iface_name: interface name
|
||||
:return: nothing
|
||||
"""
|
||||
self.run(f"{IP_BIN} link set dev {interface_name} master {bridge_name}")
|
||||
self.device_up(interface_name)
|
||||
self.run(f"{IP_BIN} link set dev {iface_name} master {bridge_name}")
|
||||
self.device_up(iface_name)
|
||||
|
||||
def delete_interface(self, bridge_name: str, interface_name: str) -> None:
|
||||
def delete_iface(self, bridge_name: str, iface_name: str) -> None:
|
||||
"""
|
||||
Delete an interface associated with a Linux bridge.
|
||||
|
||||
:param bridge_name: bridge name
|
||||
:param interface_name: interface name
|
||||
:param iface_name: interface name
|
||||
:return: nothing
|
||||
"""
|
||||
self.run(f"{IP_BIN} link set dev {interface_name} nomaster")
|
||||
self.run(f"{IP_BIN} link set dev {iface_name} nomaster")
|
||||
|
||||
def existing_bridges(self, _id: int) -> bool:
|
||||
"""
|
||||
|
@ -330,26 +330,26 @@ class OvsNetClient(LinuxNetClient):
|
|||
self.device_down(name)
|
||||
self.run(f"{OVS_BIN} del-br {name}")
|
||||
|
||||
def set_interface_master(self, bridge_name: str, interface_name: str) -> None:
|
||||
def set_iface_master(self, bridge_name: str, iface_name: str) -> None:
|
||||
"""
|
||||
Create an interface associated with a network bridge.
|
||||
|
||||
:param bridge_name: bridge name
|
||||
:param interface_name: interface name
|
||||
:param iface_name: interface name
|
||||
:return: nothing
|
||||
"""
|
||||
self.run(f"{OVS_BIN} add-port {bridge_name} {interface_name}")
|
||||
self.device_up(interface_name)
|
||||
self.run(f"{OVS_BIN} add-port {bridge_name} {iface_name}")
|
||||
self.device_up(iface_name)
|
||||
|
||||
def delete_interface(self, bridge_name: str, interface_name: str) -> None:
|
||||
def delete_iface(self, bridge_name: str, iface_name: str) -> None:
|
||||
"""
|
||||
Delete an interface associated with a OVS bridge.
|
||||
|
||||
:param bridge_name: bridge name
|
||||
:param interface_name: interface name
|
||||
:param iface_name: interface name
|
||||
:return: nothing
|
||||
"""
|
||||
self.run(f"{OVS_BIN} del-port {bridge_name} {interface_name}")
|
||||
self.run(f"{OVS_BIN} del-port {bridge_name} {iface_name}")
|
||||
|
||||
def existing_bridges(self, _id: int) -> bool:
|
||||
"""
|
||||
|
|
|
@ -216,20 +216,20 @@ class EbtablesQueue:
|
|||
]
|
||||
)
|
||||
# rebuild the chain
|
||||
for netif1, v in wlan._linked.items():
|
||||
for netif2, linked in v.items():
|
||||
for iface1, v in wlan._linked.items():
|
||||
for oface2, linked in v.items():
|
||||
if wlan.policy == NetworkPolicy.DROP and linked:
|
||||
self.cmds.extend(
|
||||
[
|
||||
f"-A {wlan.brname} -i {netif1.localname} -o {netif2.localname} -j ACCEPT",
|
||||
f"-A {wlan.brname} -o {netif1.localname} -i {netif2.localname} -j ACCEPT",
|
||||
f"-A {wlan.brname} -i {iface1.localname} -o {oface2.localname} -j ACCEPT",
|
||||
f"-A {wlan.brname} -o {iface1.localname} -i {oface2.localname} -j ACCEPT",
|
||||
]
|
||||
)
|
||||
elif wlan.policy == NetworkPolicy.ACCEPT and not linked:
|
||||
self.cmds.extend(
|
||||
[
|
||||
f"-A {wlan.brname} -i {netif1.localname} -o {netif2.localname} -j DROP",
|
||||
f"-A {wlan.brname} -o {netif1.localname} -i {netif2.localname} -j DROP",
|
||||
f"-A {wlan.brname} -i {iface1.localname} -o {oface2.localname} -j DROP",
|
||||
f"-A {wlan.brname} -o {iface1.localname} -i {oface2.localname} -j DROP",
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -347,53 +347,53 @@ class CoreNetwork(CoreNetworkBase):
|
|||
logging.exception("error during shutdown")
|
||||
|
||||
# removes veth pairs used for bridge-to-bridge connections
|
||||
for netif in self.netifs():
|
||||
netif.shutdown()
|
||||
for iface in self.get_ifaces():
|
||||
iface.shutdown()
|
||||
|
||||
self._netif.clear()
|
||||
self.ifaces.clear()
|
||||
self._linked.clear()
|
||||
del self.session
|
||||
self.up = False
|
||||
|
||||
def attach(self, netif: CoreInterface) -> None:
|
||||
def attach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Attach a network interface.
|
||||
|
||||
:param netif: network interface to attach
|
||||
:param iface: network interface to attach
|
||||
:return: nothing
|
||||
"""
|
||||
if self.up:
|
||||
netif.net_client.set_interface_master(self.brname, netif.localname)
|
||||
super().attach(netif)
|
||||
iface.net_client.set_iface_master(self.brname, iface.localname)
|
||||
super().attach(iface)
|
||||
|
||||
def detach(self, netif: CoreInterface) -> None:
|
||||
def detach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Detach a network interface.
|
||||
|
||||
:param netif: network interface to detach
|
||||
:param iface: network interface to detach
|
||||
:return: nothing
|
||||
"""
|
||||
if self.up:
|
||||
netif.net_client.delete_interface(self.brname, netif.localname)
|
||||
super().detach(netif)
|
||||
iface.net_client.delete_iface(self.brname, iface.localname)
|
||||
super().detach(iface)
|
||||
|
||||
def linked(self, netif1: CoreInterface, netif2: CoreInterface) -> bool:
|
||||
def linked(self, iface1: CoreInterface, iface2: CoreInterface) -> bool:
|
||||
"""
|
||||
Determine if the provided network interfaces are linked.
|
||||
|
||||
:param netif1: interface one
|
||||
:param netif2: interface two
|
||||
:param iface1: interface one
|
||||
:param iface2: interface two
|
||||
:return: True if interfaces are linked, False otherwise
|
||||
"""
|
||||
# check if the network interfaces are attached to this network
|
||||
if self._netif[netif1.netifi] != netif1:
|
||||
raise ValueError(f"inconsistency for netif {netif1.name}")
|
||||
if self.ifaces[iface1.net_id] != iface1:
|
||||
raise ValueError(f"inconsistency for interface {iface1.name}")
|
||||
|
||||
if self._netif[netif2.netifi] != netif2:
|
||||
raise ValueError(f"inconsistency for netif {netif2.name}")
|
||||
if self.ifaces[iface2.net_id] != iface2:
|
||||
raise ValueError(f"inconsistency for interface {iface2.name}")
|
||||
|
||||
try:
|
||||
linked = self._linked[netif1][netif2]
|
||||
linked = self._linked[iface1][iface2]
|
||||
except KeyError:
|
||||
if self.policy == NetworkPolicy.ACCEPT:
|
||||
linked = True
|
||||
|
@ -401,93 +401,93 @@ class CoreNetwork(CoreNetworkBase):
|
|||
linked = False
|
||||
else:
|
||||
raise Exception(f"unknown policy: {self.policy.value}")
|
||||
self._linked[netif1][netif2] = linked
|
||||
self._linked[iface1][iface2] = linked
|
||||
|
||||
return linked
|
||||
|
||||
def unlink(self, netif1: CoreInterface, netif2: CoreInterface) -> None:
|
||||
def unlink(self, iface1: CoreInterface, iface2: CoreInterface) -> None:
|
||||
"""
|
||||
Unlink two interfaces, resulting in adding or removing ebtables
|
||||
filtering rules.
|
||||
|
||||
:param netif1: interface one
|
||||
:param netif2: interface two
|
||||
:param iface1: interface one
|
||||
:param iface2: interface two
|
||||
:return: nothing
|
||||
"""
|
||||
with self._linked_lock:
|
||||
if not self.linked(netif1, netif2):
|
||||
if not self.linked(iface1, iface2):
|
||||
return
|
||||
self._linked[netif1][netif2] = False
|
||||
self._linked[iface1][iface2] = False
|
||||
|
||||
ebq.ebchange(self)
|
||||
|
||||
def link(self, netif1: CoreInterface, netif2: CoreInterface) -> None:
|
||||
def link(self, iface1: CoreInterface, iface2: CoreInterface) -> None:
|
||||
"""
|
||||
Link two interfaces together, resulting in adding or removing
|
||||
ebtables filtering rules.
|
||||
|
||||
:param netif1: interface one
|
||||
:param netif2: interface two
|
||||
:param iface1: interface one
|
||||
:param iface2: interface two
|
||||
:return: nothing
|
||||
"""
|
||||
with self._linked_lock:
|
||||
if self.linked(netif1, netif2):
|
||||
if self.linked(iface1, iface2):
|
||||
return
|
||||
self._linked[netif1][netif2] = True
|
||||
self._linked[iface1][iface2] = True
|
||||
|
||||
ebq.ebchange(self)
|
||||
|
||||
def linkconfig(
|
||||
self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
|
||||
self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None
|
||||
) -> None:
|
||||
"""
|
||||
Configure link parameters by applying tc queuing disciplines on the interface.
|
||||
|
||||
:param netif: interface one
|
||||
:param iface: interface one
|
||||
:param options: options for configuring link
|
||||
:param netif2: interface two
|
||||
:param iface2: interface two
|
||||
:return: nothing
|
||||
"""
|
||||
devname = netif.localname
|
||||
devname = iface.localname
|
||||
tc = f"{TC_BIN} qdisc replace dev {devname}"
|
||||
parent = "root"
|
||||
changed = False
|
||||
bw = options.bandwidth
|
||||
if netif.setparam("bw", bw):
|
||||
if iface.setparam("bw", bw):
|
||||
# from tc-tbf(8): minimum value for burst is rate / kernel_hz
|
||||
burst = max(2 * netif.mtu, int(bw / 1000))
|
||||
burst = max(2 * iface.mtu, int(bw / 1000))
|
||||
# max IP payload
|
||||
limit = 0xFFFF
|
||||
tbf = f"tbf rate {bw} burst {burst} limit {limit}"
|
||||
if bw > 0:
|
||||
if self.up:
|
||||
cmd = f"{tc} {parent} handle 1: {tbf}"
|
||||
netif.host_cmd(cmd)
|
||||
netif.setparam("has_tbf", True)
|
||||
iface.host_cmd(cmd)
|
||||
iface.setparam("has_tbf", True)
|
||||
changed = True
|
||||
elif netif.getparam("has_tbf") and bw <= 0:
|
||||
elif iface.getparam("has_tbf") and bw <= 0:
|
||||
if self.up:
|
||||
cmd = f"{TC_BIN} qdisc delete dev {devname} {parent}"
|
||||
netif.host_cmd(cmd)
|
||||
netif.setparam("has_tbf", False)
|
||||
iface.host_cmd(cmd)
|
||||
iface.setparam("has_tbf", False)
|
||||
# removing the parent removes the child
|
||||
netif.setparam("has_netem", False)
|
||||
iface.setparam("has_netem", False)
|
||||
changed = True
|
||||
if netif.getparam("has_tbf"):
|
||||
if iface.getparam("has_tbf"):
|
||||
parent = "parent 1:1"
|
||||
netem = "netem"
|
||||
delay = options.delay
|
||||
changed = max(changed, netif.setparam("delay", delay))
|
||||
changed = max(changed, iface.setparam("delay", delay))
|
||||
loss = options.loss
|
||||
if loss is not None:
|
||||
loss = float(loss)
|
||||
changed = max(changed, netif.setparam("loss", loss))
|
||||
changed = max(changed, iface.setparam("loss", loss))
|
||||
duplicate = options.dup
|
||||
if duplicate is not None:
|
||||
duplicate = int(duplicate)
|
||||
changed = max(changed, netif.setparam("duplicate", duplicate))
|
||||
changed = max(changed, iface.setparam("duplicate", duplicate))
|
||||
jitter = options.jitter
|
||||
changed = max(changed, netif.setparam("jitter", jitter))
|
||||
changed = max(changed, iface.setparam("jitter", jitter))
|
||||
if not changed:
|
||||
return
|
||||
# jitter and delay use the same delay statement
|
||||
|
@ -510,19 +510,19 @@ class CoreNetwork(CoreNetworkBase):
|
|||
duplicate_check = duplicate is None or duplicate <= 0
|
||||
if all([delay_check, jitter_check, loss_check, duplicate_check]):
|
||||
# possibly remove netem if it exists and parent queue wasn't removed
|
||||
if not netif.getparam("has_netem"):
|
||||
if not iface.getparam("has_netem"):
|
||||
return
|
||||
if self.up:
|
||||
cmd = f"{TC_BIN} qdisc delete dev {devname} {parent} handle 10:"
|
||||
netif.host_cmd(cmd)
|
||||
netif.setparam("has_netem", False)
|
||||
iface.host_cmd(cmd)
|
||||
iface.setparam("has_netem", False)
|
||||
elif len(netem) > 1:
|
||||
if self.up:
|
||||
cmd = (
|
||||
f"{TC_BIN} qdisc replace dev {devname} {parent} handle 10: {netem}"
|
||||
)
|
||||
netif.host_cmd(cmd)
|
||||
netif.setparam("has_netem", True)
|
||||
iface.host_cmd(cmd)
|
||||
iface.setparam("has_netem", True)
|
||||
|
||||
def linknet(self, net: CoreNetworkBase) -> CoreInterface:
|
||||
"""
|
||||
|
@ -551,19 +551,19 @@ class CoreNetwork(CoreNetworkBase):
|
|||
if len(name) >= 16:
|
||||
raise ValueError(f"interface name {name} too long")
|
||||
|
||||
netif = Veth(self.session, None, name, localname, start=self.up)
|
||||
self.attach(netif)
|
||||
iface = Veth(self.session, None, name, localname, start=self.up)
|
||||
self.attach(iface)
|
||||
if net.up and net.brname:
|
||||
netif.net_client.set_interface_master(net.brname, netif.name)
|
||||
i = net.newifindex()
|
||||
net._netif[i] = netif
|
||||
iface.net_client.set_iface_master(net.brname, iface.name)
|
||||
i = net.next_iface_id()
|
||||
net.ifaces[i] = iface
|
||||
with net._linked_lock:
|
||||
net._linked[netif] = {}
|
||||
netif.net = self
|
||||
netif.othernet = net
|
||||
return netif
|
||||
net._linked[iface] = {}
|
||||
iface.net = self
|
||||
iface.othernet = net
|
||||
return iface
|
||||
|
||||
def getlinknetif(self, net: CoreNetworkBase) -> Optional[CoreInterface]:
|
||||
def get_linked_iface(self, net: CoreNetworkBase) -> Optional[CoreInterface]:
|
||||
"""
|
||||
Return the interface of that links this net with another net
|
||||
(that were linked using linknet()).
|
||||
|
@ -571,9 +571,9 @@ class CoreNetwork(CoreNetworkBase):
|
|||
:param net: interface to get link for
|
||||
:return: interface the provided network is linked to
|
||||
"""
|
||||
for netif in self.netifs():
|
||||
if netif.othernet == net:
|
||||
return netif
|
||||
for iface in self.get_ifaces():
|
||||
if iface.othernet == net:
|
||||
return iface
|
||||
return None
|
||||
|
||||
def addrconfig(self, addrlist: List[str]) -> None:
|
||||
|
@ -690,17 +690,17 @@ class GreTapBridge(CoreNetwork):
|
|||
)
|
||||
self.attach(self.gretap)
|
||||
|
||||
def setkey(self, key: int, interface_data: InterfaceData) -> None:
|
||||
def setkey(self, key: int, iface_data: InterfaceData) -> None:
|
||||
"""
|
||||
Set the GRE key used for the GreTap device. This needs to be set
|
||||
prior to instantiating the GreTap device (before addrconfig).
|
||||
|
||||
:param key: gre key
|
||||
:param interface_data: interface data for setting up tunnel key
|
||||
:param iface_data: interface data for setting up tunnel key
|
||||
:return: nothing
|
||||
"""
|
||||
self.grekey = key
|
||||
addresses = interface_data.get_addresses()
|
||||
addresses = iface_data.get_addresses()
|
||||
if addresses:
|
||||
self.addrconfig(addresses)
|
||||
|
||||
|
@ -802,7 +802,7 @@ class CtrlNet(CoreNetwork):
|
|||
self.host_cmd(f"{self.updown_script} {self.brname} startup")
|
||||
|
||||
if self.serverintf:
|
||||
self.net_client.set_interface_master(self.brname, self.serverintf)
|
||||
self.net_client.set_iface_master(self.brname, self.serverintf)
|
||||
|
||||
def shutdown(self) -> None:
|
||||
"""
|
||||
|
@ -812,7 +812,7 @@ class CtrlNet(CoreNetwork):
|
|||
"""
|
||||
if self.serverintf is not None:
|
||||
try:
|
||||
self.net_client.delete_interface(self.brname, self.serverintf)
|
||||
self.net_client.delete_iface(self.brname, self.serverintf)
|
||||
except CoreCommandError:
|
||||
logging.exception(
|
||||
"error deleting server interface %s from bridge %s",
|
||||
|
@ -850,18 +850,18 @@ class PtpNet(CoreNetwork):
|
|||
|
||||
policy: NetworkPolicy = NetworkPolicy.ACCEPT
|
||||
|
||||
def attach(self, netif: CoreInterface) -> None:
|
||||
def attach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Attach a network interface, but limit attachment to two interfaces.
|
||||
|
||||
:param netif: network interface
|
||||
:param iface: network interface
|
||||
:return: nothing
|
||||
"""
|
||||
if len(self._netif) >= 2:
|
||||
if len(self.ifaces) >= 2:
|
||||
raise ValueError(
|
||||
"Point-to-point links support at most 2 network interfaces"
|
||||
)
|
||||
super().attach(netif)
|
||||
super().attach(iface)
|
||||
|
||||
def data(
|
||||
self, message_type: MessageFlags = MessageFlags.NONE, source: str = None
|
||||
|
@ -886,67 +886,67 @@ class PtpNet(CoreNetwork):
|
|||
"""
|
||||
all_links = []
|
||||
|
||||
if len(self._netif) != 2:
|
||||
if len(self.ifaces) != 2:
|
||||
return all_links
|
||||
|
||||
interface1, interface2 = self._netif.values()
|
||||
iface1, iface2 = self.get_ifaces()
|
||||
unidirectional = 0
|
||||
if interface1.getparams() != interface2.getparams():
|
||||
if iface1.getparams() != iface2.getparams():
|
||||
unidirectional = 1
|
||||
|
||||
interface1_ip4 = None
|
||||
interface1_ip4_mask = None
|
||||
interface1_ip6 = None
|
||||
interface1_ip6_mask = None
|
||||
for address in interface1.addrlist:
|
||||
iface1_ip4 = None
|
||||
iface1_ip4_mask = None
|
||||
iface1_ip6 = None
|
||||
iface1_ip6_mask = None
|
||||
for address in iface1.addrlist:
|
||||
ip, _sep, mask = address.partition("/")
|
||||
mask = int(mask)
|
||||
if netaddr.valid_ipv4(ip):
|
||||
interface1_ip4 = ip
|
||||
interface1_ip4_mask = mask
|
||||
iface1_ip4 = ip
|
||||
iface1_ip4_mask = mask
|
||||
else:
|
||||
interface1_ip6 = ip
|
||||
interface1_ip6_mask = mask
|
||||
iface1_ip6 = ip
|
||||
iface1_ip6_mask = mask
|
||||
|
||||
interface2_ip4 = None
|
||||
interface2_ip4_mask = None
|
||||
interface2_ip6 = None
|
||||
interface2_ip6_mask = None
|
||||
for address in interface2.addrlist:
|
||||
iface2_ip4 = None
|
||||
iface2_ip4_mask = None
|
||||
iface2_ip6 = None
|
||||
iface2_ip6_mask = None
|
||||
for address in iface2.addrlist:
|
||||
ip, _sep, mask = address.partition("/")
|
||||
mask = int(mask)
|
||||
if netaddr.valid_ipv4(ip):
|
||||
interface2_ip4 = ip
|
||||
interface2_ip4_mask = mask
|
||||
iface2_ip4 = ip
|
||||
iface2_ip4_mask = mask
|
||||
else:
|
||||
interface2_ip6 = ip
|
||||
interface2_ip6_mask = mask
|
||||
iface2_ip6 = ip
|
||||
iface2_ip6_mask = mask
|
||||
|
||||
link_data = LinkData(
|
||||
message_type=flags,
|
||||
node1_id=interface1.node.id,
|
||||
node2_id=interface2.node.id,
|
||||
node1_id=iface1.node.id,
|
||||
node2_id=iface2.node.id,
|
||||
link_type=self.linktype,
|
||||
unidirectional=unidirectional,
|
||||
delay=interface1.getparam("delay"),
|
||||
bandwidth=interface1.getparam("bw"),
|
||||
loss=interface1.getparam("loss"),
|
||||
dup=interface1.getparam("duplicate"),
|
||||
jitter=interface1.getparam("jitter"),
|
||||
interface1_id=interface1.node.getifindex(interface1),
|
||||
interface1_name=interface1.name,
|
||||
interface1_mac=interface1.hwaddr,
|
||||
interface1_ip4=interface1_ip4,
|
||||
interface1_ip4_mask=interface1_ip4_mask,
|
||||
interface1_ip6=interface1_ip6,
|
||||
interface1_ip6_mask=interface1_ip6_mask,
|
||||
interface2_id=interface2.node.getifindex(interface2),
|
||||
interface2_name=interface2.name,
|
||||
interface2_mac=interface2.hwaddr,
|
||||
interface2_ip4=interface2_ip4,
|
||||
interface2_ip4_mask=interface2_ip4_mask,
|
||||
interface2_ip6=interface2_ip6,
|
||||
interface2_ip6_mask=interface2_ip6_mask,
|
||||
delay=iface1.getparam("delay"),
|
||||
bandwidth=iface1.getparam("bw"),
|
||||
loss=iface1.getparam("loss"),
|
||||
dup=iface1.getparam("duplicate"),
|
||||
jitter=iface1.getparam("jitter"),
|
||||
iface1_id=iface1.node.get_iface_id(iface1),
|
||||
iface1_name=iface1.name,
|
||||
iface1_mac=iface1.hwaddr,
|
||||
iface1_ip4=iface1_ip4,
|
||||
iface1_ip4_mask=iface1_ip4_mask,
|
||||
iface1_ip6=iface1_ip6,
|
||||
iface1_ip6_mask=iface1_ip6_mask,
|
||||
iface2_id=iface2.node.get_iface_id(iface2),
|
||||
iface2_name=iface2.name,
|
||||
iface2_mac=iface2.hwaddr,
|
||||
iface2_ip4=iface2_ip4,
|
||||
iface2_ip4_mask=iface2_ip4_mask,
|
||||
iface2_ip6=iface2_ip6,
|
||||
iface2_ip6_mask=iface2_ip6_mask,
|
||||
)
|
||||
all_links.append(link_data)
|
||||
|
||||
|
@ -956,16 +956,16 @@ class PtpNet(CoreNetwork):
|
|||
link_data = LinkData(
|
||||
message_type=MessageFlags.NONE,
|
||||
link_type=self.linktype,
|
||||
node1_id=interface2.node.id,
|
||||
node2_id=interface1.node.id,
|
||||
delay=interface2.getparam("delay"),
|
||||
bandwidth=interface2.getparam("bw"),
|
||||
loss=interface2.getparam("loss"),
|
||||
dup=interface2.getparam("duplicate"),
|
||||
jitter=interface2.getparam("jitter"),
|
||||
node1_id=iface2.node.id,
|
||||
node2_id=iface1.node.id,
|
||||
delay=iface2.getparam("delay"),
|
||||
bandwidth=iface2.getparam("bw"),
|
||||
loss=iface2.getparam("loss"),
|
||||
dup=iface2.getparam("duplicate"),
|
||||
jitter=iface2.getparam("jitter"),
|
||||
unidirectional=1,
|
||||
interface1_id=interface2.node.getifindex(interface2),
|
||||
interface2_id=interface1.node.getifindex(interface1),
|
||||
iface1_id=iface2.node.get_iface_id(iface2),
|
||||
iface2_id=iface1.node.get_iface_id(iface1),
|
||||
)
|
||||
all_links.append(link_data)
|
||||
return all_links
|
||||
|
@ -1045,17 +1045,17 @@ class WlanNode(CoreNetwork):
|
|||
self.net_client.disable_mac_learning(self.brname)
|
||||
ebq.ebchange(self)
|
||||
|
||||
def attach(self, netif: CoreInterface) -> None:
|
||||
def attach(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
Attach a network interface.
|
||||
|
||||
:param netif: network interface
|
||||
:param iface: network interface
|
||||
:return: nothing
|
||||
"""
|
||||
super().attach(netif)
|
||||
super().attach(iface)
|
||||
if self.model:
|
||||
netif.poshook = self.model.position_callback
|
||||
netif.setposition()
|
||||
iface.poshook = self.model.position_callback
|
||||
iface.setposition()
|
||||
|
||||
def setmodel(self, model: "WirelessModelType", config: Dict[str, str]):
|
||||
"""
|
||||
|
@ -1068,9 +1068,9 @@ class WlanNode(CoreNetwork):
|
|||
logging.debug("node(%s) setting model: %s", self.name, model.name)
|
||||
if model.config_type == RegisterTlvs.WIRELESS:
|
||||
self.model = model(session=self.session, _id=self.id)
|
||||
for netif in self.netifs():
|
||||
netif.poshook = self.model.position_callback
|
||||
netif.setposition()
|
||||
for iface in self.get_ifaces():
|
||||
iface.poshook = self.model.position_callback
|
||||
iface.setposition()
|
||||
self.updatemodel(config)
|
||||
elif model.config_type == RegisterTlvs.MOBILITY:
|
||||
self.mobility = model(session=self.session, _id=self.id)
|
||||
|
@ -1088,8 +1088,8 @@ class WlanNode(CoreNetwork):
|
|||
"node(%s) updating model(%s): %s", self.id, self.model.name, config
|
||||
)
|
||||
self.model.update_config(config)
|
||||
for netif in self.netifs():
|
||||
netif.setposition()
|
||||
for iface in self.get_ifaces():
|
||||
iface.setposition()
|
||||
|
||||
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
||||
"""
|
||||
|
|
|
@ -51,8 +51,8 @@ class PhysicalNode(CoreNodeBase):
|
|||
_source, target = self._mounts.pop(-1)
|
||||
self.umount(target)
|
||||
|
||||
for netif in self.netifs():
|
||||
netif.shutdown()
|
||||
for iface in self.get_ifaces():
|
||||
iface.shutdown()
|
||||
|
||||
self.rmnodedir()
|
||||
|
||||
|
@ -65,117 +65,115 @@ class PhysicalNode(CoreNodeBase):
|
|||
"""
|
||||
return sh
|
||||
|
||||
def sethwaddr(self, ifindex: int, addr: str) -> None:
|
||||
def sethwaddr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Set hardware address for an interface.
|
||||
|
||||
:param ifindex: index of interface to set hardware address for
|
||||
:param iface_id: index of interface to set hardware address for
|
||||
:param addr: hardware address to set
|
||||
:return: nothing
|
||||
:raises CoreCommandError: when a non-zero exit status occurs
|
||||
"""
|
||||
addr = utils.validate_mac(addr)
|
||||
interface = self._netif[ifindex]
|
||||
interface.sethwaddr(addr)
|
||||
iface = self.ifaces[iface_id]
|
||||
iface.sethwaddr(addr)
|
||||
if self.up:
|
||||
self.net_client.device_mac(interface.name, addr)
|
||||
self.net_client.device_mac(iface.name, addr)
|
||||
|
||||
def addaddr(self, ifindex: int, addr: str) -> None:
|
||||
def addaddr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Add an address to an interface.
|
||||
|
||||
:param ifindex: index of interface to add address to
|
||||
:param iface_id: index of interface to add address to
|
||||
:param addr: address to add
|
||||
:return: nothing
|
||||
"""
|
||||
addr = utils.validate_ip(addr)
|
||||
interface = self._netif[ifindex]
|
||||
iface = self.get_iface(iface_id)
|
||||
if self.up:
|
||||
self.net_client.create_address(interface.name, addr)
|
||||
interface.addaddr(addr)
|
||||
self.net_client.create_address(iface.name, addr)
|
||||
iface.addaddr(addr)
|
||||
|
||||
def deladdr(self, ifindex: int, addr: str) -> None:
|
||||
def deladdr(self, iface_id: int, addr: str) -> None:
|
||||
"""
|
||||
Delete an address from an interface.
|
||||
|
||||
:param ifindex: index of interface to delete
|
||||
:param iface_id: index of interface to delete
|
||||
:param addr: address to delete
|
||||
:return: nothing
|
||||
"""
|
||||
interface = self._netif[ifindex]
|
||||
|
||||
iface = self.ifaces[iface_id]
|
||||
try:
|
||||
interface.deladdr(addr)
|
||||
iface.deladdr(addr)
|
||||
except ValueError:
|
||||
logging.exception("trying to delete unknown address: %s", addr)
|
||||
|
||||
if self.up:
|
||||
self.net_client.delete_address(interface.name, addr)
|
||||
self.net_client.delete_address(iface.name, addr)
|
||||
|
||||
def adoptnetif(
|
||||
self, netif: CoreInterface, ifindex: int, hwaddr: str, addrlist: List[str]
|
||||
def adopt_iface(
|
||||
self, iface: CoreInterface, iface_id: int, hwaddr: str, addrlist: List[str]
|
||||
) -> None:
|
||||
"""
|
||||
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.
|
||||
GreTap interface as the node interface.
|
||||
"""
|
||||
netif.name = f"gt{ifindex}"
|
||||
netif.node = self
|
||||
self.addnetif(netif, ifindex)
|
||||
iface.name = f"gt{iface_id}"
|
||||
iface.node = self
|
||||
self.add_iface(iface, iface_id)
|
||||
# use a more reasonable name, e.g. "gt0" instead of "gt.56286.150"
|
||||
if self.up:
|
||||
self.net_client.device_down(netif.localname)
|
||||
self.net_client.device_name(netif.localname, netif.name)
|
||||
netif.localname = netif.name
|
||||
self.net_client.device_down(iface.localname)
|
||||
self.net_client.device_name(iface.localname, iface.name)
|
||||
iface.localname = iface.name
|
||||
if hwaddr:
|
||||
self.sethwaddr(ifindex, hwaddr)
|
||||
self.sethwaddr(iface_id, hwaddr)
|
||||
for addr in addrlist:
|
||||
self.addaddr(ifindex, addr)
|
||||
self.addaddr(iface_id, addr)
|
||||
if self.up:
|
||||
self.net_client.device_up(netif.localname)
|
||||
self.net_client.device_up(iface.localname)
|
||||
|
||||
def linkconfig(
|
||||
self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
|
||||
self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None
|
||||
) -> None:
|
||||
"""
|
||||
Apply tc queing disciplines using linkconfig.
|
||||
"""
|
||||
linux_bridge = CoreNetwork(self.session)
|
||||
linux_bridge.up = True
|
||||
linux_bridge.linkconfig(netif, options, netif2)
|
||||
linux_bridge.linkconfig(iface, options, iface2)
|
||||
del linux_bridge
|
||||
|
||||
def newifindex(self) -> int:
|
||||
def next_iface_id(self) -> int:
|
||||
with self.lock:
|
||||
while self.ifindex in self._netif:
|
||||
self.ifindex += 1
|
||||
ifindex = self.ifindex
|
||||
self.ifindex += 1
|
||||
return ifindex
|
||||
while self.iface_id in self.ifaces:
|
||||
self.iface_id += 1
|
||||
iface_id = self.iface_id
|
||||
self.iface_id += 1
|
||||
return iface_id
|
||||
|
||||
def newnetif(
|
||||
self, net: CoreNetworkBase, interface_data: InterfaceData
|
||||
def new_iface(
|
||||
self, net: CoreNetworkBase, iface_data: InterfaceData
|
||||
) -> CoreInterface:
|
||||
logging.info("creating interface")
|
||||
addresses = interface_data.get_addresses()
|
||||
ifindex = interface_data.id
|
||||
if ifindex is None:
|
||||
ifindex = self.newifindex()
|
||||
name = interface_data.name
|
||||
addresses = iface_data.get_addresses()
|
||||
iface_id = iface_data.id
|
||||
if iface_id is None:
|
||||
iface_id = self.next_iface_id()
|
||||
name = iface_data.name
|
||||
if name is None:
|
||||
name = f"gt{ifindex}"
|
||||
name = f"gt{iface_id}"
|
||||
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
|
||||
_, remote_tap = self.session.distributed.create_gre_tunnel(net, self.server)
|
||||
self.adoptnetif(remote_tap, ifindex, interface_data.mac, addresses)
|
||||
self.adopt_iface(remote_tap, iface_id, iface_data.mac, addresses)
|
||||
return remote_tap
|
||||
else:
|
||||
# this is reached when configuring services (self.up=False)
|
||||
netif = GreTap(node=self, name=name, session=self.session, start=False)
|
||||
self.adoptnetif(netif, ifindex, interface_data.mac, addresses)
|
||||
return netif
|
||||
iface = GreTap(node=self, name=name, session=self.session, start=False)
|
||||
self.adopt_iface(iface, iface_id, iface_data.mac, addresses)
|
||||
return iface
|
||||
|
||||
def privatedir(self, path: str) -> None:
|
||||
if path[0] != "/":
|
||||
|
@ -257,10 +255,10 @@ class Rj45Node(CoreNodeBase):
|
|||
will run on, default is None for localhost
|
||||
"""
|
||||
super().__init__(session, _id, name, server)
|
||||
self.interface = CoreInterface(session, self, name, name, mtu, server)
|
||||
self.interface.transport_type = TransportType.RAW
|
||||
self.iface = CoreInterface(session, self, name, name, mtu, server)
|
||||
self.iface.transport_type = TransportType.RAW
|
||||
self.lock: threading.RLock = threading.RLock()
|
||||
self.ifindex: Optional[int] = None
|
||||
self.iface_id: Optional[int] = None
|
||||
self.old_up: bool = False
|
||||
self.old_addrs: List[Tuple[str, Optional[str]]] = []
|
||||
|
||||
|
@ -273,7 +271,7 @@ class Rj45Node(CoreNodeBase):
|
|||
"""
|
||||
# interface will also be marked up during net.attach()
|
||||
self.savestate()
|
||||
self.net_client.device_up(self.interface.localname)
|
||||
self.net_client.device_up(self.iface.localname)
|
||||
self.up = True
|
||||
|
||||
def shutdown(self) -> None:
|
||||
|
@ -285,7 +283,7 @@ class Rj45Node(CoreNodeBase):
|
|||
"""
|
||||
if not self.up:
|
||||
return
|
||||
localname = self.interface.localname
|
||||
localname = self.iface.localname
|
||||
self.net_client.device_down(localname)
|
||||
self.net_client.device_flush(localname)
|
||||
try:
|
||||
|
@ -295,8 +293,8 @@ class Rj45Node(CoreNodeBase):
|
|||
self.up = False
|
||||
self.restorestate()
|
||||
|
||||
def newnetif(
|
||||
self, net: CoreNetworkBase, interface_data: InterfaceData
|
||||
def new_iface(
|
||||
self, net: CoreNetworkBase, iface_data: InterfaceData
|
||||
) -> CoreInterface:
|
||||
"""
|
||||
This is called when linking with another node. Since this node
|
||||
|
@ -304,70 +302,51 @@ class Rj45Node(CoreNodeBase):
|
|||
but attach ourselves to the given network.
|
||||
|
||||
:param net: new network instance
|
||||
:param interface_data: interface data for new interface
|
||||
:param iface_data: interface data for new interface
|
||||
:return: interface index
|
||||
:raises ValueError: when an interface has already been created, one max
|
||||
"""
|
||||
with self.lock:
|
||||
ifindex = interface_data.id
|
||||
if ifindex is None:
|
||||
ifindex = 0
|
||||
if self.interface.net is not None:
|
||||
raise ValueError("RJ45 nodes support at most 1 network interface")
|
||||
self._netif[ifindex] = self.interface
|
||||
self.ifindex = ifindex
|
||||
iface_id = iface_data.id
|
||||
if iface_id is None:
|
||||
iface_id = 0
|
||||
if self.iface.net is not None:
|
||||
raise CoreError("RJ45 nodes support at most 1 network interface")
|
||||
self.ifaces[iface_id] = self.iface
|
||||
self.iface_id = iface_id
|
||||
if net is not None:
|
||||
self.interface.attachnet(net)
|
||||
for addr in interface_data.get_addresses():
|
||||
self.iface.attachnet(net)
|
||||
for addr in iface_data.get_addresses():
|
||||
self.addaddr(addr)
|
||||
return self.interface
|
||||
return self.iface
|
||||
|
||||
def delnetif(self, ifindex: int) -> None:
|
||||
def delete_iface(self, iface_id: int) -> None:
|
||||
"""
|
||||
Delete a network interface.
|
||||
|
||||
:param ifindex: interface index to delete
|
||||
:param iface_id: 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(f"ifindex {ifindex} does not exist")
|
||||
self.get_iface(iface_id)
|
||||
self.ifaces.pop(iface_id)
|
||||
self.shutdown()
|
||||
|
||||
def netif(
|
||||
self, ifindex: int, net: CoreNetworkBase = None
|
||||
) -> Optional[CoreInterface]:
|
||||
"""
|
||||
This object is considered the network interface, so we only
|
||||
return self here. This keeps the RJ45Node compatible with
|
||||
real nodes.
|
||||
def get_iface(self, iface_id: int) -> CoreInterface:
|
||||
if iface_id != self.iface_id or iface_id not in self.ifaces:
|
||||
raise CoreError(f"node({self.name}) interface({iface_id}) does not exist")
|
||||
return self.iface
|
||||
|
||||
:param ifindex: interface index to retrieve
|
||||
:param net: network to retrieve
|
||||
:return: a network interface
|
||||
"""
|
||||
if net is not None and net == self.interface.net:
|
||||
return self.interface
|
||||
if ifindex is None:
|
||||
ifindex = 0
|
||||
if ifindex == self.ifindex:
|
||||
return self.interface
|
||||
return None
|
||||
|
||||
def getifindex(self, netif: CoreInterface) -> Optional[int]:
|
||||
def get_iface_id(self, iface: CoreInterface) -> Optional[int]:
|
||||
"""
|
||||
Retrieve network interface index.
|
||||
|
||||
:param netif: network interface to retrieve
|
||||
:param iface: network interface to retrieve
|
||||
index for
|
||||
:return: interface index, None otherwise
|
||||
"""
|
||||
if netif != self.interface:
|
||||
return None
|
||||
return self.ifindex
|
||||
if iface is not self.iface:
|
||||
raise CoreError(f"node({self.name}) does not have interface({iface.name})")
|
||||
return self.iface_id
|
||||
|
||||
def addaddr(self, addr: str) -> None:
|
||||
"""
|
||||
|
@ -380,7 +359,7 @@ class Rj45Node(CoreNodeBase):
|
|||
addr = utils.validate_ip(addr)
|
||||
if self.up:
|
||||
self.net_client.create_address(self.name, addr)
|
||||
self.interface.addaddr(addr)
|
||||
self.iface.addaddr(addr)
|
||||
|
||||
def deladdr(self, addr: str) -> None:
|
||||
"""
|
||||
|
@ -392,7 +371,7 @@ class Rj45Node(CoreNodeBase):
|
|||
"""
|
||||
if self.up:
|
||||
self.net_client.delete_address(self.name, addr)
|
||||
self.interface.deladdr(addr)
|
||||
self.iface.deladdr(addr)
|
||||
|
||||
def savestate(self) -> None:
|
||||
"""
|
||||
|
@ -404,7 +383,7 @@ class Rj45Node(CoreNodeBase):
|
|||
"""
|
||||
self.old_up = False
|
||||
self.old_addrs: List[Tuple[str, Optional[str]]] = []
|
||||
localname = self.interface.localname
|
||||
localname = self.iface.localname
|
||||
output = self.net_client.address_show(localname)
|
||||
for line in output.split("\n"):
|
||||
items = line.split()
|
||||
|
@ -429,7 +408,7 @@ class Rj45Node(CoreNodeBase):
|
|||
:return: nothing
|
||||
:raises CoreCommandError: when there is a command exception
|
||||
"""
|
||||
localname = self.interface.localname
|
||||
localname = self.iface.localname
|
||||
logging.info("restoring rj45 state: %s", localname)
|
||||
for addr in self.old_addrs:
|
||||
self.net_client.create_address(localname, addr[0], addr[1])
|
||||
|
@ -446,7 +425,7 @@ class Rj45Node(CoreNodeBase):
|
|||
:return: True if position changed, False otherwise
|
||||
"""
|
||||
super().setposition(x, y, z)
|
||||
self.interface.setposition()
|
||||
self.iface.setposition()
|
||||
|
||||
def termcmdstring(self, sh: str) -> str:
|
||||
raise CoreError("rj45 does not support terminal commands")
|
||||
|
|
|
@ -35,10 +35,8 @@ class Bird(CoreService):
|
|||
"""
|
||||
Helper to return the first IPv4 address of a node as its router ID.
|
||||
"""
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
for a in iface.addrlist:
|
||||
a = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(a):
|
||||
return a
|
||||
|
@ -84,7 +82,7 @@ protocol device {
|
|||
for s in node.services:
|
||||
if cls.name not in s.dependencies:
|
||||
continue
|
||||
cfg += s.generatebirdconfig(node)
|
||||
cfg += s.generate_bird_config(node)
|
||||
|
||||
return cfg
|
||||
|
||||
|
@ -106,11 +104,11 @@ class BirdService(CoreService):
|
|||
meta = "The config file for this service can be found in the bird service."
|
||||
|
||||
@classmethod
|
||||
def generatebirdconfig(cls, node):
|
||||
def generate_bird_config(cls, node):
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def generatebirdifcconfig(cls, node):
|
||||
def generate_bird_iface_config(cls, node):
|
||||
"""
|
||||
Use only bare interfaces descriptions in generated protocol
|
||||
configurations. This has the slight advantage of being the same
|
||||
|
@ -118,10 +116,8 @@ class BirdService(CoreService):
|
|||
"""
|
||||
cfg = ""
|
||||
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += ' interface "%s";\n' % ifc.name
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += ' interface "%s";\n' % iface.name
|
||||
|
||||
return cfg
|
||||
|
||||
|
@ -135,7 +131,7 @@ class BirdBgp(BirdService):
|
|||
custom_needed = True
|
||||
|
||||
@classmethod
|
||||
def generatebirdconfig(cls, node):
|
||||
def generate_bird_config(cls, node):
|
||||
return """
|
||||
/* This is a sample config that should be customized with appropriate AS numbers
|
||||
* and peers; add one section like this for each neighbor */
|
||||
|
@ -165,7 +161,7 @@ class BirdOspf(BirdService):
|
|||
name = "BIRD_OSPFv2"
|
||||
|
||||
@classmethod
|
||||
def generatebirdconfig(cls, node):
|
||||
def generate_bird_config(cls, node):
|
||||
cfg = "protocol ospf {\n"
|
||||
cfg += " export filter {\n"
|
||||
cfg += " if source = RTS_BGP then {\n"
|
||||
|
@ -175,7 +171,7 @@ class BirdOspf(BirdService):
|
|||
cfg += " accept;\n"
|
||||
cfg += " };\n"
|
||||
cfg += " area 0.0.0.0 {\n"
|
||||
cfg += cls.generatebirdifcconfig(node)
|
||||
cfg += cls.generate_bird_iface_config(node)
|
||||
cfg += " };\n"
|
||||
cfg += "}\n\n"
|
||||
|
||||
|
@ -190,12 +186,12 @@ class BirdRadv(BirdService):
|
|||
name = "BIRD_RADV"
|
||||
|
||||
@classmethod
|
||||
def generatebirdconfig(cls, node):
|
||||
def generate_bird_config(cls, node):
|
||||
cfg = "/* This is a sample config that must be customized */\n"
|
||||
|
||||
cfg += "protocol radv {\n"
|
||||
cfg += " # auto configuration on all interfaces\n"
|
||||
cfg += cls.generatebirdifcconfig(node)
|
||||
cfg += cls.generate_bird_iface_config(node)
|
||||
cfg += " # Advertise DNS\n"
|
||||
cfg += " rdnss {\n"
|
||||
cfg += "# lifetime mult 10;\n"
|
||||
|
@ -218,11 +214,11 @@ class BirdRip(BirdService):
|
|||
name = "BIRD_RIP"
|
||||
|
||||
@classmethod
|
||||
def generatebirdconfig(cls, node):
|
||||
def generate_bird_config(cls, node):
|
||||
cfg = "protocol rip {\n"
|
||||
cfg += " period 10;\n"
|
||||
cfg += " garbage time 60;\n"
|
||||
cfg += cls.generatebirdifcconfig(node)
|
||||
cfg += cls.generate_bird_iface_config(node)
|
||||
cfg += " honor neighbor;\n"
|
||||
cfg += " authentication none;\n"
|
||||
cfg += " import all;\n"
|
||||
|
@ -241,7 +237,7 @@ class BirdStatic(BirdService):
|
|||
custom_needed = True
|
||||
|
||||
@classmethod
|
||||
def generatebirdconfig(cls, node):
|
||||
def generate_bird_config(cls, node):
|
||||
cfg = "/* This is a sample config that must be customized */\n"
|
||||
cfg += "protocol static {\n"
|
||||
cfg += "# route 0.0.0.0/0 via 198.51.100.130; # Default route. Do NOT advertise on BGP !\n"
|
||||
|
|
|
@ -20,14 +20,14 @@ class EmaneTransportService(CoreService):
|
|||
def generate_config(cls, node, filename):
|
||||
if filename == cls.configs[0]:
|
||||
transport_commands = []
|
||||
for interface in node.netifs(sort=True):
|
||||
for iface in node.get_ifaces():
|
||||
try:
|
||||
network_node = node.session.get_node(interface.net.id, EmaneNet)
|
||||
network_node = node.session.get_node(iface.net.id, EmaneNet)
|
||||
config = node.session.emane.get_configs(
|
||||
network_node.id, network_node.model.name
|
||||
)
|
||||
if config and emanexml.is_external(config):
|
||||
nem_id = network_node.getnemid(interface)
|
||||
nem_id = network_node.getnemid(iface)
|
||||
command = (
|
||||
"emanetransportd -r -l 0 -d ../transportdaemon%s.xml"
|
||||
% nem_id
|
||||
|
|
|
@ -59,12 +59,12 @@ class FRRZebra(CoreService):
|
|||
"""
|
||||
# we could verify here that filename == frr.conf
|
||||
cfg = ""
|
||||
for ifc in node.netifs():
|
||||
cfg += "interface %s\n" % ifc.name
|
||||
for iface in node.get_ifaces():
|
||||
cfg += "interface %s\n" % iface.name
|
||||
# include control interfaces in addressing but not routing daemons
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
if hasattr(iface, "control") and iface.control is True:
|
||||
cfg += " "
|
||||
cfg += "\n ".join(map(cls.addrstr, ifc.addrlist))
|
||||
cfg += "\n ".join(map(cls.addrstr, iface.addrlist))
|
||||
cfg += "\n"
|
||||
continue
|
||||
cfgv4 = ""
|
||||
|
@ -74,18 +74,18 @@ class FRRZebra(CoreService):
|
|||
for s in node.services:
|
||||
if cls.name not in s.dependencies:
|
||||
continue
|
||||
ifccfg = s.generatefrrifcconfig(node, ifc)
|
||||
iface_config = s.generate_frr_iface_config(node, iface)
|
||||
if s.ipv4_routing:
|
||||
want_ipv4 = True
|
||||
if s.ipv6_routing:
|
||||
want_ipv6 = True
|
||||
cfgv6 += ifccfg
|
||||
cfgv6 += iface_config
|
||||
else:
|
||||
cfgv4 += ifccfg
|
||||
cfgv4 += iface_config
|
||||
|
||||
if want_ipv4:
|
||||
ipv4list = filter(
|
||||
lambda x: netaddr.valid_ipv4(x.split("/")[0]), ifc.addrlist
|
||||
lambda x: netaddr.valid_ipv4(x.split("/")[0]), iface.addrlist
|
||||
)
|
||||
cfg += " "
|
||||
cfg += "\n ".join(map(cls.addrstr, ipv4list))
|
||||
|
@ -93,7 +93,7 @@ class FRRZebra(CoreService):
|
|||
cfg += cfgv4
|
||||
if want_ipv6:
|
||||
ipv6list = filter(
|
||||
lambda x: netaddr.valid_ipv6(x.split("/")[0]), ifc.addrlist
|
||||
lambda x: netaddr.valid_ipv6(x.split("/")[0]), iface.addrlist
|
||||
)
|
||||
cfg += " "
|
||||
cfg += "\n ".join(map(cls.addrstr, ipv6list))
|
||||
|
@ -104,7 +104,7 @@ class FRRZebra(CoreService):
|
|||
for s in node.services:
|
||||
if cls.name not in s.dependencies:
|
||||
continue
|
||||
cfg += s.generatefrrconfig(node)
|
||||
cfg += s.generate_frr_config(node)
|
||||
return cfg
|
||||
|
||||
@staticmethod
|
||||
|
@ -237,10 +237,10 @@ bootfrr
|
|||
frr_bin_search,
|
||||
constants.FRR_STATE_DIR,
|
||||
)
|
||||
for ifc in node.netifs():
|
||||
cfg += f"ip link set dev {ifc.name} down\n"
|
||||
for iface in node.get_ifaces():
|
||||
cfg += f"ip link set dev {iface.name} down\n"
|
||||
cfg += "sleep 1\n"
|
||||
cfg += f"ip link set dev {ifc.name} up\n"
|
||||
cfg += f"ip link set dev {iface.name} up\n"
|
||||
return cfg
|
||||
|
||||
@classmethod
|
||||
|
@ -334,10 +334,8 @@ class FrrService(CoreService):
|
|||
"""
|
||||
Helper to return the first IPv4 address of a node as its router ID.
|
||||
"""
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
for a in iface.addrlist:
|
||||
a = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(a):
|
||||
return a
|
||||
|
@ -345,16 +343,16 @@ class FrrService(CoreService):
|
|||
return "0.0.0.0"
|
||||
|
||||
@staticmethod
|
||||
def rj45check(ifc):
|
||||
def rj45check(iface):
|
||||
"""
|
||||
Helper to detect whether interface is connected an external RJ45
|
||||
link.
|
||||
"""
|
||||
if ifc.net:
|
||||
for peerifc in ifc.net.netifs():
|
||||
if peerifc == ifc:
|
||||
if iface.net:
|
||||
for peer_iface in iface.net.get_ifaces():
|
||||
if peer_iface == iface:
|
||||
continue
|
||||
if isinstance(peerifc.node, Rj45Node):
|
||||
if isinstance(peer_iface.node, Rj45Node):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -363,11 +361,11 @@ class FrrService(CoreService):
|
|||
return ""
|
||||
|
||||
@classmethod
|
||||
def generatefrrifcconfig(cls, node, ifc):
|
||||
def generate_frr_iface_config(cls, node, iface):
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def generatefrrconfig(cls, node):
|
||||
def generate_frr_config(cls, node):
|
||||
return ""
|
||||
|
||||
|
||||
|
@ -385,43 +383,41 @@ class FRROspfv2(FrrService):
|
|||
ipv4_routing = True
|
||||
|
||||
@staticmethod
|
||||
def mtucheck(ifc):
|
||||
def mtucheck(iface):
|
||||
"""
|
||||
Helper to detect MTU mismatch and add the appropriate OSPF
|
||||
mtu-ignore command. This is needed when e.g. a node is linked via a
|
||||
GreTap device.
|
||||
"""
|
||||
if ifc.mtu != 1500:
|
||||
if iface.mtu != 1500:
|
||||
# a workaround for PhysicalNode GreTap, which has no knowledge of
|
||||
# the other nodes/nets
|
||||
return " ip ospf mtu-ignore\n"
|
||||
if not ifc.net:
|
||||
if not iface.net:
|
||||
return ""
|
||||
for i in ifc.net.netifs():
|
||||
if i.mtu != ifc.mtu:
|
||||
for iface in iface.net.get_ifaces():
|
||||
if iface.mtu != iface.mtu:
|
||||
return " ip ospf mtu-ignore\n"
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def ptpcheck(ifc):
|
||||
def ptpcheck(iface):
|
||||
"""
|
||||
Helper to detect whether interface is connected to a notional
|
||||
point-to-point link.
|
||||
"""
|
||||
if isinstance(ifc.net, PtpNet):
|
||||
if isinstance(iface.net, PtpNet):
|
||||
return " ip ospf network point-to-point\n"
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def generatefrrconfig(cls, node):
|
||||
def generate_frr_config(cls, node):
|
||||
cfg = "router ospf\n"
|
||||
rtrid = cls.routerid(node)
|
||||
cfg += " router-id %s\n" % rtrid
|
||||
# network 10.0.0.0/24 area 0
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
for a in iface.addrlist:
|
||||
addr = a.split("/")[0]
|
||||
if not netaddr.valid_ipv4(addr):
|
||||
continue
|
||||
|
@ -430,8 +426,8 @@ class FRROspfv2(FrrService):
|
|||
return cfg
|
||||
|
||||
@classmethod
|
||||
def generatefrrifcconfig(cls, node, ifc):
|
||||
return cls.mtucheck(ifc)
|
||||
def generate_frr_iface_config(cls, node, iface):
|
||||
return cls.mtucheck(iface)
|
||||
|
||||
|
||||
class FRROspfv3(FrrService):
|
||||
|
@ -449,57 +445,55 @@ class FRROspfv3(FrrService):
|
|||
ipv6_routing = True
|
||||
|
||||
@staticmethod
|
||||
def minmtu(ifc):
|
||||
def minmtu(iface):
|
||||
"""
|
||||
Helper to discover the minimum MTU of interfaces linked with the
|
||||
given interface.
|
||||
"""
|
||||
mtu = ifc.mtu
|
||||
if not ifc.net:
|
||||
mtu = iface.mtu
|
||||
if not iface.net:
|
||||
return mtu
|
||||
for i in ifc.net.netifs():
|
||||
if i.mtu < mtu:
|
||||
mtu = i.mtu
|
||||
for iface in iface.net.get_ifaces():
|
||||
if iface.mtu < mtu:
|
||||
mtu = iface.mtu
|
||||
return mtu
|
||||
|
||||
@classmethod
|
||||
def mtucheck(cls, ifc):
|
||||
def mtucheck(cls, iface):
|
||||
"""
|
||||
Helper to detect MTU mismatch and add the appropriate OSPFv3
|
||||
ifmtu command. This is needed when e.g. a node is linked via a
|
||||
GreTap device.
|
||||
"""
|
||||
minmtu = cls.minmtu(ifc)
|
||||
if minmtu < ifc.mtu:
|
||||
minmtu = cls.minmtu(iface)
|
||||
if minmtu < iface.mtu:
|
||||
return " ipv6 ospf6 ifmtu %d\n" % minmtu
|
||||
else:
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def ptpcheck(ifc):
|
||||
def ptpcheck(iface):
|
||||
"""
|
||||
Helper to detect whether interface is connected to a notional
|
||||
point-to-point link.
|
||||
"""
|
||||
if isinstance(ifc.net, PtpNet):
|
||||
if isinstance(iface.net, PtpNet):
|
||||
return " ipv6 ospf6 network point-to-point\n"
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def generatefrrconfig(cls, node):
|
||||
def generate_frr_config(cls, node):
|
||||
cfg = "router ospf6\n"
|
||||
rtrid = cls.routerid(node)
|
||||
cfg += " router-id %s\n" % rtrid
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += " interface %s area 0.0.0.0\n" % ifc.name
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += " interface %s area 0.0.0.0\n" % iface.name
|
||||
cfg += "!\n"
|
||||
return cfg
|
||||
|
||||
@classmethod
|
||||
def generatefrrifcconfig(cls, node, ifc):
|
||||
return cls.mtucheck(ifc)
|
||||
def generate_frr_iface_config(cls, node, iface):
|
||||
return cls.mtucheck(iface)
|
||||
# cfg = cls.mtucheck(ifc)
|
||||
# external RJ45 connections will use default OSPF timers
|
||||
# if cls.rj45check(ifc):
|
||||
|
@ -531,7 +525,7 @@ class FRRBgp(FrrService):
|
|||
ipv6_routing = True
|
||||
|
||||
@classmethod
|
||||
def generatefrrconfig(cls, node):
|
||||
def generate_frr_config(cls, node):
|
||||
cfg = "!\n! BGP configuration\n!\n"
|
||||
cfg += "! You should configure the AS number below,\n"
|
||||
cfg += "! along with this router's peers.\n!\n"
|
||||
|
@ -555,7 +549,7 @@ class FRRRip(FrrService):
|
|||
ipv4_routing = True
|
||||
|
||||
@classmethod
|
||||
def generatefrrconfig(cls, node):
|
||||
def generate_frr_config(cls, node):
|
||||
cfg = """\
|
||||
router rip
|
||||
redistribute static
|
||||
|
@ -579,7 +573,7 @@ class FRRRipng(FrrService):
|
|||
ipv6_routing = True
|
||||
|
||||
@classmethod
|
||||
def generatefrrconfig(cls, node):
|
||||
def generate_frr_config(cls, node):
|
||||
cfg = """\
|
||||
router ripng
|
||||
redistribute static
|
||||
|
@ -604,18 +598,16 @@ class FRRBabel(FrrService):
|
|||
ipv6_routing = True
|
||||
|
||||
@classmethod
|
||||
def generatefrrconfig(cls, node):
|
||||
def generate_frr_config(cls, node):
|
||||
cfg = "router babel\n"
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += " network %s\n" % ifc.name
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += " network %s\n" % iface.name
|
||||
cfg += " redistribute static\n redistribute ipv4 connected\n"
|
||||
return cfg
|
||||
|
||||
@classmethod
|
||||
def generatefrrifcconfig(cls, node, ifc):
|
||||
if ifc.net and isinstance(ifc.net, (EmaneNet, WlanNode)):
|
||||
def generate_frr_iface_config(cls, node, iface):
|
||||
if iface.net and isinstance(iface.net, (EmaneNet, WlanNode)):
|
||||
return " babel wireless\n no babel split-horizon\n"
|
||||
else:
|
||||
return " babel wired\n babel split-horizon\n"
|
||||
|
@ -633,11 +625,11 @@ class FRRpimd(FrrService):
|
|||
ipv4_routing = True
|
||||
|
||||
@classmethod
|
||||
def generatefrrconfig(cls, node):
|
||||
def generate_frr_config(cls, node):
|
||||
ifname = "eth0"
|
||||
for ifc in node.netifs():
|
||||
if ifc.name != "lo":
|
||||
ifname = ifc.name
|
||||
for iface in node.get_ifaces():
|
||||
if iface.name != "lo":
|
||||
ifname = iface.name
|
||||
break
|
||||
cfg = "router mfea\n!\n"
|
||||
cfg += "router igmp\n!\n"
|
||||
|
@ -649,7 +641,7 @@ class FRRpimd(FrrService):
|
|||
return cfg
|
||||
|
||||
@classmethod
|
||||
def generatefrrifcconfig(cls, node, ifc):
|
||||
def generate_frr_iface_config(cls, node, iface):
|
||||
return " ip mfea\n ip igmp\n ip pim\n"
|
||||
|
||||
|
||||
|
@ -668,17 +660,17 @@ class FRRIsis(FrrService):
|
|||
ipv6_routing = True
|
||||
|
||||
@staticmethod
|
||||
def ptpcheck(ifc):
|
||||
def ptpcheck(iface):
|
||||
"""
|
||||
Helper to detect whether interface is connected to a notional
|
||||
point-to-point link.
|
||||
"""
|
||||
if isinstance(ifc.net, PtpNet):
|
||||
if isinstance(iface.net, PtpNet):
|
||||
return " isis network point-to-point\n"
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def generatefrrconfig(cls, node):
|
||||
def generate_frr_config(cls, node):
|
||||
cfg = "router isis DEFAULT\n"
|
||||
cfg += " net 47.0001.0000.1900.%04x.00\n" % node.id
|
||||
cfg += " metric-style wide\n"
|
||||
|
@ -687,9 +679,9 @@ class FRRIsis(FrrService):
|
|||
return cfg
|
||||
|
||||
@classmethod
|
||||
def generatefrrifcconfig(cls, node, ifc):
|
||||
def generate_frr_iface_config(cls, node, iface):
|
||||
cfg = " ip router isis DEFAULT\n"
|
||||
cfg += " ipv6 router isis DEFAULT\n"
|
||||
cfg += " isis circuit-type level-2-only\n"
|
||||
cfg += cls.ptpcheck(ifc)
|
||||
cfg += cls.ptpcheck(iface)
|
||||
return cfg
|
||||
|
|
|
@ -32,10 +32,8 @@ class NrlService(CoreService):
|
|||
prefix of a node, using the supplied prefix length. This ignores the
|
||||
interface's prefix length, so e.g. '/32' can turn into '/24'.
|
||||
"""
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
for a in iface.addrlist:
|
||||
a = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(a):
|
||||
return f"{a}/{prefixlen}"
|
||||
|
@ -54,8 +52,8 @@ class MgenSinkService(NrlService):
|
|||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
cfg = "0.0 LISTEN UDP 5000\n"
|
||||
for ifc in node.netifs():
|
||||
name = utils.sysctl_devname(ifc.name)
|
||||
for iface in node.get_ifaces():
|
||||
name = utils.sysctl_devname(iface.name)
|
||||
cfg += "0.0 Join 224.225.1.2 INTERFACE %s\n" % name
|
||||
return cfg
|
||||
|
||||
|
@ -91,11 +89,11 @@ class NrlNhdp(NrlService):
|
|||
cmd += " -flooding ecds"
|
||||
cmd += " -smfClient %s_smf" % node.name
|
||||
|
||||
netifs = list(filter(lambda x: not getattr(x, "control", False), node.netifs()))
|
||||
if len(netifs) > 0:
|
||||
interfacenames = map(lambda x: x.name, netifs)
|
||||
ifaces = node.get_ifaces(control=False)
|
||||
if len(ifaces) > 0:
|
||||
iface_names = map(lambda x: x.name, ifaces)
|
||||
cmd += " -i "
|
||||
cmd += " -i ".join(interfacenames)
|
||||
cmd += " -i ".join(iface_names)
|
||||
|
||||
return (cmd,)
|
||||
|
||||
|
@ -125,16 +123,16 @@ class NrlSmf(NrlService):
|
|||
cmd = "nrlsmf instance %s_smf" % node.name
|
||||
|
||||
servicenames = map(lambda x: x.name, node.services)
|
||||
netifs = list(filter(lambda x: not getattr(x, "control", False), node.netifs()))
|
||||
if len(netifs) == 0:
|
||||
ifaces = node.get_ifaces(control=False)
|
||||
if len(ifaces) == 0:
|
||||
return ""
|
||||
|
||||
if "arouted" in servicenames:
|
||||
comments += "# arouted service is enabled\n"
|
||||
cmd += " tap %s_tap" % (node.name,)
|
||||
cmd += " unicast %s" % cls.firstipv4prefix(node, 24)
|
||||
cmd += " push lo,%s resequence on" % netifs[0].name
|
||||
if len(netifs) > 0:
|
||||
cmd += " push lo,%s resequence on" % ifaces[0].name
|
||||
if len(ifaces) > 0:
|
||||
if "NHDP" in servicenames:
|
||||
comments += "# NHDP service is enabled\n"
|
||||
cmd += " ecds "
|
||||
|
@ -143,8 +141,8 @@ class NrlSmf(NrlService):
|
|||
cmd += " smpr "
|
||||
else:
|
||||
cmd += " cf "
|
||||
interfacenames = map(lambda x: x.name, netifs)
|
||||
cmd += ",".join(interfacenames)
|
||||
iface_names = map(lambda x: x.name, ifaces)
|
||||
cmd += ",".join(iface_names)
|
||||
|
||||
cmd += " hash MD5"
|
||||
cmd += " log /var/log/nrlsmf.log"
|
||||
|
@ -171,10 +169,10 @@ class NrlOlsr(NrlService):
|
|||
"""
|
||||
cmd = cls.startup[0]
|
||||
# are multiple interfaces supported? No.
|
||||
netifs = list(node.netifs())
|
||||
if len(netifs) > 0:
|
||||
ifc = netifs[0]
|
||||
cmd += " -i %s" % ifc.name
|
||||
ifaces = node.get_ifaces()
|
||||
if len(ifaces) > 0:
|
||||
iface = ifaces[0]
|
||||
cmd += " -i %s" % iface.name
|
||||
cmd += " -l /var/log/nrlolsrd.log"
|
||||
cmd += " -rpipe %s_olsr" % node.name
|
||||
|
||||
|
@ -215,11 +213,11 @@ class NrlOlsrv2(NrlService):
|
|||
|
||||
cmd += " -p olsr"
|
||||
|
||||
netifs = list(filter(lambda x: not getattr(x, "control", False), node.netifs()))
|
||||
if len(netifs) > 0:
|
||||
interfacenames = map(lambda x: x.name, netifs)
|
||||
ifaces = node.get_ifaces(control=False)
|
||||
if len(ifaces) > 0:
|
||||
iface_names = map(lambda x: x.name, ifaces)
|
||||
cmd += " -i "
|
||||
cmd += " -i ".join(interfacenames)
|
||||
cmd += " -i ".join(iface_names)
|
||||
|
||||
return (cmd,)
|
||||
|
||||
|
@ -243,11 +241,11 @@ class OlsrOrg(NrlService):
|
|||
Generate the appropriate command-line based on node interfaces.
|
||||
"""
|
||||
cmd = cls.startup[0]
|
||||
netifs = list(filter(lambda x: not getattr(x, "control", False), node.netifs()))
|
||||
if len(netifs) > 0:
|
||||
interfacenames = map(lambda x: x.name, netifs)
|
||||
ifaces = node.get_ifaces(control=False)
|
||||
if len(ifaces) > 0:
|
||||
iface_names = map(lambda x: x.name, ifaces)
|
||||
cmd += " -i "
|
||||
cmd += " -i ".join(interfacenames)
|
||||
cmd += " -i ".join(iface_names)
|
||||
|
||||
return (cmd,)
|
||||
|
||||
|
@ -607,8 +605,8 @@ class MgenActor(NrlService):
|
|||
comments = ""
|
||||
cmd = "mgenBasicActor.py -n %s -a 0.0.0.0" % node.name
|
||||
|
||||
netifs = [x for x in node.netifs() if not getattr(x, "control", False)]
|
||||
if len(netifs) == 0:
|
||||
ifaces = node.get_ifaces(control=False)
|
||||
if len(ifaces) == 0:
|
||||
return ""
|
||||
|
||||
cfg += comments + cmd + " < /dev/null > /dev/null 2>&1 &\n\n"
|
||||
|
|
|
@ -56,12 +56,12 @@ class Zebra(CoreService):
|
|||
"""
|
||||
# we could verify here that filename == Quagga.conf
|
||||
cfg = ""
|
||||
for ifc in node.netifs():
|
||||
cfg += "interface %s\n" % ifc.name
|
||||
for iface in node.get_ifaces():
|
||||
cfg += "interface %s\n" % iface.name
|
||||
# include control interfaces in addressing but not routing daemons
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
if hasattr(iface, "control") and iface.control is True:
|
||||
cfg += " "
|
||||
cfg += "\n ".join(map(cls.addrstr, ifc.addrlist))
|
||||
cfg += "\n ".join(map(cls.addrstr, iface.addrlist))
|
||||
cfg += "\n"
|
||||
continue
|
||||
cfgv4 = ""
|
||||
|
@ -71,18 +71,18 @@ class Zebra(CoreService):
|
|||
for s in node.services:
|
||||
if cls.name not in s.dependencies:
|
||||
continue
|
||||
ifccfg = s.generatequaggaifcconfig(node, ifc)
|
||||
iface_config = s.generate_quagga_iface_config(node, iface)
|
||||
if s.ipv4_routing:
|
||||
want_ipv4 = True
|
||||
if s.ipv6_routing:
|
||||
want_ipv6 = True
|
||||
cfgv6 += ifccfg
|
||||
cfgv6 += iface_config
|
||||
else:
|
||||
cfgv4 += ifccfg
|
||||
cfgv4 += iface_config
|
||||
|
||||
if want_ipv4:
|
||||
ipv4list = filter(
|
||||
lambda x: netaddr.valid_ipv4(x.split("/")[0]), ifc.addrlist
|
||||
lambda x: netaddr.valid_ipv4(x.split("/")[0]), iface.addrlist
|
||||
)
|
||||
cfg += " "
|
||||
cfg += "\n ".join(map(cls.addrstr, ipv4list))
|
||||
|
@ -90,7 +90,7 @@ class Zebra(CoreService):
|
|||
cfg += cfgv4
|
||||
if want_ipv6:
|
||||
ipv6list = filter(
|
||||
lambda x: netaddr.valid_ipv6(x.split("/")[0]), ifc.addrlist
|
||||
lambda x: netaddr.valid_ipv6(x.split("/")[0]), iface.addrlist
|
||||
)
|
||||
cfg += " "
|
||||
cfg += "\n ".join(map(cls.addrstr, ipv6list))
|
||||
|
@ -101,7 +101,7 @@ class Zebra(CoreService):
|
|||
for s in node.services:
|
||||
if cls.name not in s.dependencies:
|
||||
continue
|
||||
cfg += s.generatequaggaconfig(node)
|
||||
cfg += s.generate_quagga_config(node)
|
||||
return cfg
|
||||
|
||||
@staticmethod
|
||||
|
@ -252,10 +252,8 @@ class QuaggaService(CoreService):
|
|||
"""
|
||||
Helper to return the first IPv4 address of a node as its router ID.
|
||||
"""
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
for a in iface.addrlist:
|
||||
a = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(a):
|
||||
return a
|
||||
|
@ -263,16 +261,16 @@ class QuaggaService(CoreService):
|
|||
return "0.0.0.%d" % node.id
|
||||
|
||||
@staticmethod
|
||||
def rj45check(ifc):
|
||||
def rj45check(iface):
|
||||
"""
|
||||
Helper to detect whether interface is connected an external RJ45
|
||||
link.
|
||||
"""
|
||||
if ifc.net:
|
||||
for peerifc in ifc.net.netifs():
|
||||
if peerifc == ifc:
|
||||
if iface.net:
|
||||
for peer_iface in iface.net.get_ifaces():
|
||||
if peer_iface == iface:
|
||||
continue
|
||||
if isinstance(peerifc.node, Rj45Node):
|
||||
if isinstance(peer_iface.node, Rj45Node):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -281,11 +279,11 @@ class QuaggaService(CoreService):
|
|||
return ""
|
||||
|
||||
@classmethod
|
||||
def generatequaggaifcconfig(cls, node, ifc):
|
||||
def generate_quagga_iface_config(cls, node, iface):
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def generatequaggaconfig(cls, node):
|
||||
def generate_quagga_config(cls, node):
|
||||
return ""
|
||||
|
||||
|
||||
|
@ -303,43 +301,41 @@ class Ospfv2(QuaggaService):
|
|||
ipv4_routing = True
|
||||
|
||||
@staticmethod
|
||||
def mtucheck(ifc):
|
||||
def mtucheck(iface):
|
||||
"""
|
||||
Helper to detect MTU mismatch and add the appropriate OSPF
|
||||
mtu-ignore command. This is needed when e.g. a node is linked via a
|
||||
GreTap device.
|
||||
"""
|
||||
if ifc.mtu != 1500:
|
||||
if iface.mtu != 1500:
|
||||
# a workaround for PhysicalNode GreTap, which has no knowledge of
|
||||
# the other nodes/nets
|
||||
return " ip ospf mtu-ignore\n"
|
||||
if not ifc.net:
|
||||
if not iface.net:
|
||||
return ""
|
||||
for i in ifc.net.netifs():
|
||||
if i.mtu != ifc.mtu:
|
||||
for iface in iface.net.get_ifaces():
|
||||
if iface.mtu != iface.mtu:
|
||||
return " ip ospf mtu-ignore\n"
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def ptpcheck(ifc):
|
||||
def ptpcheck(iface):
|
||||
"""
|
||||
Helper to detect whether interface is connected to a notional
|
||||
point-to-point link.
|
||||
"""
|
||||
if isinstance(ifc.net, PtpNet):
|
||||
if isinstance(iface.net, PtpNet):
|
||||
return " ip ospf network point-to-point\n"
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def generatequaggaconfig(cls, node):
|
||||
def generate_quagga_config(cls, node):
|
||||
cfg = "router ospf\n"
|
||||
rtrid = cls.routerid(node)
|
||||
cfg += " router-id %s\n" % rtrid
|
||||
# network 10.0.0.0/24 area 0
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
for a in iface.addrlist:
|
||||
addr = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(addr):
|
||||
cfg += " network %s area 0\n" % a
|
||||
|
@ -347,12 +343,12 @@ class Ospfv2(QuaggaService):
|
|||
return cfg
|
||||
|
||||
@classmethod
|
||||
def generatequaggaifcconfig(cls, node, ifc):
|
||||
cfg = cls.mtucheck(ifc)
|
||||
def generate_quagga_iface_config(cls, node, iface):
|
||||
cfg = cls.mtucheck(iface)
|
||||
# external RJ45 connections will use default OSPF timers
|
||||
if cls.rj45check(ifc):
|
||||
if cls.rj45check(iface):
|
||||
return cfg
|
||||
cfg += cls.ptpcheck(ifc)
|
||||
cfg += cls.ptpcheck(iface)
|
||||
return (
|
||||
cfg
|
||||
+ """\
|
||||
|
@ -378,58 +374,56 @@ class Ospfv3(QuaggaService):
|
|||
ipv6_routing = True
|
||||
|
||||
@staticmethod
|
||||
def minmtu(ifc):
|
||||
def minmtu(iface):
|
||||
"""
|
||||
Helper to discover the minimum MTU of interfaces linked with the
|
||||
given interface.
|
||||
"""
|
||||
mtu = ifc.mtu
|
||||
if not ifc.net:
|
||||
mtu = iface.mtu
|
||||
if not iface.net:
|
||||
return mtu
|
||||
for i in ifc.net.netifs():
|
||||
if i.mtu < mtu:
|
||||
mtu = i.mtu
|
||||
for iface in iface.net.get_ifaces():
|
||||
if iface.mtu < mtu:
|
||||
mtu = iface.mtu
|
||||
return mtu
|
||||
|
||||
@classmethod
|
||||
def mtucheck(cls, ifc):
|
||||
def mtucheck(cls, iface):
|
||||
"""
|
||||
Helper to detect MTU mismatch and add the appropriate OSPFv3
|
||||
ifmtu command. This is needed when e.g. a node is linked via a
|
||||
GreTap device.
|
||||
"""
|
||||
minmtu = cls.minmtu(ifc)
|
||||
if minmtu < ifc.mtu:
|
||||
minmtu = cls.minmtu(iface)
|
||||
if minmtu < iface.mtu:
|
||||
return " ipv6 ospf6 ifmtu %d\n" % minmtu
|
||||
else:
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def ptpcheck(ifc):
|
||||
def ptpcheck(iface):
|
||||
"""
|
||||
Helper to detect whether interface is connected to a notional
|
||||
point-to-point link.
|
||||
"""
|
||||
if isinstance(ifc.net, PtpNet):
|
||||
if isinstance(iface.net, PtpNet):
|
||||
return " ipv6 ospf6 network point-to-point\n"
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def generatequaggaconfig(cls, node):
|
||||
def generate_quagga_config(cls, node):
|
||||
cfg = "router ospf6\n"
|
||||
rtrid = cls.routerid(node)
|
||||
cfg += " instance-id 65\n"
|
||||
cfg += " router-id %s\n" % rtrid
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += " interface %s area 0.0.0.0\n" % ifc.name
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += " interface %s area 0.0.0.0\n" % iface.name
|
||||
cfg += "!\n"
|
||||
return cfg
|
||||
|
||||
@classmethod
|
||||
def generatequaggaifcconfig(cls, node, ifc):
|
||||
return cls.mtucheck(ifc)
|
||||
def generate_quagga_iface_config(cls, node, iface):
|
||||
return cls.mtucheck(iface)
|
||||
|
||||
|
||||
class Ospfv3mdr(Ospfv3):
|
||||
|
@ -444,9 +438,9 @@ class Ospfv3mdr(Ospfv3):
|
|||
ipv4_routing = True
|
||||
|
||||
@classmethod
|
||||
def generatequaggaifcconfig(cls, node, ifc):
|
||||
cfg = cls.mtucheck(ifc)
|
||||
if ifc.net is not None and isinstance(ifc.net, (WlanNode, EmaneNet)):
|
||||
def generate_quagga_iface_config(cls, node, iface):
|
||||
cfg = cls.mtucheck(iface)
|
||||
if iface.net is not None and isinstance(iface.net, (WlanNode, EmaneNet)):
|
||||
return (
|
||||
cfg
|
||||
+ """\
|
||||
|
@ -479,7 +473,7 @@ class Bgp(QuaggaService):
|
|||
ipv6_routing = True
|
||||
|
||||
@classmethod
|
||||
def generatequaggaconfig(cls, node):
|
||||
def generate_quagga_config(cls, node):
|
||||
cfg = "!\n! BGP configuration\n!\n"
|
||||
cfg += "! You should configure the AS number below,\n"
|
||||
cfg += "! along with this router's peers.\n!\n"
|
||||
|
@ -503,7 +497,7 @@ class Rip(QuaggaService):
|
|||
ipv4_routing = True
|
||||
|
||||
@classmethod
|
||||
def generatequaggaconfig(cls, node):
|
||||
def generate_quagga_config(cls, node):
|
||||
cfg = """\
|
||||
router rip
|
||||
redistribute static
|
||||
|
@ -527,7 +521,7 @@ class Ripng(QuaggaService):
|
|||
ipv6_routing = True
|
||||
|
||||
@classmethod
|
||||
def generatequaggaconfig(cls, node):
|
||||
def generate_quagga_config(cls, node):
|
||||
cfg = """\
|
||||
router ripng
|
||||
redistribute static
|
||||
|
@ -552,18 +546,16 @@ class Babel(QuaggaService):
|
|||
ipv6_routing = True
|
||||
|
||||
@classmethod
|
||||
def generatequaggaconfig(cls, node):
|
||||
def generate_quagga_config(cls, node):
|
||||
cfg = "router babel\n"
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += " network %s\n" % ifc.name
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += " network %s\n" % iface.name
|
||||
cfg += " redistribute static\n redistribute connected\n"
|
||||
return cfg
|
||||
|
||||
@classmethod
|
||||
def generatequaggaifcconfig(cls, node, ifc):
|
||||
if ifc.net and ifc.net.linktype == LinkTypes.WIRELESS:
|
||||
def generate_quagga_iface_config(cls, node, iface):
|
||||
if iface.net and iface.net.linktype == LinkTypes.WIRELESS:
|
||||
return " babel wireless\n no babel split-horizon\n"
|
||||
else:
|
||||
return " babel wired\n babel split-horizon\n"
|
||||
|
@ -581,11 +573,11 @@ class Xpimd(QuaggaService):
|
|||
ipv4_routing = True
|
||||
|
||||
@classmethod
|
||||
def generatequaggaconfig(cls, node):
|
||||
def generate_quagga_config(cls, node):
|
||||
ifname = "eth0"
|
||||
for ifc in node.netifs():
|
||||
if ifc.name != "lo":
|
||||
ifname = ifc.name
|
||||
for iface in node.get_ifaces():
|
||||
if iface.name != "lo":
|
||||
ifname = iface.name
|
||||
break
|
||||
cfg = "router mfea\n!\n"
|
||||
cfg += "router igmp\n!\n"
|
||||
|
@ -597,5 +589,5 @@ class Xpimd(QuaggaService):
|
|||
return cfg
|
||||
|
||||
@classmethod
|
||||
def generatequaggaifcconfig(cls, node, ifc):
|
||||
def generate_quagga_iface_config(cls, node, iface):
|
||||
return " ip mfea\n ip igmp\n ip pim\n"
|
||||
|
|
|
@ -49,10 +49,8 @@ class OvsService(SdnService):
|
|||
|
||||
cfg += "\n## Now add all our interfaces as ports to the switch\n"
|
||||
portnum = 1
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
ifnumstr = re.findall(r"\d+", ifc.name)
|
||||
for iface in node.get_ifaces(control=False):
|
||||
ifnumstr = re.findall(r"\d+", iface.name)
|
||||
ifnum = ifnumstr[0]
|
||||
|
||||
# create virtual interfaces
|
||||
|
@ -61,18 +59,18 @@ class OvsService(SdnService):
|
|||
|
||||
# remove ip address of eths because quagga/zebra will assign same IPs to rtr interfaces
|
||||
# or assign them manually to rtr interfaces if zebra is not running
|
||||
for ifcaddr in ifc.addrlist:
|
||||
addr = ifcaddr.split("/")[0]
|
||||
for addr in iface.addrlist:
|
||||
addr = addr.split("/")[0]
|
||||
if netaddr.valid_ipv4(addr):
|
||||
cfg += "ip addr del %s dev %s\n" % (ifcaddr, ifc.name)
|
||||
cfg += "ip addr del %s dev %s\n" % (addr, iface.name)
|
||||
if has_zebra == 0:
|
||||
cfg += "ip addr add %s dev rtr%s\n" % (ifcaddr, ifnum)
|
||||
cfg += "ip addr add %s dev rtr%s\n" % (addr, ifnum)
|
||||
elif netaddr.valid_ipv6(addr):
|
||||
cfg += "ip -6 addr del %s dev %s\n" % (ifcaddr, ifc.name)
|
||||
cfg += "ip -6 addr del %s dev %s\n" % (addr, iface.name)
|
||||
if has_zebra == 0:
|
||||
cfg += "ip -6 addr add %s dev rtr%s\n" % (ifcaddr, ifnum)
|
||||
cfg += "ip -6 addr add %s dev rtr%s\n" % (addr, ifnum)
|
||||
else:
|
||||
raise ValueError("invalid address: %s" % ifcaddr)
|
||||
raise ValueError("invalid address: %s" % addr)
|
||||
|
||||
# add interfaces to bridge
|
||||
# Make port numbers explicit so they're easier to follow in reading the script
|
||||
|
@ -102,9 +100,7 @@ class OvsService(SdnService):
|
|||
cfg += "## if the above controller will be present then you probably want to delete them\n"
|
||||
# Setup default flows
|
||||
portnum = 1
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "## Take the data from the CORE interface and put it on the veth and vice versa\n"
|
||||
cfg += (
|
||||
"ovs-ofctl add-flow ovsbr0 priority=1000,in_port=%d,action=output:%d\n"
|
||||
|
|
|
@ -131,18 +131,18 @@ class Nat(CoreService):
|
|||
custom_needed = False
|
||||
|
||||
@classmethod
|
||||
def generateifcnatrule(cls, ifc, line_prefix=""):
|
||||
def generate_iface_nat_rule(cls, iface, line_prefix=""):
|
||||
"""
|
||||
Generate a NAT line for one interface.
|
||||
"""
|
||||
cfg = line_prefix + "iptables -t nat -A POSTROUTING -o "
|
||||
cfg += ifc.name + " -j MASQUERADE\n"
|
||||
cfg += iface.name + " -j MASQUERADE\n"
|
||||
|
||||
cfg += line_prefix + "iptables -A FORWARD -i " + ifc.name
|
||||
cfg += line_prefix + "iptables -A FORWARD -i " + iface.name
|
||||
cfg += " -m state --state RELATED,ESTABLISHED -j ACCEPT\n"
|
||||
|
||||
cfg += line_prefix + "iptables -A FORWARD -i "
|
||||
cfg += ifc.name + " -j DROP\n"
|
||||
cfg += iface.name + " -j DROP\n"
|
||||
return cfg
|
||||
|
||||
@classmethod
|
||||
|
@ -154,14 +154,12 @@ class Nat(CoreService):
|
|||
cfg += "# generated by security.py\n"
|
||||
cfg += "# NAT out the first interface by default\n"
|
||||
have_nat = False
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
for iface in node.get_ifaces(control=False):
|
||||
if have_nat:
|
||||
cfg += cls.generateifcnatrule(ifc, line_prefix="#")
|
||||
cfg += cls.generate_iface_nat_rule(iface, line_prefix="#")
|
||||
else:
|
||||
have_nat = True
|
||||
cfg += "# NAT out the " + ifc.name + " interface\n"
|
||||
cfg += cls.generateifcnatrule(ifc)
|
||||
cfg += "# NAT out the " + iface.name + " interface\n"
|
||||
cfg += cls.generate_iface_nat_rule(iface)
|
||||
cfg += "\n"
|
||||
return cfg
|
||||
|
|
|
@ -55,8 +55,8 @@ class IPForwardService(UtilService):
|
|||
""" % {
|
||||
"sysctl": constants.SYSCTL_BIN
|
||||
}
|
||||
for ifc in node.netifs():
|
||||
name = utils.sysctl_devname(ifc.name)
|
||||
for iface in node.get_ifaces():
|
||||
name = utils.sysctl_devname(iface.name)
|
||||
cfg += "%s -w net.ipv4.conf.%s.forwarding=1\n" % (
|
||||
constants.SYSCTL_BIN,
|
||||
name,
|
||||
|
@ -77,10 +77,10 @@ class DefaultRouteService(UtilService):
|
|||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
routes = []
|
||||
netifs = node.netifs(sort=True)
|
||||
if netifs:
|
||||
netif = netifs[0]
|
||||
for x in netif.addrlist:
|
||||
ifaces = node.get_ifaces()
|
||||
if ifaces:
|
||||
iface = ifaces[0]
|
||||
for x in iface.addrlist:
|
||||
net = netaddr.IPNetwork(x).cidr
|
||||
if net.size > 1:
|
||||
router = net[1]
|
||||
|
@ -104,14 +104,12 @@ class DefaultMulticastRouteService(UtilService):
|
|||
cfg += "# the first interface is chosen below; please change it "
|
||||
cfg += "as needed\n"
|
||||
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
for iface in node.get_ifaces(control=False):
|
||||
if os.uname()[0] == "Linux":
|
||||
rtcmd = "ip route add 224.0.0.0/4 dev"
|
||||
else:
|
||||
raise Exception("unknown platform")
|
||||
cfg += "%s %s\n" % (rtcmd, ifc.name)
|
||||
cfg += "%s %s\n" % (rtcmd, iface.name)
|
||||
cfg += "\n"
|
||||
break
|
||||
return cfg
|
||||
|
@ -129,10 +127,8 @@ class StaticRouteService(UtilService):
|
|||
cfg += "# auto-generated by StaticRoute service (utility.py)\n#\n"
|
||||
cfg += "# NOTE: this service must be customized to be of any use\n"
|
||||
cfg += "# Below are samples that you can uncomment and edit.\n#\n"
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += "\n".join(map(cls.routestr, ifc.addrlist))
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "\n".join(map(cls.routestr, iface.addrlist))
|
||||
cfg += "\n"
|
||||
return cfg
|
||||
|
||||
|
@ -259,10 +255,8 @@ max-lease-time 7200;
|
|||
|
||||
ddns-update-style none;
|
||||
"""
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += "\n".join(map(cls.subnetentry, ifc.addrlist))
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "\n".join(map(cls.subnetentry, iface.addrlist))
|
||||
cfg += "\n"
|
||||
return cfg
|
||||
|
||||
|
@ -320,13 +314,11 @@ class DhcpClientService(UtilService):
|
|||
cfg += "side DNS\n# resolution based on the DHCP server response.\n"
|
||||
cfg += "#mkdir -p /var/run/resolvconf/interface\n"
|
||||
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += "#ln -s /var/run/resolvconf/interface/%s.dhclient" % ifc.name
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "#ln -s /var/run/resolvconf/interface/%s.dhclient" % iface.name
|
||||
cfg += " /var/run/resolvconf/resolv.conf\n"
|
||||
cfg += "/sbin/dhclient -nw -pf /var/run/dhclient-%s.pid" % ifc.name
|
||||
cfg += " -lf /var/run/dhclient-%s.lease %s\n" % (ifc.name, ifc.name)
|
||||
cfg += "/sbin/dhclient -nw -pf /var/run/dhclient-%s.pid" % iface.name
|
||||
cfg += " -lf /var/run/dhclient-%s.lease %s\n" % (iface.name, iface.name)
|
||||
return cfg
|
||||
|
||||
|
||||
|
@ -585,10 +577,8 @@ export LANG
|
|||
"""
|
||||
% node.name
|
||||
)
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
body += "<li>%s - %s</li>\n" % (ifc.name, ifc.addrlist)
|
||||
for iface in node.get_ifaces(control=False):
|
||||
body += "<li>%s - %s</li>\n" % (iface.name, iface.addrlist)
|
||||
return "<html><body>%s</body></html>" % body
|
||||
|
||||
|
||||
|
@ -619,14 +609,14 @@ DUMPOPTS="-s 12288 -C 10 -n"
|
|||
if [ "x$1" = "xstart" ]; then
|
||||
|
||||
"""
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
for iface in node.get_ifaces():
|
||||
if hasattr(iface, "control") and iface.control is True:
|
||||
cfg += "# "
|
||||
redir = "< /dev/null"
|
||||
cfg += "tcpdump ${DUMPOPTS} -w %s.%s.pcap -i %s %s &\n" % (
|
||||
node.name,
|
||||
ifc.name,
|
||||
ifc.name,
|
||||
iface.name,
|
||||
iface.name,
|
||||
redir,
|
||||
)
|
||||
cfg += """
|
||||
|
@ -654,10 +644,8 @@ class RadvdService(UtilService):
|
|||
using the network address of each interface.
|
||||
"""
|
||||
cfg = "# auto-generated by RADVD service (utility.py)\n"
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
prefixes = list(map(cls.subnetentry, ifc.addrlist))
|
||||
for iface in node.get_ifaces(control=False):
|
||||
prefixes = list(map(cls.subnetentry, iface.addrlist))
|
||||
if len(prefixes) < 1:
|
||||
continue
|
||||
cfg += (
|
||||
|
@ -670,7 +658,7 @@ interface %s
|
|||
AdvDefaultPreference low;
|
||||
AdvHomeAgentFlag off;
|
||||
"""
|
||||
% ifc.name
|
||||
% iface.name
|
||||
)
|
||||
for prefix in prefixes:
|
||||
if prefix == "":
|
||||
|
|
|
@ -35,11 +35,11 @@ class XorpRtrmgr(CoreService):
|
|||
invoked here. Filename currently ignored.
|
||||
"""
|
||||
cfg = "interfaces {\n"
|
||||
for ifc in node.netifs():
|
||||
cfg += " interface %s {\n" % ifc.name
|
||||
cfg += "\tvif %s {\n" % ifc.name
|
||||
cfg += "".join(map(cls.addrstr, ifc.addrlist))
|
||||
cfg += cls.lladdrstr(ifc)
|
||||
for iface in node.get_ifaces():
|
||||
cfg += " interface %s {\n" % iface.name
|
||||
cfg += "\tvif %s {\n" % iface.name
|
||||
cfg += "".join(map(cls.addrstr, iface.addrlist))
|
||||
cfg += cls.lladdrstr(iface)
|
||||
cfg += "\t}\n"
|
||||
cfg += " }\n"
|
||||
cfg += "}\n\n"
|
||||
|
@ -65,11 +65,11 @@ class XorpRtrmgr(CoreService):
|
|||
return cfg
|
||||
|
||||
@staticmethod
|
||||
def lladdrstr(ifc):
|
||||
def lladdrstr(iface):
|
||||
"""
|
||||
helper for adding link-local address entries (required by OSPFv3)
|
||||
"""
|
||||
cfg = "\t address %s {\n" % ifc.hwaddr.tolinklocal()
|
||||
cfg = "\t address %s {\n" % iface.hwaddr.tolinklocal()
|
||||
cfg += "\t\tprefix-length: 64\n"
|
||||
cfg += "\t }\n"
|
||||
return cfg
|
||||
|
@ -104,15 +104,15 @@ class XorpService(CoreService):
|
|||
return cfg
|
||||
|
||||
@staticmethod
|
||||
def mfea(forwarding, ifcs):
|
||||
def mfea(forwarding, ifaces):
|
||||
"""
|
||||
Helper to add a multicast forwarding engine entry to the config file.
|
||||
"""
|
||||
names = []
|
||||
for ifc in ifcs:
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
for iface in ifaces:
|
||||
if hasattr(iface, "control") and iface.control is True:
|
||||
continue
|
||||
names.append(ifc.name)
|
||||
names.append(iface.name)
|
||||
names.append("register_vif")
|
||||
|
||||
cfg = "plumbing {\n"
|
||||
|
@ -148,10 +148,8 @@ class XorpService(CoreService):
|
|||
"""
|
||||
Helper to return the first IPv4 address of a node as its router ID.
|
||||
"""
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
for a in iface.addrlist:
|
||||
a = a.split("/")[0]
|
||||
if netaddr.valid_ipv4(a):
|
||||
return a
|
||||
|
@ -184,12 +182,10 @@ class XorpOspfv2(XorpService):
|
|||
cfg += " ospf4 {\n"
|
||||
cfg += "\trouter-id: %s\n" % rtrid
|
||||
cfg += "\tarea 0.0.0.0 {\n"
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += "\t interface %s {\n" % ifc.name
|
||||
cfg += "\t\tvif %s {\n" % ifc.name
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "\t interface %s {\n" % iface.name
|
||||
cfg += "\t\tvif %s {\n" % iface.name
|
||||
for a in iface.addrlist:
|
||||
addr = a.split("/")[0]
|
||||
if not netaddr.valid_ipv4(addr):
|
||||
continue
|
||||
|
@ -220,11 +216,9 @@ class XorpOspfv3(XorpService):
|
|||
cfg += " ospf6 0 { /* Instance ID 0 */\n"
|
||||
cfg += "\trouter-id: %s\n" % rtrid
|
||||
cfg += "\tarea 0.0.0.0 {\n"
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += "\t interface %s {\n" % ifc.name
|
||||
cfg += "\t\tvif %s {\n" % ifc.name
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "\t interface %s {\n" % iface.name
|
||||
cfg += "\t\tvif %s {\n" % iface.name
|
||||
cfg += "\t\t}\n"
|
||||
cfg += "\t }\n"
|
||||
cfg += "\t}\n"
|
||||
|
@ -277,12 +271,10 @@ class XorpRip(XorpService):
|
|||
cfg += "\nprotocols {\n"
|
||||
cfg += " rip {\n"
|
||||
cfg += '\texport: "export-connected"\n'
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += "\tinterface %s {\n" % ifc.name
|
||||
cfg += "\t vif %s {\n" % ifc.name
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "\tinterface %s {\n" % iface.name
|
||||
cfg += "\t vif %s {\n" % iface.name
|
||||
for a in iface.addrlist:
|
||||
addr = a.split("/")[0]
|
||||
if not netaddr.valid_ipv4(addr):
|
||||
continue
|
||||
|
@ -310,12 +302,10 @@ class XorpRipng(XorpService):
|
|||
cfg += "\nprotocols {\n"
|
||||
cfg += " ripng {\n"
|
||||
cfg += '\texport: "export-connected"\n'
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += "\tinterface %s {\n" % ifc.name
|
||||
cfg += "\t vif %s {\n" % ifc.name
|
||||
cfg += "\t\taddress %s {\n" % ifc.hwaddr.tolinklocal()
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "\tinterface %s {\n" % iface.name
|
||||
cfg += "\t vif %s {\n" % iface.name
|
||||
cfg += "\t\taddress %s {\n" % iface.hwaddr.tolinklocal()
|
||||
cfg += "\t\t disable: false\n"
|
||||
cfg += "\t\t}\n"
|
||||
cfg += "\t }\n"
|
||||
|
@ -334,17 +324,15 @@ class XorpPimSm4(XorpService):
|
|||
|
||||
@classmethod
|
||||
def generatexorpconfig(cls, node):
|
||||
cfg = cls.mfea("mfea4", node.netifs())
|
||||
cfg = cls.mfea("mfea4", node.get_ifaces())
|
||||
|
||||
cfg += "\nprotocols {\n"
|
||||
cfg += " igmp {\n"
|
||||
names = []
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
names.append(ifc.name)
|
||||
cfg += "\tinterface %s {\n" % ifc.name
|
||||
cfg += "\t vif %s {\n" % ifc.name
|
||||
for iface in node.get_ifaces(control=False):
|
||||
names.append(iface.name)
|
||||
cfg += "\tinterface %s {\n" % iface.name
|
||||
cfg += "\t vif %s {\n" % iface.name
|
||||
cfg += "\t\tdisable: false\n"
|
||||
cfg += "\t }\n"
|
||||
cfg += "\t}\n"
|
||||
|
@ -394,17 +382,15 @@ class XorpPimSm6(XorpService):
|
|||
|
||||
@classmethod
|
||||
def generatexorpconfig(cls, node):
|
||||
cfg = cls.mfea("mfea6", node.netifs())
|
||||
cfg = cls.mfea("mfea6", node.get_ifaces())
|
||||
|
||||
cfg += "\nprotocols {\n"
|
||||
cfg += " mld {\n"
|
||||
names = []
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
names.append(ifc.name)
|
||||
cfg += "\tinterface %s {\n" % ifc.name
|
||||
cfg += "\t vif %s {\n" % ifc.name
|
||||
for iface in node.get_ifaces(control=False):
|
||||
names.append(iface.name)
|
||||
cfg += "\tinterface %s {\n" % iface.name
|
||||
cfg += "\t vif %s {\n" % iface.name
|
||||
cfg += "\t\tdisable: false\n"
|
||||
cfg += "\t }\n"
|
||||
cfg += "\t}\n"
|
||||
|
@ -459,12 +445,10 @@ class XorpOlsr(XorpService):
|
|||
cfg += "\nprotocols {\n"
|
||||
cfg += " olsr4 {\n"
|
||||
cfg += "\tmain-address: %s\n" % rtrid
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, "control") and ifc.control is True:
|
||||
continue
|
||||
cfg += "\tinterface %s {\n" % ifc.name
|
||||
cfg += "\t vif %s {\n" % ifc.name
|
||||
for a in ifc.addrlist:
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "\tinterface %s {\n" % iface.name
|
||||
cfg += "\t vif %s {\n" % iface.name
|
||||
for a in iface.addrlist:
|
||||
addr = a.split("/")[0]
|
||||
if not netaddr.valid_ipv4(addr):
|
||||
continue
|
||||
|
|
|
@ -58,16 +58,16 @@ def add_attribute(element: etree.Element, name: str, value: Any) -> None:
|
|||
element.set(name, str(value))
|
||||
|
||||
|
||||
def create_interface_data(interface_element: etree.Element) -> InterfaceData:
|
||||
interface_id = int(interface_element.get("id"))
|
||||
name = interface_element.get("name")
|
||||
mac = interface_element.get("mac")
|
||||
ip4 = interface_element.get("ip4")
|
||||
ip4_mask = get_int(interface_element, "ip4_mask")
|
||||
ip6 = interface_element.get("ip6")
|
||||
ip6_mask = get_int(interface_element, "ip6_mask")
|
||||
def create_iface_data(iface_element: etree.Element) -> InterfaceData:
|
||||
iface_id = int(iface_element.get("id"))
|
||||
name = iface_element.get("name")
|
||||
mac = iface_element.get("mac")
|
||||
ip4 = iface_element.get("ip4")
|
||||
ip4_mask = get_int(iface_element, "ip4_mask")
|
||||
ip6 = iface_element.get("ip6")
|
||||
ip6_mask = get_int(iface_element, "ip6_mask")
|
||||
return InterfaceData(
|
||||
id=interface_id,
|
||||
id=iface_id,
|
||||
name=name,
|
||||
mac=mac,
|
||||
ip4=ip4,
|
||||
|
@ -482,7 +482,7 @@ class CoreXmlWriter:
|
|||
# add link data
|
||||
for link_data in links:
|
||||
# skip basic range links
|
||||
if link_data.interface1_id is None and link_data.interface2_id is None:
|
||||
if link_data.iface1_id is None and link_data.iface2_id is None:
|
||||
continue
|
||||
|
||||
link_element = self.create_link_element(link_data)
|
||||
|
@ -495,37 +495,37 @@ class CoreXmlWriter:
|
|||
device = DeviceElement(self.session, node)
|
||||
self.devices.append(device.element)
|
||||
|
||||
def create_interface_element(
|
||||
def create_iface_element(
|
||||
self,
|
||||
element_name: str,
|
||||
node_id: int,
|
||||
interface_id: int,
|
||||
iface_id: int,
|
||||
mac: str,
|
||||
ip4: str,
|
||||
ip4_mask: int,
|
||||
ip6: str,
|
||||
ip6_mask: int,
|
||||
) -> etree.Element:
|
||||
interface = etree.Element(element_name)
|
||||
iface = etree.Element(element_name)
|
||||
node = self.session.get_node(node_id, NodeBase)
|
||||
interface_name = None
|
||||
iface_name = None
|
||||
if isinstance(node, CoreNodeBase):
|
||||
node_interface = node.netif(interface_id)
|
||||
interface_name = node_interface.name
|
||||
node_iface = node.get_iface(iface_id)
|
||||
iface_name = node_iface.name
|
||||
|
||||
# check if emane interface
|
||||
if isinstance(node_interface.net, EmaneNet):
|
||||
nem = node_interface.net.getnemid(node_interface)
|
||||
add_attribute(interface, "nem", nem)
|
||||
if isinstance(node_iface.net, EmaneNet):
|
||||
nem = node_iface.net.getnemid(node_iface)
|
||||
add_attribute(iface, "nem", nem)
|
||||
|
||||
add_attribute(interface, "id", interface_id)
|
||||
add_attribute(interface, "name", interface_name)
|
||||
add_attribute(interface, "mac", mac)
|
||||
add_attribute(interface, "ip4", ip4)
|
||||
add_attribute(interface, "ip4_mask", ip4_mask)
|
||||
add_attribute(interface, "ip6", ip6)
|
||||
add_attribute(interface, "ip6_mask", ip6_mask)
|
||||
return interface
|
||||
add_attribute(iface, "id", iface_id)
|
||||
add_attribute(iface, "name", iface_name)
|
||||
add_attribute(iface, "mac", mac)
|
||||
add_attribute(iface, "ip4", ip4)
|
||||
add_attribute(iface, "ip4_mask", ip4_mask)
|
||||
add_attribute(iface, "ip6", ip6)
|
||||
add_attribute(iface, "ip6_mask", ip6_mask)
|
||||
return iface
|
||||
|
||||
def create_link_element(self, link_data: LinkData) -> etree.Element:
|
||||
link_element = etree.Element("link")
|
||||
|
@ -533,32 +533,32 @@ class CoreXmlWriter:
|
|||
add_attribute(link_element, "node2", link_data.node2_id)
|
||||
|
||||
# check for interface one
|
||||
if link_data.interface1_id is not None:
|
||||
interface1 = self.create_interface_element(
|
||||
if link_data.iface1_id is not None:
|
||||
iface1 = self.create_iface_element(
|
||||
"interface1",
|
||||
link_data.node1_id,
|
||||
link_data.interface1_id,
|
||||
link_data.interface1_mac,
|
||||
link_data.interface1_ip4,
|
||||
link_data.interface1_ip4_mask,
|
||||
link_data.interface1_ip6,
|
||||
link_data.interface1_ip6_mask,
|
||||
link_data.iface1_id,
|
||||
link_data.iface1_mac,
|
||||
link_data.iface1_ip4,
|
||||
link_data.iface1_ip4_mask,
|
||||
link_data.iface1_ip6,
|
||||
link_data.iface1_ip6_mask,
|
||||
)
|
||||
link_element.append(interface1)
|
||||
link_element.append(iface1)
|
||||
|
||||
# check for interface two
|
||||
if link_data.interface2_id is not None:
|
||||
interface2 = self.create_interface_element(
|
||||
if link_data.iface2_id is not None:
|
||||
iface2 = self.create_iface_element(
|
||||
"interface2",
|
||||
link_data.node2_id,
|
||||
link_data.interface2_id,
|
||||
link_data.interface2_mac,
|
||||
link_data.interface2_ip4,
|
||||
link_data.interface2_ip4_mask,
|
||||
link_data.interface2_ip6,
|
||||
link_data.interface2_ip6_mask,
|
||||
link_data.iface2_id,
|
||||
link_data.iface2_mac,
|
||||
link_data.iface2_ip4,
|
||||
link_data.iface2_ip4_mask,
|
||||
link_data.iface2_ip6,
|
||||
link_data.iface2_ip6_mask,
|
||||
)
|
||||
link_element.append(interface2)
|
||||
link_element.append(iface2)
|
||||
|
||||
# check for options, don't write for emane/wlan links
|
||||
node1 = self.session.get_node(link_data.node1_id, NodeBase)
|
||||
|
@ -940,19 +940,19 @@ class CoreXmlReader:
|
|||
node2_id = get_int(link_element, "node_two")
|
||||
node_set = frozenset((node1_id, node2_id))
|
||||
|
||||
interface1_element = link_element.find("interface1")
|
||||
if interface1_element is None:
|
||||
interface1_element = link_element.find("interface_one")
|
||||
interface1_data = None
|
||||
if interface1_element is not None:
|
||||
interface1_data = create_interface_data(interface1_element)
|
||||
iface1_element = link_element.find("interface1")
|
||||
if iface1_element is None:
|
||||
iface1_element = link_element.find("interface_one")
|
||||
iface1_data = None
|
||||
if iface1_element is not None:
|
||||
iface1_data = create_iface_data(iface1_element)
|
||||
|
||||
interface2_element = link_element.find("interface2")
|
||||
if interface2_element is None:
|
||||
interface2_element = link_element.find("interface_two")
|
||||
interface2_data = None
|
||||
if interface2_element is not None:
|
||||
interface2_data = create_interface_data(interface2_element)
|
||||
iface2_element = link_element.find("interface2")
|
||||
if iface2_element is None:
|
||||
iface2_element = link_element.find("interface_two")
|
||||
iface2_data = None
|
||||
if iface2_element is not None:
|
||||
iface2_data = create_iface_data(iface2_element)
|
||||
|
||||
options_element = link_element.find("options")
|
||||
options = LinkOptions()
|
||||
|
@ -978,12 +978,12 @@ class CoreXmlReader:
|
|||
if options.unidirectional == 1 and node_set in node_sets:
|
||||
logging.info("updating link node1(%s) node2(%s)", node1_id, node2_id)
|
||||
self.session.update_link(
|
||||
node1_id, node2_id, interface1_data.id, interface2_data.id, options
|
||||
node1_id, node2_id, iface1_data.id, iface2_data.id, options
|
||||
)
|
||||
else:
|
||||
logging.info("adding link node1(%s) node2(%s)", node1_id, node2_id)
|
||||
self.session.add_link(
|
||||
node1_id, node2_id, interface1_data, interface2_data, options
|
||||
node1_id, node2_id, iface1_data, iface2_data, options
|
||||
)
|
||||
|
||||
node_sets.add(node_set)
|
||||
|
|
|
@ -24,25 +24,25 @@ def add_address(
|
|||
parent_element: etree.Element,
|
||||
address_type: str,
|
||||
address: str,
|
||||
interface_name: str = None,
|
||||
iface_name: str = None,
|
||||
) -> None:
|
||||
address_element = etree.SubElement(parent_element, "address", type=address_type)
|
||||
address_element.text = address
|
||||
if interface_name is not None:
|
||||
address_element.set("iface", interface_name)
|
||||
if iface_name is not None:
|
||||
address_element.set("iface", iface_name)
|
||||
|
||||
|
||||
def add_mapping(parent_element: etree.Element, maptype: str, mapref: str) -> None:
|
||||
etree.SubElement(parent_element, "mapping", type=maptype, ref=mapref)
|
||||
|
||||
|
||||
def add_emane_interface(
|
||||
def add_emane_iface(
|
||||
host_element: etree.Element,
|
||||
netif: CoreInterface,
|
||||
iface: CoreInterface,
|
||||
platform_name: str = "p1",
|
||||
transport_name: str = "t1",
|
||||
) -> etree.Element:
|
||||
nem_id = netif.net.nemidmap[netif]
|
||||
nem_id = iface.net.nemidmap[iface]
|
||||
host_id = host_element.get("id")
|
||||
|
||||
# platform data
|
||||
|
@ -89,10 +89,10 @@ def get_ipv4_addresses(hostname: str) -> List[Tuple[str, str]]:
|
|||
split = line.split()
|
||||
if not split:
|
||||
continue
|
||||
interface_name = split[1]
|
||||
iface_name = split[1]
|
||||
address = split[3]
|
||||
if not address.startswith("127."):
|
||||
addresses.append((interface_name, address))
|
||||
addresses.append((iface_name, address))
|
||||
return addresses
|
||||
else:
|
||||
# TODO: handle other hosts
|
||||
|
@ -112,11 +112,11 @@ class CoreXmlDeployment:
|
|||
device = self.scenario.find(f"devices/device[@name='{name}']")
|
||||
return device
|
||||
|
||||
def find_interface(self, device: NodeBase, name: str) -> etree.Element:
|
||||
interface = self.scenario.find(
|
||||
def find_iface(self, device: NodeBase, name: str) -> etree.Element:
|
||||
iface = self.scenario.find(
|
||||
f"devices/device[@name='{device.name}']/interfaces/interface[@name='{name}']"
|
||||
)
|
||||
return interface
|
||||
return iface
|
||||
|
||||
def add_deployment(self) -> None:
|
||||
physical_host = self.add_physical_host(socket.gethostname())
|
||||
|
@ -136,8 +136,8 @@ class CoreXmlDeployment:
|
|||
add_type(host_element, "physical")
|
||||
|
||||
# add ipv4 addresses
|
||||
for interface_name, address in get_ipv4_addresses("localhost"):
|
||||
add_address(host_element, "IPv4", address, interface_name)
|
||||
for iface_name, address in get_ipv4_addresses("localhost"):
|
||||
add_address(host_element, "IPv4", address, iface_name)
|
||||
|
||||
return host_element
|
||||
|
||||
|
@ -155,15 +155,15 @@ class CoreXmlDeployment:
|
|||
# add host type
|
||||
add_type(host_element, "virtual")
|
||||
|
||||
for netif in node.netifs():
|
||||
for iface in node.get_ifaces():
|
||||
emane_element = None
|
||||
if isinstance(netif.net, EmaneNet):
|
||||
emane_element = add_emane_interface(host_element, netif)
|
||||
if isinstance(iface.net, EmaneNet):
|
||||
emane_element = add_emane_iface(host_element, iface)
|
||||
|
||||
parent_element = host_element
|
||||
if emane_element is not None:
|
||||
parent_element = emane_element
|
||||
|
||||
for address in netif.addrlist:
|
||||
for address in iface.addrlist:
|
||||
address_type = get_address_type(address)
|
||||
add_address(parent_element, address_type, address, netif.name)
|
||||
add_address(parent_element, address_type, address, iface.name)
|
||||
|
|
|
@ -158,19 +158,19 @@ def build_node_platform_xml(
|
|||
logging.warning("warning: EMANE network %s has no associated model", node.name)
|
||||
return nem_id
|
||||
|
||||
for netif in node.netifs():
|
||||
for iface in node.get_ifaces():
|
||||
logging.debug(
|
||||
"building platform xml for interface(%s) nem_id(%s)", netif.name, nem_id
|
||||
"building platform xml for interface(%s) nem_id(%s)", iface.name, nem_id
|
||||
)
|
||||
# build nem xml
|
||||
nem_definition = nem_file_name(node.model, netif)
|
||||
nem_definition = nem_file_name(node.model, iface)
|
||||
nem_element = etree.Element(
|
||||
"nem", id=str(nem_id), name=netif.localname, definition=nem_definition
|
||||
"nem", id=str(nem_id), name=iface.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.id, netif, node.model.name)
|
||||
config = emane_manager.get_iface_config(node.model.id, iface, node.model.name)
|
||||
|
||||
if is_external(config):
|
||||
nem_element.set("transport", "external")
|
||||
|
@ -180,9 +180,9 @@ def build_node_platform_xml(
|
|||
add_param(nem_element, transport_endpoint, config[transport_endpoint])
|
||||
else:
|
||||
# build transport xml
|
||||
transport_type = netif.transport_type
|
||||
transport_type = iface.transport_type
|
||||
if not transport_type:
|
||||
logging.info("warning: %s interface type unsupported!", netif.name)
|
||||
logging.info("warning: %s interface type unsupported!", iface.name)
|
||||
transport_type = TransportType.RAW
|
||||
transport_file = transport_file_name(node.id, transport_type)
|
||||
transport_element = etree.SubElement(
|
||||
|
@ -190,14 +190,14 @@ def build_node_platform_xml(
|
|||
)
|
||||
|
||||
# add transport parameter
|
||||
add_param(transport_element, "device", netif.name)
|
||||
add_param(transport_element, "device", iface.name)
|
||||
|
||||
# add nem entry
|
||||
nem_entries[netif] = nem_element
|
||||
nem_entries[iface] = nem_element
|
||||
|
||||
# merging code
|
||||
key = netif.node.id
|
||||
if netif.transport_type == TransportType.RAW:
|
||||
key = iface.node.id
|
||||
if iface.transport_type == TransportType.RAW:
|
||||
key = "host"
|
||||
otadev = control_net.brname
|
||||
eventdev = control_net.brname
|
||||
|
@ -229,10 +229,10 @@ def build_node_platform_xml(
|
|||
|
||||
platform_element.append(nem_element)
|
||||
|
||||
node.setnemid(netif, nem_id)
|
||||
node.setnemid(iface, nem_id)
|
||||
macstr = _hwaddr_prefix + ":00:00:"
|
||||
macstr += f"{(nem_id >> 8) & 0xFF:02X}:{nem_id & 0xFF:02X}"
|
||||
netif.sethwaddr(macstr)
|
||||
iface.sethwaddr(macstr)
|
||||
|
||||
# increment nem id
|
||||
nem_id += 1
|
||||
|
@ -280,19 +280,19 @@ def build_xml_files(emane_manager: "EmaneManager", node: EmaneNet) -> None:
|
|||
vtype = TransportType.VIRTUAL
|
||||
rtype = TransportType.RAW
|
||||
|
||||
for netif in node.netifs():
|
||||
for iface in node.get_ifaces():
|
||||
# check for interface specific emane configuration and write xml files
|
||||
config = emane_manager.getifcconfig(node.model.id, netif, node.model.name)
|
||||
config = emane_manager.get_iface_config(node.model.id, iface, node.model.name)
|
||||
if config:
|
||||
node.model.build_xml_files(config, netif)
|
||||
node.model.build_xml_files(config, iface)
|
||||
|
||||
# check transport type needed for interface
|
||||
if netif.transport_type == TransportType.VIRTUAL:
|
||||
if iface.transport_type == TransportType.VIRTUAL:
|
||||
need_virtual = True
|
||||
vtype = netif.transport_type
|
||||
vtype = iface.transport_type
|
||||
else:
|
||||
need_raw = True
|
||||
rtype = netif.transport_type
|
||||
rtype = iface.transport_type
|
||||
|
||||
if need_virtual:
|
||||
build_transport_xml(emane_manager, node, vtype)
|
||||
|
@ -494,70 +494,70 @@ def transport_file_name(node_id: int, transport_type: TransportType) -> str:
|
|||
return f"n{node_id}trans{transport_type.value}.xml"
|
||||
|
||||
|
||||
def _basename(emane_model: "EmaneModel", interface: CoreInterface = None) -> str:
|
||||
def _basename(emane_model: "EmaneModel", iface: CoreInterface = None) -> str:
|
||||
"""
|
||||
Create name that is leveraged for configuration file creation.
|
||||
|
||||
:param emane_model: emane model to create name for
|
||||
:param interface: interface for this model
|
||||
:param iface: interface for this model
|
||||
:return: basename used for file creation
|
||||
"""
|
||||
name = f"n{emane_model.id}"
|
||||
|
||||
if interface:
|
||||
node_id = interface.node.id
|
||||
if emane_model.session.emane.getifcconfig(node_id, interface, emane_model.name):
|
||||
name = interface.localname.replace(".", "_")
|
||||
if iface:
|
||||
node_id = iface.node.id
|
||||
if emane_model.session.emane.get_iface_config(node_id, iface, emane_model.name):
|
||||
name = iface.localname.replace(".", "_")
|
||||
|
||||
return f"{name}{emane_model.name}"
|
||||
|
||||
|
||||
def nem_file_name(emane_model: "EmaneModel", interface: CoreInterface = None) -> str:
|
||||
def nem_file_name(emane_model: "EmaneModel", iface: CoreInterface = None) -> str:
|
||||
"""
|
||||
Return the string name for the NEM XML file, e.g. "n3rfpipenem.xml"
|
||||
|
||||
:param emane_model: emane model to create file
|
||||
:param interface: interface for this model
|
||||
:param iface: interface for this model
|
||||
:return: nem xml filename
|
||||
"""
|
||||
basename = _basename(emane_model, interface)
|
||||
basename = _basename(emane_model, iface)
|
||||
append = ""
|
||||
if interface and interface.transport_type == TransportType.RAW:
|
||||
if iface and iface.transport_type == TransportType.RAW:
|
||||
append = "_raw"
|
||||
return f"{basename}nem{append}.xml"
|
||||
|
||||
|
||||
def shim_file_name(emane_model: "EmaneModel", interface: CoreInterface = None) -> str:
|
||||
def shim_file_name(emane_model: "EmaneModel", iface: CoreInterface = None) -> str:
|
||||
"""
|
||||
Return the string name for the SHIM XML file, e.g. "commeffectshim.xml"
|
||||
|
||||
:param emane_model: emane model to create file
|
||||
:param interface: interface for this model
|
||||
:param iface: interface for this model
|
||||
:return: shim xml filename
|
||||
"""
|
||||
name = _basename(emane_model, interface)
|
||||
name = _basename(emane_model, iface)
|
||||
return f"{name}shim.xml"
|
||||
|
||||
|
||||
def mac_file_name(emane_model: "EmaneModel", interface: CoreInterface = None) -> str:
|
||||
def mac_file_name(emane_model: "EmaneModel", iface: CoreInterface = None) -> str:
|
||||
"""
|
||||
Return the string name for the MAC XML file, e.g. "n3rfpipemac.xml"
|
||||
|
||||
:param emane_model: emane model to create file
|
||||
:param interface: interface for this model
|
||||
:param iface: interface for this model
|
||||
:return: mac xml filename
|
||||
"""
|
||||
name = _basename(emane_model, interface)
|
||||
name = _basename(emane_model, iface)
|
||||
return f"{name}mac.xml"
|
||||
|
||||
|
||||
def phy_file_name(emane_model: "EmaneModel", interface: CoreInterface = None) -> str:
|
||||
def phy_file_name(emane_model: "EmaneModel", iface: CoreInterface = None) -> str:
|
||||
"""
|
||||
Return the string name for the PHY XML file, e.g. "n3rfpipephy.xml"
|
||||
|
||||
:param emane_model: emane model to create file
|
||||
:param interface: interface for this model
|
||||
:param iface: interface for this model
|
||||
:return: phy xml filename
|
||||
"""
|
||||
name = _basename(emane_model, interface)
|
||||
name = _basename(emane_model, iface)
|
||||
return f"{name}phy.xml"
|
||||
|
|
|
@ -20,13 +20,13 @@ if __name__ == "__main__":
|
|||
# node one
|
||||
options.config_services = ["DefaultRoute", "IPForward"]
|
||||
node1 = session.add_node(CoreNode, options=options)
|
||||
interface = prefixes.create_interface(node1)
|
||||
session.add_link(node1.id, switch.id, interface1_data=interface)
|
||||
interface = prefixes.create_iface(node1)
|
||||
session.add_link(node1.id, switch.id, iface1_data=interface)
|
||||
|
||||
# node two
|
||||
node2 = session.add_node(CoreNode, options=options)
|
||||
interface = prefixes.create_interface(node2)
|
||||
session.add_link(node2.id, switch.id, interface1_data=interface)
|
||||
interface = prefixes.create_iface(node2)
|
||||
session.add_link(node2.id, switch.id, iface1_data=interface)
|
||||
|
||||
# start session and run services
|
||||
session.instantiate()
|
||||
|
|
|
@ -18,11 +18,11 @@ if __name__ == "__main__":
|
|||
|
||||
# create node one
|
||||
node1 = session.add_node(DockerNode, options=options)
|
||||
interface1_data = prefixes.create_interface(node1)
|
||||
interface1_data = prefixes.create_iface(node1)
|
||||
|
||||
# create node two
|
||||
node2 = session.add_node(CoreNode)
|
||||
interface2_data = prefixes.create_interface(node2)
|
||||
interface2_data = prefixes.create_iface(node2)
|
||||
|
||||
# add link
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data)
|
||||
|
|
|
@ -19,11 +19,11 @@ if __name__ == "__main__":
|
|||
|
||||
# create node one
|
||||
node1 = session.add_node(DockerNode, options=options)
|
||||
interface1_data = prefixes.create_interface(node1)
|
||||
interface1_data = prefixes.create_iface(node1)
|
||||
|
||||
# create node two
|
||||
node2 = session.add_node(DockerNode, options=options)
|
||||
interface2_data = prefixes.create_interface(node2)
|
||||
interface2_data = prefixes.create_iface(node2)
|
||||
|
||||
# add link
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data)
|
||||
|
|
|
@ -23,15 +23,15 @@ if __name__ == "__main__":
|
|||
|
||||
# node one
|
||||
node1 = session.add_node(DockerNode, options=options)
|
||||
interface1_data = prefixes.create_interface(node1)
|
||||
interface1_data = prefixes.create_iface(node1)
|
||||
|
||||
# node two
|
||||
node2 = session.add_node(DockerNode, options=options)
|
||||
interface2_data = prefixes.create_interface(node2)
|
||||
interface2_data = prefixes.create_iface(node2)
|
||||
|
||||
# node three
|
||||
node_three = session.add_node(CoreNode)
|
||||
interface_three = prefixes.create_interface(node_three)
|
||||
interface_three = prefixes.create_iface(node_three)
|
||||
|
||||
# add links
|
||||
session.add_link(node1.id, switch.id, interface1_data)
|
||||
|
|
|
@ -47,7 +47,7 @@ def main(args):
|
|||
node1_id = response.node_id
|
||||
|
||||
# create link
|
||||
interface1 = interface_helper.create_interface(node1_id, 0)
|
||||
interface1 = interface_helper.create_iface(node1_id, 0)
|
||||
response = core.add_link(session_id, node1_id, switch_id, interface1)
|
||||
logging.info("created link from node one to switch: %s", response)
|
||||
|
||||
|
@ -59,7 +59,7 @@ def main(args):
|
|||
node2_id = response.node_id
|
||||
|
||||
# create link
|
||||
interface1 = interface_helper.create_interface(node2_id, 0)
|
||||
interface1 = interface_helper.create_iface(node2_id, 0)
|
||||
response = core.add_link(session_id, node2_id, switch_id, interface1)
|
||||
logging.info("created link from node two to switch: %s", response)
|
||||
|
||||
|
|
|
@ -57,10 +57,10 @@ def main():
|
|||
node2_id = response.node_id
|
||||
|
||||
# links nodes to switch
|
||||
interface1 = interface_helper.create_interface(node1_id, 0)
|
||||
interface1 = interface_helper.create_iface(node1_id, 0)
|
||||
response = core.add_link(session_id, node1_id, emane_id, interface1)
|
||||
logging.info("created link: %s", response)
|
||||
interface1 = interface_helper.create_interface(node2_id, 0)
|
||||
interface1 = interface_helper.create_iface(node2_id, 0)
|
||||
response = core.add_link(session_id, node2_id, emane_id, interface1)
|
||||
logging.info("created link: %s", response)
|
||||
|
||||
|
|
|
@ -53,10 +53,10 @@ def main():
|
|||
node2_id = response.node_id
|
||||
|
||||
# links nodes to switch
|
||||
interface1 = interface_helper.create_interface(node1_id, 0)
|
||||
interface1 = interface_helper.create_iface(node1_id, 0)
|
||||
response = core.add_link(session_id, node1_id, switch_id, interface1)
|
||||
logging.info("created link: %s", response)
|
||||
interface1 = interface_helper.create_interface(node2_id, 0)
|
||||
interface1 = interface_helper.create_iface(node2_id, 0)
|
||||
response = core.add_link(session_id, node2_id, switch_id, interface1)
|
||||
logging.info("created link: %s", response)
|
||||
|
||||
|
|
|
@ -65,10 +65,10 @@ def main():
|
|||
node2_id = response.node_id
|
||||
|
||||
# links nodes to switch
|
||||
interface1 = interface_helper.create_interface(node1_id, 0)
|
||||
interface1 = interface_helper.create_iface(node1_id, 0)
|
||||
response = core.add_link(session_id, node1_id, wlan_id, interface1)
|
||||
logging.info("created link: %s", response)
|
||||
interface1 = interface_helper.create_interface(node2_id, 0)
|
||||
interface1 = interface_helper.create_iface(node2_id, 0)
|
||||
response = core.add_link(session_id, node2_id, wlan_id, interface1)
|
||||
logging.info("created link: %s", response)
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@ if __name__ == "__main__":
|
|||
|
||||
# create node one
|
||||
node1 = session.add_node(LxcNode, options=options)
|
||||
interface1_data = prefixes.create_interface(node1)
|
||||
interface1_data = prefixes.create_iface(node1)
|
||||
|
||||
# create node two
|
||||
node2 = session.add_node(CoreNode)
|
||||
interface2_data = prefixes.create_interface(node2)
|
||||
interface2_data = prefixes.create_iface(node2)
|
||||
|
||||
# add link
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data)
|
||||
|
|
|
@ -19,11 +19,11 @@ if __name__ == "__main__":
|
|||
|
||||
# create node one
|
||||
node1 = session.add_node(LxcNode, options=options)
|
||||
interface1_data = prefixes.create_interface(node1)
|
||||
interface1_data = prefixes.create_iface(node1)
|
||||
|
||||
# create node two
|
||||
node2 = session.add_node(LxcNode, options=options)
|
||||
interface2_data = prefixes.create_interface(node2)
|
||||
interface2_data = prefixes.create_iface(node2)
|
||||
|
||||
# add link
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data)
|
||||
|
|
|
@ -23,15 +23,15 @@ if __name__ == "__main__":
|
|||
|
||||
# node one
|
||||
node1 = session.add_node(LxcNode, options=options)
|
||||
interface1_data = prefixes.create_interface(node1)
|
||||
interface1_data = prefixes.create_iface(node1)
|
||||
|
||||
# node two
|
||||
node2 = session.add_node(LxcNode, options=options)
|
||||
interface2_data = prefixes.create_interface(node2)
|
||||
interface2_data = prefixes.create_iface(node2)
|
||||
|
||||
# node three
|
||||
node3 = session.add_node(CoreNode)
|
||||
interface3_data = prefixes.create_interface(node3)
|
||||
interface3_data = prefixes.create_iface(node3)
|
||||
|
||||
# add links
|
||||
session.add_link(node1.id, switch.id, interface1_data)
|
||||
|
|
|
@ -80,8 +80,8 @@ class MyService(CoreService):
|
|||
|
||||
if filename == cls.configs[0]:
|
||||
cfg += "# auto-generated by MyService (sample.py)\n"
|
||||
for ifc in node.netifs():
|
||||
cfg += f'echo "Node {node.name} has interface {ifc.name}"\n'
|
||||
for iface in node.get_ifaces():
|
||||
cfg += f'echo "Node {node.name} has interface {iface.name}"\n'
|
||||
elif filename == cls.configs[1]:
|
||||
cfg += "echo hello"
|
||||
|
||||
|
|
|
@ -59,10 +59,10 @@ def main(args):
|
|||
node2 = session.add_node(CoreNode, options=options)
|
||||
|
||||
# create node interfaces and link
|
||||
interface1_data = prefixes.create_interface(node1)
|
||||
interface2_data = prefixes.create_interface(node2)
|
||||
session.add_link(node1.id, emane_net.id, interface1_data=interface1_data)
|
||||
session.add_link(node2.id, emane_net.id, interface1_data=interface2_data)
|
||||
interface1_data = prefixes.create_iface(node1)
|
||||
interface2_data = prefixes.create_iface(node2)
|
||||
session.add_link(node1.id, emane_net.id, iface1_data=interface1_data)
|
||||
session.add_link(node2.id, emane_net.id, iface1_data=interface2_data)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
|
|
@ -48,8 +48,8 @@ def main(args):
|
|||
node2 = session.add_node(LxcNode, options=options)
|
||||
|
||||
# create node interfaces and link
|
||||
interface1_data = prefixes.create_interface(node1)
|
||||
interface2_data = prefixes.create_interface(node2)
|
||||
interface1_data = prefixes.create_iface(node1)
|
||||
interface2_data = prefixes.create_iface(node2)
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data)
|
||||
|
||||
# instantiate session
|
||||
|
|
|
@ -48,8 +48,8 @@ def main(args):
|
|||
node2 = session.add_node(CoreNode, options=options)
|
||||
|
||||
# create node interfaces and link
|
||||
interface1_data = prefixes.create_interface(node1)
|
||||
interface2_data = prefixes.create_interface(node2)
|
||||
interface1_data = prefixes.create_iface(node1)
|
||||
interface2_data = prefixes.create_iface(node2)
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data)
|
||||
|
||||
# instantiate session
|
||||
|
|
|
@ -52,10 +52,10 @@ def main(args):
|
|||
node2 = session.add_node(CoreNode, options=options)
|
||||
|
||||
# create node interfaces and link
|
||||
interface1_data = prefixes.create_interface(node1)
|
||||
interface2_data = prefixes.create_interface(node2)
|
||||
session.add_link(node1.id, switch.id, interface1_data=interface1_data)
|
||||
session.add_link(node2.id, switch.id, interface1_data=interface2_data)
|
||||
interface1_data = prefixes.create_iface(node1)
|
||||
interface2_data = prefixes.create_iface(node2)
|
||||
session.add_link(node1.id, switch.id, iface1_data=interface1_data)
|
||||
session.add_link(node2.id, switch.id, iface1_data=interface2_data)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
|
|
@ -42,8 +42,8 @@ def main():
|
|||
for i in range(NODES):
|
||||
node = session.add_node(CoreNode, options=options)
|
||||
node.setposition(x=150 * (i + 1), y=150)
|
||||
interface = prefixes.create_interface(node)
|
||||
session.add_link(node.id, emane_network.id, interface1_data=interface)
|
||||
interface = prefixes.create_iface(node)
|
||||
session.add_link(node.id, emane_network.id, iface1_data=interface)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
|
|
@ -31,8 +31,8 @@ def main():
|
|||
# create nodes
|
||||
for _ in range(NODES):
|
||||
node = session.add_node(CoreNode)
|
||||
interface = prefixes.create_interface(node)
|
||||
session.add_link(node.id, switch.id, interface1_data=interface)
|
||||
interface = prefixes.create_iface(node)
|
||||
session.add_link(node.id, switch.id, iface1_data=interface)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
|
|
@ -33,8 +33,8 @@ def main():
|
|||
# create nodes
|
||||
for _ in range(NODES):
|
||||
node = session.add_node(CoreNode)
|
||||
interface = prefixes.create_interface(node)
|
||||
session.add_link(node.id, switch.id, interface1_data=interface)
|
||||
interface = prefixes.create_iface(node)
|
||||
session.add_link(node.id, switch.id, iface1_data=interface)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
|
|
@ -35,8 +35,8 @@ def main():
|
|||
options.set_position(0, 0)
|
||||
for _ in range(NODES):
|
||||
node = session.add_node(CoreNode, options=options)
|
||||
interface = prefixes.create_interface(node)
|
||||
session.add_link(node.id, wlan.id, interface1_data=interface)
|
||||
interface = prefixes.create_iface(node)
|
||||
session.add_link(node.id, wlan.id, iface1_data=interface)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
|
|
@ -319,12 +319,12 @@ message ThroughputsRequest {
|
|||
message ThroughputsEvent {
|
||||
int32 session_id = 1;
|
||||
repeated BridgeThroughput bridge_throughputs = 2;
|
||||
repeated InterfaceThroughput interface_throughputs = 3;
|
||||
repeated InterfaceThroughput iface_throughputs = 3;
|
||||
}
|
||||
|
||||
message InterfaceThroughput {
|
||||
int32 node_id = 1;
|
||||
int32 interface_id = 2;
|
||||
int32 iface_id = 2;
|
||||
double throughput = 3;
|
||||
}
|
||||
|
||||
|
@ -374,7 +374,7 @@ message ConfigEvent {
|
|||
string bitmap = 8;
|
||||
string possible_values = 9;
|
||||
string groups = 10;
|
||||
int32 interface = 11;
|
||||
int32 iface_id = 11;
|
||||
int32 network_id = 12;
|
||||
string opaque = 13;
|
||||
}
|
||||
|
@ -416,7 +416,7 @@ message GetNodeRequest {
|
|||
|
||||
message GetNodeResponse {
|
||||
Node node = 1;
|
||||
repeated Interface interfaces = 2;
|
||||
repeated Interface ifaces = 2;
|
||||
}
|
||||
|
||||
message EditNodeRequest {
|
||||
|
@ -492,16 +492,16 @@ message AddLinkRequest {
|
|||
|
||||
message AddLinkResponse {
|
||||
bool result = 1;
|
||||
Interface interface1 = 2;
|
||||
Interface interface2 = 3;
|
||||
Interface iface1 = 2;
|
||||
Interface iface2 = 3;
|
||||
}
|
||||
|
||||
message EditLinkRequest {
|
||||
int32 session_id = 1;
|
||||
int32 node1_id = 2;
|
||||
int32 node2_id = 3;
|
||||
int32 interface1_id = 4;
|
||||
int32 interface2_id = 5;
|
||||
int32 iface1_id = 4;
|
||||
int32 iface2_id = 5;
|
||||
LinkOptions options = 6;
|
||||
}
|
||||
|
||||
|
@ -513,8 +513,8 @@ message DeleteLinkRequest {
|
|||
int32 session_id = 1;
|
||||
int32 node1_id = 2;
|
||||
int32 node2_id = 3;
|
||||
int32 interface1_id = 4;
|
||||
int32 interface2_id = 5;
|
||||
int32 iface1_id = 4;
|
||||
int32 iface2_id = 5;
|
||||
}
|
||||
|
||||
message DeleteLinkResponse {
|
||||
|
@ -561,7 +561,7 @@ message GetInterfacesRequest {
|
|||
}
|
||||
|
||||
message GetInterfacesResponse {
|
||||
repeated string interfaces = 1;
|
||||
repeated string ifaces = 1;
|
||||
}
|
||||
|
||||
message ExecuteScriptRequest {
|
||||
|
@ -705,8 +705,8 @@ message Link {
|
|||
int32 node1_id = 1;
|
||||
int32 node2_id = 2;
|
||||
LinkType.Enum type = 3;
|
||||
Interface interface1 = 4;
|
||||
Interface interface2 = 5;
|
||||
Interface iface1 = 4;
|
||||
Interface iface2 = 5;
|
||||
LinkOptions options = 6;
|
||||
int32 network_id = 7;
|
||||
string label = 8;
|
||||
|
|
|
@ -32,7 +32,7 @@ message GetEmaneModelsResponse {
|
|||
message GetEmaneModelConfigRequest {
|
||||
int32 session_id = 1;
|
||||
int32 node_id = 2;
|
||||
int32 interface = 3;
|
||||
int32 iface_id = 3;
|
||||
string model = 4;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ message GetEmaneModelConfigsResponse {
|
|||
message ModelConfig {
|
||||
int32 node_id = 1;
|
||||
string model = 2;
|
||||
int32 interface = 3;
|
||||
int32 iface_id = 3;
|
||||
map<string, common.ConfigOption> config = 4;
|
||||
}
|
||||
repeated ModelConfig configs = 1;
|
||||
|
@ -86,7 +86,7 @@ message EmaneLinkResponse {
|
|||
|
||||
message EmaneModelConfig {
|
||||
int32 node_id = 1;
|
||||
int32 interface_id = 2;
|
||||
int32 iface_id = 2;
|
||||
string model = 3;
|
||||
map<string, string> config = 4;
|
||||
}
|
||||
|
@ -95,10 +95,10 @@ message EmanePathlossesRequest {
|
|||
int32 session_id = 1;
|
||||
int32 node1_id = 2;
|
||||
float rx1 = 3;
|
||||
int32 interface1_id = 4;
|
||||
int32 iface1_id = 4;
|
||||
int32 node2_id = 5;
|
||||
float rx2 = 6;
|
||||
int32 interface2_id = 7;
|
||||
int32 iface2_id = 7;
|
||||
}
|
||||
|
||||
message EmanePathlossesResponse {
|
||||
|
|
|
@ -101,8 +101,8 @@ class RouterMonitor:
|
|||
node_map[node.id] = node.channel
|
||||
if self.src_id is None:
|
||||
response = self.core.get_node(self.session, node.id)
|
||||
for netif in response.interfaces:
|
||||
if self.src == netif.ip4:
|
||||
for iface in response.ifaces:
|
||||
if self.src == iface.ip4:
|
||||
self.src_id = node.id
|
||||
break
|
||||
except grpc.RpcError:
|
||||
|
|
|
@ -89,7 +89,7 @@ def ip_prefixes():
|
|||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def interface_helper():
|
||||
def iface_helper():
|
||||
return InterfaceHelper(ip4_prefix="10.83.0.0/16")
|
||||
|
||||
|
||||
|
|
|
@ -79,8 +79,8 @@ class TestEmane:
|
|||
|
||||
for i, node in enumerate([node1, node2]):
|
||||
node.setposition(x=150 * (i + 1), y=150)
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, emane_network.id, interface1_data=interface)
|
||||
iface_data = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, emane_network.id, iface1_data=iface_data)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -119,8 +119,8 @@ class TestEmane:
|
|||
|
||||
for i, node in enumerate([node1, node2]):
|
||||
node.setposition(x=150 * (i + 1), y=150)
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, emane_network.id, interface1_data=interface)
|
||||
iface_data = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, emane_network.id, iface1_data=iface_data)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
|
|
@ -53,8 +53,8 @@ class TestCore:
|
|||
|
||||
# link nodes to net node
|
||||
for node in [node1, node2]:
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, net_node.id, interface1_data=interface)
|
||||
iface_data = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, net_node.id, iface1_data=iface_data)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -80,8 +80,8 @@ class TestCore:
|
|||
|
||||
# link nodes to ptp net
|
||||
for node in [node1, node2]:
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, ptp_node.id, interface1_data=interface)
|
||||
iface_data = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, ptp_node.id, iface1_data=iface_data)
|
||||
|
||||
# get node client for testing
|
||||
client = node1.client
|
||||
|
@ -96,9 +96,9 @@ class TestCore:
|
|||
if not request.config.getoption("mock"):
|
||||
assert client.check_cmd("echo hello") == "hello"
|
||||
|
||||
def test_netif(self, session: Session, ip_prefixes: IpPrefixes):
|
||||
def test_iface(self, session: Session, ip_prefixes: IpPrefixes):
|
||||
"""
|
||||
Test netif methods.
|
||||
Test interface methods.
|
||||
|
||||
:param session: session for test
|
||||
:param ip_prefixes: generates ip addresses for nodes
|
||||
|
@ -113,8 +113,8 @@ class TestCore:
|
|||
|
||||
# link nodes to ptp net
|
||||
for node in [node1, node2]:
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, ptp_node.id, interface1_data=interface)
|
||||
iface = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, ptp_node.id, iface1_data=iface)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -126,19 +126,19 @@ class TestCore:
|
|||
assert node1.commonnets(node2)
|
||||
assert node2.commonnets(node1)
|
||||
|
||||
# check we can retrieve netif index
|
||||
assert node1.ifname(0)
|
||||
assert node2.ifname(0)
|
||||
# check we can retrieve interface id
|
||||
assert 0 in node1.ifaces
|
||||
assert 0 in node2.ifaces
|
||||
|
||||
# check interface parameters
|
||||
interface = node1.netif(0)
|
||||
interface.setparam("test", 1)
|
||||
assert interface.getparam("test") == 1
|
||||
assert interface.getparams()
|
||||
iface = node1.get_iface(0)
|
||||
iface.setparam("test", 1)
|
||||
assert iface.getparam("test") == 1
|
||||
assert iface.getparams()
|
||||
|
||||
# delete netif and test that if no longer exists
|
||||
node1.delnetif(0)
|
||||
assert not node1.netif(0)
|
||||
# delete interface and test that if no longer exists
|
||||
node1.delete_iface(0)
|
||||
assert 0 not in node1.ifaces
|
||||
|
||||
def test_wlan_ping(self, session: Session, ip_prefixes: IpPrefixes):
|
||||
"""
|
||||
|
@ -160,8 +160,8 @@ class TestCore:
|
|||
|
||||
# link nodes
|
||||
for node in [node1, node2]:
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, wlan_node.id, interface1_data=interface)
|
||||
iface_id = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, wlan_node.id, iface1_data=iface_id)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -190,8 +190,8 @@ class TestCore:
|
|||
|
||||
# link nodes
|
||||
for node in [node1, node2]:
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, wlan_node.id, interface1_data=interface)
|
||||
iface_id = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, wlan_node.id, iface1_data=iface_id)
|
||||
|
||||
# configure mobility script for session
|
||||
config = {
|
||||
|
|
|
@ -42,15 +42,17 @@ class TestGrpc:
|
|||
id=3, type=NodeTypes.WIRELESS_LAN.value, position=position
|
||||
)
|
||||
nodes = [node1, node2, wlan_node]
|
||||
interface_helper = InterfaceHelper(ip4_prefix="10.83.0.0/16")
|
||||
interface1 = interface_helper.create_interface(node1.id, 0)
|
||||
interface2 = interface_helper.create_interface(node2.id, 0)
|
||||
iface_helper = InterfaceHelper(ip4_prefix="10.83.0.0/16")
|
||||
iface1_id = 0
|
||||
iface1 = iface_helper.create_iface(node1.id, iface1_id)
|
||||
iface2_id = 0
|
||||
iface2 = iface_helper.create_iface(node2.id, iface2_id)
|
||||
link = core_pb2.Link(
|
||||
type=core_pb2.LinkType.WIRED,
|
||||
node1_id=node1.id,
|
||||
node2_id=node2.id,
|
||||
interface1=interface1,
|
||||
interface2=interface2,
|
||||
iface1=iface1,
|
||||
iface2=iface2,
|
||||
)
|
||||
links = [link]
|
||||
hook = core_pb2.Hook(
|
||||
|
@ -81,7 +83,7 @@ class TestGrpc:
|
|||
model_config_value = "500000"
|
||||
model_config = EmaneModelConfig(
|
||||
node_id=model_node_id,
|
||||
interface_id=-1,
|
||||
iface_id=-1,
|
||||
model=EmaneIeee80211abgModel.name,
|
||||
config={model_config_key: model_config_value},
|
||||
)
|
||||
|
@ -131,8 +133,8 @@ class TestGrpc:
|
|||
assert node1.id in session.nodes
|
||||
assert node2.id in session.nodes
|
||||
assert wlan_node.id in session.nodes
|
||||
assert session.nodes[node1.id].netif(0) is not None
|
||||
assert session.nodes[node2.id].netif(0) is not None
|
||||
assert iface1_id in session.nodes[node1.id].ifaces
|
||||
assert iface2_id in session.nodes[node2.id].ifaces
|
||||
hook_file, hook_data = session.hooks[EventTypes.RUNTIME_STATE][0]
|
||||
assert hook_file == hook.file
|
||||
assert hook_data == hook.data
|
||||
|
@ -522,8 +524,8 @@ class TestGrpc:
|
|||
session = grpc_server.coreemu.create_session()
|
||||
switch = session.add_node(SwitchNode)
|
||||
node = session.add_node(CoreNode)
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, switch.id, interface)
|
||||
iface_data = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, switch.id, iface_data)
|
||||
|
||||
# then
|
||||
with client.context_connect():
|
||||
|
@ -540,17 +542,15 @@ class TestGrpc:
|
|||
session = grpc_server.coreemu.create_session()
|
||||
switch = session.add_node(SwitchNode)
|
||||
node = session.add_node(CoreNode)
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, switch.id, interface)
|
||||
iface_data = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, switch.id, iface_data)
|
||||
|
||||
# then
|
||||
with pytest.raises(grpc.RpcError):
|
||||
with client.context_connect():
|
||||
client.get_node_links(session.id, 3)
|
||||
|
||||
def test_add_link(
|
||||
self, grpc_server: CoreGrpcServer, interface_helper: InterfaceHelper
|
||||
):
|
||||
def test_add_link(self, grpc_server: CoreGrpcServer, iface_helper: InterfaceHelper):
|
||||
# given
|
||||
client = CoreGrpcClient()
|
||||
session = grpc_server.coreemu.create_session()
|
||||
|
@ -559,16 +559,16 @@ class TestGrpc:
|
|||
assert len(switch.all_link_data()) == 0
|
||||
|
||||
# then
|
||||
interface = interface_helper.create_interface(node.id, 0)
|
||||
iface = iface_helper.create_iface(node.id, 0)
|
||||
with client.context_connect():
|
||||
response = client.add_link(session.id, node.id, switch.id, interface)
|
||||
response = client.add_link(session.id, node.id, switch.id, iface)
|
||||
|
||||
# then
|
||||
assert response.result is True
|
||||
assert len(switch.all_link_data()) == 1
|
||||
|
||||
def test_add_link_exception(
|
||||
self, grpc_server: CoreGrpcServer, interface_helper: InterfaceHelper
|
||||
self, grpc_server: CoreGrpcServer, iface_helper: InterfaceHelper
|
||||
):
|
||||
# given
|
||||
client = CoreGrpcClient()
|
||||
|
@ -576,10 +576,10 @@ class TestGrpc:
|
|||
node = session.add_node(CoreNode)
|
||||
|
||||
# then
|
||||
interface = interface_helper.create_interface(node.id, 0)
|
||||
iface = iface_helper.create_iface(node.id, 0)
|
||||
with pytest.raises(grpc.RpcError):
|
||||
with client.context_connect():
|
||||
client.add_link(session.id, 1, 3, interface)
|
||||
client.add_link(session.id, 1, 3, iface)
|
||||
|
||||
def test_edit_link(self, grpc_server: CoreGrpcServer, ip_prefixes: IpPrefixes):
|
||||
# given
|
||||
|
@ -587,8 +587,8 @@ class TestGrpc:
|
|||
session = grpc_server.coreemu.create_session()
|
||||
switch = session.add_node(SwitchNode)
|
||||
node = session.add_node(CoreNode)
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, switch.id, interface)
|
||||
iface = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, switch.id, iface)
|
||||
options = core_pb2.LinkOptions(bandwidth=30000)
|
||||
link = switch.all_link_data()[0]
|
||||
assert options.bandwidth != link.bandwidth
|
||||
|
@ -596,7 +596,7 @@ class TestGrpc:
|
|||
# then
|
||||
with client.context_connect():
|
||||
response = client.edit_link(
|
||||
session.id, node.id, switch.id, options, interface1_id=interface.id
|
||||
session.id, node.id, switch.id, options, iface1_id=iface.id
|
||||
)
|
||||
|
||||
# then
|
||||
|
@ -609,10 +609,10 @@ class TestGrpc:
|
|||
client = CoreGrpcClient()
|
||||
session = grpc_server.coreemu.create_session()
|
||||
node1 = session.add_node(CoreNode)
|
||||
interface1 = ip_prefixes.create_interface(node1)
|
||||
iface1 = ip_prefixes.create_iface(node1)
|
||||
node2 = session.add_node(CoreNode)
|
||||
interface2 = ip_prefixes.create_interface(node2)
|
||||
session.add_link(node1.id, node2.id, interface1, interface2)
|
||||
iface2 = ip_prefixes.create_iface(node2)
|
||||
session.add_link(node1.id, node2.id, iface1, iface2)
|
||||
link_node = None
|
||||
for node_id in session.nodes:
|
||||
node = session.nodes[node_id]
|
||||
|
@ -624,7 +624,7 @@ class TestGrpc:
|
|||
# then
|
||||
with client.context_connect():
|
||||
response = client.delete_link(
|
||||
session.id, node1.id, node2.id, interface1.id, interface2.id
|
||||
session.id, node1.id, node2.id, iface1.id, iface2.id
|
||||
)
|
||||
|
||||
# then
|
||||
|
@ -729,7 +729,7 @@ class TestGrpc:
|
|||
assert emane_network.id == model_config.node_id
|
||||
assert model_config.model == EmaneIeee80211abgModel.name
|
||||
assert len(model_config.config) > 0
|
||||
assert model_config.interface == -1
|
||||
assert model_config.iface_id == -1
|
||||
|
||||
def test_set_emane_model_config(self, grpc_server: CoreGrpcServer):
|
||||
# given
|
||||
|
@ -1028,8 +1028,8 @@ class TestGrpc:
|
|||
session = grpc_server.coreemu.create_session()
|
||||
wlan = session.add_node(WlanNode)
|
||||
node = session.add_node(CoreNode)
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, wlan.id, interface)
|
||||
iface = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, wlan.id, iface)
|
||||
link_data = wlan.all_link_data()[0]
|
||||
queue = Queue()
|
||||
|
||||
|
|
|
@ -107,15 +107,15 @@ class TestGui:
|
|||
switch_id = 2
|
||||
coretlv.session.add_node(SwitchNode, _id=switch_id)
|
||||
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||
interface1_ip4 = str(ip_prefix[node1_id])
|
||||
iface1_ip4 = str(ip_prefix[node1_id])
|
||||
message = coreapi.CoreLinkMessage.create(
|
||||
MessageFlags.ADD.value,
|
||||
[
|
||||
(LinkTlvs.N1_NUMBER, node1_id),
|
||||
(LinkTlvs.N2_NUMBER, switch_id),
|
||||
(LinkTlvs.INTERFACE1_NUMBER, 0),
|
||||
(LinkTlvs.INTERFACE1_IP4, interface1_ip4),
|
||||
(LinkTlvs.INTERFACE1_IP4_MASK, 24),
|
||||
(LinkTlvs.IFACE1_NUMBER, 0),
|
||||
(LinkTlvs.IFACE1_IP4, iface1_ip4),
|
||||
(LinkTlvs.IFACE1_IP4_MASK, 24),
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -131,15 +131,15 @@ class TestGui:
|
|||
switch_id = 2
|
||||
coretlv.session.add_node(SwitchNode, _id=switch_id)
|
||||
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||
interface2_ip4 = str(ip_prefix[node1_id])
|
||||
iface2_ip4 = str(ip_prefix[node1_id])
|
||||
message = coreapi.CoreLinkMessage.create(
|
||||
MessageFlags.ADD.value,
|
||||
[
|
||||
(LinkTlvs.N1_NUMBER, switch_id),
|
||||
(LinkTlvs.N2_NUMBER, node1_id),
|
||||
(LinkTlvs.INTERFACE2_NUMBER, 0),
|
||||
(LinkTlvs.INTERFACE2_IP4, interface2_ip4),
|
||||
(LinkTlvs.INTERFACE2_IP4_MASK, 24),
|
||||
(LinkTlvs.IFACE2_NUMBER, 0),
|
||||
(LinkTlvs.IFACE2_IP4, iface2_ip4),
|
||||
(LinkTlvs.IFACE2_IP4_MASK, 24),
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -155,19 +155,19 @@ class TestGui:
|
|||
node2_id = 2
|
||||
coretlv.session.add_node(CoreNode, _id=node2_id)
|
||||
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||
interface1_ip4 = str(ip_prefix[node1_id])
|
||||
interface2_ip4 = str(ip_prefix[node2_id])
|
||||
iface1_ip4 = str(ip_prefix[node1_id])
|
||||
iface2_ip4 = str(ip_prefix[node2_id])
|
||||
message = coreapi.CoreLinkMessage.create(
|
||||
MessageFlags.ADD.value,
|
||||
[
|
||||
(LinkTlvs.N1_NUMBER, node1_id),
|
||||
(LinkTlvs.N2_NUMBER, node2_id),
|
||||
(LinkTlvs.INTERFACE1_NUMBER, 0),
|
||||
(LinkTlvs.INTERFACE1_IP4, interface1_ip4),
|
||||
(LinkTlvs.INTERFACE1_IP4_MASK, 24),
|
||||
(LinkTlvs.INTERFACE2_NUMBER, 0),
|
||||
(LinkTlvs.INTERFACE2_IP4, interface2_ip4),
|
||||
(LinkTlvs.INTERFACE2_IP4_MASK, 24),
|
||||
(LinkTlvs.IFACE1_NUMBER, 0),
|
||||
(LinkTlvs.IFACE1_IP4, iface1_ip4),
|
||||
(LinkTlvs.IFACE1_IP4_MASK, 24),
|
||||
(LinkTlvs.IFACE2_NUMBER, 0),
|
||||
(LinkTlvs.IFACE2_IP4, iface2_ip4),
|
||||
(LinkTlvs.IFACE2_IP4_MASK, 24),
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -185,15 +185,15 @@ class TestGui:
|
|||
switch_id = 2
|
||||
coretlv.session.add_node(SwitchNode, _id=switch_id)
|
||||
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||
interface1_ip4 = str(ip_prefix[node1_id])
|
||||
iface1_ip4 = str(ip_prefix[node1_id])
|
||||
message = coreapi.CoreLinkMessage.create(
|
||||
MessageFlags.ADD.value,
|
||||
[
|
||||
(LinkTlvs.N1_NUMBER, node1_id),
|
||||
(LinkTlvs.N2_NUMBER, switch_id),
|
||||
(LinkTlvs.INTERFACE1_NUMBER, 0),
|
||||
(LinkTlvs.INTERFACE1_IP4, interface1_ip4),
|
||||
(LinkTlvs.INTERFACE1_IP4_MASK, 24),
|
||||
(LinkTlvs.IFACE1_NUMBER, 0),
|
||||
(LinkTlvs.IFACE1_IP4, iface1_ip4),
|
||||
(LinkTlvs.IFACE1_IP4_MASK, 24),
|
||||
],
|
||||
)
|
||||
coretlv.handle_message(message)
|
||||
|
@ -209,7 +209,7 @@ class TestGui:
|
|||
[
|
||||
(LinkTlvs.N1_NUMBER, node1_id),
|
||||
(LinkTlvs.N2_NUMBER, switch_id),
|
||||
(LinkTlvs.INTERFACE1_NUMBER, 0),
|
||||
(LinkTlvs.IFACE1_NUMBER, 0),
|
||||
(LinkTlvs.BANDWIDTH, bandwidth),
|
||||
],
|
||||
)
|
||||
|
@ -227,18 +227,18 @@ class TestGui:
|
|||
node2_id = 2
|
||||
coretlv.session.add_node(CoreNode, _id=node2_id)
|
||||
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||
interface1_ip4 = str(ip_prefix[node1_id])
|
||||
interface2_ip4 = str(ip_prefix[node2_id])
|
||||
iface1_ip4 = str(ip_prefix[node1_id])
|
||||
iface2_ip4 = str(ip_prefix[node2_id])
|
||||
message = coreapi.CoreLinkMessage.create(
|
||||
MessageFlags.ADD.value,
|
||||
[
|
||||
(LinkTlvs.N1_NUMBER, node1_id),
|
||||
(LinkTlvs.N2_NUMBER, node2_id),
|
||||
(LinkTlvs.INTERFACE1_NUMBER, 0),
|
||||
(LinkTlvs.INTERFACE1_IP4, interface1_ip4),
|
||||
(LinkTlvs.INTERFACE1_IP4_MASK, 24),
|
||||
(LinkTlvs.INTERFACE2_IP4, interface2_ip4),
|
||||
(LinkTlvs.INTERFACE2_IP4_MASK, 24),
|
||||
(LinkTlvs.IFACE1_NUMBER, 0),
|
||||
(LinkTlvs.IFACE1_IP4, iface1_ip4),
|
||||
(LinkTlvs.IFACE1_IP4_MASK, 24),
|
||||
(LinkTlvs.IFACE2_IP4, iface2_ip4),
|
||||
(LinkTlvs.IFACE2_IP4_MASK, 24),
|
||||
],
|
||||
)
|
||||
coretlv.handle_message(message)
|
||||
|
@ -253,8 +253,8 @@ class TestGui:
|
|||
[
|
||||
(LinkTlvs.N1_NUMBER, node1_id),
|
||||
(LinkTlvs.N2_NUMBER, node2_id),
|
||||
(LinkTlvs.INTERFACE1_NUMBER, 0),
|
||||
(LinkTlvs.INTERFACE2_NUMBER, 0),
|
||||
(LinkTlvs.IFACE1_NUMBER, 0),
|
||||
(LinkTlvs.IFACE2_NUMBER, 0),
|
||||
],
|
||||
)
|
||||
coretlv.handle_message(message)
|
||||
|
@ -271,15 +271,15 @@ class TestGui:
|
|||
switch_id = 2
|
||||
coretlv.session.add_node(SwitchNode, _id=switch_id)
|
||||
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||
interface1_ip4 = str(ip_prefix[node1_id])
|
||||
iface1_ip4 = str(ip_prefix[node1_id])
|
||||
message = coreapi.CoreLinkMessage.create(
|
||||
MessageFlags.ADD.value,
|
||||
[
|
||||
(LinkTlvs.N1_NUMBER, node1_id),
|
||||
(LinkTlvs.N2_NUMBER, switch_id),
|
||||
(LinkTlvs.INTERFACE1_NUMBER, 0),
|
||||
(LinkTlvs.INTERFACE1_IP4, interface1_ip4),
|
||||
(LinkTlvs.INTERFACE1_IP4_MASK, 24),
|
||||
(LinkTlvs.IFACE1_NUMBER, 0),
|
||||
(LinkTlvs.IFACE1_IP4, iface1_ip4),
|
||||
(LinkTlvs.IFACE1_IP4_MASK, 24),
|
||||
],
|
||||
)
|
||||
coretlv.handle_message(message)
|
||||
|
@ -292,7 +292,7 @@ class TestGui:
|
|||
[
|
||||
(LinkTlvs.N1_NUMBER, node1_id),
|
||||
(LinkTlvs.N2_NUMBER, switch_id),
|
||||
(LinkTlvs.INTERFACE1_NUMBER, 0),
|
||||
(LinkTlvs.IFACE1_NUMBER, 0),
|
||||
],
|
||||
)
|
||||
coretlv.handle_message(message)
|
||||
|
@ -307,15 +307,15 @@ class TestGui:
|
|||
switch_id = 2
|
||||
coretlv.session.add_node(SwitchNode, _id=switch_id)
|
||||
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||
interface1_ip4 = str(ip_prefix[node1_id])
|
||||
iface1_ip4 = str(ip_prefix[node1_id])
|
||||
message = coreapi.CoreLinkMessage.create(
|
||||
MessageFlags.ADD.value,
|
||||
[
|
||||
(LinkTlvs.N1_NUMBER, node1_id),
|
||||
(LinkTlvs.N2_NUMBER, switch_id),
|
||||
(LinkTlvs.INTERFACE1_NUMBER, 0),
|
||||
(LinkTlvs.INTERFACE1_IP4, interface1_ip4),
|
||||
(LinkTlvs.INTERFACE1_IP4_MASK, 24),
|
||||
(LinkTlvs.IFACE1_NUMBER, 0),
|
||||
(LinkTlvs.IFACE1_IP4, iface1_ip4),
|
||||
(LinkTlvs.IFACE1_IP4_MASK, 24),
|
||||
],
|
||||
)
|
||||
coretlv.handle_message(message)
|
||||
|
@ -328,7 +328,7 @@ class TestGui:
|
|||
[
|
||||
(LinkTlvs.N1_NUMBER, switch_id),
|
||||
(LinkTlvs.N2_NUMBER, node1_id),
|
||||
(LinkTlvs.INTERFACE2_NUMBER, 0),
|
||||
(LinkTlvs.IFACE2_NUMBER, 0),
|
||||
],
|
||||
)
|
||||
coretlv.handle_message(message)
|
||||
|
|
|
@ -14,9 +14,9 @@ def create_ptp_network(
|
|||
node2 = session.add_node(CoreNode)
|
||||
|
||||
# link nodes to net node
|
||||
interface1_data = ip_prefixes.create_interface(node1)
|
||||
interface2_data = ip_prefixes.create_interface(node2)
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data)
|
||||
iface1_data = ip_prefixes.create_iface(node1)
|
||||
iface2_data = ip_prefixes.create_iface(node2)
|
||||
session.add_link(node1.id, node2.id, iface1_data, iface2_data)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -29,41 +29,41 @@ class TestLinks:
|
|||
# given
|
||||
node1 = session.add_node(CoreNode)
|
||||
node2 = session.add_node(CoreNode)
|
||||
interface1_data = ip_prefixes.create_interface(node1)
|
||||
interface2_data = ip_prefixes.create_interface(node2)
|
||||
iface1_data = ip_prefixes.create_iface(node1)
|
||||
iface2_data = ip_prefixes.create_iface(node2)
|
||||
|
||||
# when
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data)
|
||||
session.add_link(node1.id, node2.id, iface1_data, iface2_data)
|
||||
|
||||
# then
|
||||
assert node1.netif(interface1_data.id)
|
||||
assert node2.netif(interface2_data.id)
|
||||
assert node1.get_iface(iface1_data.id)
|
||||
assert node2.get_iface(iface2_data.id)
|
||||
|
||||
def test_add_node_to_net(self, session: Session, ip_prefixes: IpPrefixes):
|
||||
# given
|
||||
node1 = session.add_node(CoreNode)
|
||||
node2 = session.add_node(SwitchNode)
|
||||
interface1_data = ip_prefixes.create_interface(node1)
|
||||
iface1_data = ip_prefixes.create_iface(node1)
|
||||
|
||||
# when
|
||||
session.add_link(node1.id, node2.id, interface1_data=interface1_data)
|
||||
session.add_link(node1.id, node2.id, iface1_data=iface1_data)
|
||||
|
||||
# then
|
||||
assert node2.all_link_data()
|
||||
assert node1.netif(interface1_data.id)
|
||||
assert node1.get_iface(iface1_data.id)
|
||||
|
||||
def test_add_net_to_node(self, session: Session, ip_prefixes: IpPrefixes):
|
||||
# given
|
||||
node1 = session.add_node(SwitchNode)
|
||||
node2 = session.add_node(CoreNode)
|
||||
interface2_data = ip_prefixes.create_interface(node2)
|
||||
iface2_data = ip_prefixes.create_iface(node2)
|
||||
|
||||
# when
|
||||
session.add_link(node1.id, node2.id, interface2_data=interface2_data)
|
||||
session.add_link(node1.id, node2.id, iface2_data=iface2_data)
|
||||
|
||||
# then
|
||||
assert node1.all_link_data()
|
||||
assert node2.netif(interface2_data.id)
|
||||
assert node2.get_iface(iface2_data.id)
|
||||
|
||||
def test_add_net_to_net(self, session):
|
||||
# given
|
||||
|
@ -85,29 +85,29 @@ class TestLinks:
|
|||
jitter = 10
|
||||
node1 = session.add_node(CoreNode)
|
||||
node2 = session.add_node(SwitchNode)
|
||||
interface1_data = ip_prefixes.create_interface(node1)
|
||||
session.add_link(node1.id, node2.id, interface1_data)
|
||||
interface1 = node1.netif(interface1_data.id)
|
||||
assert interface1.getparam("delay") != delay
|
||||
assert interface1.getparam("bw") != bandwidth
|
||||
assert interface1.getparam("loss") != loss
|
||||
assert interface1.getparam("duplicate") != dup
|
||||
assert interface1.getparam("jitter") != jitter
|
||||
iface1_data = ip_prefixes.create_iface(node1)
|
||||
session.add_link(node1.id, node2.id, iface1_data)
|
||||
iface1 = node1.get_iface(iface1_data.id)
|
||||
assert iface1.getparam("delay") != delay
|
||||
assert iface1.getparam("bw") != bandwidth
|
||||
assert iface1.getparam("loss") != loss
|
||||
assert iface1.getparam("duplicate") != dup
|
||||
assert iface1.getparam("jitter") != jitter
|
||||
|
||||
# when
|
||||
options = LinkOptions(
|
||||
delay=delay, bandwidth=bandwidth, loss=loss, dup=dup, jitter=jitter
|
||||
)
|
||||
session.update_link(
|
||||
node1.id, node2.id, interface1_id=interface1_data.id, options=options
|
||||
node1.id, node2.id, iface1_id=iface1_data.id, options=options
|
||||
)
|
||||
|
||||
# then
|
||||
assert interface1.getparam("delay") == delay
|
||||
assert interface1.getparam("bw") == bandwidth
|
||||
assert interface1.getparam("loss") == loss
|
||||
assert interface1.getparam("duplicate") == dup
|
||||
assert interface1.getparam("jitter") == jitter
|
||||
assert iface1.getparam("delay") == delay
|
||||
assert iface1.getparam("bw") == bandwidth
|
||||
assert iface1.getparam("loss") == loss
|
||||
assert iface1.getparam("duplicate") == dup
|
||||
assert iface1.getparam("jitter") == jitter
|
||||
|
||||
def test_update_net_to_node(self, session: Session, ip_prefixes: IpPrefixes):
|
||||
# given
|
||||
|
@ -118,29 +118,29 @@ class TestLinks:
|
|||
jitter = 10
|
||||
node1 = session.add_node(SwitchNode)
|
||||
node2 = session.add_node(CoreNode)
|
||||
interface2_data = ip_prefixes.create_interface(node2)
|
||||
session.add_link(node1.id, node2.id, interface2_data=interface2_data)
|
||||
interface2 = node2.netif(interface2_data.id)
|
||||
assert interface2.getparam("delay") != delay
|
||||
assert interface2.getparam("bw") != bandwidth
|
||||
assert interface2.getparam("loss") != loss
|
||||
assert interface2.getparam("duplicate") != dup
|
||||
assert interface2.getparam("jitter") != jitter
|
||||
iface2_data = ip_prefixes.create_iface(node2)
|
||||
session.add_link(node1.id, node2.id, iface2_data=iface2_data)
|
||||
iface2 = node2.get_iface(iface2_data.id)
|
||||
assert iface2.getparam("delay") != delay
|
||||
assert iface2.getparam("bw") != bandwidth
|
||||
assert iface2.getparam("loss") != loss
|
||||
assert iface2.getparam("duplicate") != dup
|
||||
assert iface2.getparam("jitter") != jitter
|
||||
|
||||
# when
|
||||
options = LinkOptions(
|
||||
delay=delay, bandwidth=bandwidth, loss=loss, dup=dup, jitter=jitter
|
||||
)
|
||||
session.update_link(
|
||||
node1.id, node2.id, interface2_id=interface2_data.id, options=options
|
||||
node1.id, node2.id, iface2_id=iface2_data.id, options=options
|
||||
)
|
||||
|
||||
# then
|
||||
assert interface2.getparam("delay") == delay
|
||||
assert interface2.getparam("bw") == bandwidth
|
||||
assert interface2.getparam("loss") == loss
|
||||
assert interface2.getparam("duplicate") == dup
|
||||
assert interface2.getparam("jitter") == jitter
|
||||
assert iface2.getparam("delay") == delay
|
||||
assert iface2.getparam("bw") == bandwidth
|
||||
assert iface2.getparam("loss") == loss
|
||||
assert iface2.getparam("duplicate") == dup
|
||||
assert iface2.getparam("jitter") == jitter
|
||||
|
||||
def test_update_ptp(self, session: Session, ip_prefixes: IpPrefixes):
|
||||
# given
|
||||
|
@ -151,83 +151,81 @@ class TestLinks:
|
|||
jitter = 10
|
||||
node1 = session.add_node(CoreNode)
|
||||
node2 = session.add_node(CoreNode)
|
||||
interface1_data = ip_prefixes.create_interface(node1)
|
||||
interface2_data = ip_prefixes.create_interface(node2)
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data)
|
||||
interface1 = node1.netif(interface1_data.id)
|
||||
interface2 = node2.netif(interface2_data.id)
|
||||
assert interface1.getparam("delay") != delay
|
||||
assert interface1.getparam("bw") != bandwidth
|
||||
assert interface1.getparam("loss") != loss
|
||||
assert interface1.getparam("duplicate") != dup
|
||||
assert interface1.getparam("jitter") != jitter
|
||||
assert interface2.getparam("delay") != delay
|
||||
assert interface2.getparam("bw") != bandwidth
|
||||
assert interface2.getparam("loss") != loss
|
||||
assert interface2.getparam("duplicate") != dup
|
||||
assert interface2.getparam("jitter") != jitter
|
||||
iface1_data = ip_prefixes.create_iface(node1)
|
||||
iface2_data = ip_prefixes.create_iface(node2)
|
||||
session.add_link(node1.id, node2.id, iface1_data, iface2_data)
|
||||
iface1 = node1.get_iface(iface1_data.id)
|
||||
iface2 = node2.get_iface(iface2_data.id)
|
||||
assert iface1.getparam("delay") != delay
|
||||
assert iface1.getparam("bw") != bandwidth
|
||||
assert iface1.getparam("loss") != loss
|
||||
assert iface1.getparam("duplicate") != dup
|
||||
assert iface1.getparam("jitter") != jitter
|
||||
assert iface2.getparam("delay") != delay
|
||||
assert iface2.getparam("bw") != bandwidth
|
||||
assert iface2.getparam("loss") != loss
|
||||
assert iface2.getparam("duplicate") != dup
|
||||
assert iface2.getparam("jitter") != jitter
|
||||
|
||||
# when
|
||||
options = LinkOptions(
|
||||
delay=delay, bandwidth=bandwidth, loss=loss, dup=dup, jitter=jitter
|
||||
)
|
||||
session.update_link(
|
||||
node1.id, node2.id, interface1_data.id, interface2_data.id, options
|
||||
)
|
||||
session.update_link(node1.id, node2.id, iface1_data.id, iface2_data.id, options)
|
||||
|
||||
# then
|
||||
assert interface1.getparam("delay") == delay
|
||||
assert interface1.getparam("bw") == bandwidth
|
||||
assert interface1.getparam("loss") == loss
|
||||
assert interface1.getparam("duplicate") == dup
|
||||
assert interface1.getparam("jitter") == jitter
|
||||
assert interface2.getparam("delay") == delay
|
||||
assert interface2.getparam("bw") == bandwidth
|
||||
assert interface2.getparam("loss") == loss
|
||||
assert interface2.getparam("duplicate") == dup
|
||||
assert interface2.getparam("jitter") == jitter
|
||||
assert iface1.getparam("delay") == delay
|
||||
assert iface1.getparam("bw") == bandwidth
|
||||
assert iface1.getparam("loss") == loss
|
||||
assert iface1.getparam("duplicate") == dup
|
||||
assert iface1.getparam("jitter") == jitter
|
||||
assert iface2.getparam("delay") == delay
|
||||
assert iface2.getparam("bw") == bandwidth
|
||||
assert iface2.getparam("loss") == loss
|
||||
assert iface2.getparam("duplicate") == dup
|
||||
assert iface2.getparam("jitter") == jitter
|
||||
|
||||
def test_delete_ptp(self, session: Session, ip_prefixes: IpPrefixes):
|
||||
# given
|
||||
node1 = session.add_node(CoreNode)
|
||||
node2 = session.add_node(CoreNode)
|
||||
interface1_data = ip_prefixes.create_interface(node1)
|
||||
interface2_data = ip_prefixes.create_interface(node2)
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data)
|
||||
assert node1.netif(interface1_data.id)
|
||||
assert node2.netif(interface2_data.id)
|
||||
iface1_data = ip_prefixes.create_iface(node1)
|
||||
iface2_data = ip_prefixes.create_iface(node2)
|
||||
session.add_link(node1.id, node2.id, iface1_data, iface2_data)
|
||||
assert node1.get_iface(iface1_data.id)
|
||||
assert node2.get_iface(iface2_data.id)
|
||||
|
||||
# when
|
||||
session.delete_link(node1.id, node2.id, interface1_data.id, interface2_data.id)
|
||||
session.delete_link(node1.id, node2.id, iface1_data.id, iface2_data.id)
|
||||
|
||||
# then
|
||||
assert not node1.netif(interface1_data.id)
|
||||
assert not node2.netif(interface2_data.id)
|
||||
assert iface1_data.id not in node1.ifaces
|
||||
assert iface2_data.id not in node2.ifaces
|
||||
|
||||
def test_delete_node_to_net(self, session: Session, ip_prefixes: IpPrefixes):
|
||||
# given
|
||||
node1 = session.add_node(CoreNode)
|
||||
node2 = session.add_node(SwitchNode)
|
||||
interface1_data = ip_prefixes.create_interface(node1)
|
||||
session.add_link(node1.id, node2.id, interface1_data)
|
||||
assert node1.netif(interface1_data.id)
|
||||
iface1_data = ip_prefixes.create_iface(node1)
|
||||
session.add_link(node1.id, node2.id, iface1_data)
|
||||
assert node1.get_iface(iface1_data.id)
|
||||
|
||||
# when
|
||||
session.delete_link(node1.id, node2.id, interface1_id=interface1_data.id)
|
||||
session.delete_link(node1.id, node2.id, iface1_id=iface1_data.id)
|
||||
|
||||
# then
|
||||
assert not node1.netif(interface1_data.id)
|
||||
assert iface1_data.id not in node1.ifaces
|
||||
|
||||
def test_delete_net_to_node(self, session: Session, ip_prefixes: IpPrefixes):
|
||||
# given
|
||||
node1 = session.add_node(SwitchNode)
|
||||
node2 = session.add_node(CoreNode)
|
||||
interface2_data = ip_prefixes.create_interface(node2)
|
||||
session.add_link(node1.id, node2.id, interface2_data=interface2_data)
|
||||
assert node2.netif(interface2_data.id)
|
||||
iface2_data = ip_prefixes.create_iface(node2)
|
||||
session.add_link(node1.id, node2.id, iface2_data=iface2_data)
|
||||
assert node2.get_iface(iface2_data.id)
|
||||
|
||||
# when
|
||||
session.delete_link(node1.id, node2.id, interface2_id=interface2_data.id)
|
||||
session.delete_link(node1.id, node2.id, iface2_id=iface2_data.id)
|
||||
|
||||
# then
|
||||
assert not node2.netif(interface2_data.id)
|
||||
assert iface2_data.id not in node2.ifaces
|
||||
|
|
|
@ -53,53 +53,53 @@ class TestNodes:
|
|||
# given
|
||||
node = session.add_node(CoreNode)
|
||||
switch = session.add_node(SwitchNode)
|
||||
interface_data = InterfaceData()
|
||||
interface = node.newnetif(switch, interface_data)
|
||||
iface_data = InterfaceData()
|
||||
iface = node.new_iface(switch, iface_data)
|
||||
mac = "aa:aa:aa:ff:ff:ff"
|
||||
|
||||
# when
|
||||
node.sethwaddr(interface.netindex, mac)
|
||||
node.sethwaddr(iface.node_id, mac)
|
||||
|
||||
# then
|
||||
assert interface.hwaddr == mac
|
||||
assert iface.hwaddr == mac
|
||||
|
||||
def test_node_sethwaddr_exception(self, session: Session):
|
||||
# given
|
||||
node = session.add_node(CoreNode)
|
||||
switch = session.add_node(SwitchNode)
|
||||
interface_data = InterfaceData()
|
||||
interface = node.newnetif(switch, interface_data)
|
||||
iface_data = InterfaceData()
|
||||
iface = node.new_iface(switch, iface_data)
|
||||
mac = "aa:aa:aa:ff:ff:fff"
|
||||
|
||||
# when
|
||||
with pytest.raises(CoreError):
|
||||
node.sethwaddr(interface.netindex, mac)
|
||||
node.sethwaddr(iface.node_id, mac)
|
||||
|
||||
def test_node_addaddr(self, session: Session):
|
||||
# given
|
||||
node = session.add_node(CoreNode)
|
||||
switch = session.add_node(SwitchNode)
|
||||
interface_data = InterfaceData()
|
||||
interface = node.newnetif(switch, interface_data)
|
||||
iface_data = InterfaceData()
|
||||
iface = node.new_iface(switch, iface_data)
|
||||
addr = "192.168.0.1/24"
|
||||
|
||||
# when
|
||||
node.addaddr(interface.netindex, addr)
|
||||
node.addaddr(iface.node_id, addr)
|
||||
|
||||
# then
|
||||
assert interface.addrlist[0] == addr
|
||||
assert iface.addrlist[0] == addr
|
||||
|
||||
def test_node_addaddr_exception(self, session):
|
||||
# given
|
||||
node = session.add_node(CoreNode)
|
||||
switch = session.add_node(SwitchNode)
|
||||
interface_data = InterfaceData()
|
||||
interface = node.newnetif(switch, interface_data)
|
||||
iface_data = InterfaceData()
|
||||
iface = node.new_iface(switch, iface_data)
|
||||
addr = "256.168.0.1/24"
|
||||
|
||||
# when
|
||||
with pytest.raises(CoreError):
|
||||
node.addaddr(interface.netindex, addr)
|
||||
node.addaddr(iface.node_id, addr)
|
||||
|
||||
@pytest.mark.parametrize("net_type", NET_TYPES)
|
||||
def test_net(self, session, net_type):
|
||||
|
|
|
@ -73,8 +73,8 @@ class TestXml:
|
|||
|
||||
# link nodes to ptp net
|
||||
for node in [node1, node2]:
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, ptp_node.id, interface1_data=interface)
|
||||
iface_data = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, ptp_node.id, iface1_data=iface_data)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -128,8 +128,8 @@ class TestXml:
|
|||
|
||||
# link nodes to ptp net
|
||||
for node in [node1, node2]:
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, ptp_node.id, interface1_data=interface)
|
||||
iface_data = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, ptp_node.id, iface1_data=iface_data)
|
||||
|
||||
# set custom values for node service
|
||||
session.services.set_service(node1.id, SshService.name)
|
||||
|
@ -197,8 +197,8 @@ class TestXml:
|
|||
|
||||
# link nodes
|
||||
for node in [node1, node2]:
|
||||
interface = ip_prefixes.create_interface(node)
|
||||
session.add_link(node.id, wlan_node.id, interface1_data=interface)
|
||||
iface_data = ip_prefixes.create_iface(node)
|
||||
session.add_link(node.id, wlan_node.id, iface1_data=iface_data)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -299,7 +299,7 @@ class TestXml:
|
|||
"""
|
||||
# create nodes
|
||||
node1 = session.add_node(CoreNode)
|
||||
interface1_data = ip_prefixes.create_interface(node1)
|
||||
iface1_data = ip_prefixes.create_iface(node1)
|
||||
switch = session.add_node(SwitchNode)
|
||||
|
||||
# create link
|
||||
|
@ -309,7 +309,7 @@ class TestXml:
|
|||
options.jitter = 10
|
||||
options.delay = 30
|
||||
options.dup = 5
|
||||
session.add_link(node1.id, switch.id, interface1_data, options=options)
|
||||
session.add_link(node1.id, switch.id, iface1_data, options=options)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -365,9 +365,9 @@ class TestXml:
|
|||
"""
|
||||
# create nodes
|
||||
node1 = session.add_node(CoreNode)
|
||||
interface1_data = ip_prefixes.create_interface(node1)
|
||||
iface1_data = ip_prefixes.create_iface(node1)
|
||||
node2 = session.add_node(CoreNode)
|
||||
interface2_data = ip_prefixes.create_interface(node2)
|
||||
iface2_data = ip_prefixes.create_iface(node2)
|
||||
|
||||
# create link
|
||||
options = LinkOptions()
|
||||
|
@ -376,7 +376,7 @@ class TestXml:
|
|||
options.jitter = 10
|
||||
options.delay = 30
|
||||
options.dup = 5
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data, options)
|
||||
session.add_link(node1.id, node2.id, iface1_data, iface2_data, options)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
@ -432,9 +432,9 @@ class TestXml:
|
|||
"""
|
||||
# create nodes
|
||||
node1 = session.add_node(CoreNode)
|
||||
interface1_data = ip_prefixes.create_interface(node1)
|
||||
iface1_data = ip_prefixes.create_iface(node1)
|
||||
node2 = session.add_node(CoreNode)
|
||||
interface2_data = ip_prefixes.create_interface(node2)
|
||||
iface2_data = ip_prefixes.create_iface(node2)
|
||||
|
||||
# create link
|
||||
options1 = LinkOptions()
|
||||
|
@ -444,7 +444,7 @@ class TestXml:
|
|||
options1.loss = 10.5
|
||||
options1.dup = 5
|
||||
options1.jitter = 5
|
||||
session.add_link(node1.id, node2.id, interface1_data, interface2_data, options1)
|
||||
session.add_link(node1.id, node2.id, iface1_data, iface2_data, options1)
|
||||
options2 = LinkOptions()
|
||||
options2.unidirectional = 1
|
||||
options2.bandwidth = 10000
|
||||
|
@ -453,7 +453,7 @@ class TestXml:
|
|||
options2.dup = 10
|
||||
options2.jitter = 10
|
||||
session.update_link(
|
||||
node2.id, node1.id, interface2_data.id, interface1_data.id, options2
|
||||
node2.id, node1.id, iface2_data.id, iface1_data.id, options2
|
||||
)
|
||||
|
||||
# instantiate session
|
||||
|
|
|
@ -61,8 +61,8 @@ def main():
|
|||
# create nodes
|
||||
for _ in range(NODES):
|
||||
node = session.add_node(CoreNode)
|
||||
interface = prefixes.create_interface(node)
|
||||
session.add_link(node.id, switch.id, interface1_data=interface)
|
||||
interface = prefixes.create_iface(node)
|
||||
session.add_link(node.id, switch.id, iface1_data=interface)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
|
Loading…
Reference in a new issue