nat: fix byte order on ipfix message fields
[vpp.git] / src / plugins / nat / test / test_nat44_ei.py
index dcd7f46..4160ea2 100644 (file)
@@ -9,7 +9,6 @@ from io import BytesIO
 from time import sleep
 
 import scapy.compat
-from framework import tag_fixme_vpp_workers
 from framework import VppTestCase, VppTestRunner
 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
@@ -624,17 +623,17 @@ class MethodHolder(VppTestCase):
         # natEvent
         self.assertEqual(scapy.compat.orb(record[230]), 13)
         # natQuotaExceededEvent
-        self.assertEqual(struct.pack("I", 1), record[466])
+        self.assertEqual(struct.pack("!I", 1), record[466])
         # maxSessionEntries
-        self.assertEqual(struct.pack("I", limit), record[471])
+        self.assertEqual(struct.pack("!I", limit), record[471])
 
     def verify_no_nat44_user(self):
         """ Verify that there is no NAT44EI user """
         users = self.vapi.nat44_ei_user_dump()
         self.assertEqual(len(users), 0)
-        users = self.statistics.get_counter('/nat44-ei/total-users')
+        users = self.statistics['/nat44-ei/total-users']
         self.assertEqual(users[0][0], 0)
-        sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
+        sessions = self.statistics['/nat44-ei/total-sessions']
         self.assertEqual(sessions[0][0], 0)
 
     def verify_syslog_apmap(self, data, is_add=True):
@@ -852,7 +851,16 @@ class MethodHolder(VppTestCase):
             self.assertEqual(data, p[Raw].load)
 
 
-@tag_fixme_vpp_workers
+def get_nat44_ei_in2out_worker_index(ip, vpp_worker_count):
+    if 0 == vpp_worker_count:
+        return 0
+    numeric = socket.inet_aton(ip)
+    numeric = struct.unpack("!L", numeric)[0]
+    numeric = socket.htonl(numeric)
+    h = numeric + (numeric >> 8) + (numeric >> 16) + (numeric >> 24)
+    return 1 + h % vpp_worker_count
+
+
 class TestNAT44EI(MethodHolder):
     """ NAT44EI Test Cases """
 
@@ -963,14 +971,14 @@ class TestNAT44EI(MethodHolder):
         capture = self.pg1.get_capture(len(pkts))
         self.verify_capture_out(capture)
 
-        sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
-        self.assertTrue(sessions[0][0] > 0)
+        sessions = self.statistics['/nat44-ei/total-sessions']
+        self.assertGreater(sessions[:, 0].sum(), 0, "Session count invalid")
         self.logger.info("sessions before clearing: %s" % sessions[0][0])
 
         self.vapi.cli("clear nat44 ei sessions")
 
-        sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
-        self.assertEqual(sessions[0][0], 0)
+        sessions = self.statistics['/nat44-ei/total-sessions']
+        self.assertEqual(sessions[:, 0].sum(), 0, "Session count invalid")
         self.logger.info("sessions after clearing: %s" % sessions[0][0])
 
     def test_dynamic(self):
@@ -985,12 +993,10 @@ class TestNAT44EI(MethodHolder):
             is_add=1)
 
         # in2out
-        tcpn = self.statistics.get_counter('/nat44-ei/in2out/slowpath/tcp')[0]
-        udpn = self.statistics.get_counter('/nat44-ei/in2out/slowpath/udp')[0]
-        icmpn = self.statistics.get_counter(
-            '/nat44-ei/in2out/slowpath/icmp')[0]
-        drops = self.statistics.get_counter(
-            '/nat44-ei/in2out/slowpath/drops')[0]
+        tcpn = self.statistics['/nat44-ei/in2out/slowpath/tcp']
+        udpn = self.statistics['/nat44-ei/in2out/slowpath/udp']
+        icmpn = self.statistics['/nat44-ei/in2out/slowpath/icmp']
+        drops = self.statistics['/nat44-ei/in2out/slowpath/drops']
 
         pkts = self.create_stream_in(self.pg0, self.pg1)
         self.pg0.add_stream(pkts)
@@ -1000,22 +1006,20 @@ class TestNAT44EI(MethodHolder):
         self.verify_capture_out(capture)
 
         if_idx = self.pg0.sw_if_index
-        cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/tcp')[0]
-        self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
-        cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/udp')[0]
-        self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
-        cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/icmp')[0]
-        self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
-        cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/drops')[0]
-        self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
+        cnt = self.statistics['/nat44-ei/in2out/slowpath/tcp']
+        self.assertEqual(cnt[:, if_idx].sum() - tcpn[:, if_idx].sum(), 2)
+        cnt = self.statistics['/nat44-ei/in2out/slowpath/udp']
+        self.assertEqual(cnt[:, if_idx].sum() - udpn[:, if_idx].sum(), 1)
+        cnt = self.statistics['/nat44-ei/in2out/slowpath/icmp']
+        self.assertEqual(cnt[:, if_idx].sum() - icmpn[:, if_idx].sum(), 1)
+        cnt = self.statistics['/nat44-ei/in2out/slowpath/drops']
+        self.assertEqual(cnt[:, if_idx].sum() - drops[:, if_idx].sum(), 0)
 
         # out2in
-        tcpn = self.statistics.get_counter('/nat44-ei/out2in/slowpath/tcp')[0]
-        udpn = self.statistics.get_counter('/nat44-ei/out2in/slowpath/udp')[0]
-        icmpn = self.statistics.get_counter(
-            '/nat44-ei/out2in/slowpath/icmp')[0]
-        drops = self.statistics.get_counter(
-            '/nat44-ei/out2in/slowpath/drops')[0]
+        tcpn = self.statistics['/nat44-ei/out2in/slowpath/tcp']
+        udpn = self.statistics['/nat44-ei/out2in/slowpath/udp']
+        icmpn = self.statistics['/nat44-ei/out2in/slowpath/icmp']
+        drops = self.statistics['/nat44-ei/out2in/slowpath/drops']
 
         pkts = self.create_stream_out(self.pg1)
         self.pg1.add_stream(pkts)
@@ -1025,19 +1029,19 @@ class TestNAT44EI(MethodHolder):
         self.verify_capture_in(capture, self.pg0)
 
         if_idx = self.pg1.sw_if_index
-        cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/tcp')[0]
-        self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
-        cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/udp')[0]
-        self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
-        cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/icmp')[0]
-        self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
-        cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/drops')[0]
-        self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
-
-        users = self.statistics.get_counter('/nat44-ei/total-users')
-        self.assertEqual(users[0][0], 1)
-        sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
-        self.assertEqual(sessions[0][0], 3)
+        cnt = self.statistics['/nat44-ei/out2in/slowpath/tcp']
+        self.assertEqual(cnt[:, if_idx].sum() - tcpn[:, if_idx].sum(), 2)
+        cnt = self.statistics['/nat44-ei/out2in/slowpath/udp']
+        self.assertEqual(cnt[:, if_idx].sum() - udpn[:, if_idx].sum(), 1)
+        cnt = self.statistics['/nat44-ei/out2in/slowpath/icmp']
+        self.assertEqual(cnt[:, if_idx].sum() - icmpn[:, if_idx].sum(), 1)
+        cnt = self.statistics['/nat44-ei/out2in/slowpath/drops']
+        self.assertEqual(cnt[:, if_idx].sum() - drops[:, if_idx].sum(), 0)
+
+        users = self.statistics['/nat44-ei/total-users']
+        self.assertEqual(users[:, 0].sum(), 1)
+        sessions = self.statistics['/nat44-ei/total-sessions']
+        self.assertEqual(sessions[:, 0].sum(), 3)
 
     def test_dynamic_icmp_errors_in2out_ttl_1(self):
         """ NAT44EI handling of client packets with TTL=1 """
@@ -1828,7 +1832,7 @@ class TestNAT44EI(MethodHolder):
                                       server_in_port, server_out_port,
                                       proto=IP_PROTOS.tcp)
 
-        cnt = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+        cnt = self.statistics['/nat44-ei/hairpinning']
         # send packet from host to server
         p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
              IP(src=host.ip4, dst=self.nat_addr) /
@@ -1851,9 +1855,9 @@ class TestNAT44EI(MethodHolder):
             self.logger.error(ppp("Unexpected or invalid packet:", p))
             raise
 
-        after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+        after = self.statistics['/nat44-ei/hairpinning']
         if_idx = self.pg0.sw_if_index
-        self.assertEqual(after[if_idx] - cnt[if_idx], 1)
+        self.assertEqual(after[:, if_idx].sum() - cnt[:, if_idx].sum(), 1)
 
         # send reply from server to host
         p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
@@ -1876,9 +1880,10 @@ class TestNAT44EI(MethodHolder):
             self.logger.error(ppp("Unexpected or invalid packet:", p))
             raise
 
-        after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+        after = self.statistics['/nat44-ei/hairpinning']
         if_idx = self.pg0.sw_if_index
-        self.assertEqual(after[if_idx] - cnt[if_idx], 2)
+        self.assertEqual(after[:, if_idx].sum() - cnt[:, if_idx].sum(),
+                         2+(1 if self.vpp_worker_count > 0 else 0))
 
     def test_hairpinning2(self):
         """ NAT44EI hairpinning - 1:1 NAT"""
@@ -2086,7 +2091,7 @@ class TestNAT44EI(MethodHolder):
         self.pg_start()
         # Here VPP used to crash due to an infinite loop
 
-        cnt = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+        cnt = self.statistics['/nat44-ei/hairpinning']
         # send packet from host to server
         p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
              IP(src=host.ip4, dst=self.nat_addr) /
@@ -2109,9 +2114,9 @@ class TestNAT44EI(MethodHolder):
             self.logger.error(ppp("Unexpected or invalid packet:", p))
             raise
 
-        after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+        after = self.statistics['/nat44-ei/hairpinning']
         if_idx = self.pg0.sw_if_index
-        self.assertEqual(after[if_idx] - cnt[if_idx], 1)
+        self.assertEqual(after[:, if_idx].sum() - cnt[:, if_idx].sum(), 1)
 
         # send reply from server to host
         p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
@@ -2134,9 +2139,10 @@ class TestNAT44EI(MethodHolder):
             self.logger.error(ppp("Unexpected or invalid packet:", p))
             raise
 
-        after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+        after = self.statistics['/nat44-ei/hairpinning']
         if_idx = self.pg0.sw_if_index
-        self.assertEqual(after[if_idx] - cnt[if_idx], 2)
+        self.assertEqual(after[:, if_idx].sum() - cnt[:, if_idx].sum(),
+                         2+(1 if self.vpp_worker_count > 0 else 0))
 
     def test_interface_addr(self):
         """ NAT44EI acquire addresses from interface """
@@ -2368,7 +2374,8 @@ class TestNAT44EI(MethodHolder):
             sw_if_index=self.pg1.sw_if_index,
             is_add=1)
 
-        max_sessions = self.max_translations
+        max_sessions_per_thread = self.max_translations
+        max_sessions = max(1, self.vpp_worker_count) * max_sessions_per_thread
 
         pkts = []
         for i in range(0, max_sessions):
@@ -2416,7 +2423,7 @@ class TestNAT44EI(MethodHolder):
         for p in capture:
             if p.haslayer(Data):
                 data = ipfix.decode_data_set(p.getlayer(Set))
-                self.verify_ipfix_max_sessions(data, max_sessions)
+                self.verify_ipfix_max_sessions(data, max_sessions_per_thread)
 
     def test_syslog_apmap(self):
         """ NAT44EI syslog address and port mapping creation and deletion """
@@ -3044,11 +3051,14 @@ class TestNAT44EI(MethodHolder):
             self.logger.error(ppp("Unexpected or invalid packet:", p))
             raise
 
-        err = self.statistics.get_err_counter(
-            '/err/nat44-ei-classify/next in2out')
+        if self.vpp_worker_count > 1:
+            node = "nat44-ei-handoff-classify"
+        else:
+            node = "nat44-ei-classify"
+
+        err = self.statistics.get_err_counter('/err/%s/next in2out' % node)
         self.assertEqual(err, 1)
-        err = self.statistics.get_err_counter(
-            '/err/nat44-ei-classify/next out2in')
+        err = self.statistics.get_err_counter('/err/%s/next out2in' % node)
         self.assertEqual(err, 1)
 
     def test_del_session(self):
@@ -3397,8 +3407,8 @@ class TestNAT44EI(MethodHolder):
         self.verify_capture_out(capture)
         # active send HA events
         self.vapi.nat44_ei_ha_flush()
-        stats = self.statistics.get_counter('/nat44-ei/ha/add-event-send')
-        self.assertEqual(stats[0][0], 3)
+        stats = self.statistics['/nat44-ei/ha/add-event-send']
+        self.assertEqual(stats[:, 0].sum(), 3)
         capture = self.pg3.get_capture(1)
         p = capture[0]
         self.assert_packet_checksums_valid(p)
@@ -3415,7 +3425,7 @@ class TestNAT44EI(MethodHolder):
             self.assertEqual(udp.sport, 12345)
             self.assertEqual(udp.dport, 12346)
             self.assertEqual(hanat.version, 1)
-            self.assertEqual(hanat.thread_index, 0)
+            self.assertEqual(hanat.thread_index, 0)
             self.assertEqual(hanat.count, 3)
             seq = hanat.sequence_number
             for event in hanat.events:
@@ -3428,11 +3438,12 @@ class TestNAT44EI(MethodHolder):
         ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
                IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
                UDP(sport=12346, dport=12345) /
-               HANATStateSync(sequence_number=seq, flags='ACK'))
+               HANATStateSync(sequence_number=seq, flags='ACK',
+                              thread_index=hanat.thread_index))
         self.pg3.add_stream(ack)
         self.pg_start()
-        stats = self.statistics.get_counter('/nat44-ei/ha/ack-recv')
-        self.assertEqual(stats[0][0], 1)
+        stats = self.statistics['/nat44-ei/ha/ack-recv']
+        self.assertEqual(stats[:, 0].sum(), 1)
 
         # delete one session
         self.pg_enable_capture(self.pg_interfaces)
@@ -3440,8 +3451,8 @@ class TestNAT44EI(MethodHolder):
             address=self.pg0.remote_ip4, port=self.tcp_port_in,
             protocol=IP_PROTOS.tcp, flags=self.config_flags.NAT44_EI_IF_INSIDE)
         self.vapi.nat44_ei_ha_flush()
-        stats = self.statistics.get_counter('/nat44-ei/ha/del-event-send')
-        self.assertEqual(stats[0][0], 1)
+        stats = self.statistics['/nat44-ei/ha/del-event-send']
+        self.assertEqual(stats[:, 0].sum(), 1)
         capture = self.pg3.get_capture(1)
         p = capture[0]
         try:
@@ -3455,10 +3466,10 @@ class TestNAT44EI(MethodHolder):
         # do not send ACK, active retry send HA event again
         self.pg_enable_capture(self.pg_interfaces)
         sleep(12)
-        stats = self.statistics.get_counter('/nat44-ei/ha/retry-count')
-        self.assertEqual(stats[0][0], 3)
-        stats = self.statistics.get_counter('/nat44-ei/ha/missed-count')
-        self.assertEqual(stats[0][0], 1)
+        stats = self.statistics['/nat44-ei/ha/retry-count']
+        self.assertEqual(stats[:, 0].sum(), 3)
+        stats = self.statistics['/nat44-ei/ha/missed-count']
+        self.assertEqual(stats[:, 0].sum(), 1)
         capture = self.pg3.get_capture(3)
         for packet in capture:
             self.assertEqual(packet, p)
@@ -3470,8 +3481,8 @@ class TestNAT44EI(MethodHolder):
         self.pg_start()
         self.pg0.get_capture(2)
         self.vapi.nat44_ei_ha_flush()
-        stats = self.statistics.get_counter('/nat44-ei/ha/refresh-event-send')
-        self.assertEqual(stats[0][0], 2)
+        stats = self.statistics['/nat44-ei/ha/refresh-event-send']
+        self.assertEqual(stats[:, 0].sum(), 2)
         capture = self.pg3.get_capture(1)
         p = capture[0]
         self.assert_packet_checksums_valid(p)
@@ -3497,14 +3508,16 @@ class TestNAT44EI(MethodHolder):
                 self.assertEqual(event.total_pkts, 2)
                 self.assertGreater(event.total_bytes, 0)
 
+        stats = self.statistics['/nat44-ei/ha/ack-recv']
         ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
                IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
                UDP(sport=12346, dport=12345) /
-               HANATStateSync(sequence_number=seq, flags='ACK'))
+               HANATStateSync(sequence_number=seq, flags='ACK',
+                              thread_index=hanat.thread_index))
         self.pg3.add_stream(ack)
         self.pg_start()
-        stats = self.statistics.get_counter('/nat44-ei/ha/ack-recv')
-        self.assertEqual(stats[0][0], 2)
+        stats = self.statistics['/nat44-ei/ha/ack-recv']
+        self.assertEqual(stats[:, 0].sum(), 2)
 
     def test_ha_recv(self):
         """ NAT44EI Receive HA session synchronization events (passive) """
@@ -3520,8 +3533,23 @@ class TestNAT44EI(MethodHolder):
                                            port=12345, path_mtu=512)
         bind_layers(UDP, HANATStateSync, sport=12345)
 
-        self.tcp_port_out = random.randint(1025, 65535)
-        self.udp_port_out = random.randint(1025, 65535)
+        # this is a bit tricky - HA dictates thread index due to how it's
+        # designed, but once we use HA to create a session, we also want
+        # to pass a packet through said session. so the session must end
+        # up on the correct thread from both directions - in2out (based on
+        # IP address) and out2in (based on outside port)
+
+        # first choose a thread index which is correct for IP
+        thread_index = get_nat44_ei_in2out_worker_index(self.pg0.remote_ip4,
+                                                        self.vpp_worker_count)
+
+        # now pick a port which is correct for given thread
+        port_per_thread = int((0xffff-1024) / max(1, self.vpp_worker_count))
+        self.tcp_port_out = 1024 + random.randint(1, port_per_thread)
+        self.udp_port_out = 1024 + random.randint(1, port_per_thread)
+        if self.vpp_worker_count > 0:
+            self.tcp_port_out += port_per_thread * (thread_index - 1)
+            self.udp_port_out += port_per_thread * (thread_index - 1)
 
         # send HA session add events to failover/passive
         p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
@@ -3541,7 +3569,8 @@ class TestNAT44EI(MethodHolder):
                        eh_addr=self.pg1.remote_ip4,
                        ehn_addr=self.pg1.remote_ip4,
                        eh_port=self.udp_external_port,
-                       ehn_port=self.udp_external_port, fib_index=0)]))
+                       ehn_port=self.udp_external_port, fib_index=0)],
+                 thread_index=thread_index))
 
         self.pg3.add_stream(p)
         self.pg_enable_capture(self.pg_interfaces)
@@ -3558,15 +3587,15 @@ class TestNAT44EI(MethodHolder):
             self.assertEqual(hanat.sequence_number, 1)
             self.assertEqual(hanat.flags, 'ACK')
             self.assertEqual(hanat.version, 1)
-            self.assertEqual(hanat.thread_index, 0)
-        stats = self.statistics.get_counter('/nat44-ei/ha/ack-send')
-        self.assertEqual(stats[0][0], 1)
-        stats = self.statistics.get_counter('/nat44-ei/ha/add-event-recv')
-        self.assertEqual(stats[0][0], 2)
-        users = self.statistics.get_counter('/nat44-ei/total-users')
-        self.assertEqual(users[0][0], 1)
-        sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
-        self.assertEqual(sessions[0][0], 2)
+            self.assertEqual(hanat.thread_index, thread_index)
+        stats = self.statistics['/nat44-ei/ha/ack-send']
+        self.assertEqual(stats[:, 0].sum(), 1)
+        stats = self.statistics['/nat44-ei/ha/add-event-recv']
+        self.assertEqual(stats[:, 0].sum(), 2)
+        users = self.statistics['/nat44-ei/total-users']
+        self.assertEqual(users[:, 0].sum(), 1)
+        sessions = self.statistics['/nat44-ei/total-sessions']
+        self.assertEqual(sessions[:, 0].sum(), 2)
         users = self.vapi.nat44_ei_user_dump()
         self.assertEqual(len(users), 1)
         self.assertEqual(str(users[0].ip_address),
@@ -3597,7 +3626,8 @@ class TestNAT44EI(MethodHolder):
                        eh_addr=self.pg1.remote_ip4,
                        ehn_addr=self.pg1.remote_ip4,
                        eh_port=self.udp_external_port,
-                       ehn_port=self.udp_external_port, fib_index=0)]))
+                       ehn_port=self.udp_external_port, fib_index=0)],
+                 thread_index=thread_index))
 
         self.pg3.add_stream(p)
         self.pg_enable_capture(self.pg_interfaces)
@@ -3622,8 +3652,8 @@ class TestNAT44EI(MethodHolder):
         sessions = self.vapi.nat44_ei_user_session_dump(users[0].ip_address,
                                                         users[0].vrf_id)
         self.assertEqual(len(sessions), 1)
-        stats = self.statistics.get_counter('/nat44-ei/ha/del-event-recv')
-        self.assertEqual(stats[0][0], 1)
+        stats = self.statistics['/nat44-ei/ha/del-event-recv']
+        self.assertEqual(stats[:, 0].sum(), 1)
 
         stats = self.statistics.get_err_counter(
             '/err/nat44-ei-ha/pkts-processed')
@@ -3641,7 +3671,8 @@ class TestNAT44EI(MethodHolder):
                        ehn_addr=self.pg1.remote_ip4,
                        eh_port=self.tcp_external_port,
                        ehn_port=self.tcp_external_port, fib_index=0,
-                       total_bytes=1024, total_pkts=2)]))
+                       total_bytes=1024, total_pkts=2)],
+                 thread_index=thread_index))
         self.pg3.add_stream(p)
         self.pg_enable_capture(self.pg_interfaces)
         self.pg_start()
@@ -3667,9 +3698,8 @@ class TestNAT44EI(MethodHolder):
         session = sessions[0]
         self.assertEqual(session.total_bytes, 1024)
         self.assertEqual(session.total_pkts, 2)
-        stats = self.statistics.get_counter(
-            '/nat44-ei/ha/refresh-event-recv')
-        self.assertEqual(stats[0][0], 1)
+        stats = self.statistics['/nat44-ei/ha/refresh-event-recv']
+        self.assertEqual(stats[:, 0].sum(), 1)
 
         stats = self.statistics.get_err_counter(
             '/err/nat44-ei-ha/pkts-processed')
@@ -3746,22 +3776,35 @@ class TestNAT44EI(MethodHolder):
 
         pkts = []
         for i in range(x):
+            info = self.create_packet_info(self.pg0, self.pg1)
+            payload = self.info_to_payload(info)
             p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                  IP(src=self.pg0.remote_hosts[i].ip4,
                      dst=self.pg1.remote_ip4) /
-                 UDP(sport=7000+i, dport=80+i))
+                 UDP(sport=7000+i, dport=8000+i) /
+                 Raw(payload))
+            info.data = p
             pkts.append(p)
 
         self.pg0.add_stream(pkts)
         self.pg_enable_capture(self.pg_interfaces)
         self.pg_start()
         recvd = self.pg1.get_capture(len(pkts))
-        for (p_sent, p_recvd) in zip(pkts, recvd):
+        for p_recvd in recvd:
+            payload_info = self.payload_to_info(p_recvd[Raw])
+            packet_index = payload_info.index
+            info = self._packet_infos[packet_index]
+            self.assertTrue(info is not None)
+            self.assertEqual(packet_index, info.index)
+            p_sent = info.data
             packed = socket.inet_aton(p_sent[IP].src)
             numeric = struct.unpack("!L", packed)[0]
             numeric = socket.htonl(numeric)
             a = nat_addresses[(numeric-1) % len(nat_addresses)]
-            self.assertEqual(a, p_recvd[IP].src, "Packet not translated")
+            self.assertEqual(
+                a, p_recvd[IP].src,
+                "Invalid packet (src IP %s translated to %s, but expected %s)"
+                % (p_sent[IP].src, p_recvd[IP].src, a))
 
 
 class TestNAT44Out2InDPO(MethodHolder):
@@ -3895,9 +3938,7 @@ class TestNAT44Out2InDPO(MethodHolder):
 
 class TestNAT44EIMW(MethodHolder):
     """ NAT44EI Test Cases (multiple workers) """
-
-    worker_config = "workers %d" % 2
-
+    vpp_worker_count = 2
     max_translations = 10240
     max_users = 10240
 
@@ -4010,7 +4051,7 @@ class TestNAT44EIMW(MethodHolder):
                                       server_in_port, server_out_port,
                                       proto=IP_PROTOS.tcp)
 
-        cnt = self.statistics.get_counter('/nat44-ei/hairpinning')
+        cnt = self.statistics['/nat44-ei/hairpinning']
         # send packet from host to server
         p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
              IP(src=host.ip4, dst=self.nat_addr) /
@@ -4033,7 +4074,7 @@ class TestNAT44EIMW(MethodHolder):
             self.logger.error(ppp("Unexpected or invalid packet:", p))
             raise
 
-        after = self.statistics.get_counter('/nat44-ei/hairpinning')
+        after = self.statistics['/nat44-ei/hairpinning']
 
         if_idx = self.pg0.sw_if_index
         self.assertEqual(after[worker_2][if_idx] - cnt[worker_1][if_idx], 1)
@@ -4059,7 +4100,7 @@ class TestNAT44EIMW(MethodHolder):
             self.logger.error(ppp("Unexpected or invalid packet:", p))
             raise
 
-        after = self.statistics.get_counter('/nat44-ei/hairpinning')
+        after = self.statistics['/nat44-ei/hairpinning']
         if_idx = self.pg0.sw_if_index
         self.assertEqual(after[worker_1][if_idx] - cnt[worker_1][if_idx], 1)
         self.assertEqual(after[worker_2][if_idx] - cnt[worker_2][if_idx], 2)