[caclmgrd][dualtor] add src IP to the SNAT rule for allowing gRPC (#13087)
This PR is a required for changing the L3 IP forwarding Behavior to SoC in active-active toplogy. Basically a src IP is added to the SNAT rule so that only packets originating from ToR with src IP as vlan IP get natted by the rule and change the src IP to LoopBack IP Master Branch PR with combined change is here sonic-net/sonic-host-services#3 How I did it check the config DB if the ToR is a DualToR and has an SoC IP assigned. put an iptable rule iptables -t nat -A POSTROUTING --destination -j SNAT --to-source " Signed-off-by: vaibhav-dahiya vdahiya@microsoft.com Signed-off-by: vaibhav-dahiya <vdahiya@microsoft.com>
This commit is contained in:
parent
1f677f5a71
commit
6e1ca643fd
@ -48,11 +48,12 @@ def get_ip_from_interface_table(table, intf_name):
|
||||
if not _ip_prefix_in_key(key):
|
||||
continue
|
||||
|
||||
|
||||
iface_name, iface_cidr = key
|
||||
if iface_name.startswith(intf_name):
|
||||
ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False)
|
||||
if isinstance(ip_ntwrk, ipaddress.IPv4Network):
|
||||
ip_addr = ip_ntwrk.network_address
|
||||
ip_str = iface_cidr.split("/")[0]
|
||||
ip_addr = ipaddress.ip_address(ip_str)
|
||||
if isinstance(ip_addr, ipaddress.IPv4Address):
|
||||
return ip_addr
|
||||
|
||||
return None
|
||||
@ -75,6 +76,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase):
|
||||
MUX_CABLE_TABLE = "MUX_CABLE_TABLE"
|
||||
CONFIG_MUX_CABLE = "MUX_CABLE"
|
||||
LOOPBACK_TABLE = "LOOPBACK_INTERFACE"
|
||||
VLAN_INTF_TABLE = "VLAN_INTERFACE"
|
||||
|
||||
ACL_TABLE_TYPE_CTRLPLANE = "CTRLPLANE"
|
||||
|
||||
@ -318,6 +320,9 @@ class ControlPlaneAclManager(daemon_base.DaemonBase):
|
||||
loopback_table = self.config_db_map[DEFAULT_NAMESPACE].get_table(self.LOOPBACK_TABLE)
|
||||
loopback_name = 'Loopback3'
|
||||
loopback_address = get_ip_from_interface_table(loopback_table, loopback_name)
|
||||
vlan_name = 'Vlan'
|
||||
vlan_table = self.config_db_map[DEFAULT_NAMESPACE].get_table(self.VLAN_INTF_TABLE)
|
||||
vlan_address = get_ip_from_interface_table(vlan_table, vlan_name)
|
||||
fwd_dualtor_grpc_traffic_from_host_to_soc_cmds.append(self.iptables_cmd_ns_prefix[namespace] +
|
||||
"iptables -t nat --flush POSTROUTING")
|
||||
|
||||
@ -328,7 +333,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase):
|
||||
kvp = mux_table.get(key)
|
||||
if 'cable_type' in kvp and kvp['cable_type'] == 'active-active':
|
||||
fwd_dualtor_grpc_traffic_from_host_to_soc_cmds.append(self.iptables_cmd_ns_prefix[namespace] +
|
||||
"iptables -t nat -A POSTROUTING --destination {} -j SNAT --to-source {}".format(kvp['soc_ipv4'], loopback_address))
|
||||
"iptables -t nat -A POSTROUTING --destination {} --source {} -j SNAT --to-source {}".format(kvp['soc_ipv4'], vlan_address, loopback_address))
|
||||
|
||||
return fwd_dualtor_grpc_traffic_from_host_to_soc_cmds
|
||||
|
||||
@ -356,7 +361,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase):
|
||||
|
||||
for ip_protocol in self.ACL_SERVICES[acl_service]["ip_protocols"]:
|
||||
if "dst_ports" in self.ACL_SERVICES[acl_service]:
|
||||
for dst_port in self.ACL_SERVICES[acl_service]["dst_ports"]:
|
||||
for dst_port in self.ACL_SERVICES[acl_service]["dst_ports"]:
|
||||
for ipv4_src_ip in nat_source_ipv4_set:
|
||||
# IPv4 rules
|
||||
fwd_traffic_from_namespace_to_host_cmds.append(self.iptables_cmd_ns_prefix[namespace] +
|
||||
|
@ -4,6 +4,7 @@ import swsscommon
|
||||
|
||||
from parameterized import parameterized
|
||||
from sonic_py_common.general import load_module_from_source
|
||||
from ipaddress import IPv4Address
|
||||
from unittest import TestCase, mock
|
||||
from pyfakefs.fake_filesystem_unittest import patchfs
|
||||
|
||||
@ -49,3 +50,11 @@ class TestCaclmgrdSoc(TestCase):
|
||||
caclmgrd_daemon.update_control_plane_nat_acls('', {})
|
||||
mocked_subprocess.Popen.assert_has_calls(test_data["expected_subprocess_calls"], any_order=True)
|
||||
|
||||
def test_get_ip_from_interface_table(self):
|
||||
if not os.path.exists(DBCONFIG_PATH):
|
||||
fs.create_file(DBCONFIG_PATH) # fake database_config.json
|
||||
|
||||
table = {("Vlan1000","10.10.10.1/32"): "val"}
|
||||
ip_addr = self.caclmgrd.get_ip_from_interface_table(table, "Vlan")
|
||||
|
||||
assert (ip_addr == IPv4Address('10.10.10.1'))
|
||||
|
@ -21,6 +21,11 @@ CACLMGRD_SOC_TEST_VECTOR = [
|
||||
"soc_ipv4": "192.168.1.0/32",
|
||||
}
|
||||
},
|
||||
"VLAN_INTERFACE": {
|
||||
"Vlan1000|10.10.2.2/23": {
|
||||
"NULL": "NULL",
|
||||
}
|
||||
},
|
||||
"LOOPBACK_INTERFACE": {
|
||||
"Loopback3|10.10.10.10/32": {
|
||||
"NULL": "NULL",
|
||||
@ -30,7 +35,7 @@ CACLMGRD_SOC_TEST_VECTOR = [
|
||||
},
|
||||
},
|
||||
"expected_subprocess_calls": [
|
||||
call("iptables -t nat -A POSTROUTING --destination 192.168.1.0/32 -j SNAT --to-source 10.10.10.10",shell=True, universal_newlines=True, stdout=-1)
|
||||
call("iptables -t nat -A POSTROUTING --destination 192.168.1.0/32 --source 10.10.10.10 -j SNAT --to-source 10.10.10.10",shell=True, universal_newlines=True, stdout=-1)
|
||||
],
|
||||
"popen_attributes": {
|
||||
'communicate.return_value': ('output', 'error'),
|
||||
|
Reference in New Issue
Block a user