#!/usr/bin/env python
+
+import six
import unittest
from random import shuffle
-from framework import VppTestCase, VppTestRunner
+from framework import VppTestCase, VppTestRunner, is_skip_aarch64_set,\
+ is_platform_aarch64
from scapy.packet import Raw
from scapy.layers.l2 import Ether, GRE
from vpp_ip import DpoProto
from vpp_ip_route import VppIpRoute, VppRoutePath
-test_packet_count = 257
+# 35 is enough to have >257 400-byte fragments
+test_packet_count = 35
class TestIPv4Reassembly(VppTestCase):
@classmethod
def create_stream(cls, packet_sizes, packet_count=test_packet_count):
- """Create input packet stream for defined interface.
+ """Create input packet stream
:param list packet_sizes: Required packet sizes.
"""
def create_fragments(cls):
infos = cls._packet_infos
cls.pkt_infos = []
- for index, info in infos.iteritems():
+ for index, info in six.iteritems(infos):
p = info.data
# cls.logger.debug(ppp("Packet:", p.__class__(str(p))))
fragments_400 = fragment_rfc791(p, 400)
self.verify_capture(packets)
self.src_if.assert_nothing_captured()
+ def test_5737(self):
+ """ fragment length + ip header size > 65535 """
+ self.vapi.cli("clear errors")
+ raw = ('E\x00\x00\x88,\xf8\x1f\xfe@\x01\x98\x00\xc0\xa8\n-\xc0\xa8\n'
+ '\x01\x08\x00\xf0J\xed\xcb\xf1\xf5Test-group: IPv4.IPv4.ipv4-'
+ 'message.Ethernet-Payload.IPv4-Packet.IPv4-Header.Fragment-Of'
+ 'fset; Test-case: 5737')
+
+ malformed_packet = (Ether(dst=self.src_if.local_mac,
+ src=self.src_if.remote_mac) /
+ IP(raw))
+ p = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
+ IP(id=1000, src=self.src_if.remote_ip4,
+ dst=self.dst_if.remote_ip4) /
+ UDP(sport=1234, dport=5678) /
+ Raw("X" * 1000))
+ valid_fragments = fragment_rfc791(p, 400)
+
+ self.pg_enable_capture()
+ self.src_if.add_stream([malformed_packet] + valid_fragments)
+ self.pg_start()
+
+ self.dst_if.get_capture(1)
+ self.assert_packet_counter_equal("ip4-reassembly-feature", 1)
+ # TODO remove above, uncomment below once clearing of counters
+ # is supported
+ # self.assert_packet_counter_equal(
+ # "/err/ip4-reassembly-feature/malformed packets", 1)
+
+ def test_44924(self):
+ """ compress tiny fragments """
+ packets = [(Ether(dst=self.src_if.local_mac,
+ src=self.src_if.remote_mac) /
+ IP(id=24339, flags="MF", frag=0, ttl=64,
+ src=self.src_if.remote_ip4,
+ dst=self.dst_if.remote_ip4) /
+ ICMP(type="echo-request", code=0, id=0x1fe6, seq=0x2407) /
+ Raw(load='Test-group: IPv4')),
+ (Ether(dst=self.src_if.local_mac,
+ src=self.src_if.remote_mac) /
+ IP(id=24339, flags="MF", frag=3, ttl=64,
+ src=self.src_if.remote_ip4,
+ dst=self.dst_if.remote_ip4) /
+ ICMP(type="echo-request", code=0, id=0x1fe6, seq=0x2407) /
+ Raw(load='.IPv4.Fragmentation.vali')),
+ (Ether(dst=self.src_if.local_mac,
+ src=self.src_if.remote_mac) /
+ IP(id=24339, frag=6, ttl=64,
+ src=self.src_if.remote_ip4,
+ dst=self.dst_if.remote_ip4) /
+ ICMP(type="echo-request", code=0, id=0x1fe6, seq=0x2407) /
+ Raw(load='d; Test-case: 44924'))
+ ]
+
+ self.pg_enable_capture()
+ self.src_if.add_stream(packets)
+ self.pg_start()
+
+ self.dst_if.get_capture(1)
+
+ def test_frag_1(self):
+ """ fragment of size 1 """
+ self.vapi.cli("clear errors")
+ malformed_packets = [(Ether(dst=self.src_if.local_mac,
+ src=self.src_if.remote_mac) /
+ IP(id=7, len=21, flags="MF", frag=0, ttl=64,
+ src=self.src_if.remote_ip4,
+ dst=self.dst_if.remote_ip4) /
+ ICMP(type="echo-request")),
+ (Ether(dst=self.src_if.local_mac,
+ src=self.src_if.remote_mac) /
+ IP(id=7, len=21, frag=1, ttl=64,
+ src=self.src_if.remote_ip4,
+ dst=self.dst_if.remote_ip4) /
+ Raw(load='\x08')),
+ ]
+
+ p = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
+ IP(id=1000, src=self.src_if.remote_ip4,
+ dst=self.dst_if.remote_ip4) /
+ UDP(sport=1234, dport=5678) /
+ Raw("X" * 1000))
+ valid_fragments = fragment_rfc791(p, 400)
+
+ self.pg_enable_capture()
+ self.src_if.add_stream(malformed_packets + valid_fragments)
+ self.pg_start()
+
+ self.dst_if.get_capture(1)
+
+ self.assert_packet_counter_equal("ip4-reassembly-feature", 1)
+ # TODO remove above, uncomment below once clearing of counters
+ # is supported
+ # self.assert_packet_counter_equal(
+ # "/err/ip4-reassembly-feature/malformed packets", 1)
+
+ @unittest.skipIf(is_skip_aarch64_set and is_platform_aarch64,
+ "test doesn't work on aarch64")
def test_random(self):
""" random order reassembly """
def create_fragments(cls):
infos = cls._packet_infos
cls.pkt_infos = []
- for index, info in infos.iteritems():
+ for index, info in six.iteritems(infos):
p = info.data
# cls.logger.debug(ppp("Packet:", p.__class__(str(p))))
fragments_400 = fragment_rfc8200(p, info.index, 400)
def create_fragments(cls):
infos = cls._packet_infos
cls.pkt_infos = []
- for index, info in infos.iteritems():
+ for index, info in six.iteritems(infos):
p = info.data
# cls.logger.debug(ppp("Packet:", p.__class__(str(p))))
fragments_300 = fragment_rfc791(p, 300)
seen.add(packet_index)
self.assertEqual(payload_info.dst, self.src_dst_if.sw_if_index)
info = self._packet_infos[packet_index]
- self.assertTrue(info is not None)
+ self.assertIsNotNone(info)
self.assertEqual(packet_index, info.index)
saved_packet = info.data
self.assertEqual(ip.src, saved_packet[IP].dst)
self.logger.error(ppp("Unexpected or invalid packet:", packet))
raise
for index in self._packet_infos:
- self.assertTrue(index in seen or index in dropped_packet_indexes,
- "Packet with packet_index %d not received" % index)
+ self.assertIn(index, seen,
+ "Packet with packet_index %d not received" % index)
def test_reassembly(self):
""" basic reassembly """
self.extend_packet(p, size, self.padding)
info.data = p[IP] # use only IP part, without ethernet header
- fragments = [x for _, p in self._packet_infos.iteritems()
+ fragments = [x for _, p in six.iteritems(self._packet_infos)
for x in fragment_rfc791(p.data, 400)]
encapped_fragments = \
self.extend_packet(p, size, self.padding)
info.data = p[IPv6] # use only IPv6 part, without ethernet header
- fragments = [x for _, i in self._packet_infos.iteritems()
+ fragments = [x for _, i in six.iteritems(self._packet_infos)
for x in fragment_rfc8200(
i.data, i.index, 400)]