Merge pull request #336 from coreemu/refactoring/remove-ipaddress
Refactoring/remove ipaddress
This commit is contained in:
commit
67c1dae357
29 changed files with 337 additions and 687 deletions
|
@ -7,9 +7,10 @@ import threading
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
import grpc
|
import grpc
|
||||||
|
import netaddr
|
||||||
|
|
||||||
|
from core import utils
|
||||||
from core.api.grpc import core_pb2, core_pb2_grpc
|
from core.api.grpc import core_pb2, core_pb2_grpc
|
||||||
from core.nodes.ipaddress import Ipv4Prefix, Ipv6Prefix, MacAddress
|
|
||||||
|
|
||||||
|
|
||||||
class InterfaceHelper:
|
class InterfaceHelper:
|
||||||
|
@ -30,10 +31,10 @@ class InterfaceHelper:
|
||||||
|
|
||||||
self.ip4 = None
|
self.ip4 = None
|
||||||
if ip4_prefix:
|
if ip4_prefix:
|
||||||
self.ip4 = Ipv4Prefix(ip4_prefix)
|
self.ip4 = netaddr.IPNetwork(ip4_prefix)
|
||||||
self.ip6 = None
|
self.ip6 = None
|
||||||
if ip6_prefix:
|
if ip6_prefix:
|
||||||
self.ip6 = Ipv6Prefix(ip6_prefix)
|
self.ip6 = netaddr.IPNetwork(ip6_prefix)
|
||||||
|
|
||||||
def ip4_address(self, node_id):
|
def ip4_address(self, node_id):
|
||||||
"""
|
"""
|
||||||
|
@ -45,7 +46,7 @@ class InterfaceHelper:
|
||||||
"""
|
"""
|
||||||
if not self.ip4:
|
if not self.ip4:
|
||||||
raise ValueError("ip4 prefixes have not been set")
|
raise ValueError("ip4 prefixes have not been set")
|
||||||
return str(self.ip4.addr(node_id))
|
return str(self.ip4[node_id])
|
||||||
|
|
||||||
def ip6_address(self, node_id):
|
def ip6_address(self, node_id):
|
||||||
"""
|
"""
|
||||||
|
@ -57,7 +58,7 @@ class InterfaceHelper:
|
||||||
"""
|
"""
|
||||||
if not self.ip6:
|
if not self.ip6:
|
||||||
raise ValueError("ip6 prefixes have not been set")
|
raise ValueError("ip6 prefixes have not been set")
|
||||||
return str(self.ip6.addr(node_id))
|
return str(self.ip6[node_id])
|
||||||
|
|
||||||
def create_interface(self, node_id, interface_id, name=None, mac=None):
|
def create_interface(self, node_id, interface_id, name=None, mac=None):
|
||||||
"""
|
"""
|
||||||
|
@ -75,19 +76,19 @@ class InterfaceHelper:
|
||||||
ip4 = None
|
ip4 = None
|
||||||
ip4_mask = None
|
ip4_mask = None
|
||||||
if self.ip4:
|
if self.ip4:
|
||||||
ip4 = str(self.ip4.addr(node_id))
|
ip4 = self.ip4_address(node_id)
|
||||||
ip4_mask = self.ip4.prefixlen
|
ip4_mask = self.ip4.prefixlen
|
||||||
|
|
||||||
# generate ip6 data
|
# generate ip6 data
|
||||||
ip6 = None
|
ip6 = None
|
||||||
ip6_mask = None
|
ip6_mask = None
|
||||||
if self.ip6:
|
if self.ip6:
|
||||||
ip6 = str(self.ip6.addr(node_id))
|
ip6 = self.ip6_address(node_id)
|
||||||
ip6_mask = self.ip6.prefixlen
|
ip6_mask = self.ip6.prefixlen
|
||||||
|
|
||||||
# random mac
|
# random mac
|
||||||
if not mac:
|
if not mac:
|
||||||
mac = MacAddress.random()
|
mac = utils.random_mac()
|
||||||
|
|
||||||
return core_pb2.Interface(
|
return core_pb2.Interface(
|
||||||
id=interface_id,
|
id=interface_id,
|
||||||
|
|
|
@ -6,7 +6,6 @@ from core.api.grpc import core_pb2
|
||||||
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
|
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
|
||||||
from core.emulator.enumerations import LinkTypes, NodeTypes
|
from core.emulator.enumerations import LinkTypes, NodeTypes
|
||||||
from core.nodes.base import CoreNetworkBase
|
from core.nodes.base import CoreNetworkBase
|
||||||
from core.nodes.ipaddress import MacAddress
|
|
||||||
|
|
||||||
WORKERS = 10
|
WORKERS = 10
|
||||||
|
|
||||||
|
@ -57,8 +56,6 @@ def link_interface(interface_proto):
|
||||||
mac = interface_proto.mac
|
mac = interface_proto.mac
|
||||||
if mac == "":
|
if mac == "":
|
||||||
mac = None
|
mac = None
|
||||||
else:
|
|
||||||
mac = MacAddress.from_string(mac)
|
|
||||||
interface = InterfaceData(
|
interface = InterfaceData(
|
||||||
_id=interface_proto.id,
|
_id=interface_proto.id,
|
||||||
name=name,
|
name=name,
|
||||||
|
|
|
@ -5,10 +5,13 @@ types and objects used for parsing and building CORE API messages.
|
||||||
CORE API messaging is leveraged for communication with the GUI.
|
CORE API messaging is leveraged for communication with the GUI.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import binascii
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
import netaddr
|
||||||
|
|
||||||
from core.api.tlv import structutils
|
from core.api.tlv import structutils
|
||||||
from core.emulator.enumerations import (
|
from core.emulator.enumerations import (
|
||||||
ConfigTlvs,
|
ConfigTlvs,
|
||||||
|
@ -24,7 +27,6 @@ from core.emulator.enumerations import (
|
||||||
RegisterTlvs,
|
RegisterTlvs,
|
||||||
SessionTlvs,
|
SessionTlvs,
|
||||||
)
|
)
|
||||||
from core.nodes.ipaddress import IpAddress, MacAddress
|
|
||||||
|
|
||||||
|
|
||||||
class CoreTlvData:
|
class CoreTlvData:
|
||||||
|
@ -258,7 +260,7 @@ class CoreTlvDataIpv4Addr(CoreTlvDataObj):
|
||||||
Utility class for packing/unpacking Ipv4 addresses.
|
Utility class for packing/unpacking Ipv4 addresses.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
data_type = IpAddress.from_string
|
data_type = str
|
||||||
data_format = "!2x4s"
|
data_format = "!2x4s"
|
||||||
pad_len = 2
|
pad_len = 2
|
||||||
|
|
||||||
|
@ -267,21 +269,22 @@ class CoreTlvDataIpv4Addr(CoreTlvDataObj):
|
||||||
"""
|
"""
|
||||||
Retrieve Ipv4 address value from object.
|
Retrieve Ipv4 address value from object.
|
||||||
|
|
||||||
:param core.misc.ipaddress.IpAddress obj: ip address to get value from
|
:param str obj: ip address to get value from
|
||||||
:return:
|
:return: packed address
|
||||||
|
:rtype: bytes
|
||||||
"""
|
"""
|
||||||
return obj.addr
|
return socket.inet_pton(socket.AF_INET, obj)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def new_obj(value):
|
def new_obj(value):
|
||||||
"""
|
"""
|
||||||
Retrieve Ipv4 address from a string representation.
|
Retrieve Ipv4 address from a string representation.
|
||||||
|
|
||||||
:param str value: value to get Ipv4 address from
|
:param bytes value: value to get Ipv4 address from
|
||||||
:return: Ipv4 address
|
:return: Ipv4 address
|
||||||
:rtype: core.nodes.ipaddress.IpAddress
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
return IpAddress(af=socket.AF_INET, address=value)
|
return socket.inet_ntop(socket.AF_INET, value)
|
||||||
|
|
||||||
|
|
||||||
class CoreTlvDataIPv6Addr(CoreTlvDataObj):
|
class CoreTlvDataIPv6Addr(CoreTlvDataObj):
|
||||||
|
@ -290,7 +293,7 @@ class CoreTlvDataIPv6Addr(CoreTlvDataObj):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
data_format = "!16s2x"
|
data_format = "!16s2x"
|
||||||
data_type = IpAddress.from_string
|
data_type = str
|
||||||
pad_len = 2
|
pad_len = 2
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -298,21 +301,22 @@ class CoreTlvDataIPv6Addr(CoreTlvDataObj):
|
||||||
"""
|
"""
|
||||||
Retrieve Ipv6 address value from object.
|
Retrieve Ipv6 address value from object.
|
||||||
|
|
||||||
:param core.nodes.ipaddress.IpAddress obj: ip address to get value from
|
:param str obj: ip address to get value from
|
||||||
:return:
|
:return: packed address
|
||||||
|
:rtype: bytes
|
||||||
"""
|
"""
|
||||||
return obj.addr
|
return socket.inet_pton(socket.AF_INET6, obj)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def new_obj(value):
|
def new_obj(value):
|
||||||
"""
|
"""
|
||||||
Retrieve Ipv6 address from a string representation.
|
Retrieve Ipv6 address from a string representation.
|
||||||
|
|
||||||
:param str value: value to get Ipv4 address from
|
:param bytes value: value to get Ipv4 address from
|
||||||
:return: Ipv4 address
|
:return: Ipv4 address
|
||||||
:rtype: core.nodes.ipaddress.IpAddress
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
return IpAddress(af=socket.AF_INET6, address=value)
|
return socket.inet_ntop(socket.AF_INET6, value)
|
||||||
|
|
||||||
|
|
||||||
class CoreTlvDataMacAddr(CoreTlvDataObj):
|
class CoreTlvDataMacAddr(CoreTlvDataObj):
|
||||||
|
@ -321,7 +325,7 @@ class CoreTlvDataMacAddr(CoreTlvDataObj):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
data_format = "!2x8s"
|
data_format = "!2x8s"
|
||||||
data_type = MacAddress.from_string
|
data_type = str
|
||||||
pad_len = 2
|
pad_len = 2
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -329,23 +333,27 @@ class CoreTlvDataMacAddr(CoreTlvDataObj):
|
||||||
"""
|
"""
|
||||||
Retrieve Ipv6 address value from object.
|
Retrieve Ipv6 address value from object.
|
||||||
|
|
||||||
:param core.nodes.ipaddress.MacAddress obj: mac address to get value from
|
:param str obj: mac address to get value from
|
||||||
:return:
|
:return: packed mac address
|
||||||
|
:rtype: bytes
|
||||||
"""
|
"""
|
||||||
# extend to 64 bits
|
# extend to 64 bits
|
||||||
return b"\0\0" + obj.addr
|
return b"\0\0" + netaddr.EUI(obj).packed
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def new_obj(value):
|
def new_obj(value):
|
||||||
"""
|
"""
|
||||||
Retrieve mac address from a string representation.
|
Retrieve mac address from a string representation.
|
||||||
|
|
||||||
:param str value: value to get Ipv4 address from
|
:param bytes value: value to get Ipv4 address from
|
||||||
:return: Ipv4 address
|
:return: mac address
|
||||||
:rtype: core.nodes.ipaddress.MacAddress
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
# only use 48 bits
|
# only use 48 bits
|
||||||
return MacAddress(address=value[2:])
|
value = binascii.hexlify(value[2:]).decode()
|
||||||
|
mac = netaddr.EUI(value)
|
||||||
|
mac.dialect = netaddr.mac_unix
|
||||||
|
return str(mac)
|
||||||
|
|
||||||
|
|
||||||
class CoreTlv:
|
class CoreTlv:
|
||||||
|
|
|
@ -8,13 +8,13 @@ import threading
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
|
import netaddr
|
||||||
from fabric import Connection
|
from fabric import Connection
|
||||||
from invoke import UnexpectedExit
|
from invoke import UnexpectedExit
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.errors import CoreCommandError
|
from core.errors import CoreCommandError
|
||||||
from core.nodes.interface import GreTap
|
from core.nodes.interface import GreTap
|
||||||
from core.nodes.ipaddress import IpAddress
|
|
||||||
from core.nodes.network import CoreNetwork, CtrlNet
|
from core.nodes.network import CoreNetwork, CtrlNet
|
||||||
|
|
||||||
LOCK = threading.Lock()
|
LOCK = threading.Lock()
|
||||||
|
@ -196,7 +196,7 @@ class DistributedController:
|
||||||
:rtype: tuple
|
:rtype: tuple
|
||||||
"""
|
"""
|
||||||
host = server.host
|
host = server.host
|
||||||
key = self.tunnel_key(node.id, IpAddress.to_int(host))
|
key = self.tunnel_key(node.id, netaddr.IPAddress(host).value)
|
||||||
tunnel = self.tunnels.get(key)
|
tunnel = self.tunnels.get(key)
|
||||||
if tunnel is not None:
|
if tunnel is not None:
|
||||||
return tunnel
|
return tunnel
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import netaddr
|
||||||
|
|
||||||
|
from core import utils
|
||||||
from core.emane.nodes import EmaneNet
|
from core.emane.nodes import EmaneNet
|
||||||
from core.emulator.enumerations import LinkTypes
|
from core.emulator.enumerations import LinkTypes
|
||||||
from core.nodes.ipaddress import Ipv4Prefix, Ipv6Prefix, MacAddress
|
|
||||||
from core.nodes.physical import PhysicalNode
|
from core.nodes.physical import PhysicalNode
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,10 +166,10 @@ class IpPrefixes:
|
||||||
|
|
||||||
self.ip4 = None
|
self.ip4 = None
|
||||||
if ip4_prefix:
|
if ip4_prefix:
|
||||||
self.ip4 = Ipv4Prefix(ip4_prefix)
|
self.ip4 = netaddr.IPNetwork(ip4_prefix)
|
||||||
self.ip6 = None
|
self.ip6 = None
|
||||||
if ip6_prefix:
|
if ip6_prefix:
|
||||||
self.ip6 = Ipv6Prefix(ip6_prefix)
|
self.ip6 = netaddr.IPNetwork(ip6_prefix)
|
||||||
|
|
||||||
def ip4_address(self, node):
|
def ip4_address(self, node):
|
||||||
"""
|
"""
|
||||||
|
@ -179,7 +181,7 @@ class IpPrefixes:
|
||||||
"""
|
"""
|
||||||
if not self.ip4:
|
if not self.ip4:
|
||||||
raise ValueError("ip4 prefixes have not been set")
|
raise ValueError("ip4 prefixes have not been set")
|
||||||
return str(self.ip4.addr(node.id))
|
return str(self.ip4[node.id])
|
||||||
|
|
||||||
def ip6_address(self, node):
|
def ip6_address(self, node):
|
||||||
"""
|
"""
|
||||||
|
@ -191,7 +193,7 @@ class IpPrefixes:
|
||||||
"""
|
"""
|
||||||
if not self.ip6:
|
if not self.ip6:
|
||||||
raise ValueError("ip6 prefixes have not been set")
|
raise ValueError("ip6 prefixes have not been set")
|
||||||
return str(self.ip6.addr(node.id))
|
return str(self.ip6[node.id])
|
||||||
|
|
||||||
def create_interface(self, node, name=None, mac=None):
|
def create_interface(self, node, name=None, mac=None):
|
||||||
"""
|
"""
|
||||||
|
@ -212,19 +214,19 @@ class IpPrefixes:
|
||||||
ip4 = None
|
ip4 = None
|
||||||
ip4_mask = None
|
ip4_mask = None
|
||||||
if self.ip4:
|
if self.ip4:
|
||||||
ip4 = str(self.ip4.addr(node.id))
|
ip4 = self.ip4_address(node)
|
||||||
ip4_mask = self.ip4.prefixlen
|
ip4_mask = self.ip4.prefixlen
|
||||||
|
|
||||||
# generate ip6 data
|
# generate ip6 data
|
||||||
ip6 = None
|
ip6 = None
|
||||||
ip6_mask = None
|
ip6_mask = None
|
||||||
if self.ip6:
|
if self.ip6:
|
||||||
ip6 = str(self.ip6.addr(node.id))
|
ip6 = self.ip6_address(node)
|
||||||
ip6_mask = self.ip6.prefixlen
|
ip6_mask = self.ip6.prefixlen
|
||||||
|
|
||||||
# random mac
|
# random mac
|
||||||
if not mac:
|
if not mac:
|
||||||
mac = MacAddress.random()
|
mac = utils.random_mac()
|
||||||
|
|
||||||
return InterfaceData(
|
return InterfaceData(
|
||||||
_id=inteface_id,
|
_id=inteface_id,
|
||||||
|
@ -248,7 +250,7 @@ class InterfaceData:
|
||||||
|
|
||||||
:param int _id: interface id
|
:param int _id: interface id
|
||||||
:param str name: name for interface
|
:param str name: name for interface
|
||||||
:param core.nodes.ipaddress.MacAddress mac: mac address
|
:param str mac: mac address
|
||||||
:param str ip4: ipv4 address
|
:param str ip4: ipv4 address
|
||||||
:param int ip4_mask: ipv4 bit mask
|
:param int ip4_mask: ipv4 bit mask
|
||||||
:param str ip6: ipv6 address
|
:param str ip6: ipv6 address
|
||||||
|
|
|
@ -33,7 +33,6 @@ from core.location.event import EventLoop
|
||||||
from core.location.mobility import BasicRangeModel, MobilityManager
|
from core.location.mobility import BasicRangeModel, MobilityManager
|
||||||
from core.nodes.base import CoreNetworkBase, CoreNode, CoreNodeBase
|
from core.nodes.base import CoreNetworkBase, CoreNode, CoreNodeBase
|
||||||
from core.nodes.docker import DockerNode
|
from core.nodes.docker import DockerNode
|
||||||
from core.nodes.ipaddress import MacAddress
|
|
||||||
from core.nodes.lxd import LxcNode
|
from core.nodes.lxd import LxcNode
|
||||||
from core.nodes.network import (
|
from core.nodes.network import (
|
||||||
CtrlNet,
|
CtrlNet,
|
||||||
|
@ -1764,7 +1763,7 @@ class Session:
|
||||||
control_ip = node.id
|
control_ip = node.id
|
||||||
|
|
||||||
try:
|
try:
|
||||||
address = control_net.prefix.addr(control_ip)
|
address = control_net.prefix[control_ip]
|
||||||
prefix = control_net.prefix.prefixlen
|
prefix = control_net.prefix.prefixlen
|
||||||
addrlist = [f"{address}/{prefix}"]
|
addrlist = [f"{address}/{prefix}"]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -1778,7 +1777,7 @@ class Session:
|
||||||
net=control_net,
|
net=control_net,
|
||||||
ifindex=control_net.CTRLIF_IDX_BASE + net_index,
|
ifindex=control_net.CTRLIF_IDX_BASE + net_index,
|
||||||
ifname=f"ctrl{net_index}",
|
ifname=f"ctrl{net_index}",
|
||||||
hwaddr=MacAddress.random(),
|
hwaddr=utils.random_mac(),
|
||||||
addrlist=addrlist,
|
addrlist=addrlist,
|
||||||
)
|
)
|
||||||
node.netif(interface1).control = True
|
node.netif(interface1).control = True
|
||||||
|
|
|
@ -5,16 +5,16 @@ Defines the base logic for nodes used within core.
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import socket
|
|
||||||
import threading
|
import threading
|
||||||
from socket import AF_INET, AF_INET6
|
|
||||||
|
import netaddr
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.constants import MOUNT_BIN, VNODED_BIN
|
from core.constants import MOUNT_BIN, VNODED_BIN
|
||||||
from core.emulator.data import LinkData, NodeData
|
from core.emulator.data import LinkData, NodeData
|
||||||
from core.emulator.enumerations import LinkTypes, NodeTypes
|
from core.emulator.enumerations import LinkTypes, NodeTypes
|
||||||
from core.errors import CoreCommandError
|
from core.errors import CoreCommandError
|
||||||
from core.nodes import client, ipaddress
|
from core.nodes import client
|
||||||
from core.nodes.interface import TunTap, Veth
|
from core.nodes.interface import TunTap, Veth
|
||||||
from core.nodes.netclient import get_net_client
|
from core.nodes.netclient import get_net_client
|
||||||
|
|
||||||
|
@ -725,39 +725,40 @@ class CoreNode(CoreNodeBase):
|
||||||
Set hardware addres for an interface.
|
Set hardware addres for an interface.
|
||||||
|
|
||||||
:param int ifindex: index of interface to set hardware address for
|
:param int ifindex: index of interface to set hardware address for
|
||||||
:param core.nodes.ipaddress.MacAddress addr: hardware address to set
|
:param str addr: hardware address to set
|
||||||
:return: nothing
|
:return: nothing
|
||||||
:raises CoreCommandError: when a non-zero exit status occurs
|
:raises CoreCommandError: when a non-zero exit status occurs
|
||||||
"""
|
"""
|
||||||
|
addr = utils.validate_mac(addr)
|
||||||
interface = self._netif[ifindex]
|
interface = self._netif[ifindex]
|
||||||
interface.sethwaddr(addr)
|
interface.sethwaddr(addr)
|
||||||
if self.up:
|
if self.up:
|
||||||
self.node_net_client.device_mac(interface.name, str(addr))
|
self.node_net_client.device_mac(interface.name, addr)
|
||||||
|
|
||||||
def addaddr(self, ifindex, addr):
|
def addaddr(self, ifindex, addr):
|
||||||
"""
|
"""
|
||||||
Add interface address.
|
Add interface address.
|
||||||
|
|
||||||
:param int ifindex: index of interface to add address to
|
:param int ifindex: index of interface to add address to
|
||||||
:param core.nodes.ipaddress.IpAddress addr: address to add to interface
|
:param str addr: address to add to interface
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
|
addr = utils.validate_ip(addr)
|
||||||
interface = self._netif[ifindex]
|
interface = self._netif[ifindex]
|
||||||
interface.addaddr(addr)
|
interface.addaddr(addr)
|
||||||
if self.up:
|
if self.up:
|
||||||
address = str(addr)
|
# ipv4 check
|
||||||
# ipv6 check
|
|
||||||
broadcast = None
|
broadcast = None
|
||||||
if ":" not in address:
|
if netaddr.valid_ipv4(addr):
|
||||||
broadcast = "+"
|
broadcast = "+"
|
||||||
self.node_net_client.create_address(interface.name, address, broadcast)
|
self.node_net_client.create_address(interface.name, addr, broadcast)
|
||||||
|
|
||||||
def deladdr(self, ifindex, addr):
|
def deladdr(self, ifindex, addr):
|
||||||
"""
|
"""
|
||||||
Delete address from an interface.
|
Delete address from an interface.
|
||||||
|
|
||||||
:param int ifindex: index of interface to delete address from
|
:param int ifindex: index of interface to delete address from
|
||||||
:param core.nodes.ipaddress.IpAddress addr: address to delete from interface
|
:param str addr: address to delete from interface
|
||||||
:return: nothing
|
:return: nothing
|
||||||
:raises CoreCommandError: when a non-zero exit status occurs
|
:raises CoreCommandError: when a non-zero exit status occurs
|
||||||
"""
|
"""
|
||||||
|
@ -769,7 +770,7 @@ class CoreNode(CoreNodeBase):
|
||||||
logging.exception("trying to delete unknown address: %s", addr)
|
logging.exception("trying to delete unknown address: %s", addr)
|
||||||
|
|
||||||
if self.up:
|
if self.up:
|
||||||
self.node_net_client.delete_address(interface.name, str(addr))
|
self.node_net_client.delete_address(interface.name, addr)
|
||||||
|
|
||||||
def ifup(self, ifindex):
|
def ifup(self, ifindex):
|
||||||
"""
|
"""
|
||||||
|
@ -788,7 +789,7 @@ class CoreNode(CoreNodeBase):
|
||||||
|
|
||||||
:param core.nodes.base.CoreNetworkBase net: network to associate with
|
:param core.nodes.base.CoreNetworkBase net: network to associate with
|
||||||
:param list addrlist: addresses to add on the interface
|
:param list addrlist: addresses to add on the interface
|
||||||
:param core.nodes.ipaddress.MacAddress hwaddr: hardware address to set for interface
|
:param str hwaddr: hardware address to set for interface
|
||||||
:param int ifindex: index of interface to create
|
:param int ifindex: index of interface to create
|
||||||
:param str ifname: name for interface
|
:param str ifname: name for interface
|
||||||
:return: interface index
|
:return: interface index
|
||||||
|
@ -799,7 +800,7 @@ class CoreNode(CoreNodeBase):
|
||||||
|
|
||||||
with self.lock:
|
with self.lock:
|
||||||
# TODO: emane specific code
|
# TODO: emane specific code
|
||||||
if net.is_emane is True:
|
if net is not None and net.is_emane is True:
|
||||||
ifindex = self.newtuntap(ifindex, ifname)
|
ifindex = self.newtuntap(ifindex, ifname)
|
||||||
# TUN/TAP is not ready for addressing yet; the device may
|
# TUN/TAP is not ready for addressing yet; the device may
|
||||||
# take some time to appear, and installing it into a
|
# take some time to appear, and installing it into a
|
||||||
|
@ -1015,15 +1016,11 @@ class CoreNetworkBase(NodeBase):
|
||||||
for address in netif.addrlist:
|
for address in netif.addrlist:
|
||||||
ip, _sep, mask = address.partition("/")
|
ip, _sep, mask = address.partition("/")
|
||||||
mask = int(mask)
|
mask = int(mask)
|
||||||
if ipaddress.is_ipv4_address(ip):
|
if netaddr.valid_ipv4(ip):
|
||||||
family = AF_INET
|
interface2_ip4 = ip
|
||||||
ipl = socket.inet_pton(family, ip)
|
|
||||||
interface2_ip4 = ipaddress.IpAddress(af=family, address=ipl)
|
|
||||||
interface2_ip4_mask = mask
|
interface2_ip4_mask = mask
|
||||||
else:
|
else:
|
||||||
family = AF_INET6
|
interface2_ip6 = ip
|
||||||
ipl = socket.inet_pton(family, ip)
|
|
||||||
interface2_ip6 = ipaddress.IpAddress(af=family, address=ipl)
|
|
||||||
interface2_ip6_mask = mask
|
interface2_ip6_mask = mask
|
||||||
|
|
||||||
link_data = LinkData(
|
link_data = LinkData(
|
||||||
|
|
|
@ -114,7 +114,7 @@ class CoreInterface:
|
||||||
:param str addr: address to add
|
:param str addr: address to add
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
|
addr = utils.validate_ip(addr)
|
||||||
self.addrlist.append(addr)
|
self.addrlist.append(addr)
|
||||||
|
|
||||||
def deladdr(self, addr):
|
def deladdr(self, addr):
|
||||||
|
@ -130,9 +130,10 @@ class CoreInterface:
|
||||||
"""
|
"""
|
||||||
Set hardware address.
|
Set hardware address.
|
||||||
|
|
||||||
:param core.nodes.ipaddress.MacAddress addr: hardware address to set to.
|
:param str addr: hardware address to set to.
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
|
addr = utils.validate_mac(addr)
|
||||||
self.hwaddr = addr
|
self.hwaddr = addr
|
||||||
|
|
||||||
def getparam(self, key):
|
def getparam(self, key):
|
||||||
|
|
|
@ -1,456 +0,0 @@
|
||||||
"""
|
|
||||||
Helper objects for dealing with IPv4/v6 addresses.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import random
|
|
||||||
import socket
|
|
||||||
import struct
|
|
||||||
from socket import AF_INET, AF_INET6
|
|
||||||
|
|
||||||
|
|
||||||
class MacAddress:
|
|
||||||
"""
|
|
||||||
Provides mac address utilities for use within core.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, address):
|
|
||||||
"""
|
|
||||||
Creates a MacAddress instance.
|
|
||||||
|
|
||||||
:param bytes address: mac address
|
|
||||||
"""
|
|
||||||
self.addr = address
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
"""
|
|
||||||
Create a string representation of a MacAddress.
|
|
||||||
|
|
||||||
:return: string representation
|
|
||||||
:rtype: str
|
|
||||||
"""
|
|
||||||
return ":".join(f"{x:02x}" for x in bytearray(self.addr))
|
|
||||||
|
|
||||||
def to_link_local(self):
|
|
||||||
"""
|
|
||||||
Convert the MAC address to a IPv6 link-local address, using EUI 48
|
|
||||||
to EUI 64 conversion process per RFC 5342.
|
|
||||||
|
|
||||||
:return: ip address object
|
|
||||||
:rtype: IpAddress
|
|
||||||
"""
|
|
||||||
if not self.addr:
|
|
||||||
return IpAddress.from_string("::")
|
|
||||||
tmp = struct.unpack("!Q", b"\x00\x00" + self.addr)[0]
|
|
||||||
nic = int(tmp) & 0x000000FFFFFF
|
|
||||||
oui = int(tmp) & 0xFFFFFF000000
|
|
||||||
# toggle U/L bit
|
|
||||||
oui ^= 0x020000000000
|
|
||||||
# append EUI-48 octets
|
|
||||||
oui = (oui << 16) | 0xFFFE000000
|
|
||||||
return IpAddress(AF_INET6, struct.pack("!QQ", 0xFE80 << 48, oui | nic))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_string(cls, s):
|
|
||||||
"""
|
|
||||||
Create a mac address object from a string.
|
|
||||||
|
|
||||||
:param s: string representation of a mac address
|
|
||||||
:return: mac address class
|
|
||||||
:rtype: MacAddress
|
|
||||||
"""
|
|
||||||
addr = b"".join(bytes([int(x, 16)]) for x in s.split(":"))
|
|
||||||
return cls(addr)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def random(cls):
|
|
||||||
"""
|
|
||||||
Create a random mac address.
|
|
||||||
|
|
||||||
:return: random mac address
|
|
||||||
:rtype: MacAddress
|
|
||||||
"""
|
|
||||||
tmp = random.randint(0, 0xFFFFFF)
|
|
||||||
# use the Xen OID 00:16:3E
|
|
||||||
tmp |= 0x00163E << 24
|
|
||||||
tmpbytes = struct.pack("!Q", tmp)
|
|
||||||
return cls(tmpbytes[2:])
|
|
||||||
|
|
||||||
|
|
||||||
class IpAddress:
|
|
||||||
"""
|
|
||||||
Provides ip utilities and functionality for use within core.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, af, address):
|
|
||||||
"""
|
|
||||||
Create a IpAddress instance.
|
|
||||||
|
|
||||||
:param int af: address family
|
|
||||||
:param bytes address: ip address
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
# check if (af, addr) is valid
|
|
||||||
if not socket.inet_ntop(af, address):
|
|
||||||
raise ValueError("invalid af/addr")
|
|
||||||
self.af = af
|
|
||||||
self.addr = address
|
|
||||||
|
|
||||||
def is_ipv4(self):
|
|
||||||
"""
|
|
||||||
Checks if this is an ipv4 address.
|
|
||||||
|
|
||||||
:return: True if ipv4 address, False otherwise
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return self.af == AF_INET
|
|
||||||
|
|
||||||
def is_ipv6(self):
|
|
||||||
"""
|
|
||||||
Checks if this is an ipv6 address.
|
|
||||||
|
|
||||||
:return: True if ipv6 address, False otherwise
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return self.af == AF_INET6
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
"""
|
|
||||||
Create a string representation of this address.
|
|
||||||
|
|
||||||
:return: string representation of address
|
|
||||||
:rtype: str
|
|
||||||
"""
|
|
||||||
return socket.inet_ntop(self.af, self.addr)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
"""
|
|
||||||
Checks for equality with another ip address.
|
|
||||||
|
|
||||||
:param IpAddress other: other ip address to check equality with
|
|
||||||
:return: True is the other IpAddress is equal, False otherwise
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
if not isinstance(other, IpAddress):
|
|
||||||
return False
|
|
||||||
elif self is other:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return other.af == self.af and other.addr == self.addr
|
|
||||||
|
|
||||||
def __add__(self, other):
|
|
||||||
"""
|
|
||||||
Add value to ip addresses.
|
|
||||||
|
|
||||||
:param int other: value to add to ip address
|
|
||||||
:return: added together ip address instance
|
|
||||||
:rtype: IpAddress
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
carry = int(other)
|
|
||||||
except ValueError:
|
|
||||||
logging.exception("error during addition")
|
|
||||||
return NotImplemented
|
|
||||||
|
|
||||||
tmp = [x for x in bytearray(self.addr)]
|
|
||||||
for i in range(len(tmp) - 1, -1, -1):
|
|
||||||
x = tmp[i] + carry
|
|
||||||
tmp[i] = x & 0xFF
|
|
||||||
carry = x >> 8
|
|
||||||
if carry == 0:
|
|
||||||
break
|
|
||||||
addr = bytes(tmp)
|
|
||||||
return self.__class__(self.af, addr)
|
|
||||||
|
|
||||||
def __sub__(self, other):
|
|
||||||
"""
|
|
||||||
Subtract value from ip address.
|
|
||||||
|
|
||||||
:param int other: value to subtract from ip address
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
tmp = -int(other)
|
|
||||||
except ValueError:
|
|
||||||
logging.exception("error during subtraction")
|
|
||||||
return NotImplemented
|
|
||||||
|
|
||||||
return self.__add__(tmp)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_string(cls, s):
|
|
||||||
"""
|
|
||||||
Create a ip address from a string representation.
|
|
||||||
|
|
||||||
:param s: string representation to create ip address from
|
|
||||||
:return: ip address instance
|
|
||||||
:rtype: IpAddress
|
|
||||||
"""
|
|
||||||
for af in AF_INET, AF_INET6:
|
|
||||||
return cls(af, socket.inet_pton(af, s))
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def to_int(s):
|
|
||||||
"""
|
|
||||||
Convert IPv4 string to integer
|
|
||||||
|
|
||||||
:param s: string to convert to 32-bit integer
|
|
||||||
:return: integer value
|
|
||||||
:rtype: int
|
|
||||||
"""
|
|
||||||
value = socket.inet_pton(AF_INET, s)
|
|
||||||
return struct.unpack("!I", value)[0]
|
|
||||||
|
|
||||||
|
|
||||||
class IpPrefix:
|
|
||||||
"""
|
|
||||||
Provides ip address generation and prefix utilities.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, af, prefixstr):
|
|
||||||
"""
|
|
||||||
Create a IpPrefix instance.
|
|
||||||
|
|
||||||
:param int af: address family for ip prefix
|
|
||||||
:param str prefixstr: ip prefix string
|
|
||||||
"""
|
|
||||||
# prefixstr format: address/prefixlen
|
|
||||||
tmp = prefixstr.split("/")
|
|
||||||
if len(tmp) > 2:
|
|
||||||
raise ValueError(f"invalid prefix: {prefixstr}")
|
|
||||||
self.af = af
|
|
||||||
if self.af == AF_INET:
|
|
||||||
self.addrlen = 32
|
|
||||||
elif self.af == AF_INET6:
|
|
||||||
self.addrlen = 128
|
|
||||||
else:
|
|
||||||
raise ValueError(f"invalid address family: {self.af}")
|
|
||||||
if len(tmp) == 2:
|
|
||||||
self.prefixlen = int(tmp[1])
|
|
||||||
else:
|
|
||||||
self.prefixlen = self.addrlen
|
|
||||||
self.prefix = socket.inet_pton(self.af, tmp[0])
|
|
||||||
self.prefix = bytes(self.prefix)
|
|
||||||
if self.addrlen > self.prefixlen:
|
|
||||||
addrbits = self.addrlen - self.prefixlen
|
|
||||||
netmask = ((1 << self.prefixlen) - 1) << addrbits
|
|
||||||
prefix = bytes(b"")
|
|
||||||
for i in range(-1, -(addrbits >> 3) - 2, -1):
|
|
||||||
prefix = bytes([self.prefix[i] & (netmask & 0xFF)]) + prefix
|
|
||||||
netmask >>= 8
|
|
||||||
self.prefix = self.prefix[:i] + prefix
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
"""
|
|
||||||
String representation of an ip prefix.
|
|
||||||
|
|
||||||
:return: string representation
|
|
||||||
:rtype: str
|
|
||||||
"""
|
|
||||||
address = socket.inet_ntop(self.af, self.prefix)
|
|
||||||
return f"{address}/{self.prefixlen}"
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
"""
|
|
||||||
Compare equality with another ip prefix.
|
|
||||||
|
|
||||||
:param IpPrefix other: other ip prefix to compare with
|
|
||||||
:return: True is equal, False otherwise
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
if not isinstance(other, IpPrefix):
|
|
||||||
return False
|
|
||||||
elif self is other:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return (
|
|
||||||
other.af == self.af
|
|
||||||
and other.prefixlen == self.prefixlen
|
|
||||||
and other.prefix == self.prefix
|
|
||||||
)
|
|
||||||
|
|
||||||
def __add__(self, other):
|
|
||||||
"""
|
|
||||||
Add a value to this ip prefix.
|
|
||||||
|
|
||||||
:param int other: value to add
|
|
||||||
:return: added ip prefix instance
|
|
||||||
:rtype: IpPrefix
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
tmp = int(other)
|
|
||||||
except ValueError:
|
|
||||||
logging.exception("error during addition")
|
|
||||||
return NotImplemented
|
|
||||||
|
|
||||||
a = IpAddress(self.af, self.prefix) + (tmp << (self.addrlen - self.prefixlen))
|
|
||||||
prefixstr = f"{a}/{self.prefixlen}"
|
|
||||||
if self.__class__ == IpPrefix:
|
|
||||||
return self.__class__(self.af, prefixstr)
|
|
||||||
else:
|
|
||||||
return self.__class__(prefixstr)
|
|
||||||
|
|
||||||
def __sub__(self, other):
|
|
||||||
"""
|
|
||||||
Subtract value from this ip prefix.
|
|
||||||
|
|
||||||
:param int other: value to subtract
|
|
||||||
:return: subtracted ip prefix instance
|
|
||||||
:rtype: IpPrefix
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
tmp = -int(other)
|
|
||||||
except ValueError:
|
|
||||||
logging.exception("error during subtraction")
|
|
||||||
return NotImplemented
|
|
||||||
|
|
||||||
return self.__add__(tmp)
|
|
||||||
|
|
||||||
def addr(self, hostid):
|
|
||||||
"""
|
|
||||||
Create an ip address for a given host id.
|
|
||||||
|
|
||||||
:param hostid: host id for an ip address
|
|
||||||
:return: ip address
|
|
||||||
:rtype: IpAddress
|
|
||||||
"""
|
|
||||||
tmp = int(hostid)
|
|
||||||
if tmp in [-1, 0, 1] and self.addrlen == self.prefixlen:
|
|
||||||
return IpAddress(self.af, self.prefix)
|
|
||||||
|
|
||||||
if (
|
|
||||||
tmp == 0
|
|
||||||
or tmp > (1 << (self.addrlen - self.prefixlen)) - 1
|
|
||||||
or (
|
|
||||||
self.af == AF_INET and tmp == (1 << (self.addrlen - self.prefixlen)) - 1
|
|
||||||
)
|
|
||||||
):
|
|
||||||
raise ValueError(f"invalid hostid for prefix {self}: {hostid}")
|
|
||||||
|
|
||||||
addr = bytes(b"")
|
|
||||||
prefix_endpoint = -1
|
|
||||||
for i in range(-1, -(self.addrlen >> 3) - 1, -1):
|
|
||||||
prefix_endpoint = i
|
|
||||||
addr = bytes([self.prefix[i] | (tmp & 0xFF)]) + addr
|
|
||||||
tmp >>= 8
|
|
||||||
if not tmp:
|
|
||||||
break
|
|
||||||
addr = self.prefix[:prefix_endpoint] + addr
|
|
||||||
return IpAddress(self.af, addr)
|
|
||||||
|
|
||||||
def min_addr(self):
|
|
||||||
"""
|
|
||||||
Return the minimum ip address for this prefix.
|
|
||||||
|
|
||||||
:return: minimum ip address
|
|
||||||
:rtype: IpAddress
|
|
||||||
"""
|
|
||||||
return self.addr(1)
|
|
||||||
|
|
||||||
def max_addr(self):
|
|
||||||
"""
|
|
||||||
Return the maximum ip address for this prefix.
|
|
||||||
|
|
||||||
:return: maximum ip address
|
|
||||||
:rtype: IpAddress
|
|
||||||
"""
|
|
||||||
if self.af == AF_INET:
|
|
||||||
return self.addr((1 << (self.addrlen - self.prefixlen)) - 2)
|
|
||||||
else:
|
|
||||||
return self.addr((1 << (self.addrlen - self.prefixlen)) - 1)
|
|
||||||
|
|
||||||
def num_addr(self):
|
|
||||||
"""
|
|
||||||
Retrieve the number of ip addresses for this prefix.
|
|
||||||
|
|
||||||
:return: maximum number of ip addresses
|
|
||||||
:rtype: int
|
|
||||||
"""
|
|
||||||
return max(0, (1 << (self.addrlen - self.prefixlen)) - 2)
|
|
||||||
|
|
||||||
def prefix_str(self):
|
|
||||||
"""
|
|
||||||
Retrieve the prefix string for this ip address.
|
|
||||||
|
|
||||||
:return: prefix string
|
|
||||||
:rtype: str
|
|
||||||
"""
|
|
||||||
return socket.inet_ntop(self.af, self.prefix)
|
|
||||||
|
|
||||||
def netmask_str(self):
|
|
||||||
"""
|
|
||||||
Retrieve the netmask string for this ip address.
|
|
||||||
|
|
||||||
:return: netmask string
|
|
||||||
:rtype: str
|
|
||||||
"""
|
|
||||||
addrbits = self.addrlen - self.prefixlen
|
|
||||||
netmask = ((1 << self.prefixlen) - 1) << addrbits
|
|
||||||
netmaskbytes = struct.pack("!L", netmask)
|
|
||||||
return IpAddress(af=AF_INET, address=netmaskbytes).__str__()
|
|
||||||
|
|
||||||
|
|
||||||
class Ipv4Prefix(IpPrefix):
|
|
||||||
"""
|
|
||||||
Provides an ipv4 specific class for ip prefixes.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, prefixstr):
|
|
||||||
"""
|
|
||||||
Create a Ipv4Prefix instance.
|
|
||||||
|
|
||||||
:param str prefixstr: ip prefix
|
|
||||||
"""
|
|
||||||
super().__init__(AF_INET, prefixstr)
|
|
||||||
|
|
||||||
|
|
||||||
class Ipv6Prefix(IpPrefix):
|
|
||||||
"""
|
|
||||||
Provides an ipv6 specific class for ip prefixes.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, prefixstr):
|
|
||||||
"""
|
|
||||||
Create a Ipv6Prefix instance.
|
|
||||||
|
|
||||||
:param str prefixstr: ip prefix
|
|
||||||
"""
|
|
||||||
super().__init__(AF_INET6, prefixstr)
|
|
||||||
|
|
||||||
|
|
||||||
def is_ip_address(af, addrstr):
|
|
||||||
"""
|
|
||||||
Check if ip address string is a valid ip address.
|
|
||||||
|
|
||||||
:param int af: address family
|
|
||||||
:param str addrstr: ip address string
|
|
||||||
:return: True if a valid ip address, False otherwise
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
socket.inet_pton(af, addrstr)
|
|
||||||
return True
|
|
||||||
except IOError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def is_ipv4_address(addrstr):
|
|
||||||
"""
|
|
||||||
Check if ipv4 address string is a valid ipv4 address.
|
|
||||||
|
|
||||||
:param str addrstr: ipv4 address string
|
|
||||||
:return: True if a valid ipv4 address, False otherwise
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return is_ip_address(AF_INET, addrstr)
|
|
||||||
|
|
||||||
|
|
||||||
def is_ipv6_address(addrstr):
|
|
||||||
"""
|
|
||||||
Check if ipv6 address string is a valid ipv6 address.
|
|
||||||
|
|
||||||
:param str addrstr: ipv6 address string
|
|
||||||
:return: True if a valid ipv6 address, False otherwise
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return is_ip_address(AF_INET6, addrstr)
|
|
|
@ -3,17 +3,16 @@ Defines network nodes used within core.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import socket
|
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from socket import AF_INET, AF_INET6
|
|
||||||
|
import netaddr
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.constants import EBTABLES_BIN, TC_BIN
|
from core.constants import EBTABLES_BIN, TC_BIN
|
||||||
from core.emulator.data import LinkData
|
from core.emulator.data import LinkData
|
||||||
from core.emulator.enumerations import LinkTypes, NodeTypes, RegisterTlvs
|
from core.emulator.enumerations import LinkTypes, NodeTypes, RegisterTlvs
|
||||||
from core.errors import CoreCommandError, CoreError
|
from core.errors import CoreCommandError, CoreError
|
||||||
from core.nodes import ipaddress
|
|
||||||
from core.nodes.base import CoreNetworkBase
|
from core.nodes.base import CoreNetworkBase
|
||||||
from core.nodes.interface import GreTap, Veth
|
from core.nodes.interface import GreTap, Veth
|
||||||
from core.nodes.netclient import get_net_client
|
from core.nodes.netclient import get_net_client
|
||||||
|
@ -750,28 +749,30 @@ class CtrlNet(CoreNetwork):
|
||||||
:param serverintf: server interface
|
:param serverintf: server interface
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
self.prefix = ipaddress.Ipv4Prefix(prefix)
|
self.prefix = netaddr.IPNetwork(prefix).cidr
|
||||||
self.hostid = hostid
|
self.hostid = hostid
|
||||||
self.assign_address = assign_address
|
self.assign_address = assign_address
|
||||||
self.updown_script = updown_script
|
self.updown_script = updown_script
|
||||||
self.serverintf = serverintf
|
self.serverintf = serverintf
|
||||||
super().__init__(session, _id, name, start, server)
|
super().__init__(session, _id, name, start, server)
|
||||||
|
|
||||||
def add_addresses(self, address):
|
def add_addresses(self, index):
|
||||||
"""
|
"""
|
||||||
Add addresses used for created control networks,
|
Add addresses used for created control networks,
|
||||||
|
|
||||||
:param core.nodes.interfaces.IpAddress address: starting address to use
|
:param int index: starting address index
|
||||||
:return:
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
use_ovs = self.session.options.get_config("ovs") == "True"
|
use_ovs = self.session.options.get_config("ovs") == "True"
|
||||||
|
address = self.prefix[index]
|
||||||
current = f"{address}/{self.prefix.prefixlen}"
|
current = f"{address}/{self.prefix.prefixlen}"
|
||||||
net_client = get_net_client(use_ovs, utils.cmd)
|
net_client = get_net_client(use_ovs, utils.cmd)
|
||||||
net_client.create_address(self.brname, current)
|
net_client.create_address(self.brname, current)
|
||||||
servers = self.session.distributed.servers
|
servers = self.session.distributed.servers
|
||||||
for name in servers:
|
for name in servers:
|
||||||
server = servers[name]
|
server = servers[name]
|
||||||
address -= 1
|
index -= 1
|
||||||
|
address = self.prefix[index]
|
||||||
current = f"{address}/{self.prefix.prefixlen}"
|
current = f"{address}/{self.prefix.prefixlen}"
|
||||||
net_client = get_net_client(use_ovs, server.remote_cmd)
|
net_client = get_net_client(use_ovs, server.remote_cmd)
|
||||||
net_client.create_address(self.brname, current)
|
net_client.create_address(self.brname, current)
|
||||||
|
@ -790,11 +791,9 @@ class CtrlNet(CoreNetwork):
|
||||||
logging.info("added control network bridge: %s %s", self.brname, self.prefix)
|
logging.info("added control network bridge: %s %s", self.brname, self.prefix)
|
||||||
|
|
||||||
if self.hostid and self.assign_address:
|
if self.hostid and self.assign_address:
|
||||||
address = self.prefix.addr(self.hostid)
|
self.add_addresses(self.hostid)
|
||||||
self.add_addresses(address)
|
|
||||||
elif self.assign_address:
|
elif self.assign_address:
|
||||||
address = self.prefix.max_addr()
|
self.add_addresses(-2)
|
||||||
self.add_addresses(address)
|
|
||||||
|
|
||||||
if self.updown_script:
|
if self.updown_script:
|
||||||
logging.info(
|
logging.info(
|
||||||
|
@ -908,15 +907,11 @@ class PtpNet(CoreNetwork):
|
||||||
for address in if1.addrlist:
|
for address in if1.addrlist:
|
||||||
ip, _sep, mask = address.partition("/")
|
ip, _sep, mask = address.partition("/")
|
||||||
mask = int(mask)
|
mask = int(mask)
|
||||||
if ipaddress.is_ipv4_address(ip):
|
if netaddr.valid_ipv4(ip):
|
||||||
family = AF_INET
|
interface1_ip4 = ip
|
||||||
ipl = socket.inet_pton(family, ip)
|
|
||||||
interface1_ip4 = ipaddress.IpAddress(af=family, address=ipl)
|
|
||||||
interface1_ip4_mask = mask
|
interface1_ip4_mask = mask
|
||||||
else:
|
else:
|
||||||
family = AF_INET6
|
interface1_ip6 = ip
|
||||||
ipl = socket.inet_pton(family, ip)
|
|
||||||
interface1_ip6 = ipaddress.IpAddress(af=family, address=ipl)
|
|
||||||
interface1_ip6_mask = mask
|
interface1_ip6_mask = mask
|
||||||
|
|
||||||
interface2_ip4 = None
|
interface2_ip4 = None
|
||||||
|
@ -926,15 +921,11 @@ class PtpNet(CoreNetwork):
|
||||||
for address in if2.addrlist:
|
for address in if2.addrlist:
|
||||||
ip, _sep, mask = address.partition("/")
|
ip, _sep, mask = address.partition("/")
|
||||||
mask = int(mask)
|
mask = int(mask)
|
||||||
if ipaddress.is_ipv4_address(ip):
|
if netaddr.valid_ipv4(ip):
|
||||||
family = AF_INET
|
interface2_ip4 = ip
|
||||||
ipl = socket.inet_pton(family, ip)
|
|
||||||
interface2_ip4 = ipaddress.IpAddress(af=family, address=ipl)
|
|
||||||
interface2_ip4_mask = mask
|
interface2_ip4_mask = mask
|
||||||
else:
|
else:
|
||||||
family = AF_INET6
|
interface2_ip6 = ip
|
||||||
ipl = socket.inet_pton(family, ip)
|
|
||||||
interface2_ip6 = ipaddress.IpAddress(af=family, address=ipl)
|
|
||||||
interface2_ip6_mask = mask
|
interface2_ip6_mask = mask
|
||||||
|
|
||||||
link_data = LinkData(
|
link_data = LinkData(
|
||||||
|
|
|
@ -59,19 +59,30 @@ class PhysicalNode(CoreNodeBase):
|
||||||
def sethwaddr(self, ifindex, addr):
|
def sethwaddr(self, ifindex, addr):
|
||||||
"""
|
"""
|
||||||
Set hardware address for an interface.
|
Set hardware address for an interface.
|
||||||
|
|
||||||
|
:param int ifindex: index of interface to set hardware address for
|
||||||
|
:param str 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 = self._netif[ifindex]
|
||||||
interface.sethwaddr(addr)
|
interface.sethwaddr(addr)
|
||||||
if self.up:
|
if self.up:
|
||||||
self.net_client.device_mac(interface.name, str(addr))
|
self.net_client.device_mac(interface.name, addr)
|
||||||
|
|
||||||
def addaddr(self, ifindex, addr):
|
def addaddr(self, ifindex, addr):
|
||||||
"""
|
"""
|
||||||
Add an address to an interface.
|
Add an address to an interface.
|
||||||
|
|
||||||
|
:param int ifindex: index of interface to add address to
|
||||||
|
:param str addr: address to add
|
||||||
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
|
addr = utils.validate_ip(addr)
|
||||||
interface = self._netif[ifindex]
|
interface = self._netif[ifindex]
|
||||||
if self.up:
|
if self.up:
|
||||||
self.net_client.create_address(interface.name, str(addr))
|
self.net_client.create_address(interface.name, addr)
|
||||||
interface.addaddr(addr)
|
interface.addaddr(addr)
|
||||||
|
|
||||||
def deladdr(self, ifindex, addr):
|
def deladdr(self, ifindex, addr):
|
||||||
|
@ -408,9 +419,9 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
:return: nothing
|
:return: nothing
|
||||||
:raises CoreCommandError: when there is a command exception
|
:raises CoreCommandError: when there is a command exception
|
||||||
"""
|
"""
|
||||||
|
addr = utils.validate_ip(addr)
|
||||||
if self.up:
|
if self.up:
|
||||||
self.net_client.create_address(self.name, str(addr))
|
self.net_client.create_address(self.name, addr)
|
||||||
|
|
||||||
CoreInterface.addaddr(self, addr)
|
CoreInterface.addaddr(self, addr)
|
||||||
|
|
||||||
def deladdr(self, addr):
|
def deladdr(self, addr):
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
"""
|
"""
|
||||||
bird.py: defines routing services provided by the BIRD Internet Routing Daemon.
|
bird.py: defines routing services provided by the BIRD Internet Routing Daemon.
|
||||||
"""
|
"""
|
||||||
from core.nodes import ipaddress
|
import netaddr
|
||||||
|
|
||||||
from core.services.coreservices import CoreService
|
from core.services.coreservices import CoreService
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ class Bird(CoreService):
|
||||||
continue
|
continue
|
||||||
for a in ifc.addrlist:
|
for a in ifc.addrlist:
|
||||||
a = a.split("/")[0]
|
a = a.split("/")[0]
|
||||||
if ipaddress.is_ipv4_address(a):
|
if netaddr.valid_ipv4(a):
|
||||||
return a
|
return a
|
||||||
# raise ValueError, "no IPv4 address found for router ID"
|
# raise ValueError, "no IPv4 address found for router ID"
|
||||||
return "0.0.0.0"
|
return "0.0.0.0"
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
frr.py: defines routing services provided by FRRouting.
|
frr.py: defines routing services provided by FRRouting.
|
||||||
Assumes installation of FRR via https://deb.frrouting.org/
|
Assumes installation of FRR via https://deb.frrouting.org/
|
||||||
"""
|
"""
|
||||||
|
import netaddr
|
||||||
|
|
||||||
from core import constants
|
from core import constants
|
||||||
from core.emulator.enumerations import LinkTypes
|
from core.emulator.enumerations import LinkTypes
|
||||||
from core.nodes import ipaddress
|
|
||||||
from core.nodes.network import PtpNet
|
from core.nodes.network import PtpNet
|
||||||
from core.nodes.physical import Rj45Node
|
from core.nodes.physical import Rj45Node
|
||||||
from core.services.coreservices import CoreService
|
from core.services.coreservices import CoreService
|
||||||
|
@ -85,7 +85,7 @@ class FRRZebra(CoreService):
|
||||||
|
|
||||||
if want_ipv4:
|
if want_ipv4:
|
||||||
ipv4list = filter(
|
ipv4list = filter(
|
||||||
lambda x: ipaddress.is_ipv4_address(x.split("/")[0]), ifc.addrlist
|
lambda x: netaddr.valid_ipv4(x.split("/")[0]), ifc.addrlist
|
||||||
)
|
)
|
||||||
cfg += " "
|
cfg += " "
|
||||||
cfg += "\n ".join(map(cls.addrstr, ipv4list))
|
cfg += "\n ".join(map(cls.addrstr, ipv4list))
|
||||||
|
@ -93,7 +93,7 @@ class FRRZebra(CoreService):
|
||||||
cfg += cfgv4
|
cfg += cfgv4
|
||||||
if want_ipv6:
|
if want_ipv6:
|
||||||
ipv6list = filter(
|
ipv6list = filter(
|
||||||
lambda x: ipaddress.is_ipv6_address(x.split("/")[0]), ifc.addrlist
|
lambda x: netaddr.valid_ipv6(x.split("/")[0]), ifc.addrlist
|
||||||
)
|
)
|
||||||
cfg += " "
|
cfg += " "
|
||||||
cfg += "\n ".join(map(cls.addrstr, ipv6list))
|
cfg += "\n ".join(map(cls.addrstr, ipv6list))
|
||||||
|
@ -113,9 +113,9 @@ class FRRZebra(CoreService):
|
||||||
helper for mapping IP addresses to zebra config statements
|
helper for mapping IP addresses to zebra config statements
|
||||||
"""
|
"""
|
||||||
addr = x.split("/")[0]
|
addr = x.split("/")[0]
|
||||||
if ipaddress.is_ipv4_address(addr):
|
if netaddr.valid_ipv4(addr):
|
||||||
return "ip address %s" % x
|
return "ip address %s" % x
|
||||||
elif ipaddress.is_ipv6_address(addr):
|
elif netaddr.valid_ipv6(addr):
|
||||||
return "ipv6 address %s" % x
|
return "ipv6 address %s" % x
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid address: %s", x)
|
raise ValueError("invalid address: %s", x)
|
||||||
|
@ -330,7 +330,7 @@ class FrrService(CoreService):
|
||||||
continue
|
continue
|
||||||
for a in ifc.addrlist:
|
for a in ifc.addrlist:
|
||||||
a = a.split("/")[0]
|
a = a.split("/")[0]
|
||||||
if ipaddress.is_ipv4_address(a):
|
if netaddr.valid_ipv4(a):
|
||||||
return a
|
return a
|
||||||
# raise ValueError, "no IPv4 address found for router ID"
|
# raise ValueError, "no IPv4 address found for router ID"
|
||||||
return "0.0.0.0"
|
return "0.0.0.0"
|
||||||
|
@ -414,29 +414,15 @@ class FRROspfv2(FrrService):
|
||||||
continue
|
continue
|
||||||
for a in ifc.addrlist:
|
for a in ifc.addrlist:
|
||||||
addr = a.split("/")[0]
|
addr = a.split("/")[0]
|
||||||
if not ipaddress.is_ipv4_address(addr):
|
if not netaddr.valid_ipv4(addr):
|
||||||
continue
|
continue
|
||||||
net = ipaddress.Ipv4Prefix(a)
|
cfg += " network %s area 0\n" % a
|
||||||
cfg += " network %s area 0\n" % net
|
|
||||||
cfg += "!\n"
|
cfg += "!\n"
|
||||||
return cfg
|
return cfg
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generatefrrifcconfig(cls, node, ifc):
|
def generatefrrifcconfig(cls, node, ifc):
|
||||||
return cls.mtucheck(ifc)
|
return cls.mtucheck(ifc)
|
||||||
# cfg = cls.mtucheck(ifc)
|
|
||||||
# external RJ45 connections will use default OSPF timers
|
|
||||||
# if cls.rj45check(ifc):
|
|
||||||
# return cfg
|
|
||||||
# cfg += cls.ptpcheck(ifc)
|
|
||||||
|
|
||||||
# return cfg + """\
|
|
||||||
|
|
||||||
|
|
||||||
# ip ospf hello-interval 2
|
|
||||||
# ip ospf dead-interval 6
|
|
||||||
# ip ospf retransmit-interval 5
|
|
||||||
# """
|
|
||||||
|
|
||||||
|
|
||||||
class FRROspfv3(FrrService):
|
class FRROspfv3(FrrService):
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
nrl.py: defines services provided by NRL protolib tools hosted here:
|
nrl.py: defines services provided by NRL protolib tools hosted here:
|
||||||
http://www.nrl.navy.mil/itd/ncs/products
|
http://www.nrl.navy.mil/itd/ncs/products
|
||||||
"""
|
"""
|
||||||
|
import netaddr
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.nodes import ipaddress
|
|
||||||
from core.nodes.ipaddress import Ipv4Prefix
|
|
||||||
from core.services.coreservices import CoreService
|
from core.services.coreservices import CoreService
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,9 +37,8 @@ class NrlService(CoreService):
|
||||||
continue
|
continue
|
||||||
for a in ifc.addrlist:
|
for a in ifc.addrlist:
|
||||||
a = a.split("/")[0]
|
a = a.split("/")[0]
|
||||||
if ipaddress.is_ipv4_address(a):
|
if netaddr.valid_ipv4(a):
|
||||||
pre = Ipv4Prefix("%s/%s" % (a, prefixlen))
|
return f"{a}/{prefixlen}"
|
||||||
return str(pre)
|
|
||||||
# raise ValueError, "no IPv4 address found"
|
# raise ValueError, "no IPv4 address found"
|
||||||
return "0.0.0.0/%s" % prefixlen
|
return "0.0.0.0/%s" % prefixlen
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
"""
|
"""
|
||||||
quagga.py: defines routing services provided by Quagga.
|
quagga.py: defines routing services provided by Quagga.
|
||||||
"""
|
"""
|
||||||
|
import netaddr
|
||||||
|
|
||||||
from core import constants
|
from core import constants
|
||||||
from core.emane.nodes import EmaneNet
|
from core.emane.nodes import EmaneNet
|
||||||
from core.emulator.enumerations import LinkTypes
|
from core.emulator.enumerations import LinkTypes
|
||||||
from core.nodes import ipaddress
|
|
||||||
from core.nodes.network import PtpNet, WlanNode
|
from core.nodes.network import PtpNet, WlanNode
|
||||||
from core.nodes.physical import Rj45Node
|
from core.nodes.physical import Rj45Node
|
||||||
from core.services.coreservices import CoreService
|
from core.services.coreservices import CoreService
|
||||||
|
@ -82,7 +82,7 @@ class Zebra(CoreService):
|
||||||
|
|
||||||
if want_ipv4:
|
if want_ipv4:
|
||||||
ipv4list = filter(
|
ipv4list = filter(
|
||||||
lambda x: ipaddress.is_ipv4_address(x.split("/")[0]), ifc.addrlist
|
lambda x: netaddr.valid_ipv4(x.split("/")[0]), ifc.addrlist
|
||||||
)
|
)
|
||||||
cfg += " "
|
cfg += " "
|
||||||
cfg += "\n ".join(map(cls.addrstr, ipv4list))
|
cfg += "\n ".join(map(cls.addrstr, ipv4list))
|
||||||
|
@ -90,7 +90,7 @@ class Zebra(CoreService):
|
||||||
cfg += cfgv4
|
cfg += cfgv4
|
||||||
if want_ipv6:
|
if want_ipv6:
|
||||||
ipv6list = filter(
|
ipv6list = filter(
|
||||||
lambda x: ipaddress.is_ipv6_address(x.split("/")[0]), ifc.addrlist
|
lambda x: netaddr.valid_ipv6(x.split("/")[0]), ifc.addrlist
|
||||||
)
|
)
|
||||||
cfg += " "
|
cfg += " "
|
||||||
cfg += "\n ".join(map(cls.addrstr, ipv6list))
|
cfg += "\n ".join(map(cls.addrstr, ipv6list))
|
||||||
|
@ -110,9 +110,9 @@ class Zebra(CoreService):
|
||||||
helper for mapping IP addresses to zebra config statements
|
helper for mapping IP addresses to zebra config statements
|
||||||
"""
|
"""
|
||||||
addr = x.split("/")[0]
|
addr = x.split("/")[0]
|
||||||
if ipaddress.is_ipv4_address(addr):
|
if netaddr.valid_ipv4(addr):
|
||||||
return "ip address %s" % x
|
return "ip address %s" % x
|
||||||
elif ipaddress.is_ipv6_address(addr):
|
elif netaddr.valid_ipv6(addr):
|
||||||
return "ipv6 address %s" % x
|
return "ipv6 address %s" % x
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid address: %s", x)
|
raise ValueError("invalid address: %s", x)
|
||||||
|
@ -257,7 +257,7 @@ class QuaggaService(CoreService):
|
||||||
continue
|
continue
|
||||||
for a in ifc.addrlist:
|
for a in ifc.addrlist:
|
||||||
a = a.split("/")[0]
|
a = a.split("/")[0]
|
||||||
if ipaddress.is_ipv4_address(a):
|
if netaddr.valid_ipv4(a):
|
||||||
return a
|
return a
|
||||||
# raise ValueError, "no IPv4 address found for router ID"
|
# raise ValueError, "no IPv4 address found for router ID"
|
||||||
return "0.0.0.0"
|
return "0.0.0.0"
|
||||||
|
@ -341,28 +341,14 @@ class Ospfv2(QuaggaService):
|
||||||
continue
|
continue
|
||||||
for a in ifc.addrlist:
|
for a in ifc.addrlist:
|
||||||
addr = a.split("/")[0]
|
addr = a.split("/")[0]
|
||||||
if ipaddress.is_ipv4_address(addr):
|
if netaddr.valid_ipv4(addr):
|
||||||
net = ipaddress.Ipv4Prefix(a)
|
cfg += " network %s area 0\n" % a
|
||||||
cfg += " network %s area 0\n" % net
|
|
||||||
cfg += "!\n"
|
cfg += "!\n"
|
||||||
return cfg
|
return cfg
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generatequaggaifcconfig(cls, node, ifc):
|
def generatequaggaifcconfig(cls, node, ifc):
|
||||||
return cls.mtucheck(ifc)
|
return cls.mtucheck(ifc)
|
||||||
# cfg = cls.mtucheck(ifc)
|
|
||||||
# external RJ45 connections will use default OSPF timers
|
|
||||||
# if cls.rj45check(ifc):
|
|
||||||
# return cfg
|
|
||||||
# cfg += cls.ptpcheck(ifc)
|
|
||||||
|
|
||||||
# return cfg + """\
|
|
||||||
|
|
||||||
|
|
||||||
# ip ospf hello-interval 2
|
|
||||||
# ip ospf dead-interval 6
|
|
||||||
# ip ospf retransmit-interval 5
|
|
||||||
# """
|
|
||||||
|
|
||||||
|
|
||||||
class Ospfv3(QuaggaService):
|
class Ospfv3(QuaggaService):
|
||||||
|
|
|
@ -4,7 +4,8 @@ sdn.py defines services to start Open vSwitch and the Ryu SDN Controller.
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from core.nodes import ipaddress
|
import netaddr
|
||||||
|
|
||||||
from core.services.coreservices import CoreService
|
from core.services.coreservices import CoreService
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ class OvsService(SdnService):
|
||||||
cfg += "# auto-generated by OvsService (OvsService.py)\n"
|
cfg += "# auto-generated by OvsService (OvsService.py)\n"
|
||||||
cfg += "/etc/init.d/openvswitch-switch start < /dev/null\n"
|
cfg += "/etc/init.d/openvswitch-switch start < /dev/null\n"
|
||||||
cfg += "ovs-vsctl add-br ovsbr0 -- set Bridge ovsbr0 fail-mode=secure\n"
|
cfg += "ovs-vsctl add-br ovsbr0 -- set Bridge ovsbr0 fail-mode=secure\n"
|
||||||
cfg += "ifconfig ovsbr0 up\n"
|
cfg += "ip link set dev ovsbr0 up\n"
|
||||||
|
|
||||||
for ifc in node.netifs():
|
for ifc in node.netifs():
|
||||||
if hasattr(ifc, "control") and ifc.control is True:
|
if hasattr(ifc, "control") and ifc.control is True:
|
||||||
|
@ -51,18 +52,18 @@ class OvsService(SdnService):
|
||||||
|
|
||||||
# create virtual interfaces
|
# create virtual interfaces
|
||||||
cfg += "ip link add rtr%s type veth peer name sw%s\n" % (ifnum, ifnum)
|
cfg += "ip link add rtr%s type veth peer name sw%s\n" % (ifnum, ifnum)
|
||||||
cfg += "ifconfig rtr%s up\n" % ifnum
|
cfg += "ip link set dev rtr%s up\n" % ifnum
|
||||||
cfg += "ifconfig sw%s up\n" % ifnum
|
cfg += "ip link set dev sw%s up\n" % ifnum
|
||||||
|
|
||||||
# remove ip address of eths because quagga/zebra will assign same IPs to rtr interfaces
|
# 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
|
# or assign them manually to rtr interfaces if zebra is not running
|
||||||
for ifcaddr in ifc.addrlist:
|
for ifcaddr in ifc.addrlist:
|
||||||
addr = ifcaddr.split("/")[0]
|
addr = ifcaddr.split("/")[0]
|
||||||
if ipaddress.is_ipv4_address(addr):
|
if netaddr.valid_ipv4(addr):
|
||||||
cfg += "ip addr del %s dev %s\n" % (ifcaddr, ifc.name)
|
cfg += "ip addr del %s dev %s\n" % (ifcaddr, ifc.name)
|
||||||
if has_zebra == 0:
|
if has_zebra == 0:
|
||||||
cfg += "ip addr add %s dev rtr%s\n" % (ifcaddr, ifnum)
|
cfg += "ip addr add %s dev rtr%s\n" % (ifcaddr, ifnum)
|
||||||
elif ipaddress.is_ipv6_address(addr):
|
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" % (ifcaddr, ifc.name)
|
||||||
if has_zebra == 0:
|
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" % (ifcaddr, ifnum)
|
||||||
|
|
|
@ -4,10 +4,10 @@ utility.py: defines miscellaneous utility services.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
import netaddr
|
||||||
|
|
||||||
from core import constants, utils
|
from core import constants, utils
|
||||||
from core.errors import CoreCommandError
|
from core.errors import CoreCommandError
|
||||||
from core.nodes import ipaddress
|
|
||||||
from core.nodes.ipaddress import Ipv4Prefix, Ipv6Prefix
|
|
||||||
from core.services.coreservices import CoreService, ServiceMode
|
from core.services.coreservices import CoreService, ServiceMode
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,19 +88,15 @@ class DefaultRouteService(UtilService):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def addrstr(x):
|
def addrstr(x):
|
||||||
addr = x.split("/")[0]
|
net = netaddr.IPNetwork(x)
|
||||||
if ipaddress.is_ipv6_address(addr):
|
if net[1] == net[-2]:
|
||||||
net = Ipv6Prefix(x)
|
|
||||||
else:
|
|
||||||
net = Ipv4Prefix(x)
|
|
||||||
if net.max_addr() == net.min_addr():
|
|
||||||
return ""
|
return ""
|
||||||
else:
|
else:
|
||||||
if os.uname()[0] == "Linux":
|
if os.uname()[0] == "Linux":
|
||||||
rtcmd = "ip route add default via"
|
rtcmd = "ip route add default via"
|
||||||
else:
|
else:
|
||||||
raise Exception("unknown platform")
|
raise Exception("unknown platform")
|
||||||
return "%s %s" % (rtcmd, net.min_addr())
|
return "%s %s" % (rtcmd, net[1])
|
||||||
|
|
||||||
|
|
||||||
class DefaultMulticastRouteService(UtilService):
|
class DefaultMulticastRouteService(UtilService):
|
||||||
|
@ -150,20 +146,19 @@ class StaticRouteService(UtilService):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def routestr(x):
|
def routestr(x):
|
||||||
addr = x.split("/")[0]
|
addr = x.split("/")[0]
|
||||||
if ipaddress.is_ipv6_address(addr):
|
if netaddr.valid_ipv6(addr):
|
||||||
net = Ipv6Prefix(x)
|
|
||||||
dst = "3ffe:4::/64"
|
dst = "3ffe:4::/64"
|
||||||
else:
|
else:
|
||||||
net = Ipv4Prefix(x)
|
|
||||||
dst = "10.9.8.0/24"
|
dst = "10.9.8.0/24"
|
||||||
if net.max_addr() == net.min_addr():
|
net = netaddr.IPNetwork(x)
|
||||||
|
if net[-2] == net[1]:
|
||||||
return ""
|
return ""
|
||||||
else:
|
else:
|
||||||
if os.uname()[0] == "Linux":
|
if os.uname()[0] == "Linux":
|
||||||
rtcmd = "#/sbin/ip route add %s via" % dst
|
rtcmd = "#/sbin/ip route add %s via" % dst
|
||||||
else:
|
else:
|
||||||
raise Exception("unknown platform")
|
raise Exception("unknown platform")
|
||||||
return "%s %s" % (rtcmd, net.min_addr())
|
return "%s %s" % (rtcmd, net[1])
|
||||||
|
|
||||||
|
|
||||||
class SshService(UtilService):
|
class SshService(UtilService):
|
||||||
|
@ -285,14 +280,14 @@ ddns-update-style none;
|
||||||
for inclusion in the dhcpd3 config file.
|
for inclusion in the dhcpd3 config file.
|
||||||
"""
|
"""
|
||||||
addr = x.split("/")[0]
|
addr = x.split("/")[0]
|
||||||
if ipaddress.is_ipv6_address(addr):
|
if netaddr.valid_ipv6(addr):
|
||||||
return ""
|
return ""
|
||||||
else:
|
else:
|
||||||
addr = x.split("/")[0]
|
net = netaddr.IPNetwork(x)
|
||||||
net = Ipv4Prefix(x)
|
|
||||||
# divide the address space in half
|
# divide the address space in half
|
||||||
rangelow = net.addr(net.num_addr() / 2)
|
index = (net.size - 2) / 2
|
||||||
rangehigh = net.max_addr()
|
rangelow = net[index]
|
||||||
|
rangehigh = net[-2]
|
||||||
return """
|
return """
|
||||||
subnet %s netmask %s {
|
subnet %s netmask %s {
|
||||||
pool {
|
pool {
|
||||||
|
@ -302,8 +297,8 @@ subnet %s netmask %s {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""" % (
|
""" % (
|
||||||
net.prefix_str(),
|
net.ip,
|
||||||
net.netmask_str(),
|
net.netmask,
|
||||||
rangelow,
|
rangelow,
|
||||||
rangehigh,
|
rangehigh,
|
||||||
addr,
|
addr,
|
||||||
|
@ -708,9 +703,8 @@ interface %s
|
||||||
for inclusion in the RADVD config file.
|
for inclusion in the RADVD config file.
|
||||||
"""
|
"""
|
||||||
addr = x.split("/")[0]
|
addr = x.split("/")[0]
|
||||||
if ipaddress.is_ipv6_address(addr):
|
if netaddr.valid_ipv6(addr):
|
||||||
net = Ipv6Prefix(x)
|
return x
|
||||||
return str(net)
|
|
||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@ xorp.py: defines routing services provided by the XORP routing suite.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from core.nodes import ipaddress
|
import netaddr
|
||||||
|
|
||||||
from core.services.coreservices import CoreService
|
from core.services.coreservices import CoreService
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,7 +153,7 @@ class XorpService(CoreService):
|
||||||
continue
|
continue
|
||||||
for a in ifc.addrlist:
|
for a in ifc.addrlist:
|
||||||
a = a.split("/")[0]
|
a = a.split("/")[0]
|
||||||
if ipaddress.is_ipv4_address(a):
|
if netaddr.valid_ipv4(a):
|
||||||
return a
|
return a
|
||||||
# raise ValueError, "no IPv4 address found for router ID"
|
# raise ValueError, "no IPv4 address found for router ID"
|
||||||
return "0.0.0.0"
|
return "0.0.0.0"
|
||||||
|
@ -190,7 +191,7 @@ class XorpOspfv2(XorpService):
|
||||||
cfg += "\t\tvif %s {\n" % ifc.name
|
cfg += "\t\tvif %s {\n" % ifc.name
|
||||||
for a in ifc.addrlist:
|
for a in ifc.addrlist:
|
||||||
addr = a.split("/")[0]
|
addr = a.split("/")[0]
|
||||||
if not ipaddress.is_ipv4_address(addr):
|
if not netaddr.valid_ipv4(addr):
|
||||||
continue
|
continue
|
||||||
cfg += "\t\t address %s {\n" % addr
|
cfg += "\t\t address %s {\n" % addr
|
||||||
cfg += "\t\t }\n"
|
cfg += "\t\t }\n"
|
||||||
|
@ -283,7 +284,7 @@ class XorpRip(XorpService):
|
||||||
cfg += "\t vif %s {\n" % ifc.name
|
cfg += "\t vif %s {\n" % ifc.name
|
||||||
for a in ifc.addrlist:
|
for a in ifc.addrlist:
|
||||||
addr = a.split("/")[0]
|
addr = a.split("/")[0]
|
||||||
if not ipaddress.is_ipv4_address(addr):
|
if not netaddr.valid_ipv4(addr):
|
||||||
continue
|
continue
|
||||||
cfg += "\t\taddress %s {\n" % addr
|
cfg += "\t\taddress %s {\n" % addr
|
||||||
cfg += "\t\t disable: false\n"
|
cfg += "\t\t disable: false\n"
|
||||||
|
@ -465,7 +466,7 @@ class XorpOlsr(XorpService):
|
||||||
cfg += "\t vif %s {\n" % ifc.name
|
cfg += "\t vif %s {\n" % ifc.name
|
||||||
for a in ifc.addrlist:
|
for a in ifc.addrlist:
|
||||||
addr = a.split("/")[0]
|
addr = a.split("/")[0]
|
||||||
if not ipaddress.is_ipv4_address(addr):
|
if not netaddr.valid_ipv4(addr):
|
||||||
continue
|
continue
|
||||||
cfg += "\t\taddress %s {\n" % addr
|
cfg += "\t\taddress %s {\n" % addr
|
||||||
cfg += "\t\t}\n"
|
cfg += "\t\t}\n"
|
||||||
|
|
|
@ -11,11 +11,14 @@ import json
|
||||||
import logging
|
import logging
|
||||||
import logging.config
|
import logging.config
|
||||||
import os
|
import os
|
||||||
|
import random
|
||||||
import shlex
|
import shlex
|
||||||
import sys
|
import sys
|
||||||
from subprocess import PIPE, STDOUT, Popen
|
from subprocess import PIPE, STDOUT, Popen
|
||||||
|
|
||||||
from core.errors import CoreCommandError
|
import netaddr
|
||||||
|
|
||||||
|
from core.errors import CoreCommandError, CoreError
|
||||||
|
|
||||||
DEVNULL = open(os.devnull, "wb")
|
DEVNULL = open(os.devnull, "wb")
|
||||||
|
|
||||||
|
@ -408,3 +411,48 @@ def threadpool(funcs, workers=10):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
exceptions.append(e)
|
exceptions.append(e)
|
||||||
return results, exceptions
|
return results, exceptions
|
||||||
|
|
||||||
|
|
||||||
|
def random_mac():
|
||||||
|
"""
|
||||||
|
Create a random mac address using Xen OID 00:16:3E.
|
||||||
|
|
||||||
|
:return: random mac address
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
value = random.randint(0, 0xFFFFFF)
|
||||||
|
value |= 0x00163E << 24
|
||||||
|
mac = netaddr.EUI(value)
|
||||||
|
mac.dialect = netaddr.mac_unix
|
||||||
|
return str(mac)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_mac(value):
|
||||||
|
"""
|
||||||
|
Validate mac and return unix formatted version.
|
||||||
|
|
||||||
|
:param str value: address to validate
|
||||||
|
:return: unix formatted mac
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
mac = netaddr.EUI(value)
|
||||||
|
mac.dialect = netaddr.mac_unix
|
||||||
|
return str(mac)
|
||||||
|
except netaddr.AddrFormatError as e:
|
||||||
|
raise CoreError(f"invalid mac address {value}: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
def validate_ip(value):
|
||||||
|
"""
|
||||||
|
Validate ip address with prefix and return formatted version.
|
||||||
|
|
||||||
|
:param str value: address to validate
|
||||||
|
:return: formatted ip address
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
ip = netaddr.IPNetwork(value)
|
||||||
|
return str(ip)
|
||||||
|
except (ValueError, netaddr.AddrFormatError) as e:
|
||||||
|
raise CoreError(f"invalid ip address {value}: {e}")
|
||||||
|
|
|
@ -8,7 +8,6 @@ from core.emane.nodes import EmaneNet
|
||||||
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
|
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
|
||||||
from core.emulator.enumerations import NodeTypes
|
from core.emulator.enumerations import NodeTypes
|
||||||
from core.nodes.base import CoreNetworkBase
|
from core.nodes.base import CoreNetworkBase
|
||||||
from core.nodes.ipaddress import MacAddress
|
|
||||||
from core.nodes.network import CtrlNet
|
from core.nodes.network import CtrlNet
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,8 +47,6 @@ def create_interface_data(interface_element):
|
||||||
interface_id = int(interface_element.get("id"))
|
interface_id = int(interface_element.get("id"))
|
||||||
name = interface_element.get("name")
|
name = interface_element.get("name")
|
||||||
mac = interface_element.get("mac")
|
mac = interface_element.get("mac")
|
||||||
if mac:
|
|
||||||
mac = MacAddress.from_string(mac)
|
|
||||||
ip4 = interface_element.get("ip4")
|
ip4 = interface_element.get("ip4")
|
||||||
ip4_mask = get_int(interface_element, "ip4_mask")
|
ip4_mask = get_int(interface_element, "ip4_mask")
|
||||||
ip6 = interface_element.get("ip6")
|
ip6 = interface_element.get("ip6")
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
import netaddr
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.constants import IP_BIN
|
from core.constants import IP_BIN
|
||||||
from core.emane.nodes import EmaneNet
|
from core.emane.nodes import EmaneNet
|
||||||
from core.nodes import ipaddress
|
|
||||||
from core.nodes.base import CoreNodeBase
|
from core.nodes.base import CoreNodeBase
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,9 +56,9 @@ def add_emane_interface(host_element, netif, platform_name="p1", transport_name=
|
||||||
|
|
||||||
def get_address_type(address):
|
def get_address_type(address):
|
||||||
addr, _slash, _prefixlen = address.partition("/")
|
addr, _slash, _prefixlen = address.partition("/")
|
||||||
if ipaddress.is_ipv4_address(addr):
|
if netaddr.valid_ipv4(addr):
|
||||||
address_type = "IPv4"
|
address_type = "IPv4"
|
||||||
elif ipaddress.is_ipv6_address(addr):
|
elif netaddr.valid_ipv6(addr):
|
||||||
address_type = "IPv6"
|
address_type = "IPv6"
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
|
@ -5,7 +5,6 @@ from tempfile import NamedTemporaryFile
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.nodes.ipaddress import MacAddress
|
|
||||||
from core.xml import corexml
|
from core.xml import corexml
|
||||||
|
|
||||||
_hwaddr_prefix = "02:02"
|
_hwaddr_prefix = "02:02"
|
||||||
|
@ -208,7 +207,7 @@ def build_node_platform_xml(emane_manager, control_net, node, nem_id, platform_x
|
||||||
node.setnemid(netif, nem_id)
|
node.setnemid(netif, nem_id)
|
||||||
macstr = _hwaddr_prefix + ":00:00:"
|
macstr = _hwaddr_prefix + ":00:00:"
|
||||||
macstr += f"{(nem_id >> 8) & 0xFF:02X}:{nem_id & 0xFF:02X}"
|
macstr += f"{(nem_id >> 8) & 0xFF:02X}:{nem_id & 0xFF:02X}"
|
||||||
netif.sethwaddr(MacAddress.from_string(macstr))
|
netif.sethwaddr(macstr)
|
||||||
|
|
||||||
# increment nem id
|
# increment nem id
|
||||||
nem_id += 1
|
nem_id += 1
|
||||||
|
|
|
@ -5,6 +5,7 @@ import os
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
import netaddr
|
||||||
import pytest
|
import pytest
|
||||||
from mock import MagicMock
|
from mock import MagicMock
|
||||||
|
|
||||||
|
@ -26,7 +27,6 @@ from core.emulator.enumerations import (
|
||||||
)
|
)
|
||||||
from core.errors import CoreError
|
from core.errors import CoreError
|
||||||
from core.location.mobility import BasicRangeModel
|
from core.location.mobility import BasicRangeModel
|
||||||
from core.nodes.ipaddress import Ipv4Prefix
|
|
||||||
|
|
||||||
|
|
||||||
def dict_to_str(values):
|
def dict_to_str(values):
|
||||||
|
@ -101,8 +101,8 @@ class TestGui:
|
||||||
coretlv.session.add_node(_id=node_one)
|
coretlv.session.add_node(_id=node_one)
|
||||||
switch = 2
|
switch = 2
|
||||||
coretlv.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
|
coretlv.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
|
||||||
ip_prefix = Ipv4Prefix("10.0.0.0/24")
|
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||||
interface_one = ip_prefix.addr(node_one)
|
interface_one = str(ip_prefix[node_one])
|
||||||
message = coreapi.CoreLinkMessage.create(
|
message = coreapi.CoreLinkMessage.create(
|
||||||
MessageFlags.ADD.value,
|
MessageFlags.ADD.value,
|
||||||
[
|
[
|
||||||
|
@ -125,8 +125,8 @@ class TestGui:
|
||||||
coretlv.session.add_node(_id=node_one)
|
coretlv.session.add_node(_id=node_one)
|
||||||
switch = 2
|
switch = 2
|
||||||
coretlv.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
|
coretlv.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
|
||||||
ip_prefix = Ipv4Prefix("10.0.0.0/24")
|
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||||
interface_one = ip_prefix.addr(node_one)
|
interface_one = str(ip_prefix[node_one])
|
||||||
message = coreapi.CoreLinkMessage.create(
|
message = coreapi.CoreLinkMessage.create(
|
||||||
MessageFlags.ADD.value,
|
MessageFlags.ADD.value,
|
||||||
[
|
[
|
||||||
|
@ -149,9 +149,9 @@ class TestGui:
|
||||||
coretlv.session.add_node(_id=node_one)
|
coretlv.session.add_node(_id=node_one)
|
||||||
node_two = 2
|
node_two = 2
|
||||||
coretlv.session.add_node(_id=node_two)
|
coretlv.session.add_node(_id=node_two)
|
||||||
ip_prefix = Ipv4Prefix("10.0.0.0/24")
|
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||||
interface_one = ip_prefix.addr(node_one)
|
interface_one = str(ip_prefix[node_one])
|
||||||
interface_two = ip_prefix.addr(node_two)
|
interface_two = str(ip_prefix[node_two])
|
||||||
message = coreapi.CoreLinkMessage.create(
|
message = coreapi.CoreLinkMessage.create(
|
||||||
MessageFlags.ADD.value,
|
MessageFlags.ADD.value,
|
||||||
[
|
[
|
||||||
|
@ -179,8 +179,8 @@ class TestGui:
|
||||||
coretlv.session.add_node(_id=node_one)
|
coretlv.session.add_node(_id=node_one)
|
||||||
switch = 2
|
switch = 2
|
||||||
coretlv.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
|
coretlv.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
|
||||||
ip_prefix = Ipv4Prefix("10.0.0.0/24")
|
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||||
interface_one = ip_prefix.addr(node_one)
|
interface_one = str(ip_prefix[node_one])
|
||||||
message = coreapi.CoreLinkMessage.create(
|
message = coreapi.CoreLinkMessage.create(
|
||||||
MessageFlags.ADD.value,
|
MessageFlags.ADD.value,
|
||||||
[
|
[
|
||||||
|
@ -221,9 +221,9 @@ class TestGui:
|
||||||
coretlv.session.add_node(_id=node_one)
|
coretlv.session.add_node(_id=node_one)
|
||||||
node_two = 2
|
node_two = 2
|
||||||
coretlv.session.add_node(_id=node_two)
|
coretlv.session.add_node(_id=node_two)
|
||||||
ip_prefix = Ipv4Prefix("10.0.0.0/24")
|
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||||
interface_one = ip_prefix.addr(node_one)
|
interface_one = str(ip_prefix[node_one])
|
||||||
interface_two = ip_prefix.addr(node_two)
|
interface_two = str(ip_prefix[node_two])
|
||||||
message = coreapi.CoreLinkMessage.create(
|
message = coreapi.CoreLinkMessage.create(
|
||||||
MessageFlags.ADD.value,
|
MessageFlags.ADD.value,
|
||||||
[
|
[
|
||||||
|
@ -265,8 +265,8 @@ class TestGui:
|
||||||
coretlv.session.add_node(_id=node_one)
|
coretlv.session.add_node(_id=node_one)
|
||||||
switch = 2
|
switch = 2
|
||||||
coretlv.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
|
coretlv.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
|
||||||
ip_prefix = Ipv4Prefix("10.0.0.0/24")
|
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||||
interface_one = ip_prefix.addr(node_one)
|
interface_one = str(ip_prefix[node_one])
|
||||||
message = coreapi.CoreLinkMessage.create(
|
message = coreapi.CoreLinkMessage.create(
|
||||||
MessageFlags.ADD.value,
|
MessageFlags.ADD.value,
|
||||||
[
|
[
|
||||||
|
@ -301,8 +301,8 @@ class TestGui:
|
||||||
coretlv.session.add_node(_id=node_one)
|
coretlv.session.add_node(_id=node_one)
|
||||||
switch = 2
|
switch = 2
|
||||||
coretlv.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
|
coretlv.session.add_node(_id=switch, _type=NodeTypes.SWITCH)
|
||||||
ip_prefix = Ipv4Prefix("10.0.0.0/24")
|
ip_prefix = netaddr.IPNetwork("10.0.0.0/24")
|
||||||
interface_one = ip_prefix.addr(node_one)
|
interface_one = str(ip_prefix[node_one])
|
||||||
message = coreapi.CoreLinkMessage.create(
|
message = coreapi.CoreLinkMessage.create(
|
||||||
MessageFlags.ADD.value,
|
MessageFlags.ADD.value,
|
||||||
[
|
[
|
||||||
|
|
|
@ -47,6 +47,54 @@ class TestNodes:
|
||||||
with pytest.raises(CoreError):
|
with pytest.raises(CoreError):
|
||||||
session.get_node(node.id)
|
session.get_node(node.id)
|
||||||
|
|
||||||
|
def test_node_sethwaddr(self, session):
|
||||||
|
# given
|
||||||
|
node = session.add_node()
|
||||||
|
index = node.newnetif()
|
||||||
|
interface = node.netif(index)
|
||||||
|
mac = "aa:aa:aa:ff:ff:ff"
|
||||||
|
|
||||||
|
# when
|
||||||
|
node.sethwaddr(index, mac)
|
||||||
|
|
||||||
|
# then
|
||||||
|
assert interface.hwaddr == mac
|
||||||
|
|
||||||
|
def test_node_sethwaddr_exception(self, session):
|
||||||
|
# given
|
||||||
|
node = session.add_node()
|
||||||
|
index = node.newnetif()
|
||||||
|
node.netif(index)
|
||||||
|
mac = "aa:aa:aa:ff:ff:fff"
|
||||||
|
|
||||||
|
# when
|
||||||
|
with pytest.raises(CoreError):
|
||||||
|
node.sethwaddr(index, mac)
|
||||||
|
|
||||||
|
def test_node_addaddr(self, session):
|
||||||
|
# given
|
||||||
|
node = session.add_node()
|
||||||
|
index = node.newnetif()
|
||||||
|
interface = node.netif(index)
|
||||||
|
addr = "192.168.0.1/24"
|
||||||
|
|
||||||
|
# when
|
||||||
|
node.addaddr(index, addr)
|
||||||
|
|
||||||
|
# then
|
||||||
|
assert interface.addrlist[0] == addr
|
||||||
|
|
||||||
|
def test_node_addaddr_exception(self, session):
|
||||||
|
# given
|
||||||
|
node = session.add_node()
|
||||||
|
index = node.newnetif()
|
||||||
|
node.netif(index)
|
||||||
|
addr = "256.168.0.1/24"
|
||||||
|
|
||||||
|
# when
|
||||||
|
with pytest.raises(CoreError):
|
||||||
|
node.addaddr(index, addr)
|
||||||
|
|
||||||
@pytest.mark.parametrize("net_type", NET_TYPES)
|
@pytest.mark.parametrize("net_type", NET_TYPES)
|
||||||
def test_net(self, session, net_type):
|
def test_net(self, session, net_type):
|
||||||
# given
|
# given
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
|
import netaddr
|
||||||
|
import pytest
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
|
from core.errors import CoreError
|
||||||
|
|
||||||
|
|
||||||
class TestUtils:
|
class TestUtils:
|
||||||
|
@ -20,3 +24,43 @@ class TestUtils:
|
||||||
assert len(one_arg) == 1
|
assert len(one_arg) == 1
|
||||||
assert len(two_args) == 2
|
assert len(two_args) == 2
|
||||||
assert len(unicode_args) == 3
|
assert len(unicode_args) == 3
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"data,expected",
|
||||||
|
[
|
||||||
|
("127", "127.0.0.0/32"),
|
||||||
|
("10.0.0.1/24", "10.0.0.1/24"),
|
||||||
|
("2001::", "2001::/128"),
|
||||||
|
("2001::/64", "2001::/64"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_validate_ip(self, data, expected):
|
||||||
|
value = utils.validate_ip(data)
|
||||||
|
assert value == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("data", ["256", "1270.0.0.1", "127.0.0.0.1"])
|
||||||
|
def test_validate_ip_exception(self, data):
|
||||||
|
with pytest.raises(CoreError):
|
||||||
|
utils.validate_ip("")
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"data,expected",
|
||||||
|
[
|
||||||
|
("AA-AA-AA-FF-FF-FF", "aa:aa:aa:ff:ff:ff"),
|
||||||
|
("AA:AA:AA:FF:FF:FF", "aa:aa:aa:ff:ff:ff"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_validate_mac(self, data, expected):
|
||||||
|
value = utils.validate_mac(data)
|
||||||
|
assert value == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"data", ["AAA:AA:AA:FF:FF:FF", "AA:AA:AA:FF:FF", "AA/AA/AA/FF/FF/FF"]
|
||||||
|
)
|
||||||
|
def test_validate_mac_exception(self, data):
|
||||||
|
with pytest.raises(CoreError):
|
||||||
|
utils.validate_mac(data)
|
||||||
|
|
||||||
|
def test_random_mac(self):
|
||||||
|
value = utils.random_mac()
|
||||||
|
assert netaddr.EUI(value) is not None
|
||||||
|
|
|
@ -8,13 +8,12 @@ import logging
|
||||||
import optparse
|
import optparse
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import netaddr
|
||||||
import ns.core
|
import ns.core
|
||||||
import ns.mobility
|
import ns.mobility
|
||||||
from corens3.obj import Ns3LteNet
|
from corens3.obj import Ns3LteNet
|
||||||
from corens3.obj import Ns3Session
|
from corens3.obj import Ns3Session
|
||||||
|
|
||||||
from core.nodes import ipaddress
|
|
||||||
|
|
||||||
|
|
||||||
def ltesession(opt):
|
def ltesession(opt):
|
||||||
"""
|
"""
|
||||||
|
@ -28,10 +27,10 @@ def ltesession(opt):
|
||||||
stream = ascii_helper.CreateFileStream('/tmp/ns3lte.tr')
|
stream = ascii_helper.CreateFileStream('/tmp/ns3lte.tr')
|
||||||
lte.lte.EnableAsciiAll(stream)
|
lte.lte.EnableAsciiAll(stream)
|
||||||
|
|
||||||
prefix = ipaddress.Ipv4Prefix("10.0.0.0/16")
|
prefix = netaddr.IPNetwork("10.0.0.0/16")
|
||||||
mobb = None
|
mobb = None
|
||||||
nodes = []
|
nodes = []
|
||||||
for i in xrange(1, opt.numnodes + 1):
|
for i in range(1, opt.numnodes + 1):
|
||||||
node = session.addnode(name="n%d" % i)
|
node = session.addnode(name="n%d" % i)
|
||||||
mob = ns.mobility.ConstantPositionMobilityModel()
|
mob = ns.mobility.ConstantPositionMobilityModel()
|
||||||
mob.SetPosition(ns.core.Vector3D(10.0 * i, 0.0, 0.0))
|
mob.SetPosition(ns.core.Vector3D(10.0 * i, 0.0, 0.0))
|
||||||
|
@ -39,7 +38,7 @@ def ltesession(opt):
|
||||||
# first node is nodeb
|
# first node is nodeb
|
||||||
lte.setnodeb(node)
|
lte.setnodeb(node)
|
||||||
mobb = mob
|
mobb = mob
|
||||||
node.newnetif(lte, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
|
node.newnetif(lte, ["%s/%s" % (prefix[i], prefix.prefixlen)])
|
||||||
nodes.append(node)
|
nodes.append(node)
|
||||||
if i == 1:
|
if i == 1:
|
||||||
_tmp, ns3dev = lte.findns3dev(node)
|
_tmp, ns3dev = lte.findns3dev(node)
|
||||||
|
|
|
@ -26,12 +26,11 @@ import logging
|
||||||
import optparse
|
import optparse
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import netaddr
|
||||||
import ns.core
|
import ns.core
|
||||||
from corens3.obj import Ns3Session
|
from corens3.obj import Ns3Session
|
||||||
from corens3.obj import Ns3WifiNet
|
from corens3.obj import Ns3WifiNet
|
||||||
|
|
||||||
from core.nodes import ipaddress
|
|
||||||
|
|
||||||
|
|
||||||
def add_to_server(session):
|
def add_to_server(session):
|
||||||
"""
|
"""
|
||||||
|
@ -60,11 +59,11 @@ def wifisession(opt):
|
||||||
wifi.setposition(30, 30, 0)
|
wifi.setposition(30, 30, 0)
|
||||||
wifi.phy.Set("RxGain", ns.core.DoubleValue(18.0))
|
wifi.phy.Set("RxGain", ns.core.DoubleValue(18.0))
|
||||||
|
|
||||||
prefix = ipaddress.Ipv4Prefix("10.0.0.0/16")
|
prefix = netaddr.IPNetwork("10.0.0.0/16")
|
||||||
nodes = []
|
nodes = []
|
||||||
for i in xrange(1, opt.numnodes + 1):
|
for i in range(1, opt.numnodes + 1):
|
||||||
node = session.addnode(name="n%d" % i)
|
node = session.addnode(name="n%d" % i)
|
||||||
node.newnetif(wifi, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
|
node.newnetif(wifi, ["%s/%s" % (prefix[i], prefix.prefixlen)])
|
||||||
nodes.append(node)
|
nodes.append(node)
|
||||||
session.setupconstantmobility()
|
session.setupconstantmobility()
|
||||||
wifi.usecorepositions()
|
wifi.usecorepositions()
|
||||||
|
|
|
@ -16,13 +16,12 @@ import optparse
|
||||||
import sys
|
import sys
|
||||||
from builtins import range
|
from builtins import range
|
||||||
|
|
||||||
|
import netaddr
|
||||||
import ns.core
|
import ns.core
|
||||||
import ns.network
|
import ns.network
|
||||||
from corens3.obj import Ns3Session
|
from corens3.obj import Ns3Session
|
||||||
from corens3.obj import Ns3WifiNet
|
from corens3.obj import Ns3WifiNet
|
||||||
|
|
||||||
from core.nodes import ipaddress
|
|
||||||
|
|
||||||
|
|
||||||
def add_to_server(session):
|
def add_to_server(session):
|
||||||
"""
|
"""
|
||||||
|
@ -51,12 +50,12 @@ def wifisession(opt):
|
||||||
# for improved connectivity
|
# for improved connectivity
|
||||||
wifi.phy.Set("RxGain", ns.core.DoubleValue(18.0))
|
wifi.phy.Set("RxGain", ns.core.DoubleValue(18.0))
|
||||||
|
|
||||||
prefix = ipaddress.Ipv4Prefix("10.0.0.0/16")
|
prefix = netaddr.IPNetwork("10.0.0.0/16")
|
||||||
services_str = "zebra|OSPFv3MDR|IPForward"
|
services_str = "zebra|OSPFv3MDR|IPForward"
|
||||||
nodes = []
|
nodes = []
|
||||||
for i in range(1, opt.numnodes + 1):
|
for i in range(1, opt.numnodes + 1):
|
||||||
node = session.addnode(name="n%d" % i)
|
node = session.addnode(name="n%d" % i)
|
||||||
node.newnetif(wifi, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
|
node.newnetif(wifi, ["%s/%s" % (prefix[i], prefix.prefixlen)])
|
||||||
nodes.append(node)
|
nodes.append(node)
|
||||||
session.services.add_services(node, "router", services_str.split("|"))
|
session.services.add_services(node, "router", services_str.split("|"))
|
||||||
session.services.boot_services(node)
|
session.services.boot_services(node)
|
||||||
|
|
|
@ -14,11 +14,10 @@ import optparse
|
||||||
import sys
|
import sys
|
||||||
from builtins import range
|
from builtins import range
|
||||||
|
|
||||||
|
import netaddr
|
||||||
from corens3.obj import Ns3Session
|
from corens3.obj import Ns3Session
|
||||||
from corens3.obj import Ns3WimaxNet
|
from corens3.obj import Ns3WimaxNet
|
||||||
|
|
||||||
from core.nodes import ipaddress
|
|
||||||
|
|
||||||
|
|
||||||
def wimaxsession(opt):
|
def wimaxsession(opt):
|
||||||
"""
|
"""
|
||||||
|
@ -28,7 +27,7 @@ def wimaxsession(opt):
|
||||||
wimax = session.create_node(cls=Ns3WimaxNet, name="wlan1")
|
wimax = session.create_node(cls=Ns3WimaxNet, name="wlan1")
|
||||||
# wimax.wimax.EnableLogComponents()
|
# wimax.wimax.EnableLogComponents()
|
||||||
|
|
||||||
prefix = ipaddress.Ipv4Prefix("10.0.0.0/16")
|
prefix = netaddr.IPNetwork("10.0.0.0/16")
|
||||||
# create one classifier for ICMP (protocol 1) traffic
|
# create one classifier for ICMP (protocol 1) traffic
|
||||||
# src port low/high, dst port low/high, protocol, priority
|
# src port low/high, dst port low/high, protocol, priority
|
||||||
# classifier = (0, 65000, 0, 65000, 1, 1)
|
# classifier = (0, 65000, 0, 65000, 1, 1)
|
||||||
|
@ -38,7 +37,7 @@ def wimaxsession(opt):
|
||||||
node = session.addnode(name="n%d" % i)
|
node = session.addnode(name="n%d" % i)
|
||||||
if i == 1:
|
if i == 1:
|
||||||
wimax.setbasestation(node)
|
wimax.setbasestation(node)
|
||||||
node.newnetif(wimax, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
|
node.newnetif(wimax, ["%s/%s" % (prefix[i], prefix.prefixlen)])
|
||||||
if i > 2:
|
if i > 2:
|
||||||
wimax.addflow(nodes[-1], node, classifier, classifier)
|
wimax.addflow(nodes[-1], node, classifier, classifier)
|
||||||
nodes.append(node)
|
nodes.append(node)
|
||||||
|
|
Loading…
Reference in a new issue