diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/dhcpv6_server.py | 33 | ||||
-rwxr-xr-x | src/conf_mode/host_name.py | 15 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-pseudo-ethernet.py | 47 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-tunnel.py | 17 | ||||
-rwxr-xr-x | src/conf_mode/ipsec-settings.py | 6 | ||||
-rwxr-xr-x | src/conf_mode/service_pppoe-server.py | 4 | ||||
-rwxr-xr-x | src/conf_mode/vpn_l2tp.py | 2 | ||||
-rwxr-xr-x | src/op_mode/vrrp.py | 1 |
8 files changed, 70 insertions, 55 deletions
diff --git a/src/conf_mode/dhcpv6_server.py b/src/conf_mode/dhcpv6_server.py index 94a307826..ce98e39c3 100755 --- a/src/conf_mode/dhcpv6_server.py +++ b/src/conf_mode/dhcpv6_server.py @@ -213,6 +213,10 @@ def get_config(): # append shared network configuration to config dictionary dhcpv6['shared_network'].append(config) + # If all shared-networks are disabled, there's nothing to do. + if all(net['disabled'] for net in dhcpv6['shared_network']): + return None + return dhcpv6 def verify(dhcpv6): @@ -302,22 +306,22 @@ def verify(dhcpv6): else: subnets.append(subnet['network']) - # DHCPv6 requires at least one configured address range or one static mapping - # (FIXME: is not actually checked right now?) + # DHCPv6 requires at least one configured address range or one static mapping + # (FIXME: is not actually checked right now?) - # There must be one subnet connected to a listen interface if network is not disabled. - if not network['disabled']: - if is_subnet_connected(subnet['network']): - listen_ok = True + # There must be one subnet connected to a listen interface if network is not disabled. + if not network['disabled']: + if is_subnet_connected(subnet['network']): + listen_ok = True - # DHCPv6 subnet must not overlap. ISC DHCP also complains about overlapping - # subnets: "Warning: subnet 2001:db8::/32 overlaps subnet 2001:db8:1::/32" - net = ipaddress.ip_network(subnet['network']) - for n in subnets: - net2 = ipaddress.ip_network(n) - if (net != net2): - if net.overlaps(net2): - raise ConfigError('DHCPv6 conflicting subnet ranges: {0} overlaps {1}'.format(net, net2)) + # DHCPv6 subnet must not overlap. ISC DHCP also complains about overlapping + # subnets: "Warning: subnet 2001:db8::/32 overlaps subnet 2001:db8:1::/32" + net = ipaddress.ip_network(subnet['network']) + for n in subnets: + net2 = ipaddress.ip_network(n) + if (net != net2): + if net.overlaps(net2): + raise ConfigError('DHCPv6 conflicting subnet ranges: {0} overlaps {1}'.format(net, net2)) if not listen_ok: raise ConfigError('None of the DHCPv6 subnets are connected to a subnet6 on\n' \ @@ -346,6 +350,7 @@ def apply(dhcpv6): if os.path.exists(config_file): os.unlink(config_file) + else: call('systemctl restart isc-dhcp-server6.service') return None diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index a669580ae..f181a7b35 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -164,10 +164,17 @@ def apply(config): if process_named_running('snmpd'): call('systemctl restart snmpd.service') - # restart pdns if it is used - ret = run('/usr/bin/rec_control --socket-dir=/run/powerdns ping') - if ret == 0: - call('systemctl restart pdns-recursor.service') + # restart pdns if it is used - we check for the control dir to not raise + # an exception on system startup + # + # File "/usr/lib/python3/dist-packages/vyos/configsession.py", line 128, in __run_command + # raise ConfigSessionError(output) + # vyos.configsession.ConfigSessionError: [ system domain-name vyos.io ] + # Fatal: Unable to generate local temporary file in directory '/run/powerdns': No such file or directory + if os.path.isdir('/run/powerdns'): + ret = run('/usr/bin/rec_control --socket-dir=/run/powerdns ping') + if ret == 0: + call('systemctl restart pdns-recursor.service') return None diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py index 8eba6ea63..d5f308ed3 100755 --- a/src/conf_mode/interfaces-pseudo-ethernet.py +++ b/src/conf_mode/interfaces-pseudo-ethernet.py @@ -246,38 +246,29 @@ def generate(peth): return None def apply(peth): - - p = '' if peth['deleted']: # delete interface - p = MACVLANIf(peth['intf']) - p.remove() + MACVLANIf(peth['intf']).remove() return None - elif peth['source_interface_changed']: - # Check if MACVLAN interface already exists. Parameters like the - # underlaying source-interface device can not be changed on the fly - # and the interface needs to be recreated from the bottom. - # - # source_interface_changed also means - the interface was not present in the - # beginning and is newly created - if peth['intf'] in interfaces(): - p = MACVLANIf(peth['intf']) - p.remove() - - # MACVLAN interface needs to be created on-block instead of passing a ton - # of arguments, I just use a dict that is managed by vyos.ifconfig - conf = deepcopy(MACVLANIf.get_config()) - - # Assign MACVLAN instance configuration parameters to config dict - conf['source_interface'] = peth['source_interface'] - conf['mode'] = peth['mode'] - - # It is safe to "re-create" the interface always, there is a sanity check - # that the interface will only be create if its non existent - p = MACVLANIf(peth['intf'], **conf) - else: - p = MACVLANIf(peth['intf']) + # Check if MACVLAN interface already exists. Parameters like the underlaying + # source-interface device can not be changed on the fly and the interface + # needs to be recreated from the bottom. + if peth['intf'] in interfaces(): + if peth['source_interface_changed']: + MACVLANIf(peth['intf']).remove() + + # MACVLAN interface needs to be created on-block instead of passing a ton + # of arguments, I just use a dict that is managed by vyos.ifconfig + conf = deepcopy(MACVLANIf.get_config()) + + # Assign MACVLAN instance configuration parameters to config dict + conf['source_interface'] = peth['source_interface'] + conf['mode'] = peth['mode'] + + # It is safe to "re-create" the interface always, there is a sanity check + # that the interface will only be create if its non existent + p = MACVLANIf(peth['intf'], **conf) # update interface description used e.g. within SNMP p.set_alias(peth['description']) diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index 2ab75fcec..9c0c42414 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -255,7 +255,9 @@ default_config_data = { 'ipv6_forwarding': 1, 'ipv6_dad_transmits': 1, # internal + 'interfaces': [], 'tunnel': {}, + 'bridge': '', # the following names are exactly matching the name # for the ip command and must not be changed 'ifname': '', @@ -264,6 +266,7 @@ default_config_data = { 'mtu': '1476', 'local': '', 'remote': '', + 'dev': '', 'multicast': 'disable', 'allmulticast': 'disable', 'ttl': '255', @@ -275,7 +278,6 @@ default_config_data = { 'tclass': 'inherit', '6rd-prefix': '', '6rd-relay-prefix': '', - 'bridge': '', } # dict name -> config name, multiple values, default @@ -286,6 +288,7 @@ mapping = { 'local': ('local-ip', False, None), 'remote': ('remote-ip', False, None), 'multicast': ('multicast', False, None), + 'dev': ('source-interface', False, None), 'ttl': ('parameters ip ttl', False, None), 'tos': ('parameters ip tos', False, None), 'key': ('parameters ip key', False, None), @@ -408,6 +411,7 @@ def get_config(): # check for bridges options['bridge'] = is_bridge_member(conf, ifname) + options['interfaces'] = interfaces() for name in ct: tunnel = ct[name] @@ -483,6 +487,7 @@ def verify(conf): afi_remote = get_afi(tun_remote) tun_ismgre = iftype == 'gre' and not options['remote'] tun_is6rd = iftype == 'sit' and options['6rd-prefix'] + tun_dev = options['dev'] # incompatible options @@ -492,6 +497,9 @@ def verify(conf): if tun_local and options['dhcp-interface']: raise ConfigError(f'Must configure only one of local-ip or dhcp-interface for tunnel {iftype} {ifname}') + if tun_dev and iftype in ('gre-bridge', 'sit'): + raise ConfigError(f'source interface can not be used with {iftype} {ifname}') + # tunnel endpoint if afi_local != afi_remote: @@ -519,9 +527,14 @@ def verify(conf): # vrf check vrf = options['vrf'] - if vrf and vrf not in interfaces(): + if vrf and vrf not in options['interfaces']: raise ConfigError(f'VRF "{vrf}" does not exist') + # source-interface check + + if tun_dev and tun_dev not in options['interfaces']: + raise ConfigError(f'device "{dev}" does not exist') + # tunnel encapsulation check convert = { diff --git a/src/conf_mode/ipsec-settings.py b/src/conf_mode/ipsec-settings.py index da19dcb26..3398bcdf2 100755 --- a/src/conf_mode/ipsec-settings.py +++ b/src/conf_mode/ipsec-settings.py @@ -170,7 +170,7 @@ def generate(data): if data["ipsec_l2tp"]: remove_confs(delim_ipsec_l2tp_begin, delim_ipsec_l2tp_end, ipsec_secrets_file) # old_umask = os.umask(0o077) - # render(ipsec_secrets_file, 'ipsec/ipsec.secrets.tmpl', c, trim_blocks=True) + # render(ipsec_secrets_file, 'ipsec/ipsec.secrets.tmpl', data, trim_blocks=True) # os.umask(old_umask) ## Use this method while IPSec CLI handler won't be overwritten to python write_ipsec_secrets(data) @@ -181,12 +181,12 @@ def generate(data): if not os.path.exists(ipsec_ra_conn_dir): os.makedirs(ipsec_ra_conn_dir) - render(ipsec_ra_conn_file, 'ipsec/remote-access.tmpl', c, trim_blocks=True) + render(ipsec_ra_conn_file, 'ipsec/remote-access.tmpl', data, trim_blocks=True) os.umask(old_umask) remove_confs(delim_ipsec_l2tp_begin, delim_ipsec_l2tp_end, ipsec_conf_file) # old_umask = os.umask(0o077) - # render(ipsec_conf_file, 'ipsec/ipsec.conf.tmpl', c, trim_blocks=True) + # render(ipsec_conf_file, 'ipsec/ipsec.conf.tmpl', data, trim_blocks=True) # os.umask(old_umask) ## Use this method while IPSec CLI handler won't be overwritten to python write_ipsec_conf(data) diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py index f0dd3751a..94eb675f7 100755 --- a/src/conf_mode/service_pppoe-server.py +++ b/src/conf_mode/service_pppoe-server.py @@ -423,10 +423,10 @@ def generate(pppoe): if not os.path.exists(dirname): os.mkdir(dirname) - render(pppoe_conf, 'accel-ppp/pppoe.config.tmpl', c, trim_blocks=True) + render(pppoe_conf, 'accel-ppp/pppoe.config.tmpl', pppoe, trim_blocks=True) if pppoe['local_users']: - render(pppoe_chap_secrets, 'accel-ppp/chap-secrets.tmpl', c, trim_blocks=True) + render(pppoe_chap_secrets, 'accel-ppp/chap-secrets.tmpl', pppoe, trim_blocks=True) os.chmod(pppoe_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP) else: if os.path.exists(pppoe_chap_secrets): diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py index 417520e09..a640e2a94 100755 --- a/src/conf_mode/vpn_l2tp.py +++ b/src/conf_mode/vpn_l2tp.py @@ -348,7 +348,7 @@ def generate(l2tp): if not os.path.exists(dirname): os.mkdir(dirname) - render(l2tp_conf, 'accel-ppp/l2tp.config.tmpl', c, trim_blocks=True) + render(l2tp_conf, 'accel-ppp/l2tp.config.tmpl', l2tp, trim_blocks=True) if l2tp['auth_mode'] == 'local': render(l2tp_chap_secrets, 'accel-ppp/chap-secrets.tmpl', l2tp) diff --git a/src/op_mode/vrrp.py b/src/op_mode/vrrp.py index 923cfa4d4..e024d7f63 100755 --- a/src/op_mode/vrrp.py +++ b/src/op_mode/vrrp.py @@ -21,7 +21,6 @@ import argparse import json import tabulate -import vyos.keepalived import vyos.util from vyos.ifconfig.vrrp import VRRP |