summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2023-12-21 16:35:32 +0100
committerGitHub <noreply@github.com>2023-12-21 16:35:32 +0100
commit04f745123a71c1ae330b02e263fa42e310aee4da (patch)
tree1192a9b753dc8cf5660f8bc46a4e0e503eb5419b /src
parentc9b71b0669924da41dc50632bdcaed710f03d4d7 (diff)
parenteac5251c4c804c580fe9f3c3d6c6f6e355fca6d1 (diff)
downloadvyos-1x-04f745123a71c1ae330b02e263fa42e310aee4da.tar.gz
vyos-1x-04f745123a71c1ae330b02e263fa42e310aee4da.zip
Merge pull request #2673 from vyos/mergify/bp/sagitta/pr-2665
T2898: add ndp-proxy service (backport #2665)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/nat66.py8
-rwxr-xr-xsrc/conf_mode/service_ndp-proxy.py91
-rwxr-xr-xsrc/migration-scripts/nat66/2-to-361
3 files changed, 157 insertions, 3 deletions
diff --git a/src/conf_mode/nat66.py b/src/conf_mode/nat66.py
index 3f7185e67..393be998f 100755
--- a/src/conf_mode/nat66.py
+++ b/src/conf_mode/nat66.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 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
@@ -35,7 +35,6 @@ airbag.enable()
k_mod = ['nft_nat', 'nft_chain_nat']
nftables_nat66_config = '/run/nftables_nat66.nft'
-ndppd_config = '/run/ndppd/ndppd.conf'
def get_handler(json, chain, target):
""" Get nftable rule handler number of given chain/target combination.
@@ -141,7 +140,6 @@ def generate(nat):
nat['first_install'] = True
render(nftables_nat66_config, 'firewall/nftables-nat66.j2', nat, permission=0o755)
- render(ndppd_config, 'ndppd/ndppd.conf.j2', nat, permission=0o755)
return None
def apply(nat):
@@ -149,6 +147,7 @@ def apply(nat):
return None
cmd(f'nft -f {nftables_nat66_config}')
+<<<<<<< HEAD
if 'deleted' in nat or not dict_search('source.rule', nat):
cmd('systemctl stop ndppd')
@@ -156,6 +155,9 @@ def apply(nat):
os.unlink(ndppd_config)
else:
cmd('systemctl restart ndppd')
+=======
+ call_dependents()
+>>>>>>> 4d721a580 (T2898: add ndp-proxy service)
return None
diff --git a/src/conf_mode/service_ndp-proxy.py b/src/conf_mode/service_ndp-proxy.py
new file mode 100755
index 000000000..aa2374f4c
--- /dev/null
+++ b/src/conf_mode/service_ndp-proxy.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
+
+import os
+
+from sys import exit
+
+from vyos.config import Config
+from vyos.configverify import verify_interface_exists
+from vyos.utils.process import call
+from vyos.template import render
+from vyos import ConfigError
+from vyos import airbag
+airbag.enable()
+
+systemd_service = 'ndppd.service'
+ndppd_config = '/run/ndppd/ndppd.conf'
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+ base = ['service', 'ndp-proxy']
+ if not conf.exists(base):
+ return None
+
+ ndpp = conf.get_config_dict(base, key_mangling=('-', '_'),
+ get_first_key=True,
+ with_recursive_defaults=True)
+
+ return ndpp
+
+def verify(ndpp):
+ if not ndpp:
+ return None
+
+ if 'interface' in ndpp:
+ for interface, interface_config in ndpp['interface'].items():
+ verify_interface_exists(interface)
+
+ if 'rule' in interface_config:
+ for rule, rule_config in interface_config['rule'].items():
+ if rule_config['mode'] == 'interface' and 'interface' not in rule_config:
+ raise ConfigError(f'Rule "{rule}" uses interface mode but no interface defined!')
+
+ if rule_config['mode'] != 'interface' and 'interface' in rule_config:
+ if interface_config['mode'] != 'interface' and 'interface' in interface_config:
+ raise ConfigError(f'Rule "{rule}" does not use interface mode, thus interface can not be defined!')
+
+ return None
+
+def generate(ndpp):
+ if not ndpp:
+ return None
+
+ render(ndppd_config, 'ndppd/ndppd.conf.j2', ndpp)
+ return None
+
+def apply(ndpp):
+ if not ndpp:
+ call(f'systemctl stop {systemd_service}')
+ if os.path.isfile(ndppd_config):
+ os.unlink(ndppd_config)
+ return None
+
+ call(f'systemctl reload-or-restart {systemd_service}')
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/migration-scripts/nat66/2-to-3 b/src/migration-scripts/nat66/2-to-3
new file mode 100755
index 000000000..f34f170b3
--- /dev/null
+++ b/src/migration-scripts/nat66/2-to-3
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
+
+from sys import argv,exit
+from vyos.configtree import ConfigTree
+
+if len(argv) < 2:
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['nat66', 'source']
+new_base = ['service', 'ndp-proxy', 'interface']
+
+config = ConfigTree(config_file)
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+for rule in config.list_nodes(base + ['rule']):
+ base_rule = base + ['rule', rule]
+
+ interface = None
+ if config.exists(base_rule + ['outbound-interface', 'name']):
+ interface = config.return_value(base_rule + ['outbound-interface', 'name'])
+ else:
+ continue
+
+ prefix_base = base_rule + ['source', 'prefix']
+ if config.exists(prefix_base):
+ prefix = config.return_value(prefix_base)
+ config.set(new_base + [interface, 'prefix', prefix, 'mode'], value='static')
+ config.set_tag(new_base)
+ config.set_tag(new_base + [interface, 'prefix'])
+
+ if config.exists(base_rule + ['disable']):
+ config.set(new_base + [interface, 'prefix', prefix, 'disable'])
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ exit(1)