summaryrefslogtreecommitdiff
path: root/src/conf_mode/nat.py
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-05-01 15:40:18 +0200
committerChristian Poessinger <christian@poessinger.com>2020-05-16 15:30:26 +0200
commit7caf1568bbb6be59e5f13693c31f23ade9349daa (patch)
tree86dcb17e927251a802a82e517d4f182db8cfc114 /src/conf_mode/nat.py
parent40e8938667b06615e0a1a26271a30e00f8cff2c6 (diff)
downloadvyos-1x-7caf1568bbb6be59e5f13693c31f23ade9349daa.tar.gz
vyos-1x-7caf1568bbb6be59e5f13693c31f23ade9349daa.zip
nat: T2198: destination nat template for iptables-restore
Diffstat (limited to 'src/conf_mode/nat.py')
-rwxr-xr-xsrc/conf_mode/nat.py91
1 files changed, 88 insertions, 3 deletions
diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py
index 188445214..538999f9a 100755
--- a/src/conf_mode/nat.py
+++ b/src/conf_mode/nat.py
@@ -16,8 +16,10 @@
from copy import deepcopy
from sys import exit
+from netifaces import interfaces
from vyos.config import Config
+from vyos.template import render
from vyos import ConfigError
default_config_data = {
@@ -25,14 +27,89 @@ default_config_data = {
'destination': []
}
+nat_source_config = '/tmp/nat_source'
+nat_destination_config = '/tmp/nat_destination'
+
+def parse_source_destination(conf, source_dest):
+ """ Common wrapper to read in both NAT source and destination CLI """
+ tmp = []
+ base_level = ['nat', source_dest]
+ conf.set_level(base_level)
+ for number in conf.list_nodes(['rule']):
+ rule = {
+ 'description': '',
+ 'dest_address': '',
+ 'dest_port': '',
+ 'disable': False,
+ 'exclude': False,
+ 'interface_in': '',
+ 'interface_out': '',
+ 'log': False,
+ 'protocol': '',
+ 'number': number,
+ 'source_address': '',
+ 'source_port': '',
+ 'translation_address': '',
+ 'translation_port': ''
+ }
+ conf.set_level(base_level + ['rule', number])
+
+ if conf.exists(['description']):
+ rule['description'] = conf.return_value(['description'])
+
+ if conf.exists(['destination', 'address']):
+ rule['dest_address'] = conf.return_value(['destination', 'address'])
+
+ if conf.exists(['destination', 'port']):
+ rule['dest_port'] = conf.return_value(['destination', 'port'])
+
+ if conf.exists(['disable']):
+ rule['disable'] = True
+
+ if conf.exists(['exclude']):
+ rule['exclude'] = True
+
+ if conf.exists(['inbound-interface']):
+ rule['interface_in'] = conf.return_value(['inbound-interface'])
+
+ if conf.exists(['outbound-interface']):
+ rule['interface_out'] = conf.return_value(['outbound-interface'])
+
+ if conf.exists(['log']):
+ rule['log'] = True
+
+ if conf.exists(['protocol']):
+ rule['protocol'] = conf.return_value(['protocol'])
+
+ if conf.exists(['source', 'address']):
+ rule['source_address'] = conf.return_value(['source', 'address'])
+
+ if conf.exists(['source', 'port']):
+ rule['source_port'] = conf.return_value(['source', 'port'])
+
+ if conf.exists(['translation', 'address']):
+ rule['translation_address'] = conf.return_value(['translation', 'address'])
+
+ if conf.exists(['translation', 'port']):
+ rule['translation_port'] = conf.return_value(['translation', 'port'])
+
+ tmp.append(rule)
+
+ return tmp
+
def get_config():
nat = deepcopy(default_config_data)
conf = Config()
- base = ['nat']
- if not conf.exists(base):
+ if not conf.exists(['nat']):
return None
else:
- conf.set_level(base)
+ conf.set_level(['nat'])
+
+ # use a common wrapper function to read in the source / destination
+ # tree from the config - thus we do not need to replicate almost the
+ # same code :-)
+ for tgt in ['source', 'destination']:
+ nat[tgt] = parse_source_destination(conf, tgt)
return nat
@@ -40,12 +117,20 @@ def verify(nat):
if not nat:
return None
+ for rule in nat['source']:
+ interface = rule['interface_out']
+ if interface and interface not in interfaces():
+ print(f'NAT configuration warning: interface {interface} does not exist on this system')
+
return None
def generate(nat):
if not nat:
return None
+ render(nat_source_config, 'nat/nat-source.tmpl', nat, trim_blocks=True)
+ render(nat_destination_config, 'nat/nat-destination.tmpl', nat, trim_blocks=True)
+
return None
def apply(nat):