summaryrefslogtreecommitdiff
path: root/src/conf_mode/policy-route.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode/policy-route.py')
-rwxr-xr-xsrc/conf_mode/policy-route.py78
1 files changed, 5 insertions, 73 deletions
diff --git a/src/conf_mode/policy-route.py b/src/conf_mode/policy-route.py
index 5de341beb..1d016695e 100755
--- a/src/conf_mode/policy-route.py
+++ b/src/conf_mode/policy-route.py
@@ -15,7 +15,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-import re
from json import loads
from sys import exit
@@ -33,35 +32,13 @@ airbag.enable()
mark_offset = 0x7FFFFFFF
nftables_conf = '/run/nftables_policy.conf'
-preserve_chains = [
- 'VYOS_PBR_PREROUTING',
- 'VYOS_PBR_POSTROUTING',
- 'VYOS_PBR6_PREROUTING',
- 'VYOS_PBR6_POSTROUTING'
-]
-
valid_groups = [
'address_group',
+ 'domain_group',
'network_group',
'port_group'
]
-def get_policy_interfaces(conf):
- out = {}
- interfaces = conf.get_config_dict(['interfaces'], key_mangling=('-', '_'), get_first_key=True,
- no_tag_node_value_mangle=True)
- def find_interfaces(iftype_conf, output={}, prefix=''):
- for ifname, if_conf in iftype_conf.items():
- if 'policy' in if_conf:
- output[prefix + ifname] = if_conf['policy']
- for vif in ['vif', 'vif_s', 'vif_c']:
- if vif in if_conf:
- output.update(find_interfaces(if_conf[vif], output, f'{prefix}{ifname}.'))
- return output
- for iftype, iftype_conf in interfaces.items():
- out.update(find_interfaces(iftype_conf))
- return out
-
def get_config(config=None):
if config:
conf = config
@@ -74,11 +51,10 @@ def get_config(config=None):
policy['firewall_group'] = conf.get_config_dict(['firewall', 'group'], key_mangling=('-', '_'), get_first_key=True,
no_tag_node_value_mangle=True)
- policy['interfaces'] = get_policy_interfaces(conf)
return policy
-def verify_rule(policy, name, rule_conf, ipv6):
+def verify_rule(policy, name, rule_conf, ipv6, rule_id):
icmp = 'icmp' if not ipv6 else 'icmpv6'
if icmp in rule_conf:
icmp_defined = False
@@ -118,8 +94,8 @@ def verify_rule(policy, name, rule_conf, ipv6):
side_conf = rule_conf[side]
if 'group' in side_conf:
- if {'address_group', 'network_group'} <= set(side_conf['group']):
- raise ConfigError('Only one address-group or network-group can be specified')
+ if len({'address_group', 'domain_group', 'network_group'} & set(side_conf['group'])) > 1:
+ raise ConfigError('Only one address-group, domain-group or network-group can be specified')
for group in valid_groups:
if group in side_conf['group']:
@@ -152,57 +128,13 @@ def verify(policy):
for name, pol_conf in policy[route].items():
if 'rule' in pol_conf:
for rule_id, rule_conf in pol_conf['rule'].items():
- verify_rule(policy, name, rule_conf, ipv6)
-
- for ifname, if_policy in policy['interfaces'].items():
- name = dict_search_args(if_policy, 'route')
- ipv6_name = dict_search_args(if_policy, 'route6')
-
- if name and not dict_search_args(policy, 'route', name):
- raise ConfigError(f'Policy route "{name}" is still referenced on interface {ifname}')
-
- if ipv6_name and not dict_search_args(policy, 'route6', ipv6_name):
- raise ConfigError(f'Policy route6 "{ipv6_name}" is still referenced on interface {ifname}')
+ verify_rule(policy, name, rule_conf, ipv6, rule_id)
return None
-def cleanup_rule(table, jump_chain):
- commands = []
- results = cmd(f'nft -a list table {table}').split("\n")
- for line in results:
- if f'jump {jump_chain}' in line:
- handle_search = re.search('handle (\d+)', line)
- if handle_search:
- commands.append(f'delete rule {table} {chain} handle {handle_search[1]}')
- return commands
-
-def cleanup_commands(policy):
- commands = []
- for table in ['ip mangle', 'ip6 mangle']:
- json_str = cmd(f'nft -j list table {table}')
- obj = loads(json_str)
- if 'nftables' not in obj:
- continue
- for item in obj['nftables']:
- if 'chain' in item:
- chain = item['chain']['name']
- if not chain.startswith("VYOS_PBR"):
- continue
- if chain not in preserve_chains:
- if table == 'ip mangle' and dict_search_args(policy, 'route', chain.replace("VYOS_PBR_", "", 1)):
- commands.append(f'flush chain {table} {chain}')
- elif table == 'ip6 mangle' and dict_search_args(policy, 'route6', chain.replace("VYOS_PBR6_", "", 1)):
- commands.append(f'flush chain {table} {chain}')
- else:
- commands += cleanup_rule(table, chain)
- commands.append(f'delete chain {table} {chain}')
- return commands
-
def generate(policy):
if not os.path.exists(nftables_conf):
policy['first_install'] = True
- else:
- policy['cleanup_commands'] = cleanup_commands(policy)
render(nftables_conf, 'firewall/nftables-policy.j2', policy)
return None