blob: 40a3ddea4f558dd5259010ec9a84098adf691f8b [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
5from framework import VppTestCase, VppTestRunner
Neale Ranns0809f6c2018-07-16 04:14:21 -07006from vpp_sub_interface import VppDot1QSubint
Neale Rannsc0a93142018-09-05 15:42:26 -07007from vpp_ip import DpoProto
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02008from vpp_ip_route import (
9 VppIpRoute,
10 VppRoutePath,
11 VppMplsRoute,
12 VppMplsLabel,
13 VppMplsTable,
14 FibPathProto,
15)
Neale Ranns039cbfe2018-02-27 03:45:38 -080016
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070017import scapy.compat
Neale Ranns039cbfe2018-02-27 03:45:38 -080018from scapy.packet import Raw
Neale Ranns0809f6c2018-07-16 04:14:21 -070019from scapy.layers.l2 import Ether, Dot1Q
Neale Ranns039cbfe2018-02-27 03:45:38 -080020from scapy.layers.inet import IP, UDP
21from scapy.layers.inet6 import IPv6
22from scapy.contrib.mpls import MPLS
Paul Vinciguerrab7658202019-05-17 09:48:15 -040023from vpp_papi import VppEnum
Neale Ranns83832e72019-07-31 02:48:02 -070024from vpp_qos import VppQosRecord, VppQosEgressMap, VppQosMark, VppQosStore
Neale Ranns039cbfe2018-02-27 03:45:38 -080025
Paul Vinciguerra4271c972019-05-14 13:25:49 -040026NUM_PKTS = 67
27
Neale Ranns039cbfe2018-02-27 03:45:38 -080028
29class TestQOS(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020030 """QOS Test Case"""
Neale Ranns039cbfe2018-02-27 03:45:38 -080031
Paul Vinciguerrab7658202019-05-17 09:48:15 -040032 # Note: Since the enums aren't created dynamically until after
33 # the papi client attaches to VPP, we put it in a property to
34 # ensure it is the value at runtime, not at module load time.
35 @property
36 def QOS_SOURCE(self):
37 return VppEnum.vl_api_qos_source_t
38
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070039 @classmethod
40 def setUpClass(cls):
41 super(TestQOS, cls).setUpClass()
42
43 @classmethod
44 def tearDownClass(cls):
45 super(TestQOS, cls).tearDownClass()
46
Neale Ranns039cbfe2018-02-27 03:45:38 -080047 def setUp(self):
48 super(TestQOS, self).setUp()
49
50 self.create_pg_interfaces(range(5))
51
Neale Ranns0809f6c2018-07-16 04:14:21 -070052 tbl = VppMplsTable(self, 0)
53 tbl.add_vpp_config()
54
Neale Ranns039cbfe2018-02-27 03:45:38 -080055 for i in self.pg_interfaces:
56 i.admin_up()
57 i.config_ip4()
58 i.resolve_arp()
59 i.config_ip6()
60 i.resolve_ndp()
Neale Ranns0809f6c2018-07-16 04:14:21 -070061 i.enable_mpls()
Neale Ranns039cbfe2018-02-27 03:45:38 -080062
63 def tearDown(self):
64 for i in self.pg_interfaces:
65 i.unconfig_ip4()
66 i.unconfig_ip6()
Neale Ranns0809f6c2018-07-16 04:14:21 -070067 i.disable_mpls()
Neale Ranns039cbfe2018-02-27 03:45:38 -080068
69 super(TestQOS, self).tearDown()
70
71 def test_qos_ip(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020072 """QoS Mark/Record/Store IP"""
Neale Ranns039cbfe2018-02-27 03:45:38 -080073
74 #
75 # for table 1 map the n=0xff possible values of input QoS mark,
76 # n to 1-n
77 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070078 output = [scapy.compat.chb(0)] * 256
Neale Ranns039cbfe2018-02-27 03:45:38 -080079 for i in range(0, 255):
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070080 output[i] = scapy.compat.chb(255 - i)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020081 os = b"".join(output)
82 rows = [{"outputs": os}, {"outputs": os}, {"outputs": os}, {"outputs": os}]
Neale Ranns039cbfe2018-02-27 03:45:38 -080083
Neale Ranns5281a902019-07-23 08:16:19 -070084 qem1 = VppQosEgressMap(self, 1, rows).add_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -080085
86 #
87 # For table 2 (and up) use the value n for everything
88 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070089 output = [scapy.compat.chb(2)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020090 os = b"".join(output)
91 rows = [{"outputs": os}, {"outputs": os}, {"outputs": os}, {"outputs": os}]
Neale Ranns039cbfe2018-02-27 03:45:38 -080092
Neale Ranns5281a902019-07-23 08:16:19 -070093 qem2 = VppQosEgressMap(self, 2, rows).add_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -080094
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070095 output = [scapy.compat.chb(3)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020096 os = b"".join(output)
97 rows = [{"outputs": os}, {"outputs": os}, {"outputs": os}, {"outputs": os}]
Neale Ranns039cbfe2018-02-27 03:45:38 -080098
Neale Ranns5281a902019-07-23 08:16:19 -070099 qem3 = VppQosEgressMap(self, 3, rows).add_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -0800100
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700101 output = [scapy.compat.chb(4)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200102 os = b"".join(output)
103 rows = [{"outputs": os}, {"outputs": os}, {"outputs": os}, {"outputs": os}]
Neale Ranns039cbfe2018-02-27 03:45:38 -0800104
Neale Ranns5281a902019-07-23 08:16:19 -0700105 qem4 = VppQosEgressMap(self, 4, rows).add_vpp_config()
106 qem5 = VppQosEgressMap(self, 5, rows).add_vpp_config()
107 qem6 = VppQosEgressMap(self, 6, rows).add_vpp_config()
108 qem7 = VppQosEgressMap(self, 7, rows).add_vpp_config()
109
110 self.assertTrue(qem7.query_vpp_config())
Neale Ranns039cbfe2018-02-27 03:45:38 -0800111 self.logger.info(self.vapi.cli("sh qos eg map"))
112
113 #
114 # Bind interface pgN to table n
115 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200116 qm1 = VppQosMark(
117 self, self.pg1, qem1, self.QOS_SOURCE.QOS_API_SOURCE_IP
118 ).add_vpp_config()
119 qm2 = VppQosMark(
120 self, self.pg2, qem2, self.QOS_SOURCE.QOS_API_SOURCE_IP
121 ).add_vpp_config()
122 qm3 = VppQosMark(
123 self, self.pg3, qem3, self.QOS_SOURCE.QOS_API_SOURCE_IP
124 ).add_vpp_config()
125 qm4 = VppQosMark(
126 self, self.pg4, qem4, self.QOS_SOURCE.QOS_API_SOURCE_IP
127 ).add_vpp_config()
Neale Ranns5281a902019-07-23 08:16:19 -0700128 self.assertTrue(qm3.query_vpp_config())
129
130 self.logger.info(self.vapi.cli("sh qos mark"))
Neale Ranns039cbfe2018-02-27 03:45:38 -0800131
132 #
133 # packets ingress on Pg0
134 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200135 p_v4 = (
136 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
137 / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, tos=1)
138 / UDP(sport=1234, dport=1234)
139 / Raw(scapy.compat.chb(100) * NUM_PKTS)
140 )
141 p_v6 = (
142 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
143 / IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6, tc=1)
144 / UDP(sport=1234, dport=1234)
145 / Raw(scapy.compat.chb(100) * NUM_PKTS)
146 )
Neale Ranns039cbfe2018-02-27 03:45:38 -0800147
148 #
149 # Since we have not yet enabled the recording of the input QoS
150 # from the input iP header, the egress packet's ToS will be unchanged
151 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400152 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800153 for p in rx:
154 self.assertEqual(p[IP].tos, 1)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400155 rx = self.send_and_expect(self.pg0, p_v6 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800156 for p in rx:
157 self.assertEqual(p[IPv6].tc, 1)
158
159 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700160 # Enable QoS recording on IP input for pg0
Neale Ranns039cbfe2018-02-27 03:45:38 -0800161 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200162 qr1 = VppQosRecord(self, self.pg0, self.QOS_SOURCE.QOS_API_SOURCE_IP)
Neale Ranns5281a902019-07-23 08:16:19 -0700163 qr1.add_vpp_config()
164 self.logger.info(self.vapi.cli("sh qos record"))
Neale Ranns039cbfe2018-02-27 03:45:38 -0800165
166 #
167 # send the same packets, this time expect the input TOS of 1
168 # to be mapped to pg1's egress value of 254
169 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400170 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800171 for p in rx:
172 self.assertEqual(p[IP].tos, 254)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400173 rx = self.send_and_expect(self.pg0, p_v6 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800174 for p in rx:
175 self.assertEqual(p[IPv6].tc, 254)
176
177 #
178 # different input ToS to test the mapping
179 #
180 p_v4[IP].tos = 127
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400181 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800182 for p in rx:
183 self.assertEqual(p[IP].tos, 128)
184 p_v6[IPv6].tc = 127
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400185 rx = self.send_and_expect(self.pg0, p_v6 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800186 for p in rx:
187 self.assertEqual(p[IPv6].tc, 128)
188
189 p_v4[IP].tos = 254
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400190 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800191 for p in rx:
192 self.assertEqual(p[IP].tos, 1)
193 p_v6[IPv6].tc = 254
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400194 rx = self.send_and_expect(self.pg0, p_v6 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800195 for p in rx:
196 self.assertEqual(p[IPv6].tc, 1)
197
198 #
199 # send packets out the other interfaces to test the maps are
200 # correctly applied
201 #
202 p_v4[IP].dst = self.pg2.remote_ip4
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400203 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg2)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800204 for p in rx:
205 self.assertEqual(p[IP].tos, 2)
206
207 p_v4[IP].dst = self.pg3.remote_ip4
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400208 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg3)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800209 for p in rx:
210 self.assertEqual(p[IP].tos, 3)
211
212 p_v6[IPv6].dst = self.pg3.remote_ip6
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400213 rx = self.send_and_expect(self.pg0, p_v6 * NUM_PKTS, self.pg3)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800214 for p in rx:
215 self.assertEqual(p[IPv6].tc, 3)
216
217 #
218 # remove the map on pg2 and pg3, now expect an unchanged IP tos
219 #
Neale Ranns5281a902019-07-23 08:16:19 -0700220 qm2.remove_vpp_config()
221 qm3.remove_vpp_config()
222 self.logger.info(self.vapi.cli("sh qos mark"))
223
224 self.assertFalse(qm3.query_vpp_config())
Neale Ranns039cbfe2018-02-27 03:45:38 -0800225 self.logger.info(self.vapi.cli("sh int feat pg2"))
226
227 p_v4[IP].dst = self.pg2.remote_ip4
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400228 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg2)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800229 for p in rx:
230 self.assertEqual(p[IP].tos, 254)
231
232 p_v4[IP].dst = self.pg3.remote_ip4
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400233 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg3)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800234 for p in rx:
235 self.assertEqual(p[IP].tos, 254)
236
237 #
238 # still mapping out of pg1
239 #
240 p_v4[IP].dst = self.pg1.remote_ip4
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400241 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800242 for p in rx:
243 self.assertEqual(p[IP].tos, 1)
244
245 #
246 # disable the input recording on pg0
247 #
Neale Ranns5281a902019-07-23 08:16:19 -0700248 self.assertTrue(qr1.query_vpp_config())
249 qr1.remove_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -0800250
251 #
252 # back to an unchanged TOS value
253 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400254 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800255 for p in rx:
256 self.assertEqual(p[IP].tos, 254)
257
258 #
Neale Ranns83832e72019-07-31 02:48:02 -0700259 # enable QoS stroe instead of record
260 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200261 qst1 = VppQosStore(
262 self, self.pg0, self.QOS_SOURCE.QOS_API_SOURCE_IP, 5
263 ).add_vpp_config()
Neale Ranns83832e72019-07-31 02:48:02 -0700264 self.logger.info(self.vapi.cli("sh qos store"))
265
266 p_v4[IP].dst = self.pg1.remote_ip4
267 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
268 for p in rx:
269 self.assertEqual(p[IP].tos, 250)
270
271 #
272 # disable the input storing on pg0
273 #
274 self.assertTrue(qst1.query_vpp_config())
275 qst1.remove_vpp_config()
276
277 #
278 # back to an unchanged TOS value
279 #
280 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
281 for p in rx:
282 self.assertEqual(p[IP].tos, 254)
283
284 #
Neale Ranns039cbfe2018-02-27 03:45:38 -0800285 # disable the egress map on pg1 and pg4
286 #
Neale Ranns5281a902019-07-23 08:16:19 -0700287 qm1.remove_vpp_config()
288 qm4.remove_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -0800289
290 #
291 # unchanged Tos on pg1
292 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400293 rx = self.send_and_expect(self.pg0, p_v4 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800294 for p in rx:
295 self.assertEqual(p[IP].tos, 254)
296
Neale Ranns039cbfe2018-02-27 03:45:38 -0800297 def test_qos_mpls(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200298 """QoS Mark/Record MPLS"""
Neale Ranns039cbfe2018-02-27 03:45:38 -0800299
300 #
301 # 255 QoS for all input values
302 #
Neale Ranns18668842018-11-15 07:46:12 +0000303 from_ext = 7
304 from_ip = 6
305 from_mpls = 5
306 from_vlan = 4
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700307 output = [scapy.compat.chb(from_ext)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200308 os1 = b"".join(output)
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700309 output = [scapy.compat.chb(from_vlan)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200310 os2 = b"".join(output)
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700311 output = [scapy.compat.chb(from_mpls)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200312 os3 = b"".join(output)
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700313 output = [scapy.compat.chb(from_ip)] * 256
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200314 os4 = b"".join(output)
315 rows = [{"outputs": os1}, {"outputs": os2}, {"outputs": os3}, {"outputs": os4}]
Neale Ranns039cbfe2018-02-27 03:45:38 -0800316
Neale Ranns5281a902019-07-23 08:16:19 -0700317 qem1 = VppQosEgressMap(self, 1, rows).add_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -0800318
319 #
320 # a route with 1 MPLS label
321 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200322 route_10_0_0_1 = VppIpRoute(
323 self,
324 "10.0.0.1",
325 32,
326 [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[32])],
327 )
Neale Ranns039cbfe2018-02-27 03:45:38 -0800328 route_10_0_0_1.add_vpp_config()
329
330 #
331 # a route with 3 MPLS labels
332 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200333 route_10_0_0_3 = VppIpRoute(
334 self,
335 "10.0.0.3",
336 32,
337 [
338 VppRoutePath(
339 self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[63, 33, 34]
340 )
341 ],
342 )
Neale Ranns039cbfe2018-02-27 03:45:38 -0800343 route_10_0_0_3.add_vpp_config()
344
345 #
346 # enable IP QoS recording on the input Pg0 and MPLS egress marking
347 # on Pg1
348 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200349 qr1 = VppQosRecord(
350 self, self.pg0, self.QOS_SOURCE.QOS_API_SOURCE_IP
351 ).add_vpp_config()
352 qm1 = VppQosMark(
353 self, self.pg1, qem1, self.QOS_SOURCE.QOS_API_SOURCE_MPLS
354 ).add_vpp_config()
Neale Ranns039cbfe2018-02-27 03:45:38 -0800355
356 #
357 # packet that will get one label added and 3 labels added resp.
358 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200359 p_1 = (
360 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
361 / IP(src=self.pg0.remote_ip4, dst="10.0.0.1", tos=1)
362 / UDP(sport=1234, dport=1234)
363 / Raw(scapy.compat.chb(100) * NUM_PKTS)
364 )
365 p_3 = (
366 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
367 / IP(src=self.pg0.remote_ip4, dst="10.0.0.3", tos=1)
368 / UDP(sport=1234, dport=1234)
369 / Raw(scapy.compat.chb(100) * NUM_PKTS)
370 )
Neale Ranns039cbfe2018-02-27 03:45:38 -0800371
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400372 rx = self.send_and_expect(self.pg0, p_1 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800373
374 #
375 # only 3 bits of ToS value in MPLS make sure tos is correct
376 # and the label and EOS bit have not been corrupted
377 #
378 for p in rx:
Neale Ranns18668842018-11-15 07:46:12 +0000379 self.assertEqual(p[MPLS].cos, from_ip)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800380 self.assertEqual(p[MPLS].label, 32)
381 self.assertEqual(p[MPLS].s, 1)
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400382 rx = self.send_and_expect(self.pg0, p_3 * NUM_PKTS, self.pg1)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800383 for p in rx:
Neale Ranns18668842018-11-15 07:46:12 +0000384 self.assertEqual(p[MPLS].cos, from_ip)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800385 self.assertEqual(p[MPLS].label, 63)
386 self.assertEqual(p[MPLS].s, 0)
387 h = p[MPLS].payload
Neale Ranns18668842018-11-15 07:46:12 +0000388 self.assertEqual(h[MPLS].cos, from_ip)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800389 self.assertEqual(h[MPLS].label, 33)
390 self.assertEqual(h[MPLS].s, 0)
391 h = h[MPLS].payload
Neale Ranns18668842018-11-15 07:46:12 +0000392 self.assertEqual(h[MPLS].cos, from_ip)
Neale Ranns039cbfe2018-02-27 03:45:38 -0800393 self.assertEqual(h[MPLS].label, 34)
394 self.assertEqual(h[MPLS].s, 1)
395
396 #
Neale Ranns0809f6c2018-07-16 04:14:21 -0700397 # enable MPLS QoS recording on the input Pg0 and IP egress marking
398 # on Pg1
399 #
Neale Ranns5281a902019-07-23 08:16:19 -0700400 qr2 = VppQosRecord(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200401 self, self.pg0, self.QOS_SOURCE.QOS_API_SOURCE_MPLS
402 ).add_vpp_config()
Neale Ranns5281a902019-07-23 08:16:19 -0700403 qm2 = VppQosMark(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200404 self, self.pg1, qem1, self.QOS_SOURCE.QOS_API_SOURCE_IP
405 ).add_vpp_config()
Neale Ranns0809f6c2018-07-16 04:14:21 -0700406
407 #
Neale Ranns18668842018-11-15 07:46:12 +0000408 # MPLS x-connect - COS according to pg1 map
Neale Ranns0809f6c2018-07-16 04:14:21 -0700409 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200410 route_32_eos = VppMplsRoute(
411 self,
412 32,
413 1,
414 [
415 VppRoutePath(
416 self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[VppMplsLabel(33)]
417 )
418 ],
419 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700420 route_32_eos.add_vpp_config()
421
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200422 p_m1 = (
423 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
424 / MPLS(label=32, cos=3, ttl=2)
425 / IP(src=self.pg0.remote_ip4, dst="10.0.0.1", tos=1)
426 / UDP(sport=1234, dport=1234)
427 / Raw(scapy.compat.chb(100) * NUM_PKTS)
428 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700429
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400430 rx = self.send_and_expect(self.pg0, p_m1 * NUM_PKTS, self.pg1)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700431 for p in rx:
Neale Ranns18668842018-11-15 07:46:12 +0000432 self.assertEqual(p[MPLS].cos, from_mpls)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700433 self.assertEqual(p[MPLS].label, 33)
434 self.assertEqual(p[MPLS].s, 1)
435
436 #
437 # MPLS deag - COS is copied from MPLS to IP
438 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200439 route_33_eos = VppMplsRoute(
440 self, 33, 1, [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=0)]
441 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700442 route_33_eos.add_vpp_config()
443
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200444 route_10_0_0_4 = VppIpRoute(
445 self,
446 "10.0.0.4",
447 32,
448 [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
449 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700450 route_10_0_0_4.add_vpp_config()
451
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200452 p_m2 = (
453 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
454 / MPLS(label=33, ttl=2, cos=3)
455 / IP(src=self.pg0.remote_ip4, dst="10.0.0.4", tos=1)
456 / UDP(sport=1234, dport=1234)
457 / Raw(scapy.compat.chb(100) * NUM_PKTS)
458 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700459
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400460 rx = self.send_and_expect(self.pg0, p_m2 * NUM_PKTS, self.pg1)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700461
462 for p in rx:
Neale Ranns18668842018-11-15 07:46:12 +0000463 self.assertEqual(p[IP].tos, from_mpls)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700464
Neale Ranns0809f6c2018-07-16 04:14:21 -0700465 def test_qos_vlan(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200466 """QoS mark/record VLAN"""
Neale Ranns0809f6c2018-07-16 04:14:21 -0700467
468 #
469 # QoS for all input values
470 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700471 output = [scapy.compat.chb(0)] * 256
Neale Ranns0809f6c2018-07-16 04:14:21 -0700472 for i in range(0, 255):
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700473 output[i] = scapy.compat.chb(255 - i)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200474 os = b"".join(output)
475 rows = [{"outputs": os}, {"outputs": os}, {"outputs": os}, {"outputs": os}]
Neale Ranns0809f6c2018-07-16 04:14:21 -0700476
Neale Ranns5281a902019-07-23 08:16:19 -0700477 qem1 = VppQosEgressMap(self, 1, rows).add_vpp_config()
Neale Ranns0809f6c2018-07-16 04:14:21 -0700478
479 sub_if = VppDot1QSubint(self, self.pg0, 11)
480
481 sub_if.admin_up()
482 sub_if.config_ip4()
483 sub_if.resolve_arp()
484 sub_if.config_ip6()
485 sub_if.resolve_ndp()
486
487 #
488 # enable VLAN QoS recording/marking on the input Pg0 subinterface and
489 #
Neale Ranns5281a902019-07-23 08:16:19 -0700490 qr_v = VppQosRecord(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200491 self, sub_if, self.QOS_SOURCE.QOS_API_SOURCE_VLAN
492 ).add_vpp_config()
Neale Ranns5281a902019-07-23 08:16:19 -0700493 qm_v = VppQosMark(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200494 self, sub_if, qem1, self.QOS_SOURCE.QOS_API_SOURCE_VLAN
495 ).add_vpp_config()
Neale Ranns0809f6c2018-07-16 04:14:21 -0700496
497 #
498 # IP marking/recording on pg1
499 #
Neale Ranns5281a902019-07-23 08:16:19 -0700500 qr_ip = VppQosRecord(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200501 self, self.pg1, self.QOS_SOURCE.QOS_API_SOURCE_IP
502 ).add_vpp_config()
Neale Ranns5281a902019-07-23 08:16:19 -0700503 qm_ip = VppQosMark(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200504 self, self.pg1, qem1, self.QOS_SOURCE.QOS_API_SOURCE_IP
505 ).add_vpp_config()
Neale Ranns0809f6c2018-07-16 04:14:21 -0700506
507 #
508 # a routes to/from sub-interface
509 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200510 route_10_0_0_1 = VppIpRoute(
511 self, "10.0.0.1", 32, [VppRoutePath(sub_if.remote_ip4, sub_if.sw_if_index)]
512 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700513 route_10_0_0_1.add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200514 route_10_0_0_2 = VppIpRoute(
515 self,
516 "10.0.0.2",
517 32,
518 [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
519 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700520 route_10_0_0_2.add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200521 route_2001_1 = VppIpRoute(
522 self, "2001::1", 128, [VppRoutePath(sub_if.remote_ip6, sub_if.sw_if_index)]
523 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700524 route_2001_1.add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200525 route_2001_2 = VppIpRoute(
526 self,
527 "2001::2",
528 128,
529 [VppRoutePath(self.pg1.remote_ip6, self.pg1.sw_if_index)],
530 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700531 route_2001_2.add_vpp_config()
532
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200533 p_v1 = (
534 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
535 / Dot1Q(vlan=11, prio=1)
536 / IP(src="1.1.1.1", dst="10.0.0.2", tos=1)
537 / UDP(sport=1234, dport=1234)
538 / Raw(scapy.compat.chb(100) * NUM_PKTS)
539 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700540
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200541 p_v2 = (
542 Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
543 / IP(src="1.1.1.1", dst="10.0.0.1", tos=1)
544 / UDP(sport=1234, dport=1234)
545 / Raw(scapy.compat.chb(100) * NUM_PKTS)
546 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700547
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200548 p_v3 = (
549 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
550 / Dot1Q(vlan=11, prio=1, id=1)
551 / IP(src="1.1.1.1", dst="10.0.0.2", tos=2)
552 / UDP(sport=1234, dport=1234)
553 / Raw(scapy.compat.chb(100) * NUM_PKTS)
554 )
Prashant Maheshwari3bcf1a92019-07-31 21:37:33 +0530555
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400556 rx = self.send_and_expect(self.pg1, p_v2 * NUM_PKTS, self.pg0)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700557
558 for p in rx:
Prashant Maheshwari3bcf1a92019-07-31 21:37:33 +0530559 self.assertEqual(p[Dot1Q].prio, 7)
560 self.assertEqual(p[Dot1Q].id, 0)
561
562 rx = self.send_and_expect(self.pg0, p_v3 * NUM_PKTS, self.pg1)
563
564 for p in rx:
565 self.assertEqual(p[IP].tos, 252)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700566
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400567 rx = self.send_and_expect(self.pg0, p_v1 * NUM_PKTS, self.pg1)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700568
569 for p in rx:
Prashant Maheshwari3bcf1a92019-07-31 21:37:33 +0530570 self.assertEqual(p[IP].tos, 253)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700571
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200572 p_v1 = (
573 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
574 / Dot1Q(vlan=11, prio=2)
575 / IPv6(src="2001::1", dst="2001::2", tc=1)
576 / UDP(sport=1234, dport=1234)
577 / Raw(scapy.compat.chb(100) * NUM_PKTS)
578 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700579
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200580 p_v2 = (
581 Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
582 / IPv6(src="3001::1", dst="2001::1", tc=1)
583 / UDP(sport=1234, dport=1234)
584 / Raw(scapy.compat.chb(100) * NUM_PKTS)
585 )
Neale Ranns0809f6c2018-07-16 04:14:21 -0700586
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400587 rx = self.send_and_expect(self.pg1, p_v2 * NUM_PKTS, self.pg0)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700588
589 for p in rx:
Prashant Maheshwari3bcf1a92019-07-31 21:37:33 +0530590 self.assertEqual(p[Dot1Q].prio, 7)
591 self.assertEqual(p[Dot1Q].id, 0)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700592
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400593 rx = self.send_and_expect(self.pg0, p_v1 * NUM_PKTS, self.pg1)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700594
595 for p in rx:
Prashant Maheshwari3bcf1a92019-07-31 21:37:33 +0530596 self.assertEqual(p[IPv6].tc, 251)
Neale Ranns0809f6c2018-07-16 04:14:21 -0700597
598 #
599 # cleanup
600 #
601 sub_if.unconfig_ip4()
602 sub_if.unconfig_ip6()
603
Neale Ranns039cbfe2018-02-27 03:45:38 -0800604
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200605if __name__ == "__main__":
Neale Ranns039cbfe2018-02-27 03:45:38 -0800606 unittest.main(testRunner=VppTestRunner)