summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzsdc <taras@vyos.io>2019-12-30 16:04:46 +0200
committerzsdc <taras@vyos.io>2019-12-30 16:04:46 +0200
commitf7eda283b6eefbbc349384c22a1e15a1d24ae384 (patch)
treeda4e26a68aeb143045ffa7d38b0ebd9a2ea49fed
parent85b4a87ffe874726a190a42ed2d754946d5dec68 (diff)
parentb9a6dab2d4f162eba59b9eec989b1de1b249f3fd (diff)
downloadvyos-1x-f7eda283b6eefbbc349384c22a1e15a1d24ae384.tar.gz
vyos-1x-f7eda283b6eefbbc349384c22a1e15a1d24ae384.zip
Merge remote-tracking branch 'upstream/current' into T1514
-rw-r--r--Makefile1
-rw-r--r--interface-definitions/l2tp-server.xml.in4
-rw-r--r--interface-definitions/system-ip.xml.in58
-rw-r--r--interface-definitions/system-ipv6.xml.in64
-rw-r--r--interface-definitions/system-options.xml.in45
-rw-r--r--interface-definitions/system-time-zone.xml.in2
-rwxr-xr-xsrc/completion/list_interfaces.py3
-rwxr-xr-xsrc/conf_mode/accel_l2tp.py24
-rwxr-xr-xsrc/conf_mode/ipsec-settings.py41
-rwxr-xr-xsrc/conf_mode/system-ip.py81
-rwxr-xr-xsrc/conf_mode/system-ipv6.py109
-rwxr-xr-xsrc/conf_mode/system-options.py81
-rwxr-xr-xsrc/conf_mode/system-timezone.py (renamed from src/conf_mode/timezone.py)0
-rwxr-xr-xsrc/migration-scripts/l2tp/1-to-233
-rwxr-xr-xsrc/migration-scripts/system/13-to-1440
-rwxr-xr-xsrc/migration-scripts/system/14-to-1538
16 files changed, 587 insertions, 37 deletions
diff --git a/Makefile b/Makefile
index c085872a1..ee0bf3ce9 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,6 @@ interface_definitions: $(BUILD_DIR) $(obj)
rm -f $(TMPL_DIR)/protocols/node.def
rm -f $(TMPL_DIR)/protocols/static/node.def
rm -f $(TMPL_DIR)/system/node.def
- rm -f $(TMPL_DIR)/system/options/node.def
rm -f $(TMPL_DIR)/vpn/node.def
rm -f $(TMPL_DIR)/vpn/ipsec/node.def
diff --git a/interface-definitions/l2tp-server.xml.in b/interface-definitions/l2tp-server.xml.in
index 98c17b8b2..7fc844054 100644
--- a/interface-definitions/l2tp-server.xml.in
+++ b/interface-definitions/l2tp-server.xml.in
@@ -28,9 +28,9 @@
</constraint>
</properties>
</leafNode>
- <leafNode name="outside-nexthop">
+ <leafNode name="gateway-address">
<properties>
- <help>Nexthop IP address for reaching the VPN clients</help>
+ <help>Gatway address uses as client tunnel termination point</help>
<constraint>
<validator name="ipv4-address"/>
</constraint>
diff --git a/interface-definitions/system-ip.xml.in b/interface-definitions/system-ip.xml.in
new file mode 100644
index 000000000..14b3b8a07
--- /dev/null
+++ b/interface-definitions/system-ip.xml.in
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="system">
+ <children>
+ <node name="ip" owner="${vyos_conf_scripts_dir}/system-ip.py">
+ <properties>
+ <help>IPv4 Settings</help>
+ <priority>400</priority>
+ </properties>
+ <children>
+ <node name="arp">
+ <properties>
+ <help>Parameters for ARP cache</help>
+ </properties>
+ <children>
+ <leafNode name="table-size">
+ <properties>
+ <help>Maximum number of entries to keep in the ARP cache</help>
+ <completionHelp>
+ <list>1024 2048 4096 8192 16384 32768</list>
+ </completionHelp>
+ <constraint>
+ <regex>(1024|2048|4096|8192|16384|32768)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="disable-forwarding">
+ <properties>
+ <help>Disable IPv4 forwarding on all interfaces</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <node name="multipath">
+ <properties>
+ <help>IPv4 multipath settings</help>
+ </properties>
+ <children>
+ <leafNode name="ignore-unreachable-nexthops">
+ <properties>
+ <help>Ignore next hops that are not in the ARP table</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="layer4-hashing">
+ <properties>
+ <help>Use layer 4 information for ECMP hashing</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/interface-definitions/system-ipv6.xml.in b/interface-definitions/system-ipv6.xml.in
new file mode 100644
index 000000000..47fbeb4e1
--- /dev/null
+++ b/interface-definitions/system-ipv6.xml.in
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="system">
+ <children>
+ <node name="ipv6" owner="${vyos_conf_scripts_dir}/system-ipv6.py">
+ <properties>
+ <help>IPv6 Settings</help>
+ <priority>290</priority>
+ </properties>
+ <children>
+ <leafNode name="disable-forwarding">
+ <properties>
+ <help>Disable IPv6 forwarding on all interfaces</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="disable">
+ <properties>
+ <help>Disable assignment of IPv6 addresses on all interfaces</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <node name="multipath">
+ <properties>
+ <help>IPv4 multipath settings</help>
+ </properties>
+ <children>
+ <leafNode name="layer4-hashing">
+ <properties>
+ <help>Use layer 4 information for ECMP hashing</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="neighbor">
+ <properties>
+ <help>Parameters for Neighbor cache</help>
+ </properties>
+ <children>
+ <leafNode name="table-size">
+ <properties>
+ <help>Maximum number of entries to keep in the Neighbor cache</help>
+ <completionHelp>
+ <list>1024 2048 4096 8192 16384 32768</list>
+ </completionHelp>
+ <constraint>
+ <regex>(1024|2048|4096|8192|16384|32768)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="strict-dad">
+ <properties>
+ <help>Disable IPv6 operation on interface when DAD fails on LL addr</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/interface-definitions/system-options.xml.in b/interface-definitions/system-options.xml.in
new file mode 100644
index 000000000..5fa0635bd
--- /dev/null
+++ b/interface-definitions/system-options.xml.in
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="system">
+ <children>
+ <node name="options" owner="${vyos_conf_scripts_dir}/system-options.py">
+ <properties>
+ <help>System Options</help>
+ <priority>400</priority>
+ </properties>
+ <children>
+ <leafNode name="ctrl-alt-del-action">
+ <properties>
+ <help>Ctrl-Alt-Delete action</help>
+ <completionHelp>
+ <list>ignore reboot poweroff</list>
+ </completionHelp>
+ <valueHelp>
+ <format>ignore</format>
+ <description>Ignore Ctrl-Alt-Delete</description>
+ </valueHelp>
+ <valueHelp>
+ <format>reboot</format>
+ <description>Reboot VyOS</description>
+ </valueHelp>
+ <valueHelp>
+ <format>poweroff</format>
+ <description>Poweroff VyOS</description>
+ </valueHelp>
+ <constraint>
+ <regex>(ignore|reboot|poweroff)</regex>
+ </constraint>
+ <constraintErrorMessage>Must be ignore, reboot, or poweroff</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="reboot-on-panic">
+ <properties>
+ <help>Reboot system on kernel panic</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/interface-definitions/system-time-zone.xml.in b/interface-definitions/system-time-zone.xml.in
index 1ef739735..ff815c9d3 100644
--- a/interface-definitions/system-time-zone.xml.in
+++ b/interface-definitions/system-time-zone.xml.in
@@ -2,7 +2,7 @@
<interfaceDefinition>
<node name="system">
<children>
- <leafNode name="time-zone" owner="${vyos_conf_scripts_dir}/timezone.py">
+ <leafNode name="time-zone" owner="${vyos_conf_scripts_dir}/system-timezone.py">
<properties>
<help>Local time zone (default UTC)</help>
<priority>100</priority>
diff --git a/src/completion/list_interfaces.py b/src/completion/list_interfaces.py
index f336968a6..0ed683074 100755
--- a/src/completion/list_interfaces.py
+++ b/src/completion/list_interfaces.py
@@ -32,10 +32,9 @@ elif args.bridgeable:
bond = vyos.interfaces.list_interfaces_of_type("bonding")
l2tpv3 = vyos.interfaces.list_interfaces_of_type("l2tpv3")
openvpn = vyos.interfaces.list_interfaces_of_type("openvpn")
- vxlan = vyos.interfaces.list_interfaces_of_type("vxlan")
wireless = vyos.interfaces.list_interfaces_of_type("wireless")
tunnel = vyos.interfaces.list_interfaces_of_type("tunnel")
- wireless = vyos.interfaces.list_interfaces_of_type("wireless")
+ vxlan = vyos.interfaces.list_interfaces_of_type("vxlan")
geneve = vyos.interfaces.list_interfaces_of_type("geneve")
interfaces = eth + bond + l2tpv3 + openvpn + vxlan + tunnel + wireless + geneve
diff --git a/src/conf_mode/accel_l2tp.py b/src/conf_mode/accel_l2tp.py
index 37fda2029..a7af9cc68 100755
--- a/src/conf_mode/accel_l2tp.py
+++ b/src/conf_mode/accel_l2tp.py
@@ -118,15 +118,15 @@ secret={{lns_shared_secret}}
{% endfor -%}
{% endif %}
{% endif %}
-{% if outside_nexthop %}
-gw-ip-address={{outside_nexthop}}
+{% if gateway_address %}
+gw-ip-address={{gateway_address}}
{% endif %}
{% if authentication['mode'] == 'local' %}
[chap-secrets]
chap-secrets=/etc/accel-ppp/l2tp/chap-secrets
-{% if outside_nexthop %}
-gw-ip-address={{outside_nexthop}}
+{% if gateway_address %}
+gw-ip-address={{gateway_address}}
{% endif %}
{% endif %}
@@ -181,7 +181,7 @@ dae-server={{authentication['radiusopt']['dae-srv']['ip-addr']}}:\
{{authentication['radiusopt']['dae-srv']['port']}},\
{{authentication['radiusopt']['dae-srv']['secret']}}
{% endif -%}
-gw-ip-address={{outside_nexthop}}
+gw-ip-address={{gateway_address}}
verbose=1
{% endif -%}
@@ -290,7 +290,7 @@ def get_config():
'mppe' : 'prefer'
},
'outside_addr' : '',
- 'outside_nexthop' : '10.255.255.0',
+ 'gateway_address' : '10.255.255.0',
'dns' : [],
'dnsv6' : [],
'wins' : [],
@@ -430,17 +430,17 @@ def get_config():
config_data['mtu'] = c.return_value('mtu')
### gateway address
- if c.exists('outside-nexthop'):
- config_data['outside_nexthop'] = c.return_value('outside-nexthop')
+ if c.exists('gateway-address'):
+ config_data['gateway_address'] = c.return_value('gateway-address')
else:
### calculate gw-ip-address
if c.exists('client-ip-pool start'):
### use start ip as gw-ip-address
- config_data['outside_nexthop'] = c.return_value('client-ip-pool start')
+ config_data['gateway_address'] = c.return_value('client-ip-pool start')
elif c.exists('client-ip-pool subnet'):
### use first ip address from first defined pool
lst_ip = re.findall("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", c.return_values('client-ip-pool subnet')[0])
- config_data['outside_nexthop'] = lst_ip[0]
+ config_data['gateway_address'] = lst_ip[0]
if c.exists('authentication require'):
auth_mods = {'pap' : 'pap','chap' : 'auth_chap_md5', 'mschap' : 'auth_mschap_v1', 'mschap-v2' : 'auth_mschap_v2'}
@@ -497,10 +497,6 @@ def verify(c):
if not c['client_ip_pool'] and not c['client_ip_subnets']:
raise ConfigError("set vpn l2tp remote-access client-ip-pool requires subnet or start/stop IP pool")
- if not c['outside_nexthop']:
- #raise ConfigError('set vpn l2tp remote-access outside-nexthop required')
- print ("WARMING: set vpn l2tp remote-access outside-nexthop required")
-
## check ipv6
if 'delegate_prefix' in c['client_ipv6_pool'] and not 'prefix' in c['client_ipv6_pool']:
raise ConfigError("\"set vpn l2tp remote-access client-ipv6-pool prefix\" required for delegate-prefix ")
diff --git a/src/conf_mode/ipsec-settings.py b/src/conf_mode/ipsec-settings.py
index 331a62316..aab3e9734 100755
--- a/src/conf_mode/ipsec-settings.py
+++ b/src/conf_mode/ipsec-settings.py
@@ -32,14 +32,15 @@ from vyos import ConfigError
ra_conn_name = "remote-access"
charon_conf_file = "/etc/strongswan.d/charon.conf"
ipsec_secrets_flie = "/etc/ipsec.secrets"
-ipsec_ra_conn_file = "/etc/ipsec.d/tunnels/"+ra_conn_name
+ipsec_ra_conn_dir = "/etc/ipsec.d/tunnels/"
+ipsec_ra_conn_file = ipsec_ra_conn_dir + ra_conn_name
ipsec_conf_flie = "/etc/ipsec.conf"
-ca_cert_path = '/etc/ipsec.d/cacerts'
-server_cert_path = '/etc/ipsec.d/certs'
-server_key_path = '/etc/ipsec.d/private'
+ca_cert_path = "/etc/ipsec.d/cacerts"
+server_cert_path = "/etc/ipsec.d/certs"
+server_key_path = "/etc/ipsec.d/private"
delim_ipsec_l2tp_begin = "### VyOS L2TP VPN Begin ###"
delim_ipsec_l2tp_end = "### VyOS L2TP VPN End ###"
-charon_pidfile = '/var/run/charon.pid'
+charon_pidfile = "/var/run/charon.pid"
l2pt_ipsec_conf = '''
{{delim_ipsec_l2tp_begin}}
@@ -147,21 +148,27 @@ def get_config():
### ipsec secret l2tp
def write_ipsec_secrets(c):
- tmpl = jinja2.Template(l2pt_ipsec_secrets_conf, trim_blocks=True)
- l2pt_ipsec_secrets_txt = tmpl.render(c)
- old_umask = os.umask(0o077)
- open(ipsec_secrets_flie,'w').write(l2pt_ipsec_secrets_txt)
- os.umask(old_umask)
- sl.syslog(sl.LOG_NOTICE, ipsec_secrets_flie + ' written')
+ tmpl = jinja2.Template(l2pt_ipsec_secrets_conf, trim_blocks=True)
+ l2pt_ipsec_secrets_txt = tmpl.render(c)
+ old_umask = os.umask(0o077)
+ open(ipsec_secrets_flie,'w').write(l2pt_ipsec_secrets_txt)
+ os.umask(old_umask)
+ sl.syslog(sl.LOG_NOTICE, ipsec_secrets_flie + ' written')
### ipsec remote access connection config
def write_ipsec_ra_conn(c):
- tmpl = jinja2.Template(l2tp_ipsec_ra_conn_conf, trim_blocks=True)
- ipsec_ra_conn_txt = tmpl.render(c)
- old_umask = os.umask(0o077)
- open(ipsec_ra_conn_file,'w').write(ipsec_ra_conn_txt)
- os.umask(old_umask)
- sl.syslog(sl.LOG_NOTICE, ipsec_ra_conn_file + ' written')
+ tmpl = jinja2.Template(l2tp_ipsec_ra_conn_conf, trim_blocks=True)
+ ipsec_ra_conn_txt = tmpl.render(c)
+ old_umask = os.umask(0o077)
+
+ # Create tunnels directory if does not exist
+ if not os.path.exists(ipsec_ra_conn_dir):
+ os.makedirs(ipsec_ra_conn_dir)
+ sl.syslog(sl.LOG_NOTICE, ipsec_ra_conn_dir + " created")
+
+ open(ipsec_ra_conn_file,'w').write(ipsec_ra_conn_txt)
+ os.umask(old_umask)
+ sl.syslog(sl.LOG_NOTICE, ipsec_ra_conn_file + ' written')
### Remove config from file by delimiter
def remove_confs(delim_begin, delim_end, conf_file):
diff --git a/src/conf_mode/system-ip.py b/src/conf_mode/system-ip.py
new file mode 100755
index 000000000..335507411
--- /dev/null
+++ b/src/conf_mode/system-ip.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2019 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+from sys import exit
+from copy import deepcopy
+from vyos.config import Config
+from vyos import ConfigError
+
+default_config_data = {
+ 'arp_table': 8192,
+ 'ipv4_forward': '1',
+ 'mp_unreach_nexthop': '0',
+ 'mp_layer4_hashing': '0'
+}
+
+def sysctl(name, value):
+ os.system('sysctl -wq {}={}'.format(name, value))
+
+def get_config():
+ ip_opt = deepcopy(default_config_data)
+ conf = Config()
+ conf.set_level('system ip')
+ if conf.exists(''):
+ if conf.exists('arp table-size'):
+ ip_opt['arp_table'] = int(conf.return_value('arp table-size'))
+
+ if conf.exists('disable-forwarding'):
+ ip_opt['ipv4_forward'] = '0'
+
+ if conf.exists('multipath ignore-unreachable-nexthops'):
+ ip_opt['mp_unreach_nexthop'] = '1'
+
+ if conf.exists('multipath layer4-hashing'):
+ ip_opt['mp_layer4_hashing'] = '1'
+
+ return ip_opt
+
+def verify(ip_opt):
+ pass
+
+def generate(ip_opt):
+ pass
+
+def apply(ip_opt):
+ # apply ARP threshold values
+ sysctl('net.ipv4.neigh.default.gc_thresh3', ip_opt['arp_table'])
+ sysctl('net.ipv4.neigh.default.gc_thresh2', ip_opt['arp_table'] // 2)
+ sysctl('net.ipv4.neigh.default.gc_thresh1', ip_opt['arp_table'] // 8)
+
+ # enable/disable IPv4 forwarding
+ with open('/proc/sys/net/ipv4/conf/all/forwarding', 'w') as f:
+ f.write(ip_opt['ipv4_forward'])
+
+ # configure multipath
+ sysctl('net.ipv4.fib_multipath_use_neigh', ip_opt['mp_unreach_nexthop'])
+ sysctl('net.ipv4.fib_multipath_hash_policy', ip_opt['mp_layer4_hashing'])
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/system-ipv6.py b/src/conf_mode/system-ipv6.py
new file mode 100755
index 000000000..bd28ec357
--- /dev/null
+++ b/src/conf_mode/system-ipv6.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2019 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import sys
+
+from sys import exit
+from copy import deepcopy
+from vyos.config import Config
+from vyos import ConfigError
+
+ipv6_disable_file = '/etc/modprobe.d/vyos_disable_ipv6.conf'
+
+default_config_data = {
+ 'reboot_message': False,
+ 'ipv6_forward': '1',
+ 'disable_addr_assignment': False,
+ 'mp_layer4_hashing': '0',
+ 'neighbor_cache': 8192,
+ 'strict_dad': '1'
+
+}
+
+def sysctl(name, value):
+ os.system('sysctl -wq {}={}'.format(name, value))
+
+def get_config():
+ ip_opt = deepcopy(default_config_data)
+ conf = Config()
+ conf.set_level('system ipv6')
+ if conf.exists(''):
+ ip_opt['disable_addr_assignment'] = conf.exists('disable')
+ if conf.exists_effective('disable') != conf.exists('disable'):
+ ip_opt['reboot_message'] = True
+
+ if conf.exists('disable-forwarding'):
+ ip_opt['ipv6_forward'] = '0'
+
+ if conf.exists('multipath layer4-hashing'):
+ ip_opt['mp_layer4_hashing'] = '1'
+
+ if conf.exists('neighbor table-size'):
+ ip_opt['neighbor_cache'] = int(conf.return_value('neighbor table-size'))
+
+ if conf.exists('strict-dad'):
+ ip_opt['strict_dad'] = 2
+
+ return ip_opt
+
+def verify(ip_opt):
+ pass
+
+def generate(ip_opt):
+ pass
+
+def apply(ip_opt):
+ # disable IPv6 address assignment
+ if ip_opt['disable_addr_assignment']:
+ with open(ipv6_disable_file, 'w') as f:
+ f.write('options ipv6 disable_ipv6=1')
+ else:
+ if os.path.exists(ipv6_disable_file):
+ os.unlink(ipv6_disable_file)
+
+ if ip_opt['reboot_message']:
+ print('Changing IPv6 disable parameter will only take affect\n' \
+ 'when the system is rebooted.')
+
+ # configure multipath
+ sysctl('net.ipv6.fib_multipath_hash_policy', ip_opt['mp_layer4_hashing'])
+
+ # apply neighbor table threshold values
+ sysctl('net.ipv6.neigh.default.gc_thresh3', ip_opt['neighbor_cache'])
+ sysctl('net.ipv6.neigh.default.gc_thresh2', ip_opt['neighbor_cache'] // 2)
+ sysctl('net.ipv6.neigh.default.gc_thresh1', ip_opt['neighbor_cache'] // 8)
+
+ # enable/disable IPv6 forwarding
+ with open('/proc/sys/net/ipv6/conf/all/forwarding', 'w') as f:
+ f.write(ip_opt['ipv6_forward'])
+
+ # configure IPv6 strict-dad
+ for root, dirs, files in os.walk('/proc/sys/net/ipv6/conf'):
+ for name in files:
+ if name == "accept_dad":
+ with open(os.path.join(root, name), 'w') as f:
+ f.write(str(ip_opt['strict_dad']))
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/system-options.py b/src/conf_mode/system-options.py
new file mode 100755
index 000000000..4c809d044
--- /dev/null
+++ b/src/conf_mode/system-options.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2019 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+from sys import exit
+from copy import deepcopy
+from vyos.config import Config
+from vyos import ConfigError
+
+systemd_ctrl_alt_del = '/lib/systemd/system/ctrl-alt-del.target'
+
+default_config_data = {
+ 'ctrl_alt_del': 'ignore',
+ 'reboot_on_panic': True
+}
+
+def get_config():
+ opt = deepcopy(default_config_data)
+ conf = Config()
+ conf.set_level('system options')
+ if conf.exists(''):
+ if conf.exists('ctrl-alt-del-action'):
+ opt['ctrl_alt_del'] = conf.return_value('ctrl-alt-del-action')
+
+ opt['reboot_on_panic'] = conf.exists('reboot-on-panic')
+
+ return opt
+
+def verify(opt):
+ pass
+
+def generate(opt):
+ pass
+
+def apply(opt):
+
+ # Ctrl-Alt-Delete action
+ if opt['ctrl_alt_del'] == 'ignore':
+ os.unlink('/lib/systemd/system/ctrl-alt-del.target')
+
+ elif opt['ctrl_alt_del'] == 'reboot':
+ if os.path.exists(systemd_ctrl_alt_del):
+ os.unlink(systemd_ctrl_alt_del)
+ os.symlink('/lib/systemd/system/reboot.target', systemd_ctrl_alt_del)
+
+ elif opt['ctrl_alt_del'] == 'poweroff':
+ if os.path.exists(systemd_ctrl_alt_del):
+ os.unlink(systemd_ctrl_alt_del)
+ os.symlink('/lib/systemd/system/poweroff.target', systemd_ctrl_alt_del)
+
+ # Reboot system on kernel panic
+ with open('/proc/sys/kernel/panic', 'w') as f:
+ if opt['reboot_on_panic']:
+ f.write('60')
+ else:
+ f.write('0')
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
+
diff --git a/src/conf_mode/timezone.py b/src/conf_mode/system-timezone.py
index d715bd27e..d715bd27e 100755
--- a/src/conf_mode/timezone.py
+++ b/src/conf_mode/system-timezone.py
diff --git a/src/migration-scripts/l2tp/1-to-2 b/src/migration-scripts/l2tp/1-to-2
new file mode 100755
index 000000000..c46eba8f8
--- /dev/null
+++ b/src/migration-scripts/l2tp/1-to-2
@@ -0,0 +1,33 @@
+#!/usr/bin/env python3
+
+# Delete depricated outside-nexthop address
+
+import sys
+
+from vyos.configtree import ConfigTree
+
+if (len(sys.argv) < 1):
+ print("Must specify file name!")
+ sys.exit(1)
+
+file_name = sys.argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+config = ConfigTree(config_file)
+
+cfg_base = ['vpn', 'l2tp', 'remote-access']
+if not config.exists(cfg_base):
+ # Nothing to do
+ sys.exit(0)
+else:
+ if config.exists(cfg_base + ['outside-nexthop']):
+ config.delete(cfg_base + ['outside-nexthop'])
+
+ try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+ except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ sys.exit(1)
diff --git a/src/migration-scripts/system/13-to-14 b/src/migration-scripts/system/13-to-14
new file mode 100755
index 000000000..c055dad1f
--- /dev/null
+++ b/src/migration-scripts/system/13-to-14
@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+#
+# Delete 'system ipv6 blacklist' option as the IPv6 module can no longer be
+# blacklisted as it is required by e.g. WireGuard and thus will always be
+# loaded.
+
+import os
+import sys
+
+ipv6_blacklist_file = '/etc/modprobe.d/vyatta_blacklist_ipv6.conf'
+
+from vyos.configtree import ConfigTree
+
+if (len(sys.argv) < 1):
+ print("Must specify file name!")
+ sys.exit(1)
+
+file_name = sys.argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+config = ConfigTree(config_file)
+ip_base = ['system', 'ipv6']
+if not config.exists(ip_base):
+ # Nothing to do
+ sys.exit(0)
+else:
+ # delete 'system ipv6 blacklist' node
+ if config.exists(ip_base + ['blacklist']):
+ config.delete(ip_base + ['blacklist'])
+ if os.path.isfile(ipv6_blacklist_file):
+ os.unlink(ipv6_blacklist_file)
+
+ try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+ except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ sys.exit(1)
diff --git a/src/migration-scripts/system/14-to-15 b/src/migration-scripts/system/14-to-15
new file mode 100755
index 000000000..fd89ae57a
--- /dev/null
+++ b/src/migration-scripts/system/14-to-15
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+#
+# Make 'system options reboot-on-panic' valueless
+
+import os
+import sys
+
+from vyos.configtree import ConfigTree
+
+if (len(sys.argv) < 1):
+ print("Must specify file name!")
+ sys.exit(1)
+
+file_name = sys.argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+config = ConfigTree(config_file)
+base = ['system', 'options']
+if not config.exists(base):
+ # Nothing to do
+ sys.exit(0)
+else:
+ # delete 'system ipv6 blacklist' node
+ if config.exists(base + ['reboot-on-panic']):
+ reboot = config.return_value(base + ['reboot-on-panic'])
+ config.delete(base + ['reboot-on-panic'])
+ # create new valueless node if action was true
+ if reboot == "true":
+ config.set(base + ['reboot-on-panic'])
+
+ try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+ except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ sys.exit(1)