test suite reviews and discussions
 help / color / mirror / Atom feed
* [dts] [PATCH 0/3] packet integrity check in sample applications
@ 2015-10-22  1:02 Yong Liu
  2015-10-22  1:02 ` [dts] [PATCH 1/3] framework: support packet objects transmit and analysis Yong Liu
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Yong Liu @ 2015-10-22  1:02 UTC (permalink / raw)
  To: dts

From: Marvin Liu <yong.liu@intel.com>

Most sample applications only validated by few packets or performance data. 
This patch set will supply other test routine which check thousands of packets
sequence and content data. There's one sample in l2fwd suite, new case will
check received 2000 packets's content exactly the same as transmited packets.

Marvin Liu (3):
  framework: support packet objects transmit and analysis
  framework: add packet integrity verification funtion
  tests: add l2fwd sample forwarding integrity check test

 framework/packet.py      | 142 ++++++++++++++++++++++++++++++++++++++---------
 framework/tester.py      |  53 ++++++++++++++++++
 tests/TestSuite_l2fwd.py |  28 +++++++++-
 3 files changed, 196 insertions(+), 27 deletions(-)

-- 
1.9.3

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [dts] [PATCH 1/3] framework: support packet objects transmit and analysis
  2015-10-22  1:02 [dts] [PATCH 0/3] packet integrity check in sample applications Yong Liu
@ 2015-10-22  1:02 ` Yong Liu
  2015-10-22  1:02 ` [dts] [PATCH 2/3] framework: add packet integrity verification funtion Yong Liu
  2015-10-22  1:02 ` [dts] [PATCH 3/3] tests: add l2fwd sample forwarding integrity check test Yong Liu
  2 siblings, 0 replies; 4+ messages in thread
From: Yong Liu @ 2015-10-22  1:02 UTC (permalink / raw)
  To: dts

From: Marvin Liu <yong.liu@intel.com>

Add new functions in packet module which support strip l2 and l4 content.
Implemented packet objects transmit and save functions. Also implemented
missed tcp protocal configuration function.

Signed-off-by: Marvin Liu <yong.liu@intel.com>

diff --git a/framework/packet.py b/framework/packet.py
index 0a3f330..238b94f 100755
--- a/framework/packet.py
+++ b/framework/packet.py
@@ -77,7 +77,7 @@ PACKETGEN = "scapy"
 LayersTypes = {
     "L2": ['ether', 'dot1q', '1588', 'arp', 'lldp'],
     # ipv4_ext_unknown, ipv6_ext_unknown
-    "L3": ['ipv4','ipv4ihl', 'ipv6', 'ipv4_ext', 'ipv6_ext','ipv6_ext2', 'ipv6_frag'],
+    "L3": ['ipv4', 'ipv4ihl', 'ipv6', 'ipv4_ext', 'ipv6_ext', 'ipv6_ext2', 'ipv6_frag'],
     "L4": ['tcp', 'udp', 'frag', 'sctp', 'icmp', 'nofrag'],
     "TUNNEL": ['ip', 'gre', 'vxlan', 'nvgre', 'geneve', 'grenat'],
     "INNER L2": ['inner_mac', 'inner_mac&vlan'],
@@ -105,8 +105,8 @@ class scapy(object):
         'ipv4ihl': IP(ihl=10),
         'ipv4_ext': IP(frag=5),
         'ipv6': IPv6(src="::1"),
-        'ipv6_ext': IPv6(src="::1", nh=43)/IPv6ExtHdrRouting(),
-        'ipv6_ext2': IPv6()/IPv6ExtHdrRouting(),
+        'ipv6_ext': IPv6(src="::1", nh=43) / IPv6ExtHdrRouting(),
+        'ipv6_ext2': IPv6() / IPv6ExtHdrRouting(),
         'udp': UDP(),
         'tcp': TCP(),
         'sctp': SCTP(),
@@ -127,13 +127,13 @@ class scapy(object):
         'inner_sctp': SCTP(),
         'inner_icmp': ICMP(),
 
-        'lldp': LLDP()/LLDPManagementAddress(),
+        'lldp': LLDP() / LLDPManagementAddress(),
         'ip_frag': IP(frag=5),
-        'ipv6_frag': IPv6(src="::1")/IPv6ExtHdrFragment(),
-        'ip_in_ip': IP()/IP(),
-        'ip_in_ip_frag': IP()/IP(frag=5),
-        'ipv6_in_ip': IP()/IPv6(src="::1"),
-        'ipv6_frag_in_ip': IP()/IPv6(src="::1", nh=44)/IPv6ExtHdrFragment(),
+        'ipv6_frag': IPv6(src="::1") / IPv6ExtHdrFragment(),
+        'ip_in_ip': IP() / IP(),
+        'ip_in_ip_frag': IP() / IP(frag=5),
+        'ipv6_in_ip': IP() / IPv6(src="::1"),
+        'ipv6_frag_in_ip': IP() / IPv6(src="::1", nh=44) / IPv6ExtHdrFragment(),
         'nvgre': NVGRE(),
         'geneve': "Not Implement",
     }
@@ -175,6 +175,32 @@ class scapy(object):
             value = int(str(self.pkt[Dot1Q].vlan))
         return value
 
+    def strip_layer2(self, element):
+        value = None
+        layer = self.pkt.getlayer(0)
+        if layer is None:
+            return None
+
+        if element == 'src':
+            value = layer.src
+        elif element == 'dst':
+            value = layer.dst
+
+        return value
+
+    def strip_layer4(self, element):
+        value = None
+        layer = self.pkt.getlayer(2)
+        if layer is None:
+            return None
+
+        if element == 'src':
+            value = layer.sport
+        elif element == 'dst':
+            valude = layer.dport
+
+        return value
+
     def ipv4(self, frag=0, src="127.0.0.1", proto=None, tos=0, dst="127.0.0.1", chksum=None, len=None, version=4, flags=None, ihl=None, ttl=64, id=1, options=None):
         self.pkt[IP].frag = frag
         self.pkt[IP].src = src
@@ -224,6 +250,14 @@ class scapy(object):
         self.pkt[IPv6][Ether][IPv6].src = src
         self.pkt[IPv6][Ether][IPv6].dst = dst
 
+    def tcp(self, src=53, dst=53, len=None, chksum=None):
+        self.pkt[TCP].sport = src
+        self.pkt[TCP].dport = dst
+        if len is not None:
+            self.pkt[TCP].len = len
+        if chksum is not None:
+            self.pkt[TCP].chksum = chksum
+
     def udp(self, src=53, dst=53, len=None, chksum=None):
         self.pkt[UDP].sport = src
         self.pkt[UDP].dport = dst
@@ -277,6 +311,7 @@ class scapy(object):
 
 
 class Packet(object):
+
     """
     Module for config/create packet
     Based on scapy module
@@ -323,7 +358,7 @@ class Packet(object):
                 self.pkt_len = 128
         else:
             self._load_pkt_layers()
-            
+
         if 'pkt_len' in self.pkt_opts.keys():
             self.pkt_len = self.pkt_opts['pkt_len']
 
@@ -340,19 +375,14 @@ class Packet(object):
         else:
             self.pktgen = scapy()
 
-    def send_pkt(self, crb=None, tx_port='', auto_cfg=True):
-        if tx_port == '':
-            print "Invalid Tx interface"
-            return
-
-        self.tx_port = tx_port
+        self._load_assign_layers()
 
+    def _load_assign_layers(self):
         # assign layer
         self.assign_layers()
 
         # config special layer
-        if auto_cfg is True:
-            self.config_def_layers()
+        self.config_def_layers()
 
         # handle packet options
         payload_len = self.pkt_len - len(self.pktgen.pkt) - 4
@@ -371,6 +401,13 @@ class Packet(object):
             raw_confs['payload'] = payload
             self._config_layer_raw(raw_confs)
 
+    def send_pkt(self, crb=None, tx_port='', auto_cfg=True):
+        if tx_port == '':
+            print "Invalid Tx interface"
+            return
+
+        self.tx_port = tx_port
+
         # check with port type
         if 'ixia' in self.tx_port:
             print "Not Support Yet"
@@ -379,7 +416,8 @@ class Packet(object):
             self.pktgen.write_pcap(self.uni_name)
             crb.session.copy_file_to(self.uni_name)
             pcap_file = self.uni_name.split('/')[2]
-            self.pktgen.send_pcap_pkt(crb=crb, file=pcap_file, intf=self.tx_port)
+            self.pktgen.send_pcap_pkt(
+                crb=crb, file=pcap_file, intf=self.tx_port)
         else:
             self.pktgen.send_pkt(intf=self.tx_port)
 
@@ -440,7 +478,7 @@ class Packet(object):
         for layer in layers:
             if layer in name2type.keys():
                 self.pkt_layers.append(name2type[layer])
-        
+
     def config_def_layers(self):
         """
         Handel config packet layers by default
@@ -478,7 +516,7 @@ class Packet(object):
                 self.config_layer('raw', {'payload': ['00'] * 40})
             else:
                 self.config_layer('raw', {'payload': ['00'] * 18})
-        
+
     def config_layer(self, layer, config={}):
         """
         Configure packet assgined layer
@@ -522,6 +560,9 @@ class Packet(object):
     def _config_layer_udp(self, config):
         return self.pktgen.udp(**config)
 
+    def _config_layer_tcp(self, config):
+        return self.pktgen.tcp(**config)
+
     def _config_layer_raw(self, config):
         return self.pktgen.raw(**config)
 
@@ -540,6 +581,9 @@ class Packet(object):
     def strip_element_dot1q(self, element):
         return self.pktgen.strip_dot1q(element)
 
+    def strip_element_layer4(self, element):
+        return self.pktgen.strip_layer4(element)
+
 
 def increment_ip_address(self, addr):
     """
@@ -567,6 +611,27 @@ def increment_ipv6_address(self, addr):
     return ipv6
 
 
+def send_packets(intf, pkts=None, interval=0.01):
+    send_pkts = []
+    try:
+        for pkt in pkts:
+            send_pkts.append(pkt.pktgen.pkt)
+        sendp(send_pkts, iface=intf, inter=interval, verbose=False)
+    except:
+        pass
+
+
+def save_packets(pkts=None, filename=None):
+    save_pkts = []
+    try:
+        for pkt in pkts:
+            save_pkts.append(pkt.pktgen.pkt)
+        if filename:
+            wrpcap(filename, save_pkts)
+    except:
+        pass
+
+
 def sniff_packets(intf, count=0, timeout=5):
     """
     sniff all packets for certain port in certain seconds
@@ -584,6 +649,7 @@ def sniff_packets(intf, count=0, timeout=5):
     pipe = subprocess.Popen(args)
     index = str(time.time())
     SNIFF_PIDS[index] = (pipe, intf, timeout)
+    time.sleep(0.5)
     return index
 
 
@@ -605,7 +671,7 @@ def load_sniff_packets(index=''):
             pipe.kill()
 
         # wait pcap file ready
-        time.sleep(0.5)
+        time.sleep(1)
         try:
             cap_pkts = rdpcap("/tmp/sniff_%s.pcap" % intf)
             for pkt in cap_pkts:
@@ -618,8 +684,29 @@ def load_sniff_packets(index=''):
 
     return pkts
 
-############################################################################################################
-############################################################################################################
+
+def compare_pktload(pkt1=None, pkt2=None, layer="L2"):
+    l_idx = 0
+    if layer == "L2":
+        l_idx = 0
+    elif layer == "L3":
+        l_idx = 1
+    elif layer == "L4":
+        l_idx = 2
+    try:
+        load1 = hexstr(str(pkt1.pktgen.pkt.getlayer(l_idx)))
+        load2 = hexstr(str(pkt2.pktgen.pkt.getlayer(l_idx)))
+    except:
+        # return pass when scapy failed to extract packet
+        return True
+
+    if load1 == load2:
+        return True
+    else:
+        return False
+
+###############################################################################
+###############################################################################
 if __name__ == "__main__":
     inst = sniff_packets("lo", timeout=5)
     time.sleep(3)
@@ -633,10 +720,11 @@ if __name__ == "__main__":
     pkt.send_pkt(tx_port='lo')
 
     pkt = Packet()
-    pkt.assign_layers(['ether', 'dot1q', 'ipv4', 'udp', 'vxlan', 'inner_mac', 'inner_ipv4', 'inner_udp', 'raw'])
+    pkt.assign_layers(['ether', 'dot1q', 'ipv4', 'udp',
+                       'vxlan', 'inner_mac', 'inner_ipv4', 'inner_udp', 'raw'])
     pkt.config_layer('ether', {'dst': '00:11:22:33:44:55'})
     pkt.config_layer('dot1q', {'vlan': 2})
     pkt.config_layer('ipv4', {'dst': '1.1.1.1'})
     pkt.config_layer('udp', {'src': 4789, 'dst': 4789, 'chksum': 0x1111})
     pkt.config_layer('vxlan', {'vni': 2})
-    pkt.config_layer('raw', {'payload': ['58']*18})
+    pkt.config_layer('raw', {'payload': ['58'] * 18})
-- 
1.9.3

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [dts] [PATCH 2/3] framework: add packet integrity verification funtion
  2015-10-22  1:02 [dts] [PATCH 0/3] packet integrity check in sample applications Yong Liu
  2015-10-22  1:02 ` [dts] [PATCH 1/3] framework: support packet objects transmit and analysis Yong Liu
@ 2015-10-22  1:02 ` Yong Liu
  2015-10-22  1:02 ` [dts] [PATCH 3/3] tests: add l2fwd sample forwarding integrity check test Yong Liu
  2 siblings, 0 replies; 4+ messages in thread
From: Yong Liu @ 2015-10-22  1:02 UTC (permalink / raw)
  To: dts

From: Marvin Liu <yong.liu@intel.com>

Add new function which support packet integrity checkt with random content.
This function will send out 2000 packets at the interval of 0.01 seconds.
Then check recevied packet exactly match transmitted packets.

Signed-off-by: Marvin Liu <yong.liu@intel.com>

diff --git a/framework/tester.py b/framework/tester.py
index de0bc24..1f4f7ae 100644
--- a/framework/tester.py
+++ b/framework/tester.py
@@ -42,6 +42,7 @@ from net_device import NetDevice
 from etgen import IxiaPacketGenerator, SoftwarePacketGenerator
 from logger import getLogger
 from settings import IXIA
+import random
 
 
 class Tester(Crb):
@@ -444,6 +445,61 @@ class Tester(Crb):
         else:
             return None
 
+    def check_random_pkts(self, portList, pktnum=2000, interval=0.01, allow_miss=True):
+        """
+        Send several random packets and check rx packets matched
+        """
+        # load functions in packet module
+        module = __import__("packet")
+        pkt_c = getattr(module, "Packet")
+        send_f = getattr(module, "send_packets")
+        sniff_f = getattr(module, "sniff_packets")
+        load_f = getattr(module, "load_sniff_packets")
+        compare_f = getattr(module, "compare_pktload")
+        pkts = []
+        # packet type random between tcp/udp/ipv6
+        random_type = ['TCP', 'UDP', 'IPv6_TCP', 'IPv6_UDP']
+        # at least wait 2 seconds
+        timeout = int(pktnum * (interval + 0.01)) + 2
+        for txport, rxport in portList:
+            txIntf = self.get_interface(txport)
+            rxIntf = self.get_interface(rxport)
+            for num in range(pktnum):
+                # chose random packet
+                pkt_type = random.choice(random_type)
+                pkt = pkt_c(pkt_type=pkt_type,
+                            pkt_len=random.randint(64, 1514),
+                            ran_payload=True)
+                # sequence saved in layer4 source port
+                if "TCP" in pkt_type:
+                    pkt.config_layer('tcp', {'src': num % 65536})
+                else:
+                    pkt.config_layer('udp', {'src': num % 65536})
+                pkts.append(pkt)
+
+            # send and sniff packets
+            inst = sniff_f(intf=rxIntf, count=pktnum, timeout=timeout)
+            send_f(intf=txIntf, pkts=pkts, interval=interval)
+            recv_pkts = load_f(inst)
+
+            # only report when recevied number not matched
+            if len(pkts) != len(recv_pkts):
+                if allow_miss is False:
+                    return False
+
+                print "Pkt number not matched,%d sent and %d received\n" \
+                       % (len(pkts), len(recv_pkts))
+
+            # check each received packet content
+            for idx in range(len(recv_pkts)):
+                t_idx = recv_pkts[idx].strip_element_layer4('src')
+                if compare_f(pkts[t_idx], recv_pkts[idx], "L4") is False:
+                    print "Pkt recevied index %d not match original " \
+                          "index %d" % (idx, t_idx)
+                    return False
+
+        return True
+
     def extend_external_packet_generator(self, clazz, instance):
         """
         Update packet generator function, will implement later.
-- 
1.9.3

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [dts] [PATCH 3/3] tests: add l2fwd sample forwarding integrity check test
  2015-10-22  1:02 [dts] [PATCH 0/3] packet integrity check in sample applications Yong Liu
  2015-10-22  1:02 ` [dts] [PATCH 1/3] framework: support packet objects transmit and analysis Yong Liu
  2015-10-22  1:02 ` [dts] [PATCH 2/3] framework: add packet integrity verification funtion Yong Liu
@ 2015-10-22  1:02 ` Yong Liu
  2 siblings, 0 replies; 4+ messages in thread
From: Yong Liu @ 2015-10-22  1:02 UTC (permalink / raw)
  To: dts

From: Marvin Liu <yong.liu@intel.com>

Add new test case for check l2fwd sample forwarded packets. The case will
meansure different core and queue configurations.

Signed-off-by: Marvin Liu <yong.liu@intel.com>

diff --git a/tests/TestSuite_l2fwd.py b/tests/TestSuite_l2fwd.py
index 5c79cbf..e36bafb 100644
--- a/tests/TestSuite_l2fwd.py
+++ b/tests/TestSuite_l2fwd.py
@@ -113,7 +113,7 @@ class TestL2fwd(TestCase):
         self.dut.send_expect("fg", "l2fwd ", 5)
         self.dut.send_expect("^C", "# ", 5)
 
-    def test_port_testing(self):
+    def notest_port_testing(self):
         """
         Check port forwarding.
         """
@@ -143,6 +143,33 @@ class TestL2fwd(TestCase):
 
         self.quit_l2fwd()
 
+    def test_l2fwd_integrity(self):
+        """
+        Check port forwarding.
+        """
+        # the cases use the first two ports
+        port_mask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])
+
+        core_mask = dts.create_mask(self.dut.get_core_list(self.core_config,
+                                                           socket=self.ports_socket))
+        for queues in self.test_queues:
+
+            command_line = "./examples/l2fwd/build/app/l2fwd -n %d -c %s -- -q %s -p %s &" % \
+                (self.dut.get_memory_channels(), core_mask,
+                 str(queues['queues']), port_mask)
+
+            self.dut.send_expect(command_line, "memory mapped", 60)
+
+            tgen_input = []
+            tx_port = self.tester.get_local_port(self.dut_ports[0])
+            rx_port = self.tester.get_local_port(self.dut_ports[1])
+            tgen_input.append((tx_port, rx_port))
+
+            result = self.tester.check_random_pkts(tgen_input, allow_miss=False)
+            self.verify(result != False, "Packet integrity check failed")
+
+            self.quit_l2fwd()
+
     def test_perf_l2fwd_performance(self):
         """
         Benchmark performance for frame_sizes.
-- 
1.9.3

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-10-22  1:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-22  1:02 [dts] [PATCH 0/3] packet integrity check in sample applications Yong Liu
2015-10-22  1:02 ` [dts] [PATCH 1/3] framework: support packet objects transmit and analysis Yong Liu
2015-10-22  1:02 ` [dts] [PATCH 2/3] framework: add packet integrity verification funtion Yong Liu
2015-10-22  1:02 ` [dts] [PATCH 3/3] tests: add l2fwd sample forwarding integrity check test Yong Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).