blob: ecefe153706e09472da083c026ae774ad5d9b1c2 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +01002
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
Neale Ranns5a8844b2019-04-16 07:15:35 +000013from vpp_gre_interface import VppGreInterface
Jakub Grajciar7c0eb562020-03-02 13:55:31 +010014from vpp_vxlan_tunnel import VppVxlanTunnel
Eyal Bari001fd402017-07-16 09:34:53 +030015from collections import namedtuple
Neale Ranns5a8844b2019-04-16 07:15:35 +000016from vpp_papi import VppEnum
17
Eyal Bari001fd402017-07-16 09:34:53 +030018
19Tag = namedtuple('Tag', ['dot1', 'vlan'])
20DOT1AD = 0x88A8
21DOT1Q = 0x8100
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010022
23
24class TestSpan(VppTestCase):
25 """ SPAN Test Case """
26
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010027 @classmethod
28 def setUpClass(cls):
29 super(TestSpan, cls).setUpClass()
Eyal Bari001fd402017-07-16 09:34:53 +030030 # Test variables
Eyal Bari001fd402017-07-16 09:34:53 +030031 cls.pkts_per_burst = 257 # Number of packets per burst
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010032 # create 3 pg interfaces
Eyal Bari001fd402017-07-16 09:34:53 +030033 cls.create_pg_interfaces(range(3))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010034
Eyal Bari001fd402017-07-16 09:34:53 +030035 cls.bd_id = 55
36 cls.sub_if = VppDot1QSubint(cls, cls.pg0, 100)
Eyal Bari17142b22017-10-16 13:38:21 +030037 cls.vlan_sub_if = VppDot1QSubint(cls, cls.pg2, 300)
38 cls.vlan_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=300)
39
40 cls.qinq_sub_if = VppDot1ADSubint(cls, cls.pg2, 33, 400, 500)
41 cls.qinq_sub_if.set_vtr(L2_VTR_OP.L2_POP_2, outer=500, inner=400)
42
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010043 # packet flows mapping pg0 -> pg1, pg2 -> pg3, etc.
Eyal Bari001fd402017-07-16 09:34:53 +030044 cls.flows = dict()
45 cls.flows[cls.pg0] = [cls.pg1]
Eyal Baricdeb7f22017-10-15 16:55:11 +030046 cls.flows[cls.pg1] = [cls.pg0]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010047
48 # packet sizes
Eyal Bari17142b22017-10-16 13:38:21 +030049 cls.pg_if_packet_sizes = [64, 512, 1518] # , 9018]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010050
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010051 # setup all interfaces
Eyal Bari17142b22017-10-16 13:38:21 +030052 for i in cls.pg_interfaces:
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010053 i.admin_up()
54 i.config_ip4()
55 i.resolve_arp()
56
Eyal Bari001fd402017-07-16 09:34:53 +030057 def setUp(self):
58 super(TestSpan, self).setUp()
Jakub Grajciar7c0eb562020-03-02 13:55:31 +010059 self.vxlan = VppVxlanTunnel(self, src=self.pg2.local_ip4,
60 dst=self.pg2.remote_ip4, vni=1111)
61 self.vxlan.add_vpp_config()
Eyal Bari001fd402017-07-16 09:34:53 +030062 self.reset_packet_infos()
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010063
64 def tearDown(self):
65 super(TestSpan, self).tearDown()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -070066
67 def show_commands_at_teardown(self):
68 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010069
Eyal Bari001fd402017-07-16 09:34:53 +030070 def xconnect(self, a, b, is_add=1):
71 self.vapi.sw_interface_set_l2_xconnect(a, b, enable=is_add)
72 self.vapi.sw_interface_set_l2_xconnect(b, a, enable=is_add)
73
74 def bridge(self, sw_if_index, is_add=1):
Ole Troana5b2eec2019-03-11 19:23:25 +010075 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=sw_if_index,
76 bd_id=self.bd_id, enable=is_add)
Eyal Bari001fd402017-07-16 09:34:53 +030077
78 def _remove_tag(self, packet, vlan, tag_type):
79 self.assertEqual(packet.type, tag_type)
80 payload = packet.payload
81 self.assertEqual(payload.vlan, vlan)
82 inner_type = payload.type
83 payload = payload.payload
84 packet.remove_payload()
85 packet.add_payload(payload)
86 packet.type = inner_type
87
88 def remove_tags(self, packet, tags):
89 for t in tags:
90 self._remove_tag(packet, t.vlan, t.dot1)
91 return packet
92
93 def decap_gre(self, pkt):
94 """
95 Decapsulate the original payload frame by removing GRE header
96 """
97 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
98 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
99
100 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
101 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
102
103 return pkt[GRE].payload
104
John Lo2bf8b812018-02-27 16:35:03 -0500105 def decap_erspan(self, pkt, session):
106 """
107 Decapsulate the original payload frame by removing ERSPAN header
108 """
109 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
110 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
111
112 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
113 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
114
115 self.assertEqual(pkt[ERSPAN].ver, 1)
116 self.assertEqual(pkt[ERSPAN].vlan, 0)
117 self.assertEqual(pkt[ERSPAN].cos, 0)
118 self.assertEqual(pkt[ERSPAN].en, 3)
119 self.assertEqual(pkt[ERSPAN].t, 0)
120 self.assertEqual(pkt[ERSPAN].session_id, session)
121 self.assertEqual(pkt[ERSPAN].reserved, 0)
122 self.assertEqual(pkt[ERSPAN].index, 0)
123
124 return pkt[ERSPAN].payload
125
Eyal Bari001fd402017-07-16 09:34:53 +0300126 def decap_vxlan(self, pkt):
127 """
128 Decapsulate the original payload frame by removing VXLAN header
129 """
130 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
131 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
132
133 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
134 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
135
136 return pkt[VXLAN].payload
137
Eyal Bari17142b22017-10-16 13:38:21 +0300138 def create_stream(self, src_if, packet_sizes, do_dot1=False, bcast=False):
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100139 pkts = []
Eyal Baricdeb7f22017-10-15 16:55:11 +0300140 dst_if = self.flows[src_if][0]
Eyal Bari17142b22017-10-16 13:38:21 +0300141 dst_mac = src_if.remote_mac
142 if bcast:
143 dst_mac = "ff:ff:ff:ff:ff:ff"
144
Eyal Bari001fd402017-07-16 09:34:53 +0300145 for i in range(0, self.pkts_per_burst):
Eyal Bari17142b22017-10-16 13:38:21 +0300146 payload = "span test"
snaramre2bb71512019-10-16 22:15:43 +0000147 size = packet_sizes[int((i / 2) % len(packet_sizes))]
Eyal Bari17142b22017-10-16 13:38:21 +0300148 p = (Ether(src=src_if.local_mac, dst=dst_mac) /
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100149 IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4) /
Eyal Baricdeb7f22017-10-15 16:55:11 +0300150 UDP(sport=10000 + src_if.sw_if_index * 1000 + i, dport=1234) /
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100151 Raw(payload))
Eyal Bari001fd402017-07-16 09:34:53 +0300152 if do_dot1:
153 p = self.sub_if.add_dot1_layer(p)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100154 self.extend_packet(p, size)
155 pkts.append(p)
156 return pkts
157
Eyal Baricdeb7f22017-10-15 16:55:11 +0300158 def verify_capture(self, cap1, cap2):
159 self.assertEqual(len(cap1), len(cap2),
160 "Different number of sent and mirrored packets :"
161 "%u != %u" % (len(cap1), len(cap2)))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100162
Eyal Baricdeb7f22017-10-15 16:55:11 +0300163 pkts1 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap1]
164 pkts2 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap2]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100165
Eyal Baricdeb7f22017-10-15 16:55:11 +0300166 self.assertEqual(pkts1.sort(), pkts2.sort())
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100167
Eyal Bari001fd402017-07-16 09:34:53 +0300168 def test_device_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300169 """ SPAN device rx mirror """
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100170
Eyal Bari001fd402017-07-16 09:34:53 +0300171 # Create bi-directional cross-connects between pg0 and pg1
172 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100173 # Create incoming packet streams for packet-generator interfaces
174 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
175 self.pg0.add_stream(pkts)
176
Eyal Bari001fd402017-07-16 09:34:53 +0300177 # Enable SPAN on pg0 (mirrored to pg2)
178 self.vapi.sw_interface_span_enable_disable(
179 self.pg0.sw_if_index, self.pg2.sw_if_index)
180
181 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100182 # Enable packet capturing and start packet sending
183 self.pg_enable_capture(self.pg_interfaces)
184 self.pg_start()
185
186 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300187 n_pkts = len(pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300188 pg1_pkts = self.pg1.get_capture(n_pkts)
189 pg2_pkts = self.pg2.get_capture(n_pkts)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100190
Eyal Bari001fd402017-07-16 09:34:53 +0300191 # Disable SPAN on pg0 (mirrored to pg2)
192 self.vapi.sw_interface_span_enable_disable(
193 self.pg0.sw_if_index, self.pg2.sw_if_index, state=0)
194 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index, is_add=0)
195
Eyal Baricdeb7f22017-10-15 16:55:11 +0300196 self.verify_capture(pg1_pkts, pg2_pkts)
197
Eyal Bari001fd402017-07-16 09:34:53 +0300198 def test_span_l2_rx(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300199 """ SPAN l2 rx mirror """
Eyal Bari001fd402017-07-16 09:34:53 +0300200
201 self.sub_if.admin_up()
202
203 self.bridge(self.pg2.sw_if_index)
Eyal Bari17142b22017-10-16 13:38:21 +0300204 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300205 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
206 # Create incoming packet streams for packet-generator interfaces
207 pkts = self.create_stream(
208 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
209 self.pg0.add_stream(pkts)
210
211 # Enable SPAN on pg0 (mirrored to pg2)
212 self.vapi.sw_interface_span_enable_disable(
213 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1)
214
215 self.logger.info(self.vapi.ppcli("show interface span"))
216 # Enable packet capturing and start packet sending
217 self.pg_enable_capture(self.pg_interfaces)
218 self.pg_start()
219
220 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300221 pg2_expected = len(pkts)
222 pg1_pkts = self.pg1.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300223 pg2_pkts = self.pg2.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300224 self.bridge(self.pg2.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300225
Eyal Bari001fd402017-07-16 09:34:53 +0300226 # Disable SPAN on pg0 (mirrored to pg2)
227 self.vapi.sw_interface_span_enable_disable(
228 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
229 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
230
Eyal Baricdeb7f22017-10-15 16:55:11 +0300231 self.verify_capture(pg1_pkts, pg2_pkts)
232
Eyal Bari001fd402017-07-16 09:34:53 +0300233 def test_span_l2_rx_dst_vxlan(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300234 """ SPAN l2 rx mirror into vxlan """
Eyal Bari001fd402017-07-16 09:34:53 +0300235
236 self.sub_if.admin_up()
237 self.vapi.sw_interface_set_flags(self.vxlan.sw_if_index,
Jakub Grajciar053204a2019-03-18 13:17:53 +0100238 flags=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300239
240 self.bridge(self.vxlan.sw_if_index, is_add=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300241 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300242 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
243 # Create incoming packet streams for packet-generator interfaces
244 pkts = self.create_stream(
245 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
246 self.pg0.add_stream(pkts)
247
248 # Enable SPAN on pg0 sub if (mirrored to vxlan)
249 self.vapi.sw_interface_span_enable_disable(
250 self.sub_if.sw_if_index, self.vxlan.sw_if_index, is_l2=1)
251
252 self.logger.info(self.vapi.ppcli("show interface span"))
253 # Enable packet capturing and start packet sending
254 self.pg_enable_capture(self.pg_interfaces)
255 self.pg_start()
256
257 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300258 n_pkts = len(pkts)
259 pg1_pkts = self.pg1.get_capture(n_pkts)
260 pg2_pkts = [self.decap_vxlan(p) for p in self.pg2.get_capture(n_pkts)]
Eyal Bari001fd402017-07-16 09:34:53 +0300261
262 self.bridge(self.vxlan.sw_if_index, is_add=0)
263 # Disable SPAN on pg0 sub if (mirrored to vxlan)
264 self.vapi.sw_interface_span_enable_disable(
265 self.sub_if.sw_if_index, self.vxlan.sw_if_index, state=0, is_l2=1)
266 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300267 self.verify_capture(pg1_pkts, pg2_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300268
John Lo2bf8b812018-02-27 16:35:03 -0500269 def test_span_l2_rx_dst_gre_erspan(self):
270 """ SPAN l2 rx mirror into gre-erspan """
271
272 self.sub_if.admin_up()
273
274 gre_if = VppGreInterface(self, self.pg2.local_ip4,
275 self.pg2.remote_ip4,
Neale Ranns5a8844b2019-04-16 07:15:35 +0000276 session=543,
277 type=(VppEnum.vl_api_gre_tunnel_type_t.
278 GRE_API_TUNNEL_TYPE_ERSPAN))
John Lo2bf8b812018-02-27 16:35:03 -0500279
280 gre_if.add_vpp_config()
281 gre_if.admin_up()
282
283 self.bridge(gre_if.sw_if_index)
284 # Create bi-directional cross-connects between pg0 and pg1
285 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
286
287 # Create incoming packet streams for packet-generator interfaces
288 pkts = self.create_stream(
289 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
290 self.pg0.add_stream(pkts)
291
292 # Enable SPAN on pg0 sub if (mirrored to gre-erspan)
293 self.vapi.sw_interface_span_enable_disable(
294 self.sub_if.sw_if_index, gre_if.sw_if_index, is_l2=1)
295
296 # Enable packet capturing and start packet sending
297 self.pg_enable_capture(self.pg_interfaces)
298 self.pg_start()
299
300 # Verify packets outgoing packet streams on mirrored interface (pg2)
301 n_pkts = len(pkts)
302 pg1_pkts = self.pg1.get_capture(n_pkts)
303 pg2_pkts = self.pg2.get_capture(n_pkts)
304
305 def decap(p): return self.decap_erspan(p, session=543)
306 pg2_decaped = [decap(p) for p in pg2_pkts]
307
308 self.bridge(gre_if.sw_if_index, is_add=0)
309
310 # Disable SPAN on pg0 sub if
311 self.vapi.sw_interface_span_enable_disable(
312 self.sub_if.sw_if_index, gre_if.sw_if_index, state=0, is_l2=1)
313 gre_if.remove_vpp_config()
314 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
315
316 self.verify_capture(pg1_pkts, pg2_decaped)
317
Eyal Bari001fd402017-07-16 09:34:53 +0300318 def test_span_l2_rx_dst_gre_subif_vtr(self):
319 """ SPAN l2 rx mirror into gre-subif+vtr """
320
321 self.sub_if.admin_up()
322
323 gre_if = VppGreInterface(self, self.pg2.local_ip4,
324 self.pg2.remote_ip4,
Neale Ranns5a8844b2019-04-16 07:15:35 +0000325 type=(VppEnum.vl_api_gre_tunnel_type_t.
326 GRE_API_TUNNEL_TYPE_TEB))
Eyal Bari001fd402017-07-16 09:34:53 +0300327
328 gre_if.add_vpp_config()
329 gre_if.admin_up()
330
331 gre_sub_if = VppDot1QSubint(self, gre_if, 500)
332 gre_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=500)
333 gre_sub_if.admin_up()
334
335 self.bridge(gre_sub_if.sw_if_index)
336 # Create bi-directional cross-connects between pg0 and pg1
337 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
338
339 # Create incoming packet streams for packet-generator interfaces
340 pkts = self.create_stream(
341 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
342 self.pg0.add_stream(pkts)
343
John Lo2bf8b812018-02-27 16:35:03 -0500344 # Enable SPAN on pg0 sub if (mirrored to gre sub if)
Eyal Bari001fd402017-07-16 09:34:53 +0300345 self.vapi.sw_interface_span_enable_disable(
346 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, is_l2=1)
347
348 # Enable packet capturing and start packet sending
349 self.pg_enable_capture(self.pg_interfaces)
350 self.pg_start()
351
352 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300353 n_pkts = len(pkts)
354 pg1_pkts = self.pg1.get_capture(n_pkts)
355 pg2_pkts = self.pg2.get_capture(n_pkts)
356
357 def decap(p): return self.remove_tags(
358 self.decap_gre(p), [Tag(dot1=DOT1Q, vlan=500)])
359 pg2_decaped = [decap(p) for p in pg2_pkts]
360
Eyal Bari001fd402017-07-16 09:34:53 +0300361 self.bridge(gre_sub_if.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300362
Eyal Bari001fd402017-07-16 09:34:53 +0300363 # Disable SPAN on pg0 sub if
364 self.vapi.sw_interface_span_enable_disable(
Eyal Baricdeb7f22017-10-15 16:55:11 +0300365 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, state=0, is_l2=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300366 gre_if.remove_vpp_config()
367 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
368
Eyal Baricdeb7f22017-10-15 16:55:11 +0300369 self.verify_capture(pg1_pkts, pg2_decaped)
370
Eyal Bari17142b22017-10-16 13:38:21 +0300371 def test_span_l2_rx_dst_1q_vtr(self):
372 """ SPAN l2 rx mirror into 1q subif+vtr """
Eyal Bari001fd402017-07-16 09:34:53 +0300373
374 self.sub_if.admin_up()
Eyal Bari17142b22017-10-16 13:38:21 +0300375 self.vlan_sub_if.admin_up()
Eyal Bari001fd402017-07-16 09:34:53 +0300376
Eyal Bari17142b22017-10-16 13:38:21 +0300377 self.bridge(self.vlan_sub_if.sw_if_index)
Eyal Bari001fd402017-07-16 09:34:53 +0300378 # Create bi-directional cross-connects between pg0 and pg1
379 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
380
381 # Create incoming packet streams for packet-generator interfaces
382 pkts = self.create_stream(
383 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
384 self.pg0.add_stream(pkts)
385
386 self.vapi.sw_interface_span_enable_disable(
Eyal Bari17142b22017-10-16 13:38:21 +0300387 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, is_l2=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300388
389 # Enable packet capturing and start packet sending
390 self.pg_enable_capture(self.pg_interfaces)
391 self.pg_start()
392
393 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300394 n_pkts = len(pkts)
395 pg1_pkts = self.pg1.get_capture(n_pkts)
396 pg2_pkts = self.pg2.get_capture(n_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300397 pg2_untagged = [self.remove_tags(p, [Tag(dot1=DOT1Q, vlan=300)])
398 for p in pg2_pkts]
Eyal Bari001fd402017-07-16 09:34:53 +0300399
Eyal Bari17142b22017-10-16 13:38:21 +0300400 self.bridge(self.vlan_sub_if.sw_if_index, is_add=0)
Eyal Bari001fd402017-07-16 09:34:53 +0300401 # Disable SPAN on pg0 sub if (mirrored to vxlan)
402 self.vapi.sw_interface_span_enable_disable(
Eyal Bari17142b22017-10-16 13:38:21 +0300403 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, state=0,
404 is_l2=1)
405 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
406
407 self.verify_capture(pg1_pkts, pg2_untagged)
408
409 def test_span_l2_rx_dst_1ad_vtr(self):
410 """ SPAN l2 rx mirror into 1ad subif+vtr """
411
412 self.sub_if.admin_up()
413 self.qinq_sub_if.admin_up()
414
415 self.bridge(self.qinq_sub_if.sw_if_index)
416 # Create bi-directional cross-connects between pg0 and pg1
417 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
418
419 # Create incoming packet streams for packet-generator interfaces
420 pkts = self.create_stream(
421 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
422 self.pg0.add_stream(pkts)
423
424 self.vapi.sw_interface_span_enable_disable(
425 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, is_l2=1)
426
427 # Enable packet capturing and start packet sending
428 self.pg_enable_capture(self.pg_interfaces)
429 self.pg_start()
430
431 # Verify packets outgoing packet streams on mirrored interface (pg2)
432 n_pkts = len(pkts)
433 pg1_pkts = self.pg1.get_capture(n_pkts)
434 pg2_pkts = self.pg2.get_capture(n_pkts)
435 pg2_untagged = [self.remove_tags(p, [Tag(dot1=DOT1AD, vlan=400),
436 Tag(dot1=DOT1Q, vlan=500)])
437 for p in pg2_pkts]
438
439 self.bridge(self.qinq_sub_if.sw_if_index, is_add=0)
440 # Disable SPAN on pg0 sub if (mirrored to vxlan)
441 self.vapi.sw_interface_span_enable_disable(
442 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, state=0,
Eyal Bari001fd402017-07-16 09:34:53 +0300443 is_l2=1)
444 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
445
Eyal Baricdeb7f22017-10-15 16:55:11 +0300446 self.verify_capture(pg1_pkts, pg2_untagged)
447
Eyal Bari001fd402017-07-16 09:34:53 +0300448 def test_l2_tx_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300449 """ SPAN l2 tx mirror """
Eyal Bari001fd402017-07-16 09:34:53 +0300450
451 self.sub_if.admin_up()
452 self.bridge(self.pg2.sw_if_index)
453 # Create bi-directional cross-connects between pg0 and pg1
454 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
455 # Create incoming packet streams for packet-generator interfaces
456 pkts = self.create_stream(
457 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
458 self.pg0.add_stream(pkts)
459
Eyal Baricdeb7f22017-10-15 16:55:11 +0300460 # Enable SPAN on pg1 (mirrored to pg2)
Eyal Bari001fd402017-07-16 09:34:53 +0300461 self.vapi.sw_interface_span_enable_disable(
462 self.pg1.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=2)
463
464 self.logger.info(self.vapi.ppcli("show interface span"))
465 # Enable packet capturing and start packet sending
466 self.pg_enable_capture(self.pg_interfaces)
467 self.pg_start()
468
469 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300470 n_pkts = len(pkts)
471 pg1_pkts = self.pg1.get_capture(n_pkts)
472 pg2_pkts = self.pg2.get_capture(n_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300473 self.bridge(self.pg2.sw_if_index, is_add=0)
474 # Disable SPAN on pg0 (mirrored to pg2)
475 self.vapi.sw_interface_span_enable_disable(
476 self.pg1.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
477 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
478
Eyal Baricdeb7f22017-10-15 16:55:11 +0300479 self.verify_capture(pg1_pkts, pg2_pkts)
480
481 def test_l2_rx_tx_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300482 """ SPAN l2 rx tx mirror """
Eyal Baricdeb7f22017-10-15 16:55:11 +0300483
484 self.sub_if.admin_up()
485 self.bridge(self.pg2.sw_if_index)
486 # Create bi-directional cross-connects between pg0 and pg1
487 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
488
489 # Create incoming packet streams for packet-generator interfaces
490 pg0_pkts = self.create_stream(
491 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
492 self.pg0.add_stream(pg0_pkts)
493 pg1_pkts = self.create_stream(
494 self.pg1, self.pg_if_packet_sizes, do_dot1=False)
495 self.pg1.add_stream(pg1_pkts)
496
497 # Enable SPAN on pg0 (mirrored to pg2)
498 self.vapi.sw_interface_span_enable_disable(
499 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3)
500 self.logger.info(self.vapi.ppcli("show interface span"))
501
502 # Enable packet capturing and start packet sending
503 self.pg_enable_capture(self.pg_interfaces)
504 self.pg_start()
505
506 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300507 pg0_expected = len(pg1_pkts)
508 pg1_expected = len(pg0_pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300509 pg2_expected = pg0_expected + pg1_expected
510
511 pg0_pkts = self.pg0.get_capture(pg0_expected)
512 pg1_pkts = self.pg1.get_capture(pg1_expected)
513 pg2_pkts = self.pg2.get_capture(pg2_expected)
514
515 self.bridge(self.pg2.sw_if_index, is_add=0)
516 # Disable SPAN on pg0 (mirrored to pg2)
517 self.vapi.sw_interface_span_enable_disable(
518 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
519 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
520
521 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
522
Eyal Bari17142b22017-10-16 13:38:21 +0300523 def test_l2_bcast_mirror(self):
524 """ SPAN l2 broadcast mirror """
525
526 self.sub_if.admin_up()
527 self.bridge(self.pg2.sw_if_index)
528
529 # Create bi-directional cross-connects between pg0 and pg1
530 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100531 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300532 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100533 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300534
535 # Create incoming packet streams for packet-generator interfaces
536 pg0_pkts = self.create_stream(
537 self.pg0, self.pg_if_packet_sizes, do_dot1=True, bcast=True)
538 self.pg0.add_stream(pg0_pkts)
539 pg1_pkts = self.create_stream(
540 self.pg1, self.pg_if_packet_sizes, do_dot1=False, bcast=True)
541 self.pg1.add_stream(pg1_pkts)
542
543 # Enable SPAN on pg0 (mirrored to pg2)
544 self.vapi.sw_interface_span_enable_disable(
545 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3)
546 self.logger.info(self.vapi.ppcli("show interface span"))
547
548 # Enable packet capturing and start packet sending
549 self.pg_enable_capture(self.pg_interfaces)
550 self.pg_start()
551
552 # Verify packets outgoing packet streams on mirrored interface (pg2)
553 pg0_expected = len(pg1_pkts)
554 pg1_expected = len(pg0_pkts)
555 pg2_expected = pg0_expected + pg1_expected
556
557 pg0_pkts = self.pg0.get_capture(pg0_expected)
558 pg1_pkts = self.pg1.get_capture(pg1_expected)
559 pg2_pkts = self.pg2.get_capture(pg2_expected)
560
561 self.bridge(self.pg2.sw_if_index, is_add=0)
562 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100563 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=0)
Eyal Bari17142b22017-10-16 13:38:21 +0300564 self.vapi.sw_interface_set_l2_bridge(
Ole Troana5b2eec2019-03-11 19:23:25 +0100565 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=0)
Eyal Bari17142b22017-10-16 13:38:21 +0300566 # Disable SPAN on pg0 (mirrored to pg2)
567 self.vapi.sw_interface_span_enable_disable(
568 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
569
570 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
571
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100572
573if __name__ == '__main__':
574 unittest.main(testRunner=VppTestRunner)