daemon: refactored CoreInterface.addrlist storing strings into CoreInterface.ip4s and ip6s, stored as netaddr.IPNetwork objects
This commit is contained in:
parent
ca2b1c9e4c
commit
d88f3a2535
20 changed files with 209 additions and 262 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ""
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue