blob: c88759d9b59dd761780484a51c1a8a4f5aa562b5 [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
Dave Wallace8800f732023-08-31 00:47:44 -040019from framework import VppTestCase
20from asfframework import VppTestRunner
Matej Klotton8d8a1da2016-12-22 11:06:56 +010021
22
23class TestLoopbackInterfaceCRUD(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020024 """CRUD Loopback"""
Matej Klotton8d8a1da2016-12-22 11:06:56 +010025
26 @classmethod
27 def setUpClass(cls):
28 super(TestLoopbackInterfaceCRUD, cls).setUpClass()
29 try:
30 cls.create_pg_interfaces(range(1))
31 for i in cls.pg_interfaces:
Paul Vinciguerra207083f2019-12-02 22:38:00 -050032 i.config_ip4().resolve_arp()
Matej Klotton8d8a1da2016-12-22 11:06:56 +010033 except:
34 cls.tearDownClass()
35 raise
36
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070037 @classmethod
38 def tearDownClass(cls):
39 super(TestLoopbackInterfaceCRUD, cls).tearDownClass()
40
Matej Klotton8d8a1da2016-12-22 11:06:56 +010041 @staticmethod
42 def create_icmp_stream(src_if, dst_ifs):
43 """
44
45 :param VppInterface src_if: Packets are send to this interface,
46 using this interfaces remote host.
47 :param list dst_ifs: IPv4 ICMP requests are send to interfaces
48 addresses.
49 :return: List of generated packets.
50 """
51 pkts = []
52 for i in dst_ifs:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020053 p = (
54 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
55 / IP(src=src_if.remote_ip4, dst=i.local_ip4)
56 / ICMP(id=i.sw_if_index, type="echo-request")
57 )
Matej Klotton8d8a1da2016-12-22 11:06:56 +010058 pkts.append(p)
59 return pkts
60
61 def verify_icmp(self, capture, request_src_if, dst_ifs):
62 """
63
64 :param capture: Capture to verify.
65 :param VppInterface request_src_if: Interface where was send packets.
66 :param list dst_ifs: Interfaces where was generated IPv4 ICMP requests.
67 """
68 rcvd_icmp_pkts = []
69 for pkt in capture:
70 try:
71 ip = pkt[IP]
72 icmp = pkt[ICMP]
73 except IndexError:
74 pass
75 else:
76 info = (ip.src, ip.dst, icmp.type, icmp.id)
77 rcvd_icmp_pkts.append(info)
78
79 for i in dst_ifs:
80 # 0 - icmp echo response
81 info = (i.local_ip4, request_src_if.remote_ip4, 0, i.sw_if_index)
82 self.assertIn(info, rcvd_icmp_pkts)
83
84 def test_crud(self):
85 # create
Klement Sekerab9ef2732018-06-24 22:49:33 +020086 loopbacks = self.create_loopback_interfaces(20)
Matej Klotton8d8a1da2016-12-22 11:06:56 +010087 for i in loopbacks:
Neale Rannsefd7bc22019-11-11 08:32:34 +000088 i.local_ip4_prefix_len = 32
Paul Vinciguerra207083f2019-12-02 22:38:00 -050089 i.config_ip4().admin_up()
Matej Klotton8d8a1da2016-12-22 11:06:56 +010090
91 # read (check sw if dump, ip4 fib, ip6 fib)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020092 if_dump = self.vapi.sw_interface_dump(
93 name_filter_valid=True, name_filter="loop"
94 )
Neale Ranns097fa662018-05-01 05:17:55 -070095 fib4_dump = self.vapi.ip_route_dump(0)
Matej Klotton8d8a1da2016-12-22 11:06:56 +010096 for i in loopbacks:
97 self.assertTrue(i.is_interface_config_in_dump(if_dump))
98 self.assertTrue(i.is_ip4_entry_in_fib_dump(fib4_dump))
99
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200100 if_dump = self.vapi.sw_interface_dump(
101 name_filter_valid=True, name_filter="loopXYZ"
102 )
Aleksander Djuricc12eae72019-10-31 14:35:21 +0300103 self.assertEqual(len(if_dump), 0)
104
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100105 # check ping
106 stream = self.create_icmp_stream(self.pg0, loopbacks)
107 self.pg0.add_stream(stream)
108 self.pg_enable_capture(self.pg_interfaces)
109 self.pg_start()
110 capture = self.pg0.get_capture(expected_count=len(stream))
111
112 self.verify_icmp(capture, self.pg0, loopbacks)
113
114 # delete
115 for i in loopbacks:
116 i.remove_vpp_config()
117
118 # read (check not in sw if dump, ip4 fib, ip6 fib)
119 if_dump = self.vapi.sw_interface_dump()
Neale Ranns097fa662018-05-01 05:17:55 -0700120 fib4_dump = self.vapi.ip_route_dump(0)
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100121 for i in loopbacks:
122 self.assertFalse(i.is_interface_config_in_dump(if_dump))
123 self.assertFalse(i.is_ip4_entry_in_fib_dump(fib4_dump))
124
125 # check not ping
126 stream = self.create_icmp_stream(self.pg0, loopbacks)
127 self.pg0.add_stream(stream)
128 self.pg_enable_capture(self.pg_interfaces)
129 self.pg_start()
130 self.pg0.assert_nothing_captured()
131
132 def test_down(self):
133 # create
Klement Sekerab9ef2732018-06-24 22:49:33 +0200134 loopbacks = self.create_loopback_interfaces(20)
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100135 for i in loopbacks:
Neale Rannsefd7bc22019-11-11 08:32:34 +0000136 i.local_ip4_prefix_len = 32
Paul Vinciguerra207083f2019-12-02 22:38:00 -0500137 i.config_ip4().admin_up()
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100138
139 # disable
140 for i in loopbacks:
Paul Vinciguerra207083f2019-12-02 22:38:00 -0500141 i.admin_down().unconfig_ip4()
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100142
143 # read (check not in sw if dump, ip4 fib, ip6 fib)
144 if_dump = self.vapi.sw_interface_dump()
Neale Ranns097fa662018-05-01 05:17:55 -0700145 fib4_dump = self.vapi.ip_route_dump(0)
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100146 for i in loopbacks:
147 self.assertTrue(i.is_interface_config_in_dump(if_dump))
148 self.assertFalse(i.is_ip4_entry_in_fib_dump(fib4_dump))
149
150 # check not ping
151 stream = self.create_icmp_stream(self.pg0, loopbacks)
152 self.pg0.add_stream(stream)
153 self.pg_enable_capture(self.pg_interfaces)
154 self.pg_start()
155 self.pg0.assert_nothing_captured()
156
157
Paul Vinciguerra6407ba52019-04-04 13:22:20 -0700158class TestInterfaceDumpApiLocalOnly(VppTestCase):
159 """test_interface_crud.TestInterfaceDumpApiLocalOnly"""
160
161 def test_sw_if_index_0(self):
162 rv = self.vapi.sw_interface_dump(sw_if_index=0)
163 self.assertEqual(rv[0].sw_if_index, 0)
164
165 def test_sw_if_index_twiddle0(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200166 rv = self.vapi.sw_interface_dump(sw_if_index=0xFFFFFFFF)
Paul Vinciguerra6407ba52019-04-04 13:22:20 -0700167 self.assertEqual(rv[0].sw_if_index, 0)
168
169 def test_sw_if_index_1_not_existing(self):
170 rv = self.vapi.sw_interface_dump(sw_if_index=1)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200171 self.assertEqual(len(rv), 0, "expected no records.")
Paul Vinciguerra6407ba52019-04-04 13:22:20 -0700172
173
174class TestInterfaceDumpApi(VppTestCase):
175 """test_interface_crud.TestInterfaceDumpApi"""
176
177 def test_sw_if_index_1(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200178 self.vapi.create_loopback_instance(is_specified=1, user_instance=10)
179 self.vapi.create_loopback_instance(is_specified=1, user_instance=5)
Paul Vinciguerra6407ba52019-04-04 13:22:20 -0700180
181 # Can I get back the specified record?
182 rv = self.vapi.sw_interface_dump(sw_if_index=1)
183 self.assertEqual(rv[0].sw_if_index, 1, rv)
184
185 # verify 3 interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200186 rv = self.vapi.sw_interface_dump(sw_if_index=0xFFFFFFFF)
187 self.assertEqual(len(rv), 3, "Expected 3 interfaces.")
Paul Vinciguerra6407ba52019-04-04 13:22:20 -0700188
Paul Vinciguerra207083f2019-12-02 22:38:00 -0500189
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200190if __name__ == "__main__":
Matej Klotton8d8a1da2016-12-22 11:06:56 +0100191 unittest.main(testRunner=VppTestRunner)