diff options
-rw-r--r-- | interface-definitions/policy-local-route.xml.in | 109 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_policy.py | 299 | ||||
-rwxr-xr-x | src/conf_mode/policy-local-route.py | 118 |
3 files changed, 36 insertions, 490 deletions
diff --git a/interface-definitions/policy-local-route.xml.in b/interface-definitions/policy-local-route.xml.in index 1c9d94ec5..3769c3748 100644 --- a/interface-definitions/policy-local-route.xml.in +++ b/interface-definitions/policy-local-route.xml.in @@ -14,7 +14,7 @@ <valueHelp> <!-- table main with prio 32766 --> <format>u32:1-32765</format> - <description>Local-route rule number (1-32765)</description> + <description>Local-route rule number (1-219)</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 1-32765"/> @@ -58,113 +58,6 @@ <multi/> </properties> </leafNode> - <leafNode name="destination"> - <properties> - <help>Destination address or prefix</help> - <valueHelp> - <format>ipv4</format> - <description>Address to match against</description> - </valueHelp> - <valueHelp> - <format>ipv4net</format> - <description>Prefix to match against</description> - </valueHelp> - <constraint> - <validator name="ipv4-address"/> - <validator name="ip-prefix"/> - </constraint> - <multi/> - </properties> - </leafNode> - </children> - </tagNode> - </children> - </node> - <node name="local-route6" owner="${vyos_conf_scripts_dir}/policy-local-route.py"> - <properties> - <help>IPv6 policy route of local traffic</help> - </properties> - <children> - <tagNode name="rule"> - <properties> - <help>IPv6 policy local-route rule set number</help> - <valueHelp> - <!-- table main with prio 32766 --> - <format>u32:1-32765</format> - <description>Local-route rule number (1-32765)</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 1-32765"/> - </constraint> - </properties> - <children> - <node name="set"> - <properties> - <help>Packet modifications</help> - </properties> - <children> - <leafNode name="table"> - <properties> - <help>Routing table to forward packet with</help> - <valueHelp> - <format>u32:1-200</format> - <description>Table number</description> - </valueHelp> - <completionHelp> - <list>main</list> - </completionHelp> - </properties> - </leafNode> - </children> - </node> - <leafNode name="fwmark"> - <properties> - <help>Match fwmark value</help> - <valueHelp> - <format>u32:1-2147483647</format> - <description>Address to match against</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 1-2147483647"/> - </constraint> - </properties> - </leafNode> - <leafNode name="source"> - <properties> - <help>Source address or prefix</help> - <valueHelp> - <format>ipv4</format> - <description>Address to match against</description> - </valueHelp> - <valueHelp> - <format>ipv4net</format> - <description>Prefix to match against</description> - </valueHelp> - <constraint> - <validator name="ipv6-address"/> - <validator name="ipv6-prefix"/> - </constraint> - <multi/> - </properties> - </leafNode> - <leafNode name="destination"> - <properties> - <help>Destination address or prefix</help> - <valueHelp> - <format>ipv6</format> - <description>Address to match against</description> - </valueHelp> - <valueHelp> - <format>ipv6net</format> - <description>Prefix to match against</description> - </valueHelp> - <constraint> - <validator name="ipv6-address"/> - <validator name="ipv6-prefix"/> - </constraint> - <multi/> - </properties> - </leafNode> </children> </tagNode> </children> diff --git a/smoketest/scripts/cli/test_policy.py b/smoketest/scripts/cli/test_policy.py index 6acb081dd..f1d195381 100755 --- a/smoketest/scripts/cli/test_policy.py +++ b/smoketest/scripts/cli/test_policy.py @@ -686,303 +686,10 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase): 50: from 203.0.113.2 lookup 23 """ tmp = cmd('ip rule show prio 50') + original = original.split() + tmp = tmp.split() - self.assertEqual(sort_ip(tmp), sort_ip(original)) - - # Test set table for fwmark - def test_fwmark_table_id(self): - path = base_path + ['local-route'] - - fwmk = '24' - rule = '101' - table = '154' - - self.cli_set(path + ['rule', rule, 'set', 'table', table]) - self.cli_set(path + ['rule', rule, 'fwmark', fwmk]) - - self.cli_commit() - - # Check generated configuration - - # Expected values - original = """ - 101: from all fwmark 0x18 lookup 154 - """ - tmp = cmd('ip rule show prio 101') - - self.assertEqual(sort_ip(tmp), sort_ip(original)) - - # Test set table for destination - def test_destination_table_id(self): - path = base_path + ['local-route'] - - dst = '203.0.113.1' - rule = '102' - table = '154' - - self.cli_set(path + ['rule', rule, 'set', 'table', table]) - self.cli_set(path + ['rule', rule, 'destination', dst]) - - self.cli_commit() - - # Check generated configuration - - # Expected values - original = """ - 102: from all to 203.0.113.1 lookup 154 - """ - tmp = cmd('ip rule show prio 102') - - self.assertEqual(sort_ip(tmp), sort_ip(original)) - - # Test set table for sources with fwmark - def test_fwmark_sources_table_id(self): - path = base_path + ['local-route'] - - sources = ['203.0.113.11', '203.0.113.12'] - fwmk = '23' - rule = '100' - table = '150' - for src in sources: - self.cli_set(path + ['rule', rule, 'set', 'table', table]) - self.cli_set(path + ['rule', rule, 'source', src]) - self.cli_set(path + ['rule', rule, 'fwmark', fwmk]) - - self.cli_commit() - - # Check generated configuration - - # Expected values - original = """ - 100: from 203.0.113.11 fwmark 0x17 lookup 150 - 100: from 203.0.113.12 fwmark 0x17 lookup 150 - """ - tmp = cmd('ip rule show prio 100') - - self.assertEqual(sort_ip(tmp), sort_ip(original)) - - # Test set table for sources and destinations with fwmark - def test_fwmark_sources_destination_table_id(self): - path = base_path + ['local-route'] - - sources = ['203.0.113.11', '203.0.113.12'] - destinations = ['203.0.113.13', '203.0.113.15'] - fwmk = '23' - rule = '103' - table = '150' - for src in sources: - for dst in destinations: - self.cli_set(path + ['rule', rule, 'set', 'table', table]) - self.cli_set(path + ['rule', rule, 'source', src]) - self.cli_set(path + ['rule', rule, 'destination', dst]) - self.cli_set(path + ['rule', rule, 'fwmark', fwmk]) - - self.cli_commit() - - # Check generated configuration - - # Expected values - original = """ - 103: from 203.0.113.11 to 203.0.113.13 fwmark 0x17 lookup 150 - 103: from 203.0.113.11 to 203.0.113.15 fwmark 0x17 lookup 150 - 103: from 203.0.113.12 to 203.0.113.13 fwmark 0x17 lookup 150 - 103: from 203.0.113.12 to 203.0.113.15 fwmark 0x17 lookup 150 - """ - tmp = cmd('ip rule show prio 103') - - self.assertEqual(sort_ip(tmp), sort_ip(original)) - - # Test set table ipv6 for some sources ipv6 - def test_ipv6_table_id(self): - path = base_path + ['local-route6'] - - sources = ['2001:db8:123::/48', '2001:db8:126::/48'] - rule = '50' - table = '23' - for src in sources: - self.cli_set(path + ['rule', rule, 'set', 'table', table]) - self.cli_set(path + ['rule', rule, 'source', src]) - - self.cli_commit() - - # Check generated configuration - - # Expected values - original = """ - 50: from 2001:db8:123::/48 lookup 23 - 50: from 2001:db8:126::/48 lookup 23 - """ - tmp = cmd('ip -6 rule show prio 50') - - self.assertEqual(sort_ip(tmp), sort_ip(original)) - - # Test set table for fwmark ipv6 - def test_fwmark_ipv6_table_id(self): - path = base_path + ['local-route6'] - - fwmk = '24' - rule = '100' - table = '154' - - self.cli_set(path + ['rule', rule, 'set', 'table', table]) - self.cli_set(path + ['rule', rule, 'fwmark', fwmk]) - - self.cli_commit() - - # Check generated configuration - - # Expected values - original = """ - 100: from all fwmark 0x18 lookup 154 - """ - tmp = cmd('ip -6 rule show prio 100') - - self.assertEqual(sort_ip(tmp), sort_ip(original)) - - # Test set table for destination ipv6 - def test_destination_ipv6_table_id(self): - path = base_path + ['local-route6'] - - dst = '2001:db8:1337::/126' - rule = '101' - table = '154' - - self.cli_set(path + ['rule', rule, 'set', 'table', table]) - self.cli_set(path + ['rule', rule, 'destination', dst]) - - self.cli_commit() - - # Check generated configuration - - # Expected values - original = """ - 101: from all to 2001:db8:1337::/126 lookup 154 - """ - tmp = cmd('ip -6 rule show prio 101') - - self.assertEqual(sort_ip(tmp), sort_ip(original)) - - # Test set table for sources with fwmark ipv6 - def test_fwmark_sources_ipv6_table_id(self): - path = base_path + ['local-route6'] - - sources = ['2001:db8:1338::/126', '2001:db8:1339::/126'] - fwmk = '23' - rule = '102' - table = '150' - for src in sources: - self.cli_set(path + ['rule', rule, 'set', 'table', table]) - self.cli_set(path + ['rule', rule, 'source', src]) - self.cli_set(path + ['rule', rule, 'fwmark', fwmk]) - - self.cli_commit() - - # Check generated configuration - - # Expected values - original = """ - 102: from 2001:db8:1338::/126 fwmark 0x17 lookup 150 - 102: from 2001:db8:1339::/126 fwmark 0x17 lookup 150 - """ - tmp = cmd('ip -6 rule show prio 102') - - self.assertEqual(sort_ip(tmp), sort_ip(original)) - - # Test set table for sources and destinations with fwmark ipv6 - def test_fwmark_sources_destination_ipv6_table_id(self): - path = base_path + ['local-route6'] - - sources = ['2001:db8:1338::/126', '2001:db8:1339::/56'] - destinations = ['2001:db8:13::/48', '2001:db8:16::/48'] - fwmk = '23' - rule = '103' - table = '150' - for src in sources: - for dst in destinations: - self.cli_set(path + ['rule', rule, 'set', 'table', table]) - self.cli_set(path + ['rule', rule, 'source', src]) - self.cli_set(path + ['rule', rule, 'destination', dst]) - self.cli_set(path + ['rule', rule, 'fwmark', fwmk]) - - self.cli_commit() - - # Check generated configuration - - # Expected values - original = """ - 103: from 2001:db8:1338::/126 to 2001:db8:13::/48 fwmark 0x17 lookup 150 - 103: from 2001:db8:1338::/126 to 2001:db8:16::/48 fwmark 0x17 lookup 150 - 103: from 2001:db8:1339::/56 to 2001:db8:13::/48 fwmark 0x17 lookup 150 - 103: from 2001:db8:1339::/56 to 2001:db8:16::/48 fwmark 0x17 lookup 150 - """ - tmp = cmd('ip -6 rule show prio 103') - - self.assertEqual(sort_ip(tmp), sort_ip(original)) - - # Test delete table for sources and destination with fwmark ipv4/ipv6 - def test_delete_ipv4_ipv6_table_id(self): - path = base_path + ['local-route'] - path_v6 = base_path + ['local-route6'] - - sources = ['203.0.113.1/24', '203.0.114.5'] - destinations = ['203.0.112.1/24', '203.0.116.5'] - sources_v6 = ['2001:db8:1338::/126', '2001:db8:1339::/56'] - destinations_v6 = ['2001:db8:13::/48', '2001:db8:16::/48'] - fwmk = '23' - rule = '103' - table = '150' - for src in sources: - for dst in destinations: - self.cli_set(path + ['rule', rule, 'set', 'table', table]) - self.cli_set(path + ['rule', rule, 'source', src]) - self.cli_set(path + ['rule', rule, 'destination', dst]) - self.cli_set(path + ['rule', rule, 'fwmark', fwmk]) - - for src in sources_v6: - for dst in destinations_v6: - self.cli_set(path_v6 + ['rule', rule, 'set', 'table', table]) - self.cli_set(path_v6 + ['rule', rule, 'source', src]) - self.cli_set(path_v6 + ['rule', rule, 'destination', dst]) - self.cli_set(path_v6 + ['rule', rule, 'fwmark', fwmk]) - - self.cli_commit() - - # Check generated configuration - - # Expected values - original = """ - 103: from 203.0.113.1/24 to 203.0.112.1/24 fwmark 0x17 lookup 150 - 103: from 203.0.113.1/24 to 203.0.116.5 fwmark 0x17 lookup 150 - 103: from 203.0.114.5 to 203.0.112.1/24 fwmark 0x17 lookup 150 - 103: from 203.0.114.5 to 203.0.116.5 fwmark 0x17 lookup 150 - """ - original_v6 = """ - 103: from 20016 to 2001:db8:13::/48 fwmark 0x17 lookup 150 - 103: from 2001:db8:1338::/126 to 2001:db8:16::/48 fwmark 0x17 lookup 150 - 103: from 2001:db8:1339::/56 to 2001:db8:13::/48 fwmark 0x17 lookup 150 - 103: from 2001:db8:1339::/56 to 2001:db8:16::/48 fwmark 0x17 lookup 150 - """ - tmp = cmd('ip rule show prio 103') - tmp_v6 = cmd('ip -6 rule show prio 103') - - self.assertEqual(sort_ip(tmp), sort_ip(original)) - self.assertEqual(sort_ip(tmp_v6), sort_ip(original_v6)) - - self.cli_delete(path) - self.cli_delete(path_v6) - self.cli_commit() - - tmp = cmd('ip rule show prio 103') - tmp_v6 = cmd('ip -6 rule show prio 103') - - original = [''] - original_v6 = [''] - - self.assertEqual(sort_ip(tmp), original) - self.assertEqual(sort_ip(tmp_v6), original_v6) - -def sort_ip(output): - return output.splitlines().sort() + self.assertEqual(tmp, original) if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/policy-local-route.py b/src/conf_mode/policy-local-route.py index 97ee6a785..013f22665 100755 --- a/src/conf_mode/policy-local-route.py +++ b/src/conf_mode/policy-local-route.py @@ -35,53 +35,25 @@ def get_config(config=None): conf = config else: conf = Config() - base = ['policy'] - + base = ['policy', 'local-route'] pbr = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) - for route in ['local_route', 'local_route6']: - dict_id = 'rule_remove' if route == 'local_route' else 'rule6_remove' - route_key = 'local-route' if route == 'local_route' else 'local-route6' - base_rule = base + [route_key, 'rule'] - - # delete policy local-route - dict = {} - tmp = node_changed(conf, base_rule, key_mangling=('-', '_')) - if tmp: - for rule in (tmp or []): - src = leaf_node_changed(conf, base_rule + [rule, 'source']) - fwmk = leaf_node_changed(conf, base_rule + [rule, 'fwmark']) - dst = leaf_node_changed(conf, base_rule + [rule, 'destination']) - rule_def = {} - if src: - rule_def = dict_merge({'source' : src}, rule_def) - if fwmk: - rule_def = dict_merge({'fwmark' : fwmk}, rule_def) - if dst: - rule_def = dict_merge({'destination' : dst}, rule_def) - dict = dict_merge({dict_id : {rule : rule_def}}, dict) + # delete policy local-route + dict = {} + tmp = node_changed(conf, ['policy', 'local-route', 'rule'], key_mangling=('-', '_')) + if tmp: + for rule in (tmp or []): + src = leaf_node_changed(conf, ['policy', 'local-route', 'rule', rule, 'source']) + if src: + dict = dict_merge({'rule_remove' : {rule : {'source' : src}}}, dict) pbr.update(dict) - if not route in pbr: - continue - - # delete policy local-route rule x source x.x.x.x - # delete policy local-route rule x fwmark x - # delete policy local-route rule x destination x.x.x.x - if 'rule' in pbr[route]: - for rule in pbr[route]['rule']: - src = leaf_node_changed(conf, base_rule + [rule, 'source']) - fwmk = leaf_node_changed(conf, base_rule + [rule, 'fwmark']) - dst = leaf_node_changed(conf, base_rule + [rule, 'destination']) - - rule_def = {} - if src: - rule_def = dict_merge({'source' : src}, rule_def) - if fwmk: - rule_def = dict_merge({'fwmark' : fwmk}, rule_def) - if dst: - rule_def = dict_merge({'destination' : dst}, rule_def) - dict = dict_merge({dict_id : {rule : rule_def}}, dict) + # delete policy local-route rule x source x.x.x.x + if 'rule' in pbr: + for rule in pbr['rule']: + src = leaf_node_changed(conf, ['policy', 'local-route', 'rule', rule, 'source']) + if src: + dict = dict_merge({'rule_remove' : {rule : {'source' : src}}}, dict) pbr.update(dict) return pbr @@ -91,18 +63,13 @@ def verify(pbr): if not pbr: return None - for route in ['local_route', 'local_route6']: - if not route in pbr: - continue - - pbr_route = pbr[route] - if 'rule' in pbr_route: - for rule in pbr_route['rule']: - if 'source' not in pbr_route['rule'][rule] and 'destination' not in pbr_route['rule'][rule] and 'fwmark' not in pbr_route['rule'][rule]: - raise ConfigError('Source or destination address or fwmark is required!') - else: - if 'set' not in pbr_route['rule'][rule] or 'table' not in pbr_route['rule'][rule]['set']: - raise ConfigError('Table set is required!') + if 'rule' in pbr: + for rule in pbr['rule']: + if 'source' not in pbr['rule'][rule]: + raise ConfigError('Source address required!') + else: + if 'set' not in pbr['rule'][rule] or 'table' not in pbr['rule'][rule]['set']: + raise ConfigError('Table set is required!') return None @@ -117,39 +84,18 @@ def apply(pbr): return None # Delete old rule if needed - for rule_rm in ['rule_remove', 'rule6_remove']: - if rule_rm in pbr: - v6 = " -6" if rule_rm == 'rule6_remove' else "" - for rule, rule_config in pbr[rule_rm].items(): - for src in (rule_config['source'] or ['']): - f_src = '' if src == '' else f' from {src} ' - for dst in (rule_config['destination'] or ['']): - f_dst = '' if dst == '' else f' to {dst} ' - for fwmk in (rule_config['fwmark'] or ['']): - f_fwmk = '' if fwmk == '' else f' fwmark {fwmk} ' - call(f'ip{v6} rule del prio {rule} {f_src}{f_dst}{f_fwmk}') + if 'rule_remove' in pbr: + for rule in pbr['rule_remove']: + for src in pbr['rule_remove'][rule]['source']: + call(f'ip rule del prio {rule} from {src}') # Generate new config - for route in ['local_route', 'local_route6']: - if not route in pbr: - continue - - v6 = " -6" if route == 'local_route6' else "" - - pbr_route = pbr[route] - if 'rule' in pbr_route: - for rule, rule_config in pbr_route['rule'].items(): - table = rule_config['set']['table'] - - for src in (rule_config['source'] or ['all']): - f_src = '' if src == '' else f' from {src} ' - for dst in (rule_config['destination'] or ['all']): - f_dst = '' if dst == '' else f' to {dst} ' - f_fwmk = '' - if 'fwmark' in rule_config: - fwmk = rule_config['fwmark'] - f_fwmk = f' fwmark {fwmk} ' - call(f'ip{v6} rule add prio {rule} {f_src}{f_dst}{f_fwmk} lookup {table}') + if 'rule' in pbr: + for rule in pbr['rule']: + table = pbr['rule'][rule]['set']['table'] + if pbr['rule'][rule]['source']: + for src in pbr['rule'][rule]['source']: + call(f'ip rule add prio {rule} from {src} lookup {table}') return None |