Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes in swss-utilities submodule to support NAT feature. #645

Merged
merged 11 commits into from
Jan 29, 2020

Conversation

AkhileshSamineni
Copy link
Contributor

Added new commands to supports NAT feature

Config Commands:
config nat add static basic {global-ip} {local-ip} -nat_type {snat/dnat} -twice_nat_id {value}
config nat remove static basic {global-ip} {local-ip}
config nat add static {tcp | udp} {global-ip} {global-port} {local-ip} {local-port} -nat_type {snat | dnat} -twice_nat_id {value}
config nat remove static {tcp | udp} {global-ip} {global-port} {local-ip} {local-port}
config nat remove static all
config nat add pool {pool-name} {global-ip-range} {global-port-range}
config nat remove pool {pool-name}
config nat remove pools
config nat add binding {binding-name} {pool-name} {acl-name} -nat_type {snat | dnat} -twice_nat_id {value}
config nat remove binding {binding-name}
config nat remove bindings
config nat add interface {interface-name} {-nat_zone {zone-value}}
config nat remove interface {interface-name}
config nat remove interfaces
config nat set timeout {secs}
config nat reset timeout
config nat feature {enable | disable}
config nat set udp-timeout {secs}
config nat reset udp-timeout
config nat set tcp-timeout {secs}
config nat reset tcp-timeout

Show Commands:
show nat translations
show nat statistics
show nat config static
show nat config pool
show nat config bindings
show nat config globalvalues
show nat config zones
show nat translations count
show nat config

Clear Commands:
sonic-clear nat translations
sonic-clear nat statistics

Link to NAT HLD : https://github.com/kirankella/SONiC/blob/nat_doc_changes/doc/nat/nat_design_spec.md

Signed-off-by: [email protected]

@msftclas
Copy link

msftclas commented Sep 16, 2019

CLA assistant check
All CLA requirements met.

"""Add Static NAT-related configutation"""

# Verify the ip address format
if is_valid_ipv4_address(local_ip) is False:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function is_valid_ipv4_address rejects if the ip is reserved IP address. Will this block use of some private ip ranges as local ip address ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arlakshm No, It won't block the private ip addresses. Function "is_reserved()" will check for IETF reserved ip addresses (Ex. 240.0.0.0/4). For private address checking, "is_private()" function is used.

config/nat.py Outdated
if 'SNAT_ENTRIES' in counter_entry:
snat_entries = counter_entry['SNAT_ENTRIES']

if int(snat_entries) >= 1024:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This limit of 1k entries is for SNAT or DNAT or overall static nat entry limit ?
Is this a Software limit or hardware limit ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1K is hardware limitation only, Both SNAT and DNAT limits the entries to 1k.
Single Static NAT entry creates a SNAT and DNAT entry is hardware.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a way to query this limit from HW?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Added "MAX_ENTRIES" in counter_db which will be queried from HW at natorch code.

"""Enbale the NAT feature """
config_db = ConfigDBConnector()
config_db.connect()
config_db.mod_entry("NAT_GLOBAL", "Values", {"admin_mode": "enabled"})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When NAT is enabled but no timeout is configured, what will be the default timeout value ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For NAT entries, the default timeout is 600 seconds.
For NAPT entries, the default tcp timeout is 86400 seconds and udp timeout is 300 seconds.
When NAT is enabled, default timeouts are set in NatMgr code if timeouts are not configured before NAT enabled.

Copy link
Contributor

@stepanblyschak stepanblyschak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add?

  1. unittest for new CLI commands
  2. update command reference

config/nat.py Outdated
from swsssdk import ConfigDBConnector
from swsssdk import SonicV2Connector

TABLE_NAME_SEPARATOR = '|'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think TABLE_NAME_SEPERATOR should be defined somewhere in swsssdk

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, TABLE_NAME_SEPERATOR is defined in ConfigDBConnector from swsssdk.
Not using the TABLE_NAME_SEPERATOR, removed this variable.

config/nat.py Outdated
ip = ipaddress.IPv4Address(address)
if (ip.is_reserved) or (ip.is_multicast) or (ip.is_loopback) or (address in invalid_list):
return False
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only IPv4Address creation can throw here, could you be more specific in except statement?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added "AddressValueError" exception here.

config/nat.py Outdated
return False
try:
netaddr.IPNetwork(val)
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be good to be more specific in except

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed this function, removed it.

config/nat.py Outdated
except ValueError:
return False

if ((port_address < 1) or (port_address > 65535)):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if port_address not in xrange(1, 65535):

looks more python-way

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

config/nat.py Outdated
@@ -0,0 +1,1104 @@
#!/usr/bin/env python -u
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why '-u' flag is needed ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed actually, removed it.

elif interface_name.startswith("Vlan"):
interface_dict = config_db.get_table('VLAN')
elif interface_name.startswith("Loopback"):
return True
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need to check LOOPBACK_INTERFACE table?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this function, checking for PORT, VLAN, PORTCHANNEL tables and for Loopback we don't have a LOOPBACK table, so returning True for it.
The verification of INTERFACE tables like LOOPBACK_INTERFACE tables are happens at add_interface(..) and remove_interface(..) functions.

config/nat.py Outdated
if 'SNAT_ENTRIES' in counter_entry:
snat_entries = counter_entry['SNAT_ENTRIES']

if int(snat_entries) >= 1024:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a way to query this limit from HW?

import subprocess

def main():
ctdumpcmd = 'conntrack -L -j > /host/warmboot/nat/nat_entries.dump'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'conntrack -L -j' output may have a lot of entries. I'm looking at https://github.com/Azure/sonic-buildimage/pull/3494/files#diff-dc200de8bc4641995c83a89e61e3c32cR51 where it is parsed using a complex regular expressions during warm start.
My concern is that parsing that output during system start can consume a lot of cpu in case of huge amount of entries. Did you test this part and impact on system warm reboot?
Right now sonic seems to have performance degradation comparing to 201811 release during system warm start causing LAG/BGP flapping on some platforms.
IMO, dumping this output in a fast-loadable format (like json) during warm start is preferred.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This option can be explored. We can do it in a separate PR ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

# Kill nat docker after saving the conntrack table
debug "Stopping nat ..."
/usr/bin/dump_nat_entries.py
docker kill nat > /dev/null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid systemd restart the service automatically after kill you should add 'systemctl stop nat'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -410,6 +410,12 @@ docker exec -i bgp pkill -9 zebra
docker exec -i bgp pkill -9 bgpd || [ $? == 1 ]
debug "Stopped bgp ..."

# Kill nat docker after saving the conntrack table
debug "Stopping nat ..."
/usr/bin/dump_nat_entries.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to put this after stopping radv, bgp ? If we stop before it will have no impact on bgp restart timeout

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No specific reason. moved it to before radv.

Signed-off-by: Akhilesh Samineni <[email protected]>
@AkhileshSamineni
Copy link
Contributor Author

AkhileshSamineni commented Nov 12, 2019

Could you please add?

  1. unittest for new CLI commands
  2. update command reference

@stepanblyschak
Will add unit tests in separate PR.
Will add command reference in next patch.

@AkhileshSamineni
Copy link
Contributor Author

Retest this please.

3 similar comments
@AkhileshSamineni
Copy link
Contributor Author

Retest this please.

@AkhileshSamineni
Copy link
Contributor Author

Retest this please.

@AkhileshSamineni
Copy link
Contributor Author

Retest this please.

@rlhui
Copy link
Contributor

rlhui commented Jan 28, 2020

retest this please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants