Skip to content

Commit

Permalink
T5681: Firewall,Nat and Nat66: simplified and standarize interface ma…
Browse files Browse the repository at this point in the history
…tcher firewal, nat and nat66.

(cherry picked from commit 51abbc0)
  • Loading branch information
nicolas-fort authored and sever-sever committed Nov 1, 2023
1 parent 03e5ab6 commit 2b38b45
Show file tree
Hide file tree
Showing 19 changed files with 348 additions and 88 deletions.
8 changes: 4 additions & 4 deletions data/templates/ndppd/ndppd.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
{% 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] %}
{% if config.outbound_interface.name is vyos_defined %}
{% if config.outbound_interface.name not in global.ndppd_interfaces %}
{% set global.ndppd_interfaces = global.ndppd_interfaces + [config.outbound_interface.name] %}
{% 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}] %}
{% set global.ndppd_prefixs = global.ndppd_prefixs + [{'interface':config.outbound_interface.name,'rule':config.translation.address}] %}
{% endif %}
{% endif %}
{% endfor %}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!-- include start from firewall/inbound-interface-no-group.xml.i -->
<node name="inbound-interface">
<properties>
<help>Match inbound-interface</help>
</properties>
<children>
<leafNode name="name">
<properties>
<help>Match interface</help>
<completionHelp>
<script>${vyos_completion_dir}/list_interfaces</script>
<path>vrf name</path>
</completionHelp>
<valueHelp>
<format>txt</format>
<description>Interface name</description>
</valueHelp>
<valueHelp>
<format>txt*</format>
<description>Interface name with wildcard</description>
</valueHelp>
<valueHelp>
<format>!txt</format>
<description>Inverted interface name to match</description>
</valueHelp>
<constraint>
<regex>(\!?)(bond|br|dum|en|ersp|eth|gnv|ifb|lan|l2tp|l2tpeth|macsec|peth|ppp|pppoe|pptp|sstp|tun|veth|vti|vtun|vxlan|wg|wlan|wwan)([0-9]?)(\*?)(.+)?|(\!?)lo</regex>
<validator name="vrf-name"/>
</constraint>
</properties>
</leafNode>
</children>
</node>
<!-- include end -->
4 changes: 2 additions & 2 deletions interface-definitions/include/firewall/match-interface.xml.i
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- include start from firewall/match-interface.xml.i -->
<leafNode name="interface-name">
<leafNode name="name">
<properties>
<help>Match interface</help>
<completionHelp>
Expand All @@ -22,7 +22,7 @@
</constraint>
</properties>
</leafNode>
<leafNode name="interface-group">
<leafNode name="group">
<properties>
<help>Match interface-group</help>
<completionHelp>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!-- include start from firewall/outbound-interface-no-group.xml.i -->
<node name="outbound-interface">
<properties>
<help>Match outbound-interface</help>
</properties>
<children>
<leafNode name="name">
<properties>
<help>Match interface</help>
<completionHelp>
<script>${vyos_completion_dir}/list_interfaces</script>
<path>vrf name</path>
</completionHelp>
<valueHelp>
<format>txt</format>
<description>Interface name</description>
</valueHelp>
<valueHelp>
<format>txt*</format>
<description>Interface name with wildcard</description>
</valueHelp>
<valueHelp>
<format>!txt</format>
<description>Inverted interface name to match</description>
</valueHelp>
<constraint>
<regex>(\!?)(bond|br|dum|en|ersp|eth|gnv|ifb|lan|l2tp|l2tpeth|macsec|peth|ppp|pppoe|pptp|sstp|tun|veth|vti|vtun|vxlan|wg|wlan|wwan)([0-9]?)(\*?)(.+)?|(\!?)lo</regex>
<validator name="vrf-name"/>
</constraint>
</properties>
</leafNode>
</children>
</node>
<!-- include end -->
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<!-- include start from include/version/firewall-version.xml.i -->
<syntaxVersion component='firewall' version='11'></syntaxVersion>
<syntaxVersion component='firewall' version='12'></syntaxVersion>
<!-- include end -->
2 changes: 1 addition & 1 deletion interface-definitions/include/version/nat-version.xml.i
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<!-- include start from include/version/nat-version.xml.i -->
<syntaxVersion component='nat' version='5'></syntaxVersion>
<syntaxVersion component='nat' version='7'></syntaxVersion>
<!-- include end -->
2 changes: 1 addition & 1 deletion interface-definitions/include/version/nat66-version.xml.i
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<!-- include start from include/version/nat66-version.xml.i -->
<syntaxVersion component='nat66' version='1'></syntaxVersion>
<syntaxVersion component='nat66' version='2'></syntaxVersion>
<!-- include end -->
19 changes: 2 additions & 17 deletions interface-definitions/nat66.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,7 @@
<valueless/>
</properties>
</leafNode>
<leafNode name="outbound-interface">
<properties>
<help>Outbound interface of NAT66 traffic</help>
<completionHelp>
<script>${vyos_completion_dir}/list_interfaces</script>
</completionHelp>
</properties>
</leafNode>
#include <include/firewall/outbound-interface-no-group.xml.i>
#include <include/nat/protocol.xml.i>
<node name="destination">
<properties>
Expand Down Expand Up @@ -166,15 +159,7 @@
<valueless/>
</properties>
</leafNode>
<leafNode name="inbound-interface">
<properties>
<help>Inbound interface of NAT66 traffic</help>
<completionHelp>
<list>any</list>
<script>${vyos_completion_dir}/list_interfaces</script>
</completionHelp>
</properties>
</leafNode>
#include <include/firewall/inbound-interface-no-group.xml.i>
#include <include/nat/protocol.xml.i>
<node name="destination">
<properties>
Expand Down
12 changes: 6 additions & 6 deletions python/vyos/firewall.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,29 +294,29 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):

if 'inbound_interface' in rule_conf:
operator = ''
if 'interface_name' in rule_conf['inbound_interface']:
iiface = rule_conf['inbound_interface']['interface_name']
if 'name' in rule_conf['inbound_interface']:
iiface = rule_conf['inbound_interface']['name']
if iiface[0] == '!':
operator = '!='
iiface = iiface[1:]
output.append(f'iifname {operator} {{{iiface}}}')
else:
iiface = rule_conf['inbound_interface']['interface_group']
iiface = rule_conf['inbound_interface']['group']
if iiface[0] == '!':
operator = '!='
iiface = iiface[1:]
output.append(f'iifname {operator} @I_{iiface}')

if 'outbound_interface' in rule_conf:
operator = ''
if 'interface_name' in rule_conf['outbound_interface']:
oiface = rule_conf['outbound_interface']['interface_name']
if 'name' in rule_conf['outbound_interface']:
oiface = rule_conf['outbound_interface']['name']
if oiface[0] == '!':
operator = '!='
oiface = oiface[1:]
output.append(f'oifname {operator} {{{oiface}}}')
else:
oiface = rule_conf['outbound_interface']['interface_group']
oiface = rule_conf['outbound_interface']['group']
if oiface[0] == '!':
operator = '!='
oiface = oiface[1:]
Expand Down
12 changes: 6 additions & 6 deletions python/vyos/nat.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,29 @@ def parse_nat_rule(rule_conf, rule_id, nat_type, ipv6=False):

if 'inbound_interface' in rule_conf:
operator = ''
if 'interface_name' in rule_conf['inbound_interface']:
iiface = rule_conf['inbound_interface']['interface_name']
if 'name' in rule_conf['inbound_interface']:
iiface = rule_conf['inbound_interface']['name']
if iiface[0] == '!':
operator = '!='
iiface = iiface[1:]
output.append(f'iifname {operator} {{{iiface}}}')
else:
iiface = rule_conf['inbound_interface']['interface_group']
iiface = rule_conf['inbound_interface']['group']
if iiface[0] == '!':
operator = '!='
iiface = iiface[1:]
output.append(f'iifname {operator} @I_{iiface}')

if 'outbound_interface' in rule_conf:
operator = ''
if 'interface_name' in rule_conf['outbound_interface']:
oiface = rule_conf['outbound_interface']['interface_name']
if 'name' in rule_conf['outbound_interface']:
oiface = rule_conf['outbound_interface']['name']
if oiface[0] == '!':
operator = '!='
oiface = oiface[1:]
output.append(f'oifname {operator} {{{oiface}}}')
else:
oiface = rule_conf['outbound_interface']['interface_group']
oiface = rule_conf['outbound_interface']['group']
if oiface[0] == '!':
operator = '!='
oiface = oiface[1:]
Expand Down
12 changes: 6 additions & 6 deletions smoketest/scripts/cli/test_firewall.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def test_groups(self):
self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'action', 'accept'])
self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'source', 'group', 'domain-group', 'smoketest_domain'])
self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '4', 'action', 'accept'])
self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '4', 'outbound-interface', 'interface-group', '!smoketest_interface'])
self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '4', 'outbound-interface', 'group', '!smoketest_interface'])

self.cli_commit()

Expand Down Expand Up @@ -244,7 +244,7 @@ def test_ipv4_basic_rules(self):
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '5', 'tcp', 'flags', 'syn'])
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '5', 'tcp', 'mss', mss_range])
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '5', 'packet-type', 'broadcast'])
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '5', 'inbound-interface', 'interface-name', interface_wc])
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '5', 'inbound-interface', 'name', interface_wc])
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '6', 'action', 'return'])
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '6', 'protocol', 'gre'])
self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '6', 'connection-mark', conn_mark])
Expand All @@ -253,7 +253,7 @@ def test_ipv4_basic_rules(self):
self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'enable-default-log'])
self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '5', 'action', 'drop'])
self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '5', 'protocol', 'gre'])
self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '5', 'outbound-interface', 'interface-name', interface_inv])
self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '5', 'outbound-interface', 'name', interface_inv])
self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '6', 'action', 'return'])
self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '6', 'protocol', 'icmp'])
self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '6', 'connection-mark', conn_mark])
Expand Down Expand Up @@ -394,18 +394,18 @@ def test_ipv6_basic_rules(self):
self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'action', 'reject'])
self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'protocol', 'tcp_udp'])
self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'destination', 'port', '8888'])
self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'inbound-interface', 'interface-name', interface])
self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'inbound-interface', 'name', interface])

self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'default-action', 'drop'])
self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'enable-default-log'])
self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '3', 'action', 'return'])
self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '3', 'protocol', 'gre'])
self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '3', 'outbound-interface', 'interface-name', interface])
self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '3', 'outbound-interface', 'name', interface])

self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '3', 'action', 'accept'])
self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '3', 'protocol', 'udp'])
self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '3', 'source', 'address', '2002::1:2'])
self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '3', 'inbound-interface', 'interface-name', interface])
self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '3', 'inbound-interface', 'name', interface])

self.cli_commit()

Expand Down
22 changes: 11 additions & 11 deletions smoketest/scripts/cli/test_nat.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ def test_snat(self):
# or configured destination address for NAT
if int(rule) < 200:
self.cli_set(src_path + ['rule', rule, 'source', 'address', network])
self.cli_set(src_path + ['rule', rule, 'outbound-interface', 'interface-name', outbound_iface_100])
self.cli_set(src_path + ['rule', rule, 'outbound-interface', 'name', outbound_iface_100])
self.cli_set(src_path + ['rule', rule, 'translation', 'address', 'masquerade'])
nftables_search.append([f'saddr {network}', f'oifname "{outbound_iface_100}"', 'masquerade'])
else:
self.cli_set(src_path + ['rule', rule, 'destination', 'address', network])
self.cli_set(src_path + ['rule', rule, 'outbound-interface', 'interface-name', outbound_iface_200])
self.cli_set(src_path + ['rule', rule, 'outbound-interface', 'name', outbound_iface_200])
self.cli_set(src_path + ['rule', rule, 'exclude'])
nftables_search.append([f'daddr {network}', f'oifname "{outbound_iface_200}"', 'return'])

Expand All @@ -106,7 +106,7 @@ def test_snat_groups(self):
self.cli_set(['firewall', 'group', 'interface-group', interface_group, 'interface', interface_group_member])

self.cli_set(src_path + ['rule', rule, 'source', 'group', 'address-group', address_group])
self.cli_set(src_path + ['rule', rule, 'outbound-interface', 'interface-group', interface_group])
self.cli_set(src_path + ['rule', rule, 'outbound-interface', 'group', interface_group])
self.cli_set(src_path + ['rule', rule, 'translation', 'address', 'masquerade'])

self.cli_commit()
Expand Down Expand Up @@ -138,12 +138,12 @@ def test_dnat(self):
rule_search = [f'dnat to 192.0.2.1:{port}']
if int(rule) < 200:
self.cli_set(dst_path + ['rule', rule, 'protocol', inbound_proto_100])
self.cli_set(dst_path + ['rule', rule, 'inbound-interface', 'interface-name', inbound_iface_100])
self.cli_set(dst_path + ['rule', rule, 'inbound-interface', 'name', inbound_iface_100])
rule_search.append(f'{inbound_proto_100} sport {port}')
rule_search.append(f'iifname "{inbound_iface_100}"')
else:
self.cli_set(dst_path + ['rule', rule, 'protocol', inbound_proto_200])
self.cli_set(dst_path + ['rule', rule, 'inbound-interface', 'interface-name', inbound_iface_200])
self.cli_set(dst_path + ['rule', rule, 'inbound-interface', 'name', inbound_iface_200])
rule_search.append(f'iifname "{inbound_iface_200}"')

nftables_search.append(rule_search)
Expand All @@ -169,7 +169,7 @@ def test_dnat_negated_addresses(self):
rule = '1000'
self.cli_set(dst_path + ['rule', rule, 'destination', 'address', '!192.0.2.1'])
self.cli_set(dst_path + ['rule', rule, 'destination', 'port', '53'])
self.cli_set(dst_path + ['rule', rule, 'inbound-interface', 'interface-name', 'eth0'])
self.cli_set(dst_path + ['rule', rule, 'inbound-interface', 'name', 'eth0'])
self.cli_set(dst_path + ['rule', rule, 'protocol', 'tcp_udp'])
self.cli_set(dst_path + ['rule', rule, 'source', 'address', '!192.0.2.1'])
self.cli_set(dst_path + ['rule', rule, 'translation', 'address', '192.0.2.1'])
Expand All @@ -188,7 +188,7 @@ def test_nat_no_rules(self):
self.cli_commit()

def test_dnat_without_translation_address(self):
self.cli_set(dst_path + ['rule', '1', 'inbound-interface', 'interface-name', 'eth1'])
self.cli_set(dst_path + ['rule', '1', 'inbound-interface', 'name', 'eth1'])
self.cli_set(dst_path + ['rule', '1', 'destination', 'port', '443'])
self.cli_set(dst_path + ['rule', '1', 'protocol', 'tcp'])
self.cli_set(dst_path + ['rule', '1', 'packet-type', 'host'])
Expand Down Expand Up @@ -238,13 +238,13 @@ def test_dnat_redirect(self):
self.cli_set(dst_path + ['rule', '10', 'destination', 'address', dst_addr_1])
self.cli_set(dst_path + ['rule', '10', 'destination', 'port', dest_port])
self.cli_set(dst_path + ['rule', '10', 'protocol', protocol])
self.cli_set(dst_path + ['rule', '10', 'inbound-interface', 'interface-name', ifname])
self.cli_set(dst_path + ['rule', '10', 'inbound-interface', 'name', ifname])
self.cli_set(dst_path + ['rule', '10', 'translation', 'redirect', 'port', redirected_port])

self.cli_set(dst_path + ['rule', '20', 'destination', 'address', dst_addr_1])
self.cli_set(dst_path + ['rule', '20', 'destination', 'port', dest_port])
self.cli_set(dst_path + ['rule', '20', 'protocol', protocol])
self.cli_set(dst_path + ['rule', '20', 'inbound-interface', 'interface-name', ifname])
self.cli_set(dst_path + ['rule', '20', 'inbound-interface', 'name', ifname])
self.cli_set(dst_path + ['rule', '20', 'translation', 'redirect'])

self.cli_commit()
Expand All @@ -268,7 +268,7 @@ def test_nat_balance(self):
weight_4 = '65'
dst_port = '443'

self.cli_set(dst_path + ['rule', '1', 'inbound-interface', 'interface-name', ifname])
self.cli_set(dst_path + ['rule', '1', 'inbound-interface', 'name', ifname])
self.cli_set(dst_path + ['rule', '1', 'protocol', 'tcp'])
self.cli_set(dst_path + ['rule', '1', 'destination', 'port', dst_port])
self.cli_set(dst_path + ['rule', '1', 'load-balance', 'hash', 'source-address'])
Expand All @@ -278,7 +278,7 @@ def test_nat_balance(self):
self.cli_set(dst_path + ['rule', '1', 'load-balance', 'backend', member_1, 'weight', weight_1])
self.cli_set(dst_path + ['rule', '1', 'load-balance', 'backend', member_2, 'weight', weight_2])

self.cli_set(src_path + ['rule', '1', 'outbound-interface', 'interface-name', ifname])
self.cli_set(src_path + ['rule', '1', 'outbound-interface', 'name', ifname])
self.cli_set(src_path + ['rule', '1', 'load-balance', 'hash', 'random'])
self.cli_set(src_path + ['rule', '1', 'load-balance', 'backend', member_3, 'weight', weight_3])
self.cli_set(src_path + ['rule', '1', 'load-balance', 'backend', member_4, 'weight', weight_4])
Expand Down
Loading

0 comments on commit 2b38b45

Please sign in to comment.