From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 94B8B378B for ; Thu, 28 May 2015 04:01:23 +0200 (CEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 27 May 2015 19:01:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,509,1427785200"; d="scan'208";a="736474028" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga002.jf.intel.com with ESMTP; 27 May 2015 19:01:21 -0700 Received: from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com [10.239.29.90]) by shvmail01.sh.intel.com with ESMTP id t4S21GTM021346; Thu, 28 May 2015 10:01:16 +0800 Received: from shecgisg003.sh.intel.com (localhost [127.0.0.1]) by shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id t4S21DWT024703; Thu, 28 May 2015 10:01:16 +0800 Received: (from jingguox@localhost) by shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id t4S21DdH024699; Thu, 28 May 2015 10:01:13 +0800 From: Xiaonan Zhang To: dts@dpdk.org Date: Thu, 28 May 2015 10:01:12 +0800 Message-Id: <1432778472-24669-1-git-send-email-xiaonanx.zhang@intel.com> X-Mailer: git-send-email 1.7.4.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: [dts] =?utf-8?q?=5BPATCH=5D_Support_IP_reassembly?= X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 May 2015 02:01:24 -0000 From: Zhangxiaonan Add IPV4 reassembly test case and test plan Signed-off-by: TangHaifeng --- test_plans/ipv4_reassembly_test_plan.rst | 233 ++++++++++++ tests/TestSuite_ipv4_reassembly.py | 579 ++++++++++++++++++++++++++++++ 2 files changed, 812 insertions(+), 0 deletions(-) create mode 100644 test_plans/ipv4_reassembly_test_plan.rst create mode 100644 tests/TestSuite_ipv4_reassembly.py diff --git a/test_plans/ipv4_reassembly_test_plan.rst b/test_plans/ipv4_reassembly_test_plan.rst new file mode 100644 index 0000000..91ba792 --- /dev/null +++ b/test_plans/ipv4_reassembly_test_plan.rst @@ -0,0 +1,233 @@ +.. Copyright (c) <2013>, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + + + +============= +IP Reassembly +============= + +This document provides a test plan for benchmarking of the IP Reassembly +sample application. This is a simple example app featuring packet processing +using Intel® Data Plane Development Kit (Intel® DPDK) that show-cases the use +of IP fragmented packets reassembly. + + + +Prerequisites +------------- + +Support igb_uio and vfio driver, if used vfio, kernel need 3.6+ and enable vt-d in bios. +When used vfio , used "modprobe vfio" and "modprobe vfio-pci" insmod vfiod driver, then used +"./tools/dpdk_nic_bind.py --bind=vfio-pci device_bus_id" to bind vfio driver to test driver. + +1x Intel® 82599 (Niantic) NICs (1x 10GbE full duplex optical ports per NIC) +plugged into the available PCIe Gen2 8-lane slots. + + +Test Case: Send 1K packets, 4 fragments each and 1K maxflows +============================================================ + +Sample command:: + + ./examples/ip_reassembly/build/ip_reassembly -c 0x2 -n 4 -- -P -p 0x2 --config "(1,0,1)" --maxflows=1024 --flowttl=10s + +Sends 1K packets split in 4 fragments each with a ``maxflows`` of 1K. + +It expects: + + - 4K IP packets to be sent to the DUT. + - 1K TCP packets being forwarded back to the TESTER. + - 1K packets with a valid TCP checksum. + + +Test Case: Send 2K packets, 4 fragments each and 1K maxflows +============================================================ + +Sample command:: + + ./examples/ip_reassembly/build/ip_reassembly -c 0x2 -n 4 -- -P -p 0x2 --config "(1,0,1)" --maxflows=1024 --flowttl=10s + +Sends 2K packets split in 4 fragments each with a ``maxflows`` of 1K. + +It expects: + + - 8K IP packets to be sent to the DUT. + - 1K TCP packets being forwarded back to the TESTER. + - 1K packets with a valid TCP checksum. + + +Test Case: Send 4K packets, 7 fragments each and 4K maxflows +============================================================ + +Sample command:: + + ./examples/ip_reassembly/build/ip_reassembly -c 0x2 -n 4 -- -P -p 0x2 --config "(1,0,1)" --maxflows=4096 --flowttl=10s + +Modifies the sample app source code to enable up to 7 fragments per packet. +Sends 4K packets split in 7 fragments each with a ``maxflows`` of 4K. + +It expects: + + - 28K IP packets to be sent to the DUT. + - 4K TCP packets being forwarded back to the TESTER. + - 4K packets with a valid TCP checksum. + + +Test Case: Send +1K packets and ttl 3s; wait +ttl; send 1K packets +================================================================== + +Sample command:: + + ./examples/ip_reassembly/build/ip_reassembly -c 0x2 -n 4 -- -P -p 0x2 --config "(1,0,1)" --maxflows=1024 --flowttl=3s + +Sends 1100 packets split in 4 fragments each. + +It expects: + + - 4400 IP packets to be sent to the DUT. + - 1K TCP packets being forwarded back to the TESTER. + - 1K packets with a valid TCP checksum. + + +Then waits until the ``flowttl`` timeout and sends 1K packets. + +It expects: + + - 4K IP packets to be sent to the DUT. + - 1K TCP packets being forwarded back to the TESTER. + - 1K packets with a valid TCP checksum. + + +Test Case: Send more packets than maxflows; only maxflows packets are forwarded back +==================================================================================== + +Sample command:: + + ./examples/ip_reassembly/build/ip_reassembly -c 0x2 -n 4 -- -P -p 0x2 --config "(1,0,1)" --maxflows=1023 --flowttl=5s + +Sends 1K packets with ``maxflows`` equal to 1023. + +It expects: + + - 4092 IP packets to be sent to the DUT. + - 1023 TCP packets being forwarded back to the TESTER. + - 1023 packets with a valid TCP checksum. + +Then sends 1023 packets. + +It expects: + + - 4092 IP packets to be sent to the DUT. + - 1023 TCP packets being forwarded back to the TESTER. + - 1023 packets with a valid TCP checksum. + +Finally waits until the ``flowttl`` timeout and re-send 1K packets. + +It expects: + + - 4092 IP packets to be sent to the DUT. + - 1023 TCP packets being forwarded back to the TESTER. + - 1023 packets with a valid TCP checksum. + + +Test Case: Send more fragments than supported +============================================= + +Sample command:: + + ./examples/ip_reassembly/build/ip_reassembly -c 0x2 -n 4 -- -P -p 0x2 --config "(1,0,1)" --maxflows=1024 --flowttl=10s + +Sends 1 packet split in 5 fragments while the maximum number of supported +fragments per packet is 4. + +It expects: + + - 5 IP packets to be sent to the DUT. + - 0 TCP packets being forwarded back to the TESTER. + - 0 packets with a valid TCP checksum. + + + +Test Case: Send 3 frames and delay the 4th; no frames are forwarded back +======================================================================== + +Sample command:: + + ./examples/ip_reassembly/build/ip_reassembly -c 0x2 -n 4 -- -P -p 0x2 --config "(1,0,1)" --maxflows=1024 --flowttl=3s + +Creates 1 packet split in 4 fragments. Sends the first 3 fragments and waits +until the ``flowttl`` timeout. Then sends the 4th fragment. + +It expects: + + - 4 IP packets to be sent to the DUT. + - 0 TCP packets being forwarded back to the TESTER. + - 0 packets with a valid TCP checksum. + + + +Test Case: Send jumbo frames +============================ + +Sample command:: + + ./examples/ip_reassembly/build/ip_reassembly -c 0x2 -n 4 -- -P -p 0x2 --config "(1,0,1)" --maxflows=1024 --flowttl=10s --enable-jumbo --max-pkt-len=9500 + +Sets the NIC MTU to 9000 and sends 1K packets of 8900B split in 4 fragments of +2500B at the most. The reassembled packet size will not be bigger than the +MTU previously defined. + +It expects: + + - 4K IP packets to be sent to the DUT. + - 1K TCP packets being forwarded back to the TESTER. + - 1K packets with a valid TCP checksum. + + +Test Case: Send jumbo frames without enable them in the app +=========================================================== + +Sample command:: + + ./examples/ip_reassembly/build/ip_reassembly -c 0x2 -n 4 -- -P -p 0x2 --config "(1,0,1)" --maxflows=1024 --flowttl=10s + +Sends jumbo packets in the same way the previous test case does but without +enabling support within the sample app. + +It expects: + + - 4K IP packets to be sent to the DUT. + - 0 TCP packets being forwarded back to the TESTER. + - 0 packets with a valid TCP checksum. + + diff --git a/tests/TestSuite_ipv4_reassembly.py b/tests/TestSuite_ipv4_reassembly.py new file mode 100644 index 0000000..e24576c --- /dev/null +++ b/tests/TestSuite_ipv4_reassembly.py @@ -0,0 +1,579 @@ +# + +""" +DPDK Test suite. + +Test the IP reassembly feature + +""" + +import os +import time +from scapy.utils import struct, socket, PcapWriter +from scapy.layers.inet import Ether, IP, TCP, fragment +from scapy.route import * + +import dts +from test_case import TestCase + + +class IpReassemblyTestConfig(object): + + """ + Helper class that encapsulates all the parameters used by the different + test cases components. + """ + + # + # + # Utility methods and other non-test code. + # + + def __init__(self, test_case, **kwargs): + self.test_case = test_case + self.init() + for name in kwargs: + setattr(self, name, kwargs[name]) + + def init(self): + self.cpu_config() + self.ports_config() + self.example_app_config() + self.packets_config() + + def cpu_config(self): + self.core_list = self.test_case.dut.get_core_list('1S/1C/1T') + self.core_mask = dts.create_mask(self.core_list) + self.memory_channels = self.test_case.dut.get_memory_channels() + + def ports_config(self): + dut_ports = self.test_case.dut.get_ports(self.test_case.nic) + dut_port = dut_ports[0] + tester_port = self.test_case.tester.get_local_port(dut_port) + self.tester_iface = self.test_case.tester.get_interface(tester_port) + self.dut_port_mask = dts.create_mask([dut_port]) + self.queue_config = '({},{},{})'.format(dut_port, '0', self.core_list[0]) + + def example_app_config(self): + self.maxflows = 1024 + self.flowttl = '10s' + self.extra_args = '' + + def packets_config(self): + self.pcap_file = 'file.pcap' + self.number_of_frames = 1024 + self.frags_per_frame = 4 + self.src_ip = '2.1.1.0' + self.dst_ip = '1.1.1.111' + self.payload_size = 140 + self.fragment_size = 40 + self.mac_src = 'DE:AD:BE:EF:02:01' + self.mac_dst = 'DE:AD:BE:EF:01:02' + self.tcp_src_port = 1234 + self.tcp_dst_port = 4321 + self.identification = 1 + +# +# +# Test class. +# + + +class TestIpReassembly(TestCase): + + # + # + # + # Test cases. + # + + def set_max_num_of_fragments(self, num_of_fragments=4): + """ + Changes the maximum number of frames by modifying the example app code. + """ + + # sed_command = (r"sed -i 's/\(\s*MAX_FRAG_NUM\s*=\)\s*[[:digit:]]*/\1 %d/' " + + # r"examples/ip_reassembly/ipv4_rsmbl.h") + # self.dut.send_expect("sed -i 's/CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=.*$/CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=%s/' ./config/common_linuxapp" %int(num_of_fragments), "# ") + # self.dut.send_expect(sed_command % int(num_of_fragments), '#', 60) + + self.dut.send_expect("sed -i 's/CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=.*$/CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=%s/' ./config/common_linuxapp" % int(num_of_fragments), "# ") + self.dut.send_expect("export RTE_TARGET=" + self.target, "#") + self.dut.send_expect("export RTE_SDK=`pwd`", "#") + self.dut.send_expect("rm -rf %s" % self.target, "# ", 5) + self.dut.build_install_dpdk(self.target) + + def set_tester_iface_mtu(self, iface, mtu=1500): + """ + Set the interface MTU value. + """ + + command = 'ip link set mtu {mtu} dev {iface}' + self.tester.send_expect(command.format(**locals()), '#') + + def compile_example_app(self): + """ + Builds the example app and checks for errors. + """ + + self.dut.send_expect('rm -rf examples/ip_reassembly/build', '#') + out = self.dut.build_dpdk_apps('examples/ip_reassembly') +# self.verify('Error' not in out and 'No such file' not in out, +# 'Compilation error') + + def execute_example_app(self): + """ + Execute the example app and checks for errors. + """ + + command = ('./examples/ip_reassembly/build/ip_reassembly -c {core_mask} ' + + '-n {memory_channels} -- -p {dut_port_mask} ' + + '--maxflows={maxflows} --flowttl={flowttl} {extra_args}') + self.dut.send_expect(command.format(**self.test_config.__dict__), 'IP_RSMBL: ') + + def tcp_ipv4_fragments(self, src_ip, identifier): + """ + Using the Scapy API generates a packet with the given configuration + and returns a list containing fragmented packets. + """ + + packet = Ether() / IP() / TCP() / ("X" * self.test_config.payload_size) + packet[Ether].src = self.test_config.mac_src + packet[Ether].dst = self.test_config.mac_dst + packet[IP].src = src_ip + packet[IP].dst = self.test_config.dst_ip + packet[IP].id = identifier + packet[TCP].sport = self.test_config.tcp_src_port + packet[TCP].dport = self.test_config.tcp_dst_port + return fragment(packet, fragsize=self.test_config.fragment_size) + + def increment_ip_address(self, addr, val): + """ + Returns the next valid IP address from a given one, like + 10.1.1.254 -> 10.1.1.255 -> 10.1.2.0 -> 10.1.2.1 + """ + + ip2int = lambda ipstr: struct.unpack('!I', socket.inet_aton(ipstr))[0] + x = ip2int(addr) + int2ip = lambda n: socket.inet_ntoa(struct.pack('!I', n)) + return int2ip(x + 1) + + def create_fragments(self): + """ + Returns a list of fragmented IP packets by creating one packet at the + time, fragmenting it and adding it to a list. + It takes the packet information from the given configuration. + """ + + all_fragments = [] + src_ip = self.test_config.src_ip + for _ in range(self.test_config.number_of_frames): + src_ip = self.increment_ip_address(src_ip, 1) + identifier = self.test_config.identification % 0x10000 + fragments = self.tcp_ipv4_fragments(src_ip, identifier) + all_fragments.extend(fragments) + self.test_config.identification += 1 + return all_fragments + + def write_shuffled_pcap(self, fragments): + """ + Receives a list of fragmented packets and writes them into a PCAP file + using the Scapy API. + Before saving the frames to a file it will reorder them like this: + + pkt0-frag3 -> pkt1-frag3 -> pkt2-frag3 -> ... -> pktN-frag3 -> + pkt0-frag2 -> pkt1-frag2 -> pkt2-frag2 -> ... -> pktN-frag2 -> + pkt0-frag1 -> pkt1-frag1 -> pkt2-frag1 -> ... -> pktN-frag1 -> + pkt0-frag0 -> pkt1-frag0 -> pkt2-frag0 -> ... -> pktN-frag0. + """ + + writer = PcapWriter(self.test_config.pcap_file) + rounds = self.test_config.frags_per_frame + while rounds > 0: + index = rounds - 1 + rounds -= 1 + while index < len(fragments): + writer.write(fragments[index]) + index += self.test_config.frags_per_frame + writer.close() + + def create_pcap_file(self): + """ + Generates a valid PCAP file with the given configuration. + """ + + fragments = self.create_fragments() + self.write_shuffled_pcap(fragments) + + def scapy_send_packets(self): + """ + Calling scapy from the tester board sends the generated PCAP file to + the DUT + """ + + self.tester.scapy_append('pcap = rdpcap("%s")' % self.test_config.pcap_file) + self.tester.scapy_append('sendp(pcap, iface="%s")' % self.test_config.tester_iface) + self.tester.scapy_execute() + time.sleep(5) + + def send_packets(self): + """ + Goes trhough all the steps to send packets from the tester to the self.dut. + Generates the PCAP file, place it into the tester board, calls scapy and + finally removes the PCAP file. + """ + + self.create_pcap_file() + self.tester.session.copy_file_to(self.test_config.pcap_file) + self.scapy_send_packets() + os.remove(self.test_config.pcap_file) + time.sleep(5) + + def tcpdump_start_sniffing(self): + """ + Starts tcpdump in the background to sniff the tester interface where + the packets are transmitted to and from the self.dut. + All the captured packets are going to be stored in a file for a + post-analysis. + """ + + command = ('tcpdump -w tcpdump.pcap -i %s 2>tcpdump.out &' % + self.test_config.tester_iface) + self.tester.send_expect('rm -f tcpdump.pcap', '#') + self.tester.send_expect(command, '#') + + def tcpdump_stop_sniff(self): + """ + Stops the tcpdump process running in the background. + """ + + self.tester.send_expect('killall tcpdump', '#') + # For the [pid]+ Done tcpdump... message after killing the process + self.tester.send_expect('cat tcpdump.out', '#') + time.sleep(3) + + def tcpdump_command(self, command): + """ + Sends a tcpdump related command and returns an integer from the output + """ + + result = self.tester.send_expect(command, '#') + return int(result.strip()) + + def number_of_received_packets(self, tcp_port): + """ + By reading the file generated by tcpdump it counts how many packets were + forwarded by the sample app and received in the self.tester. The sample app + will add a known MAC address for the test to look for. + """ + + command = ('tcpdump -nn -e -v -r tcpdump.pcap tcp dst port {tcp_port} 2>/dev/null | ' + + 'grep -c 02:00:00:00:00') # MAC address used by the example app + return self.tcpdump_command(command.format(**locals())) + + def number_of_sent_packets(self, mac_src): + """ + By reading the file generated by tcpdump it counts how many packets were + sent to the DUT searching for a given MAC address. + """ + + command = ('tcpdump -nn -e -v -r tcpdump.pcap 2>/dev/null | ' + + 'grep -c -i {mac_src}') + return self.tcpdump_command(command.format(**locals())) + + def number_of_tcp_valid_checksum(self, tcp_port): + """ + By reading the file generated by tcpdump it counts how many packets have + a valid TCP checksum or how many packets were correctly assembled. + """ + + command = ('tcpdump -nn -e -v -r tcpdump.pcap tcp dst port {tcp_port} 2>/dev/null | ' + + 'grep -c -E "cksum.*correct"') + return self.tcpdump_command(command.format(**locals())) + + def send_n_siff_packets(self): + """ + Sends the packets while tcpdump is sniffing on the background. + """ + + self.tcpdump_start_sniffing() + self.send_packets() + self.tcpdump_stop_sniff() + + def verify_sent_packets(self, expected): + """ + Verifies if the number of sent packets is the expected. + """ + + sent_packets = self.number_of_sent_packets(self.test_config.mac_src) + print 'sent packets: %d - expected: %d' % (sent_packets, expected) + self.verify(sent_packets == expected, 'Not all fragments have been sent') + + def verify_received_packets(self, expected): + """ + Verifies if the number of received packets is the expected. + """ + + received_packets = self.number_of_received_packets(self.test_config.tcp_dst_port) + print 'received packets: %d - expected: %d' % (received_packets, expected) + self.verify(received_packets == expected, + 'Not all frames have been forwarded') + + def verify_tcp_valid_checksum(self, expected): + """ + Verifies if the number of packets with a valid TCP checksum is the expected. + """ + + tcp_valid_checksum = self.number_of_tcp_valid_checksum(self.test_config.tcp_dst_port) + print 'tcp valid: %d - expected: %d' % (tcp_valid_checksum, expected) + self.verify(tcp_valid_checksum == expected, + 'Not all TCP packets have valid checksum') + + def verify_all_with_maxflows(self): + """ + Runs a common verification among different test cases were the number + of sent packets is bigger than the maxflows value which means that + only maxflows packets are expected to be received and valid. + """ + + self.verify_sent_packets(self.test_config.number_of_frames * + self.test_config.frags_per_frame) + self.verify_received_packets(self.test_config.maxflows) + self.verify_tcp_valid_checksum(self.test_config.maxflows) + + def verify_all(self): + """ + Runs a common verification among different test cases were the number + of sent packets is equal to the maxflows value. It expects to receive + the same number of frames that were sent. + """ + + self.verify_sent_packets(self.test_config.number_of_frames * + self.test_config.frags_per_frame) + self.verify_received_packets(self.test_config.number_of_frames) + self.verify_tcp_valid_checksum(self.test_config.number_of_frames) + + def set_up_all(self): + """ + Run at the start of each test suite. + + + Builds the sample app and set the shell prompt to a known and value. + """ + + self.tester.send_expect('export PS1="# "', '#') + self.compile_example_app() + + def test_send_1K_frames_split_in_4_and_1K_maxflows(self): + """ + Sends 1K frames split in 4 fragments each using + 1K maxflows. + """ + + self.test_config = IpReassemblyTestConfig(self) + + self.execute_example_app() + self.send_n_siff_packets() + + self.verify_all() + + def test_send_2K_frames_split_in_4_and_1K_maxflows(self): + """ + Sends 2K frames while the maxflow value is only 1K. + Only 1K frames are expected to be forwarded. + """ + + self.test_config = IpReassemblyTestConfig(self, number_of_frames=2048) + + self.execute_example_app() + self.send_n_siff_packets() + + self.verify_all_with_maxflows() + + def test_send_4K_frames_split_in_7_and_4K_maxflows(self): + """ + Sends 4K frames split into 7 fragments each. + """ + + self.test_config = IpReassemblyTestConfig(self, + number_of_frames=4096, + frags_per_frame=7, + payload_size=230, + maxflows=4096, + flowttl='40s') + + try: + self.set_max_num_of_fragments(7) + self.compile_example_app() + self.execute_example_app() + self.send_n_siff_packets() + self.verify_all() + self.dut.send_expect('^C', '# ') + time.sleep(5) + self.set_max_num_of_fragments(4) + time.sleep(5) + + except Exception as e: + self.dut.send_expect('^C', '# ') + time.sleep(2) + self.set_max_num_of_fragments() + self.compile_example_app() + raise e + + def test_packets_are_forwarded_after_ttl_timeout(self): + """ + Sends +1K frames with 1K maxflwos - expects only + 1K frames to be forwarded. Then it waits until flowttl timeout and + sends 1K frames. 1K frames must be forwarded back. + """ + + self.test_config = IpReassemblyTestConfig(self, + number_of_frames=1100, + flowttl='3s') + + self.execute_example_app() + + self.send_n_siff_packets() + self.verify_all_with_maxflows() + + time.sleep(5) + + self.test_config.number_of_frames = 1024 + self.send_n_siff_packets() + self.verify_all() + + def test_only_maxflows_packets_are_forwarded(self): + """ + Using a maxflow of 1023 sends 1K frames expecting 1023 back. + Then sends 1023 frames, expecting 1023 back again. And after the flowttl + timeout sends 1K frames expecting all of them to be forwarded back. + """ + + self.test_config = IpReassemblyTestConfig(self, + maxflows=1023, + flowttl='5s') + + self.execute_example_app() + + self.send_n_siff_packets() + self.verify_all_with_maxflows() + + self.test_config.number_of_frames = 1023 + self.send_n_siff_packets() + self.verify_all() + + time.sleep(5) + + self.test_config.number_of_frames = 1024 + self.send_n_siff_packets() + self.verify_all_with_maxflows() + + def test_send_more_fragments_than_supported(self): + """ + Sends 1 frame split in 5 fragments. Since the max number of + fragments is set to 4 by default, the packet can't be forwarded back. + """ + + self.test_config = IpReassemblyTestConfig(self, + number_of_frames=1, + frags_per_frame=5, + payload_size=180) + self.execute_example_app() + + self.send_n_siff_packets() + + self.verify_sent_packets(self.test_config.number_of_frames * + self.test_config.frags_per_frame) + self.verify_received_packets(0) + self.verify_tcp_valid_checksum(0) + + def test_send_delayed_fragment_packet_is_forwarded(self): + """ + Creates 1 frame split in 4. Sends 3 fragments first, waits + for the flowttl to timeout and then sends the 4th. The packet can't + be forwarded back. + """ + + self.test_config = IpReassemblyTestConfig(self, + number_of_frames=1, + flowttl='3s') + + self.execute_example_app() + self.tcpdump_start_sniffing() + + fragments = self.create_fragments() + self.write_shuffled_pcap(fragments[:3]) + self.tester.session.copy_file_to(self.test_config.pcap_file) + self.scapy_send_packets() + os.remove(self.test_config.pcap_file) + + time.sleep(3) + + self.write_shuffled_pcap(fragments[3:]) + self.tester.session.copy_file_to(self.test_config.pcap_file) + self.scapy_send_packets() + os.remove(self.test_config.pcap_file) + + self.tcpdump_stop_sniff() + + self.verify_sent_packets(self.test_config.number_of_frames * + self.test_config.frags_per_frame) + self.verify_received_packets(0) + self.verify_tcp_valid_checksum(0) + + def test_send_jumbo_frames(self): + """ + Sends 1K jumbo frames using the right configuration. + Expects all the frames to be forwarded back. + """ + + mtu = 9000 + self.test_config = IpReassemblyTestConfig(self, + payload_size=mtu - 100, + fragment_size=2500) + try: + self.set_tester_iface_mtu(self.test_config.tester_iface, mtu) + self.execute_example_app() + self.send_n_siff_packets() + self.verify_all() + except Exception as e: + self.set_tester_iface_mtu(self.test_config.tester_iface) + raise e + + def test_send_jumbo_frames_with_wrong_arguments(self): + """ + Sends 1K jumbo frames without enabling the jumbo frames + within the sample app. Expects zero frames to be forwarded back. + """ + + mtu = 9000 + self.test_config = IpReassemblyTestConfig(self, + payload_size=mtu - 100, + fragment_size=2500) + try: + self.set_tester_iface_mtu(self.test_config.tester_iface, mtu) + self.set_max_num_of_fragments(4) + self.compile_example_app() + self.execute_example_app() + self.send_n_siff_packets() + + self.verify_sent_packets(self.test_config.number_of_frames * + self.test_config.frags_per_frame) + self.verify_all() + except Exception as e: + self.set_tester_iface_mtu(self.test_config.tester_iface) + raise e + + def tear_down(self): + """ + Run after each test case. + """ + + self.dut.send_expect('^C', '# ') + + def tear_down_all(self): + """ + Run after each test suite. + """ + + self.dut.kill_all() -- 1.7.7