From 0e32faf6db96262b0a6376b54be033b4b72477f2 Mon Sep 17 00:00:00 2001
From: fett0 <50275740+fett0@users.noreply.github.com>
Date: Tue, 31 May 2022 01:46:07 -0300
Subject: IPv6: T3976: add prefix-list and access-list option from ipv6
route-map
---
data/templates/frr/policy.frr.j2 | 10 ++++--
interface-definitions/policy.xml.in | 42 +++++++++++++++++++++++++
smoketest/scripts/cli/test_policy.py | 24 +++++++++++----
src/conf_mode/policy.py | 10 ++++++
src/migration-scripts/policy/2-to-3 | 59 ++++++++++++++++++++++++++++++++++++
5 files changed, 137 insertions(+), 8 deletions(-)
create mode 100755 src/migration-scripts/policy/2-to-3
diff --git a/data/templates/frr/policy.frr.j2 b/data/templates/frr/policy.frr.j2
index 9326cdf03..40ec0bb1e 100644
--- a/data/templates/frr/policy.frr.j2
+++ b/data/templates/frr/policy.frr.j2
@@ -218,8 +218,14 @@ route-map {{ route_map }} {{ rule_config.action }} {{ rule }}
{% if rule_config.match.ipv6.address.prefix_len is vyos_defined %}
match ipv6 address prefix-len {{ rule_config.match.ipv6.address.prefix_len }}
{% endif %}
-{% if rule_config.match.ipv6.nexthop is vyos_defined %}
- match ipv6 next-hop address {{ rule_config.match.ipv6.nexthop }}
+{% if rule_config.match.ipv6.nexthop.address is vyos_defined %}
+ match ipv6 next-hop address {{ rule_config.match.ipv6.nexthop.address }}
+{% endif %}
+{% if rule_config.match.ipv6.nexthop.access_list is vyos_defined %}
+ match ipv6 next-hop {{ rule_config.match.ipv6.nexthop.access_list }}
+{% endif %}
+{% if rule_config.match.ipv6.nexthop.prefix_list is vyos_defined %}
+ match ipv6 next-hop prefix-list {{ rule_config.match.ipv6.nexthop.prefix_list }}
{% endif %}
{% if rule_config.match.large_community.large_community_list is vyos_defined %}
match large-community {{ rule_config.match.large_community.large_community_list }}
diff --git a/interface-definitions/policy.xml.in b/interface-definitions/policy.xml.in
index aaed6286f..3b61877c5 100644
--- a/interface-definitions/policy.xml.in
+++ b/interface-definitions/policy.xml.in
@@ -821,6 +821,7 @@
+
+
+
+ IPv6 next-hop of route to match
+
+
+
+
+ IPv6 address of next-hop
+
+ ipv6
+ Nexthop IPv6 address
+
+
+
+
+
+
+
+
+ IPv6 access-list to match
+
+ txt
+ IPV6 access list name
+
+
+ policy access-list6
+
+
+
+
+
+ IPv6 prefix-list to match
+
+ policy prefix-list6
+
+
+
+
+
+
diff --git a/smoketest/scripts/cli/test_policy.py b/smoketest/scripts/cli/test_policy.py
index 5a8d6995f..9c2353856 100755
--- a/smoketest/scripts/cli/test_policy.py
+++ b/smoketest/scripts/cli/test_policy.py
@@ -711,7 +711,7 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
large_community_list = 'bgp-large-community-123456'
prefix_list = 'foo-pfx-list'
- ipv6_nexthop = 'fe80::1'
+ ipv6_nexthop_address = 'fe80::1'
local_pref = '300'
metric = '50'
peer = '2.3.4.5'
@@ -791,7 +791,9 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
'30' : {
'action' : 'permit',
'match' : {
- 'ipv6-nexthop' : ipv6_nexthop,
+ 'ipv6-nexthop-address' : ipv6_nexthop_address,
+ 'ipv6-nexthop-access-list' : access_list,
+ 'ipv6-nexthop-prefix-list' : prefix_list,
'ipv6-address-pfx-len' : ipv6_prefix_len,
'large-community' : large_community_list,
'local-pref' : local_pref,
@@ -965,8 +967,12 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'address', 'prefix-list', rule_config['match']['ipv6-address-pfx']])
if 'ipv6-address-pfx-len' in rule_config['match']:
self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'address', 'prefix-len', rule_config['match']['ipv6-address-pfx-len']])
- if 'ipv6-nexthop' in rule_config['match']:
- self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'nexthop', rule_config['match']['ipv6-nexthop']])
+ if 'ipv6-nexthop-address' in rule_config['match']:
+ self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'nexthop', 'address', rule_config['match']['ipv6-nexthop-address']])
+ if 'ipv6-nexthop-access-list' in rule_config['match']:
+ self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'nexthop', 'access-list', rule_config['match']['ipv6-nexthop-access-list']])
+ if 'ipv6-nexthop-prefix-list' in rule_config['match']:
+ self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'nexthop', 'prefix-list', rule_config['match']['ipv6-nexthop-prefix-list']])
if 'large-community' in rule_config['match']:
self.cli_set(path + ['rule', rule, 'match', 'large-community', 'large-community-list', rule_config['match']['large-community']])
if 'local-pref' in rule_config['match']:
@@ -1126,8 +1132,14 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
if 'ipv6-address-pfx-len' in rule_config['match']:
tmp = f'match ipv6 address prefix-len {rule_config["match"]["ipv6-address-pfx-len"]}'
self.assertIn(tmp, config)
- if 'ipv6-nexthop' in rule_config['match']:
- tmp = f'match ipv6 next-hop address {rule_config["match"]["ipv6-nexthop"]}'
+ if 'ipv6-nexthop-address' in rule_config['match']:
+ tmp = f'match ipv6 next-hop address {rule_config["match"]["ipv6-nexthop-address"]}'
+ self.assertIn(tmp, config)
+ if 'ipv6-nexthop-access-list' in rule_config['match']:
+ tmp = f'match ipv6 next-hop {rule_config["match"]["ipv6-nexthop-access-list"]}'
+ self.assertIn(tmp, config)
+ if 'ipv6-nexthop-prefix-list' in rule_config['match']:
+ tmp = f'match ipv6 next-hop prefix-list {rule_config["match"]["ipv6-nexthop-prefix-list"]}'
self.assertIn(tmp, config)
if 'large-community' in rule_config['match']:
tmp = f'match large-community {rule_config["match"]["large-community"]}'
diff --git a/src/conf_mode/policy.py b/src/conf_mode/policy.py
index ef6008140..3008a20e0 100755
--- a/src/conf_mode/policy.py
+++ b/src/conf_mode/policy.py
@@ -150,6 +150,16 @@ def verify(policy):
tmp = dict_search('match.ipv6.address.prefix_list', rule_config)
if tmp and tmp not in policy.get('prefix_list6', []):
raise ConfigError(f'prefix-list6 {tmp} does not exist!')
+
+ # Specified access_list6 in nexthop must exist
+ tmp = dict_search('match.ipv6.nexthop.access_list', rule_config)
+ if tmp and tmp not in policy.get('access_list6', []):
+ raise ConfigError(f'access_list6 {tmp} does not exist!')
+
+ # Specified prefix-list6 in nexthop must exist
+ tmp = dict_search('match.ipv6.nexthop.prefix_list', rule_config)
+ if tmp and tmp not in policy.get('prefix_list6', []):
+ raise ConfigError(f'prefix-list6 {tmp} does not exist!')
# When routing protocols are active some use prefix-lists, route-maps etc.
# to apply the systems routing policy to the learned or redistributed routes.
diff --git a/src/migration-scripts/policy/2-to-3 b/src/migration-scripts/policy/2-to-3
new file mode 100755
index 000000000..5caec2dd2
--- /dev/null
+++ b/src/migration-scripts/policy/2-to-3
@@ -0,0 +1,59 @@
+#!/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 .
+
+# T3976: change cli
+# from: set policy route-map FOO rule 10 match ipv6 nexthop 'h:h:h:h:h:h:h:h'
+# to: set policy route-map FOO rule 10 match ipv6 nexthop address 'h:h:h:h:h:h:h:h'
+
+from sys import argv
+from sys import exit
+
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['policy', 'route-map']
+config = ConfigTree(config_file)
+
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+
+for route_map in config.list_nodes(base):
+ if not config.exists(base + [route_map, 'rule']):
+ continue
+ for rule in config.list_nodes(base + [route_map, 'rule']):
+ base_rule = base + [route_map, 'rule', rule]
+
+ if config.exists(base_rule + ['match', 'ipv6', 'nexthop']):
+ tmp = config.return_value(base_rule + ['match', 'ipv6', 'nexthop'])
+ config.delete(base_rule + ['match', 'ipv6', 'nexthop'])
+ config.set(base_rule + ['match', 'ipv6', 'nexthop', 'address'], value=tmp)
+
+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)
\ No newline at end of file
--
cgit v1.2.3