X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_ip4.py;h=f0b43947736c488a5a3845bdd7c4c37a4755f825;hb=8dc0d488e62323a6f2814a74130934f5ed2bf724;hp=b93241b652d3195b6a95b0a71d14081cd46d6cd8;hpb=2df2f75ec52003e3b6addbde5f2e8254a9aee800;p=vpp.git diff --git a/test/test_ip4.py b/test/test_ip4.py index b93241b652d..f0b43947736 100644 --- a/test/test_ip4.py +++ b/test/test_ip4.py @@ -11,6 +11,7 @@ from scapy.layers.l2 import Ether, Dot1Q, ARP from scapy.packet import Raw from six import moves +from framework import tag_fixme_vpp_workers from framework import VppTestCase, VppTestRunner from util import ppp from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpMRoute, \ @@ -22,7 +23,7 @@ from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint from vpp_papi import VppEnum from vpp_neighbor import VppNeighbor from vpp_lo_interface import VppLoInterface -from vpp_policer import VppPolicer +from vpp_policer import VppPolicer, PolicerAction NUM_PKTS = 67 @@ -1118,6 +1119,7 @@ class TestIPLoadBalance(VppTestCase): super(TestIPLoadBalance, self).tearDown() def send_and_expect_load_balancing(self, input, pkts, outputs): + self.vapi.cli("clear trace") input.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) self.pg_start() @@ -1125,8 +1127,7 @@ class TestIPLoadBalance(VppTestCase): for oo in outputs: rx = oo._get_capture(1) self.assertNotEqual(0, len(rx)) - for r in rx: - rxs.append(r) + rxs.append(rx) return rxs def send_and_expect_one_itf(self, input, pkts, itf): @@ -1135,9 +1136,18 @@ class TestIPLoadBalance(VppTestCase): self.pg_start() rx = itf.get_capture(len(pkts)) + def total_len(self, rxs): + n = 0 + for rx in rxs: + n += len(rx) + return n + def test_ip_load_balance(self): """ IP Load-Balancing """ + fhc = VppEnum.vl_api_ip_flow_hash_config_t + af = VppEnum.vl_api_address_family_t + # # An array of packets that differ only in the destination port # @@ -1192,21 +1202,41 @@ class TestIPLoadBalance(VppTestCase): # be guaranteed. But with 64 different packets we do expect some # balancing. So instead just ensure there is traffic on each link. # - self.send_and_expect_load_balancing(self.pg0, port_ip_pkts, - [self.pg1, self.pg2]) + rx = self.send_and_expect_load_balancing(self.pg0, port_ip_pkts, + [self.pg1, self.pg2]) + n_ip_pg0 = len(rx[0]) self.send_and_expect_load_balancing(self.pg0, src_ip_pkts, [self.pg1, self.pg2]) self.send_and_expect_load_balancing(self.pg0, port_mpls_pkts, [self.pg1, self.pg2]) - self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts, - [self.pg1, self.pg2]) + rx = self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts, + [self.pg1, self.pg2]) + n_mpls_pg0 = len(rx[0]) + + # + # change the router ID and expect the distribution changes + # + self.vapi.set_ip_flow_hash_router_id(router_id=0x11111111) + + rx = self.send_and_expect_load_balancing(self.pg0, port_ip_pkts, + [self.pg1, self.pg2]) + self.assertNotEqual(n_ip_pg0, len(rx[0])) + + rx = self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts, + [self.pg1, self.pg2]) + self.assertNotEqual(n_mpls_pg0, len(rx[0])) # # change the flow hash config so it's only IP src,dst # - now only the stream with differing source address will # load-balance # - self.vapi.set_ip_flow_hash(vrf_id=0, src=1, dst=1, sport=0, dport=0) + self.vapi.set_ip_flow_hash_v2( + af=af.ADDRESS_IP4, + table_id=0, + flow_hash_config=(fhc.IP_API_FLOW_HASH_SRC_IP | + fhc.IP_API_FLOW_HASH_DST_IP | + fhc.IP_API_FLOW_HASH_PROTO)) self.send_and_expect_load_balancing(self.pg0, src_ip_pkts, [self.pg1, self.pg2]) @@ -1218,7 +1248,8 @@ class TestIPLoadBalance(VppTestCase): # # change the flow hash config back to defaults # - self.vapi.set_ip_flow_hash(vrf_id=0, src=1, dst=1, sport=1, dport=1) + self.vapi.set_ip_flow_hash(vrf_id=0, src=1, dst=1, + proto=1, sport=1, dport=1) # # Recursive prefixes @@ -1264,23 +1295,23 @@ class TestIPLoadBalance(VppTestCase): self.pg3, self.pg4]) # - # bring down pg1 expect LB to adjust to use only those that are pu + # bring down pg1 expect LB to adjust to use only those that are up # self.pg1.link_down() rx = self.send_and_expect_load_balancing(self.pg0, src_pkts, [self.pg2, self.pg3, self.pg4]) - self.assertEqual(len(src_pkts), len(rx)) + self.assertEqual(len(src_pkts), self.total_len(rx)) # - # bring down pg2 expect LB to adjust to use only those that are pu + # bring down pg2 expect LB to adjust to use only those that are up # self.pg2.link_down() rx = self.send_and_expect_load_balancing(self.pg0, src_pkts, [self.pg3, self.pg4]) - self.assertEqual(len(src_pkts), len(rx)) + self.assertEqual(len(src_pkts), self.total_len(rx)) # # bring the links back up - expect LB over all again @@ -1291,7 +1322,7 @@ class TestIPLoadBalance(VppTestCase): rx = self.send_and_expect_load_balancing(self.pg0, src_pkts, [self.pg1, self.pg2, self.pg3, self.pg4]) - self.assertEqual(len(src_pkts), len(rx)) + self.assertEqual(len(src_pkts), self.total_len(rx)) # # The same link-up/down but this time admin state @@ -1300,7 +1331,7 @@ class TestIPLoadBalance(VppTestCase): self.pg2.admin_down() rx = self.send_and_expect_load_balancing(self.pg0, src_pkts, [self.pg3, self.pg4]) - self.assertEqual(len(src_pkts), len(rx)) + self.assertEqual(len(src_pkts), self.total_len(rx)) self.pg1.admin_up() self.pg2.admin_up() self.pg1.resolve_arp() @@ -1308,7 +1339,7 @@ class TestIPLoadBalance(VppTestCase): rx = self.send_and_expect_load_balancing(self.pg0, src_pkts, [self.pg1, self.pg2, self.pg3, self.pg4]) - self.assertEqual(len(src_pkts), len(rx)) + self.assertEqual(len(src_pkts), self.total_len(rx)) # # Recursive prefixes @@ -1366,7 +1397,7 @@ class TestIPLoadBalance(VppTestCase): rx = self.send_and_expect_load_balancing(self.pg0, port_pkts, [self.pg3, self.pg4]) - self.assertEqual(len(src_pkts), len(rx)) + self.assertEqual(len(src_pkts), self.total_len(rx)) class TestIPVlan0(VppTestCase): @@ -1418,20 +1449,10 @@ class TestIPVlan0(VppTestCase): self.send_and_expect(self.pg0, pkts, self.pg1) -class TestIPPunt(VppTestCase): - """ IPv4 Punt Police/Redirect """ - - @classmethod - def setUpClass(cls): - super(TestIPPunt, cls).setUpClass() - - @classmethod - def tearDownClass(cls): - super(TestIPPunt, cls).tearDownClass() - - def setUp(self): - super(TestIPPunt, self).setUp() +class IPPuntSetup(object): + """ Setup for IPv4 Punt Police/Redirect """ + def punt_setup(self): self.create_pg_interfaces(range(4)) for i in self.pg_interfaces: @@ -1439,15 +1460,6 @@ class TestIPPunt(VppTestCase): i.config_ip4() i.resolve_arp() - def tearDown(self): - super(TestIPPunt, self).tearDown() - for i in self.pg_interfaces: - i.unconfig_ip4() - i.admin_down() - - def test_ip_punt(self): - """ IP punt police and redirect """ - # use UDP packet that have a port we need to explicitly # register to get punted. pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4 @@ -1466,13 +1478,33 @@ class TestIPPunt(VppTestCase): self.vapi.set_punt(is_add=1, punt=punt_udp) - p = (Ether(src=self.pg0.remote_mac, - dst=self.pg0.local_mac) / - IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + self.pkt = (Ether(src=self.pg0.remote_mac, + dst=self.pg0.local_mac) / + IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) / + UDP(sport=1234, dport=1234) / + Raw(b'\xa5' * 100)) + + def punt_teardown(self): + for i in self.pg_interfaces: + i.unconfig_ip4() + i.admin_down() + + +class TestIPPunt(IPPuntSetup, VppTestCase): + """ IPv4 Punt Police/Redirect """ - pkts = p * 1025 + def setUp(self): + super(TestIPPunt, self).setUp() + super(TestIPPunt, self).punt_setup() + + def tearDown(self): + super(TestIPPunt, self).punt_teardown() + super(TestIPPunt, self).tearDown() + + def test_ip_punt(self): + """ IP punt police and redirect """ + + pkts = self.pkt * 1025 # # Configure a punt redirect via pg1. @@ -1502,6 +1534,14 @@ class TestIPPunt(VppTestCase): # but not equal to the number sent, since some were policed # rx = self.pg1._get_capture(1) + + stats = policer.get_stats() + + # Single rate policer - expect conform, violate but no exceed + self.assertGreater(stats['conform_packets'], 0) + self.assertEqual(stats['exceed_packets'], 0) + self.assertGreater(stats['violate_packets'], 0) + self.assertGreater(len(rx), 0) self.assertLess(len(rx), len(pkts)) @@ -1563,6 +1603,74 @@ class TestIPPunt(VppTestCase): self.assertEqual(str(punts[2].punt.nh), '0.0.0.0') +class TestIPPuntHandoff(IPPuntSetup, VppTestCase): + """ IPv4 Punt Policer thread handoff """ + worker_config = "workers 2" + + def setUp(self): + super(TestIPPuntHandoff, self).setUp() + super(TestIPPuntHandoff, self).punt_setup() + + def tearDown(self): + super(TestIPPuntHandoff, self).punt_teardown() + super(TestIPPuntHandoff, self).tearDown() + + def test_ip_punt_policer_handoff(self): + """ IP4 punt policer thread handoff """ + pkts = self.pkt * NUM_PKTS + + # + # Configure a punt redirect via pg1. + # + nh_addr = self.pg1.remote_ip4 + ip_punt_redirect = VppIpPuntRedirect(self, self.pg0.sw_if_index, + self.pg1.sw_if_index, nh_addr) + ip_punt_redirect.add_vpp_config() + + action_tx = PolicerAction( + VppEnum.vl_api_sse2_qos_action_type_t.SSE2_QOS_ACTION_API_TRANSMIT, + 0) + # + # This policer drops no packets, we are just + # testing that they get to the right thread. + # + policer = VppPolicer(self, "ip4-punt", 400, 0, 10, 0, 1, + 0, 0, False, action_tx, action_tx, action_tx) + policer.add_vpp_config() + ip_punt_policer = VppIpPuntPolicer(self, policer.policer_index) + ip_punt_policer.add_vpp_config() + + for worker in [0, 1]: + self.send_and_expect(self.pg0, pkts, self.pg1, worker=worker) + if worker == 0: + self.logger.debug(self.vapi.cli("show trace max 100")) + + # Combined stats, all threads + stats = policer.get_stats() + + # Single rate policer - expect conform, violate but no exceed + self.assertGreater(stats['conform_packets'], 0) + self.assertEqual(stats['exceed_packets'], 0) + self.assertGreater(stats['violate_packets'], 0) + + # Worker 0, should have done all the policing + stats0 = policer.get_stats(worker=0) + self.assertEqual(stats, stats0) + + # Worker 1, should have handed everything off + stats1 = policer.get_stats(worker=1) + self.assertEqual(stats1['conform_packets'], 0) + self.assertEqual(stats1['exceed_packets'], 0) + self.assertEqual(stats1['violate_packets'], 0) + + # + # Clean up + # + ip_punt_policer.remove_vpp_config() + policer.remove_vpp_config() + ip_punt_redirect.remove_vpp_config() + + class TestIPDeag(VppTestCase): """ IPv4 Deaggregate Routes """ @@ -1988,6 +2096,7 @@ class TestIPLPM(VppTestCase): rx = self.send_and_expect(self.pg0, p_24 * NUM_PKTS, self.pg1) +@tag_fixme_vpp_workers class TestIPv4Frag(VppTestCase): """ IPv4 fragmentation """