Пример #1
0
    def test_mipip4(self):
        """ p2mp IPv4 tunnel Tests """

        for itf in self.pg_interfaces:
            #
            # one underlay nh for each overlay/tunnel peer
            #
            itf.generate_remote_hosts(4)
            itf.configure_ipv4_neighbors()

            #
            # Create an p2mo IPIP tunnel.
            #  - set it admin up
            #  - assign an IP Addres
            #  - Add a route via the tunnel
            #
            ipip_if = VppIpIpTunInterface(
                self,
                itf,
                itf.local_ip4,
                "0.0.0.0",
                mode=(VppEnum.vl_api_tunnel_mode_t.TUNNEL_API_MODE_MP))
            ipip_if.add_vpp_config()
            ipip_if.admin_up()
            ipip_if.config_ip4()
            ipip_if.generate_remote_hosts(4)

            self.logger.info(self.vapi.cli("sh adj"))
            self.logger.info(self.vapi.cli("sh ip fib"))

            #
            # ensure we don't match to the tunnel if the source address
            # is all zeros
            #
            # tx = self.create_tunnel_stream_4o4(self.pg0,
            #                                    "0.0.0.0",
            #                                    itf.local_ip4,
            #                                    self.pg0.local_ip4,
            #                                    self.pg0.remote_ip4)
            # self.send_and_assert_no_replies(self.pg0, tx)

            #
            # for-each peer
            #
            for ii in range(1, 4):
                route_addr = "4.4.4.%d" % ii

                #
                # route traffic via the peer
                #
                route_via_tun = VppIpRoute(self, route_addr, 32, [
                    VppRoutePath(ipip_if._remote_hosts[ii].ip4,
                                 ipip_if.sw_if_index)
                ])
                route_via_tun.add_vpp_config()

                #
                # Add a TEIB entry resolves the peer
                #
                teib = VppTeib(self, ipip_if, ipip_if._remote_hosts[ii].ip4,
                               itf._remote_hosts[ii].ip4)
                teib.add_vpp_config()
                self.logger.info(
                    self.vapi.cli("sh adj nbr ipip0 %s" %
                                  ipip_if._remote_hosts[ii].ip4))

                #
                # Send a packet stream that is routed into the tunnel
                #  - packets are IPIP encapped
                #
                inner = (IP(dst=route_addr, src="5.5.5.5") /
                         UDP(sport=1234, dport=1234) / Raw(b'0x44' * 100))
                tx_e = [
                    (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                     inner) for x in range(63)
                ]

                rxs = self.send_and_expect(self.pg0, tx_e, itf)

                for rx in rxs:
                    self.assertEqual(rx[IP].src, itf.local_ip4)
                    self.assertEqual(rx[IP].dst, itf._remote_hosts[ii].ip4)

                tx_i = [
                    (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                     IP(src=itf._remote_hosts[ii].ip4, dst=itf.local_ip4) /
                     IP(src=self.pg0.local_ip4, dst=self.pg0.remote_ip4) /
                     UDP(sport=1234, dport=1234) / Raw(b'0x44' * 100))
                    for x in range(63)
                ]

                self.logger.info(self.vapi.cli("sh ipip tunnel-hash"))
                rx = self.send_and_expect(self.pg0, tx_i, self.pg0)

                #
                # delete and re-add the TEIB
                #
                teib.remove_vpp_config()
                self.send_and_assert_no_replies(self.pg0, tx_e)
                self.send_and_assert_no_replies(self.pg0, tx_i)

                teib.add_vpp_config()
                rx = self.send_and_expect(self.pg0, tx_e, itf)
                for rx in rxs:
                    self.assertEqual(rx[IP].src, itf.local_ip4)
                    self.assertEqual(rx[IP].dst, itf._remote_hosts[ii].ip4)
                rx = self.send_and_expect(self.pg0, tx_i, self.pg0)

            ipip_if.admin_down()
            ipip_if.unconfig_ip4()
Пример #2
0
    def test_mpls(self):
        """ MPLS over ip{6,4} test """

        tbl = VppMplsTable(self, 0)
        tbl.add_vpp_config()

        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)
        f = FibPathProto

        # IPv4 transport
        tun4 = VppIpIpTunInterface(self, self.pg1, self.pg1.local_ip4,
                                   self.pg1.remote_ip4).add_vpp_config()
        tun4.admin_up()
        tun4.config_ip4()
        tun4.enable_mpls()

        # IPv6 transport
        tun6 = VppIpIpTunInterface(self, self.pg1, self.pg1.local_ip6,
                                   self.pg1.remote_ip6).add_vpp_config()
        tun6.admin_up()
        tun6.config_ip6()
        tun6.enable_mpls()

        # ip routes into the tunnels with output labels
        r4 = VppIpRoute(self, "1.1.1.1", 32, [
            VppRoutePath(
                tun4.remote_ip4, tun4.sw_if_index, labels=[VppMplsLabel(44)])
        ]).add_vpp_config()
        r6 = VppIpRoute(self, "1::1", 128, [
            VppRoutePath(
                tun6.remote_ip6, tun6.sw_if_index, labels=[VppMplsLabel(66)])
        ]).add_vpp_config()

        # deag MPLS routes from the tunnel
        r4 = VppMplsRoute(
            self, 44, 1,
            [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index)
             ]).add_vpp_config()
        r6 = VppMplsRoute(
            self,
            66,
            1, [VppRoutePath(self.pg0.remote_ip6, self.pg0.sw_if_index)],
            eos_proto=f.FIB_PATH_NH_PROTO_IP6).add_vpp_config()

        #
        # Tunnel Encap
        #
        p4 = (self.p_ether / IP(src="2.2.2.2", dst="1.1.1.1") / self.p_payload)

        rxs = self.send_and_expect(self.pg0, p4 * N_PACKETS, self.pg1)

        for rx in rxs:
            self.assertEqual(rx[IP].src, self.pg1.local_ip4)
            self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
            self.assertEqual(rx[MPLS].label, 44)
            inner = rx[MPLS].payload
            self.assertEqual(inner.src, "2.2.2.2")
            self.assertEqual(inner.dst, "1.1.1.1")

        p6 = (self.p_ether / IPv6(src="2::2", dst="1::1") / self.p_payload)

        rxs = self.send_and_expect(self.pg0, p6 * N_PACKETS, self.pg1)

        for rx in rxs:
            self.assertEqual(rx[IPv6].src, self.pg1.local_ip6)
            self.assertEqual(rx[IPv6].dst, self.pg1.remote_ip6)
            self.assertEqual(rx[MPLS].label, 66)
            inner = rx[MPLS].payload
            self.assertEqual(inner.src, "2::2")
            self.assertEqual(inner.dst, "1::1")

        #
        # Tunnel Decap
        #
        p4 = (self.p_ether /
              IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
              MPLS(label=44, ttl=4) / IP(src="1.1.1.1", dst="2.2.2.2") /
              self.p_payload)

        rxs = self.send_and_expect(self.pg1, p4 * N_PACKETS, self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].src, "1.1.1.1")
            self.assertEqual(rx[IP].dst, "2.2.2.2")

        p6 = (self.p_ether /
              IPv6(src=self.pg1.remote_ip6, dst=self.pg1.local_ip6) /
              MPLS(label=66, ttl=4) / IPv6(src="1::1", dst="2::2") /
              self.p_payload)

        rxs = self.send_and_expect(self.pg1, p6 * N_PACKETS, self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IPv6].src, "1::1")
            self.assertEqual(rx[IPv6].dst, "2::2")

        tun4.disable_mpls()
        tun6.disable_mpls()
Пример #3
0
class TestGSO(VppTestCase):
    """ GSO Test Case """
    def __init__(self, *args):
        VppTestCase.__init__(self, *args)

    @classmethod
    def setUpClass(self):
        super(TestGSO, self).setUpClass()
        res = self.create_pg_interfaces(range(2))
        res_gso = self.create_pg_interfaces(range(2, 4), 1, 1460)
        self.create_pg_interfaces(range(4, 5), 1, 8940)
        self.pg_interfaces.append(res[0])
        self.pg_interfaces.append(res[1])
        self.pg_interfaces.append(res_gso[0])
        self.pg_interfaces.append(res_gso[1])

    @classmethod
    def tearDownClass(self):
        super(TestGSO, self).tearDownClass()

    def setUp(self):
        super(TestGSO, self).setUp()
        for i in self.pg_interfaces:
            i.admin_up()
            i.config_ip4()
            i.config_ip6()
            i.disable_ipv6_ra()
            i.resolve_arp()
            i.resolve_ndp()

        self.single_tunnel_bd = 10
        self.vxlan = VppVxlanTunnel(self,
                                    src=self.pg0.local_ip4,
                                    dst=self.pg0.remote_ip4,
                                    vni=self.single_tunnel_bd)

        self.vxlan2 = VppVxlanTunnel(self,
                                     src=self.pg0.local_ip6,
                                     dst=self.pg0.remote_ip6,
                                     vni=self.single_tunnel_bd)

        self.ipip4 = VppIpIpTunInterface(self, self.pg0, self.pg0.local_ip4,
                                         self.pg0.remote_ip4)
        self.ipip6 = VppIpIpTunInterface(self, self.pg0, self.pg0.local_ip6,
                                         self.pg0.remote_ip6)

    def tearDown(self):
        super(TestGSO, self).tearDown()
        if not self.vpp_dead:
            for i in self.pg_interfaces:
                i.unconfig_ip4()
                i.unconfig_ip6()
                i.admin_down()

    def test_gso(self):
        """ GSO test """
        #
        # Send jumbo frame with gso disabled and DF bit is set
        #
        p4 = (
            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
            IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, flags='DF') /
            TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg0, [p4], self.pg0)

        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[ICMP].type, 3)  # "dest-unreach"
            self.assertEqual(rx[ICMP].code, 4)  # "fragmentation-needed"

        #
        # Send checksum offload frames
        #
        p40 = (
            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
            IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4, flags='DF') /
            TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 1460))

        rxs = self.send_and_expect(self.pg2, 100 * [p40], self.pg0)

        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            payload_len = rx[IP].len - 20 - 20
            self.assert_ip_checksum_valid(rx)
            self.assert_tcp_checksum_valid(rx)
            self.assertEqual(payload_len, len(rx[Raw]))

        p60 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
               IPv6(src=self.pg2.remote_ip6, dst=self.pg0.remote_ip6) /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 1440))

        rxs = self.send_and_expect(self.pg2, 100 * [p60], self.pg0)

        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
            payload_len = rx[IPv6].plen - 20
            self.assert_tcp_checksum_valid(rx)
            self.assertEqual(payload_len, len(rx[Raw]))

        #
        # Send jumbo frame with gso enabled and DF bit is set
        # input and output interfaces support GSO
        #
        self.vapi.feature_gso_enable_disable(self.pg3.sw_if_index)
        p41 = (
            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
            IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4, flags='DF') /
            TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 100 * [p41], self.pg3, 100)

        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg3.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
            self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
            self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
            self.assertEqual(rx[IP].len, 65240)  # 65200 + 20 (IP) + 20 (TCP)
            self.assertEqual(rx[TCP].sport, 1234)
            self.assertEqual(rx[TCP].dport, 1234)

        #
        # ipv6
        #
        p61 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
               IPv6(src=self.pg2.remote_ip6, dst=self.pg3.remote_ip6) /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 100 * [p61], self.pg3, 100)

        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg3.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
            self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
            self.assertEqual(rx[IPv6].dst, self.pg3.remote_ip6)
            self.assertEqual(rx[IPv6].plen, 65220)  # 65200 + 20 (TCP)
            self.assertEqual(rx[TCP].sport, 1234)
            self.assertEqual(rx[TCP].dport, 1234)

        #
        # Send jumbo frame with gso enabled only on input interface
        # and DF bit is set. GSO packet will be chunked into gso_size
        # data payload
        #
        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
        p42 = (
            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
            IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4, flags='DF') /
            TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p42], self.pg0, 225)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            payload_len = rx[IP].len - 20 - 20  # len - 20 (IP4) - 20 (TCP)
            self.assert_ip_checksum_valid(rx)
            self.assert_tcp_checksum_valid(rx)
            self.assertEqual(rx[TCP].sport, 1234)
            self.assertEqual(rx[TCP].dport, 1234)
            self.assertEqual(payload_len, len(rx[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        #
        # ipv6
        #
        p62 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
               IPv6(src=self.pg2.remote_ip6, dst=self.pg0.remote_ip6) /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p62], self.pg0, 225)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
            payload_len = rx[IPv6].plen - 20
            self.assert_tcp_checksum_valid(rx)
            self.assertEqual(rx[TCP].sport, 1234)
            self.assertEqual(rx[TCP].dport, 1234)
            self.assertEqual(payload_len, len(rx[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        #
        # Send jumbo frame with gso enabled only on input interface
        # and DF bit is unset. GSO packet will be fragmented.
        #
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [576, 0, 0, 0])
        self.vapi.feature_gso_enable_disable(self.pg1.sw_if_index)

        p43 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
               IP(src=self.pg2.remote_ip4, dst=self.pg1.remote_ip4) /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p43], self.pg1, 5 * 119)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg1.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
            self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
            self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
            self.assert_ip_checksum_valid(rx)
            size += rx[IP].len - 20
        size -= 20 * 5  # TCP header
        self.assertEqual(size, 65200 * 5)

        #
        # IPv6
        # Send jumbo frame with gso enabled only on input interface.
        # ICMPv6 Packet Too Big will be sent back to sender.
        #
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1280, 0, 0, 0])
        p63 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
               IPv6(src=self.pg2.remote_ip6, dst=self.pg1.remote_ip6) /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p63], self.pg2, 5)
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg2.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
            self.assertEqual(rx[IPv6].src, self.pg2.local_ip6)
            self.assertEqual(rx[IPv6].dst, self.pg2.remote_ip6)
            self.assertEqual(rx[IPv6].plen, 1240)  # MTU - IPv6 header
            self.assertEqual(ipv6nh[rx[IPv6].nh], "ICMPv6")
            self.assertEqual(rx[ICMPv6PacketTooBig].mtu, 1280)
            self.assertEqual(rx[IPerror6].src, self.pg2.remote_ip6)
            self.assertEqual(rx[IPerror6].dst, self.pg1.remote_ip6)
            self.assertEqual(rx[IPerror6].plen - 20, 65200)

        #
        # Send jumbo frame with gso enabled only on input interface with 9K MTU
        # and DF bit is unset. GSO packet will be fragmented. MSS is 8960. GSO
        # size will be min(MSS, 2048 - 14 - 20) vlib_buffer_t size
        #
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0])
        self.vapi.sw_interface_set_mtu(self.pg4.sw_if_index, [9000, 0, 0, 0])
        p44 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
               IP(src=self.pg4.remote_ip4, dst=self.pg1.remote_ip4) /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg4, 5 * [p44], self.pg1, 165)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg1.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
            self.assertEqual(rx[IP].src, self.pg4.remote_ip4)
            self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
            payload_len = rx[IP].len - 20 - 20  # len - 20 (IP4) - 20 (TCP)
            self.assert_ip_checksum_valid(rx)
            self.assert_tcp_checksum_valid(rx)
            self.assertEqual(payload_len, len(rx[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        #
        # IPv6
        #
        p64 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
               IPv6(src=self.pg4.remote_ip6, dst=self.pg1.remote_ip6) /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg4, 5 * [p64], self.pg1, 170)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg1.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
            self.assertEqual(rx[IPv6].src, self.pg4.remote_ip6)
            self.assertEqual(rx[IPv6].dst, self.pg1.remote_ip6)
            payload_len = rx[IPv6].plen - 20
            self.assert_tcp_checksum_valid(rx)
            self.assertEqual(payload_len, len(rx[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
                                             enable_disable=0)
        self.vapi.feature_gso_enable_disable(self.pg1.sw_if_index,
                                             enable_disable=0)

    def test_gso_vxlan(self):
        """ GSO VXLAN test """
        self.logger.info(self.vapi.cli("sh int addr"))
        #
        # Send jumbo frame with gso enabled only on input interface and
        # create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg2
        # into BD.
        #

        #
        # enable ipv4/vxlan
        #
        self.vxlan.add_vpp_config()
        self.vapi.sw_interface_set_l2_bridge(
            rx_sw_if_index=self.vxlan.sw_if_index, bd_id=self.single_tunnel_bd)
        self.vapi.sw_interface_set_l2_bridge(
            rx_sw_if_index=self.pg2.sw_if_index, bd_id=self.single_tunnel_bd)
        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)

        #
        # IPv4/IPv4 - VXLAN
        #
        p45 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
               IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p45], self.pg0, 225)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assert_ip_checksum_valid(rx)
            self.assert_udp_checksum_valid(rx)
            self.assertEqual(rx[VXLAN].vni, 10)
            inner = rx[VXLAN].payload
            self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
            self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
            self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
            self.assertEqual(inner[IP].dst, "172.16.3.3")
            self.assert_ip_checksum_valid(inner)
            self.assert_tcp_checksum_valid(inner)
            payload_len = inner[IP].len - 20 - 20
            self.assertEqual(payload_len, len(inner[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        #
        # IPv4/IPv6 - VXLAN
        #
        p65 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
               IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p65], self.pg0, 225)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assert_ip_checksum_valid(rx)
            self.assert_udp_checksum_valid(rx)
            self.assertEqual(rx[VXLAN].vni, 10)
            inner = rx[VXLAN].payload
            self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
            self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
            self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
            self.assertEqual(inner[IPv6].dst, "fd01:3::3")
            self.assert_tcp_checksum_valid(inner)
            payload_len = inner[IPv6].plen - 20
            self.assertEqual(payload_len, len(inner[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        #
        # disable ipv4/vxlan
        #
        self.vxlan.remove_vpp_config()

        #
        # enable ipv6/vxlan
        #
        self.vxlan2.add_vpp_config()
        self.vapi.sw_interface_set_l2_bridge(
            rx_sw_if_index=self.vxlan2.sw_if_index,
            bd_id=self.single_tunnel_bd)

        #
        # IPv6/IPv4 - VXLAN
        #
        p46 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
               IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p46], self.pg0, 225)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
            self.assert_udp_checksum_valid(rx)
            self.assertEqual(rx[VXLAN].vni, 10)
            inner = rx[VXLAN].payload
            self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
            self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
            self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
            self.assertEqual(inner[IP].dst, "172.16.3.3")
            self.assert_ip_checksum_valid(inner)
            self.assert_tcp_checksum_valid(inner)
            payload_len = inner[IP].len - 20 - 20
            self.assertEqual(payload_len, len(inner[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        #
        # IPv6/IPv6 - VXLAN
        #
        p66 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
               IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p66], self.pg0, 225)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
            self.assert_udp_checksum_valid(rx)
            self.assertEqual(rx[VXLAN].vni, 10)
            inner = rx[VXLAN].payload
            self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
            self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
            self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
            self.assertEqual(inner[IPv6].dst, "fd01:3::3")
            self.assert_tcp_checksum_valid(inner)
            payload_len = inner[IPv6].plen - 20
            self.assertEqual(payload_len, len(inner[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        #
        # disable ipv4/vxlan
        #
        self.vxlan2.remove_vpp_config()

        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
                                             enable_disable=0)

    def test_gso_ipip(self):
        """ GSO IPIP test """
        self.logger.info(self.vapi.cli("sh int addr"))
        #
        # Send jumbo frame with gso enabled only on input interface and
        # create IPIP tunnel on VPP pg0.
        #
        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)

        #
        # enable ipip4
        #
        self.ipip4.add_vpp_config()

        # Set interface up and enable IP on it
        self.ipip4.admin_up()
        self.ipip4.set_unnumbered(self.pg0.sw_if_index)

        # Add IPv4 routes via tunnel interface
        self.ip4_via_ip4_tunnel = VppIpRoute(self, "172.16.10.0", 24, [
            VppRoutePath("0.0.0.0",
                         self.ipip4.sw_if_index,
                         proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)
        ])
        self.ip4_via_ip4_tunnel.add_vpp_config()

        #
        # IPv4/IPv4 - IPIP
        #
        p47 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
               IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p47], self.pg0, 225)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assert_ip_checksum_valid(rx)
            self.assertEqual(rx[IP].proto, 4)  # ipencap
            inner = rx[IP].payload
            self.assertEqual(rx[IP].len - 20, len(inner))
            self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
            self.assertEqual(inner[IP].dst, "172.16.10.3")
            self.assert_ip_checksum_valid(inner)
            self.assert_tcp_checksum_valid(inner)
            payload_len = inner[IP].len - 20 - 20
            self.assertEqual(payload_len, len(inner[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        self.ip6_via_ip4_tunnel = VppIpRoute(self, "fd01:10::", 64, [
            VppRoutePath("::",
                         self.ipip4.sw_if_index,
                         proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
        ])
        self.ip6_via_ip4_tunnel.add_vpp_config()
        #
        # IPv4/IPv6 - IPIP
        #
        p67 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
               IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p67], self.pg0, 225)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assert_ip_checksum_valid(rx)
            self.assertEqual(rx[IP].proto, 41)  # ipv6
            inner = rx[IP].payload
            self.assertEqual(rx[IP].len - 20, len(inner))
            self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
            self.assertEqual(inner[IPv6].dst, "fd01:10::3")
            self.assert_tcp_checksum_valid(inner)
            payload_len = inner[IPv6].plen - 20
            self.assertEqual(payload_len, len(inner[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        #
        # Send jumbo frame with gso enabled only on input interface and
        # create IPIP tunnel on VPP pg0. Enable gso feature node on ipip
        # tunnel - IPSec use case
        #
        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
                                             enable_disable=0)
        self.vapi.feature_gso_enable_disable(self.ipip4.sw_if_index)

        rxs = self.send_and_expect(self.pg2, 5 * [p47], self.pg0, 225)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assert_ip_checksum_valid(rx)
            self.assertEqual(rx[IP].proto, 4)  # ipencap
            inner = rx[IP].payload
            self.assertEqual(rx[IP].len - 20, len(inner))
            self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
            self.assertEqual(inner[IP].dst, "172.16.10.3")
            self.assert_ip_checksum_valid(inner)
            self.assert_tcp_checksum_valid(inner)
            payload_len = inner[IP].len - 20 - 20
            self.assertEqual(payload_len, len(inner[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        #
        # disable ipip4
        #
        self.vapi.feature_gso_enable_disable(self.ipip4.sw_if_index,
                                             enable_disable=0)
        self.ip4_via_ip4_tunnel.remove_vpp_config()
        self.ip6_via_ip4_tunnel.remove_vpp_config()
        self.ipip4.remove_vpp_config()

        #
        # enable ipip6
        #
        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
        self.ipip6.add_vpp_config()

        # Set interface up and enable IP on it
        self.ipip6.admin_up()
        self.ipip6.set_unnumbered(self.pg0.sw_if_index)

        # Add IPv4 routes via tunnel interface
        self.ip4_via_ip6_tunnel = VppIpRoute(self, "172.16.10.0", 24, [
            VppRoutePath("0.0.0.0",
                         self.ipip6.sw_if_index,
                         proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)
        ])
        self.ip4_via_ip6_tunnel.add_vpp_config()

        #
        # IPv6/IPv4 - IPIP
        #
        p48 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
               IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p48], self.pg0, 225)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
            self.assertEqual(ipv6nh[rx[IPv6].nh], "IP")
            inner = rx[IPv6].payload
            self.assertEqual(rx[IPv6].plen, len(inner))
            self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
            self.assertEqual(inner[IP].dst, "172.16.10.3")
            self.assert_ip_checksum_valid(inner)
            self.assert_tcp_checksum_valid(inner)
            payload_len = inner[IP].len - 20 - 20
            self.assertEqual(payload_len, len(inner[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        self.ip6_via_ip6_tunnel = VppIpRoute(self, "fd01:10::", 64, [
            VppRoutePath("::",
                         self.ipip6.sw_if_index,
                         proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
        ])
        self.ip6_via_ip6_tunnel.add_vpp_config()

        #
        # IPv6/IPv6 - IPIP
        #
        p68 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
               IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
               TCP(sport=1234, dport=1234) / Raw(b'\xa5' * 65200))

        rxs = self.send_and_expect(self.pg2, 5 * [p68], self.pg0, 225)
        size = 0
        for rx in rxs:
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
            self.assertEqual(ipv6nh[rx[IPv6].nh], "IPv6")
            inner = rx[IPv6].payload
            self.assertEqual(rx[IPv6].plen, len(inner))
            self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
            self.assertEqual(inner[IPv6].dst, "fd01:10::3")
            self.assert_tcp_checksum_valid(inner)
            payload_len = inner[IPv6].plen - 20
            self.assertEqual(payload_len, len(inner[Raw]))
            size += payload_len
        self.assertEqual(size, 65200 * 5)

        #
        # disable ipip6
        #
        self.ip4_via_ip6_tunnel.remove_vpp_config()
        self.ip6_via_ip6_tunnel.remove_vpp_config()
        self.ipip6.remove_vpp_config()

        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
                                             enable_disable=0)
Пример #4
0
    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()