diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/protocols_isis.py | 16 | ||||
-rwxr-xr-x | src/conf_mode/system_conntrack.py | 16 | ||||
-rwxr-xr-x | src/etc/ipsec.d/vti-up-down | 4 | ||||
-rwxr-xr-x | src/helpers/priority.py | 42 | ||||
-rwxr-xr-x | src/helpers/vyos_config_sync.py | 48 | ||||
-rwxr-xr-x | src/migration-scripts/policy/3-to-4 | 8 | ||||
-rwxr-xr-x | src/op_mode/conntrack.py | 3 | ||||
-rwxr-xr-x | src/services/vyos-http-api-server | 2 |
8 files changed, 94 insertions, 45 deletions
diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py index 8d594bb68..6c9925b80 100755 --- a/src/conf_mode/protocols_isis.py +++ b/src/conf_mode/protocols_isis.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020-2022 VyOS maintainers and contributors +# Copyright (C) 2020-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 @@ -155,12 +155,12 @@ def verify(isis): for proto, proto_config in isis['redistribute'][afi].items(): if 'level_1' not in proto_config and 'level_2' not in proto_config: raise ConfigError(f'Redistribute level-1 or level-2 should be specified in ' \ - f'"protocols isis {process} redistribute {afi} {proto}"!') + f'"protocols isis redistribute {afi} {proto}"!') for redistr_level, redistr_config in proto_config.items(): if proc_level and proc_level != 'level_1_2' and proc_level != redistr_level: - raise ConfigError(f'"protocols isis {process} redistribute {afi} {proto} {redistr_level}" ' \ - f'can not be used with \"protocols isis {process} level {proc_level}\"') + raise ConfigError(f'"protocols isis redistribute {afi} {proto} {redistr_level}" ' \ + f'can not be used with \"protocols isis level {proc_level}\"!') # Segment routing checks if dict_search('segment_routing.global_block', isis): @@ -220,8 +220,8 @@ def verify(isis): if ("explicit_null" in prefix_config['index']) and ("no_php_flag" in prefix_config['index']): raise ConfigError(f'Segment routing prefix {prefix} cannot have both explicit-null '\ f'and no-php-flag configured at the same time.') - - # Check for index ranges being larger than the segment routing global block + + # Check for index ranges being larger than the segment routing global block if dict_search('segment_routing.global_block', isis): g_high_label_value = dict_search('segment_routing.global_block.high_label_value', isis) g_low_label_value = dict_search('segment_routing.global_block.low_label_value', isis) @@ -233,7 +233,7 @@ def verify(isis): if int(index_size) > int(g_label_difference): raise ConfigError(f'Segment routing prefix {prefix} cannot have an '\ f'index base size larger than the SRGB label base.') - + # Check for LFA tiebreaker index duplication if dict_search('fast_reroute.lfa.local.tiebreaker', isis): comparison_dictionary = {} @@ -311,4 +311,4 @@ if __name__ == '__main__': apply(c) except ConfigError as e: print(e) - exit(1)
\ No newline at end of file + exit(1) diff --git a/src/conf_mode/system_conntrack.py b/src/conf_mode/system_conntrack.py index a1472aaaa..3d42389f6 100755 --- a/src/conf_mode/system_conntrack.py +++ b/src/conf_mode/system_conntrack.py @@ -185,12 +185,16 @@ def generate(conntrack): conntrack['ipv4_firewall_action'] = 'return' conntrack['ipv6_firewall_action'] = 'return' - for rules, path in dict_search_recursive(conntrack['firewall'], 'rule'): - if any(('state' in rule_conf or 'connection_status' in rule_conf or 'offload_target' in rule_conf) for rule_conf in rules.values()): - if path[0] == 'ipv4': - conntrack['ipv4_firewall_action'] = 'accept' - elif path[0] == 'ipv6': - conntrack['ipv6_firewall_action'] = 'accept' + if dict_search_args(conntrack['firewall'], 'global_options', 'state_policy') != None: + conntrack['ipv4_firewall_action'] = 'accept' + conntrack['ipv6_firewall_action'] = 'accept' + else: + for rules, path in dict_search_recursive(conntrack['firewall'], 'rule'): + if any(('state' in rule_conf or 'connection_status' in rule_conf or 'offload_target' in rule_conf) for rule_conf in rules.values()): + if path[0] == 'ipv4': + conntrack['ipv4_firewall_action'] = 'accept' + elif path[0] == 'ipv6': + conntrack['ipv6_firewall_action'] = 'accept' render(conntrack_config, 'conntrack/vyos_nf_conntrack.conf.j2', conntrack) render(sysctl_file, 'conntrack/sysctl.conf.j2', conntrack) diff --git a/src/etc/ipsec.d/vti-up-down b/src/etc/ipsec.d/vti-up-down index 441b316c2..01e9543c9 100755 --- a/src/etc/ipsec.d/vti-up-down +++ b/src/etc/ipsec.d/vti-up-down @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2021-2023 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 @@ -57,7 +57,9 @@ if __name__ == '__main__': if 'disable' not in vti: tmp = VTIIf(interface) tmp.update(vti) + call(f'sudo ip link set {interface} up') else: + call(f'sudo ip link set {interface} down') syslog(f'Interface {interface} is admin down ...') elif verb in ['down-client', 'down-host']: if vti_link_up: diff --git a/src/helpers/priority.py b/src/helpers/priority.py new file mode 100755 index 000000000..04186104c --- /dev/null +++ b/src/helpers/priority.py @@ -0,0 +1,42 @@ +#!/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/>. +# +# + +import sys +from argparse import ArgumentParser +from tabulate import tabulate + +from vyos.priority import get_priority_data + +if __name__ == '__main__': + parser = ArgumentParser() + parser.add_argument('--legacy-format', action='store_true', + help="format output for comparison with legacy 'priority.pl'") + args = parser.parse_args() + + prio_list = get_priority_data() + if args.legacy_format: + for p in prio_list: + print(f'{p[2]} {"/".join(p[0])}') + sys.exit(0) + + l = [] + for p in prio_list: + l.append((p[2], p[1], p[0])) + headers = ['priority', 'owner', 'path'] + out = tabulate(l, headers, numalign='right') + print(out) diff --git a/src/helpers/vyos_config_sync.py b/src/helpers/vyos_config_sync.py index 572fea61f..77f7cd810 100755 --- a/src/helpers/vyos_config_sync.py +++ b/src/helpers/vyos_config_sync.py @@ -61,14 +61,16 @@ def post_request(url: str, -def retrieve_config(section: str = None) -> Optional[Dict[str, Any]]: +def retrieve_config(section: Optional[List[str]] = None) -> Optional[Dict[str, Any]]: """Retrieves the configuration from the local server. Args: - section: str: The section of the configuration to retrieve. Default is None. + section: List[str]: The section of the configuration to retrieve. + Default is None. Returns: - Optional[Dict[str, Any]]: The retrieved configuration as a dictionary, or None if an error occurred. + Optional[Dict[str, Any]]: The retrieved configuration as a + dictionary, or None if an error occurred. """ if section is None: section = [] @@ -83,23 +85,21 @@ def retrieve_config(section: str = None) -> Optional[Dict[str, Any]]: def set_remote_config( address: str, key: str, - op: str, - path: str = None, - section: Optional[str] = None) -> Optional[Dict[str, Any]]: + commands: List[Dict[str, Any]]) -> Optional[Dict[str, Any]]: """Loads the VyOS configuration in JSON format to a remote host. Args: address (str): The address of the remote host. key (str): The key to use for loading the configuration. - path (Optional[str]): The path of the configuration. Default is None. - section (Optional[str]): The section of the configuration to load. Default is None. + commands (list): List of set/load commands for request, given as: + [{'op': str, 'path': list[str], 'section': dict}, + ...] Returns: - Optional[Dict[str, Any]]: The response from the remote host as a dictionary, or None if an error occurred. + Optional[Dict[str, Any]]: The response from the remote host as a + dictionary, or None if a RequestException occurred. """ - if path is None: - path = [] headers = {'Content-Type': 'application/json'} # Disable the InsecureRequestWarning @@ -107,9 +107,7 @@ def set_remote_config( url = f'https://{address}/configure-section' data = json.dumps({ - 'op': mode, - 'path': path, - 'section': section, + 'commands': commands, 'key': key }) @@ -122,14 +120,14 @@ def set_remote_config( return None -def is_section_revised(section: str) -> bool: +def is_section_revised(section: List[str]) -> bool: from vyos.config_mgmt import is_node_revised return is_node_revised(section) def config_sync(secondary_address: str, secondary_key: str, - sections: List[list], + sections: List[list[str]], mode: str): """Retrieve a config section from primary router in JSON format and send it to secondary router @@ -142,21 +140,25 @@ def config_sync(secondary_address: str, ) # Sync sections ("nat", "firewall", etc) + commands = [] for section in sections: config_json = retrieve_config(section=section) # Check if config path deesn't exist, for example "set nat" # we set empty value for config_json data # As we cannot send to the remote host section "nat None" config if not config_json: - config_json = "" + config_json = {} logger.debug( f"Retrieved config for section '{section}': {config_json}") - set_config = set_remote_config(address=secondary_address, - key=secondary_key, - op=mode, - path=section, - section=config_json) - logger.debug(f"Set config for section '{section}': {set_config}") + + d = {'op': mode, 'path': section, 'section': config_json} + commands.append(d) + + set_config = set_remote_config(address=secondary_address, + key=secondary_key, + commands=commands) + + logger.debug(f"Set config for sections '{sections}': {set_config}") if __name__ == '__main__': diff --git a/src/migration-scripts/policy/3-to-4 b/src/migration-scripts/policy/3-to-4 index 1ebb248b0..476fa3af2 100755 --- a/src/migration-scripts/policy/3-to-4 +++ b/src/migration-scripts/policy/3-to-4 @@ -51,7 +51,7 @@ def community_migrate(config: ConfigTree, rule: list[str]) -> bool: :rtype: bool """ community_list = list((config.return_value(rule)).split(" ")) - + config.delete(rule) if 'none' in community_list: config.set(rule + ['none']) return False @@ -61,10 +61,8 @@ def community_migrate(config: ConfigTree, rule: list[str]) -> bool: community_action = 'add' community_list.remove('additive') for community in community_list: - if len(community): - config.set(rule + [community_action], value=community, - replace=False) - config.delete(rule) + config.set(rule + [community_action], value=community, + replace=False) if community_action == 'replace': return False else: diff --git a/src/op_mode/conntrack.py b/src/op_mode/conntrack.py index cf8adf795..6ea213bec 100755 --- a/src/op_mode/conntrack.py +++ b/src/op_mode/conntrack.py @@ -112,7 +112,8 @@ def get_formatted_output(dict_data): proto = meta['layer4']['protoname'] if direction == 'independent': conn_id = meta['id'] - timeout = meta['timeout'] + # T6138 flowtable offload conntrack entries without 'timeout' + timeout = meta.get('timeout', 'n/a') orig_src = f'{orig_src}:{orig_sport}' if orig_sport else orig_src orig_dst = f'{orig_dst}:{orig_dport}' if orig_dport else orig_dst reply_src = f'{reply_src}:{reply_sport}' if reply_sport else reply_src diff --git a/src/services/vyos-http-api-server b/src/services/vyos-http-api-server index a7b14a1a3..77870a84c 100755 --- a/src/services/vyos-http-api-server +++ b/src/services/vyos-http-api-server @@ -463,7 +463,7 @@ def _configure_op(data: Union[ConfigureModel, ConfigureListModel, endpoint = request.url.path # Allow users to pass just one command - if not isinstance(data, ConfigureListModel): + if not isinstance(data, (ConfigureListModel, ConfigSectionListModel)): data = [data] else: data = data.commands |