diff options
| -rw-r--r-- | data/templates/frr/bgpd.frr.j2 | 8 | ||||
| -rw-r--r-- | interface-definitions/include/bgp/neighbor-disable-connected-check.xml.i | 2 | ||||
| -rw-r--r-- | interface-definitions/include/bgp/protocol-common-config.xml.i | 6 | ||||
| -rw-r--r-- | python/vyos/firewall.py | 6 | ||||
| -rw-r--r-- | python/vyos/ifconfig/interface.py | 2 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_protocols_bgp.py | 15 | ||||
| -rwxr-xr-x | src/conf_mode/firewall.py | 9 | ||||
| -rwxr-xr-x | src/conf_mode/nat.py | 8 | ||||
| -rwxr-xr-x | src/conf_mode/nat66.py | 6 | ||||
| -rwxr-xr-x | src/conf_mode/policy_route.py | 4 | ||||
| -rwxr-xr-x | src/conf_mode/protocols_nhrp.py | 4 | ||||
| -rwxr-xr-x | src/conf_mode/system_conntrack.py | 7 | ||||
| -rwxr-xr-x | src/conf_mode/vrf.py | 11 | ||||
| -rwxr-xr-x | src/helpers/vyos-domain-resolver.py | 7 | ||||
| -rwxr-xr-x | src/init/vyos-router | 2 | 
15 files changed, 54 insertions, 43 deletions
| diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2 index e9422b257..e5bfad59d 100644 --- a/data/templates/frr/bgpd.frr.j2 +++ b/data/templates/frr/bgpd.frr.j2 @@ -290,10 +290,7 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }}  {%         endif %}  {%         if afi_config.aggregate_address is vyos_defined %}  {%             for aggregate, aggregate_config in afi_config.aggregate_address.items() %} -  aggregate-address {{ aggregate }}{{ ' as-set' if aggregate_config.as_set is vyos_defined }}{{ ' summary-only' if aggregate_config.summary_only is vyos_defined }} -{%                 if aggregate_config.route_map is vyos_defined %} -  aggregate-address {{ aggregate }} route-map {{ aggregate_config.route_map }} -{%                 endif %} +  aggregate-address {{ aggregate }} {{ 'as-set' if aggregate_config.as_set is vyos_defined }} {{ 'summary-only' if aggregate_config.summary_only is vyos_defined }} {{ 'route-map ' ~ aggregate_config.route_map if aggregate_config.route_map is vyos_defined }}  {%             endfor %}  {%         endif %}  {%         if afi_config.maximum_paths.ebgp is vyos_defined %} @@ -537,6 +534,9 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }}  {% if parameters.allow_martian_nexthop is vyos_defined %}   bgp allow-martian-nexthop  {% endif %} +{% if parameters.disable_ebgp_connected_route_check is vyos_defined %} + bgp disable-ebgp-connected-route-check +{% endif %}  {% if parameters.always_compare_med is vyos_defined %}   bgp always-compare-med  {% endif %} diff --git a/interface-definitions/include/bgp/neighbor-disable-connected-check.xml.i b/interface-definitions/include/bgp/neighbor-disable-connected-check.xml.i index cb8b610b4..aef5a55e9 100644 --- a/interface-definitions/include/bgp/neighbor-disable-connected-check.xml.i +++ b/interface-definitions/include/bgp/neighbor-disable-connected-check.xml.i @@ -1,7 +1,7 @@  <!-- include start from bgp/neighbor-disable-connected-check.xml.i -->  <leafNode name="disable-connected-check">    <properties> -    <help>Disable check to see if eBGP peer address is a connected route</help> +    <help>Allow peerings between eBGP peer using loopback/dummy address</help>      <valueless/>    </properties>  </leafNode> diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i index ca67eaf3c..0f05625a7 100644 --- a/interface-definitions/include/bgp/protocol-common-config.xml.i +++ b/interface-definitions/include/bgp/protocol-common-config.xml.i @@ -1249,6 +1249,12 @@          <valueless/>        </properties>      </leafNode> +    <leafNode name="disable-ebgp-connected-route-check"> +      <properties> +        <help>Disable checking if nexthop is connected on eBGP session</help> +        <valueless/> +      </properties> +    </leafNode>      <leafNode name="always-compare-med">        <properties>          <help>Always compare MEDs from different neighbors</help> diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index e70b4f0d9..e29aeb0c6 100644 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -66,7 +66,7 @@ def fqdn_config_parse(firewall):          rule = path[4]          suffix = path[5][0]          set_name = f'{hook_name}_{priority}_{rule}_{suffix}' -             +          if (path[0] == 'ipv4') and (path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name'):              firewall['ip_fqdn'][set_name] = domain          elif (path[0] == 'ipv6') and (path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name'): @@ -85,7 +85,7 @@ def fqdn_resolve(fqdn, ipv6=False):  def find_nftables_rule(table, chain, rule_matches=[]):      # Find rule in table/chain that matches all criteria and return the handle -    results = cmd(f'sudo nft -a list chain {table} {chain}').split("\n") +    results = cmd(f'sudo nft --handle list chain {table} {chain}').split("\n")      for line in results:          if all(rule_match in line for rule_match in rule_matches):              handle_search = re.search('handle (\d+)', line) @@ -655,7 +655,7 @@ def geoip_update(firewall, force=False):              'ipv6_sets': ipv6_sets          }) -        result = run(f'nft -f {nftables_geoip_conf}') +        result = run(f'nft --file {nftables_geoip_conf}')          if result != 0:              print('Error: GeoIP failed to update firewall')              return False diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index c87fb9c71..b2cb621bc 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -415,7 +415,7 @@ class Interface(Control):          else:              nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ "{self.ifname}" }}'              # Check if deleting is possible first to avoid raising errors -            _, err = self._popen(f'nft -c {nft_del_element}') +            _, err = self._popen(f'nft --check {nft_del_element}')              if not err:                  # Remove map element                  self._cmd(f'nft {nft_del_element}') diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index e8556cf44..60c49b8b4 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -321,6 +321,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):          tcp_keepalive_probes = '22'          self.cli_set(base_path + ['parameters', 'allow-martian-nexthop']) +        self.cli_set(base_path + ['parameters', 'disable-ebgp-connected-route-check'])          self.cli_set(base_path + ['parameters', 'no-hard-administrative-reset'])          self.cli_set(base_path + ['parameters', 'log-neighbor-changes'])          self.cli_set(base_path + ['parameters', 'labeled-unicast', 'explicit-null']) @@ -372,6 +373,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):          self.assertIn(f'router bgp {ASN}', frrconfig)          self.assertIn(f' bgp router-id {router_id}', frrconfig)          self.assertIn(f' bgp allow-martian-nexthop', frrconfig) +        self.assertIn(f' bgp disable-ebgp-connected-route-check', frrconfig)          self.assertIn(f' bgp log-neighbor-changes', frrconfig)          self.assertIn(f' bgp default local-preference {local_pref}', frrconfig)          self.assertIn(f' bgp conditional-advertisement timer {cond_adv_timer}', frrconfig) @@ -628,6 +630,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):          networks = {              '10.0.0.0/8' : {                  'as_set' : '', +                'summary_only' : '', +                'route_map' : route_map_in,                  },              '100.64.0.0/10' : {                  'as_set' : '', @@ -652,6 +656,9 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):              if 'summary_only' in network_config:                  self.cli_set(base_path + ['address-family', 'ipv4-unicast',                                                'aggregate-address', network, 'summary-only']) +            if 'route_map' in network_config: +                self.cli_set(base_path + ['address-family', 'ipv4-unicast', +                                              'aggregate-address', network, 'route-map', network_config['route_map']])          # commit changes          self.cli_commit() @@ -666,10 +673,14 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):          for network, network_config in networks.items():              self.assertIn(f' network {network}', frrconfig) +            command = f'aggregate-address {network}'              if 'as_set' in network_config: -                self.assertIn(f' aggregate-address {network} as-set', frrconfig) +                command = f'{command} as-set'              if 'summary_only' in network_config: -                self.assertIn(f' aggregate-address {network} summary-only', frrconfig) +                command = f'{command} summary-only' +            if 'route_map' in network_config: +                command = f'{command} route-map {network_config["route_map"]}' +            self.assertIn(command, frrconfig)      def test_bgp_05_afi_ipv6(self):          networks = { diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index 810437dda..3cf618363 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -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 @@ -18,7 +18,6 @@ import os  import re  from glob import glob -from json import loads  from sys import exit  from vyos.base import Warning @@ -31,11 +30,9 @@ from vyos.ethtool import Ethtool  from vyos.firewall import fqdn_config_parse  from vyos.firewall import geoip_update  from vyos.template import render -from vyos.utils.process import call -from vyos.utils.process import cmd  from vyos.utils.dict import dict_search_args  from vyos.utils.dict import dict_search_recursive -from vyos.utils.process import process_named_running +from vyos.utils.process import call  from vyos.utils.process import rc_cmd  from vyos import ConfigError  from vyos import airbag @@ -491,7 +488,7 @@ def apply_sysfs(firewall):                      f.write(value)  def apply(firewall): -    install_result, output = rc_cmd(f'nft -f {nftables_conf}') +    install_result, output = rc_cmd(f'nft --file {nftables_conf}')      if install_result == 1:          raise ConfigError(f'Failed to apply firewall: {output}') diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py index b3f38c04a..76c07a9ec 100755 --- a/src/conf_mode/nat.py +++ b/src/conf_mode/nat.py @@ -223,19 +223,19 @@ def generate(nat):      render(nftables_static_nat_conf, 'firewall/nftables-static-nat.j2', nat)      # dry-run newly generated configuration -    tmp = run(f'nft -c -f {nftables_nat_config}') +    tmp = run(f'nft --check --file {nftables_nat_config}')      if tmp > 0:          raise ConfigError('Configuration file errors encountered!') -    tmp = run(f'nft -c -f {nftables_static_nat_conf}') +    tmp = run(f'nft --check --file {nftables_static_nat_conf}')      if tmp > 0:          raise ConfigError('Configuration file errors encountered!')      return None  def apply(nat): -    cmd(f'nft -f {nftables_nat_config}') -    cmd(f'nft -f {nftables_static_nat_conf}') +    cmd(f'nft --file {nftables_nat_config}') +    cmd(f'nft --file {nftables_static_nat_conf}')      if not nat or 'deleted' in nat:          os.unlink(nftables_nat_config) diff --git a/src/conf_mode/nat66.py b/src/conf_mode/nat66.py index 4c1ead258..fe017527d 100755 --- a/src/conf_mode/nat66.py +++ b/src/conf_mode/nat66.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2020-2023 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 @@ -14,8 +14,6 @@  # 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 jmespath -import json  import os  from sys import exit @@ -106,7 +104,7 @@ def apply(nat):      if not nat:          return None -    cmd(f'nft -f {nftables_nat66_config}') +    cmd(f'nft --file {nftables_nat66_config}')      call_dependents()      return None diff --git a/src/conf_mode/policy_route.py b/src/conf_mode/policy_route.py index 6d7a06714..c58fe1bce 100755 --- a/src/conf_mode/policy_route.py +++ b/src/conf_mode/policy_route.py @@ -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 @@ -177,7 +177,7 @@ def cleanup_table_marks():                  cmd(f'{cmd_str} rule del fwmark {fwmark} table {table}')  def apply(policy): -    install_result = run(f'nft -f {nftables_conf}') +    install_result = run(f'nft --file {nftables_conf}')      if install_result == 1:          raise ConfigError('Failed to apply policy based routing') diff --git a/src/conf_mode/protocols_nhrp.py b/src/conf_mode/protocols_nhrp.py index c339c6391..9f66407f2 100755 --- a/src/conf_mode/protocols_nhrp.py +++ b/src/conf_mode/protocols_nhrp.py @@ -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 @@ -93,7 +93,7 @@ def generate(nhrp):      return None  def apply(nhrp): -    nft_rc = run(f'nft -f {nhrp_nftables_conf}') +    nft_rc = run(f'nft --file {nhrp_nftables_conf}')      if nft_rc != 0:          raise ConfigError('Failed to apply NHRP tunnel firewall rules') diff --git a/src/conf_mode/system_conntrack.py b/src/conf_mode/system_conntrack.py index 3d42389f6..031fe63b0 100755 --- a/src/conf_mode/system_conntrack.py +++ b/src/conf_mode/system_conntrack.py @@ -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 @@ -15,19 +15,16 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  import os -import re  from sys import exit  from vyos.config import Config  from vyos.configdep import set_dependents, call_dependents -from vyos.utils.process import process_named_running  from vyos.utils.dict import dict_search  from vyos.utils.dict import dict_search_args  from vyos.utils.dict import dict_search_recursive  from vyos.utils.process import cmd  from vyos.utils.process import rc_cmd -from vyos.utils.process import run  from vyos.template import render  from vyos import ConfigError  from vyos import airbag @@ -223,7 +220,7 @@ def apply(conntrack):          cmd(f'modprobe -a {module_str}')      # Load new nftables ruleset -    install_result, output = rc_cmd(f'nft -f {nftables_ct_file}') +    install_result, output = rc_cmd(f'nft --file {nftables_ct_file}')      if install_result == 1:          raise ConfigError(f'Failed to apply configuration: {output}') diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py index 16908100f..1fc813189 100755 --- a/src/conf_mode/vrf.py +++ b/src/conf_mode/vrf.py @@ -14,8 +14,6 @@  # 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 json import loads @@ -33,6 +31,7 @@ from vyos.utils.network import get_vrf_members  from vyos.utils.network import interface_exists  from vyos.utils.process import call  from vyos.utils.process import cmd +from vyos.utils.process import popen  from vyos.utils.system import sysctl_write  from vyos import ConfigError  from vyos import frr @@ -227,7 +226,11 @@ def apply(vrf):              # Remove nftables conntrack zone map item              nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ "{tmp}" }}' -            cmd(f'nft {nft_del_element}') +            # Check if deleting is possible first to avoid raising errors +            _, err = popen(f'nft --check {nft_del_element}') +            if not err: +                # Remove map element +                cmd(f'nft {nft_del_element}')              # Delete the VRF Kernel interface              call(f'ip link delete dev {tmp}') @@ -307,7 +310,7 @@ def apply(vrf):          if vrf['conntrack']:              for chain, rule in nftables_rules.items():                  cmd(f'nft add rule inet vrf_zones {chain} {rule}') -     +      if 'name' not in vrf or not vrf['conntrack']:          for chain, rule in nftables_rules.items():              cmd(f'nft flush chain inet vrf_zones {chain}') diff --git a/src/helpers/vyos-domain-resolver.py b/src/helpers/vyos-domain-resolver.py index eac3d37af..57cfcabd7 100755 --- a/src/helpers/vyos-domain-resolver.py +++ b/src/helpers/vyos-domain-resolver.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2022-2023 VyOS maintainers and contributors +# Copyright (C) 2022-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,7 +15,6 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  import json -import os  import time  from vyos.configdict import dict_merge @@ -95,7 +94,7 @@ def nft_output(table, set_name, ip_list):  def nft_valid_sets():      try:          valid_sets = [] -        sets_json = cmd('nft -j list sets') +        sets_json = cmd('nft --json list sets')          sets_obj = json.loads(sets_json)          for obj in sets_obj['nftables']: @@ -155,7 +154,7 @@ def update(firewall):          count += 1      nft_conf_str = "\n".join(conf_lines) + "\n" -    code = run(f'nft -f -', input=nft_conf_str) +    code = run(f'nft --file -', input=nft_conf_str)      print(f'Updated {count} sets - result: {code}') diff --git a/src/init/vyos-router b/src/init/vyos-router index adf892371..06fea140d 100755 --- a/src/init/vyos-router +++ b/src/init/vyos-router @@ -430,7 +430,7 @@ start ()      nfct helper add rpc inet6 tcp      nfct helper add rpc inet6 udp      nfct helper add tns inet6 tcp -    nft -f /usr/share/vyos/vyos-firewall-init.conf || log_failure_msg "could not initiate firewall rules" +    nft --file /usr/share/vyos/vyos-firewall-init.conf || log_failure_msg "could not initiate firewall rules"      # As VyOS does not execute commands that are not present in the CLI we call      # the script by hand to have a single source for the login banner and MOTD | 
