daemon: refactored CoreInterface.addrlist storing strings into CoreInterface.ip4s and ip6s, stored as netaddr.IPNetwork objects

This commit is contained in:
Blake Harnden 2020-06-19 08:50:36 -07:00
parent ca2b1c9e4c
commit d88f3a2535
20 changed files with 209 additions and 262 deletions

View file

@ -3,7 +3,6 @@ import time
from typing import Any, Dict, List, Tuple, Type, Union
import grpc
import netaddr
from grpc import ServicerContext
from core import utils
@ -447,18 +446,16 @@ def iface_to_proto(iface: CoreInterface) -> core_pb2.Interface:
net_id = iface.net.id
ip4 = None
ip4_mask = None
ip4_net = iface.get_ip4()
if ip4_net:
ip4 = str(ip4_net.ip)
ip4_mask = ip4_net.prefixlen
ip6 = None
ip6_mask = None
for addr in iface.addrlist:
network = netaddr.IPNetwork(addr)
mask = network.prefixlen
ip = str(network.ip)
if netaddr.valid_ipv4(ip) and not ip4:
ip4 = ip
ip4_mask = mask
elif netaddr.valid_ipv6(ip) and not ip6:
ip6 = ip
ip6_mask = mask
ip6_net = iface.get_ip6()
if ip6_net:
ip6 = str(ip6_net.ip)
ip6_mask = ip6_net.prefixlen
return core_pb2.Interface(
id=iface.node_id,
net_id=net_id,

View file

@ -1,8 +1,6 @@
import abc
from typing import Any, Dict, List
import netaddr
from core import constants
from core.config import Configuration
from core.configservice.base import ConfigService, ConfigServiceMode
@ -49,10 +47,9 @@ def get_router_id(node: CoreNodeBase) -> str:
Helper to return the first IPv4 address of a node as its router ID.
"""
for iface in node.get_ifaces(control=False):
for a in iface.addrlist:
a = a.split("/")[0]
if netaddr.valid_ipv4(a):
return a
ip4 = iface.get_ip4()
if ip4:
return str(ip4.ip)
return "0.0.0.0"
@ -102,12 +99,10 @@ class FRRZebra(ConfigService):
for iface in self.node.get_ifaces():
ip4s = []
ip6s = []
for x in iface.addrlist:
addr = x.split("/")[0]
if netaddr.valid_ipv4(addr):
ip4s.append(x)
else:
ip6s.append(x)
for ip4 in iface.ip4s:
ip4s.append(str(ip4.ip))
for ip6 in iface.ip6s:
ip6s.append(str(ip6.ip))
is_control = getattr(iface, "control", False)
ifaces.append((iface, ip4s, ip6s, is_control))
@ -163,10 +158,8 @@ class FRROspfv2(FrrService, ConfigService):
router_id = get_router_id(self.node)
addresses = []
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)
for ip4 in iface.ip4s:
addresses.append(str(ip4.ip))
data = dict(router_id=router_id, addresses=addresses)
text = """
router ospf

View file

@ -1,7 +1,5 @@
from typing import Any, Dict, List
import netaddr
from core import utils
from core.config import Configuration
from core.configservice.base import ConfigService, ConfigServiceMode
@ -75,13 +73,10 @@ class NrlSmf(ConfigService):
ip4_prefix = None
for iface in self.node.get_ifaces(control=False):
ifnames.append(iface.name)
if ip4_prefix:
continue
for a in iface.addrlist:
a = a.split("/")[0]
if netaddr.valid_ipv4(a):
ip4_prefix = f"{a}/{24}"
break
ip4 = iface.get_ip4()
if ip4:
ip4_prefix = f"{ip4.ip}/{24}"
break
return dict(
has_arouted=has_arouted,
has_nhdp=has_nhdp,
@ -191,11 +186,8 @@ class Arouted(ConfigService):
def data(self) -> Dict[str, Any]:
ip4_prefix = None
for iface in self.node.get_ifaces(control=False):
if ip4_prefix:
continue
for a in iface.addrlist:
a = a.split("/")[0]
if netaddr.valid_ipv4(a):
ip4_prefix = f"{a}/{24}"
break
ip4 = iface.get_ip4()
if ip4:
ip4_prefix = f"{ip4.ip}/{24}"
break
return dict(ip4_prefix=ip4_prefix)

View file

@ -2,8 +2,6 @@ import abc
import logging
from typing import Any, Dict, List
import netaddr
from core import constants
from core.config import Configuration
from core.configservice.base import ConfigService, ConfigServiceMode
@ -50,10 +48,9 @@ def get_router_id(node: CoreNodeBase) -> str:
Helper to return the first IPv4 address of a node as its router ID.
"""
for iface in node.get_ifaces(control=False):
for a in iface.addrlist:
a = a.split("/")[0]
if netaddr.valid_ipv4(a):
return a
ip4 = iface.get_ip4()
if ip4:
return str(ip4.ip)
return "0.0.0.0"
@ -103,12 +100,10 @@ class Zebra(ConfigService):
for iface in self.node.get_ifaces():
ip4s = []
ip6s = []
for x in iface.addrlist:
addr = x.split("/")[0]
if netaddr.valid_ipv4(addr):
ip4s.append(x)
else:
ip6s.append(x)
for ip4 in iface.ip4s:
ip4s.append(str(ip4.ip))
for ip6 in iface.ip6s:
ip6s.append(str(ip6.ip))
is_control = getattr(iface, "control", False)
ifaces.append((iface, ip4s, ip6s, is_control))
@ -170,10 +165,8 @@ class Ospfv2(QuaggaService, ConfigService):
router_id = get_router_id(self.node)
addresses = []
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)
for ip4 in iface.ip4s:
addresses.append(str(ip4.ip))
data = dict(router_id=router_id, addresses=addresses)
text = """
router ospf

View file

@ -1,7 +1,5 @@
from typing import Any, Dict, List
import netaddr
from core.config import Configuration
from core.configservice.base import ConfigService, ConfigServiceMode
from core.emulator.enumerations import ConfigDataTypes
@ -79,10 +77,10 @@ class VpnServer(ConfigService):
def data(self) -> Dict[str, Any]:
address = None
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
ip4 = iface.get_ip4()
if ip4:
address = str(ip4.ip)
break
return dict(address=address)

View file

@ -29,8 +29,8 @@ class DefaultRouteService(ConfigService):
ifaces = self.node.get_ifaces()
if ifaces:
iface = ifaces[0]
for x in iface.addrlist:
net = netaddr.IPNetwork(x).cidr
for ip in iface.all_ips():
net = ip.cidr
if net.size > 1:
router = net[1]
routes.append(str(router))
@ -76,15 +76,14 @@ class StaticRouteService(ConfigService):
def data(self) -> Dict[str, Any]:
routes = []
for iface in self.node.get_ifaces(control=False):
for x in iface.addrlist:
addr = x.split("/")[0]
if netaddr.valid_ipv6(addr):
for ip in iface.all_ips():
address = str(ip.ip)
if netaddr.valid_ipv6(address):
dst = "3ffe:4::/64"
else:
dst = "10.9.8.0/24"
net = netaddr.IPNetwork(x)
if net[-2] != net[1]:
routes.append((dst, net[1]))
if ip[-2] != ip[1]:
routes.append((dst, ip[1]))
return dict(routes=routes)
@ -149,15 +148,12 @@ class DhcpService(ConfigService):
def data(self) -> Dict[str, Any]:
subnets = []
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)
# divide the address space in half
index = (net.size - 2) / 2
rangelow = net[index]
rangehigh = net[-2]
subnets.append((net.ip, net.netmask, rangelow, rangehigh, addr))
for ip4 in iface.ip4s:
# divide the address space in half
index = (ip4.size - 2) / 2
rangelow = ip4[index]
rangehigh = ip4[-2]
subnets.append((ip4.ip, ip4.netmask, rangelow, rangehigh, str(ip4.ip)))
return dict(subnets=subnets)
@ -238,10 +234,8 @@ class RadvdService(ConfigService):
ifaces = []
for iface in self.node.get_ifaces(control=False):
prefixes = []
for x in iface.addrlist:
addr = x.split("/")[0]
if netaddr.valid_ipv6(addr):
prefixes.append(x)
for ip6 in iface.ip6s:
prefixes.append(str(ip6))
if not prefixes:
continue
ifaces.append((iface.name, prefixes))

View file

@ -4,7 +4,6 @@ import threading
import time
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple
import netaddr
from lxml import etree
from core.emulator.data import LinkData
@ -214,13 +213,12 @@ class EmaneLinkMonitor:
for node in nodes:
for iface in node.get_ifaces():
if isinstance(iface.net, CtrlNet):
ip4 = None
for x in iface.addrlist:
address, prefix = x.split("/")
if netaddr.valid_ipv4(address):
ip4 = address
address = None
ip4 = iface.get_ip4()
if ip4:
addresses.append(ip4)
address = str(ip4.ip)
if address:
addresses.append(address)
break
return addresses

View file

@ -1548,9 +1548,8 @@ class Session:
entries = []
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}")
for ip in iface.all_ips():
entries.append(f"{ip.ip} {name}")
logging.info("Adding %d /etc/hosts file entries.", len(entries))
utils.file_munge("/etc/hosts", header, "\n".join(entries) + "\n")

View file

@ -1053,18 +1053,17 @@ class CoreNetworkBase(NodeBase):
if uni:
unidirectional = 1
iface2 = InterfaceData(
iface2_data = InterfaceData(
id=linked_node.get_iface_id(iface), name=iface.name, mac=iface.mac
)
for address in iface.addrlist:
ip, _sep, mask = address.partition("/")
mask = int(mask)
if netaddr.valid_ipv4(ip):
iface2.ip4 = ip
iface2.ip4_mask = mask
else:
iface2.ip6 = ip
iface2.ip6_mask = mask
ip4 = iface.get_ip4()
if ip4:
iface2_data.ip4 = str(ip4.ip)
iface2_data.ip4_mask = ip4.prefixlen
ip6 = iface.get_ip6()
if ip6:
iface2_data.ip6 = str(ip6.ip)
iface2_data.ip6_mask = ip6.prefixlen
options_data = iface.get_link_options(unidirectional)
link_data = LinkData(
@ -1072,7 +1071,7 @@ class CoreNetworkBase(NodeBase):
type=self.linktype,
node1_id=self.id,
node2_id=linked_node.id,
iface2=iface2,
iface2=iface2_data,
options=options_data,
)
all_links.append(link_data)

View file

@ -6,6 +6,8 @@ import logging
import time
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple
import netaddr
from core import utils
from core.emulator.data import LinkOptions
from core.emulator.enumerations import TransportType
@ -52,7 +54,8 @@ class CoreInterface:
self.net: Optional[CoreNetworkBase] = None
self.othernet: Optional[CoreNetworkBase] = None
self._params: Dict[str, float] = {}
self.addrlist: List[str] = []
self.ip4s: List[netaddr.IPNetwork] = []
self.ip6s: List[netaddr.IPNetwork] = []
self.mac: Optional[str] = None
# placeholder position hook
self.poshook: Callable[[CoreInterface], None] = lambda x: None
@ -131,15 +134,22 @@ class CoreInterface:
if self.net is not None:
self.net.detach(self)
def addaddr(self, addr: str) -> None:
def addaddr(self, address: str) -> None:
"""
Add address.
Add ip address in the format "10.0.0.1/24".
:param addr: address to add
:param address: address to add
:return: nothing
"""
addr = utils.validate_ip(addr)
self.addrlist.append(addr)
try:
ip = netaddr.IPNetwork(address)
value = str(ip.ip)
if netaddr.valid_ipv4(value):
self.ip4s.append(ip)
else:
self.ip6s.append(ip)
except netaddr.AddrFormatError:
raise CoreError(f"adding invalid address {address}")
def deladdr(self, addr: str) -> None:
"""
@ -148,7 +158,23 @@ class CoreInterface:
:param addr: address to delete
:return: nothing
"""
self.addrlist.remove(addr)
if netaddr.valid_ipv4(addr):
ip4 = netaddr.IPNetwork(addr)
self.ip4s.remove(ip4)
elif netaddr.valid_ipv6(addr):
ip6 = netaddr.IPNetwork(addr)
self.ip6s.remove(ip6)
else:
raise CoreError(f"deleting invalid address {addr}")
def get_ip4(self) -> Optional[netaddr.IPNetwork]:
return next(iter(self.ip4s), None)
def get_ip6(self) -> Optional[netaddr.IPNetwork]:
return next(iter(self.ip6s), None)
def all_ips(self) -> List[netaddr.IPNetwork]:
return self.ip4s + self.ip6s
def set_mac(self, mac: str) -> None:
"""
@ -487,13 +513,13 @@ class TunTap(CoreInterface):
def setaddrs(self) -> None:
"""
Set interface addresses based on self.addrlist.
Set interface addresses.
:return: nothing
"""
self.waitfordevicenode()
for addr in self.addrlist:
self.node.node_net_client.create_address(self.name, str(addr))
for ip in self.all_ips():
self.node.node_net_client.create_address(self.name, str(ip))
class GreTap(CoreInterface):

View file

@ -881,28 +881,26 @@ class PtpNet(CoreNetwork):
iface1_data = InterfaceData(
id=iface1.node.get_iface_id(iface1), name=iface1.name, mac=iface1.mac
)
for address in iface1.addrlist:
ip, _sep, mask = address.partition("/")
mask = int(mask)
if netaddr.valid_ipv4(ip):
iface1.ip4 = ip
iface1.ip4_mask = mask
else:
iface1.ip6 = ip
iface1.ip6_mask = mask
ip4 = iface1.get_ip4()
if ip4:
iface1_data.ip4 = str(ip4.ip)
iface1_data.ip4_mask = ip4.prefixlen
ip6 = iface1.get_ip6()
if ip6:
iface1_data.ip6 = str(ip6.ip)
iface1_data.ip6_mask = ip6.prefixlen
iface2_data = InterfaceData(
id=iface2.node.get_iface_id(iface2), name=iface2.name, mac=iface2.mac
)
for address in iface2.addrlist:
ip, _sep, mask = address.partition("/")
mask = int(mask)
if netaddr.valid_ipv4(ip):
iface2.ip4 = ip
iface2.ip4_mask = mask
else:
iface2.ip6 = ip
iface2.ip6_mask = mask
ip4 = iface2.get_ip4()
if ip4:
iface2_data.ip4 = str(ip4.ip)
iface2_data.ip4_mask = ip4.prefixlen
ip6 = iface2.get_ip6()
if ip6:
iface2_data.ip6 = str(ip6.ip)
iface2_data.ip6_mask = ip6.prefixlen
options_data = iface1.get_link_options(unidirectional)
link_data = LinkData(

View file

@ -3,8 +3,6 @@ bird.py: defines routing services provided by the BIRD Internet Routing Daemon.
"""
from typing import Optional, Tuple
import netaddr
from core.nodes.base import CoreNode
from core.services.coreservices import CoreService
@ -39,10 +37,9 @@ class Bird(CoreService):
Helper to return the first IPv4 address of a node as its router ID.
"""
for iface in node.get_ifaces(control=False):
for a in iface.addrlist:
a = a.split("/")[0]
if netaddr.valid_ipv4(a):
return a
ip4 = iface.get_ip4()
if ip4:
return str(ip4.ip)
return "0.0.0.0"
@classmethod

View file

@ -67,7 +67,7 @@ class FRRZebra(CoreService):
# include control interfaces in addressing but not routing daemons
if hasattr(iface, "control") and iface.control is True:
cfg += " "
cfg += "\n ".join(map(cls.addrstr, iface.addrlist))
cfg += "\n ".join(map(cls.addrstr, iface.all_ips()))
cfg += "\n"
continue
cfgv4 = ""
@ -87,19 +87,13 @@ class FRRZebra(CoreService):
cfgv4 += iface_config
if want_ipv4:
ipv4list = filter(
lambda x: netaddr.valid_ipv4(x.split("/")[0]), iface.addrlist
)
cfg += " "
cfg += "\n ".join(map(cls.addrstr, ipv4list))
cfg += "\n ".join(map(cls.addrstr, iface.ip4s))
cfg += "\n"
cfg += cfgv4
if want_ipv6:
ipv6list = filter(
lambda x: netaddr.valid_ipv6(x.split("/")[0]), iface.addrlist
)
cfg += " "
cfg += "\n ".join(map(cls.addrstr, ipv6list))
cfg += "\n ".join(map(cls.addrstr, iface.ip6s))
cfg += "\n"
cfg += cfgv6
cfg += "!\n"
@ -111,17 +105,17 @@ class FRRZebra(CoreService):
return cfg
@staticmethod
def addrstr(x: str) -> str:
def addrstr(ip: netaddr.IPNetwork) -> str:
"""
helper for mapping IP addresses to zebra config statements
"""
addr = x.split("/")[0]
if netaddr.valid_ipv4(addr):
return "ip address %s" % x
elif netaddr.valid_ipv6(addr):
return "ipv6 address %s" % x
address = str(ip.ip)
if netaddr.valid_ipv4(address):
return "ip address %s" % ip
elif netaddr.valid_ipv6(address):
return "ipv6 address %s" % ip
else:
raise ValueError("invalid address: %s", x)
raise ValueError("invalid address: %s", ip)
@classmethod
def generate_frr_boot(cls, node: CoreNode) -> str:
@ -333,10 +327,9 @@ class FrrService(CoreService):
Helper to return the first IPv4 address of a node as its router ID.
"""
for iface in node.get_ifaces(control=False):
for a in iface.addrlist:
a = a.split("/")[0]
if netaddr.valid_ipv4(a):
return a
ip4 = iface.get_ip4()
if ip4:
return str(ip4.ip)
return "0.0.0.0"
@staticmethod
@ -413,11 +406,8 @@ class FRROspfv2(FrrService):
cfg += " router-id %s\n" % rtrid
# network 10.0.0.0/24 area 0
for iface in node.get_ifaces(control=False):
for a in iface.addrlist:
addr = a.split("/")[0]
if not netaddr.valid_ipv4(addr):
continue
cfg += " network %s area 0\n" % a
for ip4 in iface.ip4s:
cfg += f" network {ip4} area 0\n"
cfg += "!\n"
return cfg

View file

@ -4,8 +4,6 @@ nrl.py: defines services provided by NRL protolib tools hosted here:
"""
from typing import Optional, Tuple
import netaddr
from core import utils
from core.nodes.base import CoreNode
from core.services.coreservices import CoreService
@ -32,10 +30,9 @@ class NrlService(CoreService):
interface's prefix length, so e.g. '/32' can turn into '/24'.
"""
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}"
ip4 = iface.get_ip4()
if ip4:
return f"{ip4.ip}/{prefixlen}"
return "0.0.0.0/%s" % prefixlen

View file

@ -64,7 +64,7 @@ class Zebra(CoreService):
# include control interfaces in addressing but not routing daemons
if getattr(iface, "control", False):
cfg += " "
cfg += "\n ".join(map(cls.addrstr, iface.addrlist))
cfg += "\n ".join(map(cls.addrstr, iface.all_ips()))
cfg += "\n"
continue
cfgv4 = ""
@ -86,19 +86,13 @@ class Zebra(CoreService):
cfgv4 += iface_config
if want_ipv4:
ipv4list = filter(
lambda x: netaddr.valid_ipv4(x.split("/")[0]), iface.addrlist
)
cfg += " "
cfg += "\n ".join(map(cls.addrstr, ipv4list))
cfg += "\n ".join(map(cls.addrstr, iface.ip4s))
cfg += "\n"
cfg += cfgv4
if want_ipv6:
ipv6list = filter(
lambda x: netaddr.valid_ipv6(x.split("/")[0]), iface.addrlist
)
cfg += " "
cfg += "\n ".join(map(cls.addrstr, ipv6list))
cfg += "\n ".join(map(cls.addrstr, iface.ip6s))
cfg += "\n"
cfg += cfgv6
cfg += "!\n"
@ -112,17 +106,17 @@ class Zebra(CoreService):
return cfg
@staticmethod
def addrstr(x: str) -> str:
def addrstr(ip: netaddr.IPNetwork) -> str:
"""
helper for mapping IP addresses to zebra config statements
"""
addr = x.split("/")[0]
if netaddr.valid_ipv4(addr):
return "ip address %s" % x
elif netaddr.valid_ipv6(addr):
return "ipv6 address %s" % x
address = str(ip.ip)
if netaddr.valid_ipv4(address):
return "ip address %s" % ip
elif netaddr.valid_ipv6(address):
return "ipv6 address %s" % ip
else:
raise ValueError("invalid address: %s", x)
raise ValueError("invalid address: %s", ip)
@classmethod
def generate_quagga_boot(cls, node: CoreNode) -> str:
@ -255,10 +249,9 @@ class QuaggaService(CoreService):
Helper to return the first IPv4 address of a node as its router ID.
"""
for iface in node.get_ifaces(control=False):
for a in iface.addrlist:
a = a.split("/")[0]
if netaddr.valid_ipv4(a):
return a
ip4 = iface.get_ip4()
if ip4:
return str(ip4.ip)
return f"0.0.0.{node.id:d}"
@staticmethod
@ -335,10 +328,8 @@ class Ospfv2(QuaggaService):
cfg += " router-id %s\n" % rtrid
# network 10.0.0.0/24 area 0
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
for ip4 in iface.ip4s:
cfg += f" network {ip4} area 0\n"
cfg += "!\n"
return cfg

View file

@ -5,8 +5,6 @@ sdn.py defines services to start Open vSwitch and the Ryu SDN Controller.
import re
from typing import Tuple
import netaddr
from core.nodes.base import CoreNode
from core.services.coreservices import CoreService
@ -65,18 +63,14 @@ 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 addr in iface.addrlist:
addr = addr.split("/")[0]
if netaddr.valid_ipv4(addr):
cfg += "ip addr del %s dev %s\n" % (addr, iface.name)
if has_zebra == 0:
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" % (addr, iface.name)
if has_zebra == 0:
cfg += "ip -6 addr add %s dev rtr%s\n" % (addr, ifnum)
else:
raise ValueError("invalid address: %s" % addr)
for ip4 in iface.ip4s:
cfg += "ip addr del %s dev %s\n" % (ip4.ip, iface.name)
if has_zebra == 0:
cfg += "ip addr add %s dev rtr%s\n" % (ip4.ip, ifnum)
for ip6 in iface.ip6s:
cfg += "ip -6 addr del %s dev %s\n" % (ip6.ip, iface.name)
if has_zebra == 0:
cfg += "ip -6 addr add %s dev rtr%s\n" % (ip6.ip, ifnum)
# add interfaces to bridge
# Make port numbers explicit so they're easier to follow in reading the script

View file

@ -74,8 +74,8 @@ class DefaultRouteService(UtilService):
ifaces = node.get_ifaces()
if ifaces:
iface = ifaces[0]
for x in iface.addrlist:
net = netaddr.IPNetwork(x).cidr
for ip in iface.all_ips():
net = ip.cidr
if net.size > 1:
router = net[1]
routes.append(str(router))
@ -118,23 +118,22 @@ class StaticRouteService(UtilService):
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 iface in node.get_ifaces(control=False):
cfg += "\n".join(map(cls.routestr, iface.addrlist))
cfg += "\n".join(map(cls.routestr, iface.all_ips()))
cfg += "\n"
return cfg
@staticmethod
def routestr(x: str) -> str:
addr = x.split("/")[0]
if netaddr.valid_ipv6(addr):
def routestr(ip: netaddr.IPNetwork) -> str:
address = str(ip.ip)
if netaddr.valid_ipv6(address):
dst = "3ffe:4::/64"
else:
dst = "10.9.8.0/24"
net = netaddr.IPNetwork(x)
if net[-2] == net[1]:
if ip[-2] == ip[1]:
return ""
else:
rtcmd = "#/sbin/ip route add %s via" % dst
return "%s %s" % (rtcmd, net[1])
return "%s %s" % (rtcmd, ip[1])
class SshService(UtilService):
@ -242,25 +241,24 @@ max-lease-time 7200;
ddns-update-style none;
"""
for iface in node.get_ifaces(control=False):
cfg += "\n".join(map(cls.subnetentry, iface.addrlist))
cfg += "\n".join(map(cls.subnetentry, iface.all_ips()))
cfg += "\n"
return cfg
@staticmethod
def subnetentry(x: str) -> str:
def subnetentry(ip: netaddr.IPNetwork) -> str:
"""
Generate a subnet declaration block given an IPv4 prefix string
for inclusion in the dhcpd3 config file.
"""
addr = x.split("/")[0]
if netaddr.valid_ipv6(addr):
address = str(ip.ip)
if netaddr.valid_ipv6(address):
return ""
else:
net = netaddr.IPNetwork(x)
# divide the address space in half
index = (net.size - 2) / 2
rangelow = net[index]
rangehigh = net[-2]
index = (ip.size - 2) / 2
rangelow = ip[index]
rangehigh = ip[-2]
return """
subnet %s netmask %s {
pool {
@ -270,11 +268,11 @@ subnet %s netmask %s {
}
}
""" % (
net.ip,
net.netmask,
ip.ip,
ip.netmask,
rangelow,
rangehigh,
addr,
address,
)
@ -557,7 +555,10 @@ export LANG
% node.name
)
for iface in node.get_ifaces(control=False):
body += "<li>%s - %s</li>\n" % (iface.name, iface.addrlist)
body += "<li>%s - %s</li>\n" % (
iface.name,
[str(x) for x in iface.all_ips()],
)
return "<html><body>%s</body></html>" % body
@ -625,7 +626,7 @@ class RadvdService(UtilService):
"""
cfg = "# auto-generated by RADVD service (utility.py)\n"
for iface in node.get_ifaces(control=False):
prefixes = list(map(cls.subnetentry, iface.addrlist))
prefixes = list(map(cls.subnetentry, iface.all_ips()))
if len(prefixes) < 1:
continue
cfg += (
@ -658,14 +659,14 @@ interface %s
return cfg
@staticmethod
def subnetentry(x: str) -> str:
def subnetentry(ip: netaddr.IPNetwork) -> str:
"""
Generate a subnet declaration block given an IPv6 prefix string
for inclusion in the RADVD config file.
"""
addr = x.split("/")[0]
if netaddr.valid_ipv6(addr):
return x
address = str(ip.ip)
if netaddr.valid_ipv6(address):
return str(ip)
else:
return ""

View file

@ -40,7 +40,7 @@ class XorpRtrmgr(CoreService):
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 += "".join(map(cls.addrstr, iface.all_ips()))
cfg += cls.lladdrstr(iface)
cfg += "\t}\n"
cfg += " }\n"
@ -55,13 +55,12 @@ class XorpRtrmgr(CoreService):
return cfg
@staticmethod
def addrstr(x: str) -> str:
def addrstr(ip: netaddr.IPNetwork) -> str:
"""
helper for mapping IP addresses to XORP config statements
"""
addr, plen = x.split("/")
cfg = "\t address %s {\n" % addr
cfg += "\t\tprefix-length: %s\n" % plen
cfg = "\t address %s {\n" % ip.ip
cfg += "\t\tprefix-length: %s\n" % ip.prefixlen
cfg += "\t }\n"
return cfg
@ -145,10 +144,9 @@ class XorpService(CoreService):
Helper to return the first IPv4 address of a node as its router ID.
"""
for iface in node.get_ifaces(control=False):
for a in iface.addrlist:
a = a.split("/")[0]
if netaddr.valid_ipv4(a):
return a
ip4 = iface.get_ip4()
if ip4:
return str(ip4.ip)
return "0.0.0.0"
@classmethod
@ -180,11 +178,8 @@ class XorpOspfv2(XorpService):
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
cfg += "\t\t address %s {\n" % addr
for ip4 in iface.ip4s:
cfg += "\t\t address %s {\n" % ip4.ip
cfg += "\t\t }\n"
cfg += "\t\t}\n"
cfg += "\t }\n"
@ -269,11 +264,8 @@ class XorpRip(XorpService):
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
cfg += "\t\taddress %s {\n" % addr
for ip4 in iface.ip4s:
cfg += "\t\taddress %s {\n" % ip4.ip
cfg += "\t\t disable: false\n"
cfg += "\t\t}\n"
cfg += "\t }\n"
@ -435,11 +427,8 @@ class XorpOlsr(XorpService):
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
cfg += "\t\taddress %s {\n" % addr
for ip4 in iface.ip4s:
cfg += "\t\taddress %s {\n" % ip4.ip
cfg += "\t\t}\n"
cfg += "\t }\n"
cfg += "\t}\n"

View file

@ -164,6 +164,7 @@ class CoreXmlDeployment:
if emane_element is not None:
parent_element = emane_element
for address in iface.addrlist:
for ip in iface.all_ips():
address = str(ip.ip)
address_type = get_address_type(address)
add_address(parent_element, address_type, address, iface.name)

View file

@ -87,7 +87,7 @@ class TestNodes:
node.addaddr(iface.node_id, addr)
# then
assert iface.addrlist[0] == addr
assert str(iface.get_ip4()) == addr
def test_node_addaddr_exception(self, session):
# given