summaryrefslogtreecommitdiff
path: root/src/conf_mode
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-xsrc/conf_mode/conntrack.py2
-rwxr-xr-xsrc/conf_mode/containers.py4
-rwxr-xr-xsrc/conf_mode/interfaces-openvpn.py5
-rwxr-xr-xsrc/conf_mode/interfaces-vti.py10
-rwxr-xr-xsrc/conf_mode/le_cert.py4
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py10
-rwxr-xr-xsrc/conf_mode/protocols_isis.py14
-rwxr-xr-xsrc/conf_mode/protocols_ospf.py2
-rwxr-xr-xsrc/conf_mode/protocols_ospfv3.py4
-rwxr-xr-xsrc/conf_mode/snmp.py6
-rwxr-xr-xsrc/conf_mode/system-option.py3
-rwxr-xr-xsrc/conf_mode/vpn_ipsec.py18
-rwxr-xr-xsrc/conf_mode/vrf.py21
-rwxr-xr-xsrc/conf_mode/vrf_vni.py76
14 files changed, 136 insertions, 43 deletions
diff --git a/src/conf_mode/conntrack.py b/src/conf_mode/conntrack.py
index 4e6e39c0f..b305265db 100755
--- a/src/conf_mode/conntrack.py
+++ b/src/conf_mode/conntrack.py
@@ -97,7 +97,7 @@ def apply(conntrack):
# Depending on the enable/disable state of the ALG (Application Layer Gateway)
# modules we need to either insmod or rmmod the helpers.
for module, module_config in module_map.items():
- if dict_search(f'modules.{module}.disable', conntrack) != None:
+ if dict_search(f'modules.{module}', conntrack) is None:
if 'ko' in module_config:
for mod in module_config['ko']:
# Only remove the module if it's loaded
diff --git a/src/conf_mode/containers.py b/src/conf_mode/containers.py
index 21b47f42a..7544bd840 100755
--- a/src/conf_mode/containers.py
+++ b/src/conf_mode/containers.py
@@ -142,9 +142,9 @@ def verify(container):
# Add new network
if 'network' in container:
- v4_prefix = 0
- v6_prefix = 0
for network, network_config in container['network'].items():
+ v4_prefix = 0
+ v6_prefix = 0
# If ipv4-prefix not defined for user-defined network
if 'prefix' not in network_config:
raise ConfigError(f'prefix for network "{net}" must be defined!')
diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py
index 74e29ed82..6be4e918b 100755
--- a/src/conf_mode/interfaces-openvpn.py
+++ b/src/conf_mode/interfaces-openvpn.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2021 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
@@ -273,6 +273,9 @@ def verify(openvpn):
if openvpn['protocol'] == 'tcp-active':
raise ConfigError('Protocol "tcp-active" is not valid in server mode')
+ if dict_search('authentication.username', openvpn) or dict_search('authentication.password', openvpn):
+ raise ConfigError('Cannot specify "authentication" in server mode')
+
if 'remote_port' in openvpn:
raise ConfigError('Cannot specify "remote-port" in server mode')
diff --git a/src/conf_mode/interfaces-vti.py b/src/conf_mode/interfaces-vti.py
index 1b38304c1..57950ffea 100755
--- a/src/conf_mode/interfaces-vti.py
+++ b/src/conf_mode/interfaces-vti.py
@@ -45,13 +45,13 @@ def generate(vti):
return None
def apply(vti):
- if vti['ifname'] in interfaces():
- # Always delete the VTI interface in advance
+ # Remove macsec interface
+ if 'deleted' in vti:
VTIIf(**vti).remove()
+ return None
- if 'deleted' not in vti:
- tmp = VTIIf(**vti)
- tmp.update(vti)
+ tmp = VTIIf(**vti)
+ tmp.update(vti)
return None
diff --git a/src/conf_mode/le_cert.py b/src/conf_mode/le_cert.py
index 755c89966..6e169a3d5 100755
--- a/src/conf_mode/le_cert.py
+++ b/src/conf_mode/le_cert.py
@@ -22,6 +22,7 @@ from vyos.config import Config
from vyos import ConfigError
from vyos.util import cmd
from vyos.util import call
+from vyos.util import is_systemd_service_running
from vyos import airbag
airbag.enable()
@@ -87,8 +88,7 @@ def generate(cert):
# certbot will attempt to reload nginx, even with 'certonly';
# start nginx if not active
- ret = call('systemctl is-active --quiet nginx.service')
- if ret:
+ if not is_systemd_service_running('nginx.service'):
call('systemctl start nginx.service')
request_certbot(cert)
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py
index 1a2fabded..9ecfd07fe 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -57,6 +57,11 @@ def get_config(config=None):
if not conf.exists(base):
bgp.update({'deleted' : ''})
+ if not vrf:
+ # We are running in the default VRF context, thus we can not delete
+ # our main BGP instance if there are dependent BGP VRF instances.
+ bgp['dependent_vrfs'] = conf.get_config_dict(['vrf', 'name'],
+ key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True)
return bgp
# We also need some additional information from the config, prefix-lists
@@ -96,6 +101,11 @@ def verify_remote_as(peer_config, bgp_config):
def verify(bgp):
if not bgp or 'deleted' in bgp:
+ if 'dependent_vrfs' in bgp:
+ for vrf, vrf_options in bgp['dependent_vrfs'].items():
+ if dict_search('protocols.bgp', vrf_options) != None:
+ raise ConfigError('Cannot delete default BGP instance, ' \
+ 'dependent VRF instance(s) exist!')
return None
if 'local_as' not in bgp:
diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py
index 50c48db28..4cf0312e9 100755
--- a/src/conf_mode/protocols_isis.py
+++ b/src/conf_mode/protocols_isis.py
@@ -113,9 +113,13 @@ def verify(isis):
# Interface MTU must be >= configured lsp-mtu
mtu = Interface(interface).get_mtu()
area_mtu = isis['lsp_mtu']
- if mtu < int(area_mtu):
- raise ConfigError(f'Interface {interface} has MTU {mtu}, minimum ' \
- f'area MTU is {area_mtu}!')
+ # Recommended maximum PDU size = interface MTU - 3 bytes
+ recom_area_mtu = mtu - 3
+ if mtu < int(area_mtu) or int(area_mtu) > recom_area_mtu:
+ raise ConfigError(f'Interface {interface} has MTU {mtu}, ' \
+ f'current area MTU is {area_mtu}! \n' \
+ f'Recommended area lsp-mtu {recom_area_mtu} or less ' \
+ '(calculated on MTU size).')
if 'vrf' in isis:
# If interface specific options are set, we must ensure that the
@@ -149,7 +153,7 @@ def verify(isis):
# If Redistribute set, but level don't set
if 'redistribute' in isis:
proc_level = isis.get('level','').replace('-','_')
- for afi in ['ipv4']:
+ for afi in ['ipv4', 'ipv6']:
if afi not in isis['redistribute']:
continue
@@ -198,7 +202,7 @@ def generate(isis):
isis['protocol'] = 'isis' # required for frr/vrf.route-map.frr.tmpl
isis['frr_zebra_config'] = render_to_string('frr/vrf.route-map.frr.tmpl', isis)
- isis['frr_isisd_config'] = render_to_string('frr/isis.frr.tmpl', isis)
+ isis['frr_isisd_config'] = render_to_string('frr/isisd.frr.tmpl', isis)
return None
def apply(isis):
diff --git a/src/conf_mode/protocols_ospf.py b/src/conf_mode/protocols_ospf.py
index 78c1c82bd..82126cb11 100755
--- a/src/conf_mode/protocols_ospf.py
+++ b/src/conf_mode/protocols_ospf.py
@@ -177,7 +177,7 @@ def generate(ospf):
ospf['protocol'] = 'ospf' # required for frr/vrf.route-map.frr.tmpl
ospf['frr_zebra_config'] = render_to_string('frr/vrf.route-map.frr.tmpl', ospf)
- ospf['frr_ospfd_config'] = render_to_string('frr/ospf.frr.tmpl', ospf)
+ ospf['frr_ospfd_config'] = render_to_string('frr/ospfd.frr.tmpl', ospf)
return None
def apply(ospf):
diff --git a/src/conf_mode/protocols_ospfv3.py b/src/conf_mode/protocols_ospfv3.py
index fef0f509b..536ffa690 100755
--- a/src/conf_mode/protocols_ospfv3.py
+++ b/src/conf_mode/protocols_ospfv3.py
@@ -65,7 +65,7 @@ def verify(ospfv3):
if 'ifmtu' in if_config:
mtu = Interface(ifname).get_mtu()
if int(if_config['ifmtu']) > int(mtu):
- raise ConfigError(f'OSPFv3 ifmtu cannot go beyond physical MTU of "{mtu}"')
+ raise ConfigError(f'OSPFv3 ifmtu can not exceed physical MTU of "{mtu}"')
return None
@@ -74,7 +74,7 @@ def generate(ospfv3):
ospfv3['new_frr_config'] = ''
return None
- ospfv3['new_frr_config'] = render_to_string('frr/ospfv3.frr.tmpl', ospfv3)
+ ospfv3['new_frr_config'] = render_to_string('frr/ospf6d.frr.tmpl', ospfv3)
return None
def apply(ospfv3):
diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py
index 3990e5735..23e45a5b7 100755
--- a/src/conf_mode/snmp.py
+++ b/src/conf_mode/snmp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-2021 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
@@ -54,6 +54,7 @@ default_config_data = {
'location' : '',
'description' : '',
'contact' : '',
+ 'route_table': 'False',
'trap_source': '',
'trap_targets': [],
'vyos_user': '',
@@ -186,6 +187,9 @@ def get_config():
snmp['script_ext'].append(extension)
+ if conf.exists('oid-enable route-table'):
+ snmp['route_table'] = True
+
if conf.exists('vrf'):
# Append key to dict but don't place it in the default dictionary.
# This is required to make the override.conf.tmpl work until we
diff --git a/src/conf_mode/system-option.py b/src/conf_mode/system-option.py
index 454611c55..55cf6b142 100755
--- a/src/conf_mode/system-option.py
+++ b/src/conf_mode/system-option.py
@@ -24,6 +24,7 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
from vyos.util import cmd
+from vyos.util import is_systemd_service_running
from vyos.validate import is_addr_assigned
from vyos.xml import defaults
from vyos import ConfigError
@@ -114,7 +115,7 @@ def apply(options):
if 'performance' in options:
cmd('systemctl restart tuned.service')
# wait until daemon has started before sending configuration
- while (int(os.system('systemctl is-active --quiet tuned.service')) != 0):
+ while (not is_systemd_service_running('tuned.service')):
sleep(0.250)
cmd('tuned-adm profile network-{performance}'.format(**options))
else:
diff --git a/src/conf_mode/vpn_ipsec.py b/src/conf_mode/vpn_ipsec.py
index a4cd33e64..d3065fc47 100755
--- a/src/conf_mode/vpn_ipsec.py
+++ b/src/conf_mode/vpn_ipsec.py
@@ -102,9 +102,20 @@ def get_config(config=None):
ipsec['esp_group'][group])
if 'ike_group' in ipsec:
default_values = defaults(base + ['ike-group'])
+ # proposal is a tag node which may come with individual defaults per node
+ if 'proposal' in default_values:
+ del default_values['proposal']
+
for group in ipsec['ike_group']:
ipsec['ike_group'][group] = dict_merge(default_values,
ipsec['ike_group'][group])
+
+ if 'proposal' in ipsec['ike_group'][group]:
+ default_values = defaults(base + ['ike-group', 'proposal'])
+ for proposal in ipsec['ike_group'][group]['proposal']:
+ ipsec['ike_group'][group]['proposal'][proposal] = dict_merge(default_values,
+ ipsec['ike_group'][group]['proposal'][proposal])
+
if 'remote_access' in ipsec and 'connection' in ipsec['remote_access']:
default_values = defaults(base + ['remote-access', 'connection'])
for rw in ipsec['remote_access']['connection']:
@@ -133,7 +144,7 @@ def get_config(config=None):
l2tp_defaults = defaults(l2tp_base)
ipsec['l2tp'] = dict_merge(l2tp_defaults, ipsec['l2tp'])
ipsec['l2tp_outside_address'] = conf.return_value(['vpn', 'l2tp', 'remote-access', 'outside-address'])
- ipsec['l2tp_ike_default'] = 'aes256-sha1-modp1024,3des-sha1-modp1024,3des-sha1-modp1024'
+ ipsec['l2tp_ike_default'] = 'aes256-sha1-modp1024,3des-sha1-modp1024'
ipsec['l2tp_esp_default'] = 'aes256-sha1,3des-sha1'
return ipsec
@@ -250,6 +261,11 @@ def verify(ipsec):
if 'ike_group' in ra_conf:
if 'ike_group' not in ipsec or ra_conf['ike_group'] not in ipsec['ike_group']:
raise ConfigError(f"Invalid ike-group on {name} remote-access config")
+
+ ike = ra_conf['ike_group']
+ if dict_search(f'ike_group.{ike}.key_exchange', ipsec) != 'ikev2':
+ raise ConfigError('IPSec remote-access connections requires IKEv2!')
+
else:
raise ConfigError(f"Missing ike-group on {name} remote-access config")
diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py
index 82956b219..919083ac4 100755
--- a/src/conf_mode/vrf.py
+++ b/src/conf_mode/vrf.py
@@ -24,7 +24,6 @@ from vyos.config import Config
from vyos.configdict import node_changed
from vyos.ifconfig import Interface
from vyos.template import render
-from vyos.template import render_to_string
from vyos.util import call
from vyos.util import cmd
from vyos.util import dict_search
@@ -32,12 +31,9 @@ from vyos.util import get_interface_config
from vyos.util import popen
from vyos.util import run
from vyos import ConfigError
-from vyos import frr
from vyos import airbag
airbag.enable()
-frr_daemon = 'zebra'
-
config_file = r'/etc/iproute2/rt_tables.d/vyos-vrf.conf'
def list_rules():
@@ -131,7 +127,6 @@ def verify(vrf):
def generate(vrf):
render(config_file, 'vrf/vrf.conf.tmpl', vrf)
- vrf['new_frr_config'] = render_to_string('frr/vrf.frr.tmpl', vrf)
# Render nftables zones config
vrf['nft_vrf_zones'] = NamedTemporaryFile().name
render(vrf['nft_vrf_zones'], 'firewall/nftables-vrf-zones.tmpl', vrf)
@@ -242,22 +237,6 @@ def apply(vrf):
if tmp == 0:
cmd('nft delete table inet vrf_zones')
- # add configuration to FRR
- frr_cfg = frr.FRRConfig()
- frr_cfg.load_configuration(frr_daemon)
- frr_cfg.modify_section(f'^vrf [a-zA-Z-]*$', '')
- frr_cfg.add_before(r'(interface .*|line vty)', vrf['new_frr_config'])
- frr_cfg.commit_configuration(frr_daemon)
-
- # If FRR config is blank, rerun the blank commit x times due to frr-reload
- # behavior/bug not properly clearing out on one commit.
- if vrf['new_frr_config'] == '':
- for a in range(5):
- frr_cfg.commit_configuration(frr_daemon)
-
- # Save configuration to /run/frr/config/frr.conf
- frr.save_configuration()
-
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/vrf_vni.py b/src/conf_mode/vrf_vni.py
new file mode 100755
index 000000000..87ee8f2d1
--- /dev/null
+++ b/src/conf_mode/vrf_vni.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020-2021 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/>.
+
+from sys import argv
+from sys import exit
+
+from vyos.config import Config
+from vyos.template import render_to_string
+from vyos import ConfigError
+from vyos import frr
+from vyos import airbag
+airbag.enable()
+
+frr_daemon = 'zebra'
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+
+ # This script only works with a passed VRF name
+ if len(argv) < 1:
+ raise NotImplementedError
+ vrf = argv[1]
+
+ # "assemble" dict - easier here then use a full blown get_config_dict()
+ # on a single leafNode
+ vni = { 'vrf' : vrf }
+ tmp = conf.return_value(['vrf', 'name', vrf, 'vni'])
+ if tmp: vni.update({ 'vni' : tmp })
+
+ return vni
+
+def verify(vni):
+ return None
+
+def generate(vni):
+ vni['new_frr_config'] = render_to_string('frr/vrf-vni.frr.tmpl', vni)
+ return None
+
+def apply(vni):
+ # add configuration to FRR
+ frr_cfg = frr.FRRConfig()
+ frr_cfg.load_configuration(frr_daemon)
+ frr_cfg.modify_section(f'^vrf [a-zA-Z-]*$', '')
+ frr_cfg.add_before(r'(interface .*|line vty)', vni['new_frr_config'])
+ frr_cfg.commit_configuration(frr_daemon)
+
+ # Save configuration to /run/frr/config/frr.conf
+ frr.save_configuration()
+
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)