예제 #1
0
파일: test_vxlan.py 프로젝트: vpp-dev/vpp
    def test_encap_big_packet(self):
        """ Encapsulation test send big frame from pg1
        Verify receipt of encapsulated frames on pg0
        """

        self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [1500, 0, 0, 0])

        frame = (Ether(src='00:00:00:00:00:02', dst='00:00:00:00:00:01') /
                 IP(src='4.3.2.1', dst='1.2.3.4') /
                 UDP(sport=20000, dport=10000) /
                 Raw('\xa5' * 1450))

        self.pg1.add_stream([frame])

        self.pg0.enable_capture()

        self.pg_start()

        # Pick first received frame and check if it's correctly encapsulated.
        out = self.pg0.get_capture(2)
        ether = out[0]
        pkt = reassemble4(out)
        pkt = ether / pkt
        self.check_encapsulation(pkt, self.single_tunnel_bd)

        payload = self.decapsulate(pkt)
예제 #2
0
파일: test_vxlan.py 프로젝트: zhongyoub/vpp
    def test_encap_big_packet(self):
        """ Encapsulation test send big frame from pg1
        Verify receipt of encapsulated frames on pg0
        """

        self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [1500, 0, 0, 0])

        frame = (Ether(src='00:00:00:00:00:02', dst='00:00:00:00:00:01') /
                 IP(src='4.3.2.1', dst='1.2.3.4') /
                 UDP(sport=20000, dport=10000) / Raw(b'\xa5' * 1450))

        self.pg1.add_stream([frame])

        self.pg0.enable_capture()

        self.pg_start()

        # Pick first received frame and check if it's correctly encapsulated.
        out = self.pg0.get_capture(2)
        ether = out[0]
        pkt = reassemble4(out)
        pkt = ether / pkt
        self.check_encapsulation(pkt, self.single_tunnel_vni)

        payload = self.decapsulate(pkt)
예제 #3
0
    def encap_fragmented_packet(self):
        frame = (
            Ether(src="00:00:00:00:00:02", dst="00:00:00:00:00:01")
            / IP(src="4.3.2.1", dst="1.2.3.4")
            / UDP(sport=20000, dport=10000)
            / Raw(b"\xa5" * 1000)
        )

        frags = util.fragment_rfc791(frame, 400)

        self.pg1.add_stream(frags)

        self.pg0.enable_capture()

        self.pg_start()

        out = self.pg0.get_capture(3)

        payload = []
        for pkt in out:
            payload.append(self.decapsulate(pkt))
            self.check_encapsulation(pkt, self.single_tunnel_vni)

        reassembled = util.reassemble4(payload)

        self.assertEqual(Ether(raw(frame))[IP], reassembled[IP])
예제 #4
0
 def verify_encrypted(self, p, sa, rxs):
     decrypt_pkts = []
     for rx in rxs:
         if p.nat_header:
             self.assertEqual(rx[UDP].dport, 4500)
         self.assert_packet_checksums_valid(rx)
         self.assertEqual(len(rx) - len(Ether()), rx[IP].len)
         try:
             rx_ip = rx[IP]
             decrypt_pkt = p.vpp_tun_sa.decrypt(rx_ip)
             if not decrypt_pkt.haslayer(IP):
                 decrypt_pkt = IP(decrypt_pkt[Raw].load)
             if rx_ip.proto == socket.IPPROTO_ESP:
                 self.verify_esp_padding(sa, rx_ip[ESP].data, decrypt_pkt)
             decrypt_pkts.append(decrypt_pkt)
             self.assert_equal(decrypt_pkt.src, p.tun_if.local_ip4)
             self.assert_equal(decrypt_pkt.dst, p.tun_if.remote_ip4)
         except:
             self.logger.debug(ppp("Unexpected packet:", rx))
             try:
                 self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
             except:
                 pass
             raise
     pkts = reassemble4(decrypt_pkts)
     for pkt in pkts:
         self.assert_packet_checksums_valid(pkt)
예제 #5
0
    def test_encap_fragmented_packet(self):
        """ Encapsulation test send fragments from pg1
        Verify receipt of encapsulated frames on pg0
        """

        frame = (Ether(src='00:00:00:00:00:02', dst='00:00:00:00:00:01') /
                 IP(src='4.3.2.1', dst='1.2.3.4') /
                 UDP(sport=20000, dport=10000) /
                 Raw(b'\xa5' * 1000))

        frags = util.fragment_rfc791(frame, 400)

        self.pg1.add_stream(frags)

        self.pg0.enable_capture()

        self.pg_start()

        out = self.pg0.get_capture(3)

        payload = []
        for pkt in out:
            payload.append(self.decapsulate(pkt))
            self.check_encapsulation(pkt, self.single_tunnel_vni)

        reassembled = util.reassemble4(payload)

        self.assertEqual(Ether(raw(frame))[IP], reassembled[IP])
예제 #6
0
 def verify_encrypted(self, p, sa, rxs):
     decrypt_pkts = []
     for rx in rxs:
         try:
             decrypt_pkt = p.vpp_tun_sa.decrypt(rx[IP])
             if not decrypt_pkt.haslayer(IP):
                 decrypt_pkt = IP(decrypt_pkt[Raw].load)
             decrypt_pkts.append(decrypt_pkt)
             self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
             self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
         except:
             self.logger.debug(ppp("Unexpected packet:", rx))
             try:
                 self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
             except:
                 pass
             raise
     pkts = reassemble4(decrypt_pkts)
     for pkt in pkts:
         self.assert_packet_checksums_valid(pkt)
예제 #7
0
    def encap_big_packet(self):
        self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [1500, 0, 0, 0])

        frame = (Ether(src="00:00:00:00:00:02", dst="00:00:00:00:00:01") /
                 IP(src="4.3.2.1", dst="1.2.3.4") /
                 UDP(sport=20000, dport=10000) / Raw(b"\xa5" * 1450))

        self.pg1.add_stream([frame])

        self.pg0.enable_capture()

        self.pg_start()

        # Pick first received frame and check if it's correctly encapsulated.
        out = self.pg0.get_capture(2)
        ether = out[0]
        pkt = reassemble4(out)
        pkt = ether / pkt
        self.check_encapsulation(pkt, self.single_tunnel_vni)

        payload = self.decapsulate(pkt)
예제 #8
0
 def verify_encrypted(self, p, sa, rxs):
     decrypt_pkts = []
     for rx in rxs:
         self.assert_packet_checksums_valid(rx)
         self.assertEqual(len(rx) - len(Ether()), rx[IP].len)
         try:
             decrypt_pkt = p.vpp_tun_sa.decrypt(rx[IP])
             if not decrypt_pkt.haslayer(IP):
                 decrypt_pkt = IP(decrypt_pkt[Raw].load)
             decrypt_pkts.append(decrypt_pkt)
             self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
             self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
         except:
             self.logger.debug(ppp("Unexpected packet:", rx))
             try:
                 self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
             except:
                 pass
             raise
     pkts = reassemble4(decrypt_pkts)
     for pkt in pkts:
         self.assert_packet_checksums_valid(pkt)
예제 #9
0
    def test_ipip4(self):
        """ ip{v4,v6} over ip4 test """

        self.pg1.generate_remote_hosts(5)
        self.pg1.configure_ipv4_neighbors()
        e = VppEnum.vl_api_tunnel_encap_decap_flags_t
        d = VppEnum.vl_api_ip_dscp_t
        self.p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
        self.p_payload = UDP(sport=1234, dport=1234) / Raw(b'X' * 100)

        # create a TOS byte by shifting a DSCP code point 2 bits. those 2 bits
        # are for the ECN.
        dscp = d.IP_API_DSCP_AF31 << 2
        ecn = 3
        dscp_ecn = d.IP_API_DSCP_AF31 << 2 | ecn

        # IPv4 transport that copies the DCSP from the payload
        tun_dscp = VppIpIpTunInterface(
            self,
            self.pg0,
            self.pg0.local_ip4,
            self.pg1.remote_hosts[0].ip4,
            flags=e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)
        tun_dscp.add_vpp_config()
        # IPv4 transport that copies the DCSP and ECN from the payload
        tun_dscp_ecn = VppIpIpTunInterface(
            self,
            self.pg0,
            self.pg0.local_ip4,
            self.pg1.remote_hosts[1].ip4,
            flags=(e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP
                   | e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN))
        tun_dscp_ecn.add_vpp_config()
        # IPv4 transport that copies the ECN from the payload and sets the
        # DF bit on encap. copies the ECN on decap
        tun_ecn = VppIpIpTunInterface(
            self,
            self.pg0,
            self.pg0.local_ip4,
            self.pg1.remote_hosts[2].ip4,
            flags=(e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN
                   | e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_SET_DF
                   | e.TUNNEL_API_ENCAP_DECAP_FLAG_DECAP_COPY_ECN))
        tun_ecn.add_vpp_config()
        # IPv4 transport that sets a fixed DSCP in the encap and copies
        # the DF bit
        tun = VppIpIpTunInterface(
            self,
            self.pg0,
            self.pg0.local_ip4,
            self.pg1.remote_hosts[3].ip4,
            dscp=d.IP_API_DSCP_AF11,
            flags=e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DF)
        tun.add_vpp_config()

        # array of all the tunnels
        tuns = [tun_dscp, tun_dscp_ecn, tun_ecn, tun]

        # addresses for prefixes routed via each tunnel
        a4s = ["" for i in range(len(tuns))]
        a6s = ["" for i in range(len(tuns))]

        # IP headers with each combination of DSCp/ECN tested
        p_ip6s = [
            IPv6(src="1::1", dst="DEAD::1", nh='UDP', tc=dscp),
            IPv6(src="1::1", dst="DEAD::1", nh='UDP', tc=dscp_ecn),
            IPv6(src="1::1", dst="DEAD::1", nh='UDP', tc=ecn),
            IPv6(src="1::1", dst="DEAD::1", nh='UDP', tc=0xff)
        ]
        p_ip4s = [
            IP(src="1.2.3.4", dst="130.67.0.1", tos=dscp, flags='DF'),
            IP(src="1.2.3.4", dst="130.67.0.1", tos=dscp_ecn),
            IP(src="1.2.3.4", dst="130.67.0.1", tos=ecn),
            IP(src="1.2.3.4", dst="130.67.0.1", tos=0xff)
        ]

        # Configure each tunnel
        for i, t in enumerate(tuns):
            # Set interface up and enable IP on it
            self.vapi.sw_interface_set_flags(t.sw_if_index, 1)
            self.vapi.sw_interface_set_unnumbered(
                sw_if_index=self.pg0.sw_if_index,
                unnumbered_sw_if_index=t.sw_if_index)

            # prefix for route / destination address for packets
            a4s[i] = "130.67.%d.0" % i
            a6s[i] = "dead:%d::" % i

            # Add IPv4 and IPv6 routes via tunnel interface
            ip4_via_tunnel = VppIpRoute(self, a4s[i], 24, [
                VppRoutePath("0.0.0.0",
                             t.sw_if_index,
                             proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)
            ])
            ip4_via_tunnel.add_vpp_config()

            ip6_via_tunnel = VppIpRoute(self, a6s[i], 64, [
                VppRoutePath("::",
                             t.sw_if_index,
                             proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
            ])
            ip6_via_tunnel.add_vpp_config()

        #
        # Encapsulation
        #

        # tun_dscp copies only the dscp
        # expected TC values are thus only the DCSP value is present from the
        # inner
        exp_tcs = [dscp, dscp, 0, 0xfc]
        p_ip44_encaps = [
            IP(src=self.pg0.local_ip4, dst=tun_dscp.dst, tos=tc)
            for tc in exp_tcs
        ]
        p_ip64_encaps = [
            IP(src=self.pg0.local_ip4,
               dst=tun_dscp.dst,
               proto='ipv6',
               id=0,
               tos=tc) for tc in exp_tcs
        ]

        # IPv4 in to IPv4 tunnel
        self.verify_ip4ip4_encaps(a4s[0], p_ip4s, p_ip44_encaps)
        # IPv6 in to IPv4 tunnel
        self.verify_ip6ip4_encaps(a6s[0], p_ip6s, p_ip64_encaps)

        # tun_dscp_ecn copies the dscp and the ecn
        exp_tcs = [dscp, dscp_ecn, ecn, 0xff]
        p_ip44_encaps = [
            IP(src=self.pg0.local_ip4, dst=tun_dscp_ecn.dst, tos=tc)
            for tc in exp_tcs
        ]
        p_ip64_encaps = [
            IP(src=self.pg0.local_ip4,
               dst=tun_dscp_ecn.dst,
               proto='ipv6',
               id=0,
               tos=tc) for tc in exp_tcs
        ]

        self.verify_ip4ip4_encaps(a4s[1], p_ip4s, p_ip44_encaps)
        self.verify_ip6ip4_encaps(a6s[1], p_ip6s, p_ip64_encaps)

        # tun_ecn copies only the ecn and always sets DF
        exp_tcs = [0, ecn, ecn, ecn]
        p_ip44_encaps = [
            IP(src=self.pg0.local_ip4, dst=tun_ecn.dst, flags='DF', tos=tc)
            for tc in exp_tcs
        ]
        p_ip64_encaps = [
            IP(src=self.pg0.local_ip4,
               dst=tun_ecn.dst,
               flags='DF',
               proto='ipv6',
               id=0,
               tos=tc) for tc in exp_tcs
        ]

        self.verify_ip4ip4_encaps(a4s[2], p_ip4s, p_ip44_encaps)
        self.verify_ip6ip4_encaps(a6s[2], p_ip6s, p_ip64_encaps)

        # tun sets a fixed dscp and copies DF
        fixed_dscp = tun.dscp << 2
        flags = ['DF', 0, 0, 0]
        p_ip44_encaps = [
            IP(src=self.pg0.local_ip4, dst=tun.dst, flags=f, tos=fixed_dscp)
            for f in flags
        ]
        p_ip64_encaps = [
            IP(src=self.pg0.local_ip4,
               dst=tun.dst,
               proto='ipv6',
               id=0,
               tos=fixed_dscp) for i in range(len(p_ip4s))
        ]

        self.verify_ip4ip4_encaps(a4s[3], p_ip4s, p_ip44_encaps)
        self.verify_ip6ip4_encaps(a6s[3], p_ip6s, p_ip64_encaps)

        #
        # Decapsulation
        #
        n_packets_decapped = 0
        self.p_ether = Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)

        # IPv4 tunnel to IPv4
        tcs = [0, dscp, dscp_ecn, ecn]

        # one overlay packet and all combinations of its encap
        p_ip4 = IP(src="1.2.3.4", dst=self.pg0.remote_ip4)
        p_ip4_encaps = [
            IP(src=tun.dst, dst=self.pg0.local_ip4, tos=tc) for tc in tcs
        ]

        # for each encap tun will produce the same inner packet because it does
        # not copy up fields from the payload
        for p_ip4_encap in p_ip4_encaps:
            p4 = (self.p_ether / p_ip4_encap / p_ip4 / self.p_payload)
            p4_reply = (p_ip4 / self.p_payload)
            p4_reply.ttl -= 1
            rx = self.send_and_expect(self.pg1, p4 * N_PACKETS, self.pg0)
            n_packets_decapped += N_PACKETS
            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, n_packets_decapped)

        # tun_ecn copies the ECN bits from the encap to the inner
        p_ip4_encaps = [
            IP(src=tun_ecn.dst, dst=self.pg0.local_ip4, tos=tc) for tc in tcs
        ]
        p_ip4_replys = [p_ip4.copy() for i in range(len(p_ip4_encaps))]
        p_ip4_replys[2].tos = ecn
        p_ip4_replys[3].tos = ecn
        for i, p_ip4_encap in enumerate(p_ip4_encaps):
            p4 = (self.p_ether / p_ip4_encap / p_ip4 / self.p_payload)
            p4_reply = (p_ip4_replys[i] / self.p_payload)
            p4_reply.ttl -= 1
            rx = self.send_and_expect(self.pg1, p4 * N_PACKETS, self.pg0)
            n_packets_decapped += N_PACKETS
            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, n_packets_decapped)

        # IPv4 tunnel to IPv6
        # for each encap tun will produce the same inner packet because it does
        # not copy up fields from the payload
        p_ip4_encaps = [
            IP(src=tun.dst, dst=self.pg0.local_ip4, tos=tc) for tc in tcs
        ]
        p_ip6 = IPv6(src="1:2:3::4", dst=self.pg0.remote_ip6)
        for p_ip4_encap in p_ip4_encaps:
            p6 = (self.p_ether / p_ip4_encap / p_ip6 / self.p_payload)
            p6_reply = (p_ip6 / self.p_payload)
            p6_reply.hlim = 63
            rx = self.send_and_expect(self.pg1, p6 * N_PACKETS, self.pg0)
            n_packets_decapped += N_PACKETS
            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, n_packets_decapped)

        # IPv4 tunnel to IPv6
        # tun_ecn copies the ECN bits from the encap to the inner
        p_ip4_encaps = [
            IP(src=tun_ecn.dst, dst=self.pg0.local_ip4, tos=tc) for tc in tcs
        ]
        p_ip6 = IPv6(src="1:2:3::4", dst=self.pg0.remote_ip6)
        p_ip6_replys = [p_ip6.copy() for i in range(len(p_ip4_encaps))]
        p_ip6_replys[2].tc = ecn
        p_ip6_replys[3].tc = ecn
        for i, p_ip4_encap in enumerate(p_ip4_encaps):
            p6 = (self.p_ether / p_ip4_encap / p_ip6 / self.p_payload)
            p6_reply = (p_ip6_replys[i] / self.p_payload)
            p6_reply.hlim = 63
            rx = self.send_and_expect(self.pg1, p6 * N_PACKETS, self.pg0)
            n_packets_decapped += N_PACKETS
            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, n_packets_decapped)

        #
        # 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)
        n_packets_decapped += 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, n_packets_decapped)

        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(tun_dscp.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)
예제 #10
0
    def test_ip4_mtu(self):
        """ IP4 MTU test """

        p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
        p_ip4 = IP(src=self.pg0.remote_ip4,
                   dst=self.pg1.remote_ip4,
                   flags='DF')

        current_mtu = self.get_mtu(self.pg1.sw_if_index)

        p_payload = UDP(sport=1234,
                        dport=1234) / self.payload(current_mtu - 20 - 8)

        p4 = p_ether / p_ip4 / p_payload
        p4_reply = p_ip4 / p_payload
        p4_reply.ttl -= 1
        rx = self.send_and_expect(self.pg0, p4 * 11, self.pg1)
        for p in rx:
            self.validate(p[1], p4_reply)

        # MTU
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [576, 0, 0, 0])
        self.assertEqual(576, self.get_mtu(self.pg1.sw_if_index))

        # Should fail. Too large MTU
        p_icmp4 = ICMP(type='dest-unreach',
                       code='fragmentation-needed',
                       nexthopmtu=576,
                       chksum=0x2dbb)
        icmp4_reply = (IP(src=self.pg0.local_ip4,
                          dst=self.pg0.remote_ip4,
                          ttl=254,
                          len=576,
                          id=0) / p_icmp4 / p_ip4 / p_payload)
        icmp4_reply[1].ttl -= 1
        n = icmp4_reply.__class__(icmp4_reply)
        s = bytes(icmp4_reply)
        icmp4_reply = s[0:576]
        rx = self.send_and_expect(self.pg0, p4 * 11, self.pg0)
        for p in rx:
            # p.show2()
            # n.show2()
            self.validate_bytes(bytes(p[1]), icmp4_reply)

        # Now with DF off. Expect fragments.
        # First go with 1500 byte packets.
        p_payload = UDP(sport=1234, dport=1234) / self.payload(1500 - 20 - 8)
        p4 = p_ether / p_ip4 / p_payload
        p4.flags = 0
        p4_reply = p_ip4 / p_payload
        p4_reply.ttl = 62  # check this
        p4_reply.flags = 0
        p4_reply.id = 256
        self.pg_enable_capture()
        self.pg0.add_stream(p4 * 1)
        self.pg_start()
        rx = self.pg1.get_capture(3)
        reass_pkt = reassemble4(rx)
        self.validate(reass_pkt, p4_reply)
        '''
        # Now what happens with a 9K frame
        p_payload = UDP(sport=1234, dport=1234) / self.payload(
            current_mtu - 20 - 8)
        p4 = p_ether / p_ip4 / p_payload
        p4.flags = 0
        p4_reply = p_ip4 / p_payload
        p4_reply.ttl = 62 # check this
        p4_reply.flags = 0
        p4_reply.id = 512

        self.pg_enable_capture()
        self.pg0.add_stream(p4*1)
        self.pg_start()
        rx = self.pg1.get_capture(16)
        reass_pkt = reassemble4(rx)
        reass_pkt.show2()
        p4_reply.show2()
        self.validate(reass_pkt, p4_reply)
        '''

        # Reset MTU
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index,
                                       [current_mtu, 0, 0, 0])
예제 #11
0
파일: test_mtu.py 프로젝트: vpp-dev/vpp
    def test_ip4_mtu(self):
        """ IP4 MTU test """

        p_ether = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
        p_ip4 = IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4,
                   flags='DF')

        current_mtu = self.get_mtu(self.pg1.sw_if_index)

        p_payload = UDP(sport=1234, dport=1234) / self.payload(
            current_mtu - 20 - 8)

        p4 = p_ether / p_ip4 / p_payload
        p4_reply = p_ip4 / p_payload
        p4_reply.ttl -= 1
        rx = self.send_and_expect(self.pg0, p4*11, self.pg1)
        for p in rx:
            self.validate(p[1], p4_reply)

        # MTU
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [576, 0, 0, 0])
        self.assertEqual(576, self.get_mtu(self.pg1.sw_if_index))

        # Should fail. Too large MTU
        p_icmp4 = ICMP(type='dest-unreach', code='fragmentation-needed',
                       nexthopmtu=576, chksum=0x2dbb)
        icmp4_reply = (IP(src=self.pg0.local_ip4,
                          dst=self.pg0.remote_ip4,
                          ttl=254, len=576, id=0) /
                       p_icmp4 / p_ip4 / p_payload)
        icmp4_reply[1].ttl -= 1
        n = icmp4_reply.__class__(icmp4_reply)
        s = bytes(icmp4_reply)
        icmp4_reply = s[0:576]
        rx = self.send_and_expect(self.pg0, p4*11, self.pg0)
        for p in rx:
            # p.show2()
            # n.show2()
            self.validate_bytes(bytes(p[1]), icmp4_reply)

        # Now with DF off. Expect fragments.
        # First go with 1500 byte packets.
        p_payload = UDP(sport=1234, dport=1234) / self.payload(
            1500 - 20 - 8)
        p4 = p_ether / p_ip4 / p_payload
        p4.flags = 0
        p4_reply = p_ip4 / p_payload
        p4_reply.ttl = 62  # check this
        p4_reply.flags = 0
        p4_reply.id = 256
        self.pg_enable_capture()
        self.pg0.add_stream(p4*1)
        self.pg_start()
        rx = self.pg1.get_capture(3)
        reass_pkt = reassemble4(rx)
        self.validate(reass_pkt, p4_reply)

        '''
        # Now what happens with a 9K frame
        p_payload = UDP(sport=1234, dport=1234) / self.payload(
            current_mtu - 20 - 8)
        p4 = p_ether / p_ip4 / p_payload
        p4.flags = 0
        p4_reply = p_ip4 / p_payload
        p4_reply.ttl = 62 # check this
        p4_reply.flags = 0
        p4_reply.id = 512

        self.pg_enable_capture()
        self.pg0.add_stream(p4*1)
        self.pg_start()
        rx = self.pg1.get_capture(16)
        reass_pkt = reassemble4(rx)
        reass_pkt.show2()
        p4_reply.show2()
        self.validate(reass_pkt, p4_reply)
        '''

        # Reset MTU
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index,
                                       [current_mtu, 0, 0, 0])
예제 #12
0
    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)

        # 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=DpoProto.DPO_PROTO_IP4)
            ],
            is_ip6=0)
        ip4_via_tunnel.add_vpp_config()

        ip6_via_tunnel = VppIpRoute(
            self,
            "dead::",
            16,
            [VppRoutePath("::", sw_if_index, proto=DpoProto.DPO_PROTO_IP6)],
            is_ip6=1)
        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)

        # 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)

        # 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)

        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)

        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.ttl -= 1
        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.ttl -= 1
        p4_reply.id = 512
        self.validate(reass_pkt, p4_reply)
예제 #13
0
파일: test_ipip.py 프로젝트: chrisy/vpp
    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)

        # IPv4 transport
        rv = self.vapi.ipip_add_tunnel(
            src_address=self.pg0.local_ip4n,
            dst_address=self.pg1.remote_ip4n,
            is_ipv6=0, 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=DpoProto.DPO_PROTO_IP4)], is_ip6=0)
        ip4_via_tunnel.add_vpp_config()

        ip6_via_tunnel = VppIpRoute(
            self, "dead::", 16,
            [VppRoutePath("::",
                          sw_if_index,
                          proto=DpoProto.DPO_PROTO_IP6)], is_ip6=1)
        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)

        # 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)

        # 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)

        err = self.statistics.get_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)

        err = self.statistics.get_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)

        # 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_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.ttl -= 1
        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.ttl -= 1
        p4_reply.id = 512
        self.validate(reass_pkt, p4_reply)