blob: 3572d64e79c44e31ebc59c30f8460dce53bd5a69 [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
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020019Tag = namedtuple("Tag", ["dot1", "vlan"])
Eyal Bari001fd402017-07-16 09:34:53 +030020DOT1AD = 0x88A8
21DOT1Q = 0x8100
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010022
23
24class TestSpan(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020025 """SPAN Test Case"""
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010026
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
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020031 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()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020059 self.vxlan = VppVxlanTunnel(
60 self, src=self.pg2.local_ip4, dst=self.pg2.remote_ip4, vni=1111
61 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +010062 self.vxlan.add_vpp_config()
Eyal Bari001fd402017-07-16 09:34:53 +030063 self.reset_packet_infos()
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010064
65 def tearDown(self):
66 super(TestSpan, self).tearDown()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -070067
68 def show_commands_at_teardown(self):
69 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010070
Eyal Bari001fd402017-07-16 09:34:53 +030071 def xconnect(self, a, b, is_add=1):
72 self.vapi.sw_interface_set_l2_xconnect(a, b, enable=is_add)
73 self.vapi.sw_interface_set_l2_xconnect(b, a, enable=is_add)
74
75 def bridge(self, sw_if_index, is_add=1):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020076 self.vapi.sw_interface_set_l2_bridge(
77 rx_sw_if_index=sw_if_index, bd_id=self.bd_id, enable=is_add
78 )
Eyal Bari001fd402017-07-16 09:34:53 +030079
80 def _remove_tag(self, packet, vlan, tag_type):
81 self.assertEqual(packet.type, tag_type)
82 payload = packet.payload
83 self.assertEqual(payload.vlan, vlan)
84 inner_type = payload.type
85 payload = payload.payload
86 packet.remove_payload()
87 packet.add_payload(payload)
88 packet.type = inner_type
89
90 def remove_tags(self, packet, tags):
91 for t in tags:
92 self._remove_tag(packet, t.vlan, t.dot1)
93 return packet
94
95 def decap_gre(self, pkt):
96 """
97 Decapsulate the original payload frame by removing GRE header
98 """
99 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
100 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
101
102 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
103 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
104
105 return pkt[GRE].payload
106
John Lo2bf8b812018-02-27 16:35:03 -0500107 def decap_erspan(self, pkt, session):
108 """
109 Decapsulate the original payload frame by removing ERSPAN header
110 """
111 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
112 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
113
114 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
115 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
116
117 self.assertEqual(pkt[ERSPAN].ver, 1)
118 self.assertEqual(pkt[ERSPAN].vlan, 0)
119 self.assertEqual(pkt[ERSPAN].cos, 0)
120 self.assertEqual(pkt[ERSPAN].en, 3)
121 self.assertEqual(pkt[ERSPAN].t, 0)
122 self.assertEqual(pkt[ERSPAN].session_id, session)
123 self.assertEqual(pkt[ERSPAN].reserved, 0)
124 self.assertEqual(pkt[ERSPAN].index, 0)
125
126 return pkt[ERSPAN].payload
127
Eyal Bari001fd402017-07-16 09:34:53 +0300128 def decap_vxlan(self, pkt):
129 """
130 Decapsulate the original payload frame by removing VXLAN header
131 """
132 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
133 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
134
135 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
136 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
137
138 return pkt[VXLAN].payload
139
Eyal Bari17142b22017-10-16 13:38:21 +0300140 def create_stream(self, src_if, packet_sizes, do_dot1=False, bcast=False):
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100141 pkts = []
Eyal Baricdeb7f22017-10-15 16:55:11 +0300142 dst_if = self.flows[src_if][0]
Eyal Bari17142b22017-10-16 13:38:21 +0300143 dst_mac = src_if.remote_mac
144 if bcast:
145 dst_mac = "ff:ff:ff:ff:ff:ff"
146
Eyal Bari001fd402017-07-16 09:34:53 +0300147 for i in range(0, self.pkts_per_burst):
Eyal Bari17142b22017-10-16 13:38:21 +0300148 payload = "span test"
snaramre2bb71512019-10-16 22:15:43 +0000149 size = packet_sizes[int((i / 2) % len(packet_sizes))]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200150 p = (
151 Ether(src=src_if.local_mac, dst=dst_mac)
152 / IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
153 / UDP(sport=10000 + src_if.sw_if_index * 1000 + i, dport=1234)
154 / Raw(payload)
155 )
Eyal Bari001fd402017-07-16 09:34:53 +0300156 if do_dot1:
157 p = self.sub_if.add_dot1_layer(p)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100158 self.extend_packet(p, size)
159 pkts.append(p)
160 return pkts
161
Eyal Baricdeb7f22017-10-15 16:55:11 +0300162 def verify_capture(self, cap1, cap2):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200163 self.assertEqual(
164 len(cap1),
165 len(cap2),
166 "Different number of sent and mirrored packets :"
167 "%u != %u" % (len(cap1), len(cap2)),
168 )
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100169
Eyal Baricdeb7f22017-10-15 16:55:11 +0300170 pkts1 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap1]
171 pkts2 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap2]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100172
Eyal Baricdeb7f22017-10-15 16:55:11 +0300173 self.assertEqual(pkts1.sort(), pkts2.sort())
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100174
Eyal Bari001fd402017-07-16 09:34:53 +0300175 def test_device_span(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200176 """SPAN device rx mirror"""
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100177
Eyal Bari001fd402017-07-16 09:34:53 +0300178 # Create bi-directional cross-connects between pg0 and pg1
179 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100180 # Create incoming packet streams for packet-generator interfaces
181 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
182 self.pg0.add_stream(pkts)
183
Eyal Bari001fd402017-07-16 09:34:53 +0300184 # Enable SPAN on pg0 (mirrored to pg2)
185 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200186 self.pg0.sw_if_index, self.pg2.sw_if_index
187 )
Eyal Bari001fd402017-07-16 09:34:53 +0300188
189 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100190 # Enable packet capturing and start packet sending
191 self.pg_enable_capture(self.pg_interfaces)
192 self.pg_start()
193
194 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300195 n_pkts = len(pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300196 pg1_pkts = self.pg1.get_capture(n_pkts)
197 pg2_pkts = self.pg2.get_capture(n_pkts)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100198
Eyal Bari001fd402017-07-16 09:34:53 +0300199 # Disable SPAN on pg0 (mirrored to pg2)
200 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200201 self.pg0.sw_if_index, self.pg2.sw_if_index, state=0
202 )
Eyal Bari001fd402017-07-16 09:34:53 +0300203 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index, is_add=0)
204
Eyal Baricdeb7f22017-10-15 16:55:11 +0300205 self.verify_capture(pg1_pkts, pg2_pkts)
206
Eyal Bari001fd402017-07-16 09:34:53 +0300207 def test_span_l2_rx(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200208 """SPAN l2 rx mirror"""
Eyal Bari001fd402017-07-16 09:34:53 +0300209
210 self.sub_if.admin_up()
211
212 self.bridge(self.pg2.sw_if_index)
Eyal Bari17142b22017-10-16 13:38:21 +0300213 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300214 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
215 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200216 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300217 self.pg0.add_stream(pkts)
218
219 # Enable SPAN on pg0 (mirrored to pg2)
220 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200221 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1
222 )
Eyal Bari001fd402017-07-16 09:34:53 +0300223
224 self.logger.info(self.vapi.ppcli("show interface span"))
225 # Enable packet capturing and start packet sending
226 self.pg_enable_capture(self.pg_interfaces)
227 self.pg_start()
228
229 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300230 pg2_expected = len(pkts)
231 pg1_pkts = self.pg1.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300232 pg2_pkts = self.pg2.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300233 self.bridge(self.pg2.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300234
Eyal Bari001fd402017-07-16 09:34:53 +0300235 # Disable SPAN on pg0 (mirrored to pg2)
236 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200237 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
238 )
Eyal Bari001fd402017-07-16 09:34:53 +0300239 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
240
Eyal Baricdeb7f22017-10-15 16:55:11 +0300241 self.verify_capture(pg1_pkts, pg2_pkts)
242
Eyal Bari001fd402017-07-16 09:34:53 +0300243 def test_span_l2_rx_dst_vxlan(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200244 """SPAN l2 rx mirror into vxlan"""
Eyal Bari001fd402017-07-16 09:34:53 +0300245
246 self.sub_if.admin_up()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200247 self.vapi.sw_interface_set_flags(self.vxlan.sw_if_index, flags=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300248
249 self.bridge(self.vxlan.sw_if_index, is_add=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300250 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300251 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
252 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200253 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300254 self.pg0.add_stream(pkts)
255
256 # Enable SPAN on pg0 sub if (mirrored to vxlan)
257 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200258 self.sub_if.sw_if_index, self.vxlan.sw_if_index, is_l2=1
259 )
Eyal Bari001fd402017-07-16 09:34:53 +0300260
261 self.logger.info(self.vapi.ppcli("show interface span"))
262 # Enable packet capturing and start packet sending
263 self.pg_enable_capture(self.pg_interfaces)
264 self.pg_start()
265
266 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300267 n_pkts = len(pkts)
268 pg1_pkts = self.pg1.get_capture(n_pkts)
269 pg2_pkts = [self.decap_vxlan(p) for p in self.pg2.get_capture(n_pkts)]
Eyal Bari001fd402017-07-16 09:34:53 +0300270
271 self.bridge(self.vxlan.sw_if_index, is_add=0)
272 # Disable SPAN on pg0 sub if (mirrored to vxlan)
273 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200274 self.sub_if.sw_if_index, self.vxlan.sw_if_index, state=0, is_l2=1
275 )
Eyal Bari001fd402017-07-16 09:34:53 +0300276 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300277 self.verify_capture(pg1_pkts, pg2_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300278
John Lo2bf8b812018-02-27 16:35:03 -0500279 def test_span_l2_rx_dst_gre_erspan(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200280 """SPAN l2 rx mirror into gre-erspan"""
John Lo2bf8b812018-02-27 16:35:03 -0500281
282 self.sub_if.admin_up()
283
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200284 gre_if = VppGreInterface(
285 self,
286 self.pg2.local_ip4,
287 self.pg2.remote_ip4,
288 session=543,
289 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_ERSPAN),
290 )
John Lo2bf8b812018-02-27 16:35:03 -0500291
292 gre_if.add_vpp_config()
293 gre_if.admin_up()
294
295 self.bridge(gre_if.sw_if_index)
296 # Create bi-directional cross-connects between pg0 and pg1
297 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
298
299 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200300 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
John Lo2bf8b812018-02-27 16:35:03 -0500301 self.pg0.add_stream(pkts)
302
303 # Enable SPAN on pg0 sub if (mirrored to gre-erspan)
304 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200305 self.sub_if.sw_if_index, gre_if.sw_if_index, is_l2=1
306 )
John Lo2bf8b812018-02-27 16:35:03 -0500307
308 # Enable packet capturing and start packet sending
309 self.pg_enable_capture(self.pg_interfaces)
310 self.pg_start()
311
312 # Verify packets outgoing packet streams on mirrored interface (pg2)
313 n_pkts = len(pkts)
314 pg1_pkts = self.pg1.get_capture(n_pkts)
315 pg2_pkts = self.pg2.get_capture(n_pkts)
316
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200317 def decap(p):
318 return self.decap_erspan(p, session=543)
319
John Lo2bf8b812018-02-27 16:35:03 -0500320 pg2_decaped = [decap(p) for p in pg2_pkts]
321
322 self.bridge(gre_if.sw_if_index, is_add=0)
323
324 # Disable SPAN on pg0 sub if
325 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200326 self.sub_if.sw_if_index, gre_if.sw_if_index, state=0, is_l2=1
327 )
John Lo2bf8b812018-02-27 16:35:03 -0500328 gre_if.remove_vpp_config()
329 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
330
331 self.verify_capture(pg1_pkts, pg2_decaped)
332
Eyal Bari001fd402017-07-16 09:34:53 +0300333 def test_span_l2_rx_dst_gre_subif_vtr(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200334 """SPAN l2 rx mirror into gre-subif+vtr"""
Eyal Bari001fd402017-07-16 09:34:53 +0300335
336 self.sub_if.admin_up()
337
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200338 gre_if = VppGreInterface(
339 self,
340 self.pg2.local_ip4,
341 self.pg2.remote_ip4,
342 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_TEB),
343 )
Eyal Bari001fd402017-07-16 09:34:53 +0300344
345 gre_if.add_vpp_config()
346 gre_if.admin_up()
347
348 gre_sub_if = VppDot1QSubint(self, gre_if, 500)
349 gre_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=500)
350 gre_sub_if.admin_up()
351
352 self.bridge(gre_sub_if.sw_if_index)
353 # Create bi-directional cross-connects between pg0 and pg1
354 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
355
356 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200357 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300358 self.pg0.add_stream(pkts)
359
John Lo2bf8b812018-02-27 16:35:03 -0500360 # Enable SPAN on pg0 sub if (mirrored to gre sub if)
Eyal Bari001fd402017-07-16 09:34:53 +0300361 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200362 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, is_l2=1
363 )
Eyal Bari001fd402017-07-16 09:34:53 +0300364
365 # Enable packet capturing and start packet sending
366 self.pg_enable_capture(self.pg_interfaces)
367 self.pg_start()
368
369 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300370 n_pkts = len(pkts)
371 pg1_pkts = self.pg1.get_capture(n_pkts)
372 pg2_pkts = self.pg2.get_capture(n_pkts)
373
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200374 def decap(p):
375 return self.remove_tags(self.decap_gre(p), [Tag(dot1=DOT1Q, vlan=500)])
376
Eyal Bari17142b22017-10-16 13:38:21 +0300377 pg2_decaped = [decap(p) for p in pg2_pkts]
378
Eyal Bari001fd402017-07-16 09:34:53 +0300379 self.bridge(gre_sub_if.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300380
Eyal Bari001fd402017-07-16 09:34:53 +0300381 # Disable SPAN on pg0 sub if
382 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200383 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, state=0, is_l2=1
384 )
Eyal Bari001fd402017-07-16 09:34:53 +0300385 gre_if.remove_vpp_config()
386 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
387
Eyal Baricdeb7f22017-10-15 16:55:11 +0300388 self.verify_capture(pg1_pkts, pg2_decaped)
389
Eyal Bari17142b22017-10-16 13:38:21 +0300390 def test_span_l2_rx_dst_1q_vtr(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200391 """SPAN l2 rx mirror into 1q subif+vtr"""
Eyal Bari001fd402017-07-16 09:34:53 +0300392
393 self.sub_if.admin_up()
Eyal Bari17142b22017-10-16 13:38:21 +0300394 self.vlan_sub_if.admin_up()
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)
Eyal Bari001fd402017-07-16 09:34:53 +0300397 # Create bi-directional cross-connects between pg0 and pg1
398 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
399
400 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200401 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300402 self.pg0.add_stream(pkts)
403
404 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200405 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, is_l2=1
406 )
Eyal Bari001fd402017-07-16 09:34:53 +0300407
408 # Enable packet capturing and start packet sending
409 self.pg_enable_capture(self.pg_interfaces)
410 self.pg_start()
411
412 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300413 n_pkts = len(pkts)
414 pg1_pkts = self.pg1.get_capture(n_pkts)
415 pg2_pkts = self.pg2.get_capture(n_pkts)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200416 pg2_untagged = [
417 self.remove_tags(p, [Tag(dot1=DOT1Q, vlan=300)]) for p in pg2_pkts
418 ]
Eyal Bari001fd402017-07-16 09:34:53 +0300419
Eyal Bari17142b22017-10-16 13:38:21 +0300420 self.bridge(self.vlan_sub_if.sw_if_index, is_add=0)
Eyal Bari001fd402017-07-16 09:34:53 +0300421 # Disable SPAN on pg0 sub if (mirrored to vxlan)
422 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200423 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, state=0, is_l2=1
424 )
Eyal Bari17142b22017-10-16 13:38:21 +0300425 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
426
427 self.verify_capture(pg1_pkts, pg2_untagged)
428
429 def test_span_l2_rx_dst_1ad_vtr(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200430 """SPAN l2 rx mirror into 1ad subif+vtr"""
Eyal Bari17142b22017-10-16 13:38:21 +0300431
432 self.sub_if.admin_up()
433 self.qinq_sub_if.admin_up()
434
435 self.bridge(self.qinq_sub_if.sw_if_index)
436 # Create bi-directional cross-connects between pg0 and pg1
437 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
438
439 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200440 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari17142b22017-10-16 13:38:21 +0300441 self.pg0.add_stream(pkts)
442
443 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200444 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, is_l2=1
445 )
Eyal Bari17142b22017-10-16 13:38:21 +0300446
447 # Enable packet capturing and start packet sending
448 self.pg_enable_capture(self.pg_interfaces)
449 self.pg_start()
450
451 # Verify packets outgoing packet streams on mirrored interface (pg2)
452 n_pkts = len(pkts)
453 pg1_pkts = self.pg1.get_capture(n_pkts)
454 pg2_pkts = self.pg2.get_capture(n_pkts)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200455 pg2_untagged = [
456 self.remove_tags(p, [Tag(dot1=DOT1AD, vlan=400), Tag(dot1=DOT1Q, vlan=500)])
457 for p in pg2_pkts
458 ]
Eyal Bari17142b22017-10-16 13:38:21 +0300459
460 self.bridge(self.qinq_sub_if.sw_if_index, is_add=0)
461 # Disable SPAN on pg0 sub if (mirrored to vxlan)
462 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200463 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, state=0, is_l2=1
464 )
Eyal Bari001fd402017-07-16 09:34:53 +0300465 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
466
Eyal Baricdeb7f22017-10-15 16:55:11 +0300467 self.verify_capture(pg1_pkts, pg2_untagged)
468
Eyal Bari001fd402017-07-16 09:34:53 +0300469 def test_l2_tx_span(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200470 """SPAN l2 tx mirror"""
Eyal Bari001fd402017-07-16 09:34:53 +0300471
472 self.sub_if.admin_up()
473 self.bridge(self.pg2.sw_if_index)
474 # Create bi-directional cross-connects between pg0 and pg1
475 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
476 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200477 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300478 self.pg0.add_stream(pkts)
479
Eyal Baricdeb7f22017-10-15 16:55:11 +0300480 # Enable SPAN on pg1 (mirrored to pg2)
Eyal Bari001fd402017-07-16 09:34:53 +0300481 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200482 self.pg1.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=2
483 )
Eyal Bari001fd402017-07-16 09:34:53 +0300484
485 self.logger.info(self.vapi.ppcli("show interface span"))
486 # Enable packet capturing and start packet sending
487 self.pg_enable_capture(self.pg_interfaces)
488 self.pg_start()
489
490 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300491 n_pkts = len(pkts)
492 pg1_pkts = self.pg1.get_capture(n_pkts)
493 pg2_pkts = self.pg2.get_capture(n_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300494 self.bridge(self.pg2.sw_if_index, is_add=0)
495 # Disable SPAN on pg0 (mirrored to pg2)
496 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200497 self.pg1.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
498 )
Eyal Bari001fd402017-07-16 09:34:53 +0300499 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
500
Eyal Baricdeb7f22017-10-15 16:55:11 +0300501 self.verify_capture(pg1_pkts, pg2_pkts)
502
503 def test_l2_rx_tx_span(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200504 """SPAN l2 rx tx mirror"""
Eyal Baricdeb7f22017-10-15 16:55:11 +0300505
506 self.sub_if.admin_up()
507 self.bridge(self.pg2.sw_if_index)
508 # Create bi-directional cross-connects between pg0 and pg1
509 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
510
511 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200512 pg0_pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300513 self.pg0.add_stream(pg0_pkts)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200514 pg1_pkts = self.create_stream(self.pg1, self.pg_if_packet_sizes, do_dot1=False)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300515 self.pg1.add_stream(pg1_pkts)
516
517 # Enable SPAN on pg0 (mirrored to pg2)
518 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200519 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3
520 )
Eyal Baricdeb7f22017-10-15 16:55:11 +0300521 self.logger.info(self.vapi.ppcli("show interface span"))
522
523 # Enable packet capturing and start packet sending
524 self.pg_enable_capture(self.pg_interfaces)
525 self.pg_start()
526
527 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300528 pg0_expected = len(pg1_pkts)
529 pg1_expected = len(pg0_pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300530 pg2_expected = pg0_expected + pg1_expected
531
532 pg0_pkts = self.pg0.get_capture(pg0_expected)
533 pg1_pkts = self.pg1.get_capture(pg1_expected)
534 pg2_pkts = self.pg2.get_capture(pg2_expected)
535
536 self.bridge(self.pg2.sw_if_index, is_add=0)
537 # Disable SPAN on pg0 (mirrored to pg2)
538 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200539 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
540 )
Eyal Baricdeb7f22017-10-15 16:55:11 +0300541 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
542
543 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
544
Eyal Bari17142b22017-10-16 13:38:21 +0300545 def test_l2_bcast_mirror(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200546 """SPAN l2 broadcast mirror"""
Eyal Bari17142b22017-10-16 13:38:21 +0300547
548 self.sub_if.admin_up()
549 self.bridge(self.pg2.sw_if_index)
550
551 # Create bi-directional cross-connects between pg0 and pg1
552 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200553 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=1
554 )
Eyal Bari17142b22017-10-16 13:38:21 +0300555 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200556 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=1
557 )
Eyal Bari17142b22017-10-16 13:38:21 +0300558
559 # Create incoming packet streams for packet-generator interfaces
560 pg0_pkts = self.create_stream(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200561 self.pg0, self.pg_if_packet_sizes, do_dot1=True, bcast=True
562 )
Eyal Bari17142b22017-10-16 13:38:21 +0300563 self.pg0.add_stream(pg0_pkts)
564 pg1_pkts = self.create_stream(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200565 self.pg1, self.pg_if_packet_sizes, do_dot1=False, bcast=True
566 )
Eyal Bari17142b22017-10-16 13:38:21 +0300567 self.pg1.add_stream(pg1_pkts)
568
569 # Enable SPAN on pg0 (mirrored to pg2)
570 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200571 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3
572 )
Eyal Bari17142b22017-10-16 13:38:21 +0300573 self.logger.info(self.vapi.ppcli("show interface span"))
574
575 # Enable packet capturing and start packet sending
576 self.pg_enable_capture(self.pg_interfaces)
577 self.pg_start()
578
579 # Verify packets outgoing packet streams on mirrored interface (pg2)
580 pg0_expected = len(pg1_pkts)
581 pg1_expected = len(pg0_pkts)
582 pg2_expected = pg0_expected + pg1_expected
583
584 pg0_pkts = self.pg0.get_capture(pg0_expected)
585 pg1_pkts = self.pg1.get_capture(pg1_expected)
586 pg2_pkts = self.pg2.get_capture(pg2_expected)
587
588 self.bridge(self.pg2.sw_if_index, is_add=0)
589 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200590 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=0
591 )
Eyal Bari17142b22017-10-16 13:38:21 +0300592 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200593 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=0
594 )
Eyal Bari17142b22017-10-16 13:38:21 +0300595 # Disable SPAN on pg0 (mirrored to pg2)
596 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200597 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
598 )
Eyal Bari17142b22017-10-16 13:38:21 +0300599
600 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
601
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100602
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200603if __name__ == "__main__":
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100604 unittest.main(testRunner=VppTestRunner)