diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/conf_mode/protocols_bgp.py | 9 | ||||
| -rwxr-xr-x | src/conf_mode/service_dhcpv6-server.py | 44 | ||||
| -rw-r--r-- | src/etc/dhcp/dhclient-exit-hooks.d/03-vyos-dhclient-hook | 1 | ||||
| -rwxr-xr-x | src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook | 4 | ||||
| -rwxr-xr-x | src/migration-scripts/bgp/0-to-1 | 2 | ||||
| -rwxr-xr-x | src/migration-scripts/bgp/1-to-2 | 12 | ||||
| -rwxr-xr-x | src/migration-scripts/dhcpv6-server/3-to-4 | 35 | ||||
| -rwxr-xr-x | src/migration-scripts/ipsec/12-to-13 | 52 | ||||
| -rwxr-xr-x | src/migration-scripts/nat/5-to-6 | 5 | ||||
| -rwxr-xr-x | src/migration-scripts/ospf/0-to-1 | 4 | ||||
| -rwxr-xr-x | src/op_mode/dhcp.py | 9 | ||||
| -rwxr-xr-x | src/op_mode/powerctrl.py | 4 | 
12 files changed, 145 insertions, 36 deletions
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py index 89e2aab8c..f6f3370c3 100755 --- a/src/conf_mode/protocols_bgp.py +++ b/src/conf_mode/protocols_bgp.py @@ -220,9 +220,12 @@ def verify_afi(peer_config, bgp_config):      # If address_family configured under peer-group      # if neighbor interface configured -    peer_group_name = '' +    peer_group_name = None      if dict_search('interface.peer_group', peer_config):          peer_group_name = peer_config['interface']['peer_group'] +    elif dict_search('interface.v6only.peer_group', peer_config): +        peer_group_name = peer_config['interface']['v6only']['peer_group'] +      # if neighbor IP configured.      if 'peer_group' in peer_config:          peer_group_name = peer_config['peer_group'] @@ -542,6 +545,10 @@ def verify(bgp):                      tmp = dict_search(f'route_map.vpn.{export_import}', afi_config)                      if tmp: verify_route_map(tmp, bgp) +                # per-vrf sid and per-af sid are mutually exclusive +                if 'sid' in afi_config and 'sid' in bgp: +                    raise ConfigError('SID per VRF and SID per address-family are mutually exclusive!') +              # Checks only required for L2VPN EVPN              if afi in ['l2vpn_evpn']:                  if 'vni' in afi_config: diff --git a/src/conf_mode/service_dhcpv6-server.py b/src/conf_mode/service_dhcpv6-server.py index 7cd801cdd..214531904 100755 --- a/src/conf_mode/service_dhcpv6-server.py +++ b/src/conf_mode/service_dhcpv6-server.py @@ -81,26 +81,29 @@ def verify(dhcpv6):              subnet_ids.append(subnet_config['subnet_id']) -            if 'address_range' in subnet_config: -                if 'start' in subnet_config['address_range']: -                    range6_start = [] -                    range6_stop = [] -                    for start, start_config in subnet_config['address_range']['start'].items(): -                        if 'stop' not in start_config: -                            raise ConfigError(f'address-range stop address for start "{start}" is not defined!') -                        stop = start_config['stop'] +            if 'range' in subnet_config: +                range6_start = [] +                range6_stop = [] + +                for num, range_config in subnet_config['range'].items(): +                    if 'start' in range_config: +                        start = range_config['start'] + +                        if 'stop' not in range_config: +                            raise ConfigError(f'Range stop address for start "{start}" is not defined!') +                        stop = range_config['stop']                          # Start address must be inside network                          if not ip_address(start) in ip_network(subnet): -                            raise ConfigError(f'address-range start address "{start}" is not in subnet "{subnet}"!') +                            raise ConfigError(f'Range start address "{start}" is not in subnet "{subnet}"!')                          # Stop address must be inside network                          if not ip_address(stop) in ip_network(subnet): -                             raise ConfigError(f'address-range stop address "{stop}" is not in subnet "{subnet}"!') +                             raise ConfigError(f'Range stop address "{stop}" is not in subnet "{subnet}"!')                          # Stop address must be greater or equal to start address                          if not ip_address(stop) >= ip_address(start): -                            raise ConfigError(f'address-range stop address "{stop}" must be greater then or equal ' \ +                            raise ConfigError(f'Range stop address "{stop}" must be greater then or equal ' \                                                f'to the range start address "{start}"!')                          # DHCPv6 range start address must be unique - two ranges can't @@ -108,6 +111,7 @@ def verify(dhcpv6):                          if start in range6_start:                              raise ConfigError(f'Conflicting DHCPv6 lease range: '\                                                f'Pool start address "{start}" defined multipe times!') +                          range6_start.append(start)                          # DHCPv6 range stop address must be unique - two ranges can't @@ -115,12 +119,14 @@ def verify(dhcpv6):                          if stop in range6_stop:                              raise ConfigError(f'Conflicting DHCPv6 lease range: '\                                                f'Pool stop address "{stop}" defined multipe times!') +                          range6_stop.append(stop) -                if 'prefix' in subnet_config: -                    for prefix in subnet_config['prefix']: -                        if ip_network(prefix) not in ip_network(subnet): -                            raise ConfigError(f'address-range prefix "{prefix}" is not in subnet "{subnet}""') +                    if 'prefix' in range_config: +                        prefix = range_config['prefix'] + +                        if not ip_network(prefix).subnet_of(ip_network(subnet)): +                            raise ConfigError(f'Range prefix "{prefix}" is not in subnet "{subnet}"')              # Prefix delegation sanity checks              if 'prefix_delegation' in subnet_config: @@ -151,13 +157,15 @@ def verify(dhcpv6):                              raise ConfigError(f'Either MAC address or Client identifier (DUID) is required for '                                                f'static mapping "{mapping}" within shared-network "{network}, {subnet}"!') -            if 'vendor_option' in subnet_config: -                if len(dict_search('vendor_option.cisco.tftp_server', subnet_config)) > 2: -                    raise ConfigError(f'No more then two Cisco tftp-servers should be defined for subnet "{subnet}"!') +            if 'option' in subnet_config: +                if 'vendor_option' in subnet_config['option']: +                    if len(dict_search('option.vendor_option.cisco.tftp_server', subnet_config)) > 2: +                        raise ConfigError(f'No more then two Cisco tftp-servers should be defined for subnet "{subnet}"!')              # Subnets must be unique              if subnet in subnets:                  raise ConfigError(f'DHCPv6 subnets must be unique! Subnet {subnet} defined multiple times!') +              subnets.append(subnet)          # DHCPv6 requires at least one configured address range or one static mapping diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/03-vyos-dhclient-hook b/src/etc/dhcp/dhclient-exit-hooks.d/03-vyos-dhclient-hook index 35721d009..d5e6462ba 100644 --- a/src/etc/dhcp/dhclient-exit-hooks.d/03-vyos-dhclient-hook +++ b/src/etc/dhcp/dhclient-exit-hooks.d/03-vyos-dhclient-hook @@ -29,6 +29,7 @@ fi  if [ "$RUN" = "yes" ]; then          BASE_PATH=$(python3 -c "from vyos.defaults import directories; print(directories['isc_dhclient_dir'])") +        mkdir -p ${BASE_PATH}          LOG=${BASE_PATH}/dhclient_"$interface"."$proto"lease          echo `date` > $LOG diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook b/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook index c7a92fe26..e6edc1ac3 100755 --- a/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook +++ b/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook @@ -71,10 +71,6 @@ if __name__ == '__main__':                  conf_lines[i] = line.replace(old_ip, new_ip)                  found = True -        for i, line in enumerate(secrets_lines): -            if line.find(to_match) > 0: -                secrets_lines[i] = line.replace(old_ip, new_ip) -          if found:              write_file(SWANCTL_CONF, conf_lines)              ipsec_down(old_ip) diff --git a/src/migration-scripts/bgp/0-to-1 b/src/migration-scripts/bgp/0-to-1 index 03c45107b..5b8e8a163 100755 --- a/src/migration-scripts/bgp/0-to-1 +++ b/src/migration-scripts/bgp/0-to-1 @@ -14,7 +14,7 @@  # You should have received a copy of the GNU General Public License  # along with this program.  If not, see <http://www.gnu.org/licenses/>. -# T3417: migrate IS-IS tagNode to node as we can only have one IS-IS process +# T3417: migrate BGP tagNode to node as we can only have one BGP process  from sys import argv  from sys import exit diff --git a/src/migration-scripts/bgp/1-to-2 b/src/migration-scripts/bgp/1-to-2 index 96b939b47..a40d86e67 100755 --- a/src/migration-scripts/bgp/1-to-2 +++ b/src/migration-scripts/bgp/1-to-2 @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2021-2022 VyOS maintainers and contributors +# Copyright (C) 2021-2024 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 @@ -15,6 +15,7 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # T3741: no-ipv4-unicast is now enabled by default +# T5937: Migrate IPv6 BGP Neighbor Peer Groups  from sys import argv  from sys import exit @@ -66,6 +67,15 @@ else:              if not config.exists(afi_ipv4):                  config.set(afi_ipv4) +# Migrate IPv6 AFI peer-group +if config.exists(base + ['neighbor']): +    for neighbor in config.list_nodes(base + ['neighbor']): +        tmp_path = base + ['neighbor', neighbor, 'address-family', 'ipv6-unicast', 'peer-group'] +        if config.exists(tmp_path): +            peer_group = config.return_value(tmp_path) +            config.set(base + ['neighbor', neighbor, 'peer-group'], value=peer_group) +            config.delete(tmp_path) +  try:      with open(file_name, 'w') as f:          f.write(config.to_string()) diff --git a/src/migration-scripts/dhcpv6-server/3-to-4 b/src/migration-scripts/dhcpv6-server/3-to-4 index c065e3d43..4747ebd60 100755 --- a/src/migration-scripts/dhcpv6-server/3-to-4 +++ b/src/migration-scripts/dhcpv6-server/3-to-4 @@ -16,6 +16,8 @@  # T3316:  # - Add subnet IDs to existing subnets +# - Move options to option node +# - Migrate address-range to range tagNode  import sys  import re @@ -37,6 +39,10 @@ if not config.exists(base):      # Nothing to do      sys.exit(0) +option_nodes = ['captive-portal', 'domain-search', 'name-server', +                'nis-domain', 'nis-server', 'nisplus-domain', 'nisplus-server', +                'sip-server', 'sntp-server', 'vendor-option'] +  subnet_id = 1  for network in config.list_nodes(base): @@ -44,6 +50,35 @@ for network in config.list_nodes(base):          for subnet in config.list_nodes(base + [network, 'subnet']):              base_subnet = base + [network, 'subnet', subnet] +            if config.exists(base_subnet + ['address-range']): +                config.set(base_subnet + ['range']) +                config.set_tag(base_subnet + ['range']) + +                range_id = 1 + +                if config.exists(base_subnet + ['address-range', 'prefix']): +                    for prefix in config.return_values(base_subnet + ['address-range', 'prefix']): +                        config.set(base_subnet + ['range', range_id, 'prefix'], value=prefix) + +                        range_id += 1 + +                if config.exists(base_subnet + ['address-range', 'start']): +                    for start in config.list_nodes(base_subnet + ['address-range', 'start']): +                        stop = config.return_value(base_subnet + ['address-range', 'start', start, 'stop']) + +                        config.set(base_subnet + ['range', range_id, 'start'], value=start) +                        config.set(base_subnet + ['range', range_id, 'stop'], value=stop) + +                        range_id += 1 + +                config.delete(base_subnet + ['address-range']) + +            for option in option_nodes: +                if config.exists(base_subnet + [option]): +                    config.set(base_subnet + ['option']) +                    config.copy(base_subnet + [option], base_subnet + ['option', option]) +                    config.delete(base_subnet + [option]) +              config.set(base_subnet + ['subnet-id'], value=subnet_id)              subnet_id += 1 diff --git a/src/migration-scripts/ipsec/12-to-13 b/src/migration-scripts/ipsec/12-to-13 new file mode 100755 index 000000000..504a2e9c7 --- /dev/null +++ b/src/migration-scripts/ipsec/12-to-13 @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 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/>. + +# Changed value of dead-peer-detection.action from hold to trap + +import re + +from sys import argv +from sys import exit + +from vyos.configtree import ConfigTree + +if len(argv) < 2: +    print("Must specify file name!") +    exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: +    config_file = f.read() + +base = ['vpn', 'ipsec', 'ike-group'] +config = ConfigTree(config_file) + +if not config.exists(base): +    # Nothing to do +    exit(0) +else: +    for ike_group in config.list_nodes(base): +        base_dpd_action = base + [ike_group, 'dead-peer-detection', 'action'] +        if config.exists(base_dpd_action) and config.return_value(base_dpd_action) == 'hold': +            config.set(base_dpd_action, 'trap', replace=True) + +try: +    with open(file_name, 'w') as f: +        f.write(config.to_string()) +except OSError as e: +    print(f'Failed to save the modified config: {e}') +    exit(1) diff --git a/src/migration-scripts/nat/5-to-6 b/src/migration-scripts/nat/5-to-6 index de3830582..c83b93d84 100755 --- a/src/migration-scripts/nat/5-to-6 +++ b/src/migration-scripts/nat/5-to-6 @@ -51,8 +51,9 @@ for direction in ['source', 'destination']:          for iface in ['inbound-interface','outbound-interface']:              if config.exists(base + [iface]):                  tmp = config.return_value(base + [iface]) -                config.delete(base + [iface]) -                config.set(base + [iface, 'interface-name'], value=tmp) +                if tmp: +                    config.delete(base + [iface]) +                    config.set(base + [iface, 'interface-name'], value=tmp)  try:      with open(file_name, 'w') as f: diff --git a/src/migration-scripts/ospf/0-to-1 b/src/migration-scripts/ospf/0-to-1 index 8f02acada..a6cb9feb8 100755 --- a/src/migration-scripts/ospf/0-to-1 +++ b/src/migration-scripts/ospf/0-to-1 @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2021 VyOS maintainers and contributors +# Copyright (C) 2021-2024 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 @@ -28,6 +28,7 @@ def ospf_passive_migration(config, ospf_base):                      default = True                      continue                  config.set(ospf_base + ['interface', interface, 'passive']) +                config.set_tag(ospf_base + ['interface'])              config.delete(ospf_base + ['passive-interface'])              config.set(ospf_base + ['passive-interface'], value='default') @@ -35,6 +36,7 @@ def ospf_passive_migration(config, ospf_base):          if config.exists(ospf_base + ['passive-interface-exclude']):              for interface in config.return_values(ospf_base + ['passive-interface-exclude']):                  config.set(ospf_base + ['interface', interface, 'passive', 'disable']) +                config.set_tag(ospf_base + ['interface'])              config.delete(ospf_base + ['passive-interface-exclude'])  if len(argv) < 2: diff --git a/src/op_mode/dhcp.py b/src/op_mode/dhcp.py index 02f4d5bbb..a64acec31 100755 --- a/src/op_mode/dhcp.py +++ b/src/op_mode/dhcp.py @@ -194,14 +194,11 @@ def _get_pool_size(pool, family='inet'):      size = 0      subnets = config.list_nodes(f'{base} subnet')      for subnet in subnets: -        if family == 'inet6': -            ranges = config.list_nodes(f'{base} subnet {subnet} address-range start') -        else: -            ranges = config.list_nodes(f'{base} subnet {subnet} range') +        ranges = config.list_nodes(f'{base} subnet {subnet} range')          for range in ranges:              if family == 'inet6': -                start = config.list_nodes(f'{base} subnet {subnet} address-range start')[0] -                stop = config.value(f'{base} subnet {subnet} address-range start {start} stop') +                start = config.value(f'{base} subnet {subnet} range {range} start') +                stop = config.value(f'{base} subnet {subnet} range {range} stop')              else:                  start = config.value(f'{base} subnet {subnet} range {range} start')                  stop = config.value(f'{base} subnet {subnet} range {range} stop') diff --git a/src/op_mode/powerctrl.py b/src/op_mode/powerctrl.py index 3ac5991b4..c07d0c4bd 100755 --- a/src/op_mode/powerctrl.py +++ b/src/op_mode/powerctrl.py @@ -191,7 +191,7 @@ def main():                          nargs="*",                          metavar="HH:MM") -    action.add_argument("--reboot_in", "-i", +    action.add_argument("--reboot-in", "-i",                          help="Reboot the system",                          nargs="*",                          metavar="Minutes") @@ -214,7 +214,7 @@ def main():          if args.reboot is not None:              for r in args.reboot:                  if ':' not in r and '/' not in r and '.' not in r: -                    print("Incorrect  format! Use HH:MM") +                    print("Incorrect format! Use HH:MM")                      exit(1)              execute_shutdown(args.reboot, reboot=True, ask=args.yes)          if args.reboot_in is not None:  | 
