blob: 535978582386829aec4e00031b9af8215a13db7f [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Neale Ranns039cbfe2018-02-27 03:45:38 -08002
3import unittest
Neale Ranns039cbfe2018-02-27 03:45:38 -08004
Dave Wallace8800f732023-08-31 00:47:44 -04005from framework import VppTestCase
6from asfframework import VppTestRunner
Neale Ranns0809f6c2018-07-16 04:14:21 -07007from vpp_sub_interface import VppDot1QSubint
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02008from vpp_ip_route import (
9 VppIpRoute,
10 VppRoutePath,
11 VppMplsRoute,
12 VppMplsLabel,
13 VppMplsTable,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020014)
Neale Ranns039cbfe2018-02-27 03:45:38 -080015
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070016import scapy.compat
Neale Ranns039cbfe2018-02-27 03:45:38 -080017from scapy.packet import Raw
Neale Ranns0809f6c2018-07-16 04:14:21 -070018from scapy.layers.l2 import Ether, Dot1Q
Neale Ranns039cbfe2018-02-27 03:45:38 -080019from scapy.layers.inet import IP, UDP
20from scapy.layers.inet6 import IPv6
21from scapy.contrib.mpls import MPLS
Paul Vinciguerrab7658202019-05-17 09:48:15 -040022from vpp_papi import VppEnum
Neale Ranns83832e72019-07-31 02:48:02 -070023from vpp_qos import VppQosRecord, VppQosEgressMap, VppQosMark, VppQosStore
Neale Ranns039cbfe2018-02-27 03:45:38 -080024
Paul Vinciguerra4271c972019-05-14 13:25:49 -040025NUM_PKTS = 67
26
Neale Ranns039cbfe2018-02-27 03:45:38 -080027
28class TestQOS(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020029 """QOS Test Case"""
Neale Ranns039cbfe2018-02-27 03:45:38 -080030
Paul Vinciguerrab7658202019-05-17 09:48:15 -040031 # Note: Since the enums aren't created dynamically until after
32 # the papi client attaches to VPP, we put it in a property to
33 # ensure it is the value at runtime, not at module load time.
34 @property
35 def QOS_SOURCE(self):
36 return VppEnum.vl_api_qos_source_t
37
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070038 @classmethod
39 def setUpClass(cls):
40 super(TestQOS, cls).setUpClass()
41
42 @classmethod
43 def tearDownClass(cls):
44 super(TestQOS, cls).tearDownClass()
45
Neale Ranns039cbfe2018-02-27 03:45:38 -080046 def setUp(self):
47 super(TestQOS, self).setUp()
48
49 self.create_pg_interfaces(range(5))
50
Neale Ranns0809f6c2018-07-16 04:14:21 -070051 tbl = VppMplsTable(self, 0)
52 tbl.add_vpp_config()
53
Neale Ranns039cbfe2018-02-27 03:45:38 -080054 for i in self.pg_interfaces:
55 i.admin_up()
56 i.config_ip4()
57 i.resolve_arp()
58 i.config_ip6()
59 i.resolve_ndp()
Neale Ranns0809f6c2018-07-16 04:14:21 -070060 i.enable_mpls()
Neale Ranns039cbfe2018-02-27 03:45:38 -080061
62 def tearDown(self):
63 for i in self.pg_interfaces:
64 i.unconfig_ip4()
65 i.unconfig_ip6()
Neale Ranns0809f6c2018-07-16 04:14:21 -070066 i.disable_mpls()
Neale Ranns039cbfe2018-02-27 03:45:38 -080067
68 super(TestQOS, self).tearDown()
69
70 def test_qos_ip(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020071 """QoS Mark/Record/Store IP"""
Neale Ranns039cbfe2018-02-27 03:45:38 -080072
73 #
74 # for table 1 map the n=0xff possible values of input QoS mark,
75 # n to 1-n
76 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070077 output = [scapy.compat.chb(0)] * 256
Neale Ranns039cbfe2018-02-27 03:45:38 -080078 for i in range(0, 255):
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070079 output[i] = scapy.compat.chb(255 - i)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020080 os = b"".join(output)
81 rows = [{"outputs": os}, {"outputs": os}, {"outputs": os}, {"outputs": os}]
Neale Ranns039cbfe2018-02-27 03:45:38 -080082
Neale Ranns5281a902019-07-23 08:16:19 -070083 qem1 = VppQosEgressMap(self, 1, rows).add_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -080084
85 #
86 # For table 2 (and up) use the value n for everything
87 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070088 output = [scapy.compat.chb(2)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020089 os = b"".join(output)
90 rows = [{"outputs": os}, {"outputs": os}, {"outputs": os}, {"outputs": os}]
Neale Ranns039cbfe2018-02-27 03:45:38 -080091
Neale Ranns5281a902019-07-23 08:16:19 -070092 qem2 = VppQosEgressMap(self, 2, rows).add_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -080093
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070094 output = [scapy.compat.chb(3)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020095 os = b"".join(output)
96 rows = [{"outputs": os}, {"outputs": os}, {"outputs": os}, {"outputs": os}]
Neale Ranns039cbfe2018-02-27 03:45:38 -080097
Neale Ranns5281a902019-07-23 08:16:19 -070098 qem3 = VppQosEgressMap(self, 3, rows).add_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -080099
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700100 output = [scapy.compat.chb(4)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200101 os = b"".join(output)
102 rows = [{"outputs": os}, {"outputs": os}, {"outputs": os}, {"outputs": os}]
Neale Ranns039cbfe2018-02-27 03:45:38 -0800103
Neale Ranns5281a902019-07-23 08:16:19 -0700104 qem4 = VppQosEgressMap(self, 4, rows).add_vpp_config()
105 qem5 = VppQosEgressMap(self, 5, rows).add_vpp_config()
106 qem6 = VppQosEgressMap(self, 6, rows).add_vpp_config()
107 qem7 = VppQosEgressMap(self, 7, rows).add_vpp_config()
108
109 self.assertTrue(qem7.query_vpp_config())
Neale Ranns039cbfe2018-02-27 03:45:38 -0800110 self.logger.info(self.vapi.cli("sh qos eg map"))
111
112 #
113 # Bind interface pgN to table n
114 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200115 qm1 = VppQosMark(
116 self, self.pg1, qem1, self.QOS_SOURCE.QOS_API_SOURCE_IP
117 ).add_vpp_config()
118 qm2 = VppQosMark(
119 self, self.pg2, qem2, self.QOS_SOURCE.QOS_API_SOURCE_IP
120 ).add_vpp_config()
121 qm3 = VppQosMark(
122 self, self.pg3, qem3, self.QOS_SOURCE.QOS_API_SOURCE_IP
123 ).add_vpp_config()
124 qm4 = VppQosMark(
125 self, self.pg4, qem4, self.QOS_SOURCE.QOS_API_SOURCE_IP
126 ).add_vpp_config()
Neale Ranns5281a902019-07-23 08:16:19 -0700127 self.assertTrue(qm3.query_vpp_config())
128
129 self.logger.info(self.vapi.cli("sh qos mark"))
Neale Ranns039cbfe2018-02-27 03:45:38 -0800130
131 #
132 # packets ingress on Pg0
133 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200134 p_v4 = (
135 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
136 / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, tos=1)
137 / UDP(sport=1234, dport=1234)
138 / Raw(scapy.compat.chb(100) * NUM_PKTS)
139 )
140 p_v6 = (
141 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
142 / IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6, tc=1)
143 / UDP(sport=1234, dport=1234)
144 / Raw(scapy.compat.chb(100) * NUM_PKTS)
145 )
Neale Ranns039cbfe2018-02-27 03:45:38 -0800146
147 #
148 # Since we have not yet enabled the recording of the input QoS
149 # from the input iP header, the egress packet's ToS will be unchanged
150 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400151 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800152 for p in rx:
153 self.assertEqual(p[IP].tos, 1)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400154 rx = self.send_and_expect(self.pg0, p_v6 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800155 for p in rx:
156 self.assertEqual(p[IPv6].tc, 1)
157
158 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700159 # Enable QoS recording on IP input for pg0
Neale Ranns039cbfe2018-02-27 03:45:38 -0800160 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200161 qr1 = VppQosRecord(self, self.pg0, self.QOS_SOURCE.QOS_API_SOURCE_IP)
Neale Ranns5281a902019-07-23 08:16:19 -0700162 qr1.add_vpp_config()
163 self.logger.info(self.vapi.cli("sh qos record"))
Neale Ranns039cbfe2018-02-27 03:45:38 -0800164
165 #
166 # send the same packets, this time expect the input TOS of 1
167 # to be mapped to pg1's egress value of 254
168 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400169 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800170 for p in rx:
171 self.assertEqual(p[IP].tos, 254)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400172 rx = self.send_and_expect(self.pg0, p_v6 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800173 for p in rx:
174 self.assertEqual(p[IPv6].tc, 254)
175
176 #
177 # different input ToS to test the mapping
178 #
179 p_v4[IP].tos = 127
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400180 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800181 for p in rx:
182 self.assertEqual(p[IP].tos, 128)
183 p_v6[IPv6].tc = 127
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400184 rx = self.send_and_expect(self.pg0, p_v6 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800185 for p in rx:
186 self.assertEqual(p[IPv6].tc, 128)
187
188 p_v4[IP].tos = 254
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400189 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800190 for p in rx:
191 self.assertEqual(p[IP].tos, 1)
192 p_v6[IPv6].tc = 254
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400193 rx = self.send_and_expect(self.pg0, p_v6 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800194 for p in rx:
195 self.assertEqual(p[IPv6].tc, 1)
196
197 #
198 # send packets out the other interfaces to test the maps are
199 # correctly applied
200 #
201 p_v4[IP].dst = self.pg2.remote_ip4
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400202 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg2)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800203 for p in rx:
204 self.assertEqual(p[IP].tos, 2)
205
206 p_v4[IP].dst = self.pg3.remote_ip4
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400207 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg3)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800208 for p in rx:
209 self.assertEqual(p[IP].tos, 3)
210
211 p_v6[IPv6].dst = self.pg3.remote_ip6
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400212 rx = self.send_and_expect(self.pg0, p_v6 * NUM_PKTS, self.pg3)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800213 for p in rx:
214 self.assertEqual(p[IPv6].tc, 3)
215
216 #
217 # remove the map on pg2 and pg3, now expect an unchanged IP tos
218 #
Neale Ranns5281a902019-07-23 08:16:19 -0700219 qm2.remove_vpp_config()
220 qm3.remove_vpp_config()
221 self.logger.info(self.vapi.cli("sh qos mark"))
222
223 self.assertFalse(qm3.query_vpp_config())
Neale Ranns039cbfe2018-02-27 03:45:38 -0800224 self.logger.info(self.vapi.cli("sh int feat pg2"))
225
226 p_v4[IP].dst = self.pg2.remote_ip4
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400227 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg2)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800228 for p in rx:
229 self.assertEqual(p[IP].tos, 254)
230
231 p_v4[IP].dst = self.pg3.remote_ip4
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400232 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg3)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800233 for p in rx:
234 self.assertEqual(p[IP].tos, 254)
235
236 #
237 # still mapping out of pg1
238 #
239 p_v4[IP].dst = self.pg1.remote_ip4
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400240 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800241 for p in rx:
242 self.assertEqual(p[IP].tos, 1)
243
244 #
245 # disable the input recording on pg0
246 #
Neale Ranns5281a902019-07-23 08:16:19 -0700247 self.assertTrue(qr1.query_vpp_config())
248 qr1.remove_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -0800249
250 #
251 # back to an unchanged TOS value
252 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400253 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800254 for p in rx:
255 self.assertEqual(p[IP].tos, 254)
256
257 #
Neale Ranns83832e72019-07-31 02:48:02 -0700258 # enable QoS stroe instead of record
259 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200260 qst1 = VppQosStore(
261 self, self.pg0, self.QOS_SOURCE.QOS_API_SOURCE_IP, 5
262 ).add_vpp_config()
Neale Ranns83832e72019-07-31 02:48:02 -0700263 self.logger.info(self.vapi.cli("sh qos store"))
264
265 p_v4[IP].dst = self.pg1.remote_ip4
266 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
267 for p in rx:
268 self.assertEqual(p[IP].tos, 250)
269
270 #
271 # disable the input storing on pg0
272 #
273 self.assertTrue(qst1.query_vpp_config())
274 qst1.remove_vpp_config()
275
276 #
277 # back to an unchanged TOS value
278 #
279 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
280 for p in rx:
281 self.assertEqual(p[IP].tos, 254)
282
283 #
Neale Ranns039cbfe2018-02-27 03:45:38 -0800284 # disable the egress map on pg1 and pg4
285 #
Neale Ranns5281a902019-07-23 08:16:19 -0700286 qm1.remove_vpp_config()
287 qm4.remove_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -0800288
289 #
290 # unchanged Tos on pg1
291 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400292 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800293 for p in rx:
294 self.assertEqual(p[IP].tos, 254)
295
Neale Ranns039cbfe2018-02-27 03:45:38 -0800296 def test_qos_mpls(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200297 """QoS Mark/Record MPLS"""
Neale Ranns039cbfe2018-02-27 03:45:38 -0800298
299 #
300 # 255 QoS for all input values
301 #
Neale Ranns18668842018-11-15 07:46:12 +0000302 from_ext = 7
303 from_ip = 6
304 from_mpls = 5
305 from_vlan = 4
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700306 output = [scapy.compat.chb(from_ext)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200307 os1 = b"".join(output)
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700308 output = [scapy.compat.chb(from_vlan)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200309 os2 = b"".join(output)
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700310 output = [scapy.compat.chb(from_mpls)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200311 os3 = b"".join(output)
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700312 output = [scapy.compat.chb(from_ip)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200313 os4 = b"".join(output)
314 rows = [{"outputs": os1}, {"outputs": os2}, {"outputs": os3}, {"outputs": os4}]
Neale Ranns039cbfe2018-02-27 03:45:38 -0800315
Neale Ranns5281a902019-07-23 08:16:19 -0700316 qem1 = VppQosEgressMap(self, 1, rows).add_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -0800317
318 #
319 # a route with 1 MPLS label
320 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200321 route_10_0_0_1 = VppIpRoute(
322 self,
323 "10.0.0.1",
324 32,
325 [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[32])],
326 )
Neale Ranns039cbfe2018-02-27 03:45:38 -0800327 route_10_0_0_1.add_vpp_config()
328
329 #
330 # a route with 3 MPLS labels
331 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200332 route_10_0_0_3 = VppIpRoute(
333 self,
334 "10.0.0.3",
335 32,
336 [
337 VppRoutePath(
338 self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[63, 33, 34]
339 )
340 ],
341 )
Neale Ranns039cbfe2018-02-27 03:45:38 -0800342 route_10_0_0_3.add_vpp_config()
343
344 #
345 # enable IP QoS recording on the input Pg0 and MPLS egress marking
346 # on Pg1
347 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200348 qr1 = VppQosRecord(
349 self, self.pg0, self.QOS_SOURCE.QOS_API_SOURCE_IP
350 ).add_vpp_config()
351 qm1 = VppQosMark(
352 self, self.pg1, qem1, self.QOS_SOURCE.QOS_API_SOURCE_MPLS
353 ).add_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -0800354
355 #
356 # packet that will get one label added and 3 labels added resp.
357 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200358 p_1 = (
359 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
360 / IP(src=self.pg0.remote_ip4, dst="10.0.0.1", tos=1)
361 / UDP(sport=1234, dport=1234)
362 / Raw(scapy.compat.chb(100) * NUM_PKTS)
363 )
364 p_3 = (
365 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
366 / IP(src=self.pg0.remote_ip4, dst="10.0.0.3", tos=1)
367 / UDP(sport=1234, dport=1234)
368 / Raw(scapy.compat.chb(100) * NUM_PKTS)
369 )
Neale Ranns039cbfe2018-02-27 03:45:38 -0800370
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400371 rx = self.send_and_expect(self.pg0, p_1 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800372
373 #
374 # only 3 bits of ToS value in MPLS make sure tos is correct
375 # and the label and EOS bit have not been corrupted
376 #
377 for p in rx:
Neale Ranns18668842018-11-15 07:46:12 +0000378 self.assertEqual(p[MPLS].cos, from_ip)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800379 self.assertEqual(p[MPLS].label, 32)
380 self.assertEqual(p[MPLS].s, 1)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400381 rx = self.send_and_expect(self.pg0, p_3 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800382 for p in rx:
Neale Ranns18668842018-11-15 07:46:12 +0000383 self.assertEqual(p[MPLS].cos, from_ip)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800384 self.assertEqual(p[MPLS].label, 63)
385 self.assertEqual(p[MPLS].s, 0)
386 h = p[MPLS].payload
Neale Ranns18668842018-11-15 07:46:12 +0000387 self.assertEqual(h[MPLS].cos, from_ip)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800388 self.assertEqual(h[MPLS].label, 33)
389 self.assertEqual(h[MPLS].s, 0)
390 h = h[MPLS].payload
Neale Ranns18668842018-11-15 07:46:12 +0000391 self.assertEqual(h[MPLS].cos, from_ip)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800392 self.assertEqual(h[MPLS].label, 34)
393 self.assertEqual(h[MPLS].s, 1)
394
395 #
Neale Ranns0809f6c2018-07-16 04:14:21 -0700396 # enable MPLS QoS recording on the input Pg0 and IP egress marking
397 # on Pg1
398 #
Neale Ranns5281a902019-07-23 08:16:19 -0700399 qr2 = VppQosRecord(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200400 self, self.pg0, self.QOS_SOURCE.QOS_API_SOURCE_MPLS
401 ).add_vpp_config()
Neale Ranns5281a902019-07-23 08:16:19 -0700402 qm2 = VppQosMark(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200403 self, self.pg1, qem1, self.QOS_SOURCE.QOS_API_SOURCE_IP
404 ).add_vpp_config()
Neale Ranns0809f6c2018-07-16 04:14:21 -0700405
406 #
Neale Ranns18668842018-11-15 07:46:12 +0000407 # MPLS x-connect - COS according to pg1 map
Neale Ranns0809f6c2018-07-16 04:14:21 -0700408 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200409 route_32_eos = VppMplsRoute(
410 self,
411 32,
412 1,
413 [
414 VppRoutePath(
415 self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[VppMplsLabel(33)]
416 )
417 ],
418 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700419 route_32_eos.add_vpp_config()
420
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200421 p_m1 = (
422 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
423 / MPLS(label=32, cos=3, ttl=2)
424 / IP(src=self.pg0.remote_ip4, dst="10.0.0.1", tos=1)
425 / UDP(sport=1234, dport=1234)
426 / Raw(scapy.compat.chb(100) * NUM_PKTS)
427 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700428
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400429 rx = self.send_and_expect(self.pg0, p_m1 * NUM_PKTS, self.pg1)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700430 for p in rx:
Neale Ranns18668842018-11-15 07:46:12 +0000431 self.assertEqual(p[MPLS].cos, from_mpls)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700432 self.assertEqual(p[MPLS].label, 33)
433 self.assertEqual(p[MPLS].s, 1)
434
435 #
436 # MPLS deag - COS is copied from MPLS to IP
437 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200438 route_33_eos = VppMplsRoute(
439 self, 33, 1, [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=0)]
440 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700441 route_33_eos.add_vpp_config()
442
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200443 route_10_0_0_4 = VppIpRoute(
444 self,
445 "10.0.0.4",
446 32,
447 [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
448 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700449 route_10_0_0_4.add_vpp_config()
450
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200451 p_m2 = (
452 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
453 / MPLS(label=33, ttl=2, cos=3)
454 / IP(src=self.pg0.remote_ip4, dst="10.0.0.4", tos=1)
455 / UDP(sport=1234, dport=1234)
456 / Raw(scapy.compat.chb(100) * NUM_PKTS)
457 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700458
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400459 rx = self.send_and_expect(self.pg0, p_m2 * NUM_PKTS, self.pg1)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700460
461 for p in rx:
Neale Ranns18668842018-11-15 07:46:12 +0000462 self.assertEqual(p[IP].tos, from_mpls)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700463
Neale Ranns0809f6c2018-07-16 04:14:21 -0700464 def test_qos_vlan(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200465 """QoS mark/record VLAN"""
Neale Ranns0809f6c2018-07-16 04:14:21 -0700466
467 #
468 # QoS for all input values
469 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700470 output = [scapy.compat.chb(0)] * 256
Neale Ranns0809f6c2018-07-16 04:14:21 -0700471 for i in range(0, 255):
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700472 output[i] = scapy.compat.chb(255 - i)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200473 os = b"".join(output)
474 rows = [{"outputs": os}, {"outputs": os}, {"outputs": os}, {"outputs": os}]
Neale Ranns0809f6c2018-07-16 04:14:21 -0700475
Neale Ranns5281a902019-07-23 08:16:19 -0700476 qem1 = VppQosEgressMap(self, 1, rows).add_vpp_config()
Neale Ranns0809f6c2018-07-16 04:14:21 -0700477
478 sub_if = VppDot1QSubint(self, self.pg0, 11)
479
480 sub_if.admin_up()
481 sub_if.config_ip4()
482 sub_if.resolve_arp()
483 sub_if.config_ip6()
484 sub_if.resolve_ndp()
485
486 #
487 # enable VLAN QoS recording/marking on the input Pg0 subinterface and
488 #
Neale Ranns5281a902019-07-23 08:16:19 -0700489 qr_v = VppQosRecord(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200490 self, sub_if, self.QOS_SOURCE.QOS_API_SOURCE_VLAN
491 ).add_vpp_config()
Neale Ranns5281a902019-07-23 08:16:19 -0700492 qm_v = VppQosMark(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200493 self, sub_if, qem1, self.QOS_SOURCE.QOS_API_SOURCE_VLAN
494 ).add_vpp_config()
Neale Ranns0809f6c2018-07-16 04:14:21 -0700495
496 #
497 # IP marking/recording on pg1
498 #
Neale Ranns5281a902019-07-23 08:16:19 -0700499 qr_ip = VppQosRecord(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200500 self, self.pg1, self.QOS_SOURCE.QOS_API_SOURCE_IP
501 ).add_vpp_config()
Neale Ranns5281a902019-07-23 08:16:19 -0700502 qm_ip = VppQosMark(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200503 self, self.pg1, qem1, self.QOS_SOURCE.QOS_API_SOURCE_IP
504 ).add_vpp_config()
Neale Ranns0809f6c2018-07-16 04:14:21 -0700505
506 #
507 # a routes to/from sub-interface
508 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200509 route_10_0_0_1 = VppIpRoute(
510 self, "10.0.0.1", 32, [VppRoutePath(sub_if.remote_ip4, sub_if.sw_if_index)]
511 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700512 route_10_0_0_1.add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200513 route_10_0_0_2 = VppIpRoute(
514 self,
515 "10.0.0.2",
516 32,
517 [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
518 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700519 route_10_0_0_2.add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200520 route_2001_1 = VppIpRoute(
521 self, "2001::1", 128, [VppRoutePath(sub_if.remote_ip6, sub_if.sw_if_index)]
522 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700523 route_2001_1.add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200524 route_2001_2 = VppIpRoute(
525 self,
526 "2001::2",
527 128,
528 [VppRoutePath(self.pg1.remote_ip6, self.pg1.sw_if_index)],
529 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700530 route_2001_2.add_vpp_config()
531
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200532 p_v1 = (
533 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
534 / Dot1Q(vlan=11, prio=1)
535 / IP(src="1.1.1.1", dst="10.0.0.2", tos=1)
536 / UDP(sport=1234, dport=1234)
537 / Raw(scapy.compat.chb(100) * NUM_PKTS)
538 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700539
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200540 p_v2 = (
541 Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
542 / IP(src="1.1.1.1", dst="10.0.0.1", tos=1)
543 / UDP(sport=1234, dport=1234)
544 / Raw(scapy.compat.chb(100) * NUM_PKTS)
545 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700546
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200547 p_v3 = (
548 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
549 / Dot1Q(vlan=11, prio=1, id=1)
550 / IP(src="1.1.1.1", dst="10.0.0.2", tos=2)
551 / UDP(sport=1234, dport=1234)
552 / Raw(scapy.compat.chb(100) * NUM_PKTS)
553 )
Prashant Maheshwari3bcf1a92019-07-31 21:37:33 +0530554
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400555 rx = self.send_and_expect(self.pg1, p_v2 * NUM_PKTS, self.pg0)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700556
557 for p in rx:
Prashant Maheshwari3bcf1a92019-07-31 21:37:33 +0530558 self.assertEqual(p[Dot1Q].prio, 7)
559 self.assertEqual(p[Dot1Q].id, 0)
560
561 rx = self.send_and_expect(self.pg0, p_v3 * NUM_PKTS, self.pg1)
562
563 for p in rx:
564 self.assertEqual(p[IP].tos, 252)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700565
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400566 rx = self.send_and_expect(self.pg0, p_v1 * NUM_PKTS, self.pg1)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700567
568 for p in rx:
Prashant Maheshwari3bcf1a92019-07-31 21:37:33 +0530569 self.assertEqual(p[IP].tos, 253)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700570
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200571 p_v1 = (
572 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
573 / Dot1Q(vlan=11, prio=2)
574 / IPv6(src="2001::1", dst="2001::2", tc=1)
575 / UDP(sport=1234, dport=1234)
576 / Raw(scapy.compat.chb(100) * NUM_PKTS)
577 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700578
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200579 p_v2 = (
580 Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
581 / IPv6(src="3001::1", dst="2001::1", tc=1)
582 / UDP(sport=1234, dport=1234)
583 / Raw(scapy.compat.chb(100) * NUM_PKTS)
584 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700585
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400586 rx = self.send_and_expect(self.pg1, p_v2 * NUM_PKTS, self.pg0)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700587
588 for p in rx:
Prashant Maheshwari3bcf1a92019-07-31 21:37:33 +0530589 self.assertEqual(p[Dot1Q].prio, 7)
590 self.assertEqual(p[Dot1Q].id, 0)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700591
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400592 rx = self.send_and_expect(self.pg0, p_v1 * NUM_PKTS, self.pg1)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700593
594 for p in rx:
Prashant Maheshwari3bcf1a92019-07-31 21:37:33 +0530595 self.assertEqual(p[IPv6].tc, 251)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700596
597 #
598 # cleanup
599 #
600 sub_if.unconfig_ip4()
601 sub_if.unconfig_ip6()
602
Neale Ranns039cbfe2018-02-27 03:45:38 -0800603
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200604if __name__ == "__main__":
Neale Ranns039cbfe2018-02-27 03:45:38 -0800605 unittest.main(testRunner=VppTestRunner)