blob: b0ea1e5eb9007888fd139cc2680616ca01dd469a [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
Paul Vinciguerra95c0ca42019-03-28 13:07:00 -070012from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint, VppDot1ADSubint
Eyal Bari001fd402017-07-16 09:34:53 +030013from vpp_gre_interface import VppGreInterface, VppGre6Interface
Eyal Bari001fd402017-07-16 09:34:53 +030014from collections import namedtuple
15
16Tag = namedtuple('Tag', ['dot1', 'vlan'])
17DOT1AD = 0x88A8
18DOT1Q = 0x8100
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010019
20
21class TestSpan(VppTestCase):
22 """ SPAN Test Case """
23
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010024 @classmethod
25 def setUpClass(cls):
26 super(TestSpan, cls).setUpClass()
Eyal Bari001fd402017-07-16 09:34:53 +030027 # Test variables
Eyal Bari001fd402017-07-16 09:34:53 +030028 cls.pkts_per_burst = 257 # Number of packets per burst
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010029 # create 3 pg interfaces
Eyal Bari001fd402017-07-16 09:34:53 +030030 cls.create_pg_interfaces(range(3))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010031
Eyal Bari001fd402017-07-16 09:34:53 +030032 cls.bd_id = 55
33 cls.sub_if = VppDot1QSubint(cls, cls.pg0, 100)
Eyal Bari17142b22017-10-16 13:38:21 +030034 cls.vlan_sub_if = VppDot1QSubint(cls, cls.pg2, 300)
35 cls.vlan_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=300)
36
37 cls.qinq_sub_if = VppDot1ADSubint(cls, cls.pg2, 33, 400, 500)
38 cls.qinq_sub_if.set_vtr(L2_VTR_OP.L2_POP_2, outer=500, inner=400)
39
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010040 # packet flows mapping pg0 -> pg1, pg2 -> pg3, etc.
Eyal Bari001fd402017-07-16 09:34:53 +030041 cls.flows = dict()
42 cls.flows[cls.pg0] = [cls.pg1]
Eyal Baricdeb7f22017-10-15 16:55:11 +030043 cls.flows[cls.pg1] = [cls.pg0]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010044
45 # packet sizes
Eyal Bari17142b22017-10-16 13:38:21 +030046 cls.pg_if_packet_sizes = [64, 512, 1518] # , 9018]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010047
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010048 # setup all interfaces
Eyal Bari17142b22017-10-16 13:38:21 +030049 for i in cls.pg_interfaces:
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010050 i.admin_up()
51 i.config_ip4()
52 i.resolve_arp()
53
Eyal Bari001fd402017-07-16 09:34:53 +030054 cls.vxlan = cls.vapi.vxlan_add_del_tunnel(
Ole Troana5b2eec2019-03-11 19:23:25 +010055 src_address=cls.pg2.local_ip4n, dst_address=cls.pg2.remote_ip4n,
56 is_add=1, vni=1111)
Eyal Bari001fd402017-07-16 09:34:53 +030057
58 def setUp(self):
59 super(TestSpan, self).setUp()
60 self.reset_packet_infos()
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010061
62 def tearDown(self):
63 super(TestSpan, self).tearDown()
Eyal Bari001fd402017-07-16 09:34:53 +030064 if not self.vpp_dead:
65 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010066
Eyal Bari001fd402017-07-16 09:34:53 +030067 def xconnect(self, a, b, is_add=1):
68 self.vapi.sw_interface_set_l2_xconnect(a, b, enable=is_add)
69 self.vapi.sw_interface_set_l2_xconnect(b, a, enable=is_add)
70
71 def bridge(self, sw_if_index, is_add=1):
Ole Troana5b2eec2019-03-11 19:23:25 +010072 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=sw_if_index,
73 bd_id=self.bd_id, enable=is_add)
Eyal Bari001fd402017-07-16 09:34:53 +030074
75 def _remove_tag(self, packet, vlan, tag_type):
76 self.assertEqual(packet.type, tag_type)
77 payload = packet.payload
78 self.assertEqual(payload.vlan, vlan)
79 inner_type = payload.type
80 payload = payload.payload
81 packet.remove_payload()
82 packet.add_payload(payload)
83 packet.type = inner_type
84
85 def remove_tags(self, packet, tags):
86 for t in tags:
87 self._remove_tag(packet, t.vlan, t.dot1)
88 return packet
89
90 def decap_gre(self, pkt):
91 """
92 Decapsulate the original payload frame by removing GRE header
93 """
94 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
95 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
96
97 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
98 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
99
100 return pkt[GRE].payload
101
John Lo2bf8b812018-02-27 16:35:03 -0500102 def decap_erspan(self, pkt, session):
103 """
104 Decapsulate the original payload frame by removing ERSPAN header
105 """
106 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
107 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
108
109 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
110 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
111
112 self.assertEqual(pkt[ERSPAN].ver, 1)
113 self.assertEqual(pkt[ERSPAN].vlan, 0)
114 self.assertEqual(pkt[ERSPAN].cos, 0)
115 self.assertEqual(pkt[ERSPAN].en, 3)
116 self.assertEqual(pkt[ERSPAN].t, 0)
117 self.assertEqual(pkt[ERSPAN].session_id, session)
118 self.assertEqual(pkt[ERSPAN].reserved, 0)
119 self.assertEqual(pkt[ERSPAN].index, 0)
120
121 return pkt[ERSPAN].payload
122
Eyal Bari001fd402017-07-16 09:34:53 +0300123 def decap_vxlan(self, pkt):
124 """
125 Decapsulate the original payload frame by removing VXLAN header
126 """
127 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
128 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
129
130 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
131 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
132
133 return pkt[VXLAN].payload
134
Eyal Bari17142b22017-10-16 13:38:21 +0300135 def create_stream(self, src_if, packet_sizes, do_dot1=False, bcast=False):
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100136 pkts = []
Eyal Baricdeb7f22017-10-15 16:55:11 +0300137 dst_if = self.flows[src_if][0]
Eyal Bari17142b22017-10-16 13:38:21 +0300138 dst_mac = src_if.remote_mac
139 if bcast:
140 dst_mac = "ff:ff:ff:ff:ff:ff"
141
Eyal Bari001fd402017-07-16 09:34:53 +0300142 for i in range(0, self.pkts_per_burst):
Eyal Bari17142b22017-10-16 13:38:21 +0300143 payload = "span test"
Eyal Baricdeb7f22017-10-15 16:55:11 +0300144 size = packet_sizes[(i / 2) % len(packet_sizes)]
Eyal Bari17142b22017-10-16 13:38:21 +0300145 p = (Ether(src=src_if.local_mac, dst=dst_mac) /
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100146 IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4) /
Eyal Baricdeb7f22017-10-15 16:55:11 +0300147 UDP(sport=10000 + src_if.sw_if_index * 1000 + i, dport=1234) /
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100148 Raw(payload))
Eyal Bari001fd402017-07-16 09:34:53 +0300149 if do_dot1:
150 p = self.sub_if.add_dot1_layer(p)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100151 self.extend_packet(p, size)
152 pkts.append(p)
153 return pkts
154
Eyal Baricdeb7f22017-10-15 16:55:11 +0300155 def verify_capture(self, cap1, cap2):
156 self.assertEqual(len(cap1), len(cap2),
157 "Different number of sent and mirrored packets :"
158 "%u != %u" % (len(cap1), len(cap2)))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100159
Eyal Baricdeb7f22017-10-15 16:55:11 +0300160 pkts1 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap1]
161 pkts2 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap2]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100162
Eyal Baricdeb7f22017-10-15 16:55:11 +0300163 self.assertEqual(pkts1.sort(), pkts2.sort())
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100164
Eyal Bari001fd402017-07-16 09:34:53 +0300165 def test_device_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300166 """ SPAN device rx mirror """
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100167
Eyal Bari001fd402017-07-16 09:34:53 +0300168 # Create bi-directional cross-connects between pg0 and pg1
169 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100170 # Create incoming packet streams for packet-generator interfaces
171 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
172 self.pg0.add_stream(pkts)
173
Eyal Bari001fd402017-07-16 09:34:53 +0300174 # Enable SPAN on pg0 (mirrored to pg2)
175 self.vapi.sw_interface_span_enable_disable(
176 self.pg0.sw_if_index, self.pg2.sw_if_index)
177
178 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100179 # Enable packet capturing and start packet sending
180 self.pg_enable_capture(self.pg_interfaces)
181 self.pg_start()
182
183 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300184 n_pkts = len(pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300185 pg1_pkts = self.pg1.get_capture(n_pkts)
186 pg2_pkts = self.pg2.get_capture(n_pkts)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100187
Eyal Bari001fd402017-07-16 09:34:53 +0300188 # Disable SPAN on pg0 (mirrored to pg2)
189 self.vapi.sw_interface_span_enable_disable(
190 self.pg0.sw_if_index, self.pg2.sw_if_index, state=0)
191 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index, is_add=0)
192
Eyal Baricdeb7f22017-10-15 16:55:11 +0300193 self.verify_capture(pg1_pkts, pg2_pkts)
194
Eyal Bari001fd402017-07-16 09:34:53 +0300195 def test_span_l2_rx(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300196 """ SPAN l2 rx mirror """
Eyal Bari001fd402017-07-16 09:34:53 +0300197
198 self.sub_if.admin_up()
199
200 self.bridge(self.pg2.sw_if_index)
Eyal Bari17142b22017-10-16 13:38:21 +0300201 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300202 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
203 # Create incoming packet streams for packet-generator interfaces
204 pkts = self.create_stream(
205 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
206 self.pg0.add_stream(pkts)
207
208 # Enable SPAN on pg0 (mirrored to pg2)
209 self.vapi.sw_interface_span_enable_disable(
210 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1)
211
212 self.logger.info(self.vapi.ppcli("show interface span"))
213 # Enable packet capturing and start packet sending
214 self.pg_enable_capture(self.pg_interfaces)
215 self.pg_start()
216
217 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300218 pg2_expected = len(pkts)
219 pg1_pkts = self.pg1.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300220 pg2_pkts = self.pg2.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300221 self.bridge(self.pg2.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300222
Eyal Bari001fd402017-07-16 09:34:53 +0300223 # Disable SPAN on pg0 (mirrored to pg2)
224 self.vapi.sw_interface_span_enable_disable(
225 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
226 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
227
Eyal Baricdeb7f22017-10-15 16:55:11 +0300228 self.verify_capture(pg1_pkts, pg2_pkts)
229
Eyal Bari001fd402017-07-16 09:34:53 +0300230 def test_span_l2_rx_dst_vxlan(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300231 """ SPAN l2 rx mirror into vxlan """
Eyal Bari001fd402017-07-16 09:34:53 +0300232
233 self.sub_if.admin_up()
234 self.vapi.sw_interface_set_flags(self.vxlan.sw_if_index,
Ole Trøan3b0d7e42019-03-15 16:14:41 +0000235 admin_up_down=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300236
237 self.bridge(self.vxlan.sw_if_index, is_add=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300238 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300239 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
240 # Create incoming packet streams for packet-generator interfaces
241 pkts = self.create_stream(
242 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
243 self.pg0.add_stream(pkts)
244
245 # Enable SPAN on pg0 sub if (mirrored to vxlan)
246 self.vapi.sw_interface_span_enable_disable(
247 self.sub_if.sw_if_index, self.vxlan.sw_if_index, is_l2=1)
248
249 self.logger.info(self.vapi.ppcli("show interface span"))
250 # Enable packet capturing and start packet sending
251 self.pg_enable_capture(self.pg_interfaces)
252 self.pg_start()
253
254 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300255 n_pkts = len(pkts)
256 pg1_pkts = self.pg1.get_capture(n_pkts)
257 pg2_pkts = [self.decap_vxlan(p) for p in self.pg2.get_capture(n_pkts)]
Eyal Bari001fd402017-07-16 09:34:53 +0300258
259 self.bridge(self.vxlan.sw_if_index, is_add=0)
260 # Disable SPAN on pg0 sub if (mirrored to vxlan)
261 self.vapi.sw_interface_span_enable_disable(
262 self.sub_if.sw_if_index, self.vxlan.sw_if_index, state=0, is_l2=1)
263 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300264 self.verify_capture(pg1_pkts, pg2_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300265
John Lo2bf8b812018-02-27 16:35:03 -0500266 def test_span_l2_rx_dst_gre_erspan(self):
267 """ SPAN l2 rx mirror into gre-erspan """
268
269 self.sub_if.admin_up()
270
271 gre_if = VppGreInterface(self, self.pg2.local_ip4,
272 self.pg2.remote_ip4,
273 type=2,
274 session=543)
275
276 gre_if.add_vpp_config()
277 gre_if.admin_up()
278
279 self.bridge(gre_if.sw_if_index)
280 # Create bi-directional cross-connects between pg0 and pg1
281 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
282
283 # Create incoming packet streams for packet-generator interfaces
284 pkts = self.create_stream(
285 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
286 self.pg0.add_stream(pkts)
287
288 # Enable SPAN on pg0 sub if (mirrored to gre-erspan)
289 self.vapi.sw_interface_span_enable_disable(
290 self.sub_if.sw_if_index, gre_if.sw_if_index, is_l2=1)
291
292 # Enable packet capturing and start packet sending
293 self.pg_enable_capture(self.pg_interfaces)
294 self.pg_start()
295
296 # Verify packets outgoing packet streams on mirrored interface (pg2)
297 n_pkts = len(pkts)
298 pg1_pkts = self.pg1.get_capture(n_pkts)
299 pg2_pkts = self.pg2.get_capture(n_pkts)
300
301 def decap(p): return self.decap_erspan(p, session=543)
302 pg2_decaped = [decap(p) for p in pg2_pkts]
303
304 self.bridge(gre_if.sw_if_index, is_add=0)
305
306 # Disable SPAN on pg0 sub if
307 self.vapi.sw_interface_span_enable_disable(
308 self.sub_if.sw_if_index, gre_if.sw_if_index, state=0, is_l2=1)
309 gre_if.remove_vpp_config()
310 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
311
312 self.verify_capture(pg1_pkts, pg2_decaped)
313
Eyal Bari001fd402017-07-16 09:34:53 +0300314 def test_span_l2_rx_dst_gre_subif_vtr(self):
315 """ SPAN l2 rx mirror into gre-subif+vtr """
316
317 self.sub_if.admin_up()
318
319 gre_if = VppGreInterface(self, self.pg2.local_ip4,
320 self.pg2.remote_ip4,
John Loa43ccae2018-02-13 17:15:23 -0500321 type=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300322
323 gre_if.add_vpp_config()
324 gre_if.admin_up()
325
326 gre_sub_if = VppDot1QSubint(self, gre_if, 500)
327 gre_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=500)
328 gre_sub_if.admin_up()
329
330 self.bridge(gre_sub_if.sw_if_index)
331 # Create bi-directional cross-connects between pg0 and pg1
332 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
333
334 # Create incoming packet streams for packet-generator interfaces
335 pkts = self.create_stream(
336 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
337 self.pg0.add_stream(pkts)
338
John Lo2bf8b812018-02-27 16:35:03 -0500339 # Enable SPAN on pg0 sub if (mirrored to gre sub if)
Eyal Bari001fd402017-07-16 09:34:53 +0300340 self.vapi.sw_interface_span_enable_disable(
341 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, is_l2=1)
342
343 # Enable packet capturing and start packet sending
344 self.pg_enable_capture(self.pg_interfaces)
345 self.pg_start()
346
347 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300348 n_pkts = len(pkts)
349 pg1_pkts = self.pg1.get_capture(n_pkts)
350 pg2_pkts = self.pg2.get_capture(n_pkts)
351
352 def decap(p): return self.remove_tags(
353 self.decap_gre(p), [Tag(dot1=DOT1Q, vlan=500)])
354 pg2_decaped = [decap(p) for p in pg2_pkts]
355
Eyal Bari001fd402017-07-16 09:34:53 +0300356 self.bridge(gre_sub_if.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300357
Eyal Bari001fd402017-07-16 09:34:53 +0300358 # Disable SPAN on pg0 sub if
359 self.vapi.sw_interface_span_enable_disable(
Eyal Baricdeb7f22017-10-15 16:55:11 +0300360 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, state=0, is_l2=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300361 gre_if.remove_vpp_config()
362 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
363
Eyal Baricdeb7f22017-10-15 16:55:11 +0300364 self.verify_capture(pg1_pkts, pg2_decaped)
365
Eyal Bari17142b22017-10-16 13:38:21 +0300366 def test_span_l2_rx_dst_1q_vtr(self):
367 """ SPAN l2 rx mirror into 1q subif+vtr """
Eyal Bari001fd402017-07-16 09:34:53 +0300368
369 self.sub_if.admin_up()
Eyal Bari17142b22017-10-16 13:38:21 +0300370 self.vlan_sub_if.admin_up()
Eyal Bari001fd402017-07-16 09:34:53 +0300371
Eyal Bari17142b22017-10-16 13:38:21 +0300372 self.bridge(self.vlan_sub_if.sw_if_index)
Eyal Bari001fd402017-07-16 09:34:53 +0300373 # Create bi-directional cross-connects between pg0 and pg1
374 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
375
376 # Create incoming packet streams for packet-generator interfaces
377 pkts = self.create_stream(
378 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
379 self.pg0.add_stream(pkts)
380
381 self.vapi.sw_interface_span_enable_disable(
Eyal Bari17142b22017-10-16 13:38:21 +0300382 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, is_l2=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300383
384 # Enable packet capturing and start packet sending
385 self.pg_enable_capture(self.pg_interfaces)
386 self.pg_start()
387
388 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300389 n_pkts = len(pkts)
390 pg1_pkts = self.pg1.get_capture(n_pkts)
391 pg2_pkts = self.pg2.get_capture(n_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300392 pg2_untagged = [self.remove_tags(p, [Tag(dot1=DOT1Q, vlan=300)])
393 for p in pg2_pkts]
Eyal Bari001fd402017-07-16 09:34:53 +0300394
Eyal Bari17142b22017-10-16 13:38:21 +0300395 self.bridge(self.vlan_sub_if.sw_if_index, is_add=0)
Eyal Bari001fd402017-07-16 09:34:53 +0300396 # Disable SPAN on pg0 sub if (mirrored to vxlan)
397 self.vapi.sw_interface_span_enable_disable(
Eyal Bari17142b22017-10-16 13:38:21 +0300398 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, state=0,
399 is_l2=1)
400 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
401
402 self.verify_capture(pg1_pkts, pg2_untagged)
403
404 def test_span_l2_rx_dst_1ad_vtr(self):
405 """ SPAN l2 rx mirror into 1ad subif+vtr """
406
407 self.sub_if.admin_up()
408 self.qinq_sub_if.admin_up()
409
410 self.bridge(self.qinq_sub_if.sw_if_index)
411 # Create bi-directional cross-connects between pg0 and pg1
412 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
413
414 # Create incoming packet streams for packet-generator interfaces
415 pkts = self.create_stream(
416 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
417 self.pg0.add_stream(pkts)
418
419 self.vapi.sw_interface_span_enable_disable(
420 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, is_l2=1)
421
422 # Enable packet capturing and start packet sending
423 self.pg_enable_capture(self.pg_interfaces)
424 self.pg_start()
425
426 # Verify packets outgoing packet streams on mirrored interface (pg2)
427 n_pkts = len(pkts)
428 pg1_pkts = self.pg1.get_capture(n_pkts)
429 pg2_pkts = self.pg2.get_capture(n_pkts)
430 pg2_untagged = [self.remove_tags(p, [Tag(dot1=DOT1AD, vlan=400),
431 Tag(dot1=DOT1Q, vlan=500)])
432 for p in pg2_pkts]
433
434 self.bridge(self.qinq_sub_if.sw_if_index, is_add=0)
435 # Disable SPAN on pg0 sub if (mirrored to vxlan)
436 self.vapi.sw_interface_span_enable_disable(
437 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, state=0,
Eyal Bari001fd402017-07-16 09:34:53 +0300438 is_l2=1)
439 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
440
Eyal Baricdeb7f22017-10-15 16:55:11 +0300441 self.verify_capture(pg1_pkts, pg2_untagged)
442
Eyal Bari001fd402017-07-16 09:34:53 +0300443 def test_l2_tx_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300444 """ SPAN l2 tx mirror """
Eyal Bari001fd402017-07-16 09:34:53 +0300445
446 self.sub_if.admin_up()
447 self.bridge(self.pg2.sw_if_index)
448 # Create bi-directional cross-connects between pg0 and pg1
449 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
450 # Create incoming packet streams for packet-generator interfaces
451 pkts = self.create_stream(
452 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
453 self.pg0.add_stream(pkts)
454
Eyal Baricdeb7f22017-10-15 16:55:11 +0300455 # Enable SPAN on pg1 (mirrored to pg2)
Eyal Bari001fd402017-07-16 09:34:53 +0300456 self.vapi.sw_interface_span_enable_disable(
457 self.pg1.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=2)
458
459 self.logger.info(self.vapi.ppcli("show interface span"))
460 # Enable packet capturing and start packet sending
461 self.pg_enable_capture(self.pg_interfaces)
462 self.pg_start()
463
464 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300465 n_pkts = len(pkts)
466 pg1_pkts = self.pg1.get_capture(n_pkts)
467 pg2_pkts = self.pg2.get_capture(n_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300468 self.bridge(self.pg2.sw_if_index, is_add=0)
469 # Disable SPAN on pg0 (mirrored to pg2)
470 self.vapi.sw_interface_span_enable_disable(
471 self.pg1.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
472 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
473
Eyal Baricdeb7f22017-10-15 16:55:11 +0300474 self.verify_capture(pg1_pkts, pg2_pkts)
475
476 def test_l2_rx_tx_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300477 """ SPAN l2 rx tx mirror """
Eyal Baricdeb7f22017-10-15 16:55:11 +0300478
479 self.sub_if.admin_up()
480 self.bridge(self.pg2.sw_if_index)
481 # Create bi-directional cross-connects between pg0 and pg1
482 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
483
484 # Create incoming packet streams for packet-generator interfaces
485 pg0_pkts = self.create_stream(
486 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
487 self.pg0.add_stream(pg0_pkts)
488 pg1_pkts = self.create_stream(
489 self.pg1, self.pg_if_packet_sizes, do_dot1=False)
490 self.pg1.add_stream(pg1_pkts)
491
492 # Enable SPAN on pg0 (mirrored to pg2)
493 self.vapi.sw_interface_span_enable_disable(
494 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3)
495 self.logger.info(self.vapi.ppcli("show interface span"))
496
497 # Enable packet capturing and start packet sending
498 self.pg_enable_capture(self.pg_interfaces)
499 self.pg_start()
500
501 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300502 pg0_expected = len(pg1_pkts)
503 pg1_expected = len(pg0_pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300504 pg2_expected = pg0_expected + pg1_expected
505
506 pg0_pkts = self.pg0.get_capture(pg0_expected)
507 pg1_pkts = self.pg1.get_capture(pg1_expected)
508 pg2_pkts = self.pg2.get_capture(pg2_expected)
509
510 self.bridge(self.pg2.sw_if_index, is_add=0)
511 # Disable SPAN on pg0 (mirrored to pg2)
512 self.vapi.sw_interface_span_enable_disable(
513 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
514 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
515
516 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
517
Eyal Bari17142b22017-10-16 13:38:21 +0300518 def test_l2_bcast_mirror(self):
519 """ SPAN l2 broadcast mirror """
520
521 self.sub_if.admin_up()
522 self.bridge(self.pg2.sw_if_index)
523
524 # Create bi-directional cross-connects between pg0 and pg1
525 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100526 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300527 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100528 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300529
530 # Create incoming packet streams for packet-generator interfaces
531 pg0_pkts = self.create_stream(
532 self.pg0, self.pg_if_packet_sizes, do_dot1=True, bcast=True)
533 self.pg0.add_stream(pg0_pkts)
534 pg1_pkts = self.create_stream(
535 self.pg1, self.pg_if_packet_sizes, do_dot1=False, bcast=True)
536 self.pg1.add_stream(pg1_pkts)
537
538 # Enable SPAN on pg0 (mirrored to pg2)
539 self.vapi.sw_interface_span_enable_disable(
540 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3)
541 self.logger.info(self.vapi.ppcli("show interface span"))
542
543 # Enable packet capturing and start packet sending
544 self.pg_enable_capture(self.pg_interfaces)
545 self.pg_start()
546
547 # Verify packets outgoing packet streams on mirrored interface (pg2)
548 pg0_expected = len(pg1_pkts)
549 pg1_expected = len(pg0_pkts)
550 pg2_expected = pg0_expected + pg1_expected
551
552 pg0_pkts = self.pg0.get_capture(pg0_expected)
553 pg1_pkts = self.pg1.get_capture(pg1_expected)
554 pg2_pkts = self.pg2.get_capture(pg2_expected)
555
556 self.bridge(self.pg2.sw_if_index, is_add=0)
557 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100558 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=0)
Eyal Bari17142b22017-10-16 13:38:21 +0300559 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100560 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=0)
Eyal Bari17142b22017-10-16 13:38:21 +0300561 # Disable SPAN on pg0 (mirrored to pg2)
562 self.vapi.sw_interface_span_enable_disable(
563 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
564
565 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
566
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100567
568if __name__ == '__main__':
569 unittest.main(testRunner=VppTestRunner)