def test_linux_cp_tun(self): """ Linux CP TUN """ # # Setup # N_PKTS = 31 # create two pairs, wihch a bunch of hots on the phys hosts = [self.pg4, self.pg5] phy = self.pg2 phy.config_ip4() phy.config_ip6() phy.resolve_arp() phy.resolve_ndp() tun4 = VppIpIpTunInterface( self, phy, phy.local_ip4, phy.remote_ip4).add_vpp_config() tun6 = VppIpIpTunInterface( self, phy, phy.local_ip6, phy.remote_ip6).add_vpp_config() tuns = [tun4, tun6] tun4.admin_up() tun4.config_ip4() tun6.admin_up() tun6.config_ip6() pair1 = VppLcpPair(self, tuns[0], hosts[0]).add_vpp_config() pair2 = VppLcpPair(self, tuns[1], hosts[1]).add_vpp_config() self.logger.info(self.vapi.cli("sh lcp adj verbose")) self.logger.info(self.vapi.cli("sh lcp")) self.logger.info(self.vapi.cli("sh ip punt redirect")) # # Traffic Tests # # host to phy for v4 p = (IP(src=tun4.local_ip4, dst="2.2.2.2") / UDP(sport=1234, dport=1234) / Raw()) rxs = self.send_and_expect(self.pg4, p * N_PKTS, phy) # verify inner packet is unchanged and has the tunnel encap for rx in rxs: self.assertEqual(rx[Ether].dst, phy.remote_mac) self.assertEqual(rx[IP].dst, phy.remote_ip4) self.assertEqual(rx[IP].src, phy.local_ip4) inner = IP(rx[IP].payload) self.assertEqual(inner.src, tun4.local_ip4) self.assertEqual(inner.dst, "2.2.2.2") # host to phy for v6 p = (IPv6(src=tun6.local_ip6, dst="2::2") / UDP(sport=1234, dport=1234) / Raw()) rxs = self.send_and_expect(self.pg5, p * N_PKTS, phy) # verify inner packet is unchanged and has the tunnel encap for rx in rxs: self.assertEqual(rx[IPv6].dst, phy.remote_ip6) self.assertEqual(rx[IPv6].src, phy.local_ip6) inner = IPv6(rx[IPv6].payload) self.assertEqual(inner.src, tun6.local_ip6) self.assertEqual(inner.dst, "2::2") # phy to host v4 p = (Ether(dst=phy.local_mac, src=phy.remote_mac) / IP(dst=phy.local_ip4, src=phy.remote_ip4) / IP(dst=tun4.local_ip4, src=tun4.remote_ip4) / UDP(sport=1234, dport=1234) / Raw()) rxs = self.send_and_expect(phy, p * N_PKTS, self.pg4) for rx in rxs: rx = IP(rx) self.assertEqual(rx[IP].dst, tun4.local_ip4) self.assertEqual(rx[IP].src, tun4.remote_ip4) # phy to host v6 p = (Ether(dst=phy.local_mac, src=phy.remote_mac) / IPv6(dst=phy.local_ip6, src=phy.remote_ip6) / IPv6(dst=tun6.local_ip6, src=tun6.remote_ip6) / UDP(sport=1234, dport=1234) / Raw()) rxs = self.send_and_expect(phy, p * N_PKTS, self.pg5) for rx in rxs: rx = IPv6(rx) self.assertEqual(rx[IPv6].dst, tun6.local_ip6) self.assertEqual(rx[IPv6].src, tun6.remote_ip6) # cleanup phy.unconfig_ip4() phy.unconfig_ip6() tun4.unconfig_ip4() tun6.unconfig_ip6()
def test_ipip4(self): """ ip{v4,v6} over ip4 test """ p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) p_ip6 = IPv6(src="1::1", dst="DEAD::1", nh='UDP', tc=42) p_ip4 = IP(src="1.2.3.4", dst="130.67.0.1", tos=42) p_payload = UDP(sport=1234, dport=1234) / Raw(b'X' * 100) # IPv4 transport rv = ipip_add_tunnel(self, self.pg0.local_ip4, self.pg1.remote_ip4, tc_tos=0xFF) sw_if_index = rv.sw_if_index # Set interface up and enable IP on it self.vapi.sw_interface_set_flags(sw_if_index, 1) self.vapi.sw_interface_set_unnumbered( sw_if_index=self.pg0.sw_if_index, unnumbered_sw_if_index=sw_if_index) # Add IPv4 and IPv6 routes via tunnel interface ip4_via_tunnel = VppIpRoute(self, "130.67.0.0", 16, [ VppRoutePath("0.0.0.0", sw_if_index, proto=FibPathProto.FIB_PATH_NH_PROTO_IP4) ]) ip4_via_tunnel.add_vpp_config() ip6_via_tunnel = VppIpRoute(self, "dead::", 16, [ VppRoutePath( "::", sw_if_index, proto=FibPathProto.FIB_PATH_NH_PROTO_IP6) ]) ip6_via_tunnel.add_vpp_config() # IPv6 in to IPv4 tunnel p6 = (p_ether / p_ip6 / p_payload) p_inner_ip6 = p_ip6 p_inner_ip6.hlim -= 1 p6_reply = (IP(src=self.pg0.local_ip4, dst=self.pg1.remote_ip4, proto='ipv6', id=0, tos=42) / p_inner_ip6 / p_payload) p6_reply.ttl -= 1 rx = self.send_and_expect(self.pg0, p6 * 10, self.pg1) for p in rx: self.validate(p[1], p6_reply) self.assert_packet_checksums_valid(p) # IPv4 in to IPv4 tunnel p4 = (p_ether / p_ip4 / p_payload) p_ip4_inner = p_ip4 p_ip4_inner.ttl -= 1 p4_reply = ( IP(src=self.pg0.local_ip4, dst=self.pg1.remote_ip4, tos=42) / p_ip4_inner / p_payload) p4_reply.ttl -= 1 p4_reply.id = 0 rx = self.send_and_expect(self.pg0, p4 * 10, self.pg1) for p in rx: self.validate(p[1], p4_reply) self.assert_packet_checksums_valid(p) # Decapsulation p_ether = Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) # IPv4 tunnel to IPv4 p_ip4 = IP(src="1.2.3.4", dst=self.pg0.remote_ip4) p4 = (p_ether / IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4) / p_ip4 / p_payload) p4_reply = (p_ip4 / p_payload) p4_reply.ttl -= 1 rx = self.send_and_expect(self.pg1, p4 * 10, self.pg0) for p in rx: self.validate(p[1], p4_reply) self.assert_packet_checksums_valid(p) err = self.statistics.get_err_counter( '/err/ipip4-input/packets decapsulated') self.assertEqual(err, 10) # IPv4 tunnel to IPv6 p_ip6 = IPv6(src="1:2:3::4", dst=self.pg0.remote_ip6) p6 = (p_ether / IP(src=self.pg1.remote_ip4, dst=self.pg0.local_ip4) / p_ip6 / p_payload) p6_reply = (p_ip6 / p_payload) p6_reply.hlim = 63 rx = self.send_and_expect(self.pg1, p6 * 10, self.pg0) for p in rx: self.validate(p[1], p6_reply) self.assert_packet_checksums_valid(p) err = self.statistics.get_err_counter( '/err/ipip4-input/packets decapsulated') self.assertEqual(err, 20) # # Fragmentation / Reassembly and Re-fragmentation # rv = self.vapi.ip_reassembly_enable_disable( sw_if_index=self.pg1.sw_if_index, enable_ip4=1) self.vapi.ip_reassembly_set(timeout_ms=1000, max_reassemblies=1000, max_reassembly_length=1000, expire_walk_interval_ms=10000, is_ip6=0) # Send lots of fragments, verify reassembled packet frags, p4_reply = self.generate_ip4_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], p4_reply) err = self.statistics.get_err_counter( '/err/ipip4-input/packets decapsulated') self.assertEqual(err, 1020) f = [] r = [] for i in range(1, 90): frags, p4_reply = self.generate_ip4_frags(i * 100, 1000) f.extend(frags) r.extend(p4_reply) self.pg_enable_capture() self.pg1.add_stream(f) self.pg_start() rx = self.pg0.get_capture(89) i = 0 for p in rx: self.validate(p[1], r[i]) i += 1 # Now try with re-fragmentation # # Send fragments to tunnel head-end, for the tunnel head end # to reassemble and then refragment # self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [576, 0, 0, 0]) frags, p4_reply = self.generate_ip4_frags(3123, 1200) self.pg_enable_capture() self.pg1.add_stream(frags) self.pg_start() rx = self.pg0.get_capture(6) reass_pkt = reassemble4(rx) p4_reply.id = 256 self.validate(reass_pkt, p4_reply) self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [1600, 0, 0, 0]) frags, p4_reply = self.generate_ip4_frags(3123, 1200) self.pg_enable_capture() self.pg1.add_stream(frags) self.pg_start() rx = self.pg0.get_capture(2) reass_pkt = reassemble4(rx) p4_reply.id = 512 self.validate(reass_pkt, p4_reply) # send large packets through the tunnel, expect them to be fragmented self.vapi.sw_interface_set_mtu(sw_if_index, [600, 0, 0, 0]) p4 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src="1.2.3.4", dst="130.67.0.1", tos=42) / UDP(sport=1234, dport=1234) / Raw(b'Q' * 1000)) rx = self.send_and_expect(self.pg0, p4 * 15, self.pg1, 30) inners = [] for p in rx: inners.append(p[IP].payload) reass_pkt = reassemble4(inners) for p in reass_pkt: self.assert_packet_checksums_valid(p) self.assertEqual(p[IP].ttl, 63)