-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
T7181: VPP add initial source NAT implentation
Add initial source NAT implementation ``` set vpp nat source inbound-interface 'eth2' set vpp nat source outbound-interface 'eth1' set vpp nat source translation-pool '192.0.2.1-192.0.2.2' ``` Add initial simple implementation of the source NAT In the future, we'll extend it to the rules if it is possible to do via VPP API
- Loading branch information
1 parent
752b400
commit c4f5e7e
Showing
7 changed files
with
261 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from .nat44 import Nat44 | ||
|
||
__all__ = ['Nat44'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
# | ||
# Copyright (C) 2025 VyOS Inc. | ||
# | ||
# This program is free software; you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation; either version 2 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License along | ||
# with this program; if not, write to the Free Software Foundation, Inc., | ||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
|
||
from vyos.vpp import VPPControl | ||
|
||
|
||
class Nat44: | ||
def __init__( | ||
self, | ||
interface_in: str, | ||
interface_out: str, | ||
translation_pool: str, | ||
): | ||
self.interface_in = interface_in | ||
self.interface_out = interface_out | ||
self.translation_pool = translation_pool | ||
self.vpp = VPPControl() | ||
|
||
def enable_nat44_ed(self): | ||
"""Enable NAT44 endpoint dependent plugin | ||
Example: | ||
from vyos.vpp.nat import Nat44 | ||
nat44 = Nat44() | ||
nat44.enable_nat44_ed() | ||
https://github.com/FDio/vpp/blob/stable/2410/src/plugins/nat/nat44-ed/nat44_ed.api | ||
""" | ||
self.vpp.api.nat44_ed_plugin_enable_disable(enable=True) | ||
|
||
def enable_nat44_ei(self): | ||
"""Enable NAT44 endpoint independent plugin | ||
Example: | ||
from vyos.vpp.nat import Nat44 | ||
nat44 = Nat44() | ||
nat44.enable_nat44_ei() | ||
""" | ||
self.vpp.api.nat44_ei_plugin_enable_disable(enable=True) | ||
|
||
def add_nat44_out_interface(self): | ||
"""Add NAT44 output interface | ||
Example: | ||
from vyos.vpp.nat import Nat44 | ||
nat44 = Nat44('eth0') | ||
nat44.add_nat44_out_interface() | ||
""" | ||
self.vpp.api.nat44_ed_add_del_output_interface( | ||
sw_if_index=self.vpp.get_sw_if_index(self.interface_out), | ||
is_add=True, | ||
) | ||
|
||
def delete_nat44_out_interface(self): | ||
"""Delete NAT44 output interface""" | ||
self.vpp.api.nat44_ed_add_del_output_interface( | ||
sw_if_index=self.vpp.get_sw_if_index(self.interface_out), | ||
is_add=False, | ||
) | ||
|
||
def add_nat44_address_range(self): | ||
"""Add NAT44 address range""" | ||
self.vpp.api.nat44_add_del_address_range( | ||
first_ip_address=self.translation_pool.split('-')[0], | ||
last_ip_address=self.translation_pool.split('-')[1], | ||
is_add=True, | ||
) | ||
|
||
def delete_nat44_address_range(self): | ||
"""Delete NAT44 address range""" | ||
self.vpp.api.nat44_add_del_address_range( | ||
first_ip_address=self.translation_pool.split('-')[0], | ||
last_ip_address=self.translation_pool.split('-')[1], | ||
is_add=False, | ||
) | ||
|
||
def enable_ipfix(self): | ||
"""Enable NAT44 IPFIX logging""" | ||
self.vpp.api.nat44_ei_ipfix_enable_disable(enable=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#!/usr/bin/env python3 | ||
# | ||
# Copyright (C) 2025 VyOS Inc. | ||
# | ||
# This program is free software; you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation; either version 2 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License along | ||
# with this program; if not, write to the Free Software Foundation, Inc., | ||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
|
||
from vyos.config import Config | ||
from vyos import ConfigError | ||
from vyos.vpp.nat import Nat44 | ||
|
||
|
||
def get_config(config=None) -> dict: | ||
if config: | ||
conf = config | ||
else: | ||
conf = Config() | ||
|
||
base = ['vpp', 'nat', 'source'] | ||
|
||
# Get config_dict with default values | ||
config = conf.get_config_dict( | ||
base, | ||
key_mangling=('-', '_'), | ||
get_first_key=True, | ||
no_tag_node_value_mangle=True, | ||
with_defaults=True, | ||
with_recursive_defaults=True, | ||
) | ||
|
||
# Get effective config as we need full dicitonary per interface delete | ||
effective_config = conf.get_config_dict( | ||
base, | ||
key_mangling=('-', '_'), | ||
effective=True, | ||
get_first_key=True, | ||
no_tag_node_value_mangle=True, | ||
) | ||
|
||
if not config: | ||
config['remove'] = True | ||
|
||
if effective_config: | ||
config.update({'effective': effective_config}) | ||
|
||
return config | ||
|
||
|
||
def verify(config): | ||
if 'remove' in config: | ||
return None | ||
|
||
required_keys = {'inbound_interface', 'outbound_interface', 'translation_pool'} | ||
if not all(key in config for key in required_keys): | ||
missing_keys = required_keys - set(config.keys()) | ||
raise ConfigError( | ||
f"Required options are missing: {', '.join(missing_keys).replace('_', '-')}" | ||
) | ||
|
||
|
||
def generate(config): | ||
pass | ||
|
||
|
||
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') | ||
translation_pool = remove_config.get('translation_pool') | ||
|
||
n = Nat44(interface_in, interface_out, translation_pool) | ||
n.delete_nat44_out_interface() | ||
n.delete_nat44_out_interface() | ||
|
||
if 'remove' in config: | ||
return None | ||
|
||
# Add NAT64 | ||
interface_in = config.get('inbound_interface') | ||
interface_out = config.get('outbound_interface') | ||
translation_pool = config.get('translation_pool') | ||
|
||
n = Nat44(interface_in, interface_out, translation_pool) | ||
n.enable_nat44_ed() | ||
n.add_nat44_out_interface() | ||
n.add_nat44_address_range() | ||
|
||
|
||
if __name__ == '__main__': | ||
try: | ||
c = get_config() | ||
verify(c) | ||
generate(c) | ||
apply(c) | ||
except ConfigError as e: | ||
print(e) | ||
exit(1) |