From 9eab0cdd0bbea0f899af5a7d68cc63523a12a703 Mon Sep 17 00:00:00 2001
From: Christian Poessinger <christian@poessinger.com>
Date: Sun, 1 May 2022 20:08:28 +0200
Subject: firewall: T4353: fix Jinja2 linting errors

---
 data/templates/firewall/nftables-defines.j2   |  32 +++
 data/templates/firewall/nftables-defines.tmpl |  32 ---
 data/templates/firewall/nftables-nat.j2       | 182 +++++++++++++++++
 data/templates/firewall/nftables-nat.tmpl     | 182 -----------------
 data/templates/firewall/nftables-nat66.j2     | 102 ++++++++++
 data/templates/firewall/nftables-nat66.tmpl   | 102 ----------
 data/templates/firewall/nftables-policy.j2    |  55 ++++++
 data/templates/firewall/nftables-policy.tmpl  |  55 ------
 data/templates/firewall/nftables.j2           | 274 ++++++++++++++++++++++++++
 data/templates/firewall/nftables.tmpl         | 274 --------------------------
 data/templates/firewall/upnpd.conf.j2         | 172 ++++++++++++++++
 data/templates/firewall/upnpd.conf.tmpl       | 172 ----------------
 data/templates/ndppd/ndppd.conf.j2            |  44 +++++
 data/templates/ndppd/ndppd.conf.tmpl          |  44 -----
 14 files changed, 861 insertions(+), 861 deletions(-)
 create mode 100644 data/templates/firewall/nftables-defines.j2
 delete mode 100644 data/templates/firewall/nftables-defines.tmpl
 create mode 100644 data/templates/firewall/nftables-nat.j2
 delete mode 100644 data/templates/firewall/nftables-nat.tmpl
 create mode 100644 data/templates/firewall/nftables-nat66.j2
 delete mode 100644 data/templates/firewall/nftables-nat66.tmpl
 create mode 100644 data/templates/firewall/nftables-policy.j2
 delete mode 100644 data/templates/firewall/nftables-policy.tmpl
 create mode 100644 data/templates/firewall/nftables.j2
 delete mode 100644 data/templates/firewall/nftables.tmpl
 create mode 100644 data/templates/firewall/upnpd.conf.j2
 delete mode 100644 data/templates/firewall/upnpd.conf.tmpl
 create mode 100644 data/templates/ndppd/ndppd.conf.j2
 delete mode 100644 data/templates/ndppd/ndppd.conf.tmpl

(limited to 'data')

diff --git a/data/templates/firewall/nftables-defines.j2 b/data/templates/firewall/nftables-defines.j2
new file mode 100644
index 000000000..4fa92f2e3
--- /dev/null
+++ b/data/templates/firewall/nftables-defines.j2
@@ -0,0 +1,32 @@
+{% if group is vyos_defined %}
+{%     if group.address_group is vyos_defined %}
+{%         for group_name, group_conf in group.address_group.items() %}
+define A_{{ group_name }} = { {{ group_conf.address | join(",") }} }
+{%         endfor %}
+{%     endif %}
+{%     if group.ipv6_address_group is vyos_defined %}
+{%         for group_name, group_conf in group.ipv6_address_group.items() %}
+define A6_{{ group_name }} = { {{ group_conf.address | join(",") }} }
+{%         endfor %}
+{%     endif %}
+{%     if group.mac_group is vyos_defined %}
+{%         for group_name, group_conf in group.mac_group.items() %}
+define M_{{ group_name }} = { {{ group_conf.mac_address | join(",") }} }
+{%         endfor %}
+{%     endif %}
+{%     if group.network_group is vyos_defined %}
+{%         for group_name, group_conf in group.network_group.items() %}
+define N_{{ group_name }} = { {{ group_conf.network | join(",") }} }
+{%         endfor %}
+{%     endif %}
+{%     if group.ipv6_network_group is vyos_defined %}
+{%         for group_name, group_conf in group.ipv6_network_group.items() %}
+define N6_{{ group_name }} = { {{ group_conf.network | join(",") }} }
+{%         endfor %}
+{%     endif %}
+{%     if group.port_group is vyos_defined %}
+{%         for group_name, group_conf in group.port_group.items() %}
+define P_{{ group_name }} = { {{ group_conf.port | join(",") }} }
+{%         endfor %}
+{%     endif %}
+{% endif %}
\ No newline at end of file
diff --git a/data/templates/firewall/nftables-defines.tmpl b/data/templates/firewall/nftables-defines.tmpl
deleted file mode 100644
index 66d31093b..000000000
--- a/data/templates/firewall/nftables-defines.tmpl
+++ /dev/null
@@ -1,32 +0,0 @@
-{% if group is vyos_defined %}
-{%   if group.address_group is vyos_defined %}
-{%     for group_name, group_conf in group.address_group.items() %}
-define A_{{ group_name }} = { {{ group_conf.address | join(",") }} }
-{%     endfor %}
-{%   endif %}
-{%   if group.ipv6_address_group is vyos_defined %}
-{%     for group_name, group_conf in group.ipv6_address_group.items() %}
-define A6_{{ group_name }} = { {{ group_conf.address | join(",") }} }
-{%     endfor %}
-{%   endif %}
-{%   if group.mac_group is vyos_defined %}
-{%     for group_name, group_conf in group.mac_group.items() %}
-define M_{{ group_name }} = { {{ group_conf.mac_address | join(",") }} }
-{%     endfor %}
-{%   endif %}
-{%   if group.network_group is vyos_defined %}
-{%     for group_name, group_conf in group.network_group.items() %}
-define N_{{ group_name }} = { {{ group_conf.network | join(",") }} }
-{%     endfor %}
-{%   endif %}
-{%   if group.ipv6_network_group is vyos_defined %}
-{%     for group_name, group_conf in group.ipv6_network_group.items() %}
-define N6_{{ group_name }} = { {{ group_conf.network | join(",") }} }
-{%     endfor %}
-{%   endif %}
-{%   if group.port_group is vyos_defined %}
-{%     for group_name, group_conf in group.port_group.items() %}
-define P_{{ group_name }} = { {{ group_conf.port | join(",") }} }
-{%     endfor %}
-{%   endif %}
-{% endif %}
\ No newline at end of file
diff --git a/data/templates/firewall/nftables-nat.j2 b/data/templates/firewall/nftables-nat.j2
new file mode 100644
index 000000000..1481e9104
--- /dev/null
+++ b/data/templates/firewall/nftables-nat.j2
@@ -0,0 +1,182 @@
+#!/usr/sbin/nft -f
+
+{% macro nat_rule(rule, config, chain) %}
+{% set comment  = '' %}
+{% set base_log = '' %}
+{% set src_addr  = 'ip saddr ' ~ config.source.address.replace('!','!= ') if config.source.address is vyos_defined %}
+{% set dst_addr  = 'ip daddr ' ~ config.destination.address.replace('!','!= ') if config.destination.address is vyos_defined %}
+{# negated port groups need special treatment, move != in front of { } group #}
+{% if config.source.port is vyos_defined and config.source.port.startswith('!') %}
+{%     set src_port  = 'sport != { ' ~ config.source.port.replace('!','') ~ ' }' %}
+{% else %}
+{%     set src_port  = 'sport { ' ~ config.source.port ~ ' }' if config.source.port is vyos_defined %}
+{% endif %}
+{# negated port groups need special treatment, move != in front of { } group #}
+{% if config.destination.port is vyos_defined and config.destination.port.startswith('!') %}
+{%     set dst_port  = 'dport != { ' ~ config.destination.port.replace('!','') ~ ' }' %}
+{% else %}
+{%     set dst_port  = 'dport { ' ~ config.destination.port ~ ' }' if config.destination.port is vyos_defined %}
+{% endif %}
+{% if chain is vyos_defined('PREROUTING') %}
+{%     set comment   = 'DST-NAT-' ~ rule %}
+{%     set base_log  = '[NAT-DST-' ~ rule %}
+{%     set interface = ' iifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %}
+{%     if config.translation.address is vyos_defined %}
+{#         support 1:1 network translation #}
+{%         if config.translation.address | is_ip_network %}
+{%             set trns_addr = 'dnat ip prefix to ip daddr map { ' ~ config.destination.address ~ ' : ' ~ config.translation.address ~ ' }' %}
+{#             we can now clear out the dst_addr part as it's already covered in aboves map #}
+{%             set dst_addr  = '' %}
+{%         else %}
+{%             set trns_addr = 'dnat to ' ~ config.translation.address %}
+{%         endif %}
+{%     endif %}
+{% elif chain is vyos_defined('POSTROUTING') %}
+{%     set comment   = 'SRC-NAT-' ~ rule %}
+{%     set base_log  = '[NAT-SRC-' ~ rule %}
+{%     set interface = ' oifname "' ~ config.outbound_interface ~ '"' if config.outbound_interface is vyos_defined and config.outbound_interface is not vyos_defined('any') else '' %}
+{%     if config.translation.address is vyos_defined %}
+{%         if config.translation.address is vyos_defined('masquerade') %}
+{%             set trns_addr = config.translation.address %}
+{%             if config.translation.port is vyos_defined %}
+{%                 set trns_addr = trns_addr ~ ' to ' %}
+{%             endif %}
+{#         support 1:1 network translation #}
+{%         elif config.translation.address | is_ip_network %}
+{%             set trns_addr = 'snat ip prefix to ip saddr map { ' ~ config.source.address ~ ' : ' ~ config.translation.address ~ ' }' %}
+{#             we can now clear out the src_addr part as it's already covered in aboves map #}
+{%             set src_addr  = '' %}
+{%         else %}
+{%             set trns_addr = 'snat to ' ~ config.translation.address %}
+{%         endif %}
+{%     endif %}
+{% endif %}
+{% set trns_port = ':' ~ config.translation.port if config.translation.port is vyos_defined %}
+{# protocol has a default value thus it is always present #}
+{% if config.protocol is vyos_defined('tcp_udp') %}
+{%     set protocol  = 'tcp' %}
+{%     set comment   = comment ~ ' tcp_udp' %}
+{% else %}
+{%     set protocol  = config.protocol %}
+{% endif %}
+{% if config.log is vyos_defined %}
+{%     if config.exclude is vyos_defined %}
+{%         set log = base_log ~ '-EXCL]' %}
+{%     elif config.translation.address is vyos_defined('masquerade') %}
+{%         set log = base_log ~ '-MASQ]' %}
+{%     else %}
+{%         set log = base_log ~ ']' %}
+{%     endif %}
+{% endif %}
+{% if config.exclude is vyos_defined %}
+{#     rule has been marked as 'exclude' thus we simply return here #}
+{%     set trns_addr = 'return' %}
+{%     set trns_port = '' %}
+{% endif %}
+{# T1083: NAT address and port translation options #}
+{% if config.translation.options is vyos_defined %}
+{%     if config.translation.options.address_mapping is vyos_defined('persistent') %}
+{%         set trns_opts_addr  = 'persistent' %}
+{%     endif %}
+{%     if config.translation.options.port_mapping is vyos_defined('random') %}
+{%         set trns_opts_port  = 'random' %}
+{%     elif config.translation.options.port_mapping is vyos_defined('fully-random') %}
+{%         set trns_opts_port  = 'fully-random' %}
+{%     endif %}
+{% endif %}
+{% if trns_opts_addr is vyos_defined and trns_opts_port is vyos_defined %}
+{%     set trns_opts  = trns_opts_addr ~ ',' ~ trns_opts_port %}
+{% elif trns_opts_addr is vyos_defined %}
+{%     set trns_opts  = trns_opts_addr %}
+{% elif trns_opts_port is vyos_defined %}
+{%     set trns_opts  = trns_opts_port %}
+{% endif %}
+{% set output = 'add rule ip nat ' ~ chain ~ interface %}
+{% if protocol is not vyos_defined('all') %}
+{%     set output = output ~ ' ip protocol ' ~ protocol %}
+{% endif %}
+{% if src_addr is vyos_defined %}
+{%     set output = output ~ ' ' ~ src_addr %}
+{% endif %}
+{% if src_port is vyos_defined %}
+{%     set output = output ~ ' ' ~ protocol ~ ' ' ~ src_port %}
+{% endif %}
+{% if dst_addr is vyos_defined %}
+{%     set output = output ~ ' ' ~ dst_addr %}
+{% endif %}
+{% if dst_port is vyos_defined %}
+{%     set output = output ~ ' ' ~ protocol ~ ' ' ~ dst_port %}
+{% endif %}
+{# Count packets #}
+{% set output = output ~ ' counter' %}
+{# Special handling of log option, we must repeat the entire rule before the #}
+{# NAT translation options are added, this is essential                      #}
+{% if log is vyos_defined %}
+{%     set log_output = output ~ ' log prefix "' ~ log ~ '" comment "' ~ comment ~ '"' %}
+{% endif %}
+{% if trns_addr is vyos_defined %}
+{%     set output = output ~ ' ' ~ trns_addr %}
+{% endif %}
+{% if trns_port is vyos_defined %}
+{#     Do not add a whitespace here, translation port must be directly added after IP address #}
+{#     e.g. 192.0.2.10:3389                                                                   #}
+{%     set output = output ~ trns_port %}
+{% endif %}
+{% if trns_opts is vyos_defined %}
+{%     set output = output ~ ' ' ~ trns_opts %}
+{% endif %}
+{% if comment is vyos_defined %}
+{%     set output = output ~ ' comment "' ~ comment ~ '"' %}
+{% endif %}
+{{ log_output if log_output is vyos_defined }}
+{{ output }}
+{# Special handling if protocol is tcp_udp, we must repeat the entire rule with udp as protocol #}
+{% if config.protocol is vyos_defined('tcp_udp') %}
+{#     Beware of trailing whitespace, without it the comment tcp_udp will be changed to udp_udp #}
+{{ log_output | replace('tcp ', 'udp ') if log_output is vyos_defined }}
+{{ output | replace('tcp ', 'udp ') }}
+{% endif %}
+{% endmacro %}
+
+# Start with clean SNAT and DNAT chains
+flush chain ip nat PREROUTING
+flush chain ip nat POSTROUTING
+{% if helper_functions is vyos_defined('remove') %}
+{# NAT if going to be disabled - remove rules and targets from nftables #}
+{%     set base_command = 'delete rule ip raw' %}
+{{ base_command }} PREROUTING handle {{ pre_ct_ignore }}
+{{ base_command }} OUTPUT     handle {{ out_ct_ignore }}
+{{ base_command }} PREROUTING handle {{ pre_ct_conntrack }}
+{{ base_command }} OUTPUT     handle {{ out_ct_conntrack }}
+
+delete chain ip raw NAT_CONNTRACK
+
+{% elif helper_functions is vyos_defined('add') %}
+{# NAT if enabled - add targets to nftables #}
+add chain ip raw NAT_CONNTRACK
+add rule ip raw NAT_CONNTRACK counter accept
+{%     set base_command = 'add rule ip raw' %}
+{{ base_command }} PREROUTING position {{ pre_ct_ignore }}    counter jump VYOS_CT_HELPER
+{{ base_command }} OUTPUT     position {{ out_ct_ignore }}    counter jump VYOS_CT_HELPER
+{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK
+{{ base_command }} OUTPUT     position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK
+{% endif %}
+
+#
+# Destination NAT rules build up here
+#
+add rule ip nat PREROUTING counter jump VYOS_PRE_DNAT_HOOK
+{% if destination.rule is vyos_defined %}
+{%     for rule, config in destination.rule.items() if config.disable is not vyos_defined %}
+{{ nat_rule(rule, config, 'PREROUTING') }}
+{%     endfor %}
+{% endif %}
+#
+# Source NAT rules build up here
+#
+add rule ip nat POSTROUTING counter jump VYOS_PRE_SNAT_HOOK
+{% if source.rule is vyos_defined %}
+{%     for rule, config in source.rule.items() if config.disable is not vyos_defined %}
+{{ nat_rule(rule, config, 'POSTROUTING') }}
+{%     endfor %}
+{% endif %}
diff --git a/data/templates/firewall/nftables-nat.tmpl b/data/templates/firewall/nftables-nat.tmpl
deleted file mode 100644
index 63aa48c77..000000000
--- a/data/templates/firewall/nftables-nat.tmpl
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/usr/sbin/nft -f
-
-{% macro nat_rule(rule, config, chain) %}
-{%   set comment  = '' %}
-{%   set base_log = '' %}
-{%   set src_addr  = 'ip saddr ' ~ config.source.address.replace('!','!= ') if config.source.address is vyos_defined %}
-{%   set dst_addr  = 'ip daddr ' ~ config.destination.address.replace('!','!= ') if config.destination.address is vyos_defined %}
-{#   negated port groups need special treatment, move != in front of { } group #}
-{%   if config.source.port is vyos_defined and config.source.port.startswith('!') %}
-{%     set src_port  = 'sport != { ' ~ config.source.port.replace('!','') ~ ' }' %}
-{%   else %}
-{%     set src_port  = 'sport { ' ~ config.source.port ~ ' }' if config.source.port is vyos_defined %}
-{%   endif %}
-{#   negated port groups need special treatment, move != in front of { } group #}
-{%   if config.destination.port is vyos_defined and config.destination.port.startswith('!') %}
-{%     set dst_port  = 'dport != { ' ~ config.destination.port.replace('!','') ~ ' }' %}
-{%   else %}
-{%     set dst_port  = 'dport { ' ~ config.destination.port ~ ' }' if config.destination.port is vyos_defined %}
-{%   endif %}
-{%   if chain is vyos_defined('PREROUTING') %}
-{%     set comment   = 'DST-NAT-' ~ rule %}
-{%     set base_log  = '[NAT-DST-' ~ rule %}
-{%     set interface = ' iifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %}
-{%     if config.translation.address is vyos_defined %}
-{#       support 1:1 network translation #}
-{%       if config.translation.address | is_ip_network %}
-{%         set trns_addr = 'dnat ip prefix to ip daddr map { ' ~ config.destination.address ~ ' : ' ~ config.translation.address ~ ' }' %}
-{#         we can now clear out the dst_addr part as it's already covered in aboves map #}
-{%         set dst_addr  = '' %}
-{%       else %}
-{%         set trns_addr = 'dnat to ' ~ config.translation.address %}
-{%       endif %}
-{%     endif %}
-{%   elif chain is vyos_defined('POSTROUTING') %}
-{%     set comment   = 'SRC-NAT-' ~ rule %}
-{%     set base_log  = '[NAT-SRC-' ~ rule %}
-{%     set interface = ' oifname "' ~ config.outbound_interface ~ '"' if config.outbound_interface is vyos_defined and config.outbound_interface is not vyos_defined('any') else '' %}
-{%     if config.translation.address is vyos_defined %}
-{%       if config.translation.address is vyos_defined('masquerade') %}
-{%         set trns_addr = config.translation.address %}
-{%         if config.translation.port is vyos_defined %}
-{%           set trns_addr = trns_addr ~ ' to ' %}
-{%         endif %}
-{#       support 1:1 network translation #}
-{%       elif config.translation.address | is_ip_network %}
-{%         set trns_addr = 'snat ip prefix to ip saddr map { ' ~ config.source.address ~ ' : ' ~ config.translation.address ~ ' }' %}
-{#         we can now clear out the src_addr part as it's already covered in aboves map #}
-{%         set src_addr  = '' %}
-{%       else %}
-{%         set trns_addr = 'snat to ' ~ config.translation.address %}
-{%       endif %}
-{%     endif %}
-{%   endif %}
-{%   set trns_port = ':' ~ config.translation.port if config.translation.port is vyos_defined %}
-{#   protocol has a default value thus it is always present #}
-{%   if config.protocol is vyos_defined('tcp_udp') %}
-{%     set protocol  = 'tcp' %}
-{%     set comment   = comment ~ ' tcp_udp' %}
-{%   else %}
-{%     set protocol  = config.protocol %}
-{%   endif %}
-{%   if config.log is vyos_defined %}
-{%     if config.exclude is vyos_defined %}
-{%       set log = base_log ~ '-EXCL]' %}
-{%     elif config.translation.address is vyos_defined('masquerade') %}
-{%       set log = base_log +'-MASQ]' %}
-{%     else %}
-{%       set log = base_log ~ ']' %}
-{%     endif %}
-{%   endif %}
-{%   if config.exclude is vyos_defined %}
-{#     rule has been marked as 'exclude' thus we simply return here #}
-{%     set trns_addr = 'return' %}
-{%     set trns_port = '' %}
-{%   endif %}
-{#   T1083: NAT address and port translation options #}
-{%   if config.translation.options is vyos_defined %}
-{%     if config.translation.options.address_mapping is vyos_defined('persistent') %}
-{%         set trns_opts_addr  = 'persistent' %}
-{%     endif %}
-{%     if config.translation.options.port_mapping is vyos_defined('random') %}
-{%       set trns_opts_port  = 'random' %}
-{%     elif config.translation.options.port_mapping is vyos_defined('fully-random') %}
-{%       set trns_opts_port  = 'fully-random' %}
-{%     endif %}
-{%   endif %}
-{%   if trns_opts_addr is vyos_defined and trns_opts_port is vyos_defined %}
-{%     set trns_opts  = trns_opts_addr ~ ',' ~ trns_opts_port %}
-{%   elif trns_opts_addr is vyos_defined %}
-{%     set trns_opts  = trns_opts_addr %}
-{%   elif trns_opts_port is vyos_defined %}
-{%     set trns_opts  = trns_opts_port %}
-{%   endif %}
-{%   set output = 'add rule ip nat ' ~ chain ~ interface %}
-{%   if protocol is not vyos_defined('all') %}
-{%     set output = output ~ ' ip protocol ' ~ protocol %}
-{%   endif %}
-{%   if src_addr is vyos_defined %}
-{%     set output = output ~ ' ' ~ src_addr %}
-{%   endif %}
-{%   if src_port is vyos_defined %}
-{%     set output = output ~ ' ' ~ protocol ~ ' ' ~ src_port %}
-{%   endif %}
-{%   if dst_addr is vyos_defined %}
-{%     set output = output ~ ' ' ~ dst_addr %}
-{%   endif %}
-{%   if dst_port is vyos_defined %}
-{%     set output = output ~ ' ' ~ protocol ~ ' ' ~ dst_port %}
-{%   endif %}
-{#   Count packets #}
-{%   set output = output ~ ' counter' %}
-{#   Special handling of log option, we must repeat the entire rule before the #}
-{#   NAT translation options are added, this is essential                      #}
-{%   if log is vyos_defined %}
-{%     set log_output = output ~ ' log prefix "' ~ log ~ '" comment "' ~ comment ~ '"' %}
-{%   endif %}
-{%   if trns_addr is vyos_defined %}
-{%     set output = output ~ ' ' ~ trns_addr %}
-{%   endif %}
-{%   if trns_port is vyos_defined %}
-{#     Do not add a whitespace here, translation port must be directly added after IP address #}
-{#     e.g. 192.0.2.10:3389                                                                   #}
-{%     set output = output ~ trns_port %}
-{%   endif %}
-{%   if trns_opts is vyos_defined %}
-{%     set output = output ~ ' ' ~ trns_opts %}
-{%   endif %}
-{%   if comment is vyos_defined %}
-{%     set output = output ~ ' comment "' ~ comment ~ '"' %}
-{%   endif %}
-{{ log_output if log_output is vyos_defined}}
-{{ output }}
-{#   Special handling if protocol is tcp_udp, we must repeat the entire rule with udp as protocol #}
-{%   if config.protocol is vyos_defined('tcp_udp') %}
-{#     Beware of trailing whitespace, without it the comment tcp_udp will be changed to udp_udp #}
-{{ log_output | replace('tcp ', 'udp ') if log_output is vyos_defined }}
-{{ output | replace('tcp ', 'udp ') }}
-{%   endif %}
-{% endmacro %}
-
-# Start with clean SNAT and DNAT chains
-flush chain ip nat PREROUTING
-flush chain ip nat POSTROUTING
-{% if helper_functions is vyos_defined('remove') %}
-{# NAT if going to be disabled - remove rules and targets from nftables #}
-{%   set base_command = 'delete rule ip raw' %}
-{{ base_command }} PREROUTING handle {{ pre_ct_ignore }}
-{{ base_command }} OUTPUT     handle {{ out_ct_ignore }}
-{{ base_command }} PREROUTING handle {{ pre_ct_conntrack }}
-{{ base_command }} OUTPUT     handle {{ out_ct_conntrack }}
-
-delete chain ip raw NAT_CONNTRACK
-
-{% elif helper_functions is vyos_defined('add') %}
-{# NAT if enabled - add targets to nftables #}
-add chain ip raw NAT_CONNTRACK
-add rule ip raw NAT_CONNTRACK counter accept
-{%   set base_command = 'add rule ip raw' %}
-{{ base_command }} PREROUTING position {{ pre_ct_ignore }}    counter jump VYOS_CT_HELPER
-{{ base_command }} OUTPUT     position {{ out_ct_ignore }}    counter jump VYOS_CT_HELPER
-{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK
-{{ base_command }} OUTPUT     position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK
-{% endif %}
-
-#
-# Destination NAT rules build up here
-#
-add rule ip nat PREROUTING counter jump VYOS_PRE_DNAT_HOOK
-{% if destination.rule is vyos_defined %}
-{%   for rule, config in destination.rule.items() if config.disable is not vyos_defined %}
-{{ nat_rule(rule, config, 'PREROUTING') }}
-{%   endfor %}
-{% endif %}
-#
-# Source NAT rules build up here
-#
-add rule ip nat POSTROUTING counter jump VYOS_PRE_SNAT_HOOK
-{% if source.rule is vyos_defined %}
-{%   for rule, config in source.rule.items() if config.disable is not vyos_defined %}
-{{ nat_rule(rule, config, 'POSTROUTING') }}
-{%   endfor %}
-{% endif %}
diff --git a/data/templates/firewall/nftables-nat66.j2 b/data/templates/firewall/nftables-nat66.j2
new file mode 100644
index 000000000..003b138b2
--- /dev/null
+++ b/data/templates/firewall/nftables-nat66.j2
@@ -0,0 +1,102 @@
+#!/usr/sbin/nft -f
+
+{% macro nptv6_rule(rule,config, chain) %}
+{% set comment  = '' %}
+{% set base_log = '' %}
+{% set src_prefix  = 'ip6 saddr ' ~ config.source.prefix if config.source.prefix is vyos_defined %}
+{% set dest_address  = 'ip6 daddr ' ~ config.destination.address if config.destination.address is vyos_defined %}
+{% if chain is vyos_defined('PREROUTING') %}
+{%     set comment   = 'DST-NAT66-' ~ rule %}
+{%     set base_log  = '[NAT66-DST-' ~ rule %}
+{%     set interface = ' iifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %}
+{%     if config.translation.address | is_ip_network %}
+{#         support 1:1 network translation #}
+{%         set dnat_type = 'dnat prefix to ' %}
+{%     else   %}
+{%         set dnat_type = 'dnat to ' %}
+{%     endif %}
+{%     set trns_address = dnat_type ~ config.translation.address if config.translation.address is vyos_defined %}
+{% elif chain is vyos_defined('POSTROUTING') %}
+{%     set comment   = 'SRC-NAT66-' ~ rule %}
+{%     set base_log  = '[NAT66-SRC-' ~ rule %}
+{%     if config.translation.address is vyos_defined %}
+{%         if config.translation.address is vyos_defined('masquerade') %}
+{%             set trns_address = config.translation.address %}
+{%         else %}
+{%             if config.translation.address | is_ip_network %}
+{#                 support 1:1 network translation #}
+{%                 set snat_type = 'snat prefix to ' %}
+{%             else   %}
+{%                 set snat_type = 'snat to ' %}
+{%             endif %}
+{%             set trns_address = snat_type ~ config.translation.address %}
+{%         endif %}
+{%     endif   %}
+{%     set interface = ' oifname "' ~ config.outbound_interface ~ '"' if config.outbound_interface is vyos_defined else '' %}
+{% endif %}
+{% if config.log is vyos_defined %}
+{%     if config.translation.address is vyos_defined('masquerade') %}
+{%         set log = base_log ~ '-MASQ]' %}
+{%     else %}
+{%         set log = base_log ~ ']' %}
+{%     endif %}
+{% endif %}
+{% set output = 'add rule ip6 nat ' ~ chain ~ interface %}
+{# Count packets #}
+{% set output = output ~ ' counter' %}
+{# Special handling of log option, we must repeat the entire rule before the #}
+{# NAT translation options are added, this is essential                      #}
+{% if log is vyos_defined %}
+{%     set log_output = output ~ ' log prefix "' ~ log ~ '" comment "' ~ comment ~ '"' %}
+{% endif %}
+{% if src_prefix is vyos_defined %}
+{%     set output = output ~ ' ' ~ src_prefix %}
+{% endif %}
+{% if dest_address is vyos_defined %}
+{%     set output = output ~ ' ' ~ dest_address %}
+{% endif %}
+{% if trns_address is vyos_defined %}
+{%     set output = output ~ ' ' ~ trns_address %}
+{% endif %}
+{% if comment is vyos_defined %}
+{%     set output = output ~ ' comment "' ~ comment ~ '"' %}
+{% endif %}
+{{ log_output if log_output is vyos_defined }}
+{{ output }}
+{% endmacro %}
+
+# Start with clean NAT table
+flush table ip6 nat
+{% if helper_functions is vyos_defined('remove') %}
+{# NAT if going to be disabled - remove rules and targets from nftables #}
+{%     set base_command = 'delete rule ip6 raw' %}
+{{ base_command }} PREROUTING handle {{ pre_ct_conntrack }}
+{{ base_command }} OUTPUT handle {{ out_ct_conntrack }}
+
+delete chain ip6 raw NAT_CONNTRACK
+
+{% elif helper_functions is vyos_defined('add') %}
+{# NAT if enabled - add targets to nftables #}
+add chain ip6 raw NAT_CONNTRACK
+add rule ip6 raw NAT_CONNTRACK counter accept
+{%     set base_command = 'add rule ip6 raw' %}
+{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK
+{{ base_command }} OUTPUT     position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK
+{% endif %}
+
+#
+# Destination NAT66 rules build up here
+#
+{% if destination.rule is vyos_defined %}
+{%     for rule, config in destination.rule.items() if config.disable is not vyos_defined %}
+{{ nptv6_rule(rule, config, 'PREROUTING') }}
+{%     endfor %}
+{% endif %}
+#
+# Source NAT66 rules build up here
+#
+{% if source.rule is vyos_defined %}
+{%     for rule, config in source.rule.items() if config.disable is not vyos_defined %}
+{{ nptv6_rule(rule, config, 'POSTROUTING') }}
+{%     endfor %}
+{% endif %}
diff --git a/data/templates/firewall/nftables-nat66.tmpl b/data/templates/firewall/nftables-nat66.tmpl
deleted file mode 100644
index ed98b888a..000000000
--- a/data/templates/firewall/nftables-nat66.tmpl
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/sbin/nft -f
-
-{% macro nptv6_rule(rule,config, chain) %}
-{%   set comment  = '' %}
-{%   set base_log = '' %}
-{%   set src_prefix  = 'ip6 saddr ' ~ config.source.prefix if config.source.prefix is vyos_defined %}
-{%   set dest_address  = 'ip6 daddr ' ~ config.destination.address if config.destination.address is vyos_defined %}
-{%   if chain is vyos_defined('PREROUTING') %}
-{%     set comment   = 'DST-NAT66-' ~ rule %}
-{%     set base_log  = '[NAT66-DST-' ~ rule %}
-{%     set interface = ' iifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %}
-{%     if config.translation.address | is_ip_network %}
-{#       support 1:1 network translation #}
-{%       set dnat_type = 'dnat prefix to ' %}
-{%     else   %}
-{%       set dnat_type = 'dnat to ' %}
-{%     endif %}
-{%     set trns_address = dnat_type ~ config.translation.address if config.translation.address is vyos_defined %}
-{%   elif chain is vyos_defined('POSTROUTING') %}
-{%     set comment   = 'SRC-NAT66-' ~ rule %}
-{%     set base_log  = '[NAT66-SRC-' ~ rule %}
-{%     if config.translation.address is vyos_defined %}
-{%         if config.translation.address is vyos_defined('masquerade') %}
-{%             set trns_address = config.translation.address %}
-{%         else %}
-{%             if config.translation.address | is_ip_network %}
-{#                 support 1:1 network translation #}
-{%                 set snat_type = 'snat prefix to ' %}
-{%             else   %}
-{%                 set snat_type = 'snat to ' %}
-{%             endif %}
-{%             set trns_address = snat_type ~ config.translation.address %}
-{%         endif %}
-{%     endif   %}
-{%     set interface = ' oifname "' ~ config.outbound_interface ~ '"' if config.outbound_interface is vyos_defined else '' %}
-{%   endif %}
-{%   if config.log is vyos_defined %}
-{%     if config.translation.address is vyos_defined('masquerade') %}
-{%       set log = base_log +'-MASQ]' %}
-{%     else %}
-{%       set log = base_log ~ ']' %}
-{%     endif %}
-{%   endif %}
-{%   set output = 'add rule ip6 nat ' ~ chain ~ interface %}
-{#   Count packets #}
-{%   set output = output ~ ' counter' %}
-{#   Special handling of log option, we must repeat the entire rule before the #}
-{#   NAT translation options are added, this is essential                      #}
-{%   if log is vyos_defined %}
-{%     set log_output = output ~ ' log prefix "' ~ log ~ '" comment "' ~ comment ~ '"' %}
-{%   endif %}
-{%   if src_prefix is vyos_defined %}
-{%     set output = output ~ ' ' ~ src_prefix %}
-{%   endif %}
-{%   if dest_address is vyos_defined %}
-{%     set output = output ~ ' ' ~ dest_address %}
-{%   endif %}
-{%   if trns_address is vyos_defined %}
-{%     set output = output ~ ' ' ~ trns_address %}
-{%   endif %}
-{%   if comment is vyos_defined %}
-{%     set output = output ~ ' comment "' ~ comment ~ '"' %}
-{%   endif %}
-{{ log_output if log_output is vyos_defined }}
-{{ output }}
-{% endmacro %}
-
-# Start with clean NAT table
-flush table ip6 nat
-{% if helper_functions is vyos_defined('remove') %}
-{# NAT if going to be disabled - remove rules and targets from nftables #}
-{%   set base_command = 'delete rule ip6 raw' %}
-{{base_command}} PREROUTING handle {{ pre_ct_conntrack }}
-{{base_command}} OUTPUT handle {{ out_ct_conntrack }}
-
-delete chain ip6 raw NAT_CONNTRACK
-
-{% elif helper_functions is vyos_defined('add') %}
-{# NAT if enabled - add targets to nftables #}
-add chain ip6 raw NAT_CONNTRACK
-add rule ip6 raw NAT_CONNTRACK counter accept
-{%   set base_command = 'add rule ip6 raw' %}
-{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK
-{{ base_command }} OUTPUT     position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK
-{% endif %}
-
-#
-# Destination NAT66 rules build up here
-#
-{% if destination.rule is vyos_defined %}
-{%   for rule, config in destination.rule.items() if config.disable is not vyos_defined %}
-{{ nptv6_rule(rule, config, 'PREROUTING') }}
-{%   endfor %}
-{% endif %}
-#
-# Source NAT66 rules build up here
-#
-{% if source.rule is vyos_defined %}
-{%   for rule, config in source.rule.items() if config.disable is not vyos_defined %}
-{{ nptv6_rule(rule, config, 'POSTROUTING') }}
-{%   endfor %}
-{% endif %}
diff --git a/data/templates/firewall/nftables-policy.j2 b/data/templates/firewall/nftables-policy.j2
new file mode 100644
index 000000000..0154c9f7e
--- /dev/null
+++ b/data/templates/firewall/nftables-policy.j2
@@ -0,0 +1,55 @@
+#!/usr/sbin/nft -f
+
+{% if cleanup_commands is vyos_defined %}
+{%     for command in cleanup_commands %}
+{{ command }}
+{%     endfor %}
+{% endif %}
+
+include "/run/nftables_defines.conf"
+
+table ip mangle {
+{% if first_install is vyos_defined %}
+    chain VYOS_PBR_PREROUTING {
+        type filter hook prerouting priority -150; policy accept;
+    }
+    chain VYOS_PBR_POSTROUTING {
+        type filter hook postrouting priority -150; policy accept;
+    }
+{% endif %}
+{% if route is vyos_defined %}
+{%     for route_text, conf in route.items() %}
+    chain VYOS_PBR_{{ route_text }} {
+{%         if conf.rule is vyos_defined %}
+{%             for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
+        {{ rule_conf | nft_rule(route_text, rule_id, 'ip') }}
+{%             endfor %}
+{%         endif %}
+        {{ conf | nft_default_rule(route_text) }}
+    }
+{%     endfor %}
+{% endif %}
+}
+
+table ip6 mangle {
+{% if first_install is vyos_defined %}
+    chain VYOS_PBR6_PREROUTING {
+        type filter hook prerouting priority -150; policy accept;
+    }
+    chain VYOS_PBR6_POSTROUTING {
+        type filter hook postrouting priority -150; policy accept;
+    }
+{% endif %}
+{% if route6 is vyos_defined %}
+{%     for route_text, conf in route6.items() %}
+    chain VYOS_PBR6_{{ route_text }} {
+{%         if conf.rule is vyos_defined %}
+{%             for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
+        {{ rule_conf | nft_rule(route_text, rule_id, 'ip6') }}
+{%             endfor %}
+{%         endif %}
+        {{ conf | nft_default_rule(route_text) }}
+    }
+{%     endfor %}
+{% endif %}
+}
diff --git a/data/templates/firewall/nftables-policy.tmpl b/data/templates/firewall/nftables-policy.tmpl
deleted file mode 100644
index d1b0fa56e..000000000
--- a/data/templates/firewall/nftables-policy.tmpl
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/sbin/nft -f
-
-{% if cleanup_commands is vyos_defined %}
-{%   for command in cleanup_commands %}
-{{ command }}
-{%   endfor %}
-{% endif %}
-
-include "/run/nftables_defines.conf"
-
-table ip mangle {
-{% if first_install is vyos_defined %}
-    chain VYOS_PBR_PREROUTING {
-        type filter hook prerouting priority -150; policy accept;
-    }
-    chain VYOS_PBR_POSTROUTING {
-        type filter hook postrouting priority -150; policy accept;
-    }
-{% endif %}
-{% if route is vyos_defined %}
-{%   for route_text, conf in route.items() %}
-    chain VYOS_PBR_{{ route_text }} {
-{%     if conf.rule is vyos_defined %}
-{%       for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
-        {{ rule_conf | nft_rule(route_text, rule_id, 'ip') }}
-{%       endfor %}
-{%     endif %}
-        {{ conf | nft_default_rule(route_text) }}
-    }
-{%   endfor %}
-{%- endif %}
-}
-
-table ip6 mangle {
-{% if first_install is vyos_defined %}
-    chain VYOS_PBR6_PREROUTING {
-        type filter hook prerouting priority -150; policy accept;
-    }
-    chain VYOS_PBR6_POSTROUTING {
-        type filter hook postrouting priority -150; policy accept;
-    }
-{% endif %}
-{% if route6 is vyos_defined %}
-{%   for route_text, conf in route6.items() %}
-    chain VYOS_PBR6_{{ route_text }} {
-{%     if conf.rule is vyos_defined %}
-{%       for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
-        {{ rule_conf | nft_rule(route_text, rule_id, 'ip6') }}
-{%       endfor %}
-{%     endif %}
-        {{ conf | nft_default_rule(route_text) }}
-    }
-{%   endfor %}
-{% endif %}
-}
diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2
new file mode 100644
index 000000000..fac3fad03
--- /dev/null
+++ b/data/templates/firewall/nftables.j2
@@ -0,0 +1,274 @@
+#!/usr/sbin/nft -f
+
+{% if cleanup_commands is vyos_defined %}
+{%     for command in cleanup_commands %}
+{{ command }}
+{%     endfor %}
+{% endif %}
+
+include "/run/nftables_defines.conf"
+
+table ip filter {
+{% if first_install is vyos_defined %}
+    chain VYOS_FW_FORWARD {
+        type filter hook forward priority 0; policy accept;
+        jump VYOS_POST_FW
+    }
+    chain VYOS_FW_LOCAL {
+        type filter hook input priority 0; policy accept;
+        jump VYOS_POST_FW
+    }
+    chain VYOS_FW_OUTPUT {
+        type filter hook output priority 0; policy accept;
+        jump VYOS_POST_FW
+    }
+    chain VYOS_POST_FW {
+        return
+    }
+    chain VYOS_FRAG_MARK {
+        type filter hook prerouting priority -450; policy accept;
+        ip frag-off & 0x3fff != 0 meta mark set 0xffff1 return
+    }
+{% endif %}
+{% if name is vyos_defined %}
+{%     set ns = namespace(sets=[]) %}
+{%     for name_text, conf in name.items() %}
+    chain NAME_{{ name_text }} {
+{%         if conf.rule is vyos_defined %}
+{%             for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
+        {{ rule_conf | nft_rule(name_text, rule_id) }}
+{%                 if rule_conf.recent is vyos_defined %}
+{%                     set ns.sets = ns.sets + [name_text + '_' + rule_id] %}
+{%                 endif %}
+{%             endfor %}
+{%         endif %}
+        {{ conf | nft_default_rule(name_text) }}
+    }
+{%     endfor %}
+{%     for set_name in ns.sets %}
+    set RECENT_{{ set_name }} {
+        type ipv4_addr
+        size 65535
+        flags dynamic
+    }
+{%     endfor %}
+{% endif %}
+{% if state_policy is vyos_defined %}
+    chain VYOS_STATE_POLICY {
+{%     if state_policy.established is vyos_defined %}
+        {{ state_policy.established | nft_state_policy('established') }}
+{%     endif %}
+{%     if state_policy.invalid is vyos_defined %}
+        {{ state_policy.invalid | nft_state_policy('invalid') }}
+{%     endif %}
+{%     if state_policy.related is vyos_defined %}
+        {{ state_policy.related | nft_state_policy('related') }}
+{%     endif %}
+        return
+    }
+{% endif %}
+}
+
+table ip6 filter {
+{% if first_install is vyos_defined %}
+    chain VYOS_FW6_FORWARD {
+        type filter hook forward priority 0; policy accept;
+        jump VYOS_POST_FW6
+    }
+    chain VYOS_FW6_LOCAL {
+        type filter hook input priority 0; policy accept;
+        jump VYOS_POST_FW6
+    }
+    chain VYOS_FW6_OUTPUT {
+        type filter hook output priority 0; policy accept;
+        jump VYOS_POST_FW6
+    }
+    chain VYOS_POST_FW6 {
+        return
+    }
+    chain VYOS_FRAG6_MARK {
+        type filter hook prerouting priority -450; policy accept;
+        exthdr frag exists meta mark set 0xffff1 return
+    }
+{% endif %}
+{% if ipv6_name is vyos_defined %}
+{%     set ns = namespace(sets=[]) %}
+{%     for name_text, conf in ipv6_name.items() %}
+    chain NAME6_{{ name_text }} {
+{%         if conf.rule is vyos_defined %}
+{%             for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
+        {{ rule_conf | nft_rule(name_text, rule_id, 'ip6') }}
+{%                 if rule_conf.recent is vyos_defined %}
+{%                     set ns.sets = ns.sets + [name_text + '_' + rule_id] %}
+{%                 endif %}
+{%             endfor %}
+{%         endif %}
+        {{ conf | nft_default_rule(name_text) }}
+    }
+{%     endfor %}
+{%     for set_name in ns.sets %}
+    set RECENT6_{{ set_name }} {
+        type ipv6_addr
+        size 65535
+        flags dynamic
+    }
+{%     endfor %}
+{% endif %}
+{% if state_policy is vyos_defined %}
+    chain VYOS_STATE_POLICY6 {
+{%     if state_policy.established is vyos_defined %}
+        {{ state_policy.established | nft_state_policy('established', ipv6=True) }}
+{%     endif %}
+{%     if state_policy.invalid is vyos_defined %}
+        {{ state_policy.invalid | nft_state_policy('invalid', ipv6=True) }}
+{%     endif %}
+{%     if state_policy.related is vyos_defined %}
+        {{ state_policy.related | nft_state_policy('related', ipv6=True) }}
+{%     endif %}
+        return
+    }
+{% endif %}
+}
+
+{% if first_install is vyos_defined %}
+table ip nat {
+    chain PREROUTING {
+        type nat hook prerouting priority -100; policy accept;
+        counter jump VYOS_PRE_DNAT_HOOK
+    }
+
+    chain POSTROUTING {
+        type nat hook postrouting priority 100; policy accept;
+        counter jump VYOS_PRE_SNAT_HOOK
+    }
+
+    chain VYOS_PRE_DNAT_HOOK {
+        return
+    }
+
+    chain VYOS_PRE_SNAT_HOOK {
+        return
+    }
+}
+
+table ip6 nat {
+    chain PREROUTING {
+        type nat hook prerouting priority -100; policy accept;
+        counter jump VYOS_DNPT_HOOK
+    }
+
+    chain POSTROUTING {
+        type nat hook postrouting priority 100; policy accept;
+        counter jump VYOS_SNPT_HOOK
+    }
+
+    chain VYOS_DNPT_HOOK {
+        return
+    }
+
+    chain VYOS_SNPT_HOOK {
+        return
+    }
+}
+
+table inet mangle {
+    chain FORWARD {
+        type filter hook forward priority -150; policy accept;
+    }
+}
+
+table raw {
+    chain VYOS_TCP_MSS {
+        type filter hook forward priority -300; policy accept;
+    }
+
+    chain PREROUTING {
+        type filter hook prerouting priority -200; policy accept;
+        counter jump VYOS_CT_IGNORE
+        counter jump VYOS_CT_TIMEOUT
+        counter jump VYOS_CT_PREROUTING_HOOK
+        counter jump FW_CONNTRACK
+        notrack
+    }
+
+    chain OUTPUT {
+        type filter hook output priority -200; policy accept;
+        counter jump VYOS_CT_IGNORE
+        counter jump VYOS_CT_TIMEOUT
+        counter jump VYOS_CT_OUTPUT_HOOK
+        counter jump FW_CONNTRACK
+        notrack
+    }
+
+    ct helper rpc_tcp {
+        type "rpc" protocol tcp;
+    }
+
+    ct helper rpc_udp {
+        type "rpc" protocol udp;
+    }
+
+    ct helper tns_tcp {
+        type "tns" protocol tcp;
+    }
+
+    chain VYOS_CT_HELPER {
+        ct helper set "rpc_tcp" tcp dport {111} return
+        ct helper set "rpc_udp" udp dport {111} return
+        ct helper set "tns_tcp" tcp dport {1521,1525,1536} return
+        return
+    }
+
+    chain VYOS_CT_IGNORE {
+        return
+    }
+
+    chain VYOS_CT_TIMEOUT {
+        return
+    }
+
+    chain VYOS_CT_PREROUTING_HOOK {
+        return
+    }
+
+    chain VYOS_CT_OUTPUT_HOOK {
+        return
+    }
+
+    chain FW_CONNTRACK {
+        accept
+    }
+}
+
+table ip6 raw {
+    chain VYOS_TCP_MSS {
+        type filter hook forward priority -300; policy accept;
+    }
+
+    chain PREROUTING {
+        type filter hook prerouting priority -300; policy accept;
+        counter jump VYOS_CT_PREROUTING_HOOK
+        counter jump FW_CONNTRACK
+        notrack
+    }
+
+    chain OUTPUT {
+        type filter hook output priority -300; policy accept;
+        counter jump VYOS_CT_OUTPUT_HOOK
+        counter jump FW_CONNTRACK
+        notrack
+    }
+
+    chain VYOS_CT_PREROUTING_HOOK {
+        return
+    }
+
+    chain VYOS_CT_OUTPUT_HOOK {
+        return
+    }
+
+    chain FW_CONNTRACK {
+        accept
+    }
+}
+{% endif %}
diff --git a/data/templates/firewall/nftables.tmpl b/data/templates/firewall/nftables.tmpl
deleted file mode 100644
index 3a3f2e04c..000000000
--- a/data/templates/firewall/nftables.tmpl
+++ /dev/null
@@ -1,274 +0,0 @@
-#!/usr/sbin/nft -f
-
-{% if cleanup_commands is vyos_defined %}
-{%   for command in cleanup_commands %}
-{{ command }}
-{%   endfor %}
-{% endif %}
-
-include "/run/nftables_defines.conf"
-
-table ip filter {
-{% if first_install is vyos_defined %}
-    chain VYOS_FW_FORWARD {
-        type filter hook forward priority 0; policy accept;
-        jump VYOS_POST_FW
-    }
-    chain VYOS_FW_LOCAL {
-        type filter hook input priority 0; policy accept;
-        jump VYOS_POST_FW
-    }
-    chain VYOS_FW_OUTPUT {
-        type filter hook output priority 0; policy accept;
-        jump VYOS_POST_FW
-    }
-    chain VYOS_POST_FW {
-        return
-    }
-    chain VYOS_FRAG_MARK {
-        type filter hook prerouting priority -450; policy accept;
-        ip frag-off & 0x3fff != 0 meta mark set 0xffff1 return
-    }
-{% endif %}
-{% if name is vyos_defined %}
-{%   set ns = namespace(sets=[]) %}
-{%   for name_text, conf in name.items() %}
-    chain NAME_{{ name_text }} {
-{%     if conf.rule is vyos_defined %}
-{%       for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
-        {{ rule_conf | nft_rule(name_text, rule_id) }}
-{%         if rule_conf.recent is vyos_defined %}
-{%           set ns.sets = ns.sets + [name_text + '_' + rule_id] %}
-{%         endif %}
-{%       endfor %}
-{%     endif %}
-        {{ conf | nft_default_rule(name_text) }}
-    }
-{%   endfor %}
-{%   for set_name in ns.sets %}
-    set RECENT_{{ set_name }} {
-        type ipv4_addr
-        size 65535
-        flags dynamic
-    }
-{%   endfor %}
-{% endif %}
-{% if state_policy is vyos_defined %}
-    chain VYOS_STATE_POLICY {
-{%   if state_policy.established is vyos_defined %}
-        {{ state_policy.established | nft_state_policy('established') }}
-{%   endif %}
-{%   if state_policy.invalid is vyos_defined %}
-        {{ state_policy.invalid | nft_state_policy('invalid') }}
-{%   endif %}
-{%   if state_policy.related is vyos_defined %}
-        {{ state_policy.related | nft_state_policy('related') }}
-{%   endif %}
-        return
-    }
-{% endif %}
-}
-
-table ip6 filter {
-{% if first_install is vyos_defined %}
-    chain VYOS_FW6_FORWARD {
-        type filter hook forward priority 0; policy accept;
-        jump VYOS_POST_FW6
-    }
-    chain VYOS_FW6_LOCAL {
-        type filter hook input priority 0; policy accept;
-        jump VYOS_POST_FW6
-    }
-    chain VYOS_FW6_OUTPUT {
-        type filter hook output priority 0; policy accept;
-        jump VYOS_POST_FW6
-    }
-    chain VYOS_POST_FW6 {
-        return
-    }
-    chain VYOS_FRAG6_MARK {
-        type filter hook prerouting priority -450; policy accept;
-        exthdr frag exists meta mark set 0xffff1 return
-    }
-{% endif %}
-{% if ipv6_name is vyos_defined %}
-{%   set ns = namespace(sets=[]) %}
-{%   for name_text, conf in ipv6_name.items() %}
-    chain NAME6_{{ name_text }} {
-{%     if conf.rule is vyos_defined %}
-{%       for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
-        {{ rule_conf | nft_rule(name_text, rule_id, 'ip6') }}
-{%         if rule_conf.recent is vyos_defined %}
-{%           set ns.sets = ns.sets + [name_text + '_' + rule_id] %}
-{%         endif %}
-{%       endfor %}
-{%     endif %}
-        {{ conf | nft_default_rule(name_text) }}
-    }
-{%   endfor %}
-{%   for set_name in ns.sets %}
-    set RECENT6_{{ set_name }} {
-        type ipv6_addr
-        size 65535
-        flags dynamic
-    }
-{%   endfor %}
-{% endif %}
-{% if state_policy is vyos_defined %}
-    chain VYOS_STATE_POLICY6 {
-{%   if state_policy.established is vyos_defined %}
-        {{ state_policy.established | nft_state_policy('established', ipv6=True) }}
-{%   endif %}
-{%   if state_policy.invalid is vyos_defined %}
-        {{ state_policy.invalid | nft_state_policy('invalid', ipv6=True) }}
-{%   endif %}
-{%   if state_policy.related is vyos_defined %}
-        {{ state_policy.related | nft_state_policy('related', ipv6=True) }}
-{%   endif %}
-        return
-    }
-{% endif %}
-}
-
-{% if first_install is vyos_defined %}
-table ip nat {
-    chain PREROUTING {
-        type nat hook prerouting priority -100; policy accept;
-        counter jump VYOS_PRE_DNAT_HOOK
-    }
-
-    chain POSTROUTING {
-        type nat hook postrouting priority 100; policy accept;
-        counter jump VYOS_PRE_SNAT_HOOK
-    }
-
-    chain VYOS_PRE_DNAT_HOOK {
-        return
-    }
-
-    chain VYOS_PRE_SNAT_HOOK {
-        return
-    }
-}
-
-table ip6 nat {
-    chain PREROUTING {
-        type nat hook prerouting priority -100; policy accept;
-        counter jump VYOS_DNPT_HOOK
-    }
-
-    chain POSTROUTING {
-        type nat hook postrouting priority 100; policy accept;
-        counter jump VYOS_SNPT_HOOK
-    }
-
-    chain VYOS_DNPT_HOOK {
-        return
-    }
-
-    chain VYOS_SNPT_HOOK {
-        return
-    }
-}
-
-table inet mangle {
-    chain FORWARD {
-        type filter hook forward priority -150; policy accept;
-    }
-}
-
-table raw {
-    chain VYOS_TCP_MSS {
-        type filter hook forward priority -300; policy accept;
-    }
-
-    chain PREROUTING {
-        type filter hook prerouting priority -200; policy accept;
-        counter jump VYOS_CT_IGNORE
-        counter jump VYOS_CT_TIMEOUT
-        counter jump VYOS_CT_PREROUTING_HOOK
-        counter jump FW_CONNTRACK
-        notrack
-    }
-
-    chain OUTPUT {
-        type filter hook output priority -200; policy accept;
-        counter jump VYOS_CT_IGNORE
-        counter jump VYOS_CT_TIMEOUT
-        counter jump VYOS_CT_OUTPUT_HOOK
-        counter jump FW_CONNTRACK
-        notrack
-    }
-
-    ct helper rpc_tcp {
-        type "rpc" protocol tcp;
-    }
-
-    ct helper rpc_udp {
-        type "rpc" protocol udp;
-    }
-
-    ct helper tns_tcp {
-        type "tns" protocol tcp;
-    }
-
-    chain VYOS_CT_HELPER {
-        ct helper set "rpc_tcp" tcp dport {111} return
-        ct helper set "rpc_udp" udp dport {111} return
-        ct helper set "tns_tcp" tcp dport {1521,1525,1536} return
-        return
-    }
-
-    chain VYOS_CT_IGNORE {
-        return
-    }
-
-    chain VYOS_CT_TIMEOUT {
-        return
-    }
-
-    chain VYOS_CT_PREROUTING_HOOK {
-        return
-    }
-
-    chain VYOS_CT_OUTPUT_HOOK {
-        return
-    }
-
-    chain FW_CONNTRACK {
-        accept
-    }
-}
-
-table ip6 raw {
-    chain VYOS_TCP_MSS {
-        type filter hook forward priority -300; policy accept;
-    }
-
-    chain PREROUTING {
-        type filter hook prerouting priority -300; policy accept;
-        counter jump VYOS_CT_PREROUTING_HOOK
-        counter jump FW_CONNTRACK
-        notrack
-    }
-
-    chain OUTPUT {
-        type filter hook output priority -300; policy accept;
-        counter jump VYOS_CT_OUTPUT_HOOK
-        counter jump FW_CONNTRACK
-        notrack
-    }
-
-    chain VYOS_CT_PREROUTING_HOOK {
-        return
-    }
-
-    chain VYOS_CT_OUTPUT_HOOK {
-        return
-    }
-
-    chain FW_CONNTRACK {
-        accept
-    }
-}
-{% endif %}
diff --git a/data/templates/firewall/upnpd.conf.j2 b/data/templates/firewall/upnpd.conf.j2
new file mode 100644
index 000000000..27573cbf9
--- /dev/null
+++ b/data/templates/firewall/upnpd.conf.j2
@@ -0,0 +1,172 @@
+# This is the UPNP configuration file
+
+# WAN network interface
+ext_ifname={{ wan_interface }}
+{% if wan_ip is vyos_defined %}
+# If the WAN interface has several IP addresses, you
+# can specify the one to use below
+{%     for addr in wan_ip %}
+ext_ip={{ addr }}
+{%     endfor  %}
+{% endif %}
+
+# LAN network interfaces IPs / networks
+{% if listen is vyos_defined %}
+# There can be multiple listening IPs for SSDP traffic, in that case
+# use multiple 'listening_ip=...' lines, one for each network interface.
+# It can be IP address or network interface name (ie. "eth0")
+# It is mandatory to use the network interface name in order to enable IPv6
+# HTTP is available on all interfaces.
+# When MULTIPLE_EXTERNAL_IP is enabled, the external IP
+# address associated with the subnet follows. For example:
+#  listening_ip=192.168.0.1/24 88.22.44.13
+{%     for addr in listen %}
+{%         if addr | is_ipv4  %}
+listening_ip={{ addr }}
+{%         elif addr | is_ipv6  %}
+ipv6_listening_ip={{ addr }}
+{%         else %}
+listening_ip={{ addr }}
+{%         endif  %}
+{%     endfor  %}
+{% endif %}
+
+# CAUTION: mixing up WAN and LAN interfaces may introduce security risks!
+# Be sure to assign the correct interfaces to LAN and WAN and consider
+# implementing UPnP permission rules at the bottom of this configuration file
+
+# Port for HTTP (descriptions and SOAP) traffic. Set to 0 for autoselect.
+#http_port=0
+# Port for HTTPS. Set to 0 for autoselect (default)
+#https_port=0
+
+# Path to the UNIX socket used to communicate with MiniSSDPd
+# If running, MiniSSDPd will manage M-SEARCH answering.
+# default is /var/run/minissdpd.sock
+#minissdpdsocket=/var/run/minissdpd.sock
+
+{% if nat_pmp is vyos_defined %}
+# Enable NAT-PMP support (default is no)
+enable_natpmp=yes
+{% endif %}
+
+# Enable UPNP support (default is yes)
+enable_upnp=yes
+
+{% if pcp_lifetime is vyos_defined %}
+# PCP
+# Configure the minimum and maximum lifetime of a port mapping in seconds
+# 120s and 86400s (24h) are suggested values from PCP-base
+{%     if pcp_lifetime.max is vyos_defined %}
+max_lifetime={{ pcp_lifetime.max }}
+{%     endif %}
+{%     if pcp_lifetime.min is vyos_defined %}
+min_lifetime={{ pcp_lifetime.min }}
+{%     endif %}
+{% endif %}
+
+
+# To enable the next few runtime options, see compile time
+# ENABLE_MANUFACTURER_INFO_CONFIGURATION (config.h)
+
+{% if friendly_name is vyos_defined %}
+# Name of this service, default is "`uname -s` router"
+friendly_name= {{ friendly_name }}
+{% endif  %}
+
+# Manufacturer name, default is "`uname -s`"
+manufacturer_name=VyOS
+
+# Manufacturer URL, default is URL of OS vendor
+manufacturer_url=https://vyos.io/
+
+# Model name, default is "`uname -s` router"
+model_name=VyOS Router Model
+
+# Model description, default is "`uname -s` router"
+model_description=Vyos open source enterprise router/firewall operating system
+
+# Model URL, default is URL of OS vendor
+model_url=https://vyos.io/
+
+{% if secure_mode is vyos_defined %}
+# Secure Mode, UPnP clients can only add mappings to their own IP
+secure_mode=yes
+{% else %}
+# Secure Mode, UPnP clients can only add mappings to their own IP
+secure_mode=no
+{% endif %}
+
+{% if presentation_url is vyos_defined %}
+# Default presentation URL is HTTP address on port 80
+# If set to an empty string, no presentationURL element will appear
+# in the XML description of the device, which prevents MS Windows
+# from displaying an icon in the "Network Connections" panel.
+#presentation_url= {{ presentation_url }}
+{% endif %}
+
+# Report system uptime instead of daemon uptime
+system_uptime=yes
+
+# Unused rules cleaning.
+# never remove any rule before this threshold for the number
+# of redirections is exceeded. default to 20
+clean_ruleset_threshold=10
+# Clean process work interval in seconds. default to 0 (disabled).
+# a 600 seconds (10 minutes) interval makes sense
+clean_ruleset_interval=600
+
+# Anchor name in pf (default is miniupnpd)
+anchor=VyOS
+
+uuid={{ uuid }}
+
+# Lease file location
+lease_file=/config/upnp.leases
+
+# Daemon's serial and model number when reporting to clients
+# (in XML description)
+#serial=12345678
+#model_number=1
+
+{% if rules is vyos_defined %}
+# UPnP permission rules
+# (allow|deny) (external port range) IP/mask (internal port range)
+# A port range is <min port>-<max port> or <port> if there is only
+# one port in the range.
+# IP/mask format must be nnn.nnn.nnn.nnn/nn
+# It is advised to only allow redirection of port >= 1024
+# and end the rule set with "deny 0-65535 0.0.0.0/0 0-65535"
+# The following default ruleset allows specific LAN side IP addresses
+# to request only ephemeral ports. It is recommended that users
+# modify the IP ranges to match their own internal networks, and
+# also consider implementing network-specific restrictions
+# CAUTION: failure to enforce any rules may permit insecure requests to be made!
+{%     for rule, config in rules.items() %}
+{%         if config.disable is vyos_defined %}
+{{ config.action }} {{ config.external_port_range }} {{ config.ip }} {{ config.internal_port_range }}
+{%         endif %}
+{%     endfor %}
+{% endif %}
+
+{% if stun is vyos_defined %}
+# WAN interface must have public IP address. Otherwise it is behind NAT
+# and port forwarding is impossible. In some cases WAN interface can be
+# behind unrestricted NAT 1:1 when all incoming traffic is NAT-ed and
+# routed to WAN interfaces without any filtering. In this cases miniupnpd
+# needs to know public IP address and it can be learnt by asking external
+# server via STUN protocol. Following option enable retrieving external
+# public IP address from STUN server and detection of NAT type. You need
+# to specify also external STUN server in stun_host option below.
+# This option is disabled by default.
+ext_perform_stun=yes
+# Specify STUN server, either hostname or IP address
+# Some public STUN servers:
+#  stun.stunprotocol.org
+#  stun.sipgate.net
+#  stun.xten.com
+#  stun.l.google.com (on non standard port 19302)
+ext_stun_host={{ stun.host }}
+# Specify STUN UDP port, by default it is standard port 3478.
+ext_stun_port={{ stun.port }}
+{% endif %}
diff --git a/data/templates/firewall/upnpd.conf.tmpl b/data/templates/firewall/upnpd.conf.tmpl
deleted file mode 100644
index 6e73995fa..000000000
--- a/data/templates/firewall/upnpd.conf.tmpl
+++ /dev/null
@@ -1,172 +0,0 @@
-# This is the UPNP configuration file
-
-# WAN network interface
-ext_ifname={{ wan_interface }}
-{% if wan_ip is vyos_defined %}
-# If the WAN interface has several IP addresses, you
-# can specify the one to use below
-{%   for addr in wan_ip %}
-ext_ip={{ addr }}
-{%   endfor  %}
-{% endif %}
-
-# LAN network interfaces IPs / networks
-{% if listen is vyos_defined %}
-# There can be multiple listening IPs for SSDP traffic, in that case
-# use multiple 'listening_ip=...' lines, one for each network interface.
-# It can be IP address or network interface name (ie. "eth0")
-# It is mandatory to use the network interface name in order to enable IPv6
-# HTTP is available on all interfaces.
-# When MULTIPLE_EXTERNAL_IP is enabled, the external IP
-# address associated with the subnet follows. For example:
-#  listening_ip=192.168.0.1/24 88.22.44.13
-{%   for addr in listen %}
-{%     if addr | is_ipv4  %}
-listening_ip={{ addr }}
-{%     elif addr | is_ipv6  %}
-ipv6_listening_ip={{ addr }}
-{%     else %}
-listening_ip={{ addr }}
-{%     endif  %}
-{%   endfor  %}
-{% endif %}
-
-# CAUTION: mixing up WAN and LAN interfaces may introduce security risks!
-# Be sure to assign the correct interfaces to LAN and WAN and consider
-# implementing UPnP permission rules at the bottom of this configuration file
-
-# Port for HTTP (descriptions and SOAP) traffic. Set to 0 for autoselect.
-#http_port=0
-# Port for HTTPS. Set to 0 for autoselect (default)
-#https_port=0
-
-# Path to the UNIX socket used to communicate with MiniSSDPd
-# If running, MiniSSDPd will manage M-SEARCH answering.
-# default is /var/run/minissdpd.sock
-#minissdpdsocket=/var/run/minissdpd.sock
-
-{% if nat_pmp is vyos_defined %}
-# Enable NAT-PMP support (default is no)
-enable_natpmp=yes
-{% endif %}
-
-# Enable UPNP support (default is yes)
-enable_upnp=yes
-
-{% if pcp_lifetime is vyos_defined %}
-# PCP
-# Configure the minimum and maximum lifetime of a port mapping in seconds
-# 120s and 86400s (24h) are suggested values from PCP-base
-{% if pcp_lifetime.max is vyos_defined %}
-max_lifetime={{ pcp_lifetime.max }}
-{% endif %}
-{% if pcp_lifetime.min is vyos_defined %}
-min_lifetime={{ pcp_lifetime.min }}
-{% endif %}
-{% endif %}
-
-
-# To enable the next few runtime options, see compile time
-# ENABLE_MANUFACTURER_INFO_CONFIGURATION (config.h)
-
-{% if friendly_name is vyos_defined %}
-# Name of this service, default is "`uname -s` router"
-friendly_name= {{ friendly_name }}
-{% endif  %}
-
-# Manufacturer name, default is "`uname -s`"
-manufacturer_name=VyOS
-
-# Manufacturer URL, default is URL of OS vendor
-manufacturer_url=https://vyos.io/
-
-# Model name, default is "`uname -s` router"
-model_name=VyOS Router Model
-
-# Model description, default is "`uname -s` router"
-model_description=Vyos open source enterprise router/firewall operating system
-
-# Model URL, default is URL of OS vendor
-model_url=https://vyos.io/
-
-{% if secure_mode is vyos_defined %}
-# Secure Mode, UPnP clients can only add mappings to their own IP
-secure_mode=yes
-{% else %}
-# Secure Mode, UPnP clients can only add mappings to their own IP
-secure_mode=no
-{% endif %}
-
-{% if presentation_url is vyos_defined %}
-# Default presentation URL is HTTP address on port 80
-# If set to an empty string, no presentationURL element will appear
-# in the XML description of the device, which prevents MS Windows
-# from displaying an icon in the "Network Connections" panel.
-#presentation_url= {{ presentation_url }}
-{% endif %}
-
-# Report system uptime instead of daemon uptime
-system_uptime=yes
-
-# Unused rules cleaning.
-# never remove any rule before this threshold for the number
-# of redirections is exceeded. default to 20
-clean_ruleset_threshold=10
-# Clean process work interval in seconds. default to 0 (disabled).
-# a 600 seconds (10 minutes) interval makes sense
-clean_ruleset_interval=600
-
-# Anchor name in pf (default is miniupnpd)
-anchor=VyOS
-
-uuid={{ uuid }}
-
-# Lease file location
-lease_file=/config/upnp.leases
-
-# Daemon's serial and model number when reporting to clients
-# (in XML description)
-#serial=12345678
-#model_number=1
-
-{% if rules is vyos_defined %}
-# UPnP permission rules
-# (allow|deny) (external port range) IP/mask (internal port range)
-# A port range is <min port>-<max port> or <port> if there is only
-# one port in the range.
-# IP/mask format must be nnn.nnn.nnn.nnn/nn
-# It is advised to only allow redirection of port >= 1024
-# and end the rule set with "deny 0-65535 0.0.0.0/0 0-65535"
-# The following default ruleset allows specific LAN side IP addresses
-# to request only ephemeral ports. It is recommended that users
-# modify the IP ranges to match their own internal networks, and
-# also consider implementing network-specific restrictions
-# CAUTION: failure to enforce any rules may permit insecure requests to be made!
-{% for rule, config in rules.items() %}
-{%  if config.disable is vyos_defined %}
-{{ config.action}} {{ config.external_port_range }} {{ config.ip }} {{ config.internal_port_range }}
-{%  endif %}
-{% endfor %}
-{% endif %}
-
-{% if stun is vyos_defined %}
-# WAN interface must have public IP address. Otherwise it is behind NAT
-# and port forwarding is impossible. In some cases WAN interface can be
-# behind unrestricted NAT 1:1 when all incoming traffic is NAT-ed and
-# routed to WAN interfaces without any filtering. In this cases miniupnpd
-# needs to know public IP address and it can be learnt by asking external
-# server via STUN protocol. Following option enable retrieving external
-# public IP address from STUN server and detection of NAT type. You need
-# to specify also external STUN server in stun_host option below.
-# This option is disabled by default.
-ext_perform_stun=yes
-# Specify STUN server, either hostname or IP address
-# Some public STUN servers:
-#  stun.stunprotocol.org
-#  stun.sipgate.net
-#  stun.xten.com
-#  stun.l.google.com (on non standard port 19302)
-ext_stun_host={{ stun.host }}
-# Specify STUN UDP port, by default it is standard port 3478.
-ext_stun_port={{ stun.port }}
-{% endif %}
diff --git a/data/templates/ndppd/ndppd.conf.j2 b/data/templates/ndppd/ndppd.conf.j2
new file mode 100644
index 000000000..120fa0a64
--- /dev/null
+++ b/data/templates/ndppd/ndppd.conf.j2
@@ -0,0 +1,44 @@
+########################################################
+#
+# autogenerated by nat66.py
+#
+#   The configuration file must define one upstream
+#   interface.
+#
+#   For some services, such as nat66, because it runs
+#    stateless, it needs to rely on NDP Proxy to respond
+#   to NDP requests.
+#
+#   When using nat66 source rules, NDP Proxy needs
+#   to be enabled
+#
+########################################################
+
+{% set global = namespace(ndppd_interfaces = [],ndppd_prefixs = []) %}
+{% if source.rule is vyos_defined %}
+{%     for rule, config in source.rule.items() if config.disable is not defined %}
+{%         if config.outbound_interface is vyos_defined %}
+{%             if config.outbound_interface not in global.ndppd_interfaces %}
+{%                 set global.ndppd_interfaces = global.ndppd_interfaces + [config.outbound_interface] %}
+{%             endif   %}
+{%             if config.translation.address is vyos_defined and config.translation.address | is_ip_network %}
+{%                 set global.ndppd_prefixs = global.ndppd_prefixs + [{'interface':config.outbound_interface,'rule':config.translation.address}] %}
+{%             endif %}
+{%         endif %}
+{%     endfor %}
+{% endif %}
+
+{% for interface in global.ndppd_interfaces %}
+proxy {{ interface }} {
+    router yes
+    timeout 500
+    ttl 30000
+{%     for map in global.ndppd_prefixs %}
+{%         if map.interface == interface %}
+    rule {{ map.rule }} {
+        static
+    }
+{%         endif  %}
+{%     endfor   %}
+}
+{% endfor %}
diff --git a/data/templates/ndppd/ndppd.conf.tmpl b/data/templates/ndppd/ndppd.conf.tmpl
deleted file mode 100644
index c41392cc7..000000000
--- a/data/templates/ndppd/ndppd.conf.tmpl
+++ /dev/null
@@ -1,44 +0,0 @@
-########################################################
-#
-# autogenerated by nat66.py
-#
-#   The configuration file must define one upstream
-#   interface.
-#
-#   For some services, such as nat66, because it runs
-#    stateless, it needs to rely on NDP Proxy to respond
-#   to NDP requests.
-#
-#   When using nat66 source rules, NDP Proxy needs
-#   to be enabled
-#
-########################################################
-
-{% set global = namespace(ndppd_interfaces = [],ndppd_prefixs = []) %}
-{% if source.rule is vyos_defined %}
-{%   for rule, config in source.rule.items() if config.disable is not defined %}
-{%     if config.outbound_interface is vyos_defined %}
-{%         if config.outbound_interface not in global.ndppd_interfaces %}
-{%             set global.ndppd_interfaces = global.ndppd_interfaces + [config.outbound_interface] %}
-{%         endif   %}
-{%         if config.translation.address is vyos_defined and config.translation.address | is_ip_network %}
-{%             set global.ndppd_prefixs = global.ndppd_prefixs + [{'interface':config.outbound_interface,'rule':config.translation.address}] %}
-{%         endif    %}
-{%     endif    %}
-{%   endfor %}
-{% endif %}
-
-{% for interface in global.ndppd_interfaces %}
-proxy {{ interface }} {
-    router yes
-    timeout 500
-    ttl 30000
-{%  for map in global.ndppd_prefixs %}
-{%     if map.interface == interface %}
-    rule {{ map.rule }} {
-        static
-    }
-{%     endif  %}
-{%  endfor   %}
-}
-{% endfor %}
-- 
cgit v1.2.3