okay. let's give this a shot.
This commit is contained in:
parent
4df9287abd
commit
80765e58ed
@ -1,4 +1,3 @@
|
|||||||
* fix creds
|
DHCPv6:
|
||||||
** needs user/password, and the updateKey is unique per-tunnel so move it into an element in there.
|
* NTP server in <ra>? (dnsmasq: option6:ntpserver,...)
|
||||||
** need to get user/password into HEConf somehow. if i can get ?tid= working for the URL, that'd be perfect.
|
* bootfile-(url|param) in <ra>? (dnsmasq: option6:*)
|
||||||
^ need to use updateKey for tunnel-specific xml
|
|
||||||
|
@ -233,6 +233,12 @@ class Config(BaseConfig):
|
|||||||
tun_creds_id = tun_xml.attrib['creds']
|
tun_creds_id = tun_xml.attrib['creds']
|
||||||
creds = self.creds[tun_creds_id]
|
creds = self.creds[tun_creds_id]
|
||||||
update_key = tun_xml.find('updateKey').text.strip()
|
update_key = tun_xml.find('updateKey').text.strip()
|
||||||
|
# TODO: do I instead want to use HEConfig() and fetch the single unified config?
|
||||||
|
# Pros:
|
||||||
|
# * I wouldn't completely die on a misconfigured tunnel in the user config.
|
||||||
|
# Cons:
|
||||||
|
# * We'd have to skip missing tunnels (bad auth at HE, etc.)
|
||||||
|
# * We would use more memory and take more time during init.
|
||||||
he_conf = HETunnelConfig(tun_id, creds, update_key)
|
he_conf = HETunnelConfig(tun_id, creds, update_key)
|
||||||
tun = tunnel.Tunnel(tun_xml, he_conf, self.creds[tun_creds_id])
|
tun = tunnel.Tunnel(tun_xml, he_conf, self.creds[tun_creds_id])
|
||||||
self.tunnels[tun_id] = tun
|
self.tunnels[tun_id] = tun
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
the "ra" child element under <assign> for further details.
|
the "ra" child element under <assign> for further details.
|
||||||
If you are using dnsmasq, you will want to edit dnsmasq.conf to *include* the generated file, most likely, as it
|
If you are using dnsmasq, you will want to edit dnsmasq.conf to *include* the generated file, most likely, as it
|
||||||
only generates configuration for IPv6 options.
|
only generates configuration for IPv6 options.
|
||||||
|
If this is not specified, NO RA/DHCPv6 management will be done *regardless* of any "re" child elements for below
|
||||||
|
"assign" objects.
|
||||||
-->
|
-->
|
||||||
<assignments raProvider="dnsmasq">
|
<assignments raProvider="dnsmasq">
|
||||||
<!--
|
<!--
|
||||||
@ -76,27 +78,50 @@
|
|||||||
resolver via RDNSS.
|
resolver via RDNSS.
|
||||||
It takes one (optional) attribute, "domains", which is a space-separated list of search domains, referred
|
It takes one (optional) attribute, "domains", which is a space-separated list of search domains, referred
|
||||||
to in IPv6 as DNSSL (RFC 6106).
|
to in IPv6 as DNSSL (RFC 6106).
|
||||||
Note that Windows does not support DNSSL, and as such you must use dhcpv6's "domains" attribute if you wish
|
Note that Windows does not support DNSSL properly, and as such you must use dnsmasq as your RA provider if
|
||||||
to do that.
|
you wish to send search domains.
|
||||||
If "domains" is specified but the element is false, the configuration will only advertise DNSSL and not
|
If "domains" is specified but the element is false, the configuration will only advertise DNSSL and not
|
||||||
RDNSS.
|
RDNSS.
|
||||||
|
If you also specify dhcpv6 below and are using dnsmasq as your raProvider, then:
|
||||||
|
* the same domains will be sent via DHCPv6 option 24
|
||||||
|
* the same RDNSS resolver will be passed via DHCPv6 option 23
|
||||||
-->
|
-->
|
||||||
<dns domains="foo.com bar.com">true</dns>
|
<dns domains="foo.com bar.com">true</dns>
|
||||||
<!--
|
<!--
|
||||||
Enable DHCPv6 for this assignment. Only used for dnsmasq, has no effect for radvd. As mentioned above, you
|
Enable DHCPv6 for this assignment.
|
||||||
can also specify the "domains" attribute here as well, which will pass them via a regular DHCPv6 option.
|
|
||||||
If "domains" is specified but the element is false, only the domains will be passed.
|
RADVD:
|
||||||
Again, this only pertains to dnsmasq since radvd offers no DHCPv6 capabilities whatsoever.
|
If you're using radvd, this will only enable the "AdvManagedFlag" and/or "AdvOtherConfigFlag" flags
|
||||||
|
(the "MO" bits). *No actual DHCPv6 address assignment will, or can, occur via radvd, only SLAAC.*
|
||||||
|
|
||||||
|
DNSMASQ:
|
||||||
|
To ensure maximum compatability with SLAAC, addresses will be served in the fixed range of:
|
||||||
|
<PREFIX>:dead:beef:cafe:[0000-FFFF]
|
||||||
|
(65535 addresses per prefix assignment, a.k.a. a /112).
|
||||||
|
Obviously your assignment's prefix length *must* be smaller than /112 (but should be at LEAST a /64 anyways
|
||||||
|
per RFC specification). Regardless of settings below, SLAAC *will* be offered if an "ra" element is defined.
|
||||||
|
|
||||||
|
It has an optional attribute, "advOther", which controls the "Other Configuration" bit.
|
||||||
|
The default is "false".
|
||||||
|
The "MO" bits (RFC 4861 § 4.2) are set accordingly:
|
||||||
|
===================================================================================================
|
||||||
|
| Condition | M | O | Will addresses be assigned via DHCPv6 (if dnsmasq)? |
|
||||||
|
===================================================================================================
|
||||||
|
| advOther="true", dhcpv6 is true | 1 | 1 | Yes |
|
||||||
|
| advOther="true", dhcpv6 is false | 0 | 1 | No |
|
||||||
|
| advOther="false", dhcpv6 is false | 0 | 0 | No |
|
||||||
|
| advOther="false", dhcpv6 is true | 1 | 0 | Yes |
|
||||||
|
===================================================================================================
|
||||||
-->
|
-->
|
||||||
<dhcpv6 domains="foo.com bar.com">true</dhcpv6>
|
<dhcpv6 advOther="true">true</dhcpv6>
|
||||||
</ra>
|
</ra>
|
||||||
</assign>
|
</assign>
|
||||||
<!-- Disable RA for this set (no "ra" chiled specified). -->
|
<!-- Disable RA for this set (no "ra" child specified). -->
|
||||||
<assign prefix="64" alloc="48" iface="eth0"/>
|
<assign prefix="64" alloc="48" iface="eth0"/>
|
||||||
<assign prefix="64" alloc="48" iface="eth1">
|
<assign prefix="64" alloc="48" iface="eth1">
|
||||||
<ra tag="vmlan">
|
<ra tag="vmlan">
|
||||||
<!-- This will use strictly SLAAC (if using dnsmasq, obviously - radvd only does SLAAC). -->
|
<!-- This will use strictly SLAAC (if using dnsmasq, obviously - radvd only does SLAAC). -->
|
||||||
<dhcpv6>false</dhcpv6>
|
<dhcpv6 advOther="false">false</dhcpv6>
|
||||||
<!-- And let clients choose their own resolver. -->
|
<!-- And let clients choose their own resolver. -->
|
||||||
<dns>false</dns>
|
<dns>false</dns>
|
||||||
</ra>
|
</ra>
|
||||||
@ -105,7 +130,7 @@
|
|||||||
<ra tag="wlan">
|
<ra tag="wlan">
|
||||||
<!-- Only pass RDNSS resolvers. -->
|
<!-- Only pass RDNSS resolvers. -->
|
||||||
<dns>true</dns>
|
<dns>true</dns>
|
||||||
<dhcpv6>false</dhcpv6>
|
<dhcpv6 advOther="false">false</dhcpv6>
|
||||||
</ra>
|
</ra>
|
||||||
</assign>
|
</assign>
|
||||||
</assignments>
|
</assignments>
|
||||||
@ -116,7 +141,8 @@
|
|||||||
<assignments>
|
<assignments>
|
||||||
<!--
|
<!--
|
||||||
Uses the default prefix of /64 from your standard /64 allocation from Hurricane Electric.
|
Uses the default prefix of /64 from your standard /64 allocation from Hurricane Electric.
|
||||||
Most users probably want this unless they're running an IPv6 router.
|
Most users probably want this if they just want IPv6 for their local computer unless they're running an IPv6
|
||||||
|
router.
|
||||||
-->
|
-->
|
||||||
<assign iface="eth0"/>
|
<assign iface="eth0"/>
|
||||||
</assignments>
|
</assignments>
|
||||||
|
@ -43,14 +43,8 @@ class RAConf(object):
|
|||||||
return(None)
|
return(None)
|
||||||
|
|
||||||
def generate(self, assignments):
|
def generate(self, assignments):
|
||||||
ns = {}
|
self.cfgstr = self.tpl.render(assignments = assignments)
|
||||||
for a in assignments:
|
return(None)
|
||||||
if len(a.iface_addrs) > 3:
|
|
||||||
ns_addrs = a.iface_addrs[:3]
|
|
||||||
else:
|
|
||||||
ns_addrs = a.iface_addrs
|
|
||||||
ns[a.iface] = ns_addrs
|
|
||||||
self.cfgstr = self.tpl.render(assignments = assignments, nameservers = ns)
|
|
||||||
|
|
||||||
def write(self):
|
def write(self):
|
||||||
if not self.cfgstr:
|
if not self.cfgstr:
|
||||||
|
@ -32,3 +32,10 @@
|
|||||||
# https://tools.ietf.org/html/rfc5175
|
# https://tools.ietf.org/html/rfc5175
|
||||||
# https://tools.ietf.org/html/rfc6104
|
# https://tools.ietf.org/html/rfc6104
|
||||||
# https://tools.ietf.org/html/rfc7772
|
# https://tools.ietf.org/html/rfc7772
|
||||||
|
# DHCPv6
|
||||||
|
# https://tools.ietf.org/html/rfc3315
|
||||||
|
# https://tools.ietf.org/html/rfc3646
|
||||||
|
# https://tools.ietf.org/html/rfc4649
|
||||||
|
# https://tools.ietf.org/html/rfc8415
|
||||||
|
##
|
||||||
|
# https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/ipv6_fhsec/configuration/xe-3s/ip6f-xe-3s-book/ip6-rfcs.pdf
|
||||||
|
@ -5,12 +5,19 @@
|
|||||||
{%- set mtu = 1480 -%}
|
{%- set mtu = 1480 -%}
|
||||||
{#- Minimum seconds allowed between sending unsolicited multicast RAs. 3 < x < (0.75 * max_inter) -#}
|
{#- Minimum seconds allowed between sending unsolicited multicast RAs. 3 < x < (0.75 * max_inter) -#}
|
||||||
{#- If using Mobile Extensions, 0.33 < x (0.75 * max_inter) -#}
|
{#- If using Mobile Extensions, 0.33 < x (0.75 * max_inter) -#}
|
||||||
{%- set min_inter = 60 -%}
|
{%- set min_inter = 10 -%}
|
||||||
{#- Maximum seconds allowed between sending unsolicited multicast RAs. 4 < x < 1800 -#}
|
{#- Maximum seconds allowed between sending unsolicited multicast RAs. 4 < x < 1800 -#}
|
||||||
{#- If using Mobile Extensions, 0.07 < x 1800 -#}
|
{#- If using Mobile Extensions, 0.07 < x 1800 -#}
|
||||||
{%- set max_inter = 600 -%}
|
{%- set max_inter = 60 -%}
|
||||||
{#- Minimum seconds between sending multicast RAs (solicited and unsolicited). -#}
|
{#- Minimum seconds between sending multicast RAs (solicited and unsolicited). -#}
|
||||||
{#- If using Mobile Extensions, 0.03 < x -#}
|
{#- If using Mobile Extensions, 0.03 < x -#}
|
||||||
{%- set min_delay = 3 -%}
|
{%- set min_delay = 3 -%}
|
||||||
|
{#- The lifetime associated with the default router in units of seconds. 0 OR max_inter < x < 9000 -#}
|
||||||
|
{%- set lifetime = 9000 -%}
|
||||||
{#- ## DHCPv6 OPTIONS ## -#}
|
{#- ## DHCPv6 OPTIONS ## -#}
|
||||||
{#- Obviously, these only works for DNSMasq. -#}
|
{#- Obviously, these only work for DNSMasq. -#}
|
||||||
|
{#- How long the lease should last until a new one is requested. -#}
|
||||||
|
{#- This is also used for *SLAAC addresses* in radvd. -#}
|
||||||
|
{%- set lease_life = 21600 -%}{#- 6 hours -#}
|
||||||
|
{#- How long should the options be valid for. -#}
|
||||||
|
{%- set opts_life = lease_life -%}
|
||||||
|
@ -1,2 +1,49 @@
|
|||||||
|
{%- import '_common.j2' as common_opts with context -%}
|
||||||
# This file should be *included* in your dnsmasq configuration.
|
# This file should be *included* in your dnsmasq configuration.
|
||||||
|
# Generated by he_ipv6.
|
||||||
|
# See "dnsmasq --help dhcp6" for matching option identifers ("dhcp-option = ..., option6: <option>").
|
||||||
|
enable-ra
|
||||||
|
{% for assignment in assignments %}
|
||||||
|
{%- set assign_loop = loop -%}
|
||||||
|
{%- set ra_opts = [] -%}
|
||||||
|
{%- if assignment.ra_tag -%}
|
||||||
|
{%- set id_set = 'tag:' + assignment.ra_tag -%}
|
||||||
|
{%- set identifier = id_set -%}
|
||||||
|
{%- set do_listen = false -%}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set id_set = 'set:' + assignment.iface -%}
|
||||||
|
{%- set identifier = 'tag:' + assignment.iface -%}
|
||||||
|
{%- set do_listen = true -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if assignment.ra_dns -%}
|
||||||
|
{%- do ra_opts.append('sa-names') -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if assignment.ra_dhcp is false -%}
|
||||||
|
{%- do ra_opts.append('ra-only') -%}
|
||||||
|
{%- if assignment.ra_other is true -%}
|
||||||
|
{%- do ra_opts.append('ra-stateless') -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- do ra_opts.append('slaac') -%}
|
||||||
|
{%- do ra_opts.append('ra-names') -%}
|
||||||
|
# {{ assignment.iface }} assignment
|
||||||
|
{%- if do_listen %}
|
||||||
|
listen = {{ assignment.iface_ll }}
|
||||||
|
{%- endif %}
|
||||||
|
ra-param = {{ assignment.iface }}, mtu:{{ common_opts.mtu }}, high, {{ common_opts.min_delay }}, {{ common_opts.lifetime }}
|
||||||
|
{%- if assignment.ra_dhcp %}
|
||||||
|
{%- for block in assignment.iface_blocks %}
|
||||||
|
dhcp-range = {{ id_set }}, {{ assignment.dhcp6_ranges[assign_loop.index0]|join(', ') }}, {{ ra_opts|join(', ') }}, {{ common_opts.lease_life }}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- else %}
|
||||||
|
dhcp-range = {{ id_set }}, ::, constructor={{ assignment.iface }}, {{ ra_opts|join(', ') }}, {{ common_opts.lease_life }}{#- TODO: check this. #}
|
||||||
|
{%- endif %}
|
||||||
|
dhcp-option = {{ identifier }}, option6:information-refresh-time, {{ common_opts.opts_life }}
|
||||||
|
{%- if assignment.ra_dns %}
|
||||||
|
dhcp-option = {{ identifier }}, option6:dns-server, [{{ assignment.iface_ll }}]
|
||||||
|
{%- endif %}
|
||||||
|
{%- if assignment.ra_domains %}
|
||||||
|
dhcp-option = {{ identifier }}, option6:domain-search, {{ assignment.ra_domains|join(',') }}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
@ -1,30 +1,44 @@
|
|||||||
# Generated by he_ipv6
|
{%- import '_common.j2' as common_opts with context -%}
|
||||||
{% for assign in assignments %}
|
# Generated by he_ipv6.
|
||||||
{% for assignment in assign.iface_blocks %}
|
# This may go wonky with multiple assignments on the same iface.
|
||||||
|
{% for assignment in assignments %}
|
||||||
interface {{ assignment.iface }} {
|
interface {{ assignment.iface }} {
|
||||||
AdvSendAdvert on;
|
AdvSendAdvert on;
|
||||||
# Is it 1480 or 1280? Arch wiki says 1480, but everything else (older) says 1280.
|
AdvLinkMTU {{ common_opts.mtu }};
|
||||||
# AdvLinkMTU 1280;
|
MinRtrAdvInterval {{ common_opts.min_inter }};
|
||||||
AdvLinkMTU 1480;
|
MaxRtrAdvInterval {{ common_opts.max_inter }};
|
||||||
MinRtrAdvInterval 60;
|
MinDelayBetweenRAs {{ common_opts.min_delay }};
|
||||||
MaxRtrAdvInterval 600;
|
AdvDefaultLifetime {{ common_opts.lifetime }};
|
||||||
AdvDefaultLifetime 9000;
|
{%- if assignment.ra_dhcp is true -%}
|
||||||
|
AdvManagedFlag on;
|
||||||
|
{%- endif %}
|
||||||
|
{%- if assignment.ra_other is true -%}
|
||||||
|
AdvOtherConfigFlag on;
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
{%- for block in assignment.iface_blocks %}
|
{%- for block in assignment.iface_blocks %}
|
||||||
prefix {{ block|string }} {
|
prefix {{ block|string }} {
|
||||||
AdvOnLink on;
|
AdvOnLink on;
|
||||||
{%- if block.prefixlen == 64 %}
|
{%- if block.prefixlen <= 64 %}
|
||||||
AdvAutonomous on;
|
AdvAutonomous on;
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
AdvValidLifetime {{ common_opts.lease_life }};
|
||||||
|
AdvPreferredLifetime {{ common_opts.lease_life }};
|
||||||
AdvRouterAddr off;
|
AdvRouterAddr off;
|
||||||
};
|
};
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
||||||
{%- if ra.dns is true %}
|
{%- if assign.ra_dns is true %}
|
||||||
RDNSS {{ nameservers[assignment.iface]|join(' ') }} {
|
RDNSS {{ assignment.iface_ll }} {
|
||||||
|
AdvRDNSSLifetime {{ common_opts.opts_life }};
|
||||||
|
};
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
{%- if assign.ra_domains %}
|
||||||
|
DNSSL {{ assignment.ra_domains|join(' ') }} {
|
||||||
|
AdvDNSSLLifetime {{ common_opts.opts_life }};
|
||||||
};
|
};
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
};
|
};
|
||||||
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import ipaddress
|
import ipaddress
|
||||||
|
import socket
|
||||||
##
|
##
|
||||||
import netaddr
|
import netaddr
|
||||||
from pyroute2 import IPRoute
|
from pyroute2 import IPRoute
|
||||||
##
|
##
|
||||||
from . import utils
|
|
||||||
from . import ra
|
from . import ra
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
class IP(object):
|
class IP(object):
|
||||||
@ -51,14 +52,28 @@ class IP6(IP):
|
|||||||
|
|
||||||
|
|
||||||
class Assignment(object):
|
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.xml = assign_xml
|
||||||
self.ra = ra
|
self.ra_dns = ra_dns
|
||||||
self.dns = 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 = None
|
||||||
|
self.iface_ll = None
|
||||||
self.iface_idx = None
|
self.iface_idx = None
|
||||||
self.iface_addrs = []
|
|
||||||
self.iface_blocks = []
|
self.iface_blocks = []
|
||||||
|
self.dhcp6_ranges = []
|
||||||
self.alloc = None # This must be set externally to a mapped Allocation instance
|
self.alloc = None # This must be set externally to a mapped Allocation instance
|
||||||
self.alloc_id = None
|
self.alloc_id = None
|
||||||
self.prefix = None
|
self.prefix = None
|
||||||
@ -74,6 +89,16 @@ class Assignment(object):
|
|||||||
self.iface = _iface_txt.strip()
|
self.iface = _iface_txt.strip()
|
||||||
ipr = IPRoute()
|
ipr = IPRoute()
|
||||||
self.iface_idx = ipr.link_lookup(ifname = self.iface)[0]
|
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()
|
ipr.close()
|
||||||
return(None)
|
return(None)
|
||||||
|
|
||||||
@ -92,7 +117,11 @@ class Assignment(object):
|
|||||||
# NOT AN IP6 OBJECT!
|
# NOT AN IP6 OBJECT!
|
||||||
self.iface_blocks = self.alloc_block.extract_subnet(self.prefix, count = 1)
|
self.iface_blocks = self.alloc_block.extract_subnet(self.prefix, count = 1)
|
||||||
for i in self.iface_blocks:
|
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)
|
return(None)
|
||||||
|
|
||||||
|
|
||||||
@ -114,11 +143,8 @@ class Tunnel(object):
|
|||||||
self.client = None
|
self.client = None
|
||||||
self.server = None
|
self.server = None
|
||||||
self.endpoint = None
|
self.endpoint = None
|
||||||
self.ra = False
|
|
||||||
self.ra_provider = None
|
self.ra_provider = None
|
||||||
self.ra_dns = False
|
self.allocations = {} # This is a dict of {}[alloc.id] = Allocation obj (as provided by HE)
|
||||||
self.ra_dhcp = False
|
|
||||||
self.allocations = {} # This is a dict of {}[alloc.id] = Allocation obj
|
|
||||||
self.assignments = [] # This is a list of Assignment objs
|
self.assignments = [] # This is a list of Assignment objs
|
||||||
self.parse()
|
self.parse()
|
||||||
|
|
||||||
@ -128,11 +154,27 @@ class Tunnel(object):
|
|||||||
|
|
||||||
def _assignments(self):
|
def _assignments(self):
|
||||||
_assigns_xml = self.xml.find('assignments')
|
_assigns_xml = self.xml.find('assignments')
|
||||||
|
self.ra_provider = _assigns_xml.attrib.get('raProvider')
|
||||||
self.enable_ra = utils.xml2bool(_assigns_xml.attrib.get('radvd', 'false'))
|
|
||||||
self.ra_dns = utils.xml2bool(_assigns_xml.attrib.get('radvdDns', 'false'))
|
|
||||||
for _assign_xml in _assigns_xml.findall('assign'):
|
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.alloc = self.allocations[assign.alloc_id]
|
||||||
assign.parse_alloc()
|
assign.parse_alloc()
|
||||||
self.assignments.append(assign)
|
self.assignments.append(assign)
|
||||||
@ -154,9 +196,13 @@ class Tunnel(object):
|
|||||||
self.id = int(self.xml.attrib['id'].strip())
|
self.id = int(self.xml.attrib['id'].strip())
|
||||||
return(None)
|
return(None)
|
||||||
|
|
||||||
def _radvd(self):
|
def _ra(self):
|
||||||
|
# TODO: support conf path override via config XML?
|
||||||
self.radvd.conf.generate(self.assignments)
|
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)
|
return(None)
|
||||||
|
|
||||||
def _server(self):
|
def _server(self):
|
||||||
@ -171,5 +217,5 @@ class Tunnel(object):
|
|||||||
self._endpoint()
|
self._endpoint()
|
||||||
self._allocations()
|
self._allocations()
|
||||||
self._assignments()
|
self._assignments()
|
||||||
self._radvd()
|
self._ra()
|
||||||
return(None)
|
return(None)
|
||||||
|
@ -143,30 +143,6 @@ class TunnelBroker(object):
|
|||||||
ipr.close()
|
ipr.close()
|
||||||
raise e
|
raise e
|
||||||
for assignment in self.tun.assignments:
|
for assignment in self.tun.assignments:
|
||||||
for a in assignment.iface_addrs:
|
|
||||||
# The interface-specific ":1" addrs.
|
|
||||||
# Try to remove first in case it's already assigned.
|
|
||||||
try:
|
|
||||||
ipr.addr('del',
|
|
||||||
index = assignment.iface_idx,
|
|
||||||
address = a.str,
|
|
||||||
mask = a.prefix,
|
|
||||||
family = socket.AF_INET6)
|
|
||||||
logger.debug('Removed {0} with prefix {1} from {2}.'.format(a.str, a.prefixlen, assignment.iface))
|
|
||||||
except Exception as e:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
ipr.addr('add',
|
|
||||||
index = assignment.iface_idx,
|
|
||||||
address = a.str,
|
|
||||||
mask = a.prefix,
|
|
||||||
family = socket.AF_INET6)
|
|
||||||
logger.debug('Added {0} with prefix {1} to {2}.'.format(a.str, a.prefix, assignment.iface))
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(('Could not add address {0} on {1}: '
|
|
||||||
'{2}').format(a.str, assignment.iface, e))
|
|
||||||
ipr.close()
|
|
||||||
raise e
|
|
||||||
# The SLAAC prefixes.
|
# The SLAAC prefixes.
|
||||||
for b in assignment.iface_blocks:
|
for b in assignment.iface_blocks:
|
||||||
# Try to remove first in case it's already assigned.
|
# Try to remove first in case it's already assigned.
|
||||||
|
Loading…
Reference in New Issue
Block a user