okay. let's give this a shot.
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import ipaddress
|
||||
import socket
|
||||
##
|
||||
import netaddr
|
||||
from pyroute2 import IPRoute
|
||||
##
|
||||
from . import utils
|
||||
from . import ra
|
||||
from . import utils
|
||||
|
||||
|
||||
class IP(object):
|
||||
@@ -51,14 +52,28 @@ class IP6(IP):
|
||||
|
||||
|
||||
class Assignment(object):
|
||||
def __init__(self, assign_xml, ra = False, dns = False, ra_provider = 'dnsmasq'):
|
||||
def __init__(self,
|
||||
assign_xml,
|
||||
ra_dns = False,
|
||||
ra_dhcp = False,
|
||||
ra_other = False,
|
||||
ra_tag = None,
|
||||
ra_domains = None):
|
||||
self.xml = assign_xml
|
||||
self.ra = ra
|
||||
self.dns = dns
|
||||
self.ra_dns = ra_dns
|
||||
self.ra_tag = ra_tag
|
||||
self.ra_other = ra_other
|
||||
self.ra_domains = set()
|
||||
if isinstance(ra_domains, list):
|
||||
self.ra_domains.update(ra_domains)
|
||||
elif isinstance(ra_domains, str):
|
||||
self.ra_domains.update([i.lower().strip() for i in ra_domains if i.strip() != ''])
|
||||
self.ra_dhcp = ra_dhcp
|
||||
self.iface = None
|
||||
self.iface_ll = None
|
||||
self.iface_idx = None
|
||||
self.iface_addrs = []
|
||||
self.iface_blocks = []
|
||||
self.dhcp6_ranges = []
|
||||
self.alloc = None # This must be set externally to a mapped Allocation instance
|
||||
self.alloc_id = None
|
||||
self.prefix = None
|
||||
@@ -74,6 +89,16 @@ class Assignment(object):
|
||||
self.iface = _iface_txt.strip()
|
||||
ipr = IPRoute()
|
||||
self.iface_idx = ipr.link_lookup(ifname = self.iface)[0]
|
||||
# Link-Local address
|
||||
ll = ipr.get_addr(index = self.iface_idx,
|
||||
family = socket.AF_INET6,
|
||||
scope = 253)[0]['attrs']
|
||||
addrs = dict(ll)['IFA_ADDRESS']
|
||||
if isinstance(addrs, (list, tuple)):
|
||||
addr = addrs[0]
|
||||
else:
|
||||
addr = addrs
|
||||
self.iface_ll = addr
|
||||
ipr.close()
|
||||
return(None)
|
||||
|
||||
@@ -92,7 +117,11 @@ class Assignment(object):
|
||||
# NOT AN IP6 OBJECT!
|
||||
self.iface_blocks = self.alloc_block.extract_subnet(self.prefix, count = 1)
|
||||
for i in self.iface_blocks:
|
||||
self.iface_addrs.append(IP6(str(next(i.iter_hosts())), 128))
|
||||
# DHCPv6 range.
|
||||
_base = str(i.ip).rstrip(':')
|
||||
start = '{0}:dead:beef:cafe:0'.format(_base)
|
||||
stop = '{0}:dead:beef:cafe:ffff'.format(_base)
|
||||
self.dhcp6_ranges.append((start, stop))
|
||||
return(None)
|
||||
|
||||
|
||||
@@ -114,11 +143,8 @@ class Tunnel(object):
|
||||
self.client = None
|
||||
self.server = None
|
||||
self.endpoint = None
|
||||
self.ra = False
|
||||
self.ra_provider = None
|
||||
self.ra_dns = False
|
||||
self.ra_dhcp = False
|
||||
self.allocations = {} # This is a dict of {}[alloc.id] = Allocation obj
|
||||
self.allocations = {} # This is a dict of {}[alloc.id] = Allocation obj (as provided by HE)
|
||||
self.assignments = [] # This is a list of Assignment objs
|
||||
self.parse()
|
||||
|
||||
@@ -128,11 +154,27 @@ class Tunnel(object):
|
||||
|
||||
def _assignments(self):
|
||||
_assigns_xml = self.xml.find('assignments')
|
||||
|
||||
self.enable_ra = utils.xml2bool(_assigns_xml.attrib.get('radvd', 'false'))
|
||||
self.ra_dns = utils.xml2bool(_assigns_xml.attrib.get('radvdDns', 'false'))
|
||||
self.ra_provider = _assigns_xml.attrib.get('raProvider')
|
||||
for _assign_xml in _assigns_xml.findall('assign'):
|
||||
assign = Assignment(_assign_xml, ra = self.enable_ra, dns = self.ra_dns)
|
||||
do_dns = False
|
||||
domains = []
|
||||
do_dhcp = False
|
||||
ra_other = False
|
||||
tag = _assign_xml.attrib.get('tag', None)
|
||||
dns = _assign_xml.find('dns')
|
||||
if dns and self.ra_provider:
|
||||
do_dns = utils.xml2bool(dns.text.strip())
|
||||
domains = [i.strip() for i in dns.attrib.get('domains', '').split() if i.strip() != '']
|
||||
dhcp = _assign_xml.find('dhcpv6')
|
||||
if dhcp and self.ra_provider:
|
||||
do_dhcp = utils.xml2bool(dhcp.text.strip())
|
||||
ra_other = utils.xml2bool(dhcp.attrib.get('advOther', 'false').strip())
|
||||
assign = Assignment(_assign_xml,
|
||||
ra_dns = do_dns,
|
||||
ra_dhcp = do_dhcp,
|
||||
ra_other = ra_other,
|
||||
ra_tag = tag,
|
||||
ra_domains = domains)
|
||||
assign.alloc = self.allocations[assign.alloc_id]
|
||||
assign.parse_alloc()
|
||||
self.assignments.append(assign)
|
||||
@@ -154,9 +196,13 @@ class Tunnel(object):
|
||||
self.id = int(self.xml.attrib['id'].strip())
|
||||
return(None)
|
||||
|
||||
def _radvd(self):
|
||||
|
||||
self.radvd.conf.generate(self.assignments)
|
||||
def _ra(self):
|
||||
# TODO: support conf path override via config XML?
|
||||
if self.ra_provider.strip().lower() == 'dnsmasq':
|
||||
self.ra = ra.DNSMasq()
|
||||
elif self.ra_provider.strip().lower() == 'radvd':
|
||||
self.ra = ra.RADVD()
|
||||
self.ra.conf.generate(self.assignments)
|
||||
return(None)
|
||||
|
||||
def _server(self):
|
||||
@@ -171,5 +217,5 @@ class Tunnel(object):
|
||||
self._endpoint()
|
||||
self._allocations()
|
||||
self._assignments()
|
||||
self._radvd()
|
||||
self._ra()
|
||||
return(None)
|
||||
|
||||
Reference in New Issue
Block a user