From 45a2a7d0adc7e9d27d6c7aee1ccbd9b64a1437ad Mon Sep 17 00:00:00 2001
From: Daniil Baturin <daniil@baturin.org>
Date: Mon, 28 Mar 2022 19:49:24 +0300
Subject: Revert "backport: T4515: T4219: policy local-route6 and
 inbound-interface support"

---
 src/conf_mode/policy-local-route.py | 183 +++++++-----------------------------
 1 file changed, 34 insertions(+), 149 deletions(-)

(limited to 'src/conf_mode')

diff --git a/src/conf_mode/policy-local-route.py b/src/conf_mode/policy-local-route.py
index 0a4597869..013f22665 100755
--- a/src/conf_mode/policy-local-route.py
+++ b/src/conf_mode/policy-local-route.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020 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
 
 from sys import exit
 
-from netifaces import interfaces
 from vyos.config import Config
 from vyos.configdict import dict_merge
 from vyos.configdict import node_changed
@@ -36,95 +35,26 @@ 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'])
-                iif = leaf_node_changed(conf, base_rule + [rule, 'inbound-interface'])
-                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 iif:
-                    rule_def = dict_merge({'inbound_interface' : iif}, rule_def)
-                if dst:
-                    rule_def = dict_merge({'destination' : dst}, rule_def)
-                dict = dict_merge({dict_id : {rule : rule_def}}, dict)
-                pbr.update(dict)
-            if fwmk:
-                dict = dict_merge({'rule_remove' : {rule : {'fwmark' : fwmk}}}, 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, rule_config in pbr[route]['rule'].items():
-                src = leaf_node_changed(conf, base_rule + [rule, 'source'])
-                fwmk = leaf_node_changed(conf, base_rule + [rule, 'fwmark'])
-                iif = leaf_node_changed(conf, base_rule + [rule, 'inbound-interface'])
-                dst = leaf_node_changed(conf, base_rule + [rule, 'destination'])
-                # keep track of changes in configuration
-                # otherwise we might remove an existing node although nothing else has changed
-                changed = False
-
-                rule_def = {}
-                # src is None if there are no changes to src
-                if src is None:
-                    # if src hasn't changed, include it in the removal selector
-                    # if a new selector is added, we have to remove all previous rules without this selector
-                    # to make sure we remove all previous rules with this source(s), it will be included
-                    if 'source' in rule_config:
-                        rule_def = dict_merge({'source': rule_config['source']}, rule_def)
-                else:
-                    # if src is not None, it's previous content will be returned
-                    # this can be an empty array if it's just being set, or the previous value
-                    # either way, something has to be changed and we only want to remove previous values
-                    changed = True
-                    # set the old value for removal if it's not empty
-                    if len(src) > 0:
-                        rule_def = dict_merge({'source' : src}, rule_def)
-                if fwmk is None:
-                    if 'fwmark' in rule_config:
-                        rule_def = dict_merge({'fwmark': rule_config['fwmark']}, rule_def)
-                else:
-                    changed = True
-                    if len(fwmk) > 0:
-                        rule_def = dict_merge({'fwmark' : fwmk}, rule_def)
-                if iif is None:
-                    if 'inbound_interface' in rule_config:
-                        rule_def = dict_merge({'inbound_interface': rule_config['inbound_interface']}, rule_def)
-                else:
-                    changed = True
-                    if len(iif) > 0:
-                        rule_def = dict_merge({'inbound_interface' : iif}, rule_def)
-                if dst is None:
-                    if 'destination' in rule_config:
-                        rule_def = dict_merge({'destination': rule_config['destination']}, rule_def)
-                else:
-                    changed = True
-                    if len(dst) > 0:
-                        rule_def = dict_merge({'destination' : dst}, rule_def)
-                if changed:
-                    dict = dict_merge({dict_id : {rule : rule_def}}, dict)
-                    pbr.update(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
 
@@ -133,25 +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] \
-                        and 'inbound_interface' not in pbr_route['rule'][rule]:
-                    raise ConfigError('Source or destination address or fwmark or inbound-interface 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 'inbound_interface' in pbr_route['rule'][rule]:
-                        interface = pbr_route['rule'][rule]['inbound_interface']
-                        if interface not in interfaces():
-                            raise ConfigError(f'Interface "{interface}" does not exist')
+    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
 
@@ -166,51 +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():
-                rule_config['source'] = rule_config['source'] if 'source' in rule_config else ['']
-                for src in rule_config['source']:
-                    f_src = '' if src == '' else f' from {src} '
-                    rule_config['destination'] = rule_config['destination'] if 'destination' in rule_config else ['']
-                    for dst in rule_config['destination']:
-                        f_dst = '' if dst == '' else f' to {dst} '
-                        rule_config['fwmark'] = rule_config['fwmark'] if 'fwmark' in rule_config else ['']
-                        for fwmk in rule_config['fwmark']:
-                            f_fwmk = '' if fwmk == '' else f' fwmark {fwmk} '
-                            rule_config['inbound_interface'] = rule_config['inbound_interface'] if 'inbound_interface' in rule_config else ['']
-                            for iif in rule_config['inbound_interface']:
-                                f_iif = '' if iif == '' else f' iif {iif} '
-                                call(f'ip{v6} rule del prio {rule} {f_src}{f_dst}{f_fwmk}{f_iif}')
+    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']
-
-                rule_config['source'] = rule_config['source'] if 'source' in rule_config else ['all']
-                for src in rule_config['source'] or ['all']:
-                    f_src = '' if src == '' else f' from {src} '
-                    rule_config['destination'] = rule_config['destination'] if 'destination' in rule_config else ['all']
-                    for dst in rule_config['destination']:
-                        f_dst = '' if dst == '' else f' to {dst} '
-                        f_fwmk = ''
-                        if 'fwmark' in rule_config:
-                            fwmk = rule_config['fwmark']
-                            f_fwmk = f' fwmark {fwmk} '
-                        f_iif = ''
-                        if 'inbound_interface' in rule_config:
-                            iif = rule_config['inbound_interface']
-                            f_iif = f' iif {iif} '
-                        call(f'ip{v6} rule add prio {rule} {f_src}{f_dst}{f_fwmk}{f_iif} 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
 
-- 
cgit v1.2.3