diff options
Diffstat (limited to 'src')
22 files changed, 174 insertions, 22 deletions
diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py index 431d65f1f..661dc2298 100755 --- a/src/conf_mode/interfaces-bonding.py +++ b/src/conf_mode/interfaces-bonding.py @@ -27,8 +27,10 @@ from vyos.configdict import is_source_interface from vyos.configverify import verify_address from vyos.configverify import verify_bridge_delete from vyos.configverify import verify_dhcpv6 -from vyos.configverify import verify_source_interface +from vyos.configverify import verify_mirror from vyos.configverify import verify_mtu_ipv6 +from vyos.configverify import verify_redirect +from vyos.configverify import verify_source_interface from vyos.configverify import verify_vlan_config from vyos.configverify import verify_vrf from vyos.ifconfig import BondIf @@ -132,10 +134,10 @@ def verify(bond): return None if 'arp_monitor' in bond: - if 'target' in bond['arp_monitor'] and len(int(bond['arp_monitor']['target'])) > 16: + if 'target' in bond['arp_monitor'] and len(bond['arp_monitor']['target']) > 16: raise ConfigError('The maximum number of arp-monitor targets is 16') - if 'interval' in bond['arp_monitor'] and len(int(bond['arp_monitor']['interval'])) > 0: + if 'interval' in bond['arp_monitor'] and int(bond['arp_monitor']['interval']) > 0: if bond['mode'] in ['802.3ad', 'balance-tlb', 'balance-alb']: raise ConfigError('ARP link monitoring does not work for mode 802.3ad, ' \ 'transmit-load-balance or adaptive-load-balance') @@ -149,6 +151,8 @@ def verify(bond): verify_address(bond) verify_dhcpv6(bond) verify_vrf(bond) + verify_mirror(bond) + verify_redirect(bond) # use common function to verify VLAN configuration verify_vlan_config(bond) diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py index f4dba9d4a..e16c0e9f4 100755 --- a/src/conf_mode/interfaces-bridge.py +++ b/src/conf_mode/interfaces-bridge.py @@ -27,6 +27,8 @@ from vyos.configdict import is_source_interface from vyos.configdict import has_vlan_subinterface_configured from vyos.configdict import dict_merge from vyos.configverify import verify_dhcpv6 +from vyos.configverify import verify_mirror +from vyos.configverify import verify_redirect from vyos.configverify import verify_vrf from vyos.ifconfig import BridgeIf from vyos.validate import has_address_configured @@ -105,6 +107,8 @@ def verify(bridge): verify_dhcpv6(bridge) verify_vrf(bridge) + verify_mirror(bridge) + verify_redirect(bridge) ifname = bridge['ifname'] diff --git a/src/conf_mode/interfaces-dummy.py b/src/conf_mode/interfaces-dummy.py index 55c783f38..4072c4452 100755 --- a/src/conf_mode/interfaces-dummy.py +++ b/src/conf_mode/interfaces-dummy.py @@ -21,6 +21,7 @@ from vyos.configdict import get_interface_dict from vyos.configverify import verify_vrf from vyos.configverify import verify_address from vyos.configverify import verify_bridge_delete +from vyos.configverify import verify_redirect from vyos.ifconfig import DummyIf from vyos import ConfigError from vyos import airbag @@ -46,6 +47,7 @@ def verify(dummy): verify_vrf(dummy) verify_address(dummy) + verify_redirect(dummy) return None diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index 2a8a126f2..3eeddf190 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -28,6 +28,7 @@ from vyos.configverify import verify_interface_exists from vyos.configverify import verify_mirror from vyos.configverify import verify_mtu from vyos.configverify import verify_mtu_ipv6 +from vyos.configverify import verify_redirect from vyos.configverify import verify_vlan_config from vyos.configverify import verify_vrf from vyos.ethtool import Ethtool @@ -84,6 +85,7 @@ def verify(ethernet): verify_vrf(ethernet) verify_eapol(ethernet) verify_mirror(ethernet) + verify_redirect(ethernet) ethtool = Ethtool(ifname) # No need to check speed and duplex keys as both have default values. diff --git a/src/conf_mode/interfaces-geneve.py b/src/conf_mode/interfaces-geneve.py index 2a63b60aa..a94b5e1f7 100755 --- a/src/conf_mode/interfaces-geneve.py +++ b/src/conf_mode/interfaces-geneve.py @@ -24,6 +24,7 @@ from vyos.configdict import get_interface_dict from vyos.configverify import verify_address from vyos.configverify import verify_mtu_ipv6 from vyos.configverify import verify_bridge_delete +from vyos.configverify import verify_redirect from vyos.ifconfig import GeneveIf from vyos import ConfigError @@ -50,6 +51,7 @@ def verify(geneve): verify_mtu_ipv6(geneve) verify_address(geneve) + verify_redirect(geneve) if 'remote' not in geneve: raise ConfigError('Remote side must be configured') diff --git a/src/conf_mode/interfaces-l2tpv3.py b/src/conf_mode/interfaces-l2tpv3.py index 9b6ddd5aa..5ea7159dc 100755 --- a/src/conf_mode/interfaces-l2tpv3.py +++ b/src/conf_mode/interfaces-l2tpv3.py @@ -25,6 +25,7 @@ from vyos.configdict import leaf_node_changed from vyos.configverify import verify_address from vyos.configverify import verify_bridge_delete from vyos.configverify import verify_mtu_ipv6 +from vyos.configverify import verify_redirect from vyos.ifconfig import L2TPv3If from vyos.util import check_kmod from vyos.validate import is_addr_assigned @@ -76,6 +77,7 @@ def verify(l2tpv3): verify_mtu_ipv6(l2tpv3) verify_address(l2tpv3) + verify_redirect(l2tpv3) return None def generate(l2tpv3): diff --git a/src/conf_mode/interfaces-loopback.py b/src/conf_mode/interfaces-loopback.py index 193334443..e6a851113 100755 --- a/src/conf_mode/interfaces-loopback.py +++ b/src/conf_mode/interfaces-loopback.py @@ -20,6 +20,7 @@ from sys import exit from vyos.config import Config from vyos.configdict import get_interface_dict +from vyos.configverify import verify_redirect from vyos.ifconfig import LoopbackIf from vyos import ConfigError from vyos import airbag @@ -39,6 +40,7 @@ def get_config(config=None): return loopback def verify(loopback): + verify_redirect(loopback) return None def generate(loopback): diff --git a/src/conf_mode/interfaces-macsec.py b/src/conf_mode/interfaces-macsec.py index eab69f36e..6a29fdb11 100755 --- a/src/conf_mode/interfaces-macsec.py +++ b/src/conf_mode/interfaces-macsec.py @@ -29,6 +29,7 @@ from vyos.configverify import verify_vrf from vyos.configverify import verify_address from vyos.configverify import verify_bridge_delete from vyos.configverify import verify_mtu_ipv6 +from vyos.configverify import verify_redirect from vyos.configverify import verify_source_interface from vyos import ConfigError from vyos import airbag @@ -66,6 +67,7 @@ def verify(macsec): verify_vrf(macsec) verify_mtu_ipv6(macsec) verify_address(macsec) + verify_redirect(macsec) if not (('security' in macsec) and ('cipher' in macsec['security'])): diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py index 29a25eedc..c30c0bdd0 100755 --- a/src/conf_mode/interfaces-openvpn.py +++ b/src/conf_mode/interfaces-openvpn.py @@ -32,6 +32,7 @@ from shutil import rmtree from vyos.config import Config from vyos.configdict import get_interface_dict +from vyos.configdict import leaf_node_changed from vyos.configverify import verify_vrf from vyos.configverify import verify_bridge_delete from vyos.ifconfig import VTunIf @@ -88,6 +89,9 @@ def get_config(config=None): if 'deleted' not in openvpn: openvpn['pki'] = tmp_pki + tmp = leaf_node_changed(conf, ['openvpn-option']) + if tmp: openvpn['restart_required'] = '' + # We have to get the dict using 'get_config_dict' instead of 'get_interface_dict' # as 'get_interface_dict' merges the defaults in, so we can not check for defaults in there. tmp = conf.get_config_dict(base + [openvpn['ifname']], get_first_key=True) @@ -651,7 +655,10 @@ def apply(openvpn): # No matching OpenVPN process running - maybe it got killed or none # existed - nevertheless, spawn new OpenVPN process - call(f'systemctl reload-or-restart openvpn@{interface}.service') + action = 'reload-or-restart' + if 'restart_required' in openvpn: + action = 'restart' + call(f'systemctl {action} openvpn@{interface}.service') o = VTunIf(**openvpn) o.update(openvpn) diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py index 584adc75e..9962e0a08 100755 --- a/src/conf_mode/interfaces-pppoe.py +++ b/src/conf_mode/interfaces-pppoe.py @@ -28,6 +28,7 @@ from vyos.configverify import verify_source_interface from vyos.configverify import verify_interface_exists from vyos.configverify import verify_vrf from vyos.configverify import verify_mtu_ipv6 +from vyos.configverify import verify_redirect from vyos.ifconfig import PPPoEIf from vyos.template import render from vyos.util import call @@ -85,6 +86,7 @@ def verify(pppoe): verify_authentication(pppoe) verify_vrf(pppoe) verify_mtu_ipv6(pppoe) + verify_redirect(pppoe) if {'connect_on_demand', 'vrf'} <= set(pppoe): raise ConfigError('On-demand dialing and VRF can not be used at the same time') diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py index 945a2ea9c..f57e41cc4 100755 --- a/src/conf_mode/interfaces-pseudo-ethernet.py +++ b/src/conf_mode/interfaces-pseudo-ethernet.py @@ -25,6 +25,7 @@ from vyos.configverify import verify_bridge_delete from vyos.configverify import verify_source_interface from vyos.configverify import verify_vlan_config from vyos.configverify import verify_mtu_parent +from vyos.configverify import verify_redirect from vyos.ifconfig import MACVLANIf from vyos import ConfigError @@ -60,6 +61,7 @@ def verify(peth): verify_vrf(peth) verify_address(peth) verify_mtu_parent(peth, peth['parent']) + verify_redirect(peth) # use common function to verify VLAN configuration verify_vlan_config(peth) diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index 433764b8a..005fae5eb 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -26,6 +26,7 @@ from vyos.configverify import verify_address from vyos.configverify import verify_bridge_delete from vyos.configverify import verify_interface_exists from vyos.configverify import verify_mtu_ipv6 +from vyos.configverify import verify_redirect from vyos.configverify import verify_vrf from vyos.configverify import verify_tunnel from vyos.ifconfig import Interface @@ -157,6 +158,7 @@ def verify(tunnel): verify_mtu_ipv6(tunnel) verify_address(tunnel) verify_vrf(tunnel) + verify_redirect(tunnel) if 'source_interface' in tunnel: verify_interface_exists(tunnel['source_interface']) diff --git a/src/conf_mode/interfaces-vti.py b/src/conf_mode/interfaces-vti.py index 57950ffea..30e13536f 100755 --- a/src/conf_mode/interfaces-vti.py +++ b/src/conf_mode/interfaces-vti.py @@ -19,6 +19,7 @@ from sys import exit from vyos.config import Config from vyos.configdict import get_interface_dict +from vyos.configverify import verify_redirect from vyos.ifconfig import VTIIf from vyos.util import dict_search from vyos import ConfigError @@ -39,6 +40,7 @@ def get_config(config=None): return vti def verify(vti): + verify_redirect(vti) return None def generate(vti): diff --git a/src/conf_mode/interfaces-vxlan.py b/src/conf_mode/interfaces-vxlan.py index 29b16af89..a29836efd 100755 --- a/src/conf_mode/interfaces-vxlan.py +++ b/src/conf_mode/interfaces-vxlan.py @@ -25,6 +25,7 @@ from vyos.configdict import leaf_node_changed from vyos.configverify import verify_address from vyos.configverify import verify_bridge_delete from vyos.configverify import verify_mtu_ipv6 +from vyos.configverify import verify_redirect from vyos.configverify import verify_source_interface from vyos.ifconfig import Interface from vyos.ifconfig import VXLANIf @@ -140,6 +141,7 @@ def verify(vxlan): verify_mtu_ipv6(vxlan) verify_address(vxlan) + verify_redirect(vxlan) return None def generate(vxlan): diff --git a/src/conf_mode/interfaces-wireguard.py b/src/conf_mode/interfaces-wireguard.py index da64dd076..dc0fe7b9c 100755 --- a/src/conf_mode/interfaces-wireguard.py +++ b/src/conf_mode/interfaces-wireguard.py @@ -28,6 +28,7 @@ from vyos.configverify import verify_vrf from vyos.configverify import verify_address from vyos.configverify import verify_bridge_delete from vyos.configverify import verify_mtu_ipv6 +from vyos.configverify import verify_redirect from vyos.ifconfig import WireGuardIf from vyos.util import check_kmod from vyos.util import check_port_availability @@ -70,6 +71,7 @@ def verify(wireguard): verify_mtu_ipv6(wireguard) verify_address(wireguard) verify_vrf(wireguard) + verify_redirect(wireguard) if 'private_key' not in wireguard: raise ConfigError('Wireguard private-key not defined') diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py index af35b5f03..fdf9e3988 100755 --- a/src/conf_mode/interfaces-wireless.py +++ b/src/conf_mode/interfaces-wireless.py @@ -27,6 +27,7 @@ from vyos.configverify import verify_address from vyos.configverify import verify_bridge_delete from vyos.configverify import verify_dhcpv6 from vyos.configverify import verify_source_interface +from vyos.configverify import verify_redirect from vyos.configverify import verify_vlan_config from vyos.configverify import verify_vrf from vyos.ifconfig import WiFiIf @@ -189,6 +190,7 @@ def verify(wifi): verify_address(wifi) verify_vrf(wifi) + verify_redirect(wifi) # use common function to verify VLAN configuration verify_vlan_config(wifi) diff --git a/src/conf_mode/interfaces-wwan.py b/src/conf_mode/interfaces-wwan.py index a4b033374..367a50e82 100755 --- a/src/conf_mode/interfaces-wwan.py +++ b/src/conf_mode/interfaces-wwan.py @@ -23,6 +23,7 @@ from vyos.config import Config from vyos.configdict import get_interface_dict from vyos.configverify import verify_authentication from vyos.configverify import verify_interface_exists +from vyos.configverify import verify_redirect from vyos.configverify import verify_vrf from vyos.ifconfig import WWANIf from vyos.util import cmd @@ -77,6 +78,7 @@ def verify(wwan): verify_interface_exists(ifname) verify_authentication(wwan) verify_vrf(wwan) + verify_redirect(wwan) return None diff --git a/src/conf_mode/protocols_ospf.py b/src/conf_mode/protocols_ospf.py index 4895cde6f..26d491838 100755 --- a/src/conf_mode/protocols_ospf.py +++ b/src/conf_mode/protocols_ospf.py @@ -25,6 +25,7 @@ from vyos.configdict import node_changed from vyos.configverify import verify_common_route_maps from vyos.configverify import verify_route_map from vyos.configverify import verify_interface_exists +from vyos.configverify import verify_access_list from vyos.template import render_to_string from vyos.util import dict_search from vyos.util import get_interface_config @@ -159,6 +160,16 @@ def verify(ospf): route_map_name = dict_search('default_information.originate.route_map', ospf) if route_map_name: verify_route_map(route_map_name, ospf) + # Validate if configured Access-list exists + if 'area' in ospf: + for area, area_config in ospf['area'].items(): + if 'import_list' in area_config: + acl_import = area_config['import_list'] + if acl_import: verify_access_list(acl_import, ospf) + if 'export_list' in area_config: + acl_export = area_config['export_list'] + if acl_export: verify_access_list(acl_export, ospf) + if 'interface' in ospf: for interface, interface_config in ospf['interface'].items(): verify_interface_exists(interface) diff --git a/src/conf_mode/qos.py b/src/conf_mode/qos.py new file mode 100755 index 000000000..cf447d4b5 --- /dev/null +++ b/src/conf_mode/qos.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2022 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 exit + +from vyos.config import Config +from vyos.configdict import dict_merge +from vyos.xml import defaults +from vyos import ConfigError +from vyos import airbag +airbag.enable() + +def get_config(config=None): + if config: + conf = config + else: + conf = Config() + base = ['traffic-policy'] + if not conf.exists(base): + return None + + qos = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) + + for traffic_policy in ['drop-tail', 'fair-queue', 'fq-codel', 'limiter', + 'network-emulator', 'priority-queue', 'random-detect', + 'rate-control', 'round-robin', 'shaper', 'shaper-hfsc']: + traffic_policy_us = traffic_policy.replace('-','_') + # Individual policy type not present on CLI - no need to blend in + # any default values + if traffic_policy_us not in qos: + continue + + default_values = defaults(base + [traffic_policy_us]) + + # class is another tag node which requires individual handling + class_default_values = defaults(base + [traffic_policy_us, 'class']) + if 'class' in default_values: + del default_values['class'] + + for policy, policy_config in qos[traffic_policy_us].items(): + qos[traffic_policy_us][policy] = dict_merge( + default_values, qos[traffic_policy_us][policy]) + + if 'class' in policy_config: + for policy_class in policy_config['class']: + qos[traffic_policy_us][policy]['class'][policy_class] = dict_merge( + class_default_values, qos[traffic_policy_us][policy]['class'][policy_class]) + + import pprint + pprint.pprint(qos) + return qos + +def verify(qos): + if not qos: + return None + + # network policy emulator + # reorder rerquires delay to be set + + raise ConfigError('123') + return None + +def generate(qos): + return None + +def apply(qos): + return None + +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/migration-scripts/bgp/0-to-1 b/src/migration-scripts/bgp/0-to-1 index b1d5a6514..5e9dffe1f 100755 --- a/src/migration-scripts/bgp/0-to-1 +++ b/src/migration-scripts/bgp/0-to-1 @@ -33,7 +33,7 @@ with open(file_name, 'r') as f: base = ['protocols', 'bgp'] config = ConfigTree(config_file) -if not config.exists(base): +if not config.exists(base) or not config.is_tag(base): # Nothing to do exit(0) diff --git a/src/op_mode/generate_public_key_command.py b/src/op_mode/generate_public_key_command.py index 7a7b6c923..f071ae350 100755 --- a/src/op_mode/generate_public_key_command.py +++ b/src/op_mode/generate_public_key_command.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2021 VyOS maintainers and contributors +# Copyright (C) 2022 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 @@ -29,8 +29,12 @@ def get_key(path): key_string = vyos.remote.get_remote_config(path) return key_string.split() -username = sys.argv[1] -algorithm, key, identifier = get_key(sys.argv[2]) +try: + username = sys.argv[1] + algorithm, key, identifier = get_key(sys.argv[2]) +except Exception as e: + print("Failed to retrieve the public key: {}".format(e)) + sys.exit(1) print('# To add this key as an embedded key, run the following commands:') print('configure') @@ -39,3 +43,4 @@ print(f'set system login user {username} authentication public-keys {identifier} print('commit') print('save') print('exit') + diff --git a/src/validators/ipv6-range b/src/validators/ipv6-range index a3c401281..7080860c4 100755 --- a/src/validators/ipv6-range +++ b/src/validators/ipv6-range @@ -1,17 +1,20 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 -import sys -import re -from vyos.template import is_ipv6 +from ipaddress import IPv6Address +from sys import argv, exit if __name__ == '__main__': - if len(sys.argv)>1: - ipv6_range = sys.argv[1] - # Regex for ipv6-ipv6 https://regexr.com/ - if re.search('([a-f0-9:]+:+)+[a-f0-9]+-([a-f0-9:]+:+)+[a-f0-9]+', ipv6_range): - for tmp in ipv6_range.split('-'): - if not is_ipv6(tmp): - print(f'Error: {ipv6_range} is not a valid IPv6 range') - sys.exit(1) - - sys.exit(0) + if len(argv) > 1: + # try to pass validation and raise an error if failed + try: + ipv6_range = argv[1] + range_left = ipv6_range.split('-')[0] + range_right = ipv6_range.split('-')[1] + if not IPv6Address(range_left) < IPv6Address(range_right): + raise ValueError(f'left element {range_left} must be less than right element {range_right}') + except Exception as err: + print(f'Error: {ipv6_range} is not a valid IPv6 range: {err}') + exit(1) + else: + print('Error: an IPv6 range argument must be provided') + exit(1) |