Typos. A bunch of typos I've been collecting.
[vpp.git] / test / test_srv6.py
index 4c46380..ed453b2 100644 (file)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
 import unittest
 #!/usr/bin/env python
 
 import unittest
+import binascii
 from socket import AF_INET6
 
 from framework import VppTestCase, VppTestRunner
 from socket import AF_INET6
 
 from framework import VppTestCase, VppTestRunner
@@ -8,6 +9,7 @@ from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto, VppIpTable
 from vpp_srv6 import SRv6LocalSIDBehaviors, VppSRv6LocalSID, VppSRv6Policy, \
     SRv6PolicyType, VppSRv6Steering, SRv6PolicySteeringTypes
 
 from vpp_srv6 import SRv6LocalSIDBehaviors, VppSRv6LocalSID, VppSRv6Policy, \
     SRv6PolicyType, VppSRv6Steering, SRv6PolicySteeringTypes
 
+import scapy.compat
 from scapy.packet import Raw
 from scapy.layers.l2 import Ether, Dot1Q
 from scapy.layers.inet6 import IPv6, UDP, IPv6ExtHdrSegmentRouting
 from scapy.packet import Raw
 from scapy.layers.l2 import Ether, Dot1Q
 from scapy.layers.inet6 import IPv6, UDP, IPv6ExtHdrSegmentRouting
@@ -100,19 +102,6 @@ class TestSRv6(VppTestCase):
         # create 'count' pg interfaces
         self.create_pg_interfaces(range(count))
 
         # create 'count' pg interfaces
         self.create_pg_interfaces(range(count))
 
-        # create all tables
-        self.tables = []
-        ids = sorted(set(ipv4_table_id))
-        for i in range(len(ids)):
-            if 0 != ids[i]:
-                self.tables.append(VppIpTable(self, ids[i]))
-        ids = sorted(set(ipv6_table_id))
-        for i in range(len(ids)):
-            if 0 != ids[i]:
-                self.tables.append(VppIpTable(self, ids[i], is_ip6=1))
-        for t in self.tables:
-            t.add_vpp_config()
-
         # setup all interfaces
         for i in range(count):
             intf = self.pg_interfaces[i]
         # setup all interfaces
         for i in range(count):
             intf = self.pg_interfaces[i]
@@ -137,11 +126,12 @@ class TestSRv6(VppTestCase):
         # AFAIK they cannot be deleted
         for i in self.pg_interfaces:
             self.logger.debug("Tear down interface %s" % (i.name))
         # AFAIK they cannot be deleted
         for i in self.pg_interfaces:
             self.logger.debug("Tear down interface %s" % (i.name))
+            i.admin_down()
             i.unconfig()
             i.set_table_ip4(0)
             i.set_table_ip6(0)
             i.unconfig()
             i.set_table_ip4(0)
             i.set_table_ip6(0)
-            i.admin_down()
 
 
+    @unittest.skipUnless(0, "PC to fix")
     def test_SRv6_T_Encaps(self):
         """ Test SRv6 Transit.Encaps behavior for IPv6.
         """
     def test_SRv6_T_Encaps(self):
         """ Test SRv6 Transit.Encaps behavior for IPv6.
         """
@@ -243,6 +233,7 @@ class TestSRv6(VppTestCase):
         # cleanup interfaces
         self.teardown_interfaces()
 
         # cleanup interfaces
         self.teardown_interfaces()
 
+    @unittest.skipUnless(0, "PC to fix")
     def test_SRv6_T_Insert(self):
         """ Test SRv6 Transit.Insert behavior (IPv6 only).
         """
     def test_SRv6_T_Insert(self):
         """ Test SRv6 Transit.Insert behavior (IPv6 only).
         """
@@ -334,6 +325,7 @@ class TestSRv6(VppTestCase):
         # cleanup interfaces
         self.teardown_interfaces()
 
         # cleanup interfaces
         self.teardown_interfaces()
 
+    @unittest.skipUnless(0, "PC to fix")
     def test_SRv6_T_Encaps_IPv4(self):
         """ Test SRv6 Transit.Encaps behavior for IPv4.
         """
     def test_SRv6_T_Encaps_IPv4(self):
         """ Test SRv6 Transit.Encaps behavior for IPv4.
         """
@@ -523,9 +515,10 @@ class TestSRv6(VppTestCase):
 
         # configure SRv6 localSID End without PSP behavior
         localsid = VppSRv6LocalSID(
 
         # configure SRv6 localSID End without PSP behavior
         localsid = VppSRv6LocalSID(
-                        self, localsid_addr='A3::0',
+                        self, localsid={'addr': 'A3::0'},
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_END,
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_END,
-                        nh_addr='::',
+                        nh_addr4='0.0.0.0',
+                        nh_addr6='::',
                         end_psp=0,
                         sw_if_index=0,
                         vlan_index=0,
                         end_psp=0,
                         sw_if_index=0,
                         vlan_index=0,
@@ -594,9 +587,10 @@ class TestSRv6(VppTestCase):
 
         # configure SRv6 localSID End with PSP behavior
         localsid = VppSRv6LocalSID(
 
         # configure SRv6 localSID End with PSP behavior
         localsid = VppSRv6LocalSID(
-                        self, localsid_addr='A3::0',
+                        self, localsid={'addr': 'A3::0'},
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_END,
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_END,
-                        nh_addr='::',
+                        nh_addr4='0.0.0.0',
+                        nh_addr6='::',
                         end_psp=1,
                         sw_if_index=0,
                         vlan_index=0,
                         end_psp=1,
                         sw_if_index=0,
                         vlan_index=0,
@@ -669,9 +663,10 @@ class TestSRv6(VppTestCase):
         # configure SRv6 localSID End.X without PSP behavior
         # End.X points to interface pg1
         localsid = VppSRv6LocalSID(
         # configure SRv6 localSID End.X without PSP behavior
         # End.X points to interface pg1
         localsid = VppSRv6LocalSID(
-                        self, localsid_addr='A3::C4',
+                        self, localsid={'addr': 'A3::C4'},
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_X,
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_X,
-                        nh_addr=self.pg1.remote_ip6,
+                        nh_addr4='0.0.0.0',
+                        nh_addr6=self.pg1.remote_ip6,
                         end_psp=0,
                         sw_if_index=self.pg1.sw_if_index,
                         vlan_index=0,
                         end_psp=0,
                         sw_if_index=self.pg1.sw_if_index,
                         vlan_index=0,
@@ -746,9 +741,10 @@ class TestSRv6(VppTestCase):
 
         # configure SRv6 localSID End with PSP behavior
         localsid = VppSRv6LocalSID(
 
         # configure SRv6 localSID End with PSP behavior
         localsid = VppSRv6LocalSID(
-                        self, localsid_addr='A3::C4',
+                        self, localsid={'addr': 'A3::C4'},
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_X,
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_X,
-                        nh_addr=self.pg1.remote_ip6,
+                        nh_addr4='0.0.0.0',
+                        nh_addr6=self.pg1.remote_ip6,
                         end_psp=1,
                         sw_if_index=self.pg1.sw_if_index,
                         vlan_index=0,
                         end_psp=1,
                         sw_if_index=self.pg1.sw_if_index,
                         vlan_index=0,
@@ -811,9 +807,10 @@ class TestSRv6(VppTestCase):
 
         # configure SRv6 localSID End.DX6 behavior
         localsid = VppSRv6LocalSID(
 
         # configure SRv6 localSID End.DX6 behavior
         localsid = VppSRv6LocalSID(
-                        self, localsid_addr='a3::c4',
+                        self, localsid={'addr': 'A3::C4'},
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DX6,
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DX6,
-                        nh_addr=self.pg1.remote_ip6,
+                        nh_addr4='0.0.0.0',
+                        nh_addr6=self.pg1.remote_ip6,
                         end_psp=0,
                         sw_if_index=self.pg1.sw_if_index,
                         vlan_index=0,
                         end_psp=0,
                         sw_if_index=self.pg1.sw_if_index,
                         vlan_index=0,
@@ -867,6 +864,8 @@ class TestSRv6(VppTestCase):
         # source interface in global FIB (0)
         # destination interfaces in global and vrf
         vrf_1 = 1
         # source interface in global FIB (0)
         # destination interfaces in global and vrf
         vrf_1 = 1
+        ipt = VppIpTable(self, vrf_1, is_ip6=True)
+        ipt.add_vpp_config()
         self.setup_interfaces(ipv6=[True, True, True],
                               ipv6_table_id=[0, 0, vrf_1])
 
         self.setup_interfaces(ipv6=[True, True, True],
                               ipv6_table_id=[0, 0, vrf_1])
 
@@ -897,9 +896,10 @@ class TestSRv6(VppTestCase):
         # fib_table: where the localsid is installed
         # sw_if_index: in T-variants of localsid this is the vrf table_id
         localsid = VppSRv6LocalSID(
         # fib_table: where the localsid is installed
         # sw_if_index: in T-variants of localsid this is the vrf table_id
         localsid = VppSRv6LocalSID(
-                        self, localsid_addr='a3::c4',
+                        self, localsid={'addr': 'A3::C4'},
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DT6,
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DT6,
-                        nh_addr='::',
+                        nh_addr4='0.0.0.0',
+                        nh_addr6='::',
                         end_psp=0,
                         sw_if_index=vrf_1,
                         vlan_index=0,
                         end_psp=0,
                         sw_if_index=vrf_1,
                         vlan_index=0,
@@ -962,9 +962,10 @@ class TestSRv6(VppTestCase):
 
         # configure SRv6 localSID End.DX4 behavior
         localsid = VppSRv6LocalSID(
 
         # configure SRv6 localSID End.DX4 behavior
         localsid = VppSRv6LocalSID(
-                        self, localsid_addr='a3::c4',
+                        self, localsid={'addr': 'A3::C4'},
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DX4,
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DX4,
-                        nh_addr=self.pg1.remote_ip4,
+                        nh_addr4=self.pg1.remote_ip4,
+                        nh_addr6='::',
                         end_psp=0,
                         sw_if_index=self.pg1.sw_if_index,
                         vlan_index=0,
                         end_psp=0,
                         sw_if_index=self.pg1.sw_if_index,
                         vlan_index=0,
@@ -1018,6 +1019,8 @@ class TestSRv6(VppTestCase):
         # source interface in global FIB (0)
         # destination interfaces in global and vrf
         vrf_1 = 1
         # source interface in global FIB (0)
         # destination interfaces in global and vrf
         vrf_1 = 1
+        ipt = VppIpTable(self, vrf_1)
+        ipt.add_vpp_config()
         self.setup_interfaces(ipv6=[True, False, False],
                               ipv4=[False, True, True],
                               ipv6_table_id=[0, 0, 0],
         self.setup_interfaces(ipv6=[True, False, False],
                               ipv4=[False, True, True],
                               ipv6_table_id=[0, 0, 0],
@@ -1048,9 +1051,10 @@ class TestSRv6(VppTestCase):
         # fib_table: where the localsid is installed
         # sw_if_index: in T-variants of localsid: vrf table_id
         localsid = VppSRv6LocalSID(
         # fib_table: where the localsid is installed
         # sw_if_index: in T-variants of localsid: vrf table_id
         localsid = VppSRv6LocalSID(
-                        self, localsid_addr='a3::c4',
+                        self, localsid={'addr': 'A3::C4'},
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DT4,
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DT4,
-                        nh_addr='::',
+                        nh_addr4='0.0.0.0',
+                        nh_addr6='::',
                         end_psp=0,
                         sw_if_index=vrf_1,
                         vlan_index=0,
                         end_psp=0,
                         sw_if_index=vrf_1,
                         vlan_index=0,
@@ -1112,9 +1116,10 @@ class TestSRv6(VppTestCase):
 
         # configure SRv6 localSID End.DX2 behavior
         localsid = VppSRv6LocalSID(
 
         # configure SRv6 localSID End.DX2 behavior
         localsid = VppSRv6LocalSID(
-                        self, localsid_addr='a3::c4',
+                        self, localsid={'addr': 'A3::C4'},
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DX2,
                         behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DX2,
-                        nh_addr='::',
+                        nh_addr4='0.0.0.0',
+                        nh_addr6='::',
                         end_psp=0,
                         sw_if_index=self.pg1.sw_if_index,
                         vlan_index=0,
                         end_psp=0,
                         sw_if_index=self.pg1.sw_if_index,
                         vlan_index=0,
@@ -1180,6 +1185,151 @@ class TestSRv6(VppTestCase):
         # cleanup interfaces
         self.teardown_interfaces()
 
         # cleanup interfaces
         self.teardown_interfaces()
 
+    @unittest.skipUnless(0, "PC to fix")
+    def test_SRv6_T_Insert_Classifier(self):
+        """ Test SRv6 Transit.Insert behavior (IPv6 only).
+            steer packets using the classifier
+        """
+        # send traffic to one destination interface
+        # source and destination are IPv6 only
+        self.setup_interfaces(ipv6=[False, False, False, True, True])
+
+        # configure FIB entries
+        route = VppIpRoute(self, "a4::", 64,
+                           [VppRoutePath(self.pg4.remote_ip6,
+                                         self.pg4.sw_if_index,
+                                         proto=DpoProto.DPO_PROTO_IP6)],
+                           is_ip6=1)
+        route.add_vpp_config()
+
+        # configure encaps IPv6 source address
+        # needs to be done before SR Policy config
+        # TODO: API?
+        self.vapi.cli("set sr encaps source addr a3::")
+
+        bsid = 'a3::9999:1'
+        # configure SRv6 Policy
+        # Note: segment list order: first -> last
+        sr_policy = VppSRv6Policy(
+            self, bsid=bsid,
+            is_encap=0,
+            sr_type=SRv6PolicyType.SR_POLICY_TYPE_DEFAULT,
+            weight=1, fib_table=0,
+            segments=['a4::', 'a5::', 'a6::c7'],
+            source='a3::')
+        sr_policy.add_vpp_config()
+        self.sr_policy = sr_policy
+
+        # log the sr policies
+        self.logger.info(self.vapi.cli("show sr policies"))
+
+        # add classify table
+        # mask on dst ip address prefix a7::/8
+        mask = '{!s:0<16}'.format('ff')
+        r = self.vapi.classify_add_del_table(
+            1,
+            binascii.unhexlify(mask),
+            match_n_vectors=(len(mask) - 1) // 32 + 1,
+            current_data_flag=1,
+            skip_n_vectors=2)  # data offset
+        self.assertIsNotNone(r, 'No response msg for add_del_table')
+        table_index = r.new_table_index
+
+        # add the source routing node as a ip6 inacl netxt node
+        r = self.vapi.add_node_next('ip6-inacl',
+                                    'sr-pl-rewrite-insert')
+        inacl_next_node_index = r.node_index
+
+        match = '{!s:0<16}'.format('a7')
+        r = self.vapi.classify_add_del_session(
+            1,
+            table_index,
+            binascii.unhexlify(match),
+            hit_next_index=inacl_next_node_index,
+            action=3,
+            metadata=0)  # sr policy index
+        self.assertIsNotNone(r, 'No response msg for add_del_session')
+
+        # log the classify table used in the steering policy
+        self.logger.info(self.vapi.cli("show classify table"))
+
+        r = self.vapi.input_acl_set_interface(
+            is_add=1,
+            sw_if_index=self.pg3.sw_if_index,
+            ip6_table_index=table_index)
+        self.assertIsNotNone(r,
+                             'No response msg for input_acl_set_interface')
+
+        # log the ip6 inacl
+        self.logger.info(self.vapi.cli("show inacl type ip6"))
+
+        # create packets
+        count = len(self.pg_packet_sizes)
+        dst_inner = 'a7::1234'
+        pkts = []
+
+        # create IPv6 packets without SRH
+        packet_header = self.create_packet_header_IPv6(dst_inner)
+        # create traffic stream pg3->pg4
+        pkts.extend(self.create_stream(self.pg3, self.pg4, packet_header,
+                                       self.pg_packet_sizes, count))
+
+        # create IPv6 packets with SRH
+        # packets with segments-left 1, active segment a7::
+        packet_header = self.create_packet_header_IPv6_SRH(
+            sidlist=['a8::', 'a7::', 'a6::'],
+            segleft=1)
+        # create traffic stream pg3->pg4
+        pkts.extend(self.create_stream(self.pg3, self.pg4, packet_header,
+                                       self.pg_packet_sizes, count))
+
+        # send packets and verify received packets
+        self.send_and_verify_pkts(self.pg3, pkts, self.pg4,
+                                  self.compare_rx_tx_packet_T_Insert)
+
+        # remove the interface l2 input feature
+        r = self.vapi.input_acl_set_interface(
+            is_add=0,
+            sw_if_index=self.pg3.sw_if_index,
+            ip6_table_index=table_index)
+        self.assertIsNotNone(r,
+                             'No response msg for input_acl_set_interface')
+
+        # log the ip6 inacl after cleaning
+        self.logger.info(self.vapi.cli("show inacl type ip6"))
+
+        # log the localsid counters
+        self.logger.info(self.vapi.cli("show sr localsid"))
+
+        # remove classifier SR steering
+        # classifier_steering.remove_vpp_config()
+        self.logger.info(self.vapi.cli("show sr steering policies"))
+
+        # remove SR Policies
+        self.sr_policy.remove_vpp_config()
+        self.logger.info(self.vapi.cli("show sr policies"))
+
+        # remove classify session and table
+        r = self.vapi.classify_add_del_session(
+            0,
+            table_index,
+            binascii.unhexlify(match))
+        self.assertIsNotNone(r, 'No response msg for add_del_session')
+
+        r = self.vapi.classify_add_del_table(
+            0,
+            binascii.unhexlify(mask),
+            table_index=table_index)
+        self.assertIsNotNone(r, 'No response msg for add_del_table')
+
+        self.logger.info(self.vapi.cli("show classify table"))
+
+        # remove FIB entries
+        # done by tearDown
+
+        # cleanup interfaces
+        self.teardown_interfaces()
+
     def compare_rx_tx_packet_T_Encaps(self, tx_pkt, rx_pkt):
         """ Compare input and output packet after passing T.Encaps
 
     def compare_rx_tx_packet_T_Encaps(self, tx_pkt, rx_pkt):
         """ Compare input and output packet after passing T.Encaps
 
@@ -1288,7 +1438,7 @@ class TestSRv6(VppTestCase):
         tx_ip.chksum = None
         # read back the pkt (with str()) to force computing these fields
         # probably other ways to accomplish this are possible
         tx_ip.chksum = None
         # read back the pkt (with str()) to force computing these fields
         # probably other ways to accomplish this are possible
-        tx_ip = IP(str(tx_ip))
+        tx_ip = IP(scapy.compat.raw(tx_ip))
 
         self.assertEqual(rx_srh.payload, tx_ip)
 
 
         self.assertEqual(rx_srh.payload, tx_ip)
 
@@ -1340,7 +1490,7 @@ class TestSRv6(VppTestCase):
         self.assertEqual(rx_srh.nh, 59)
 
         # the whole rx'ed pkt beyond SRH should be equal to tx'ed pkt
         self.assertEqual(rx_srh.nh, 59)
 
         # the whole rx'ed pkt beyond SRH should be equal to tx'ed pkt
-        self.assertEqual(Ether(str(rx_srh.payload)), tx_ether)
+        self.assertEqual(Ether(scapy.compat.raw(rx_srh.payload)), tx_ether)
 
         self.logger.debug("packet verification: SUCCESS")
 
 
         self.logger.debug("packet verification: SUCCESS")
 
@@ -1616,7 +1766,7 @@ class TestSRv6(VppTestCase):
         tx_ip2.chksum = None
         # read back the pkt (with str()) to force computing these fields
         # probably other ways to accomplish this are possible
         tx_ip2.chksum = None
         # read back the pkt (with str()) to force computing these fields
         # probably other ways to accomplish this are possible
-        tx_ip2 = IP(str(tx_ip2))
+        tx_ip2 = IP(scapy.compat.raw(tx_ip2))
 
         self.assertEqual(rx_ip, tx_ip2)
 
 
         self.assertEqual(rx_ip, tx_ip2)
 
@@ -1642,7 +1792,7 @@ class TestSRv6(VppTestCase):
         tx_ip = tx_pkt.getlayer(IPv6)
         # we can't just get the 2nd Ether layer
         # get the Raw content and dissect it as Ether
         tx_ip = tx_pkt.getlayer(IPv6)
         # we can't just get the 2nd Ether layer
         # get the Raw content and dissect it as Ether
-        tx_eth1 = Ether(str(tx_pkt[Raw]))
+        tx_eth1 = Ether(scapy.compat.raw(tx_pkt[Raw]))
 
         # verify if rx'ed packet has no SRH
         self.assertFalse(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))
 
         # verify if rx'ed packet has no SRH
         self.assertFalse(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))
@@ -1688,7 +1838,7 @@ class TestSRv6(VppTestCase):
             # read back the dumped packet (with str())
             # to force computing these fields
             # probably other ways are possible
             # read back the dumped packet (with str())
             # to force computing these fields
             # probably other ways are possible
-            p = Ether(str(p))
+            p = Ether(scapy.compat.raw(p))
             payload_info.data = p.copy()
             self.logger.debug(ppp("Created packet:", p))
             pkts.append(p)
             payload_info.data = p.copy()
             self.logger.debug(ppp("Created packet:", p))
             pkts.append(p)
@@ -1931,14 +2081,14 @@ class TestSRv6(VppTestCase):
         # but packet[Raw] gives the complete payload
         # (incl L2 header) for the T.Encaps L2 case
         try:
         # but packet[Raw] gives the complete payload
         # (incl L2 header) for the T.Encaps L2 case
         try:
-            payload_info = self.payload_to_info(str(packet[Raw]))
+            payload_info = self.payload_to_info(packet[Raw])
 
         except:
             # remote L2 header from packet[Raw]:
             # take packet[Raw], convert it to an Ether layer
             # and then extract Raw from it
             payload_info = self.payload_to_info(
 
         except:
             # remote L2 header from packet[Raw]:
             # take packet[Raw], convert it to an Ether layer
             # and then extract Raw from it
             payload_info = self.payload_to_info(
-                str(Ether(str(packet[Raw]))[Raw]))
+                Ether(scapy.compat.r(packet[Raw]))[Raw])
 
         return payload_info
 
 
         return payload_info
 
@@ -1952,7 +2102,7 @@ class TestSRv6(VppTestCase):
         :param compare_func: function to compare in and out packet
         """
         self.logger.info("Verifying capture on interface %s using function %s"
         :param compare_func: function to compare in and out packet
         """
         self.logger.info("Verifying capture on interface %s using function %s"
-                         % (dst_if.name, compare_func.func_name))
+                         % (dst_if.name, compare_func.__name__))
 
         last_info = dict()
         for i in self.pg_interfaces:
 
         last_info = dict()
         for i in self.pg_interfaces:
@@ -1995,7 +2145,6 @@ class TestSRv6(VppTestCase):
                 compare_func(txed_packet, packet)
 
             except:
                 compare_func(txed_packet, packet)
 
             except:
-                print packet.command()
                 self.logger.error(ppp("Unexpected or invalid packet:", packet))
                 raise
 
                 self.logger.error(ppp("Unexpected or invalid packet:", packet))
                 raise