blob: b6f816e9cf24580a981ffe0ad10c7ea0a43f88db [file] [log] [blame]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +01001#!/usr/bin/env python
2
3import unittest
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +01004
5from scapy.packet import Raw
John Lo2bf8b812018-02-27 16:35:03 -05006from scapy.layers.l2 import Ether, Dot1Q, GRE, ERSPAN
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +01007from scapy.layers.inet import IP, UDP
Eyal Bari001fd402017-07-16 09:34:53 +03008from scapy.layers.vxlan import VXLAN
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +01009
10from framework import VppTestCase, VppTestRunner
Klement Sekera7bb873a2016-11-18 07:38:42 +010011from util import Host, ppp
Eyal Bari001fd402017-07-16 09:34:53 +030012from vpp_sub_interface import VppDot1QSubint, VppDot1ADSubint
13from vpp_gre_interface import VppGreInterface, VppGre6Interface
14from vpp_papi_provider import L2_VTR_OP
15from collections import namedtuple
16
17Tag = namedtuple('Tag', ['dot1', 'vlan'])
18DOT1AD = 0x88A8
19DOT1Q = 0x8100
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010020
21
22class TestSpan(VppTestCase):
23 """ SPAN Test Case """
24
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010025 @classmethod
26 def setUpClass(cls):
27 super(TestSpan, cls).setUpClass()
Eyal Bari001fd402017-07-16 09:34:53 +030028 # Test variables
Eyal Bari001fd402017-07-16 09:34:53 +030029 cls.pkts_per_burst = 257 # Number of packets per burst
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010030 # create 3 pg interfaces
Eyal Bari001fd402017-07-16 09:34:53 +030031 cls.create_pg_interfaces(range(3))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010032
Eyal Bari001fd402017-07-16 09:34:53 +030033 cls.bd_id = 55
34 cls.sub_if = VppDot1QSubint(cls, cls.pg0, 100)
Eyal Bari17142b22017-10-16 13:38:21 +030035 cls.vlan_sub_if = VppDot1QSubint(cls, cls.pg2, 300)
36 cls.vlan_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=300)
37
38 cls.qinq_sub_if = VppDot1ADSubint(cls, cls.pg2, 33, 400, 500)
39 cls.qinq_sub_if.set_vtr(L2_VTR_OP.L2_POP_2, outer=500, inner=400)
40
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010041 # packet flows mapping pg0 -> pg1, pg2 -> pg3, etc.
Eyal Bari001fd402017-07-16 09:34:53 +030042 cls.flows = dict()
43 cls.flows[cls.pg0] = [cls.pg1]
Eyal Baricdeb7f22017-10-15 16:55:11 +030044 cls.flows[cls.pg1] = [cls.pg0]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010045
46 # packet sizes
Eyal Bari17142b22017-10-16 13:38:21 +030047 cls.pg_if_packet_sizes = [64, 512, 1518] # , 9018]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010048
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010049 # setup all interfaces
Eyal Bari17142b22017-10-16 13:38:21 +030050 for i in cls.pg_interfaces:
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010051 i.admin_up()
52 i.config_ip4()
53 i.resolve_arp()
54
Eyal Bari001fd402017-07-16 09:34:53 +030055 cls.vxlan = cls.vapi.vxlan_add_del_tunnel(
Ole Troana5b2eec2019-03-11 19:23:25 +010056 src_address=cls.pg2.local_ip4n, dst_address=cls.pg2.remote_ip4n,
57 is_add=1, vni=1111)
Eyal Bari001fd402017-07-16 09:34:53 +030058
59 def setUp(self):
60 super(TestSpan, self).setUp()
61 self.reset_packet_infos()
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010062
63 def tearDown(self):
64 super(TestSpan, self).tearDown()
Eyal Bari001fd402017-07-16 09:34:53 +030065 if not self.vpp_dead:
66 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010067
Eyal Bari001fd402017-07-16 09:34:53 +030068 def xconnect(self, a, b, is_add=1):
69 self.vapi.sw_interface_set_l2_xconnect(a, b, enable=is_add)
70 self.vapi.sw_interface_set_l2_xconnect(b, a, enable=is_add)
71
72 def bridge(self, sw_if_index, is_add=1):
Ole Troana5b2eec2019-03-11 19:23:25 +010073 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=sw_if_index,
74 bd_id=self.bd_id, enable=is_add)
Eyal Bari001fd402017-07-16 09:34:53 +030075
76 def _remove_tag(self, packet, vlan, tag_type):
77 self.assertEqual(packet.type, tag_type)
78 payload = packet.payload
79 self.assertEqual(payload.vlan, vlan)
80 inner_type = payload.type
81 payload = payload.payload
82 packet.remove_payload()
83 packet.add_payload(payload)
84 packet.type = inner_type
85
86 def remove_tags(self, packet, tags):
87 for t in tags:
88 self._remove_tag(packet, t.vlan, t.dot1)
89 return packet
90
91 def decap_gre(self, pkt):
92 """
93 Decapsulate the original payload frame by removing GRE header
94 """
95 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
96 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
97
98 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
99 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
100
101 return pkt[GRE].payload
102
John Lo2bf8b812018-02-27 16:35:03 -0500103 def decap_erspan(self, pkt, session):
104 """
105 Decapsulate the original payload frame by removing ERSPAN header
106 """
107 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
108 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
109
110 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
111 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
112
113 self.assertEqual(pkt[ERSPAN].ver, 1)
114 self.assertEqual(pkt[ERSPAN].vlan, 0)
115 self.assertEqual(pkt[ERSPAN].cos, 0)
116 self.assertEqual(pkt[ERSPAN].en, 3)
117 self.assertEqual(pkt[ERSPAN].t, 0)
118 self.assertEqual(pkt[ERSPAN].session_id, session)
119 self.assertEqual(pkt[ERSPAN].reserved, 0)
120 self.assertEqual(pkt[ERSPAN].index, 0)
121
122 return pkt[ERSPAN].payload
123
Eyal Bari001fd402017-07-16 09:34:53 +0300124 def decap_vxlan(self, pkt):
125 """
126 Decapsulate the original payload frame by removing VXLAN header
127 """
128 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
129 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
130
131 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
132 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
133
134 return pkt[VXLAN].payload
135
Eyal Bari17142b22017-10-16 13:38:21 +0300136 def create_stream(self, src_if, packet_sizes, do_dot1=False, bcast=False):
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100137 pkts = []
Eyal Baricdeb7f22017-10-15 16:55:11 +0300138 dst_if = self.flows[src_if][0]
Eyal Bari17142b22017-10-16 13:38:21 +0300139 dst_mac = src_if.remote_mac
140 if bcast:
141 dst_mac = "ff:ff:ff:ff:ff:ff"
142
Eyal Bari001fd402017-07-16 09:34:53 +0300143 for i in range(0, self.pkts_per_burst):
Eyal Bari17142b22017-10-16 13:38:21 +0300144 payload = "span test"
Eyal Baricdeb7f22017-10-15 16:55:11 +0300145 size = packet_sizes[(i / 2) % len(packet_sizes)]
Eyal Bari17142b22017-10-16 13:38:21 +0300146 p = (Ether(src=src_if.local_mac, dst=dst_mac) /
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100147 IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4) /
Eyal Baricdeb7f22017-10-15 16:55:11 +0300148 UDP(sport=10000 + src_if.sw_if_index * 1000 + i, dport=1234) /
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100149 Raw(payload))
Eyal Bari001fd402017-07-16 09:34:53 +0300150 if do_dot1:
151 p = self.sub_if.add_dot1_layer(p)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100152 self.extend_packet(p, size)
153 pkts.append(p)
154 return pkts
155
Eyal Baricdeb7f22017-10-15 16:55:11 +0300156 def verify_capture(self, cap1, cap2):
157 self.assertEqual(len(cap1), len(cap2),
158 "Different number of sent and mirrored packets :"
159 "%u != %u" % (len(cap1), len(cap2)))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100160
Eyal Baricdeb7f22017-10-15 16:55:11 +0300161 pkts1 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap1]
162 pkts2 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap2]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100163
Eyal Baricdeb7f22017-10-15 16:55:11 +0300164 self.assertEqual(pkts1.sort(), pkts2.sort())
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100165
Eyal Bari001fd402017-07-16 09:34:53 +0300166 def test_device_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300167 """ SPAN device rx mirror """
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100168
Eyal Bari001fd402017-07-16 09:34:53 +0300169 # Create bi-directional cross-connects between pg0 and pg1
170 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100171 # Create incoming packet streams for packet-generator interfaces
172 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
173 self.pg0.add_stream(pkts)
174
Eyal Bari001fd402017-07-16 09:34:53 +0300175 # Enable SPAN on pg0 (mirrored to pg2)
176 self.vapi.sw_interface_span_enable_disable(
177 self.pg0.sw_if_index, self.pg2.sw_if_index)
178
179 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100180 # Enable packet capturing and start packet sending
181 self.pg_enable_capture(self.pg_interfaces)
182 self.pg_start()
183
184 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300185 n_pkts = len(pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300186 pg1_pkts = self.pg1.get_capture(n_pkts)
187 pg2_pkts = self.pg2.get_capture(n_pkts)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100188
Eyal Bari001fd402017-07-16 09:34:53 +0300189 # Disable SPAN on pg0 (mirrored to pg2)
190 self.vapi.sw_interface_span_enable_disable(
191 self.pg0.sw_if_index, self.pg2.sw_if_index, state=0)
192 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index, is_add=0)
193
Eyal Baricdeb7f22017-10-15 16:55:11 +0300194 self.verify_capture(pg1_pkts, pg2_pkts)
195
Eyal Bari001fd402017-07-16 09:34:53 +0300196 def test_span_l2_rx(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300197 """ SPAN l2 rx mirror """
Eyal Bari001fd402017-07-16 09:34:53 +0300198
199 self.sub_if.admin_up()
200
201 self.bridge(self.pg2.sw_if_index)
Eyal Bari17142b22017-10-16 13:38:21 +0300202 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300203 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
204 # Create incoming packet streams for packet-generator interfaces
205 pkts = self.create_stream(
206 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
207 self.pg0.add_stream(pkts)
208
209 # Enable SPAN on pg0 (mirrored to pg2)
210 self.vapi.sw_interface_span_enable_disable(
211 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1)
212
213 self.logger.info(self.vapi.ppcli("show interface span"))
214 # Enable packet capturing and start packet sending
215 self.pg_enable_capture(self.pg_interfaces)
216 self.pg_start()
217
218 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300219 pg2_expected = len(pkts)
220 pg1_pkts = self.pg1.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300221 pg2_pkts = self.pg2.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300222 self.bridge(self.pg2.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300223
Eyal Bari001fd402017-07-16 09:34:53 +0300224 # Disable SPAN on pg0 (mirrored to pg2)
225 self.vapi.sw_interface_span_enable_disable(
226 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
227 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
228
Eyal Baricdeb7f22017-10-15 16:55:11 +0300229 self.verify_capture(pg1_pkts, pg2_pkts)
230
Eyal Bari001fd402017-07-16 09:34:53 +0300231 def test_span_l2_rx_dst_vxlan(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300232 """ SPAN l2 rx mirror into vxlan """
Eyal Bari001fd402017-07-16 09:34:53 +0300233
234 self.sub_if.admin_up()
235 self.vapi.sw_interface_set_flags(self.vxlan.sw_if_index,
236 admin_up_down=1)
237
238 self.bridge(self.vxlan.sw_if_index, is_add=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300239 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300240 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
241 # Create incoming packet streams for packet-generator interfaces
242 pkts = self.create_stream(
243 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
244 self.pg0.add_stream(pkts)
245
246 # Enable SPAN on pg0 sub if (mirrored to vxlan)
247 self.vapi.sw_interface_span_enable_disable(
248 self.sub_if.sw_if_index, self.vxlan.sw_if_index, is_l2=1)
249
250 self.logger.info(self.vapi.ppcli("show interface span"))
251 # Enable packet capturing and start packet sending
252 self.pg_enable_capture(self.pg_interfaces)
253 self.pg_start()
254
255 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300256 n_pkts = len(pkts)
257 pg1_pkts = self.pg1.get_capture(n_pkts)
258 pg2_pkts = [self.decap_vxlan(p) for p in self.pg2.get_capture(n_pkts)]
Eyal Bari001fd402017-07-16 09:34:53 +0300259
260 self.bridge(self.vxlan.sw_if_index, is_add=0)
261 # Disable SPAN on pg0 sub if (mirrored to vxlan)
262 self.vapi.sw_interface_span_enable_disable(
263 self.sub_if.sw_if_index, self.vxlan.sw_if_index, state=0, is_l2=1)
264 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300265 self.verify_capture(pg1_pkts, pg2_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300266
John Lo2bf8b812018-02-27 16:35:03 -0500267 def test_span_l2_rx_dst_gre_erspan(self):
268 """ SPAN l2 rx mirror into gre-erspan """
269
270 self.sub_if.admin_up()
271
272 gre_if = VppGreInterface(self, self.pg2.local_ip4,
273 self.pg2.remote_ip4,
274 type=2,
275 session=543)
276
277 gre_if.add_vpp_config()
278 gre_if.admin_up()
279
280 self.bridge(gre_if.sw_if_index)
281 # Create bi-directional cross-connects between pg0 and pg1
282 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
283
284 # Create incoming packet streams for packet-generator interfaces
285 pkts = self.create_stream(
286 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
287 self.pg0.add_stream(pkts)
288
289 # Enable SPAN on pg0 sub if (mirrored to gre-erspan)
290 self.vapi.sw_interface_span_enable_disable(
291 self.sub_if.sw_if_index, gre_if.sw_if_index, is_l2=1)
292
293 # Enable packet capturing and start packet sending
294 self.pg_enable_capture(self.pg_interfaces)
295 self.pg_start()
296
297 # Verify packets outgoing packet streams on mirrored interface (pg2)
298 n_pkts = len(pkts)
299 pg1_pkts = self.pg1.get_capture(n_pkts)
300 pg2_pkts = self.pg2.get_capture(n_pkts)
301
302 def decap(p): return self.decap_erspan(p, session=543)
303 pg2_decaped = [decap(p) for p in pg2_pkts]
304
305 self.bridge(gre_if.sw_if_index, is_add=0)
306
307 # Disable SPAN on pg0 sub if
308 self.vapi.sw_interface_span_enable_disable(
309 self.sub_if.sw_if_index, gre_if.sw_if_index, state=0, is_l2=1)
310 gre_if.remove_vpp_config()
311 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
312
313 self.verify_capture(pg1_pkts, pg2_decaped)
314
Eyal Bari001fd402017-07-16 09:34:53 +0300315 def test_span_l2_rx_dst_gre_subif_vtr(self):
316 """ SPAN l2 rx mirror into gre-subif+vtr """
317
318 self.sub_if.admin_up()
319
320 gre_if = VppGreInterface(self, self.pg2.local_ip4,
321 self.pg2.remote_ip4,
John Loa43ccae2018-02-13 17:15:23 -0500322 type=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300323
324 gre_if.add_vpp_config()
325 gre_if.admin_up()
326
327 gre_sub_if = VppDot1QSubint(self, gre_if, 500)
328 gre_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=500)
329 gre_sub_if.admin_up()
330
331 self.bridge(gre_sub_if.sw_if_index)
332 # Create bi-directional cross-connects between pg0 and pg1
333 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
334
335 # Create incoming packet streams for packet-generator interfaces
336 pkts = self.create_stream(
337 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
338 self.pg0.add_stream(pkts)
339
John Lo2bf8b812018-02-27 16:35:03 -0500340 # Enable SPAN on pg0 sub if (mirrored to gre sub if)
Eyal Bari001fd402017-07-16 09:34:53 +0300341 self.vapi.sw_interface_span_enable_disable(
342 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, is_l2=1)
343
344 # Enable packet capturing and start packet sending
345 self.pg_enable_capture(self.pg_interfaces)
346 self.pg_start()
347
348 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300349 n_pkts = len(pkts)
350 pg1_pkts = self.pg1.get_capture(n_pkts)
351 pg2_pkts = self.pg2.get_capture(n_pkts)
352
353 def decap(p): return self.remove_tags(
354 self.decap_gre(p), [Tag(dot1=DOT1Q, vlan=500)])
355 pg2_decaped = [decap(p) for p in pg2_pkts]
356
Eyal Bari001fd402017-07-16 09:34:53 +0300357 self.bridge(gre_sub_if.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300358
Eyal Bari001fd402017-07-16 09:34:53 +0300359 # Disable SPAN on pg0 sub if
360 self.vapi.sw_interface_span_enable_disable(
Eyal Baricdeb7f22017-10-15 16:55:11 +0300361 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, state=0, is_l2=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300362 gre_if.remove_vpp_config()
363 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
364
Eyal Baricdeb7f22017-10-15 16:55:11 +0300365 self.verify_capture(pg1_pkts, pg2_decaped)
366
Eyal Bari17142b22017-10-16 13:38:21 +0300367 def test_span_l2_rx_dst_1q_vtr(self):
368 """ SPAN l2 rx mirror into 1q subif+vtr """
Eyal Bari001fd402017-07-16 09:34:53 +0300369
370 self.sub_if.admin_up()
Eyal Bari17142b22017-10-16 13:38:21 +0300371 self.vlan_sub_if.admin_up()
Eyal Bari001fd402017-07-16 09:34:53 +0300372
Eyal Bari17142b22017-10-16 13:38:21 +0300373 self.bridge(self.vlan_sub_if.sw_if_index)
Eyal Bari001fd402017-07-16 09:34:53 +0300374 # Create bi-directional cross-connects between pg0 and pg1
375 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
376
377 # Create incoming packet streams for packet-generator interfaces
378 pkts = self.create_stream(
379 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
380 self.pg0.add_stream(pkts)
381
382 self.vapi.sw_interface_span_enable_disable(
Eyal Bari17142b22017-10-16 13:38:21 +0300383 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, is_l2=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300384
385 # Enable packet capturing and start packet sending
386 self.pg_enable_capture(self.pg_interfaces)
387 self.pg_start()
388
389 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300390 n_pkts = len(pkts)
391 pg1_pkts = self.pg1.get_capture(n_pkts)
392 pg2_pkts = self.pg2.get_capture(n_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300393 pg2_untagged = [self.remove_tags(p, [Tag(dot1=DOT1Q, vlan=300)])
394 for p in pg2_pkts]
Eyal Bari001fd402017-07-16 09:34:53 +0300395
Eyal Bari17142b22017-10-16 13:38:21 +0300396 self.bridge(self.vlan_sub_if.sw_if_index, is_add=0)
Eyal Bari001fd402017-07-16 09:34:53 +0300397 # Disable SPAN on pg0 sub if (mirrored to vxlan)
398 self.vapi.sw_interface_span_enable_disable(
Eyal Bari17142b22017-10-16 13:38:21 +0300399 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, state=0,
400 is_l2=1)
401 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
402
403 self.verify_capture(pg1_pkts, pg2_untagged)
404
405 def test_span_l2_rx_dst_1ad_vtr(self):
406 """ SPAN l2 rx mirror into 1ad subif+vtr """
407
408 self.sub_if.admin_up()
409 self.qinq_sub_if.admin_up()
410
411 self.bridge(self.qinq_sub_if.sw_if_index)
412 # Create bi-directional cross-connects between pg0 and pg1
413 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
414
415 # Create incoming packet streams for packet-generator interfaces
416 pkts = self.create_stream(
417 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
418 self.pg0.add_stream(pkts)
419
420 self.vapi.sw_interface_span_enable_disable(
421 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, is_l2=1)
422
423 # Enable packet capturing and start packet sending
424 self.pg_enable_capture(self.pg_interfaces)
425 self.pg_start()
426
427 # Verify packets outgoing packet streams on mirrored interface (pg2)
428 n_pkts = len(pkts)
429 pg1_pkts = self.pg1.get_capture(n_pkts)
430 pg2_pkts = self.pg2.get_capture(n_pkts)
431 pg2_untagged = [self.remove_tags(p, [Tag(dot1=DOT1AD, vlan=400),
432 Tag(dot1=DOT1Q, vlan=500)])
433 for p in pg2_pkts]
434
435 self.bridge(self.qinq_sub_if.sw_if_index, is_add=0)
436 # Disable SPAN on pg0 sub if (mirrored to vxlan)
437 self.vapi.sw_interface_span_enable_disable(
438 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, state=0,
Eyal Bari001fd402017-07-16 09:34:53 +0300439 is_l2=1)
440 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
441
Eyal Baricdeb7f22017-10-15 16:55:11 +0300442 self.verify_capture(pg1_pkts, pg2_untagged)
443
Eyal Bari001fd402017-07-16 09:34:53 +0300444 def test_l2_tx_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300445 """ SPAN l2 tx mirror """
Eyal Bari001fd402017-07-16 09:34:53 +0300446
447 self.sub_if.admin_up()
448 self.bridge(self.pg2.sw_if_index)
449 # Create bi-directional cross-connects between pg0 and pg1
450 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
451 # Create incoming packet streams for packet-generator interfaces
452 pkts = self.create_stream(
453 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
454 self.pg0.add_stream(pkts)
455
Eyal Baricdeb7f22017-10-15 16:55:11 +0300456 # Enable SPAN on pg1 (mirrored to pg2)
Eyal Bari001fd402017-07-16 09:34:53 +0300457 self.vapi.sw_interface_span_enable_disable(
458 self.pg1.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=2)
459
460 self.logger.info(self.vapi.ppcli("show interface span"))
461 # Enable packet capturing and start packet sending
462 self.pg_enable_capture(self.pg_interfaces)
463 self.pg_start()
464
465 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300466 n_pkts = len(pkts)
467 pg1_pkts = self.pg1.get_capture(n_pkts)
468 pg2_pkts = self.pg2.get_capture(n_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300469 self.bridge(self.pg2.sw_if_index, is_add=0)
470 # Disable SPAN on pg0 (mirrored to pg2)
471 self.vapi.sw_interface_span_enable_disable(
472 self.pg1.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
473 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
474
Eyal Baricdeb7f22017-10-15 16:55:11 +0300475 self.verify_capture(pg1_pkts, pg2_pkts)
476
477 def test_l2_rx_tx_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300478 """ SPAN l2 rx tx mirror """
Eyal Baricdeb7f22017-10-15 16:55:11 +0300479
480 self.sub_if.admin_up()
481 self.bridge(self.pg2.sw_if_index)
482 # Create bi-directional cross-connects between pg0 and pg1
483 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
484
485 # Create incoming packet streams for packet-generator interfaces
486 pg0_pkts = self.create_stream(
487 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
488 self.pg0.add_stream(pg0_pkts)
489 pg1_pkts = self.create_stream(
490 self.pg1, self.pg_if_packet_sizes, do_dot1=False)
491 self.pg1.add_stream(pg1_pkts)
492
493 # Enable SPAN on pg0 (mirrored to pg2)
494 self.vapi.sw_interface_span_enable_disable(
495 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3)
496 self.logger.info(self.vapi.ppcli("show interface span"))
497
498 # Enable packet capturing and start packet sending
499 self.pg_enable_capture(self.pg_interfaces)
500 self.pg_start()
501
502 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300503 pg0_expected = len(pg1_pkts)
504 pg1_expected = len(pg0_pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300505 pg2_expected = pg0_expected + pg1_expected
506
507 pg0_pkts = self.pg0.get_capture(pg0_expected)
508 pg1_pkts = self.pg1.get_capture(pg1_expected)
509 pg2_pkts = self.pg2.get_capture(pg2_expected)
510
511 self.bridge(self.pg2.sw_if_index, is_add=0)
512 # Disable SPAN on pg0 (mirrored to pg2)
513 self.vapi.sw_interface_span_enable_disable(
514 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
515 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
516
517 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
518
Eyal Bari17142b22017-10-16 13:38:21 +0300519 def test_l2_bcast_mirror(self):
520 """ SPAN l2 broadcast mirror """
521
522 self.sub_if.admin_up()
523 self.bridge(self.pg2.sw_if_index)
524
525 # Create bi-directional cross-connects between pg0 and pg1
526 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100527 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300528 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100529 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300530
531 # Create incoming packet streams for packet-generator interfaces
532 pg0_pkts = self.create_stream(
533 self.pg0, self.pg_if_packet_sizes, do_dot1=True, bcast=True)
534 self.pg0.add_stream(pg0_pkts)
535 pg1_pkts = self.create_stream(
536 self.pg1, self.pg_if_packet_sizes, do_dot1=False, bcast=True)
537 self.pg1.add_stream(pg1_pkts)
538
539 # Enable SPAN on pg0 (mirrored to pg2)
540 self.vapi.sw_interface_span_enable_disable(
541 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3)
542 self.logger.info(self.vapi.ppcli("show interface span"))
543
544 # Enable packet capturing and start packet sending
545 self.pg_enable_capture(self.pg_interfaces)
546 self.pg_start()
547
548 # Verify packets outgoing packet streams on mirrored interface (pg2)
549 pg0_expected = len(pg1_pkts)
550 pg1_expected = len(pg0_pkts)
551 pg2_expected = pg0_expected + pg1_expected
552
553 pg0_pkts = self.pg0.get_capture(pg0_expected)
554 pg1_pkts = self.pg1.get_capture(pg1_expected)
555 pg2_pkts = self.pg2.get_capture(pg2_expected)
556
557 self.bridge(self.pg2.sw_if_index, is_add=0)
558 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100559 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=0)
Eyal Bari17142b22017-10-16 13:38:21 +0300560 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100561 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=0)
Eyal Bari17142b22017-10-16 13:38:21 +0300562 # Disable SPAN on pg0 (mirrored to pg2)
563 self.vapi.sw_interface_span_enable_disable(
564 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
565
566 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
567
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100568
569if __name__ == '__main__':
570 unittest.main(testRunner=VppTestRunner)