+ def test_frag(self):
+ """ ip{v4,v6} over ip6 test frag """
+
+ p_ether = Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
+ p_ip6 = IPv6(src="1::1", dst="DEAD::1", tc=42, nh='UDP')
+ p_ip4 = IP(src="1.2.3.4", dst=self.pg0.remote_ip4)
+ p_payload = UDP(sport=1234, dport=1234)
+
+ #
+ # Fragmentation / Reassembly and Re-fragmentation
+ #
+ rv = self.vapi.ip_reassembly_enable_disable(
+ sw_if_index=self.pg1.sw_if_index,
+ enable_ip6=1)
+
+ # Send lots of fragments, verify reassembled packet
+ before_cnt = self.statistics.get_counter(
+ '/err/ipip6-input/packets decapsulated')
+ frags, p6_reply = self.generate_ip6_frags(3131, 1400)
+ f = []
+ for i in range(0, 1000):
+ f.extend(frags)
+ self.pg1.add_stream(f)
+ self.pg_enable_capture()
+ self.pg_start()
+ rx = self.pg0.get_capture(1000)
+
+ for p in rx:
+ self.validate(p[1], p6_reply)
+
+ cnt = self.statistics.get_counter(
+ '/err/ipip6-input/packets decapsulated')
+ self.assertEqual(cnt, before_cnt + 1000)
+
+ f = []
+ r = []
+ # TODO: Check out why reassembly of atomic fragments don't work
+ for i in range(10, 90):
+ frags, p6_reply = self.generate_ip6_frags(i * 100, 1000)
+ f.extend(frags)
+ r.extend(p6_reply)
+ self.pg_enable_capture()
+ self.pg1.add_stream(f)
+ self.pg_start()
+ rx = self.pg0.get_capture(80)
+ i = 0
+ for p in rx:
+ self.validate(p[1], r[i])
+ i += 1
+
+ # Simple fragmentation
+ p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
+ self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1280, 0, 0, 0])
+
+ # IPv6 in to IPv6 tunnel
+ p_payload = UDP(sport=1234, dport=1234) / self.payload(1300)
+
+ p6 = (p_ether / p_ip6 / p_payload)
+ p6_reply = (IPv6(src=self.pg0.local_ip6, dst=self.pg1.remote_ip6,
+ hlim=63, tc=42) /
+ p_ip6 / p_payload)
+ p6_reply[1].hlim -= 1
+ self.pg_enable_capture()
+ self.pg0.add_stream(p6)
+ self.pg_start()
+ rx = self.pg1.get_capture(2)
+
+ # Scapy defragment doesn't deal well with multiple layers
+ # of samy type / Ethernet header first
+ f = [p[1] for p in rx]
+ reass_pkt = defragment6(f)
+ self.validate(reass_pkt, p6_reply)
+
+ # Now try with re-fragmentation
+ #
+ # Send large fragments to tunnel head-end, for the tunnel head end
+ # to reassemble and then refragment out the tunnel again.
+ # Hair-pinning
+ #
+ self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1280, 0, 0, 0])
+ frags, p6_reply = self.generate_ip6_hairpin_frags(8000, 1200)
+ self.pg_enable_capture()
+ self.pg1.add_stream(frags)
+ self.pg_start()
+ rx = self.pg1.get_capture(7)
+ f = [p[1] for p in rx]
+ reass_pkt = defragment6(f)
+ p6_reply.id = 256
+ self.validate(reass_pkt, p6_reply)
+