diff options
Diffstat (limited to 'python/vyos')
-rw-r--r-- | python/vyos/configdict.py | 2 | ||||
-rw-r--r-- | python/vyos/configverify.py | 4 | ||||
-rw-r--r-- | python/vyos/ifconfig/interface.py | 4 | ||||
-rw-r--r-- | python/vyos/ifconfig/tunnel.py | 40 | ||||
-rw-r--r-- | python/vyos/ifconfig/wireguard.py | 24 | ||||
-rw-r--r-- | python/vyos/template.py | 23 | ||||
-rw-r--r-- | python/vyos/validate.py | 16 |
7 files changed, 85 insertions, 28 deletions
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 0b03dfc7d..b14f96364 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -431,7 +431,7 @@ def get_accel_dict(config, base, chap_secrets): Return a dictionary with the necessary interface config keys. """ from vyos.util import get_half_cpus - from vyos.validate import is_ipv4 + from vyos.template import is_ipv4 dict = config.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) diff --git a/python/vyos/configverify.py b/python/vyos/configverify.py index babb0feb7..675dac5b1 100644 --- a/python/vyos/configverify.py +++ b/python/vyos/configverify.py @@ -51,7 +51,7 @@ def verify_mtu_ipv6(config): recurring validation if the specified MTU can be used when IPv6 is configured on the interface. IPv6 requires a 1280 bytes MTU. """ - from vyos.validate import is_ipv6 + from vyos.template import is_ipv6 if 'mtu' in config: # IPv6 minimum required link mtu min_mtu = 1280 @@ -278,7 +278,7 @@ def verify_diffie_hellman_length(file, min_keysize): prog = re.compile('\d+\s+bit') if prog.search(out): bits = prog.search(out)[0].split()[0] - if int(min_keysize) >= int(bits): + if int(bits) >= int(min_keysize): return True return False diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 894410871..893623284 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -35,8 +35,8 @@ from vyos.configdict import dict_merge from vyos.template import render from vyos.util import mac2eui64 from vyos.util import dict_search -from vyos.validate import is_ipv4 -from vyos.validate import is_ipv6 +from vyos.template import is_ipv4 +from vyos.template import is_ipv6 from vyos.validate import is_intf_addr_assigned from vyos.validate import assert_boolean from vyos.validate import assert_list diff --git a/python/vyos/ifconfig/tunnel.py b/python/vyos/ifconfig/tunnel.py index 4122d1a2f..926d66c18 100644 --- a/python/vyos/ifconfig/tunnel.py +++ b/python/vyos/ifconfig/tunnel.py @@ -22,6 +22,10 @@ from vyos.ifconfig.interface import Interface from vyos.ifconfig.afi import IP4, IP6 from vyos.validate import assert_list +import random +from random import seed, getrandbits +from ipaddress import IPv6Network, IPv6Address + def enable_to_on(value): if value == 'enable': return 'on' @@ -122,6 +126,16 @@ class _Tunnel(Interface): @classmethod def get_config(cls): return dict(zip(cls.options, ['']*len(cls.options))) + + def generate_link_local(): + # Linux Kernel does not generate IPv6 Link Local address do to missing MAC + # We have to generate address manually and assign to interface + net = IPv6Network("FE80::/16") + rand_net = IPv6Network((net.network_address + (random.getrandbits(64 - net.prefixlen) << 64 ),64)) + network = IPv6Network(rand_net) + address = str(IPv6Address(network.network_address + getrandbits(network.max_prefixlen - network.prefixlen)))+'/'+str(network.prefixlen) + + return address class GREIf(_Tunnel): @@ -154,6 +168,12 @@ class GREIf(_Tunnel): create = 'ip tunnel add {ifname} mode {type}' change = 'ip tunnel cha {ifname}' delete = 'ip tunnel del {ifname}' + + + def _create(self): + super()._create(self) + # Assign generated IPv6 Link Local address to the interface + self.add_addr(self.generate_link_local()) # GreTap also called GRE Bridge @@ -219,6 +239,11 @@ class IP6GREIf(_Tunnel): # sudo ip tunnel cha tun100 local: : 2 # Error: an IP address is expected rather than "::2" # works if mode is explicit + + def _create(self): + super()._create(self) + # Assign generated IPv6 Link Local address to the interface + self.add_addr(self.generate_link_local()) class IPIPIf(_Tunnel): @@ -270,6 +295,11 @@ class IPIP6If(_Tunnel): create = 'ip -6 tunnel add {ifname} mode {type}' change = 'ip -6 tunnel cha {ifname}' delete = 'ip -6 tunnel del {ifname}' + + def _create(self): + super()._create(self) + # Assign generated IPv6 Link Local address to the interface + self.add_addr(self.generate_link_local()) class IP6IP6If(IPIP6If): @@ -283,6 +313,11 @@ class IP6IP6If(IPIP6If): ip = [IP6,] default = {'type': 'ip6ip6'} + + def _create(self): + super()._create(self) + # Assign generated IPv6 Link Local address to the interface + self.add_addr(self.generate_link_local()) class SitIf(_Tunnel): @@ -306,6 +341,11 @@ class SitIf(_Tunnel): create = 'ip tunnel add {ifname} mode {type}' change = 'ip tunnel cha {ifname}' delete = 'ip tunnel del {ifname}' + + def _create(self): + super()._create(self) + # Assign generated IPv6 Link Local address to the interface + self.add_addr(self.generate_link_local()) class Sit6RDIf(SitIf): diff --git a/python/vyos/ifconfig/wireguard.py b/python/vyos/ifconfig/wireguard.py index d8e89229d..5e9173349 100644 --- a/python/vyos/ifconfig/wireguard.py +++ b/python/vyos/ifconfig/wireguard.py @@ -24,7 +24,11 @@ from hurry.filesize import alternative from vyos.config import Config from vyos.ifconfig import Interface from vyos.ifconfig import Operational -from vyos.validate import is_ipv6 +from vyos.template import is_ipv6 + +import random +from random import seed, getrandbits +from ipaddress import IPv6Network, IPv6Address class WireGuardOperational(Operational): def _dump(self): @@ -168,7 +172,23 @@ class WireGuardIf(Interface): options = Interface.options + \ ['port', 'private_key', 'pubkey', 'psk', 'allowed_ips', 'fwmark', 'endpoint', 'keepalive'] - + + + def generate_link_local(): + # Linux Kernel does not generate IPv6 Link Local address do to missing MAC + # We have to generate address manually and assign to interface + net = IPv6Network("FE80::/16") + rand_net = IPv6Network((net.network_address + (random.getrandbits(64 - net.prefixlen) << 64 ),64)) + network = IPv6Network(rand_net) + address = str(IPv6Address(network.network_address + getrandbits(network.max_prefixlen - network.prefixlen)))+'/'+str(network.prefixlen) + + return address + + def _create(self): + super()._create(self) + # Assign generated IPv6 Link Local address to the interface + self.add_addr(self.generate_link_local()) + def update(self, config): """ General helper function which works on a dictionary retrived by get_config_dict(). It's main intention is to consolidate the scattered diff --git a/python/vyos/template.py b/python/vyos/template.py index 53e1dc1b5..58ba75972 100644 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -124,7 +124,7 @@ def render( ################################## @register_filter('address_from_cidr') -def vyos_address_from_cidr(text): +def address_from_cidr(text): """ Take an IPv4/IPv6 CIDR prefix and convert the network to an "address". Example: 192.0.2.0/24 -> 192.0.2.0, 2001:db8::/48 -> 2001:db8:: @@ -133,7 +133,7 @@ def vyos_address_from_cidr(text): return str(ip_network(text).network_address) @register_filter('netmask_from_cidr') -def vyos_netmask_from_cidr(text): +def netmask_from_cidr(text): """ Take CIDR prefix and convert the prefix length to a "subnet mask". Example: - 192.0.2.0/24 -> 255.255.255.0 @@ -142,22 +142,27 @@ def vyos_netmask_from_cidr(text): from ipaddress import ip_network return str(ip_network(text).netmask) -@register_filter('ipv4') -def vyos_ipv4(text): +@register_filter('is_ip') +def is_ip(addr): + """ Check addr if it is an IPv4 or IPv6 address """ + return is_ipv4(addr) or is_ipv6(addr) + +@register_filter('is_ipv4') +def is_ipv4(text): """ Filter IP address, return True on IPv4 address, False otherwise """ from ipaddress import ip_interface try: return ip_interface(text).version == 4 except: return False @register_filter('ipv6') -def vyos_ipv6(text): +def is_ipv6(text): """ Filter IP address, return True on IPv6 address, False otherwise """ from ipaddress import ip_interface try: return ip_interface(text).version == 6 except: return False @register_filter('first_host_address') -def vyos_first_host_address(text): +def first_host_address(text): """ Return first usable (host) IP address from given prefix. Example: - 10.0.0.0/24 -> 10.0.0.1 @@ -173,7 +178,7 @@ def vyos_first_host_address(text): return str(addr.ip) @register_filter('last_host_address') -def vyos_last_host_address(text): +def last_host_address(text): """ Return first usable IP address from given prefix. Example: - 10.0.0.0/24 -> 10.0.0.254 @@ -190,7 +195,7 @@ def vyos_last_host_address(text): return str(IPv6Network(addr).broadcast_address) @register_filter('inc_ip') -def vyos_inc_ip(address, increment): +def inc_ip(address, increment): """ Increment given IP address by 'increment' Example (inc by 2): @@ -201,7 +206,7 @@ def vyos_inc_ip(address, increment): return str(ip_interface(address).ip + int(increment)) @register_filter('dec_ip') -def vyos_dec_ip(address, decrement): +def dec_ip(address, decrement): """ Decrement given IP address by 'decrement' Example (inc by 2): diff --git a/python/vyos/validate.py b/python/vyos/validate.py index 74b8adcfc..84a7bc2de 100644 --- a/python/vyos/validate.py +++ b/python/vyos/validate.py @@ -25,21 +25,10 @@ from vyos.util import cmd # parameters with default will be left unset # all other paramters will receive the value to check -def is_ip(addr): - """ Check addr if it is an IPv4 or IPv6 address """ - return is_ipv4(addr) or is_ipv6(addr) - -def is_ipv4(addr): - from vyos.template import vyos_ipv4 - return vyos_ipv4(addr) - -def is_ipv6(addr): - from vyos.template import vyos_ipv6 - return vyos_ipv6(addr) - def is_ipv6_link_local(addr): """ Check if addrsss is an IPv6 link-local address. Returns True/False """ from ipaddress import IPv6Address + from vyos.template import is_ipv6 addr = addr.split('%')[0] if is_ipv6(addr): if IPv6Address(addr).is_link_local: @@ -51,6 +40,7 @@ def _are_same_ip(one, two): from socket import AF_INET from socket import AF_INET6 from socket import inet_pton + from vyos.template import is_ipv4 # compare the binary representation of the IP f_one = AF_INET if is_ipv4(one) else AF_INET6 s_two = AF_INET if is_ipv4(two) else AF_INET6 @@ -68,6 +58,7 @@ def _is_intf_addr_assigned(intf, address, netmask=''): It can check both a single IP address (e.g. 192.0.2.1 or a assigned CIDR address 192.0.2.1/24. """ + from vyos.template import is_ipv4 # check if the requested address type is configured at all # { @@ -138,6 +129,7 @@ def is_subnet_connected(subnet, primary=False): """ from ipaddress import ip_address from ipaddress import ip_network + from vyos.template import is_ipv6 # determine IP version (AF_INET or AF_INET6) depending on passed address addr_type = netifaces.AF_INET |