From 720e816a75bbd72cba09623eb0ef1521f8e2bf0f Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni <47657796+AkhileshSamineni@users.noreply.github.com> Date: Fri, 11 Jun 2021 00:12:13 +0530 Subject: [PATCH] [Yang] SONiC Yang model support for NAT (#7051) This change has SONiC Yang model support for NAT - Created SONiC Yang model for NAT - Tables: STATIC_NAPT, STATIC_NAT, NAT_GLOBAL, NAT_POOL, NAT_BINDINGS. How I did it Defined Yang models for NAT based on Guideline doc: https://github.com/Azure/SONiC/blob/master/doc/mgmt/SONiC_YANG_Model_Guidelines.md and https://github.com/Azure/sonic-utilities/blob/master/doc/Command-Reference.md How to verify it Added test cases to verify it. --- src/sonic-yang-models/setup.py | 1 + .../tests/files/sample_config_db.json | 48 ++- .../yang_model_tests/tests/interface.json | 7 + .../yang_model_tests/tests/loopback.json | 7 + .../tests/yang_model_tests/tests/nat.json | 100 +++++ .../yang_model_tests/tests/portchannel.json | 7 + .../tests/yang_model_tests/tests/vlan.json | 7 + .../tests_config/interface.json | 72 ++++ .../tests_config/loopback.json | 40 ++ .../yang_model_tests/tests_config/nat.json | 391 ++++++++++++++++++ .../tests_config/portchannel.json | 94 +++++ .../yang_model_tests/tests_config/vlan.json | 104 +++++ .../yang-models/sonic-interface.yang | 11 + .../yang-models/sonic-loopback-interface.yang | 11 + .../yang-models/sonic-nat.yang | 294 +++++++++++++ .../yang-models/sonic-portchannel.yang | 11 + .../yang-models/sonic-types.yang | 15 + .../yang-models/sonic-vlan.yang | 11 + 18 files changed, 1227 insertions(+), 4 deletions(-) create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests/nat.json create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/nat.json create mode 100644 src/sonic-yang-models/yang-models/sonic-nat.yang diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index d511b9898a5a..4e265ceef90a 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -50,6 +50,7 @@ './yang-models/sonic-flex_counter.yang', './yang-models/sonic-interface.yang', './yang-models/sonic-loopback-interface.yang', + './yang-models/sonic-nat.yang', './yang-models/sonic-port.yang', './yang-models/sonic-portchannel.yang', './yang-models/sonic-types.yang', diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index ce18c538fee5..a114a61045f0 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -27,7 +27,9 @@ } }, "PORTCHANNEL_INTERFACE": { - "PortChannel0003": {}, + "PortChannel0003": { + "nat_zone": "1" + }, "PortChannel0004": {"vrf_name": "Vrf_blue"} }, "PORTCHANNEL_MEMBER": { @@ -35,7 +37,9 @@ "PortChannel0004|Ethernet2": {} }, "VLAN_INTERFACE": { - "Vlan111": {}, + "Vlan111": { + "nat_zone": "0" + }, "Vlan777": {}, "Vlan111|2a04:5555:45:6709::1/64": { "scope": "global", @@ -587,7 +591,9 @@ "Ethernet112": {}, "Ethernet14": {}, "Ethernet16": {}, - "Ethernet18": {}, + "Ethernet18": { + "nat_zone": "1" + }, "Ethernet112|2a04:5555:40:a709::2/126": { "scope": "global", "family": "IPv6" @@ -672,7 +678,9 @@ } }, "LOOPBACK_INTERFACE": { - "Loopback0": {}, + "Loopback0": { + "nat_zone": "2" + }, "Loopback0|2a04:5555:40:4::4e9/128": { "scope": "global", "family": "IPv6" @@ -740,6 +748,38 @@ "nexthop_group_threshold_type": "percentage", "polling_interval": "0" } + }, + "NAT_BINDINGS": { + "bind1": { + "nat_pool": "pool1", + "nat_type": "snat", + "twice_nat_id": "1" + } + }, + "NAT_GLOBAL": { + "Values": { + "admin_mode": "enabled", + "nat_tcp_timeout": "86400", + "nat_timeout": "600", + "nat_udp_timeout": "300" + } + }, + "NAT_POOL": { + "pool1": { + "nat_ip": "125.56.90.50-125.56.90.100", + "nat_port": "50-100" + } + }, + "STATIC_NAPT": { + "125.56.90.10|UDP|100": { + "local_ip": "12.12.0.2", + "local_port": "251" + } + }, + "STATIC_NAT": { + "125.56.90.8": { + "local_ip": "12.12.0.2" + } } }, diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/interface.json b/src/sonic-yang-models/tests/yang_model_tests/tests/interface.json index 246298bbc8f2..1c93238c1889 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests/interface.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/interface.json @@ -10,5 +10,12 @@ }, "INTERFACE_IPPREFIX_PORT_MUST_CONDITION_TRUE": { "desc": "Interface Ip-prefix port-name must condition pass." + }, + "INTERFACE_WRONG_NAT_ZONE_RANGE": { + "desc": "Configure wrong value for nat zone.", + "eStr" : "Invalid nat zone for the interface." + }, + "INTERFACE_VALID_NAT_ZONE_RANGE": { + "desc": "Configure valid value for nat zone." } } diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/loopback.json b/src/sonic-yang-models/tests/yang_model_tests/tests/loopback.json index a0e9b5b5edd0..a4e4f9b6f2ca 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests/loopback.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/loopback.json @@ -2,5 +2,12 @@ "LOOPBACK_IPPREFIX_PORT_MUST_CONDITION_FALSE": { "desc": "Loopback Ip-prefix port-name must condition failure.", "eStrKey" : "Must" + }, + "LOOPBACK_INTERFACE_WRONG_NAT_ZONE_RANGE": { + "desc": "Configure wrong value for nat zone.", + "eStr" : "Invalid nat zone for the loopback interface." + }, + "LOOPBACK_INTERFACE_VALID_NAT_ZONE_RANGE": { + "desc": "Configure valid value for nat zone." } } diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/nat.json b/src/sonic-yang-models/tests/yang_model_tests/tests/nat.json new file mode 100644 index 000000000000..2d69dacb7379 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/nat.json @@ -0,0 +1,100 @@ +{ + "STATIC_NAPT_ENTRY_WITH_VALID_VALUES": { + "desc": "Configuring the Static NAPT table with valid values." + }, + "STATIC_NAPT_ENTRY_WRONG_GLOBAL_IP": { + "desc": "Configuring a wrong global ip in Static NAPT table.", + "eStrKey" : "Pattern" + }, + "STATIC_NAPT_ENTRY_WRONG_IP_PROTOCOL": { + "desc": "Configuring a wrong ip protocol in Static NAPT table.", + "eStrKey": "InvalidValue", + "eStr": ["ip_protocol"] + }, + "STATIC_NAPT_ENTRY_WRONG_GLOBAL_L4_PORT": { + "desc": "Configuring a wrong global l4 port in Static NAPT table.", + "eStrKey": "InvalidValue", + "eStr": ["global_l4_port"] + }, + "STATIC_NAPT_ENTRY_WITHOUT_LOCAL_IP": { + "desc": "Configuring a Static NAPT table without local ip.", + "eStrKey" : "Mandatory" + }, + "STATIC_NAPT_ENTRY_WITHOUT_LOCAL_PORT": { + "desc": "Configuring a Static NAPT table without local port.", + "eStrKey" : "Mandatory" + }, + "STATIC_NAPT_ENTRY_INVALID_TWICE_NAT_ID": { + "desc": "Configuring a invalid twice nat id in Static NAPT table.", + "eStrKey": "InvalidValue" + }, + "STATIC_NAT_ENTRY_WITH_VALID_VALUES": { + "desc": "Configuring the Static NAT table with valid values." + }, + "STATIC_NAT_ENTRY_WRONG_GLOBAL_IP": { + "desc": "Configuring a wrong global ip in Static NAT table.", + "eStrKey" : "Pattern" + }, + "STATIC_NAT_ENTRY_WITHOUT_LOCAL_IP": { + "desc": "Configuring a Static NAT table without local ip.", + "eStrKey" : "Mandatory" + }, + "STATIC_NAT_ENTRY_INVALID_TWICE_NAT_ID": { + "desc": "Configuring a invalid twice nat id in Static NAT table.", + "eStrKey": "InvalidValue" + }, + "NAT_GLOBAL_WITH_VALID_VALUES": { + "desc": "Configuring a NAT Global table with valid values." + }, + "NAT_GLOBAL_WITH_INVALID_UDP_TIMEOUT": { + "desc": "Configuring a NAT Global table with a invalid udp timeout.", + "eStr": "Invalid NAT UDP Timeout, valid range 120 sec to 600 sec." + }, + "NAT_GLOBAL_WITH_INVALID_TIMEOUT": { + "desc": "Configuring a NAT Global table with a invalid timeout.", + "eStr": "Invalid NAT Timeout, valid range 300 sec to 432000 sec." + }, + "NAT_GLOBAL_WITH_INVALID_TCP_TIMEOUT": { + "desc": "Configuring a NAT Global table with a invalid tcp timeout.", + "eStr": "Invalid NAT TCP Timeout, valid range 300 sec to 432000 sec." + }, + "NAT_POOL_WITH_VALID_VALUES": { + "desc": "Configuring a NAT Pool table with valid values." + }, + "NAT_POOL_WITH_INVALID_POOL_NAME": { + "desc": "Configuring a invalid pool name in NAT Pool table.", + "eStr": "Invalid length for the pool name." + }, + "NAT_POOL_WITHOUT_NAT_IP": { + "desc": "Configuring a NAT Pool table without NAT ip.", + "eStrKey" : "Mandatory" + }, + "NAT_POOL_WITH_INVALID_NAT_IP": { + "desc": "Configuring a invalid nat ip in NAT Pool table.", + "eStrKey": "InvalidValue", + "eStr": ["nat_ip"] + }, + "NAT_POOL_WITH_INVALID_NAT_PORT": { + "desc": "Configuring a invalid nat port in NAT Pool table.", + "eStrKey" : "Pattern" + }, + "NAT_BINDING_WITH_INVALID_BINDING_NAME": { + "desc": "Configuring a invalid binding name in NAT Binding table.", + "eStr": "Invalid length for the binding name." + }, + "NAT_BINDING_WITHOUT_NAT_POOL": { + "desc": "Configuring a NAT Binding table without NAT Pool.", + "eStrKey" : "Mandatory" + }, + "NAT_BINDING_WITH_INVALID_NAT_TYPE": { + "desc": "Configuring a invalid nat type in NAT Binding table.", + "eStrKey": "InvalidValue" + }, + "NAT_BINDING_WITH_INVALID_TWICE_NAT_ID": { + "desc": "Configuring a invalid twice nat id in NAT Binding table.", + "eStrKey": "InvalidValue" + }, + "NAT_BINDING_WITHOUT_ACL_TABLE": { + "desc": "Configuring a NAT Binding table without acl." + } +} diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/portchannel.json b/src/sonic-yang-models/tests/yang_model_tests/tests/portchannel.json index 3f263535b9ae..c461fae1b674 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests/portchannel.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/portchannel.json @@ -44,5 +44,12 @@ "desc": "Configure a non existent Vrf in PORTCHANNEL_INTERFACE table.", "eStrKey": "LeafRef", "eStr": ["sonic-vrf:name"] + }, + "PORTCHANNEL_INTERFACE_WRONG_NAT_ZONE_RANGE": { + "desc": "Configure wrong value for nat zone.", + "eStr" : "Invalid nat zone for the portchannel interface." + }, + "PORTCHANNEL_INTERFACE_VALID_NAT_ZONE_RANGE": { + "desc": "Configure valid value for nat zone." } } diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/vlan.json b/src/sonic-yang-models/tests/yang_model_tests/tests/vlan.json index e6cdd27b4625..2d38ef453c32 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests/vlan.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/vlan.json @@ -36,5 +36,12 @@ "desc": "Configure wrong value for tagging_mode.", "eStrKey" : "InvalidValue", "eStr": ["tagging_mode"] + }, + "VLAN_INTERFACE_WRONG_NAT_ZONE_RANGE": { + "desc": "Configure wrong value for nat zone.", + "eStr" : "Invalid nat zone for the vlan interface." + }, + "VLAN_INTERFACE_VALID_NAT_ZONE_RANGE": { + "desc": "Configure valid value for nat zone." } } diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/interface.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/interface.json index 6cac64a7ffad..db4763870d1d 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/interface.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/interface.json @@ -109,5 +109,77 @@ ] } } + }, + "INTERFACE_WRONG_NAT_ZONE_RANGE": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "10.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8", + "nat_zone": "4" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + } + }, + "INTERFACE_VALID_NAT_ZONE_RANGE": { + "sonic-interface:sonic-interface": { + "sonic-interface:INTERFACE": { + "INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "10.0.0.1/30", + "name": "Ethernet8", + "scope": "global" + } + ], + "INTERFACE_LIST": [ + { + "name": "Ethernet8", + "nat_zone": "2" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth8", + "description": "Ethernet8", + "fec": "rs", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet8", + "speed": 25000 + } + ] + } + } } } diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/loopback.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/loopback.json index 281db8315628..89c40918739e 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/loopback.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/loopback.json @@ -12,5 +12,45 @@ ] } } + }, + "LOOPBACK_INTERFACE_WRONG_NAT_ZONE_RANGE": { + "sonic-loopback-interface:sonic-loopback-interface": { + "sonic-loopback-interface:LOOPBACK_INTERFACE": { + "LOOPBACK_INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "10.0.0.1/30", + "name": "lo1", + "scope": "global" + } + ], + "LOOPBACK_INTERFACE_LIST": [ + { + "name": "lo1", + "nat_zone": "4" + } + ] + } + } + }, + "LOOPBACK_INTERFACE_VALID_NAT_ZONE_RANGE": { + "sonic-loopback-interface:sonic-loopback-interface": { + "sonic-loopback-interface:LOOPBACK_INTERFACE": { + "LOOPBACK_INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "10.0.0.1/30", + "name": "lo1", + "scope": "global" + } + ], + "LOOPBACK_INTERFACE_LIST": [ + { + "name": "lo1", + "nat_zone": "2" + } + ] + } + } } } diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/nat.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/nat.json new file mode 100644 index 000000000000..015aebf8fb48 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/nat.json @@ -0,0 +1,391 @@ +{ + "STATIC_NAPT_ENTRY_WITH_VALID_VALUES": { + "sonic-nat:sonic-nat": { + "sonic-nat:STATIC_NAPT": { + "STATIC_NAPT_LIST": [ + { + "global_ip": "125.56.90.1", + "ip_protocol": "UDP", + "global_l4_port": "100", + "local_ip": "12.0.0.1", + "local_port": "200", + "nat_type": "dnat", + "twice_nat_id": "100" + } + ] + } + } + }, + "STATIC_NAPT_ENTRY_WRONG_GLOBAL_IP": { + "sonic-nat:sonic-nat": { + "sonic-nat:STATIC_NAPT": { + "STATIC_NAPT_LIST": [ + { + "global_ip": "1001::1", + "ip_protocol": "UDP", + "global_l4_port": "100", + "local_ip": "12.0.0.1", + "local_port": "200", + "nat_type": "dnat", + "twice_nat_id": "100" + } + ] + } + } + }, + "STATIC_NAPT_ENTRY_WRONG_IP_PROTOCOL": { + "sonic-nat:sonic-nat": { + "sonic-nat:STATIC_NAPT": { + "STATIC_NAPT_LIST": [ + { + "global_ip": "125.56.90.1", + "ip_protocol": "ICMP", + "global_l4_port": "100", + "local_ip": "12.0.0.1", + "local_port": "200", + "nat_type": "dnat", + "twice_nat_id": "100" + } + ] + } + } + }, + "STATIC_NAPT_ENTRY_WRONG_GLOBAL_L4_PORT": { + "sonic-nat:sonic-nat": { + "sonic-nat:STATIC_NAPT": { + "STATIC_NAPT_LIST": [ + { + "global_ip": "125.56.90.1", + "ip_protocol": "UDP", + "global_l4_port": "100000", + "local_ip": "12.0.0.1", + "local_port": "200", + "nat_type": "dnat", + "twice_nat_id": "100" + } + ] + } + } + }, + "STATIC_NAPT_ENTRY_WITHOUT_LOCAL_IP": { + "sonic-nat:sonic-nat": { + "sonic-nat:STATIC_NAPT": { + "STATIC_NAPT_LIST": [ + { + "global_ip": "125.56.90.1", + "ip_protocol": "UDP", + "global_l4_port": "100", + "local_port": "200", + "nat_type": "dnat", + "twice_nat_id": "100" + } + ] + } + } + }, + "STATIC_NAPT_ENTRY_WITHOUT_LOCAL_PORT": { + "sonic-nat:sonic-nat": { + "sonic-nat:STATIC_NAPT": { + "STATIC_NAPT_LIST": [ + { + "global_ip": "125.56.90.1", + "ip_protocol": "UDP", + "global_l4_port": "100", + "local_ip": "12.0.0.1", + "nat_type": "dnat", + "twice_nat_id": "100" + } + ] + } + } + }, + "STATIC_NAPT_ENTRY_INVALID_TWICE_NAT_ID": { + "sonic-nat:sonic-nat": { + "sonic-nat:STATIC_NAPT": { + "STATIC_NAPT_LIST": [ + { + "global_ip": "125.56.90.1", + "ip_protocol": "UDP", + "global_l4_port": "100", + "local_ip": "12.0.0.1", + "local_port": "200", + "nat_type": "dnat", + "twice_nat_id": "65538" + } + ] + } + } + }, + "STATIC_NAT_ENTRY_WITH_VALID_VALUES": { + "sonic-nat:sonic-nat": { + "sonic-nat:STATIC_NAT": { + "STATIC_NAT_LIST": [ + { + "global_ip": "125.56.90.1", + "local_ip": "12.0.0.1", + "nat_type": "dnat", + "twice_nat_id": "100" + } + ] + } + } + }, + "STATIC_NAT_ENTRY_WRONG_GLOBAL_IP": { + "sonic-nat:sonic-nat": { + "sonic-nat:STATIC_NAT": { + "STATIC_NAT_LIST": [ + { + "global_ip": "1001::1", + "local_ip": "12.0.0.1", + "nat_type": "dnat", + "twice_nat_id": "100" + } + ] + } + } + }, + "STATIC_NAT_ENTRY_WITHOUT_LOCAL_IP": { + "sonic-nat:sonic-nat": { + "sonic-nat:STATIC_NAT": { + "STATIC_NAT_LIST": [ + { + "global_ip": "125.56.90.1", + "nat_type": "dnat", + "twice_nat_id": "100" + } + ] + } + } + }, + "STATIC_NAT_ENTRY_INVALID_TWICE_NAT_ID": { + "sonic-nat:sonic-nat": { + "sonic-nat:STATIC_NAT": { + "STATIC_NAT_LIST": [ + { + "global_ip": "125.56.90.1", + "local_ip": "12.0.0.1", + "nat_type": "dnat", + "twice_nat_id": "100000" + } + ] + } + } + }, + "NAT_GLOBAL_WITH_VALID_VALUES": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_GLOBAL": { + "Values": { + "admin_mode": "enabled", + "nat_timeout": "500", + "nat_tcp_timeout": "500", + "nat_udp_timeout": "500" + } + } + } + }, + "NAT_GLOBAL_WITH_INVALID_UDP_TIMEOUT": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_GLOBAL": { + "Values": { + "admin_mode": "enabled", + "nat_timeout": "500", + "nat_tcp_timeout": "500", + "nat_udp_timeout": "50" + } + } + } + }, + "NAT_GLOBAL_WITH_INVALID_TIMEOUT": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_GLOBAL": { + "Values": { + "admin_mode": "enabled", + "nat_timeout": "50", + "nat_tcp_timeout": "500", + "nat_udp_timeout": "500" + } + } + } + }, + "NAT_GLOBAL_WITH_INVALID_TCP_TIMEOUT": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_GLOBAL": { + "Values": { + "admin_mode": "enabled", + "nat_timeout": "500", + "nat_tcp_timeout": "50", + "nat_udp_timeout": "500" + } + } + } + }, + "NAT_POOL_WITH_VALID_VALUES": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_POOL": { + "NAT_POOL_LIST": [ + { + "name": "pool1", + "nat_ip": "125.56.90.1-125.56.90.100", + "nat_port": "500-1000" + } + ] + } + } + }, + "NAT_POOL_WITH_INVALID_POOL_NAME": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_POOL": { + "NAT_POOL_LIST": [ + { + "name": "p123456789p123456789p123456789p12345", + "nat_ip": "125.56.90.1-125.56.90.100", + "nat_port": "500-1000" + } + ] + } + } + }, + "NAT_POOL_WITHOUT_NAT_IP": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_POOL": { + "NAT_POOL_LIST": [ + { + "name": "pool1", + "nat_port": "500-1000" + } + ] + } + } + }, + "NAT_POOL_WITH_INVALID_NAT_IP": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_POOL": { + "NAT_POOL_LIST": [ + { + "name": "pool1", + "nat_ip": "2001::1", + "nat_port": "500-1000" + } + ] + } + } + }, + "NAT_POOL_WITH_INVALID_NAT_PORT": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_POOL": { + "NAT_POOL_LIST": [ + { + "name": "pool1", + "nat_ip": "125.56.90.1", + "nat_port": "500" + } + ] + } + } + }, + "NAT_BINDING_WITH_INVALID_BINDING_NAME": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_POOL": { + "NAT_POOL_LIST": [ + { + "name": "pool2", + "nat_ip": "125.56.90.1-125.56.90.100", + "nat_port": "500-1000" + } + ] + }, + "sonic-nat:NAT_BINDINGS": { + "NAT_BINDINGS_LIST": [ + { + "name": "b123456789b123456789b123456789b12345", + "nat_pool": "pool2", + "nat_type": "snat", + "twice_nat_id": "100" + } + ] + } + } + }, + "NAT_BINDING_WITHOUT_NAT_POOL": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_BINDINGS": { + "NAT_BINDINGS_LIST": [ + { + "name": "bind3", + "nat_type": "snat", + "twice_nat_id": "100" + } + ] + } + } + }, + "NAT_BINDING_WITH_INVALID_NAT_TYPE": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_POOL": { + "NAT_POOL_LIST": [ + { + "name": "pool4", + "nat_ip": "125.56.90.1-125.56.90.100", + "nat_port": "500-1000" + } + ] + }, + "sonic-nat:NAT_BINDINGS": { + "NAT_BINDINGS_LIST": [ + { + "name": "bind4", + "nat_pool": "pool4", + "nat_type": "double_nat", + "twice_nat_id": "100" + } + ] + } + } + }, + "NAT_BINDING_WITH_INVALID_TWICE_NAT_ID": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_POOL": { + "NAT_POOL_LIST": [ + { + "name": "pool1", + "nat_ip": "125.56.90.1-125.56.90.100", + "nat_port": "500-1000" + } + ] + }, + "sonic-nat:NAT_BINDINGS": { + "NAT_BINDINGS_LIST": [ + { + "name": "bind5", + "nat_pool": "pool5", + "nat_type": "snat", + "twice_nat_id": "1000000" + } + ] + } + } + }, + "NAT_BINDING_WITHOUT_ACL_TABLE": { + "sonic-nat:sonic-nat": { + "sonic-nat:NAT_POOL": { + "NAT_POOL_LIST": [ + { + "name": "pool1", + "nat_ip": "125.56.90.1-125.56.90.100", + "nat_port": "500-1000" + } + ] + }, + "sonic-nat:NAT_BINDINGS": { + "NAT_BINDINGS_LIST": [ + { + "name": "bind1", + "nat_pool": "pool1", + "nat_type": "snat", + "twice_nat_id": "100" + } + ] + } + } + } +} diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/portchannel.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/portchannel.json index 67e3a41af7b2..315d6cee6d91 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/portchannel.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/portchannel.json @@ -216,5 +216,99 @@ }] } } + }, + + "PORTCHANNEL_INTERFACE_WRONG_NAT_ZONE_RANGE": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-portchannel:sonic-portchannel": { + "sonic-portchannel:PORTCHANNEL": { + "PORTCHANNEL_LIST": [ + { + "admin_status": "up", + "members": [ + "Ethernet0" + ], + "min_links": "1", + "mtu": "9100", + "name": "PortChannel0001" + } + ] + }, + "sonic-portchannel:PORTCHANNEL_INTERFACE": { + "PORTCHANNEL_INTERFACE_LIST": [ + { + "name": "PortChannel0001", + "nat_zone": "4" + } + ], + "PORTCHANNEL_INTERFACE_IPPREFIX_LIST": [ + { + "name": "PortChannel0001", + "ip_prefix": "1.1.1.1/24" + } + ] + } + } + }, + + "PORTCHANNEL_INTERFACE_VALID_NAT_ZONE_RANGE": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-portchannel:sonic-portchannel": { + "sonic-portchannel:PORTCHANNEL": { + "PORTCHANNEL_LIST": [ + { + "admin_status": "up", + "members": [ + "Ethernet0" + ], + "min_links": "1", + "mtu": "9100", + "name": "PortChannel0001" + } + ] + }, + "sonic-portchannel:PORTCHANNEL_INTERFACE": { + "PORTCHANNEL_INTERFACE_LIST": [ + { + "name": "PortChannel0001", + "nat_zone": "1" + } + ], + "PORTCHANNEL_INTERFACE_IPPREFIX_LIST": [ + { + "name": "PortChannel0001", + "ip_prefix": "1.1.1.1/24" + } + ] + } + } } } diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/vlan.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/vlan.json index dd9874972fe9..0faa3926b21e 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/vlan.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/vlan.json @@ -263,5 +263,109 @@ }] } } + }, + "VLAN_INTERFACE_WRONG_NAT_ZONE_RANGE": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "mtu": 9000, + "lanes": "1", + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN": { + "VLAN_LIST": [ + { + "description": "vlan_nat", + "name": "Vlan100" + } + ] + }, + "sonic-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [ + { + "port": "Ethernet0", + "tagging_mode": "tagged", + "name": "Vlan100" + } + ] + }, + "sonic-vlan:VLAN_INTERFACE": { + "VLAN_INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "10.0.0.1/24", + "scope": "global", + "name": "Vlan100" + } + ], + "VLAN_INTERFACE_LIST": [ + { + "name": "Vlan100", + "nat_zone": "4" + } + ] + } + } + }, + "VLAN_INTERFACE_VALID_NAT_ZONE_RANGE": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "mtu": 9000, + "lanes": "1", + "name": "Ethernet0", + "speed": 25000 + } + ] + } + }, + "sonic-vlan:sonic-vlan": { + "sonic-vlan:VLAN": { + "VLAN_LIST": [ + { + "description": "vlan_nat", + "name": "Vlan100" + } + ] + }, + "sonic-vlan:VLAN_MEMBER": { + "VLAN_MEMBER_LIST": [ + { + "port": "Ethernet0", + "tagging_mode": "tagged", + "name": "Vlan100" + } + ] + }, + "sonic-vlan:VLAN_INTERFACE": { + "VLAN_INTERFACE_IPPREFIX_LIST": [ + { + "family": "IPv4", + "ip-prefix": "10.0.0.1/24", + "scope": "global", + "name": "Vlan100" + } + ], + "VLAN_INTERFACE_LIST": [ + { + "name": "Vlan100", + "nat_zone": "2" + } + ] + } + } } } diff --git a/src/sonic-yang-models/yang-models/sonic-interface.yang b/src/sonic-yang-models/yang-models/sonic-interface.yang index 912268f86be5..48f63a29c563 100644 --- a/src/sonic-yang-models/yang-models/sonic-interface.yang +++ b/src/sonic-yang-models/yang-models/sonic-interface.yang @@ -57,6 +57,17 @@ module sonic-interface { path "/vrf:sonic-vrf/vrf:VRF/vrf:VRF_LIST/vrf:name"; } } + + leaf nat_zone { + description "NAT Zone for the interface"; + type uint8 { + range "0..3" { + error-message "Invalid nat zone for the interface."; + error-app-tag nat-zone-invalid; + } + } + default "0"; + } } /* end of INTERFACE_LIST */ diff --git a/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang b/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang index 54f622c81717..0414f3b94344 100644 --- a/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang +++ b/src/sonic-yang-models/yang-models/sonic-loopback-interface.yang @@ -46,6 +46,17 @@ module sonic-loopback-interface { path "/vrf:sonic-vrf/vrf:VRF/vrf:VRF_LIST/vrf:name"; } } + + leaf nat_zone { + description "NAT Zone for the loopback interface"; + type uint8 { + range "0..3" { + error-message "Invalid nat zone for the loopback interface."; + error-app-tag nat-zone-invalid; + } + } + default "0"; + } } /* end of LOOPBACK_INTERFACE_LIST */ diff --git a/src/sonic-yang-models/yang-models/sonic-nat.yang b/src/sonic-yang-models/yang-models/sonic-nat.yang new file mode 100644 index 000000000000..03e12c2301a3 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-nat.yang @@ -0,0 +1,294 @@ +module sonic-nat { + namespace "http://github.com/Azure/sonic-nat"; + prefix snat; + yang-version 1.1; + + import ietf-inet-types { + prefix inet; + } + + import sonic-acl { + prefix sacl; + } + + import sonic-types { + prefix stypes; + } + + organization + "SONiC"; + + contact + "SONiC"; + + description + "SONiC NAT yang model"; + + revision 2021-03-14 { + description + "Initial revision."; + } + + typedef nat-type { + type enumeration { + enum snat { + description "Source NAT."; + } + enum dnat { + description "Destination NAT."; + } + } + } + + typedef ip-address-range { + type union { + type inet:ipv4-address; + type string { + pattern '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(-(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]))?'; + } + } + + description + "This type denotes a single IP address or a range of addresses."; + } + + container sonic-nat { + + container STATIC_NAPT { + + description "STATIC_NAPT table part of config_db.json"; + + list STATIC_NAPT_LIST { + key "global_ip ip_protocol global_l4_port"; + + leaf global_ip { + description "Global ip for the Static NAPT entry."; + + type inet:ipv4-address; + } + + leaf ip_protocol { + description "IP Protocol (tcp or udp) for the Static NAPT entry."; + + type stypes:ip-protocol-type; + } + + leaf global_l4_port { + description "Global L4 port for the Static NAPT entry."; + + type inet:port-number; + } + + leaf local_ip { + description "Local ip for the Static NAPT entry."; + + mandatory true; + type inet:ipv4-address; + } + + leaf local_port { + description "Local port for the Static NAPT entry."; + + mandatory true; + type inet:port-number ; + } + + leaf nat_type { + description "Nat type for the static napt entry - snat or dnat"; + + type nat-type; + default dnat; + } + + leaf twice_nat_id { + description "Twice nat id for the static napt to achieve the twice napt"; + + type uint16 { + range "1..9999" { + error-message "Invalid twice nat id for the static NAPT."; + error-app-tag twice-nat-id-invalid; + } + } + } + } + } + + container STATIC_NAT { + + description "STATIC_NAT table part of config_db.json"; + + list STATIC_NAT_LIST { + key "global_ip"; + + leaf global_ip { + description "Global ip for the Static NAT entry."; + + type inet:ipv4-address; + } + + leaf local_ip { + description "Local ip for the Static NAT entry."; + + mandatory true; + type inet:ipv4-address; + } + + leaf nat_type { + description "Nat type for the static nat entry - snat or dnat"; + + type nat-type; + default dnat; + } + + leaf twice_nat_id { + description "Twice nat id for the static nat to achieve the twice nat"; + + type uint16 { + range "1..9999" { + error-message "Invalid twice nat id for the static NAT."; + error-app-tag twice-nat-id-invalid; + } + } + } + } + } + + container NAT_GLOBAL { + + description "NAT_GLOBAL table part of config_db.json"; + + container Values { + + leaf admin_mode { + description "Admin mode of the NAT feature."; + + type stypes:admin_mode; + default disabled; + } + + leaf nat_timeout { + description "Timeout for the nat entries within the range of 300 sec to 432000 secs."; + + type uint32 { + range "300..432000" { + error-message "Invalid NAT Timeout, valid range 300 sec to 432000 sec."; + error-app-tag nat-timeout-invalid; + } + } + default "600"; + } + leaf nat_tcp_timeout { + description "Timeout for the nat tcp entries within the range of 300 sec to 432000 secs."; + + type uint32 { + range "300..432000" { + error-message "Invalid NAT TCP Timeout, valid range 300 sec to 432000 sec."; + error-app-tag nat-tcp-timeout-invalid; + } + } + default "86400"; + } + leaf nat_udp_timeout { + description "Timeout for the nat udp entries within the range of 120 sec to 600 secs."; + + type uint16 { + range "120..600" { + error-message "Invalid NAT UDP Timeout, valid range 120 sec to 600 sec."; + error-app-tag nat-udp-timeout-invalid; + } + } + default "300"; + } + } + } + + container NAT_POOL { + + description "NAT_POOL table part of config_db.json"; + + list NAT_POOL_LIST { + key "name"; + max-elements 16; + + leaf name { + description "Key - Name of the NAT Pool"; + + type string { + pattern '[a-zA-Z0-9]{1}([-a-zA-Z0-9_]{0,31})'; + length 1..32 { + error-message "Invalid length for the pool name."; + error-app-tag pool-name-invalid-length; + } + } + } + + leaf nat_ip { + description "Single IP address or a range of addresses for a NAT pool."; + + mandatory true; + + type ip-address-range; + } + + leaf nat_port { + description "Range of port values for a NAT pool."; + + type string { + pattern "(([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-4])(-)([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))"; + } + } + } + } + + container NAT_BINDINGS { + + description "NAT_BINDINGS table part of config_db.json"; + + list NAT_BINDINGS_LIST { + key "name"; + max-elements 16; + + leaf name { + description "Key - Name of the NAT Binding"; + + type string { + + pattern '[a-zA-Z0-9]{1}([-a-zA-Z0-9_]{0,31})'; + length 1..32 { + error-message "Invalid length for the binding name."; + error-app-tag binding-name-invalid-length; + } + } + } + + leaf nat_pool { + description "NAT Pool name mapping for the binding"; + + mandatory true; + + type leafref { + path "../../../NAT_POOL/NAT_POOL_LIST/name"; + } + } + + leaf nat_type { + description "Nat type for the binding - snat or dnat"; + + type nat-type; + default snat; + } + + leaf twice_nat_id { + description "Twice nat id for the binding to achieve the Dynamic twice nat"; + + type uint16 { + range "1..9999" { + error-message "Invalid twice nat id for the binding."; + error-app-tag twice-nat-id-invalid; + } + } + } + } + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-portchannel.yang b/src/sonic-yang-models/yang-models/sonic-portchannel.yang index f1abe3ccde67..837d18bef4c0 100644 --- a/src/sonic-yang-models/yang-models/sonic-portchannel.yang +++ b/src/sonic-yang-models/yang-models/sonic-portchannel.yang @@ -164,6 +164,17 @@ module sonic-portchannel { path "/vrf:sonic-vrf/vrf:VRF/vrf:VRF_LIST/vrf:name"; } } + + leaf nat_zone { + description "NAT Zone for the portchannel interface"; + type uint8 { + range "0..3" { + error-message "Invalid nat zone for the portchannel interface."; + error-app-tag nat-zone-invalid; + } + } + default "0"; + } } /* end of list PORTCHANNEL_INTERFACE_LIST */ list PORTCHANNEL_INTERFACE_IPPREFIX_LIST { diff --git a/src/sonic-yang-models/yang-models/sonic-types.yang b/src/sonic-yang-models/yang-models/sonic-types.yang index f70f720b7e5a..db0f9a0ac16f 100644 --- a/src/sonic-yang-models/yang-models/sonic-types.yang +++ b/src/sonic-yang-models/yang-models/sonic-types.yang @@ -63,6 +63,7 @@ module sonic-types { enum DROP; enum FORWARD; enum REDIRECT; + enum DO_NOT_NAT; } } @@ -115,6 +116,20 @@ module sonic-types { } } + typedef admin_mode { + type enumeration { + enum enabled; + enum disabled; + } + } + + typedef ip-protocol-type { + type enumeration { + enum TCP; + enum UDP; + } + } + typedef interface_type { type enumeration { enum CR; diff --git a/src/sonic-yang-models/yang-models/sonic-vlan.yang b/src/sonic-yang-models/yang-models/sonic-vlan.yang index d2309965ebe1..d6f2a4808a6f 100644 --- a/src/sonic-yang-models/yang-models/sonic-vlan.yang +++ b/src/sonic-yang-models/yang-models/sonic-vlan.yang @@ -69,6 +69,17 @@ module sonic-vlan { path "/vrf:sonic-vrf/vrf:VRF/vrf:VRF_LIST/vrf:name"; } } + + leaf nat_zone { + description "NAT Zone for the vlan interface"; + type uint8 { + range "0..3" { + error-message "Invalid nat zone for the vlan interface."; + error-app-tag nat-zone-invalid; + } + } + default "0"; + } } /* end of VLAN_INTERFACE_LIST */