blob: 0f1c5a472558d55672e31e860864dd21c0466a25 [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
Neale Ranns810086d2017-11-05 16:26:46 -08003from framework import VppTestCase, VppTestRunner
Neale Ranns097fa662018-05-01 05:17:55 -07004
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -08005from vpp_udp_encap import find_udp_encap, VppUdpEncap
Neale Ranns097fa662018-05-01 05:17:55 -07006from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, VppMplsLabel, \
7 FibPathType
Neale Ranns810086d2017-11-05 16:26:46 -08008
9from scapy.packet import Raw
Klement Sekerab9ef2732018-06-24 22:49:33 +020010from scapy.layers.l2 import Ether
Neale Ranns810086d2017-11-05 16:26:46 -080011from scapy.layers.inet import IP, UDP
12from scapy.layers.inet6 import IPv6
13from scapy.contrib.mpls import MPLS
14
Paul Vinciguerra4271c972019-05-14 13:25:49 -040015NUM_PKTS = 67
16
Neale Ranns810086d2017-11-05 16:26:46 -080017
18class TestUdpEncap(VppTestCase):
19 """ UDP Encap Test Case """
20
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070021 @classmethod
22 def setUpClass(cls):
23 super(TestUdpEncap, cls).setUpClass()
24
25 @classmethod
26 def tearDownClass(cls):
27 super(TestUdpEncap, cls).tearDownClass()
28
Neale Ranns810086d2017-11-05 16:26:46 -080029 def setUp(self):
30 super(TestUdpEncap, self).setUp()
31
32 # create 2 pg interfaces
33 self.create_pg_interfaces(range(4))
34
35 # setup interfaces
36 # assign them different tables.
37 table_id = 0
38 self.tables = []
39
40 for i in self.pg_interfaces:
41 i.admin_up()
42
43 if table_id != 0:
44 tbl = VppIpTable(self, table_id)
45 tbl.add_vpp_config()
46 self.tables.append(tbl)
47 tbl = VppIpTable(self, table_id, is_ip6=1)
48 tbl.add_vpp_config()
49 self.tables.append(tbl)
50
51 i.set_table_ip4(table_id)
52 i.set_table_ip6(table_id)
53 i.config_ip4()
54 i.resolve_arp()
55 i.config_ip6()
56 i.resolve_ndp()
57 table_id += 1
58
59 def tearDown(self):
60 for i in self.pg_interfaces:
61 i.unconfig_ip4()
62 i.unconfig_ip6()
Neale Ranns810086d2017-11-05 16:26:46 -080063 i.set_table_ip4(0)
64 i.set_table_ip6(0)
65 i.admin_down()
66 super(TestUdpEncap, self).tearDown()
67
68 def validate_outer4(self, rx, encap_obj):
69 self.assertEqual(rx[IP].src, encap_obj.src_ip_s)
70 self.assertEqual(rx[IP].dst, encap_obj.dst_ip_s)
71 self.assertEqual(rx[UDP].sport, encap_obj.src_port)
72 self.assertEqual(rx[UDP].dport, encap_obj.dst_port)
73
74 def validate_outer6(self, rx, encap_obj):
75 self.assertEqual(rx[IPv6].src, encap_obj.src_ip_s)
76 self.assertEqual(rx[IPv6].dst, encap_obj.dst_ip_s)
77 self.assertEqual(rx[UDP].sport, encap_obj.src_port)
78 self.assertEqual(rx[UDP].dport, encap_obj.dst_port)
79
80 def validate_inner4(self, rx, tx, ttl=None):
Neale Ranns31ed7442018-02-23 05:29:09 -080081 self.assertEqual(rx[IP].src, tx[IP].src)
82 self.assertEqual(rx[IP].dst, tx[IP].dst)
Neale Ranns810086d2017-11-05 16:26:46 -080083 if ttl:
Neale Ranns31ed7442018-02-23 05:29:09 -080084 self.assertEqual(rx[IP].ttl, ttl)
Neale Ranns810086d2017-11-05 16:26:46 -080085 else:
Neale Ranns31ed7442018-02-23 05:29:09 -080086 self.assertEqual(rx[IP].ttl, tx[IP].ttl)
Neale Ranns810086d2017-11-05 16:26:46 -080087
88 def validate_inner6(self, rx, tx):
89 self.assertEqual(rx.src, tx[IPv6].src)
90 self.assertEqual(rx.dst, tx[IPv6].dst)
91 self.assertEqual(rx.hlim, tx[IPv6].hlim)
92
Neale Ranns810086d2017-11-05 16:26:46 -080093 def test_udp_encap(self):
94 """ UDP Encap test
95 """
96
97 #
98 # construct a UDP encap object through each of the peers
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -070099 # v4 through the first two peers, v6 through the second.
Neale Ranns810086d2017-11-05 16:26:46 -0800100 #
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700101 udp_encap_0 = VppUdpEncap(self,
Neale Ranns810086d2017-11-05 16:26:46 -0800102 self.pg0.local_ip4,
103 self.pg0.remote_ip4,
104 330, 440)
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700105 udp_encap_1 = VppUdpEncap(self,
Neale Ranns810086d2017-11-05 16:26:46 -0800106 self.pg1.local_ip4,
107 self.pg1.remote_ip4,
108 331, 441,
109 table_id=1)
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700110 udp_encap_2 = VppUdpEncap(self,
Neale Ranns810086d2017-11-05 16:26:46 -0800111 self.pg2.local_ip6,
112 self.pg2.remote_ip6,
113 332, 442,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700114 table_id=2)
Neale Ranns9c0a3c42018-09-07 08:57:41 -0700115 udp_encap_3 = VppUdpEncap(self,
Neale Ranns810086d2017-11-05 16:26:46 -0800116 self.pg3.local_ip6,
117 self.pg3.remote_ip6,
118 333, 443,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700119 table_id=3)
Neale Ranns810086d2017-11-05 16:26:46 -0800120 udp_encap_0.add_vpp_config()
121 udp_encap_1.add_vpp_config()
122 udp_encap_2.add_vpp_config()
123 udp_encap_3.add_vpp_config()
124
Neale Rannsd0df49f2018-08-08 01:06:40 -0700125 self.logger.info(self.vapi.cli("sh udp encap"))
126
127 self.assertTrue(find_udp_encap(self, udp_encap_2))
128 self.assertTrue(find_udp_encap(self, udp_encap_3))
129 self.assertTrue(find_udp_encap(self, udp_encap_0))
130 self.assertTrue(find_udp_encap(self, udp_encap_1))
131
Neale Ranns810086d2017-11-05 16:26:46 -0800132 #
133 # Routes via each UDP encap object - all combinations of v4 and v6.
134 #
Neale Ranns097fa662018-05-01 05:17:55 -0700135 route_4o4 = VppIpRoute(
136 self, "1.1.0.1", 32,
137 [VppRoutePath("0.0.0.0",
138 0xFFFFFFFF,
139 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
140 next_hop_id=udp_encap_0.id)])
141 route_4o6 = VppIpRoute(
142 self, "1.1.2.1", 32,
143 [VppRoutePath("0.0.0.0",
144 0xFFFFFFFF,
145 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
146 next_hop_id=udp_encap_2.id)])
147 route_6o4 = VppIpRoute(
148 self, "2001::1", 128,
149 [VppRoutePath("0.0.0.0",
150 0xFFFFFFFF,
151 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
152 next_hop_id=udp_encap_1.id)])
153 route_6o6 = VppIpRoute(
154 self, "2001::3", 128,
155 [VppRoutePath("0.0.0.0",
156 0xFFFFFFFF,
157 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
158 next_hop_id=udp_encap_3.id)])
Neale Ranns810086d2017-11-05 16:26:46 -0800159 route_4o6.add_vpp_config()
160 route_6o6.add_vpp_config()
161 route_6o4.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -0700162 route_4o4.add_vpp_config()
Neale Ranns810086d2017-11-05 16:26:46 -0800163
164 #
165 # 4o4 encap
166 #
167 p_4o4 = (Ether(src=self.pg0.remote_mac,
168 dst=self.pg0.local_mac) /
169 IP(src="2.2.2.2", dst="1.1.0.1") /
170 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +0100171 Raw(b'\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400172 rx = self.send_and_expect(self.pg0, p_4o4*NUM_PKTS, self.pg0)
Neale Ranns810086d2017-11-05 16:26:46 -0800173 for p in rx:
174 self.validate_outer4(p, udp_encap_0)
175 p = IP(p["UDP"].payload.load)
176 self.validate_inner4(p, p_4o4)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400177 self.assertEqual(udp_encap_0.get_stats()['packets'], NUM_PKTS)
Neale Ranns810086d2017-11-05 16:26:46 -0800178
179 #
180 # 4o6 encap
181 #
182 p_4o6 = (Ether(src=self.pg0.remote_mac,
183 dst=self.pg0.local_mac) /
184 IP(src="2.2.2.2", dst="1.1.2.1") /
185 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +0100186 Raw(b'\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400187 rx = self.send_and_expect(self.pg0, p_4o6*NUM_PKTS, self.pg2)
Neale Ranns810086d2017-11-05 16:26:46 -0800188 for p in rx:
189 self.validate_outer6(p, udp_encap_2)
190 p = IP(p["UDP"].payload.load)
191 self.validate_inner4(p, p_4o6)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400192 self.assertEqual(udp_encap_2.get_stats()['packets'], NUM_PKTS)
Neale Ranns810086d2017-11-05 16:26:46 -0800193
194 #
195 # 6o4 encap
196 #
197 p_6o4 = (Ether(src=self.pg0.remote_mac,
198 dst=self.pg0.local_mac) /
199 IPv6(src="2001::100", dst="2001::1") /
200 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +0100201 Raw(b'\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400202 rx = self.send_and_expect(self.pg0, p_6o4*NUM_PKTS, self.pg1)
Neale Ranns810086d2017-11-05 16:26:46 -0800203 for p in rx:
204 self.validate_outer4(p, udp_encap_1)
205 p = IPv6(p["UDP"].payload.load)
206 self.validate_inner6(p, p_6o4)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400207 self.assertEqual(udp_encap_1.get_stats()['packets'], NUM_PKTS)
Neale Ranns810086d2017-11-05 16:26:46 -0800208
209 #
210 # 6o6 encap
211 #
212 p_6o6 = (Ether(src=self.pg0.remote_mac,
213 dst=self.pg0.local_mac) /
214 IPv6(src="2001::100", dst="2001::3") /
215 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +0100216 Raw(b'\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400217 rx = self.send_and_expect(self.pg0, p_6o6*NUM_PKTS, self.pg3)
Neale Ranns810086d2017-11-05 16:26:46 -0800218 for p in rx:
219 self.validate_outer6(p, udp_encap_3)
220 p = IPv6(p["UDP"].payload.load)
221 self.validate_inner6(p, p_6o6)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400222 self.assertEqual(udp_encap_3.get_stats()['packets'], NUM_PKTS)
Neale Ranns810086d2017-11-05 16:26:46 -0800223
224 #
225 # A route with an output label
226 # the TTL of the inner packet is decremented on LSP ingress
227 #
Neale Ranns097fa662018-05-01 05:17:55 -0700228 route_4oMPLSo4 = VppIpRoute(
229 self, "1.1.2.22", 32,
230 [VppRoutePath("0.0.0.0",
231 0xFFFFFFFF,
232 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
233 next_hop_id=1,
234 labels=[VppMplsLabel(66)])])
Neale Ranns810086d2017-11-05 16:26:46 -0800235 route_4oMPLSo4.add_vpp_config()
236
237 p_4omo4 = (Ether(src=self.pg0.remote_mac,
238 dst=self.pg0.local_mac) /
239 IP(src="2.2.2.2", dst="1.1.2.22") /
240 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +0100241 Raw(b'\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400242 rx = self.send_and_expect(self.pg0, p_4omo4*NUM_PKTS, self.pg1)
Neale Ranns810086d2017-11-05 16:26:46 -0800243 for p in rx:
244 self.validate_outer4(p, udp_encap_1)
245 p = MPLS(p["UDP"].payload.load)
246 self.validate_inner4(p, p_4omo4, ttl=63)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400247 self.assertEqual(udp_encap_1.get_stats()['packets'], 2*NUM_PKTS)
Neale Ranns810086d2017-11-05 16:26:46 -0800248
249
Florin Coras40903ac2018-06-10 14:41:23 -0700250class TestUDP(VppTestCase):
251 """ UDP Test Case """
252
253 @classmethod
254 def setUpClass(cls):
255 super(TestUDP, cls).setUpClass()
256
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700257 @classmethod
258 def tearDownClass(cls):
259 super(TestUDP, cls).tearDownClass()
260
Florin Coras40903ac2018-06-10 14:41:23 -0700261 def setUp(self):
262 super(TestUDP, self).setUp()
263 self.vapi.session_enable_disable(is_enabled=1)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200264 self.create_loopback_interfaces(2)
Florin Coras40903ac2018-06-10 14:41:23 -0700265
266 table_id = 0
267
268 for i in self.lo_interfaces:
269 i.admin_up()
270
271 if table_id != 0:
272 tbl = VppIpTable(self, table_id)
273 tbl.add_vpp_config()
274
275 i.set_table_ip4(table_id)
276 i.config_ip4()
277 table_id += 1
278
279 # Configure namespaces
Jakub Grajciarb4e5e502020-01-31 09:35:29 +0100280 self.vapi.app_namespace_add_del(namespace_id="0",
Ole Troane1ade682019-03-04 23:55:43 +0100281 sw_if_index=self.loop0.sw_if_index)
Jakub Grajciarb4e5e502020-01-31 09:35:29 +0100282 self.vapi.app_namespace_add_del(namespace_id="1",
Ole Troane1ade682019-03-04 23:55:43 +0100283 sw_if_index=self.loop1.sw_if_index)
Florin Coras40903ac2018-06-10 14:41:23 -0700284
285 def tearDown(self):
286 for i in self.lo_interfaces:
287 i.unconfig_ip4()
288 i.set_table_ip4(0)
289 i.admin_down()
290 self.vapi.session_enable_disable(is_enabled=0)
291 super(TestUDP, self).tearDown()
292
293 def test_udp_transfer(self):
294 """ UDP echo client/server transfer """
295
296 # Add inter-table routes
297 ip_t01 = VppIpRoute(self, self.loop1.local_ip4, 32,
298 [VppRoutePath("0.0.0.0",
299 0xffffffff,
300 nh_table_id=1)])
301 ip_t10 = VppIpRoute(self, self.loop0.local_ip4, 32,
302 [VppRoutePath("0.0.0.0",
303 0xffffffff,
304 nh_table_id=0)], table_id=1)
305 ip_t01.add_vpp_config()
306 ip_t10.add_vpp_config()
307
308 # Start builtin server and client
309 uri = "udp://" + self.loop0.local_ip4 + "/1234"
310 error = self.vapi.cli("test echo server appns 0 fifo-size 4 no-echo" +
311 "uri " + uri)
312 if error:
313 self.logger.critical(error)
Paul Vinciguerra9a6dafd2019-03-06 15:11:28 -0800314 self.assertNotIn("failed", error)
Florin Coras40903ac2018-06-10 14:41:23 -0700315
316 error = self.vapi.cli("test echo client mbytes 10 appns 1 " +
317 "fifo-size 4 no-output test-bytes " +
318 "syn-timeout 2 no-return uri " + uri)
319 if error:
320 self.logger.critical(error)
Paul Vinciguerra9a6dafd2019-03-06 15:11:28 -0800321 self.assertNotIn("failed", error)
Florin Coras40903ac2018-06-10 14:41:23 -0700322
Florin Coras7a2abce2020-04-05 19:25:44 +0000323 self.logger.debug(self.vapi.cli("show session verbose 2"))
324
Florin Coras40903ac2018-06-10 14:41:23 -0700325 # Delete inter-table routes
326 ip_t01.remove_vpp_config()
327 ip_t10.remove_vpp_config()
328
329
Neale Ranns810086d2017-11-05 16:26:46 -0800330if __name__ == '__main__':
331 unittest.main(testRunner=VppTestRunner)