blob: c79999b5bc5f2e42dd722ee45e151f1e3ee58ba1 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Matej Klotton8d8a1da2016-12-22 11:06:56 +01002"""CRUD tests of APIs (Create, Read, Update, Delete) HLD:
3
4- interface up/down/add/delete - interface type:
5 - pg (TBD)
6 - loopback
7 - vhostuser (TBD)
8 - af_packet (TBD)
9 - netmap (TBD)
10 - tuntap (root privileges needed)
11 - vxlan (TBD)
12"""
13
14import unittest
15
16from scapy.layers.inet import IP, ICMP
17from scapy.layers.l2 import Ether
18
19from framework import VppTestCase, VppTestRunner
20
21
22class TestLoopbackInterfaceCRUD(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020023 """CRUD Loopback"""
Matej Klotton8d8a1da2016-12-22 11:06:56 +010024
25 @classmethod
26 def setUpClass(cls):
27 super(TestLoopbackInterfaceCRUD, cls).setUpClass()
28 try:
29 cls.create_pg_interfaces(range(1))
30 for i in cls.pg_interfaces:
Paul Vinciguerra207083f2019-12-02 22:38:00 -050031 i.config_ip4().resolve_arp()
Matej Klotton8d8a1da2016-12-22 11:06:56 +010032 except:
33 cls.tearDownClass()
34 raise
35
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070036 @classmethod
37 def tearDownClass(cls):
38 super(TestLoopbackInterfaceCRUD, cls).tearDownClass()
39
Matej Klotton8d8a1da2016-12-22 11:06:56 +010040 @staticmethod
41 def create_icmp_stream(src_if, dst_ifs):
42 """
43
44 :param VppInterface src_if: Packets are send to this interface,
45 using this interfaces remote host.
46 :param list dst_ifs: IPv4 ICMP requests are send to interfaces
47 addresses.
48 :return: List of generated packets.
49 """
50 pkts = []
51 for i in dst_ifs:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020052 p = (
53 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
54 / IP(src=src_if.remote_ip4, dst=i.local_ip4)
55 / ICMP(id=i.sw_if_index, type="echo-request")
56 )
Matej Klotton8d8a1da2016-12-22 11:06:56 +010057 pkts.append(p)
58 return pkts
59
60 def verify_icmp(self, capture, request_src_if, dst_ifs):
61 """
62
63 :param capture: Capture to verify.
64 :param VppInterface request_src_if: Interface where was send packets.
65 :param list dst_ifs: Interfaces where was generated IPv4 ICMP requests.
66 """
67 rcvd_icmp_pkts = []
68 for pkt in capture:
69 try:
70 ip = pkt[IP]
71 icmp = pkt[ICMP]
72 except IndexError:
73 pass
74 else:
75 info = (ip.src, ip.dst, icmp.type, icmp.id)
76 rcvd_icmp_pkts.append(info)
77
78 for i in dst_ifs:
79 # 0 - icmp echo response
80 info = (i.local_ip4, request_src_if.remote_ip4, 0, i.sw_if_index)
81 self.assertIn(info, rcvd_icmp_pkts)
82
83 def test_crud(self):
84 # create
Klement Sekerab9ef2732018-06-24 22:49:33 +020085 loopbacks = self.create_loopback_interfaces(20)
Matej Klotton8d8a1da2016-12-22 11:06:56 +010086 for i in loopbacks:
Neale Rannsefd7bc22019-11-11 08:32:34 +000087 i.local_ip4_prefix_len = 32
Paul Vinciguerra207083f2019-12-02 22:38:00 -050088 i.config_ip4().admin_up()
Matej Klotton8d8a1da2016-12-22 11:06:56 +010089
90 # read (check sw if dump, ip4 fib, ip6 fib)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020091 if_dump = self.vapi.sw_interface_dump(
92 name_filter_valid=True, name_filter="loop"
93 )
Neale Ranns097fa662018-05-01 05:17:55 -070094 fib4_dump = self.vapi.ip_route_dump(0)
Matej Klotton8d8a1da2016-12-22 11:06:56 +010095 for i in loopbacks:
96 self.assertTrue(i.is_interface_config_in_dump(if_dump))
97 self.assertTrue(i.is_ip4_entry_in_fib_dump(fib4_dump))
98
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020099 if_dump = self.vapi.sw_interface_dump(
100 name_filter_valid=True, name_filter="loopXYZ"
101 )
Aleksander Djuricc12eae72019-10-31 14:35:21 +0300102 self.assertEqual(len(if_dump), 0)
103
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100104 # check ping
105 stream = self.create_icmp_stream(self.pg0, loopbacks)
106 self.pg0.add_stream(stream)
107 self.pg_enable_capture(self.pg_interfaces)
108 self.pg_start()
109 capture = self.pg0.get_capture(expected_count=len(stream))
110
111 self.verify_icmp(capture, self.pg0, loopbacks)
112
113 # delete
114 for i in loopbacks:
115 i.remove_vpp_config()
116
117 # read (check not in sw if dump, ip4 fib, ip6 fib)
118 if_dump = self.vapi.sw_interface_dump()
Neale Ranns097fa662018-05-01 05:17:55 -0700119 fib4_dump = self.vapi.ip_route_dump(0)
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100120 for i in loopbacks:
121 self.assertFalse(i.is_interface_config_in_dump(if_dump))
122 self.assertFalse(i.is_ip4_entry_in_fib_dump(fib4_dump))
123
124 # check not ping
125 stream = self.create_icmp_stream(self.pg0, loopbacks)
126 self.pg0.add_stream(stream)
127 self.pg_enable_capture(self.pg_interfaces)
128 self.pg_start()
129 self.pg0.assert_nothing_captured()
130
131 def test_down(self):
132 # create
Klement Sekerab9ef2732018-06-24 22:49:33 +0200133 loopbacks = self.create_loopback_interfaces(20)
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100134 for i in loopbacks:
Neale Rannsefd7bc22019-11-11 08:32:34 +0000135 i.local_ip4_prefix_len = 32
Paul Vinciguerra207083f2019-12-02 22:38:00 -0500136 i.config_ip4().admin_up()
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100137
138 # disable
139 for i in loopbacks:
Paul Vinciguerra207083f2019-12-02 22:38:00 -0500140 i.admin_down().unconfig_ip4()
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100141
142 # read (check not in sw if dump, ip4 fib, ip6 fib)
143 if_dump = self.vapi.sw_interface_dump()
Neale Ranns097fa662018-05-01 05:17:55 -0700144 fib4_dump = self.vapi.ip_route_dump(0)
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100145 for i in loopbacks:
146 self.assertTrue(i.is_interface_config_in_dump(if_dump))
147 self.assertFalse(i.is_ip4_entry_in_fib_dump(fib4_dump))
148
149 # check not ping
150 stream = self.create_icmp_stream(self.pg0, loopbacks)
151 self.pg0.add_stream(stream)
152 self.pg_enable_capture(self.pg_interfaces)
153 self.pg_start()
154 self.pg0.assert_nothing_captured()
155
156
Paul Vinciguerra6407ba52019-04-04 13:22:20 -0700157class TestInterfaceDumpApiLocalOnly(VppTestCase):
158 """test_interface_crud.TestInterfaceDumpApiLocalOnly"""
159
160 def test_sw_if_index_0(self):
161 rv = self.vapi.sw_interface_dump(sw_if_index=0)
162 self.assertEqual(rv[0].sw_if_index, 0)
163
164 def test_sw_if_index_twiddle0(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200165 rv = self.vapi.sw_interface_dump(sw_if_index=0xFFFFFFFF)
Paul Vinciguerra6407ba52019-04-04 13:22:20 -0700166 self.assertEqual(rv[0].sw_if_index, 0)
167
168 def test_sw_if_index_1_not_existing(self):
169 rv = self.vapi.sw_interface_dump(sw_if_index=1)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200170 self.assertEqual(len(rv), 0, "expected no records.")
Paul Vinciguerra6407ba52019-04-04 13:22:20 -0700171
172
173class TestInterfaceDumpApi(VppTestCase):
174 """test_interface_crud.TestInterfaceDumpApi"""
175
176 def test_sw_if_index_1(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200177 self.vapi.create_loopback_instance(is_specified=1, user_instance=10)
178 self.vapi.create_loopback_instance(is_specified=1, user_instance=5)
Paul Vinciguerra6407ba52019-04-04 13:22:20 -0700179
180 # Can I get back the specified record?
181 rv = self.vapi.sw_interface_dump(sw_if_index=1)
182 self.assertEqual(rv[0].sw_if_index, 1, rv)
183
184 # verify 3 interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200185 rv = self.vapi.sw_interface_dump(sw_if_index=0xFFFFFFFF)
186 self.assertEqual(len(rv), 3, "Expected 3 interfaces.")
Paul Vinciguerra6407ba52019-04-04 13:22:20 -0700187
Paul Vinciguerra207083f2019-12-02 22:38:00 -0500188
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200189if __name__ == "__main__":
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100190 unittest.main(testRunner=VppTestRunner)