tests: Use errno value rather than a specific int
[vpp.git] / test / test_ip4.py
index 9079e54..926ca77 100644 (file)
@@ -1,19 +1,18 @@
 #!/usr/bin/env python3
-import binascii
 import random
 import socket
 import unittest
 
-import scapy.compat
 from scapy.contrib.mpls import MPLS
+from scapy.contrib.gtp import GTP_U_Header
 from scapy.layers.inet import IP, UDP, TCP, ICMP, icmptypes, icmpcodes
 from scapy.layers.inet6 import IPv6
 from scapy.layers.l2 import Ether, Dot1Q, ARP
 from scapy.packet import Raw
 from six import moves
 
-from framework import tag_fixme_vpp_workers
-from framework import VppTestCase, VppTestRunner
+from framework import VppTestCase
+from asfframework import VppTestRunner, tag_fixme_vpp_workers
 from util import ppp
 from vpp_ip_route import (
     VppIpRoute,
@@ -562,7 +561,6 @@ class TestIPv4FibCrud(VppTestCase):
         return routes
 
     def unconfig_fib_many_to_one(self, start_dest_addr, next_hop_addr, count, start=0):
-
         routes = []
         for i in range(count):
             r = VppIpRoute(
@@ -1210,6 +1208,7 @@ class TestIPLoadBalance(VppTestCase):
         """IP Load-Balancing"""
 
         fhc = VppEnum.vl_api_ip_flow_hash_config_t
+        fhcv2 = VppEnum.vl_api_ip_flow_hash_config_v2_t
         af = VppEnum.vl_api_address_family_t
 
         #
@@ -1217,16 +1216,20 @@ class TestIPLoadBalance(VppTestCase):
         #
         port_ip_pkts = []
         port_mpls_pkts = []
+        port_gtp_pkts = []
 
         #
         # An array of packets that differ only in the source address
         #
         src_ip_pkts = []
         src_mpls_pkts = []
+        src_gtp_pkts = []
 
         for ii in range(NUM_PKTS):
+            internal_src_ip_hdr = IP(dst="10.0.0.1", src="20.0.0.1")
+
             port_ip_hdr = (
-                IP(dst="10.0.0.1", src="20.0.0.1")
+                internal_src_ip_hdr
                 / UDP(sport=1234, dport=1234 + ii)
                 / Raw(b"\xa5" * 100)
             )
@@ -1240,6 +1243,15 @@ class TestIPLoadBalance(VppTestCase):
                     / port_ip_hdr
                 )
             )
+            port_gtp_pkts.append(
+                (
+                    Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
+                    / internal_src_ip_hdr
+                    / UDP(sport=2152, dport=2152, chksum=0)
+                    / GTP_U_Header(gtp_type="g_pdu", teid=200)
+                    / Raw(b"\xa5" * 100)
+                )
+            )
 
             src_ip_hdr = (
                 IP(dst="10.0.0.1", src="20.0.0.%d" % ii)
@@ -1256,6 +1268,15 @@ class TestIPLoadBalance(VppTestCase):
                     / src_ip_hdr
                 )
             )
+            src_gtp_pkts.append(
+                (
+                    Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
+                    / IP(dst="10.0.0.1", src="20.0.0.1")
+                    / UDP(sport=2152, dport=2152, chksum=0)
+                    / GTP_U_Header(gtp_type="g_pdu", teid=ii)
+                    / Raw(b"\xa5" * 100)
+                )
+            )
 
         route_10_0_0_1 = VppIpRoute(
             self,
@@ -1330,6 +1351,26 @@ class TestIPLoadBalance(VppTestCase):
 
         self.send_and_expect_only(self.pg0, port_ip_pkts, self.pg2)
 
+        #
+        # this case gtp v1 teid key LB
+        #
+        self.vapi.set_ip_flow_hash_v3(
+            af=af.ADDRESS_IP4,
+            table_id=0,
+            flow_hash_config=(
+                fhcv2.IP_API_V2_FLOW_HASH_SRC_IP
+                | fhcv2.IP_API_V2_FLOW_HASH_PROTO
+                | fhcv2.IP_API_V2_FLOW_HASH_GTPV1_TEID
+            ),
+        )
+        self.logger.info(self.vapi.cli("show ip fib"))
+
+        self.send_and_expect_load_balancing(
+            self.pg0, src_gtp_pkts, [self.pg1, self.pg2]
+        )
+
+        self.send_and_expect_only(self.pg0, port_gtp_pkts, self.pg2)
+
         #
         # change the flow hash config back to defaults
         #
@@ -1793,9 +1834,7 @@ class TestIPPunt(IPPuntSetup, VppTestCase):
         self.send_and_assert_no_replies(self.pg0, [pkts[0]])
         self.send_and_assert_no_replies(self.pg0, pkts)
 
-        self.assert_error_counter_equal(
-            "/err/ip4-local/ip4 source lookup miss", len(pkts) + 1
-        )
+        self.assert_error_counter_equal("/err/ip4-local/src_lookup_miss", len(pkts) + 1)
 
         # using the same source in different tables, should reject
         # for the table that the source is not present in
@@ -1855,9 +1894,7 @@ class TestIPPunt(IPPuntSetup, VppTestCase):
         self.send_and_assert_no_replies(self.pg0, [pkts[0]])
         self.send_and_assert_no_replies(self.pg0, pkts)
 
-        self.assert_error_counter_equal(
-            "/err/ip6-input/ip6 source lookup miss", len(pkts) + 1
-        )
+        self.assert_error_counter_equal("/err/ip6-input/src_lookup_miss", len(pkts) + 1)
 
         # using the same source in different tables, should reject
         # for the table that the source is not present in
@@ -3258,5 +3295,138 @@ class TestIPv4ItfRebind(VppTestCase):
             i.admin_down()
 
 
+class TestIP4InterfaceRx(VppTestCase):
+    """IPv4 Interface Receive"""
+
+    @classmethod
+    def setUpClass(cls):
+        super(TestIP4InterfaceRx, cls).setUpClass()
+
+    @classmethod
+    def tearDownClass(cls):
+        super(TestIP4InterfaceRx, cls).tearDownClass()
+
+    def setUp(self):
+        super(TestIP4InterfaceRx, self).setUp()
+
+        self.create_pg_interfaces(range(3))
+
+        table_id = 0
+
+        for i in self.pg_interfaces:
+            i.admin_up()
+
+            if table_id != 0:
+                table = VppIpTable(self, table_id)
+                table.add_vpp_config()
+
+            i.set_table_ip4(table_id)
+            i.config_ip4()
+            i.resolve_arp()
+            table_id += 1
+
+    def tearDown(self):
+        for i in self.pg_interfaces:
+            i.unconfig_ip4()
+            i.admin_down()
+            i.set_table_ip4(0)
+
+        super(TestIP4InterfaceRx, self).tearDown()
+
+    def test_interface_rx(self):
+        """IPv4 Interface Receive"""
+
+        #
+        # add a route in the default table to receive ...
+        #
+        route_to_dst = VppIpRoute(
+            self,
+            "1.1.1.0",
+            24,
+            [
+                VppRoutePath(
+                    "0.0.0.0",
+                    self.pg1.sw_if_index,
+                    type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
+                )
+            ],
+        )
+        route_to_dst.add_vpp_config()
+
+        #
+        # packets to these destination are dropped, since they'll
+        # hit the respective default routes in table 1
+        #
+        p_dst = (
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
+            / IP(src="5.5.5.5", dst="1.1.1.1")
+            / TCP(sport=1234, dport=1234)
+            / Raw(b"\xa5" * 100)
+        )
+        pkts_dst = p_dst * 10
+
+        self.send_and_assert_no_replies(self.pg0, pkts_dst, "IP in table 1")
+
+        #
+        # add a route in the dst table to forward via pg1
+        #
+        route_in_dst = VppIpRoute(
+            self,
+            "1.1.1.1",
+            32,
+            [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
+            table_id=1,
+        )
+        route_in_dst.add_vpp_config()
+
+        self.send_and_expect(self.pg0, pkts_dst, self.pg1)
+
+        #
+        # add a route in the default table to receive ...
+        #
+        route_to_dst = VppIpRoute(
+            self,
+            "1.1.1.0",
+            24,
+            [
+                VppRoutePath(
+                    "0.0.0.0",
+                    self.pg2.sw_if_index,
+                    type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
+                )
+            ],
+            table_id=1,
+        )
+        route_to_dst.add_vpp_config()
+
+        #
+        # packets to these destination are dropped, since they'll
+        # hit the respective default routes in table 2
+        #
+        p_dst = (
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
+            / IP(src="6.6.6.6", dst="1.1.1.2")
+            / TCP(sport=1234, dport=1234)
+            / Raw(b"\xa5" * 100)
+        )
+        pkts_dst = p_dst * 10
+
+        self.send_and_assert_no_replies(self.pg0, pkts_dst, "IP in table 2")
+
+        #
+        # add a route in the table 2 to forward via pg2
+        #
+        route_in_dst = VppIpRoute(
+            self,
+            "1.1.1.2",
+            32,
+            [VppRoutePath(self.pg2.remote_ip4, self.pg2.sw_if_index)],
+            table_id=2,
+        )
+        route_in_dst.add_vpp_config()
+
+        self.send_and_expect(self.pg0, pkts_dst, self.pg2)
+
+
 if __name__ == "__main__":
     unittest.main(testRunner=VppTestRunner)