diff options
| author | Nataliia S. <81954790+natali-rs1985@users.noreply.github.com> | 2025-04-08 17:15:42 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-08 15:15:42 +0100 |
| commit | 4d32bcddda72c1df944470f06b75908b2dc31667 (patch) | |
| tree | 80fcf34ef72675d2ee5b2407b350f301a1382f81 | |
| parent | 07a3b0f5ae87a2ab400390c9fa0ca632d7815e15 (diff) | |
| download | vyos-1x-4d32bcddda72c1df944470f06b75908b2dc31667.tar.gz vyos-1x-4d32bcddda72c1df944470f06b75908b2dc31667.zip | |
T7315: Change CLI fot VPP NAT (#25)
New CLI
```
set vpp nat44 static rule 10 outside-interface 'eth0'
set vpp nat44 static rule 10 inside-interface 'eth1'
set vpp nat44 static rule 10 external address 192.168.122.10
set vpp nat44 static rule 10 external port 6545 # optional
set vpp nat44 static rule 10 protocol tcp|udp|icmp|all # optional, defaults to "all"
set vpp nat44 static rule 10 local address 100.64.0.10
set vpp nat44 static rule 10 local port 64010 # optional
```
| -rw-r--r-- | interface-definitions/vpp.xml.in | 25 | ||||
| -rw-r--r-- | python/vyos/vpp/nat/nat44.py | 32 | ||||
| -rw-r--r-- | src/conf_mode/vpp_nat_source.py | 10 | ||||
| -rw-r--r-- | src/conf_mode/vpp_nat_static.py | 63 | ||||
| -rw-r--r-- | src/op_mode/show_vpp_nat44.py | 27 |
5 files changed, 61 insertions, 96 deletions
diff --git a/interface-definitions/vpp.xml.in b/interface-definitions/vpp.xml.in index 66a38f546..263f9cb91 100644 --- a/interface-definitions/vpp.xml.in +++ b/interface-definitions/vpp.xml.in @@ -853,18 +853,18 @@ <priority>320</priority> </properties> <children> - <leafNode name="inbound-interface"> + <leafNode name="inside-interface"> <properties> - <help>Inbound interface of NAT traffic</help> + <help>NAT inside interface</help> <completionHelp> <list>any</list> <script>${vyos_completion_dir}/list_interfaces</script> </completionHelp> </properties> </leafNode> - <leafNode name="outbound-interface"> + <leafNode name="outside-interface"> <properties> - <help>Outbound interface of NAT traffic</help> + <help>NAT outside interface</help> <completionHelp> <list>any</list> <script>${vyos_completion_dir}/list_interfaces</script> @@ -920,7 +920,7 @@ </valueHelp> </properties> <children> - <node name="destination"> + <node name="external"> <properties> <help>NAT external parameters</help> </properties> @@ -968,27 +968,25 @@ </properties> <defaultValue>all</defaultValue> </leafNode> - <leafNode name="outbound-interface"> + <leafNode name="outside-interface"> <properties> - <help>Outbound interface of NAT traffic</help> + <help>NAT outside interface</help> <completionHelp> - <list>any</list> <script>${vyos_completion_dir}/list_interfaces</script> </completionHelp> </properties> </leafNode> - <leafNode name="inbound-interface"> + <leafNode name="inside-interface"> <properties> - <help>Inbound interface of NAT traffic</help> + <help>NAT inside interface</help> <completionHelp> - <list>any</list> <script>${vyos_completion_dir}/list_interfaces</script> </completionHelp> </properties> </leafNode> - <node name="translation"> + <node name="local"> <properties> - <help>NAT internal parameters</help> + <help>NAT local parameters</help> </properties> <children> <leafNode name="address"> @@ -1006,6 +1004,7 @@ #include <include/port-number.xml.i> </children> </node> + #include <include/generic-description.xml.i> </children> </tagNode> </children> diff --git a/python/vyos/vpp/nat/nat44.py b/python/vyos/vpp/nat/nat44.py index 985e5a583..97c4518e6 100644 --- a/python/vyos/vpp/nat/nat44.py +++ b/python/vyos/vpp/nat/nat44.py @@ -151,31 +151,24 @@ class Nat44Static(Nat44): def __init__(self): self.vpp = VPPControl() - def add_inbound_interface(self, interface_in): + def add_inside_interface(self, interface_in): self.interface_in = interface_in self.add_nat44_interface_inside() - def delete_inbound_interface(self, interface_in): + def delete_inside_interface(self, interface_in): self.interface_in = interface_in self.delete_nat44_interface_inside() - def add_outbound_interface(self, interface_out): + def add_outside_interface(self, interface_out): self.interface_out = interface_out self.add_nat44_interface_outside() - def delete_outbound_interface(self, interface_out): + def delete_outside_interface(self, interface_out): self.interface_out = interface_out self.delete_nat44_interface_outside() def add_nat44_static_mapping( - self, - iface_out, - local_ip, - external_ip, - local_port, - external_port, - protocol, - use_iface, + self, local_ip, external_ip, local_port, external_port, protocol ): """Add NAT44 static mapping""" self.vpp.api.nat44_add_del_static_mapping_v2( @@ -185,21 +178,11 @@ class Nat44Static(Nat44): local_port=local_port, external_port=external_port, flags=0x08 if not (protocol or local_port) else 0x00, - external_sw_if_index=( - self.vpp.get_sw_if_index(iface_out) if use_iface else 0xFFFFFFFF - ), is_add=True, ) def delete_nat44_static_mapping( - self, - iface_out, - local_ip, - external_ip, - local_port, - external_port, - protocol, - use_iface, + self, local_ip, external_ip, local_port, external_port, protocol ): """Delete NAT44 static mapping""" self.vpp.api.nat44_add_del_static_mapping_v2( @@ -209,8 +192,5 @@ class Nat44Static(Nat44): local_port=local_port, external_port=external_port, flags=0x08 if not (protocol or local_port) else 0x00, - external_sw_if_index=( - self.vpp.get_sw_if_index(iface_out) if use_iface else 0xFFFFFFFF - ), is_add=False, ) diff --git a/src/conf_mode/vpp_nat_source.py b/src/conf_mode/vpp_nat_source.py index 2e1884c3a..40b16a3c8 100644 --- a/src/conf_mode/vpp_nat_source.py +++ b/src/conf_mode/vpp_nat_source.py @@ -61,7 +61,7 @@ def verify(config): if 'remove' in config: return None - required_keys = {'inbound_interface', 'outbound_interface'} + required_keys = {'inside_interface', 'outside_interface'} if not all(key in config for key in required_keys): missing_keys = required_keys - set(config.keys()) raise ConfigError( @@ -83,8 +83,8 @@ def apply(config): # Delete NAT source if 'effective' in config: remove_config = config.get('effective') - interface_in = remove_config.get('inbound_interface') - interface_out = remove_config.get('outbound_interface') + interface_in = remove_config.get('inside_interface') + interface_out = remove_config.get('outside_interface') translation_address = remove_config.get('translation', {}).get('address') n = Nat44(interface_in, interface_out, translation_address) @@ -96,8 +96,8 @@ def apply(config): return None # Add NAT44 - interface_in = config.get('inbound_interface') - interface_out = config.get('outbound_interface') + interface_in = config.get('inside_interface') + interface_out = config.get('outside_interface') translation_address = config.get('translation', {}).get('address') n = Nat44(interface_in, interface_out, translation_address) diff --git a/src/conf_mode/vpp_nat_static.py b/src/conf_mode/vpp_nat_static.py index 50384a00b..b890ea150 100644 --- a/src/conf_mode/vpp_nat_static.py +++ b/src/conf_mode/vpp_nat_static.py @@ -86,12 +86,12 @@ def get_config(config=None) -> dict: expand_nodes=Diff.DELETE | Diff.ADD, ) - if 'inbound_interface' in tmp: - new, old = diff.get_value_diff(base_rule + ['inbound-interface']) + if 'inside_interface' in tmp: + new, old = diff.get_value_diff(base_rule + ['inside-interface']) in_iface_add.append(new) if new else None in_iface_del.append(old) if old else None - if 'outbound_interface' in tmp: - new, old = diff.get_value_diff(base_rule + ['outbound-interface']) + if 'outside_interface' in tmp: + new, old = diff.get_value_diff(base_rule + ['outside-interface']) out_iface_add.append(new) if new else None out_iface_del.append(old) if old else None @@ -120,7 +120,7 @@ def verify(config): if 'remove' in config: return None - required_keys = {'inbound_interface', 'outbound_interface'} + required_keys = {'inside_interface', 'outside_interface'} for rule, rule_config in config['rule'].items(): missing_keys = required_keys - rule_config.keys() if missing_keys: @@ -128,13 +128,16 @@ def verify(config): f"Required options are missing: {', '.join(missing_keys).replace('_', '-')} in rule {rule}" ) - if not rule_config.get('translation', {}).get('address'): - raise ConfigError(f'Translation requires address in rule {rule}') + if not rule_config.get('local', {}).get('address'): + raise ConfigError(f'Local settings require address in rule {rule}') - has_dest_port = 'port' in rule_config.get('destination', {}) - has_trans_port = 'port' in rule_config.get('translation', {}) + if not rule_config.get('external', {}).get('address'): + raise ConfigError(f'External settings require address in rule {rule}') - if not has_trans_port == has_dest_port: + has_local_port = 'port' in rule_config.get('local', {}) + has_external_port = 'port' in rule_config.get('external', {}) + + if not has_external_port == has_local_port: raise ConfigError( 'Source and destination ports must either both be specified, or neither must be specified' ) @@ -147,28 +150,22 @@ def generate(config): def apply(config): n = Nat44Static() - # Delete inbound interfaces + # Delete inside interfaces for interface in config['in_iface_del']: - n.delete_inbound_interface(interface) - # Delete outbound interfaces + n.delete_inside_interface(interface) + # Delete outside interfaces for interface in config['out_iface_del']: - n.delete_outbound_interface(interface) + n.delete_outside_interface(interface) # Delete NAT static mapping rules for rule in config['changed_rules']: if rule in config.get('effective', {}).get('rule', {}): rule_config = config['effective']['rule'][rule] n.delete_nat44_static_mapping( - iface_out=rule_config.get('outbound_interface'), - local_ip=rule_config.get('translation').get('address'), - external_ip=rule_config.get('destination', {}).get('address', ''), - local_port=int(rule_config.get('translation', {}).get('port', 0)), - external_port=int(rule_config.get('destination', {}).get('port', 0)), + local_ip=rule_config.get('local').get('address'), + external_ip=rule_config.get('external', {}).get('address', ''), + local_port=int(rule_config.get('local', {}).get('port', 0)), + external_port=int(rule_config.get('external', {}).get('port', 0)), protocol=protocol_map[rule_config.get('protocol', 'all')], - use_iface=( - True - if not rule_config.get('destination', {}).get('address') - else False - ), ) if 'remove' in config: @@ -177,24 +174,18 @@ def apply(config): # Add NAT44 static mapping rules n.enable_nat44_ed() for interface in config['in_iface_add']: - n.add_inbound_interface(interface) + n.add_inside_interface(interface) for interface in config['out_iface_add']: - n.add_outbound_interface(interface) + n.add_outside_interface(interface) for rule in config['changed_rules']: if rule in config.get('rule', {}): rule_config = config['rule'][rule] n.add_nat44_static_mapping( - iface_out=rule_config.get('outbound_interface'), - local_ip=rule_config.get('translation').get('address'), - external_ip=rule_config.get('destination', {}).get('address', ''), - local_port=int(rule_config.get('translation', {}).get('port', 0)), - external_port=int(rule_config.get('destination', {}).get('port', 0)), + local_ip=rule_config.get('local').get('address'), + external_ip=rule_config.get('external', {}).get('address', ''), + local_port=int(rule_config.get('local', {}).get('port', 0)), + external_port=int(rule_config.get('external', {}).get('port', 0)), protocol=protocol_map[rule_config.get('protocol', 'all')], - use_iface=( - True - if not rule_config.get('destination', {}).get('address') - else False - ), ) diff --git a/src/op_mode/show_vpp_nat44.py b/src/op_mode/show_vpp_nat44.py index 1aae8164e..fcf28f76a 100644 --- a/src/op_mode/show_vpp_nat44.py +++ b/src/op_mode/show_vpp_nat44.py @@ -116,27 +116,22 @@ def _get_raw_output_static_rules(vpp_api): return rules_list -def _get_formatted_output_rules(vpp, rules_list): +def _get_formatted_output_rules(rules_list): data_entries = [] for rule in rules_list: - dest_address = rule.get('external_ip_address') - dest_port = rule.get('external_port') or '' - trans_address = rule.get('local_ip_address') - trans_port = rule.get('local_port') or '' + external_address = rule.get('external_ip_address') + external_port = rule.get('external_port') or '' + local_address = rule.get('local_ip_address') + local_port = rule.get('local_port') or '' protocol = protocol_map[rule.get('protocol', 0)] - dest_sh_if_index = rule.get('external_sw_if_index') - vpp_if_name = vpp.get_interface_name(dest_sh_if_index) - if vpp_if_name: - dest_address = vpp_if_name - - values = [dest_address, dest_port, trans_address, trans_port, protocol] + values = [external_address, external_port, local_address, local_port, protocol] data_entries.append(values) headers = [ - 'Des_address/interface', - 'Dest_port', - 'Trans_address', - 'Trans_port', + 'External address', + 'External port', + 'Local address', + 'Local port', 'Protocol', ] out = sorted(data_entries, key=lambda x: x[2]) @@ -170,7 +165,7 @@ def show_static(raw: bool): return rules_list else: - return _get_formatted_output_rules(vpp, rules_list) + return _get_formatted_output_rules(rules_list) if __name__ == '__main__': |
