X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_cnat.py;h=ff8e1ebbbbbaef32a69106a04e56ecc6e806a5f2;hb=56e17cf7a23831b353bc1836def47dad7f869dad;hp=1881653dcc96b6ec264c7784c0c6a6ccd5dff19e;hpb=d3e0d104ad6ebc687609c10a6c936954d2a7abdd;p=vpp.git diff --git a/test/test_cnat.py b/test/test_cnat.py index 1881653dcc9..ff8e1ebbbbb 100644 --- a/test/test_cnat.py +++ b/test/test_cnat.py @@ -2,27 +2,19 @@ import unittest -from framework import VppTestCase, VppTestRunner -from vpp_ip import DpoProto, INVALID_INDEX +from framework import VppTestCase +from asfframework import VppTestRunner +from vpp_ip import INVALID_INDEX from itertools import product from scapy.packet import Raw from scapy.layers.l2 import Ether from scapy.layers.inet import IP, UDP, TCP, ICMP -from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror +from scapy.layers.inet import IPerror, TCPerror, UDPerror from scapy.layers.inet6 import IPv6, IPerror6, ICMPv6DestUnreach from scapy.layers.inet6 import ICMPv6EchoRequest, ICMPv6EchoReply -import struct - -from ipaddress import ( - ip_address, - ip_network, - IPv4Address, - IPv6Address, - IPv4Network, - IPv6Network, -) +from ipaddress import ip_network from vpp_object import VppObject from vpp_papi import VppEnum @@ -110,11 +102,12 @@ class Endpoint(object): class Translation(VppObject): - def __init__(self, test, iproto, vip, paths): + def __init__(self, test, iproto, vip, paths, fhc): self._test = test self.vip = vip self.iproto = iproto self.paths = paths + self.fhc = fhc self.id = None def __str__(self): @@ -140,6 +133,7 @@ class Translation(VppObject): "ip_proto": self._vl4_proto(), "n_paths": len(self.paths), "paths": self._encoded_paths(), + "flow_hash_config": self.fhc, } ) self._test.registry.register(self, self._test.logger) @@ -381,6 +375,41 @@ class TestCNatTranslation(CnatCommonTestCase): i.admin_down() super(TestCNatTranslation, self).tearDown() + def cnat_fhc_translation(self): + """CNat Translation""" + self.logger.info(self.vapi.cli("sh cnat client")) + self.logger.info(self.vapi.cli("sh cnat translation")) + + for nbr, translation in enumerate(self.mbtranslations): + vip = translation.vip + + # + # Flows to the VIP with same ips and different source ports are loadbalanced identically + # in both cases of flow hash 0x03 (src ip and dst ip) and 0x08 (dst port) + # + ctx = CnatTestContext(self, translation.iproto, vip.is_v6) + for src_pgi, sport in product(range(N_REMOTE_HOSTS), [1234, 1233]): + # from client to vip + ctx.cnat_send(self.pg0, src_pgi, sport, self.pg1, vip.ip, vip.port) + dport1 = ctx.rxs[0][ctx.L4PROTO].dport + ctx._test.assertIn( + dport1, + [translation.paths[0][DST].port, translation.paths[1][DST].port], + ) + ctx.cnat_expect(self.pg0, src_pgi, sport, self.pg1, nbr, dport1) + + ctx.cnat_send( + self.pg0, src_pgi, sport + 122, self.pg1, vip.ip, vip.port + ) + dport2 = ctx.rxs[0][ctx.L4PROTO].dport + ctx._test.assertIn( + dport2, + [translation.paths[0][DST].port, translation.paths[1][DST].port], + ) + ctx.cnat_expect(self.pg0, src_pgi, sport + 122, self.pg1, nbr, dport2) + + ctx._test.assertEqual(dport1, dport2) + def cnat_translation(self): """CNat Translation""" self.logger.info(self.vapi.cli("sh cnat client")) @@ -470,7 +499,6 @@ class TestCNatTranslation(CnatCommonTestCase): ctx.cnat_expect(self.pg0, src_pgi, sport, self.pg2, 0, 5000) def _test_icmp(self): - # # Testing ICMP # @@ -495,6 +523,46 @@ class TestCNatTranslation(CnatCommonTestCase): ctx.cnat_expect(self.pg0, 0, 1234, self.pg2, 0, vip.port) ctx.cnat_send_icmp_return_error().cnat_expect_icmp_error_return() + def _make_multi_backend_translations(self): + self.translations = [] + self.mbtranslations = [] + self.mbtranslations.append( + Translation( + self, + TCP, + Endpoint(ip="30.0.0.5", port=5555, is_v6=False), + [ + ( + Endpoint(is_v6=False), + Endpoint(pg=self.pg1, pgi=0, port=4001, is_v6=False), + ), + ( + Endpoint(is_v6=False), + Endpoint(pg=self.pg1, pgi=0, port=4005, is_v6=False), + ), + ], + 0x03, # hash only on dst ip and src ip + ).add_vpp_config() + ) + self.mbtranslations.append( + Translation( + self, + TCP, + Endpoint(ip="30.0.0.6", port=5555, is_v6=False), + [ + ( + Endpoint(is_v6=False), + Endpoint(pg=self.pg1, pgi=1, port=4006, is_v6=False), + ), + ( + Endpoint(is_v6=False), + Endpoint(pg=self.pg1, pgi=1, port=4007, is_v6=False), + ), + ], + 0x08, # hash only on dst port + ).add_vpp_config() + ) + def _make_translations_v4(self): self.translations = [] self.translations.append( @@ -508,6 +576,7 @@ class TestCNatTranslation(CnatCommonTestCase): Endpoint(pg=self.pg1, pgi=0, port=4001, is_v6=False), ) ], + 0x9F, ).add_vpp_config() ) self.translations.append( @@ -521,6 +590,7 @@ class TestCNatTranslation(CnatCommonTestCase): Endpoint(pg=self.pg1, pgi=1, port=4002, is_v6=False), ) ], + 0x9F, ).add_vpp_config() ) self.translations.append( @@ -534,6 +604,7 @@ class TestCNatTranslation(CnatCommonTestCase): Endpoint(pg=self.pg1, pgi=2, port=4003, is_v6=False), ) ], + 0x9F, ).add_vpp_config() ) @@ -550,6 +621,7 @@ class TestCNatTranslation(CnatCommonTestCase): Endpoint(pg=self.pg1, pgi=0, port=4001, is_v6=True), ) ], + 0x9F, ).add_vpp_config() ) self.translations.append( @@ -563,6 +635,7 @@ class TestCNatTranslation(CnatCommonTestCase): Endpoint(pg=self.pg1, pgi=1, port=4002, is_v6=True), ) ], + 0x9F, ).add_vpp_config() ) self.translations.append( @@ -576,6 +649,7 @@ class TestCNatTranslation(CnatCommonTestCase): Endpoint(pg=self.pg1, pgi=2, port=4003, is_v6=True), ) ], + 0x9F, ).add_vpp_config() ) @@ -599,6 +673,11 @@ class TestCNatTranslation(CnatCommonTestCase): self._make_translations_v4() self.cnat_translation() + def test_cnat_fhc(self): + # """ CNat Translation flow hash config """ + self._make_multi_backend_translations() + self.cnat_fhc_translation() + class TestCNatSourceNAT(CnatCommonTestCase): """CNat Source NAT""" @@ -798,7 +877,7 @@ class TestCNatDHCP(CnatCommonTestCase): (Endpoint(pg=self.pg1, is_v6=is_v6), Endpoint(pg=self.pg3, is_v6=is_v6)), ] ep = Endpoint(pg=self.pg0, is_v6=is_v6) - t = Translation(self, TCP, ep, paths).add_vpp_config() + t = Translation(self, TCP, ep, paths, 0x9F).add_vpp_config() # Add an address on every interface # and check it is reflected in the cnat config for pg in self.pg_interfaces: