blob: 03a0812a342ace2605199b9731d99db862232cc4 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Klement Sekerab9ef2732018-06-24 22:49:33 +02002import unittest
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00003from framework import tag_fixme_vpp_workers
Neale Ranns810086d2017-11-05 16:26:46 -08004from framework import VppTestCase, VppTestRunner
Neale Ranns097fa662018-05-01 05:17:55 -07005
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -08006from vpp_udp_encap import find_udp_encap, VppUdpEncap
Neale Ranns097fa662018-05-01 05:17:55 -07007from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, VppMplsLabel, \
8 FibPathType
Neale Ranns810086d2017-11-05 16:26:46 -08009
10from scapy.packet import Raw
Klement Sekerab9ef2732018-06-24 22:49:33 +020011from scapy.layers.l2 import Ether
Neale Ranns810086d2017-11-05 16:26:46 -080012from scapy.layers.inet import IP, UDP
13from scapy.layers.inet6 import IPv6
14from scapy.contrib.mpls import MPLS
15
Paul Vinciguerra4271c972019-05-14 13:25:49 -040016NUM_PKTS = 67
17
Neale Ranns810086d2017-11-05 16:26:46 -080018
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +000019@tag_fixme_vpp_workers
Neale Ranns810086d2017-11-05 16:26:46 -080020class TestUdpEncap(VppTestCase):
21 """ UDP Encap Test Case """
22
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070023 @classmethod
24 def setUpClass(cls):
25 super(TestUdpEncap, cls).setUpClass()
26
27 @classmethod
28 def tearDownClass(cls):
29 super(TestUdpEncap, cls).tearDownClass()
30
Neale Ranns810086d2017-11-05 16:26:46 -080031 def setUp(self):
32 super(TestUdpEncap, self).setUp()
33
34 # create 2 pg interfaces
35 self.create_pg_interfaces(range(4))
36
37 # setup interfaces
38 # assign them different tables.
39 table_id = 0
40 self.tables = []
41
42 for i in self.pg_interfaces:
43 i.admin_up()
44
45 if table_id != 0:
46 tbl = VppIpTable(self, table_id)
47 tbl.add_vpp_config()
48 self.tables.append(tbl)
49 tbl = VppIpTable(self, table_id, is_ip6=1)
50 tbl.add_vpp_config()
51 self.tables.append(tbl)
52
53 i.set_table_ip4(table_id)
54 i.set_table_ip6(table_id)
55 i.config_ip4()
56 i.resolve_arp()
57 i.config_ip6()
58 i.resolve_ndp()
59 table_id += 1
60
61 def tearDown(self):
62 for i in self.pg_interfaces:
63 i.unconfig_ip4()
64 i.unconfig_ip6()
Neale Ranns810086d2017-11-05 16:26:46 -080065 i.set_table_ip4(0)
66 i.set_table_ip6(0)
67 i.admin_down()
68 super(TestUdpEncap, self).tearDown()
69
70 def validate_outer4(self, rx, encap_obj):
71 self.assertEqual(rx[IP].src, encap_obj.src_ip_s)
72 self.assertEqual(rx[IP].dst, encap_obj.dst_ip_s)
73 self.assertEqual(rx[UDP].sport, encap_obj.src_port)
74 self.assertEqual(rx[UDP].dport, encap_obj.dst_port)
75
76 def validate_outer6(self, rx, encap_obj):
77 self.assertEqual(rx[IPv6].src, encap_obj.src_ip_s)
78 self.assertEqual(rx[IPv6].dst, encap_obj.dst_ip_s)
79 self.assertEqual(rx[UDP].sport, encap_obj.src_port)
80 self.assertEqual(rx[UDP].dport, encap_obj.dst_port)
81
82 def validate_inner4(self, rx, tx, ttl=None):
Neale Ranns31ed7442018-02-23 05:29:09 -080083 self.assertEqual(rx[IP].src, tx[IP].src)
84 self.assertEqual(rx[IP].dst, tx[IP].dst)
Neale Ranns810086d2017-11-05 16:26:46 -080085 if ttl:
Neale Ranns31ed7442018-02-23 05:29:09 -080086 self.assertEqual(rx[IP].ttl, ttl)
Neale Ranns810086d2017-11-05 16:26:46 -080087 else:
Neale Ranns31ed7442018-02-23 05:29:09 -080088 self.assertEqual(rx[IP].ttl, tx[IP].ttl)
Neale Ranns810086d2017-11-05 16:26:46 -080089
90 def validate_inner6(self, rx, tx):
91 self.assertEqual(rx.src, tx[IPv6].src)
92 self.assertEqual(rx.dst, tx[IPv6].dst)
93 self.assertEqual(rx.hlim, tx[IPv6].hlim)
94
Neale Ranns810086d2017-11-05 16:26:46 -080095 def test_udp_encap(self):
96 """ UDP Encap test
97 """
98
99 #
100 # construct a UDP encap object through each of the peers
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700101 # v4 through the first two peers, v6 through the second.
Neale Ranns810086d2017-11-05 16:26:46 -0800102 #
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700103 udp_encap_0 = VppUdpEncap(self,
Neale Ranns810086d2017-11-05 16:26:46 -0800104 self.pg0.local_ip4,
105 self.pg0.remote_ip4,
106 330, 440)
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700107 udp_encap_1 = VppUdpEncap(self,
Neale Ranns810086d2017-11-05 16:26:46 -0800108 self.pg1.local_ip4,
109 self.pg1.remote_ip4,
110 331, 441,
111 table_id=1)
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700112 udp_encap_2 = VppUdpEncap(self,
Neale Ranns810086d2017-11-05 16:26:46 -0800113 self.pg2.local_ip6,
114 self.pg2.remote_ip6,
115 332, 442,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700116 table_id=2)
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700117 udp_encap_3 = VppUdpEncap(self,
Neale Ranns810086d2017-11-05 16:26:46 -0800118 self.pg3.local_ip6,
119 self.pg3.remote_ip6,
120 333, 443,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700121 table_id=3)
Neale Ranns810086d2017-11-05 16:26:46 -0800122 udp_encap_0.add_vpp_config()
123 udp_encap_1.add_vpp_config()
124 udp_encap_2.add_vpp_config()
125 udp_encap_3.add_vpp_config()
126
Neale Rannsd0df49f2018-08-08 01:06:40 -0700127 self.logger.info(self.vapi.cli("sh udp encap"))
128
129 self.assertTrue(find_udp_encap(self, udp_encap_2))
130 self.assertTrue(find_udp_encap(self, udp_encap_3))
131 self.assertTrue(find_udp_encap(self, udp_encap_0))
132 self.assertTrue(find_udp_encap(self, udp_encap_1))
133
Neale Ranns810086d2017-11-05 16:26:46 -0800134 #
135 # Routes via each UDP encap object - all combinations of v4 and v6.
136 #
Neale Ranns097fa662018-05-01 05:17:55 -0700137 route_4o4 = VppIpRoute(
138 self, "1.1.0.1", 32,
139 [VppRoutePath("0.0.0.0",
140 0xFFFFFFFF,
141 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
142 next_hop_id=udp_encap_0.id)])
143 route_4o6 = VppIpRoute(
144 self, "1.1.2.1", 32,
145 [VppRoutePath("0.0.0.0",
146 0xFFFFFFFF,
147 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
148 next_hop_id=udp_encap_2.id)])
149 route_6o4 = VppIpRoute(
150 self, "2001::1", 128,
151 [VppRoutePath("0.0.0.0",
152 0xFFFFFFFF,
153 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
154 next_hop_id=udp_encap_1.id)])
155 route_6o6 = VppIpRoute(
156 self, "2001::3", 128,
157 [VppRoutePath("0.0.0.0",
158 0xFFFFFFFF,
159 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
160 next_hop_id=udp_encap_3.id)])
Neale Ranns810086d2017-11-05 16:26:46 -0800161 route_4o6.add_vpp_config()
162 route_6o6.add_vpp_config()
163 route_6o4.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -0700164 route_4o4.add_vpp_config()
Neale Ranns810086d2017-11-05 16:26:46 -0800165
166 #
167 # 4o4 encap
168 #
169 p_4o4 = (Ether(src=self.pg0.remote_mac,
170 dst=self.pg0.local_mac) /
171 IP(src="2.2.2.2", dst="1.1.0.1") /
172 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +0100173 Raw(b'\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400174 rx = self.send_and_expect(self.pg0, p_4o4*NUM_PKTS, self.pg0)
Neale Ranns810086d2017-11-05 16:26:46 -0800175 for p in rx:
176 self.validate_outer4(p, udp_encap_0)
177 p = IP(p["UDP"].payload.load)
178 self.validate_inner4(p, p_4o4)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400179 self.assertEqual(udp_encap_0.get_stats()['packets'], NUM_PKTS)
Neale Ranns810086d2017-11-05 16:26:46 -0800180
181 #
182 # 4o6 encap
183 #
184 p_4o6 = (Ether(src=self.pg0.remote_mac,
185 dst=self.pg0.local_mac) /
186 IP(src="2.2.2.2", dst="1.1.2.1") /
187 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +0100188 Raw(b'\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400189 rx = self.send_and_expect(self.pg0, p_4o6*NUM_PKTS, self.pg2)
Neale Ranns810086d2017-11-05 16:26:46 -0800190 for p in rx:
191 self.validate_outer6(p, udp_encap_2)
192 p = IP(p["UDP"].payload.load)
193 self.validate_inner4(p, p_4o6)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400194 self.assertEqual(udp_encap_2.get_stats()['packets'], NUM_PKTS)
Neale Ranns810086d2017-11-05 16:26:46 -0800195
196 #
197 # 6o4 encap
198 #
199 p_6o4 = (Ether(src=self.pg0.remote_mac,
200 dst=self.pg0.local_mac) /
201 IPv6(src="2001::100", dst="2001::1") /
202 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +0100203 Raw(b'\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400204 rx = self.send_and_expect(self.pg0, p_6o4*NUM_PKTS, self.pg1)
Neale Ranns810086d2017-11-05 16:26:46 -0800205 for p in rx:
206 self.validate_outer4(p, udp_encap_1)
207 p = IPv6(p["UDP"].payload.load)
208 self.validate_inner6(p, p_6o4)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400209 self.assertEqual(udp_encap_1.get_stats()['packets'], NUM_PKTS)
Neale Ranns810086d2017-11-05 16:26:46 -0800210
211 #
212 # 6o6 encap
213 #
214 p_6o6 = (Ether(src=self.pg0.remote_mac,
215 dst=self.pg0.local_mac) /
216 IPv6(src="2001::100", dst="2001::3") /
217 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +0100218 Raw(b'\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400219 rx = self.send_and_expect(self.pg0, p_6o6*NUM_PKTS, self.pg3)
Neale Ranns810086d2017-11-05 16:26:46 -0800220 for p in rx:
221 self.validate_outer6(p, udp_encap_3)
222 p = IPv6(p["UDP"].payload.load)
223 self.validate_inner6(p, p_6o6)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400224 self.assertEqual(udp_encap_3.get_stats()['packets'], NUM_PKTS)
Neale Ranns810086d2017-11-05 16:26:46 -0800225
226 #
227 # A route with an output label
228 # the TTL of the inner packet is decremented on LSP ingress
229 #
Neale Ranns097fa662018-05-01 05:17:55 -0700230 route_4oMPLSo4 = VppIpRoute(
231 self, "1.1.2.22", 32,
232 [VppRoutePath("0.0.0.0",
233 0xFFFFFFFF,
234 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
235 next_hop_id=1,
236 labels=[VppMplsLabel(66)])])
Neale Ranns810086d2017-11-05 16:26:46 -0800237 route_4oMPLSo4.add_vpp_config()
238
239 p_4omo4 = (Ether(src=self.pg0.remote_mac,
240 dst=self.pg0.local_mac) /
241 IP(src="2.2.2.2", dst="1.1.2.22") /
242 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +0100243 Raw(b'\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400244 rx = self.send_and_expect(self.pg0, p_4omo4*NUM_PKTS, self.pg1)
Neale Ranns810086d2017-11-05 16:26:46 -0800245 for p in rx:
246 self.validate_outer4(p, udp_encap_1)
247 p = MPLS(p["UDP"].payload.load)
248 self.validate_inner4(p, p_4omo4, ttl=63)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400249 self.assertEqual(udp_encap_1.get_stats()['packets'], 2*NUM_PKTS)
Neale Ranns810086d2017-11-05 16:26:46 -0800250
251
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +0000252@tag_fixme_vpp_workers
Florin Coras40903ac2018-06-10 14:41:23 -0700253class TestUDP(VppTestCase):
254 """ UDP Test Case """
255
256 @classmethod
257 def setUpClass(cls):
258 super(TestUDP, cls).setUpClass()
259
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700260 @classmethod
261 def tearDownClass(cls):
262 super(TestUDP, cls).tearDownClass()
263
Florin Coras40903ac2018-06-10 14:41:23 -0700264 def setUp(self):
265 super(TestUDP, self).setUp()
Jakub Grajciar6a2794e2020-11-24 11:22:01 +0100266 self.vapi.session_enable_disable(is_enable=1)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200267 self.create_loopback_interfaces(2)
Florin Coras40903ac2018-06-10 14:41:23 -0700268
269 table_id = 0
270
271 for i in self.lo_interfaces:
272 i.admin_up()
273
274 if table_id != 0:
275 tbl = VppIpTable(self, table_id)
276 tbl.add_vpp_config()
277
278 i.set_table_ip4(table_id)
279 i.config_ip4()
280 table_id += 1
281
282 # Configure namespaces
Jakub Grajciarb4e5e502020-01-31 09:35:29 +0100283 self.vapi.app_namespace_add_del(namespace_id="0",
Ole Troane1ade682019-03-04 23:55:43 +0100284 sw_if_index=self.loop0.sw_if_index)
Jakub Grajciarb4e5e502020-01-31 09:35:29 +0100285 self.vapi.app_namespace_add_del(namespace_id="1",
Ole Troane1ade682019-03-04 23:55:43 +0100286 sw_if_index=self.loop1.sw_if_index)
Florin Coras40903ac2018-06-10 14:41:23 -0700287
288 def tearDown(self):
289 for i in self.lo_interfaces:
290 i.unconfig_ip4()
291 i.set_table_ip4(0)
292 i.admin_down()
Jakub Grajciar6a2794e2020-11-24 11:22:01 +0100293 self.vapi.session_enable_disable(is_enable=0)
Florin Coras40903ac2018-06-10 14:41:23 -0700294 super(TestUDP, self).tearDown()
295
296 def test_udp_transfer(self):
297 """ UDP echo client/server transfer """
298
299 # Add inter-table routes
300 ip_t01 = VppIpRoute(self, self.loop1.local_ip4, 32,
301 [VppRoutePath("0.0.0.0",
302 0xffffffff,
303 nh_table_id=1)])
304 ip_t10 = VppIpRoute(self, self.loop0.local_ip4, 32,
305 [VppRoutePath("0.0.0.0",
306 0xffffffff,
307 nh_table_id=0)], table_id=1)
308 ip_t01.add_vpp_config()
309 ip_t10.add_vpp_config()
310
311 # Start builtin server and client
312 uri = "udp://" + self.loop0.local_ip4 + "/1234"
313 error = self.vapi.cli("test echo server appns 0 fifo-size 4 no-echo" +
314 "uri " + uri)
315 if error:
316 self.logger.critical(error)
Paul Vinciguerra9a6dafd2019-03-06 15:11:28 -0800317 self.assertNotIn("failed", error)
Florin Coras40903ac2018-06-10 14:41:23 -0700318
319 error = self.vapi.cli("test echo client mbytes 10 appns 1 " +
320 "fifo-size 4 no-output test-bytes " +
321 "syn-timeout 2 no-return uri " + uri)
322 if error:
323 self.logger.critical(error)
Paul Vinciguerra9a6dafd2019-03-06 15:11:28 -0800324 self.assertNotIn("failed", error)
Florin Coras40903ac2018-06-10 14:41:23 -0700325
Florin Coras7a2abce2020-04-05 19:25:44 +0000326 self.logger.debug(self.vapi.cli("show session verbose 2"))
327
Florin Coras40903ac2018-06-10 14:41:23 -0700328 # Delete inter-table routes
329 ip_t01.remove_vpp_config()
330 ip_t10.remove_vpp_config()
331
332
Neale Ranns810086d2017-11-05 16:26:46 -0800333if __name__ == '__main__':
334 unittest.main(testRunner=VppTestRunner)