1ead1e536SRenato Botelho do Couto#!/usr/bin/env python3
222e9cfd7SMohsin Kazmi"""GSO functional tests"""
322e9cfd7SMohsin Kazmi
422e9cfd7SMohsin Kazmi#
522e9cfd7SMohsin Kazmi# Add tests for:
622e9cfd7SMohsin Kazmi# - GSO
722e9cfd7SMohsin Kazmi# - Verify that sending Jumbo frame without GSO enabled correctly
822e9cfd7SMohsin Kazmi# - Verify that sending Jumbo frame with GSO enabled correctly
922e9cfd7SMohsin Kazmi# - Verify that sending Jumbo frame with GSO enabled only on ingress interface
1022e9cfd7SMohsin Kazmi#
1122e9cfd7SMohsin Kazmiimport unittest
1222e9cfd7SMohsin Kazmi
1322e9cfd7SMohsin Kazmifrom scapy.packet import Raw
1422e9cfd7SMohsin Kazmifrom scapy.layers.inet6 import IPv6, Ether, IP, UDP, ICMPv6PacketTooBig
150b04209eSMohsin Kazmifrom scapy.layers.inet6 import ipv6nh, IPerror6
1622e9cfd7SMohsin Kazmifrom scapy.layers.inet import TCP, ICMP
1722e9cfd7SMohsin Kazmifrom scapy.layers.vxlan import VXLAN
1822e9cfd7SMohsin Kazmifrom scapy.data import ETH_P_IP, ETH_P_IPV6, ETH_P_ARP
1922e9cfd7SMohsin Kazmi
2022e9cfd7SMohsin Kazmifrom framework import VppTestCase, VppTestRunner
2122e9cfd7SMohsin Kazmifrom vpp_object import VppObject
2222e9cfd7SMohsin Kazmifrom vpp_interface import VppInterface
2322e9cfd7SMohsin Kazmifrom vpp_ip import DpoProto
2422e9cfd7SMohsin Kazmifrom vpp_ip_route import VppIpRoute, VppRoutePath, FibPathProto
2584f91fa9SMohsin Kazmifrom vpp_ipip_tun_interface import VppIpIpTunInterface
260b04209eSMohsin Kazmifrom vpp_vxlan_tunnel import VppVxlanTunnel
2722e9cfd7SMohsin Kazmifrom socket import AF_INET, AF_INET6, inet_pton
2822e9cfd7SMohsin Kazmifrom util import reassemble4
2922e9cfd7SMohsin Kazmi
3022e9cfd7SMohsin Kazmi
3122e9cfd7SMohsin Kazmi""" Test_gso is a subclass of VPPTestCase classes.
3222e9cfd7SMohsin Kazmi    GSO tests.
3322e9cfd7SMohsin Kazmi"""
3422e9cfd7SMohsin Kazmi
3522e9cfd7SMohsin Kazmi
3622e9cfd7SMohsin Kazmiclass TestGSO(VppTestCase):
3722e9cfd7SMohsin Kazmi    """ GSO Test Case """
3822e9cfd7SMohsin Kazmi
3922e9cfd7SMohsin Kazmi    def __init__(self, *args):
4022e9cfd7SMohsin Kazmi        VppTestCase.__init__(self, *args)
4122e9cfd7SMohsin Kazmi
4222e9cfd7SMohsin Kazmi    @classmethod
4322e9cfd7SMohsin Kazmi    def setUpClass(self):
4422e9cfd7SMohsin Kazmi        super(TestGSO, self).setUpClass()
450b04209eSMohsin Kazmi        res = self.create_pg_interfaces(range(2))
460b04209eSMohsin Kazmi        res_gso = self.create_pg_interfaces(range(2, 4), 1, 1460)
470b04209eSMohsin Kazmi        self.create_pg_interfaces(range(4, 5), 1, 8940)
480b04209eSMohsin Kazmi        self.pg_interfaces.append(res[0])
490b04209eSMohsin Kazmi        self.pg_interfaces.append(res[1])
500b04209eSMohsin Kazmi        self.pg_interfaces.append(res_gso[0])
510b04209eSMohsin Kazmi        self.pg_interfaces.append(res_gso[1])
5222e9cfd7SMohsin Kazmi
5322e9cfd7SMohsin Kazmi    @classmethod
5422e9cfd7SMohsin Kazmi    def tearDownClass(self):
5522e9cfd7SMohsin Kazmi        super(TestGSO, self).tearDownClass()
5622e9cfd7SMohsin Kazmi
5722e9cfd7SMohsin Kazmi    def setUp(self):
5822e9cfd7SMohsin Kazmi        super(TestGSO, self).setUp()
590b04209eSMohsin Kazmi        for i in self.pg_interfaces:
600b04209eSMohsin Kazmi            i.admin_up()
610b04209eSMohsin Kazmi            i.config_ip4()
620b04209eSMohsin Kazmi            i.config_ip6()
630b04209eSMohsin Kazmi            i.disable_ipv6_ra()
640b04209eSMohsin Kazmi            i.resolve_arp()
650b04209eSMohsin Kazmi            i.resolve_ndp()
660b04209eSMohsin Kazmi
670b04209eSMohsin Kazmi        self.single_tunnel_bd = 10
680b04209eSMohsin Kazmi        self.vxlan = VppVxlanTunnel(self, src=self.pg0.local_ip4,
690b04209eSMohsin Kazmi                                    dst=self.pg0.remote_ip4,
700b04209eSMohsin Kazmi                                    vni=self.single_tunnel_bd)
710b04209eSMohsin Kazmi
720b04209eSMohsin Kazmi        self.vxlan2 = VppVxlanTunnel(self, src=self.pg0.local_ip6,
730b04209eSMohsin Kazmi                                     dst=self.pg0.remote_ip6,
740b04209eSMohsin Kazmi                                     vni=self.single_tunnel_bd)
7584f91fa9SMohsin Kazmi
7684f91fa9SMohsin Kazmi        self.ipip4 = VppIpIpTunInterface(self, self.pg0, self.pg0.local_ip4,
7784f91fa9SMohsin Kazmi                                         self.pg0.remote_ip4)
7884f91fa9SMohsin Kazmi        self.ipip6 = VppIpIpTunInterface(self, self.pg0, self.pg0.local_ip6,
7984f91fa9SMohsin Kazmi                                         self.pg0.remote_ip6)
8022e9cfd7SMohsin Kazmi
8122e9cfd7SMohsin Kazmi    def tearDown(self):
8222e9cfd7SMohsin Kazmi        super(TestGSO, self).tearDown()
8322e9cfd7SMohsin Kazmi        if not self.vpp_dead:
8422e9cfd7SMohsin Kazmi            for i in self.pg_interfaces:
8522e9cfd7SMohsin Kazmi                i.unconfig_ip4()
8622e9cfd7SMohsin Kazmi                i.unconfig_ip6()
8722e9cfd7SMohsin Kazmi                i.admin_down()
8822e9cfd7SMohsin Kazmi
8922e9cfd7SMohsin Kazmi    def test_gso(self):
9022e9cfd7SMohsin Kazmi        """ GSO test """
9122e9cfd7SMohsin Kazmi        #
9222e9cfd7SMohsin Kazmi        # Send jumbo frame with gso disabled and DF bit is set
9322e9cfd7SMohsin Kazmi        #
9422e9cfd7SMohsin Kazmi        p4 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9522e9cfd7SMohsin Kazmi              IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4,
9622e9cfd7SMohsin Kazmi                 flags='DF') /
9722e9cfd7SMohsin Kazmi              TCP(sport=1234, dport=1234) /
982915649fSOle Troan              Raw(b'\xa5' * 65200))
9922e9cfd7SMohsin Kazmi
10022e9cfd7SMohsin Kazmi        rxs = self.send_and_expect(self.pg0, [p4], self.pg0)
10122e9cfd7SMohsin Kazmi
10222e9cfd7SMohsin Kazmi        for rx in rxs:
10322e9cfd7SMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
10422e9cfd7SMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
10522e9cfd7SMohsin Kazmi            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
10622e9cfd7SMohsin Kazmi            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
10722e9cfd7SMohsin Kazmi            self.assertEqual(rx[ICMP].type, 3)  # "dest-unreach"
10822e9cfd7SMohsin Kazmi            self.assertEqual(rx[ICMP].code, 4)  # "fragmentation-needed"
10922e9cfd7SMohsin Kazmi
11022e9cfd7SMohsin Kazmi        #
11122e9cfd7SMohsin Kazmi        # Send jumbo frame with gso enabled and DF bit is set
11222e9cfd7SMohsin Kazmi        # input and output interfaces support GSO
11322e9cfd7SMohsin Kazmi        #
11422e9cfd7SMohsin Kazmi        p41 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
11522e9cfd7SMohsin Kazmi               IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4,
11622e9cfd7SMohsin Kazmi                  flags='DF') /
11722e9cfd7SMohsin Kazmi               TCP(sport=1234, dport=1234) /
1182915649fSOle Troan               Raw(b'\xa5' * 65200))
11922e9cfd7SMohsin Kazmi
12022e9cfd7SMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p41], self.pg3)
12122e9cfd7SMohsin Kazmi
12222e9cfd7SMohsin Kazmi        for rx in rxs:
12322e9cfd7SMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg3.local_mac)
12422e9cfd7SMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
12522e9cfd7SMohsin Kazmi            self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
12622e9cfd7SMohsin Kazmi            self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
12722e9cfd7SMohsin Kazmi            self.assertEqual(rx[IP].len, 65240)  # 65200 + 20 (IP) + 20 (TCP)
12822e9cfd7SMohsin Kazmi            self.assertEqual(rx[TCP].sport, 1234)
12922e9cfd7SMohsin Kazmi            self.assertEqual(rx[TCP].dport, 1234)
13022e9cfd7SMohsin Kazmi
1310b04209eSMohsin Kazmi        #
1320b04209eSMohsin Kazmi        # ipv6
1330b04209eSMohsin Kazmi        #
1340b04209eSMohsin Kazmi        p61 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
1350b04209eSMohsin Kazmi               IPv6(src=self.pg2.remote_ip6, dst=self.pg3.remote_ip6) /
1360b04209eSMohsin Kazmi               TCP(sport=1234, dport=1234) /
1370b04209eSMohsin Kazmi               Raw(b'\xa5' * 65200))
1380b04209eSMohsin Kazmi
1390b04209eSMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p61], self.pg3)
1400b04209eSMohsin Kazmi
1410b04209eSMohsin Kazmi        for rx in rxs:
1420b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg3.local_mac)
1430b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
1440b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
1450b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].dst, self.pg3.remote_ip6)
1460b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].plen, 65220)  # 65200 + 20 (TCP)
1470b04209eSMohsin Kazmi            self.assertEqual(rx[TCP].sport, 1234)
1480b04209eSMohsin Kazmi            self.assertEqual(rx[TCP].dport, 1234)
1490b04209eSMohsin Kazmi
15022e9cfd7SMohsin Kazmi        #
15122e9cfd7SMohsin Kazmi        # Send jumbo frame with gso enabled only on input interface
15222e9cfd7SMohsin Kazmi        # and DF bit is set. GSO packet will be chunked into gso_size
15322e9cfd7SMohsin Kazmi        # data payload
15422e9cfd7SMohsin Kazmi        #
1550b04209eSMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
15622e9cfd7SMohsin Kazmi        p42 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
1570b04209eSMohsin Kazmi               IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4,
15822e9cfd7SMohsin Kazmi                  flags='DF') /
15922e9cfd7SMohsin Kazmi               TCP(sport=1234, dport=1234) /
1602915649fSOle Troan               Raw(b'\xa5' * 65200))
16122e9cfd7SMohsin Kazmi
1620b04209eSMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p42], self.pg0, 45)
16322e9cfd7SMohsin Kazmi        size = 0
16422e9cfd7SMohsin Kazmi        for rx in rxs:
1650b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1660b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
16722e9cfd7SMohsin Kazmi            self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
1680b04209eSMohsin Kazmi            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
16922e9cfd7SMohsin Kazmi            self.assertEqual(rx[TCP].sport, 1234)
17022e9cfd7SMohsin Kazmi            self.assertEqual(rx[TCP].dport, 1234)
17122e9cfd7SMohsin Kazmi
17222e9cfd7SMohsin Kazmi        size = rxs[44][TCP].seq + rxs[44][IP].len - 20 - 20
17322e9cfd7SMohsin Kazmi        self.assertEqual(size, 65200)
17422e9cfd7SMohsin Kazmi
1750b04209eSMohsin Kazmi        #
1760b04209eSMohsin Kazmi        # ipv6
1770b04209eSMohsin Kazmi        #
1780b04209eSMohsin Kazmi        p62 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
1790b04209eSMohsin Kazmi               IPv6(src=self.pg2.remote_ip6, dst=self.pg0.remote_ip6) /
1800b04209eSMohsin Kazmi               TCP(sport=1234, dport=1234) /
1810b04209eSMohsin Kazmi               Raw(b'\xa5' * 65200))
1820b04209eSMohsin Kazmi
1830b04209eSMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p62], self.pg0, 45)
1840b04209eSMohsin Kazmi        size = 0
1850b04209eSMohsin Kazmi        for rx in rxs:
1860b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1870b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1880b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
1890b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
1900b04209eSMohsin Kazmi            self.assertEqual(rx[TCP].sport, 1234)
1910b04209eSMohsin Kazmi            self.assertEqual(rx[TCP].dport, 1234)
1920b04209eSMohsin Kazmi
1930b04209eSMohsin Kazmi        size = rxs[44][TCP].seq + rxs[44][IPv6].plen - 20
1940b04209eSMohsin Kazmi        self.assertEqual(size, 65200)
1950b04209eSMohsin Kazmi
19622e9cfd7SMohsin Kazmi        #
19722e9cfd7SMohsin Kazmi        # Send jumbo frame with gso enabled only on input interface
19822e9cfd7SMohsin Kazmi        # and DF bit is unset. GSO packet will be fragmented.
19922e9cfd7SMohsin Kazmi        #
20022e9cfd7SMohsin Kazmi        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [576, 0, 0, 0])
2010b04209eSMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.pg1.sw_if_index)
20222e9cfd7SMohsin Kazmi
20322e9cfd7SMohsin Kazmi        p43 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
20422e9cfd7SMohsin Kazmi               IP(src=self.pg2.remote_ip4, dst=self.pg1.remote_ip4) /
20522e9cfd7SMohsin Kazmi               TCP(sport=1234, dport=1234) /
2062915649fSOle Troan               Raw(b'\xa5' * 65200))
20722e9cfd7SMohsin Kazmi
20822e9cfd7SMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p43], self.pg1, 119)
20922e9cfd7SMohsin Kazmi        size = 0
21022e9cfd7SMohsin Kazmi        for rx in rxs:
21122e9cfd7SMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg1.local_mac)
21222e9cfd7SMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
21322e9cfd7SMohsin Kazmi            self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
21422e9cfd7SMohsin Kazmi            self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
21522e9cfd7SMohsin Kazmi            size += rx[IP].len - 20
21622e9cfd7SMohsin Kazmi        size -= 20  # TCP header
21722e9cfd7SMohsin Kazmi        self.assertEqual(size, 65200)
21822e9cfd7SMohsin Kazmi
2190b04209eSMohsin Kazmi        #
2200b04209eSMohsin Kazmi        # IPv6
2210b04209eSMohsin Kazmi        # Send jumbo frame with gso enabled only on input interface.
2220b04209eSMohsin Kazmi        # ICMPv6 Packet Too Big will be sent back to sender.
2230b04209eSMohsin Kazmi        #
2240b04209eSMohsin Kazmi        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1280, 0, 0, 0])
2250b04209eSMohsin Kazmi        p63 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
2260b04209eSMohsin Kazmi               IPv6(src=self.pg2.remote_ip6, dst=self.pg1.remote_ip6) /
2270b04209eSMohsin Kazmi               TCP(sport=1234, dport=1234) /
2280b04209eSMohsin Kazmi               Raw(b'\xa5' * 65200))
2290b04209eSMohsin Kazmi
2300b04209eSMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p63], self.pg2, 1)
2310b04209eSMohsin Kazmi        for rx in rxs:
2320b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg2.local_mac)
2330b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
2340b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].src, self.pg2.local_ip6)
2350b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].dst, self.pg2.remote_ip6)
2360b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].plen, 1240)  # MTU - IPv6 header
2370b04209eSMohsin Kazmi            self.assertEqual(ipv6nh[rx[IPv6].nh], "ICMPv6")
2380b04209eSMohsin Kazmi            self.assertEqual(rx[ICMPv6PacketTooBig].mtu, 1280)
2390b04209eSMohsin Kazmi            self.assertEqual(rx[IPerror6].src, self.pg2.remote_ip6)
2400b04209eSMohsin Kazmi            self.assertEqual(rx[IPerror6].dst, self.pg1.remote_ip6)
2410b04209eSMohsin Kazmi            self.assertEqual(rx[IPerror6].plen - 20, 65200)
2420b04209eSMohsin Kazmi
2433f1964d2SMohsin Kazmi        #
2443f1964d2SMohsin Kazmi        # Send jumbo frame with gso enabled only on input interface with 9K MTU
2450b04209eSMohsin Kazmi        # and DF bit is unset. GSO packet will be fragmented. MSS is 8960. GSO
2460b04209eSMohsin Kazmi        # size will be min(MSS, 2048 - 14 - 20) vlib_buffer_t size
2473f1964d2SMohsin Kazmi        #
2483f1964d2SMohsin Kazmi        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0])
2490b04209eSMohsin Kazmi        self.vapi.sw_interface_set_mtu(self.pg4.sw_if_index, [9000, 0, 0, 0])
2500b04209eSMohsin Kazmi        p44 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2510b04209eSMohsin Kazmi               IP(src=self.pg4.remote_ip4, dst=self.pg1.remote_ip4) /
2523f1964d2SMohsin Kazmi               TCP(sport=1234, dport=1234) /
2532915649fSOle Troan               Raw(b'\xa5' * 65200))
2543f1964d2SMohsin Kazmi
2553f1964d2SMohsin Kazmi        self.pg1.enable_capture()
2560b04209eSMohsin Kazmi        rxs = self.send_and_expect(self.pg4, [p44], self.pg1, 33)
2573f1964d2SMohsin Kazmi        size = 0
2583f1964d2SMohsin Kazmi        for rx in rxs:
2593f1964d2SMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg1.local_mac)
2603f1964d2SMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
2610b04209eSMohsin Kazmi            self.assertEqual(rx[IP].src, self.pg4.remote_ip4)
2623f1964d2SMohsin Kazmi            self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
2633f1964d2SMohsin Kazmi        size = rxs[32][TCP].seq + rxs[32][IP].len - 20 - 20
2643f1964d2SMohsin Kazmi        self.assertEqual(size, 65200)
2653f1964d2SMohsin Kazmi
2660b04209eSMohsin Kazmi        #
2670b04209eSMohsin Kazmi        # IPv6
2680b04209eSMohsin Kazmi        #
2690b04209eSMohsin Kazmi        p64 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2700b04209eSMohsin Kazmi               IPv6(src=self.pg4.remote_ip6, dst=self.pg1.remote_ip6) /
2710b04209eSMohsin Kazmi               TCP(sport=1234, dport=1234) /
2720b04209eSMohsin Kazmi               Raw(b'\xa5' * 65200))
2730b04209eSMohsin Kazmi
2740b04209eSMohsin Kazmi        self.pg1.enable_capture()
2750b04209eSMohsin Kazmi        rxs = self.send_and_expect(self.pg4, [p64], self.pg1, 34)
2760b04209eSMohsin Kazmi        size = 0
2770b04209eSMohsin Kazmi        for rx in rxs:
2780b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg1.local_mac)
2790b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
2800b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].src, self.pg4.remote_ip6)
2810b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].dst, self.pg1.remote_ip6)
2820b04209eSMohsin Kazmi        size = rxs[33][TCP].seq + rxs[33][IPv6].plen - 20
2830b04209eSMohsin Kazmi        self.assertEqual(size, 65200)
2840b04209eSMohsin Kazmi
2851ab8b3c6SMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
2861ab8b3c6SMohsin Kazmi                                             enable_disable=0)
2871ab8b3c6SMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.pg1.sw_if_index,
2881ab8b3c6SMohsin Kazmi                                             enable_disable=0)
2891ab8b3c6SMohsin Kazmi
2900b04209eSMohsin Kazmi    def test_gso_vxlan(self):
2910b04209eSMohsin Kazmi        """ GSO VXLAN test """
2920b04209eSMohsin Kazmi        self.logger.info(self.vapi.cli("sh int addr"))
2930b04209eSMohsin Kazmi        #
2940b04209eSMohsin Kazmi        # Send jumbo frame with gso enabled only on input interface and
2950b04209eSMohsin Kazmi        # create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg2
2960b04209eSMohsin Kazmi        # into BD.
2970b04209eSMohsin Kazmi        #
29884f91fa9SMohsin Kazmi
29984f91fa9SMohsin Kazmi        #
30084f91fa9SMohsin Kazmi        # enable ipv4/vxlan
30184f91fa9SMohsin Kazmi        #
30284f91fa9SMohsin Kazmi        self.vxlan.add_vpp_config()
3030b04209eSMohsin Kazmi        self.vapi.sw_interface_set_l2_bridge(
3040b04209eSMohsin Kazmi            rx_sw_if_index=self.vxlan.sw_if_index, bd_id=self.single_tunnel_bd)
3050b04209eSMohsin Kazmi        self.vapi.sw_interface_set_l2_bridge(
3060b04209eSMohsin Kazmi            rx_sw_if_index=self.pg2.sw_if_index, bd_id=self.single_tunnel_bd)
3070b04209eSMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
3080b04209eSMohsin Kazmi
3090b04209eSMohsin Kazmi        #
3100b04209eSMohsin Kazmi        # IPv4/IPv4 - VXLAN
3110b04209eSMohsin Kazmi        #
3120b04209eSMohsin Kazmi        p45 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
3130b04209eSMohsin Kazmi               IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
3140b04209eSMohsin Kazmi               TCP(sport=1234, dport=1234) /
3150b04209eSMohsin Kazmi               Raw(b'\xa5' * 65200))
3160b04209eSMohsin Kazmi
3170b04209eSMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p45], self.pg0, 45)
3180b04209eSMohsin Kazmi        size = 0
3190b04209eSMohsin Kazmi        for rx in rxs:
3200b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
3210b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
3220b04209eSMohsin Kazmi            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
3230b04209eSMohsin Kazmi            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
3240b04209eSMohsin Kazmi            self.assertEqual(rx[VXLAN].vni, 10)
3250b04209eSMohsin Kazmi            inner = rx[VXLAN].payload
3260b04209eSMohsin Kazmi            self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
3270b04209eSMohsin Kazmi            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
3280b04209eSMohsin Kazmi            self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
3290b04209eSMohsin Kazmi            self.assertEqual(inner[IP].dst, "172.16.3.3")
3300b04209eSMohsin Kazmi            size += inner[IP].len - 20 - 20
3310b04209eSMohsin Kazmi        self.assertEqual(size, 65200)
3320b04209eSMohsin Kazmi
3330b04209eSMohsin Kazmi        #
3340b04209eSMohsin Kazmi        # IPv4/IPv6 - VXLAN
3350b04209eSMohsin Kazmi        #
3360b04209eSMohsin Kazmi        p65 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
3370b04209eSMohsin Kazmi               IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
3380b04209eSMohsin Kazmi               TCP(sport=1234, dport=1234) /
3390b04209eSMohsin Kazmi               Raw(b'\xa5' * 65200))
3400b04209eSMohsin Kazmi
3410b04209eSMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p65], self.pg0, 45)
3420b04209eSMohsin Kazmi        size = 0
3430b04209eSMohsin Kazmi        for rx in rxs:
3440b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
3450b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
3460b04209eSMohsin Kazmi            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
3470b04209eSMohsin Kazmi            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
3480b04209eSMohsin Kazmi            self.assertEqual(rx[VXLAN].vni, 10)
3490b04209eSMohsin Kazmi            inner = rx[VXLAN].payload
3500b04209eSMohsin Kazmi            self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
3510b04209eSMohsin Kazmi            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
3520b04209eSMohsin Kazmi            self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
3530b04209eSMohsin Kazmi            self.assertEqual(inner[IPv6].dst, "fd01:3::3")
3540b04209eSMohsin Kazmi            size += inner[IPv6].plen - 20
3550b04209eSMohsin Kazmi        self.assertEqual(size, 65200)
3560b04209eSMohsin Kazmi
3570b04209eSMohsin Kazmi        #
3580b04209eSMohsin Kazmi        # disable ipv4/vxlan
3590b04209eSMohsin Kazmi        #
3600b04209eSMohsin Kazmi        self.vxlan.remove_vpp_config()
3610b04209eSMohsin Kazmi
3620b04209eSMohsin Kazmi        #
3630b04209eSMohsin Kazmi        # enable ipv6/vxlan
3640b04209eSMohsin Kazmi        #
36584f91fa9SMohsin Kazmi        self.vxlan2.add_vpp_config()
3660b04209eSMohsin Kazmi        self.vapi.sw_interface_set_l2_bridge(
3670b04209eSMohsin Kazmi            rx_sw_if_index=self.vxlan2.sw_if_index,
3680b04209eSMohsin Kazmi            bd_id=self.single_tunnel_bd)
3690b04209eSMohsin Kazmi
3700b04209eSMohsin Kazmi        #
3710b04209eSMohsin Kazmi        # IPv6/IPv4 - VXLAN
3720b04209eSMohsin Kazmi        #
3730b04209eSMohsin Kazmi        p46 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
3740b04209eSMohsin Kazmi               IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
3750b04209eSMohsin Kazmi               TCP(sport=1234, dport=1234) /
3760b04209eSMohsin Kazmi               Raw(b'\xa5' * 65200))
3770b04209eSMohsin Kazmi
3780b04209eSMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p46], self.pg0, 45)
3790b04209eSMohsin Kazmi        size = 0
3800b04209eSMohsin Kazmi        for rx in rxs:
3810b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
3820b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
3830b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
3840b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
3850b04209eSMohsin Kazmi            self.assertEqual(rx[VXLAN].vni, 10)
3860b04209eSMohsin Kazmi            inner = rx[VXLAN].payload
3870b04209eSMohsin Kazmi            self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
3880b04209eSMohsin Kazmi            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
3890b04209eSMohsin Kazmi            self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
3900b04209eSMohsin Kazmi            self.assertEqual(inner[IP].dst, "172.16.3.3")
3910b04209eSMohsin Kazmi            size += inner[IP].len - 20 - 20
3920b04209eSMohsin Kazmi        self.assertEqual(size, 65200)
3930b04209eSMohsin Kazmi
3940b04209eSMohsin Kazmi        #
3950b04209eSMohsin Kazmi        # IPv6/IPv6 - VXLAN
3960b04209eSMohsin Kazmi        #
3970b04209eSMohsin Kazmi        p66 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
3980b04209eSMohsin Kazmi               IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
3990b04209eSMohsin Kazmi               TCP(sport=1234, dport=1234) /
4000b04209eSMohsin Kazmi               Raw(b'\xa5' * 65200))
4010b04209eSMohsin Kazmi
4020b04209eSMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p66], self.pg0, 45)
4030b04209eSMohsin Kazmi        size = 0
4040b04209eSMohsin Kazmi        for rx in rxs:
4050b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
4060b04209eSMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
4070b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
4080b04209eSMohsin Kazmi            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
4090b04209eSMohsin Kazmi            self.assertEqual(rx[VXLAN].vni, 10)
4100b04209eSMohsin Kazmi            inner = rx[VXLAN].payload
4110b04209eSMohsin Kazmi            self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
4120b04209eSMohsin Kazmi            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
4130b04209eSMohsin Kazmi            self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
4140b04209eSMohsin Kazmi            self.assertEqual(inner[IPv6].dst, "fd01:3::3")
4150b04209eSMohsin Kazmi            size += inner[IPv6].plen - 20
4160b04209eSMohsin Kazmi        self.assertEqual(size, 65200)
4170b04209eSMohsin Kazmi
41884f91fa9SMohsin Kazmi        #
41984f91fa9SMohsin Kazmi        # disable ipv4/vxlan
42084f91fa9SMohsin Kazmi        #
42184f91fa9SMohsin Kazmi        self.vxlan2.remove_vpp_config()
42284f91fa9SMohsin Kazmi
4231ab8b3c6SMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
4241ab8b3c6SMohsin Kazmi                                             enable_disable=0)
4251ab8b3c6SMohsin Kazmi
42684f91fa9SMohsin Kazmi    def test_gso_ipip(self):
42784f91fa9SMohsin Kazmi        """ GSO IPIP test """
42884f91fa9SMohsin Kazmi        self.logger.info(self.vapi.cli("sh int addr"))
42984f91fa9SMohsin Kazmi        #
43084f91fa9SMohsin Kazmi        # Send jumbo frame with gso enabled only on input interface and
43184f91fa9SMohsin Kazmi        # create IPIP tunnel on VPP pg0.
43284f91fa9SMohsin Kazmi        #
43384f91fa9SMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
43484f91fa9SMohsin Kazmi
43584f91fa9SMohsin Kazmi        #
43684f91fa9SMohsin Kazmi        # enable ipip4
43784f91fa9SMohsin Kazmi        #
43884f91fa9SMohsin Kazmi        self.ipip4.add_vpp_config()
43984f91fa9SMohsin Kazmi
44084f91fa9SMohsin Kazmi        # Set interface up and enable IP on it
44184f91fa9SMohsin Kazmi        self.ipip4.admin_up()
44284f91fa9SMohsin Kazmi        self.ipip4.set_unnumbered(self.pg0.sw_if_index)
44384f91fa9SMohsin Kazmi
44484f91fa9SMohsin Kazmi        # Add IPv4 routes via tunnel interface
44584f91fa9SMohsin Kazmi        self.ip4_via_ip4_tunnel = VppIpRoute(
44684f91fa9SMohsin Kazmi                self, "172.16.10.0", 24,
44784f91fa9SMohsin Kazmi                [VppRoutePath("0.0.0.0",
44884f91fa9SMohsin Kazmi                              self.ipip4.sw_if_index,
44984f91fa9SMohsin Kazmi                              proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)])
45084f91fa9SMohsin Kazmi        self.ip4_via_ip4_tunnel.add_vpp_config()
45184f91fa9SMohsin Kazmi
45284f91fa9SMohsin Kazmi        #
45384f91fa9SMohsin Kazmi        # IPv4/IPv4 - IPIP
45484f91fa9SMohsin Kazmi        #
45584f91fa9SMohsin Kazmi        p47 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
45684f91fa9SMohsin Kazmi               IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
45784f91fa9SMohsin Kazmi               TCP(sport=1234, dport=1234) /
45884f91fa9SMohsin Kazmi               Raw(b'\xa5' * 65200))
45984f91fa9SMohsin Kazmi
46084f91fa9SMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p47], self.pg0, 45)
46184f91fa9SMohsin Kazmi        size = 0
46284f91fa9SMohsin Kazmi        for rx in rxs:
46384f91fa9SMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
46484f91fa9SMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
46584f91fa9SMohsin Kazmi            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
46684f91fa9SMohsin Kazmi            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
46784f91fa9SMohsin Kazmi            self.assertEqual(rx[IP].proto, 4)  # ipencap
46884f91fa9SMohsin Kazmi            inner = rx[IP].payload
46984f91fa9SMohsin Kazmi            self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
47084f91fa9SMohsin Kazmi            self.assertEqual(inner[IP].dst, "172.16.10.3")
47184f91fa9SMohsin Kazmi            size += inner[IP].len - 20 - 20
47284f91fa9SMohsin Kazmi        self.assertEqual(size, 65200)
47384f91fa9SMohsin Kazmi
47484f91fa9SMohsin Kazmi        self.ip6_via_ip4_tunnel = VppIpRoute(
47584f91fa9SMohsin Kazmi                self, "fd01:10::", 64,
47684f91fa9SMohsin Kazmi                [VppRoutePath("::",
47784f91fa9SMohsin Kazmi                              self.ipip4.sw_if_index,
47884f91fa9SMohsin Kazmi                              proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
47984f91fa9SMohsin Kazmi        self.ip6_via_ip4_tunnel.add_vpp_config()
48084f91fa9SMohsin Kazmi        #
48184f91fa9SMohsin Kazmi        # IPv4/IPv6 - IPIP
48284f91fa9SMohsin Kazmi        #
48384f91fa9SMohsin Kazmi        p67 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
48484f91fa9SMohsin Kazmi               IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
48584f91fa9SMohsin Kazmi               TCP(sport=1234, dport=1234) /
48684f91fa9SMohsin Kazmi               Raw(b'\xa5' * 65200))
48784f91fa9SMohsin Kazmi
48884f91fa9SMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p67], self.pg0, 45)
48984f91fa9SMohsin Kazmi        size = 0
49084f91fa9SMohsin Kazmi        for rx in rxs:
49184f91fa9SMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
49284f91fa9SMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
49384f91fa9SMohsin Kazmi            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
49484f91fa9SMohsin Kazmi            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
49584f91fa9SMohsin Kazmi            self.assertEqual(rx[IP].proto, 41)  # ipv6
49684f91fa9SMohsin Kazmi            inner = rx[IP].payload
49784f91fa9SMohsin Kazmi            self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
49884f91fa9SMohsin Kazmi            self.assertEqual(inner[IPv6].dst, "fd01:10::3")
49984f91fa9SMohsin Kazmi            size += inner[IPv6].plen - 20
50084f91fa9SMohsin Kazmi        self.assertEqual(size, 65200)
50184f91fa9SMohsin Kazmi
50284f91fa9SMohsin Kazmi        #
50384f91fa9SMohsin Kazmi        # Send jumbo frame with gso enabled only on input interface and
50484f91fa9SMohsin Kazmi        # create IPIP tunnel on VPP pg0. Enable gso feature node on ipip
50584f91fa9SMohsin Kazmi        # tunnel - IPSec use case
50684f91fa9SMohsin Kazmi        #
5071ab8b3c6SMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
5081ab8b3c6SMohsin Kazmi                                             enable_disable=0)
50984f91fa9SMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.ipip4.sw_if_index)
51084f91fa9SMohsin Kazmi
51184f91fa9SMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p47], self.pg0, 45)
51284f91fa9SMohsin Kazmi        size = 0
51384f91fa9SMohsin Kazmi        for rx in rxs:
51484f91fa9SMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
51584f91fa9SMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
51684f91fa9SMohsin Kazmi            self.assertEqual(rx[IP].src, self.pg0.local_ip4)
51784f91fa9SMohsin Kazmi            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
51884f91fa9SMohsin Kazmi            self.assertEqual(rx[IP].proto, 4)  # ipencap
51984f91fa9SMohsin Kazmi            inner = rx[IP].payload
52084f91fa9SMohsin Kazmi            self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
52184f91fa9SMohsin Kazmi            self.assertEqual(inner[IP].dst, "172.16.10.3")
52284f91fa9SMohsin Kazmi            size += inner[IP].len - 20 - 20
52384f91fa9SMohsin Kazmi        self.assertEqual(size, 65200)
52484f91fa9SMohsin Kazmi
52584f91fa9SMohsin Kazmi        #
52684f91fa9SMohsin Kazmi        # disable ipip4
52784f91fa9SMohsin Kazmi        #
5281ab8b3c6SMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.ipip4.sw_if_index,
5291ab8b3c6SMohsin Kazmi                                             enable_disable=0)
53084f91fa9SMohsin Kazmi        self.ip4_via_ip4_tunnel.remove_vpp_config()
53184f91fa9SMohsin Kazmi        self.ip6_via_ip4_tunnel.remove_vpp_config()
53284f91fa9SMohsin Kazmi        self.ipip4.remove_vpp_config()
53384f91fa9SMohsin Kazmi
53484f91fa9SMohsin Kazmi        #
53584f91fa9SMohsin Kazmi        # enable ipip6
53684f91fa9SMohsin Kazmi        #
53784f91fa9SMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
53884f91fa9SMohsin Kazmi        self.ipip6.add_vpp_config()
53984f91fa9SMohsin Kazmi
54084f91fa9SMohsin Kazmi        # Set interface up and enable IP on it
54184f91fa9SMohsin Kazmi        self.ipip6.admin_up()
54284f91fa9SMohsin Kazmi        self.ipip6.set_unnumbered(self.pg0.sw_if_index)
54384f91fa9SMohsin Kazmi
54484f91fa9SMohsin Kazmi        # Add IPv4 routes via tunnel interface
54584f91fa9SMohsin Kazmi        self.ip4_via_ip6_tunnel = VppIpRoute(
54684f91fa9SMohsin Kazmi                self, "172.16.10.0", 24,
54784f91fa9SMohsin Kazmi                [VppRoutePath("0.0.0.0",
54884f91fa9SMohsin Kazmi                              self.ipip6.sw_if_index,
54984f91fa9SMohsin Kazmi                              proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)])
55084f91fa9SMohsin Kazmi        self.ip4_via_ip6_tunnel.add_vpp_config()
55184f91fa9SMohsin Kazmi
55284f91fa9SMohsin Kazmi        #
55384f91fa9SMohsin Kazmi        # IPv6/IPv4 - IPIP
55484f91fa9SMohsin Kazmi        #
55584f91fa9SMohsin Kazmi        p48 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
55684f91fa9SMohsin Kazmi               IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
55784f91fa9SMohsin Kazmi               TCP(sport=1234, dport=1234) /
55884f91fa9SMohsin Kazmi               Raw(b'\xa5' * 65200))
55984f91fa9SMohsin Kazmi
56084f91fa9SMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p48], self.pg0, 45)
56184f91fa9SMohsin Kazmi        size = 0
56284f91fa9SMohsin Kazmi        for rx in rxs:
56384f91fa9SMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
56484f91fa9SMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
56584f91fa9SMohsin Kazmi            self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
56684f91fa9SMohsin Kazmi            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
56784f91fa9SMohsin Kazmi            self.assertEqual(ipv6nh[rx[IPv6].nh], "IP")
56884f91fa9SMohsin Kazmi            inner = rx[IPv6].payload
56984f91fa9SMohsin Kazmi            self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
57084f91fa9SMohsin Kazmi            self.assertEqual(inner[IP].dst, "172.16.10.3")
57184f91fa9SMohsin Kazmi            size += inner[IP].len - 20 - 20
57284f91fa9SMohsin Kazmi        self.assertEqual(size, 65200)
57384f91fa9SMohsin Kazmi
57484f91fa9SMohsin Kazmi        self.ip6_via_ip6_tunnel = VppIpRoute(
57584f91fa9SMohsin Kazmi                self, "fd01:10::", 64,
57684f91fa9SMohsin Kazmi                [VppRoutePath("::",
57784f91fa9SMohsin Kazmi                              self.ipip6.sw_if_index,
57884f91fa9SMohsin Kazmi                              proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
57984f91fa9SMohsin Kazmi        self.ip6_via_ip6_tunnel.add_vpp_config()
58084f91fa9SMohsin Kazmi
58184f91fa9SMohsin Kazmi        #
58284f91fa9SMohsin Kazmi        # IPv6/IPv6 - IPIP
58384f91fa9SMohsin Kazmi        #
58484f91fa9SMohsin Kazmi        p68 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
58584f91fa9SMohsin Kazmi               IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
58684f91fa9SMohsin Kazmi               TCP(sport=1234, dport=1234) /
58784f91fa9SMohsin Kazmi               Raw(b'\xa5' * 65200))
58884f91fa9SMohsin Kazmi
58984f91fa9SMohsin Kazmi        rxs = self.send_and_expect(self.pg2, [p68], self.pg0, 45)
59084f91fa9SMohsin Kazmi        size = 0
59184f91fa9SMohsin Kazmi        for rx in rxs:
59284f91fa9SMohsin Kazmi            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
59384f91fa9SMohsin Kazmi            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
59484f91fa9SMohsin Kazmi            self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
59584f91fa9SMohsin Kazmi            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
59684f91fa9SMohsin Kazmi            self.assertEqual(ipv6nh[rx[IPv6].nh], "IPv6")
59784f91fa9SMohsin Kazmi            inner = rx[IPv6].payload
59884f91fa9SMohsin Kazmi            self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
59984f91fa9SMohsin Kazmi            self.assertEqual(inner[IPv6].dst, "fd01:10::3")
60084f91fa9SMohsin Kazmi            size += inner[IPv6].plen - 20
60184f91fa9SMohsin Kazmi        self.assertEqual(size, 65200)
60284f91fa9SMohsin Kazmi
60384f91fa9SMohsin Kazmi        #
60484f91fa9SMohsin Kazmi        # disable ipip6
60584f91fa9SMohsin Kazmi        #
60684f91fa9SMohsin Kazmi        self.ip4_via_ip6_tunnel.remove_vpp_config()
60784f91fa9SMohsin Kazmi        self.ip6_via_ip6_tunnel.remove_vpp_config()
60884f91fa9SMohsin Kazmi        self.ipip6.remove_vpp_config()
60984f91fa9SMohsin Kazmi
6101ab8b3c6SMohsin Kazmi        self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
6111ab8b3c6SMohsin Kazmi                                             enable_disable=0)
6121ab8b3c6SMohsin Kazmi
61322e9cfd7SMohsin Kazmiif __name__ == '__main__':
61422e9cfd7SMohsin Kazmi    unittest.main(testRunner=VppTestRunner)
615