blob: 31dff682f927397180ec6c79cf79356f97e7361d [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
Dave Wallace8800f732023-08-31 00:47:44 -04006from scapy.layers.l2 import Ether, 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
Dave Wallace8800f732023-08-31 00:47:44 -040010from framework import VppTestCase
11from asfframework import VppTestRunner
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
Dmitry Valter34fa0ce2024-03-11 10:38:46 +000017from config import config
Neale Ranns5a8844b2019-04-16 07:15:35 +000018
Eyal Bari001fd402017-07-16 09:34:53 +030019
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020020Tag = namedtuple("Tag", ["dot1", "vlan"])
Eyal Bari001fd402017-07-16 09:34:53 +030021DOT1AD = 0x88A8
22DOT1Q = 0x8100
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010023
24
Dmitry Valter34fa0ce2024-03-11 10:38:46 +000025@unittest.skipIf(
26 "vxlan" in config.excluded_plugins, "Exclude tests requiring VXLAN plugin"
27)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010028class TestSpan(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020029 """SPAN Test Case"""
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010030
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010031 @classmethod
32 def setUpClass(cls):
33 super(TestSpan, cls).setUpClass()
Eyal Bari001fd402017-07-16 09:34:53 +030034 # Test variables
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020035 cls.pkts_per_burst = 257 # Number of packets per burst
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010036 # create 3 pg interfaces
Eyal Bari001fd402017-07-16 09:34:53 +030037 cls.create_pg_interfaces(range(3))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010038
Eyal Bari001fd402017-07-16 09:34:53 +030039 cls.bd_id = 55
40 cls.sub_if = VppDot1QSubint(cls, cls.pg0, 100)
Eyal Bari17142b22017-10-16 13:38:21 +030041 cls.vlan_sub_if = VppDot1QSubint(cls, cls.pg2, 300)
42 cls.vlan_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=300)
43
44 cls.qinq_sub_if = VppDot1ADSubint(cls, cls.pg2, 33, 400, 500)
45 cls.qinq_sub_if.set_vtr(L2_VTR_OP.L2_POP_2, outer=500, inner=400)
46
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010047 # packet flows mapping pg0 -> pg1, pg2 -> pg3, etc.
Eyal Bari001fd402017-07-16 09:34:53 +030048 cls.flows = dict()
49 cls.flows[cls.pg0] = [cls.pg1]
Eyal Baricdeb7f22017-10-15 16:55:11 +030050 cls.flows[cls.pg1] = [cls.pg0]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010051
52 # packet sizes
Eyal Bari17142b22017-10-16 13:38:21 +030053 cls.pg_if_packet_sizes = [64, 512, 1518] # , 9018]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010054
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010055 # setup all interfaces
Eyal Bari17142b22017-10-16 13:38:21 +030056 for i in cls.pg_interfaces:
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010057 i.admin_up()
58 i.config_ip4()
59 i.resolve_arp()
60
Eyal Bari001fd402017-07-16 09:34:53 +030061 def setUp(self):
62 super(TestSpan, self).setUp()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020063 self.vxlan = VppVxlanTunnel(
64 self, src=self.pg2.local_ip4, dst=self.pg2.remote_ip4, vni=1111
65 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +010066 self.vxlan.add_vpp_config()
Eyal Bari001fd402017-07-16 09:34:53 +030067 self.reset_packet_infos()
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010068
69 def tearDown(self):
70 super(TestSpan, self).tearDown()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -070071
72 def show_commands_at_teardown(self):
73 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010074
Eyal Bari001fd402017-07-16 09:34:53 +030075 def xconnect(self, a, b, is_add=1):
76 self.vapi.sw_interface_set_l2_xconnect(a, b, enable=is_add)
77 self.vapi.sw_interface_set_l2_xconnect(b, a, enable=is_add)
78
79 def bridge(self, sw_if_index, is_add=1):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020080 self.vapi.sw_interface_set_l2_bridge(
81 rx_sw_if_index=sw_if_index, bd_id=self.bd_id, enable=is_add
82 )
Eyal Bari001fd402017-07-16 09:34:53 +030083
84 def _remove_tag(self, packet, vlan, tag_type):
85 self.assertEqual(packet.type, tag_type)
86 payload = packet.payload
87 self.assertEqual(payload.vlan, vlan)
88 inner_type = payload.type
89 payload = payload.payload
90 packet.remove_payload()
91 packet.add_payload(payload)
92 packet.type = inner_type
93
94 def remove_tags(self, packet, tags):
95 for t in tags:
96 self._remove_tag(packet, t.vlan, t.dot1)
97 return packet
98
99 def decap_gre(self, pkt):
100 """
101 Decapsulate the original payload frame by removing GRE header
102 """
103 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
104 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
105
106 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
107 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
108
109 return pkt[GRE].payload
110
John Lo2bf8b812018-02-27 16:35:03 -0500111 def decap_erspan(self, pkt, session):
112 """
113 Decapsulate the original payload frame by removing ERSPAN header
114 """
115 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
116 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
117
118 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
119 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
120
121 self.assertEqual(pkt[ERSPAN].ver, 1)
122 self.assertEqual(pkt[ERSPAN].vlan, 0)
123 self.assertEqual(pkt[ERSPAN].cos, 0)
124 self.assertEqual(pkt[ERSPAN].en, 3)
125 self.assertEqual(pkt[ERSPAN].t, 0)
126 self.assertEqual(pkt[ERSPAN].session_id, session)
127 self.assertEqual(pkt[ERSPAN].reserved, 0)
128 self.assertEqual(pkt[ERSPAN].index, 0)
129
130 return pkt[ERSPAN].payload
131
Eyal Bari001fd402017-07-16 09:34:53 +0300132 def decap_vxlan(self, pkt):
133 """
134 Decapsulate the original payload frame by removing VXLAN header
135 """
136 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
137 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
138
139 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
140 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
141
142 return pkt[VXLAN].payload
143
Eyal Bari17142b22017-10-16 13:38:21 +0300144 def create_stream(self, src_if, packet_sizes, do_dot1=False, bcast=False):
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100145 pkts = []
Eyal Baricdeb7f22017-10-15 16:55:11 +0300146 dst_if = self.flows[src_if][0]
Eyal Bari17142b22017-10-16 13:38:21 +0300147 dst_mac = src_if.remote_mac
148 if bcast:
149 dst_mac = "ff:ff:ff:ff:ff:ff"
150
Eyal Bari001fd402017-07-16 09:34:53 +0300151 for i in range(0, self.pkts_per_burst):
Eyal Bari17142b22017-10-16 13:38:21 +0300152 payload = "span test"
snaramre2bb71512019-10-16 22:15:43 +0000153 size = packet_sizes[int((i / 2) % len(packet_sizes))]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200154 p = (
155 Ether(src=src_if.local_mac, dst=dst_mac)
156 / IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
157 / UDP(sport=10000 + src_if.sw_if_index * 1000 + i, dport=1234)
158 / Raw(payload)
159 )
Eyal Bari001fd402017-07-16 09:34:53 +0300160 if do_dot1:
161 p = self.sub_if.add_dot1_layer(p)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100162 self.extend_packet(p, size)
163 pkts.append(p)
164 return pkts
165
Eyal Baricdeb7f22017-10-15 16:55:11 +0300166 def verify_capture(self, cap1, cap2):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200167 self.assertEqual(
168 len(cap1),
169 len(cap2),
170 "Different number of sent and mirrored packets :"
171 "%u != %u" % (len(cap1), len(cap2)),
172 )
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100173
Eyal Baricdeb7f22017-10-15 16:55:11 +0300174 pkts1 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap1]
175 pkts2 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap2]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100176
Eyal Baricdeb7f22017-10-15 16:55:11 +0300177 self.assertEqual(pkts1.sort(), pkts2.sort())
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100178
Eyal Bari001fd402017-07-16 09:34:53 +0300179 def test_device_span(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200180 """SPAN device rx mirror"""
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100181
Eyal Bari001fd402017-07-16 09:34:53 +0300182 # Create bi-directional cross-connects between pg0 and pg1
183 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100184 # Create incoming packet streams for packet-generator interfaces
185 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
186 self.pg0.add_stream(pkts)
187
Eyal Bari001fd402017-07-16 09:34:53 +0300188 # Enable SPAN on pg0 (mirrored to pg2)
189 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200190 self.pg0.sw_if_index, self.pg2.sw_if_index
191 )
Eyal Bari001fd402017-07-16 09:34:53 +0300192
193 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100194 # Enable packet capturing and start packet sending
195 self.pg_enable_capture(self.pg_interfaces)
196 self.pg_start()
197
198 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300199 n_pkts = len(pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300200 pg1_pkts = self.pg1.get_capture(n_pkts)
201 pg2_pkts = self.pg2.get_capture(n_pkts)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100202
Eyal Bari001fd402017-07-16 09:34:53 +0300203 # Disable SPAN on pg0 (mirrored to pg2)
204 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200205 self.pg0.sw_if_index, self.pg2.sw_if_index, state=0
206 )
Eyal Bari001fd402017-07-16 09:34:53 +0300207 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index, is_add=0)
208
Eyal Baricdeb7f22017-10-15 16:55:11 +0300209 self.verify_capture(pg1_pkts, pg2_pkts)
210
Eyal Bari001fd402017-07-16 09:34:53 +0300211 def test_span_l2_rx(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200212 """SPAN l2 rx mirror"""
Eyal Bari001fd402017-07-16 09:34:53 +0300213
214 self.sub_if.admin_up()
215
216 self.bridge(self.pg2.sw_if_index)
Eyal Bari17142b22017-10-16 13:38:21 +0300217 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300218 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
219 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200220 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300221 self.pg0.add_stream(pkts)
222
223 # Enable SPAN on pg0 (mirrored to pg2)
224 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200225 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1
226 )
Eyal Bari001fd402017-07-16 09:34:53 +0300227
228 self.logger.info(self.vapi.ppcli("show interface span"))
229 # Enable packet capturing and start packet sending
230 self.pg_enable_capture(self.pg_interfaces)
231 self.pg_start()
232
233 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300234 pg2_expected = len(pkts)
235 pg1_pkts = self.pg1.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300236 pg2_pkts = self.pg2.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300237 self.bridge(self.pg2.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300238
Eyal Bari001fd402017-07-16 09:34:53 +0300239 # Disable SPAN on pg0 (mirrored to pg2)
240 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200241 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
242 )
Eyal Bari001fd402017-07-16 09:34:53 +0300243 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
244
Eyal Baricdeb7f22017-10-15 16:55:11 +0300245 self.verify_capture(pg1_pkts, pg2_pkts)
246
Eyal Bari001fd402017-07-16 09:34:53 +0300247 def test_span_l2_rx_dst_vxlan(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200248 """SPAN l2 rx mirror into vxlan"""
Eyal Bari001fd402017-07-16 09:34:53 +0300249
250 self.sub_if.admin_up()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200251 self.vapi.sw_interface_set_flags(self.vxlan.sw_if_index, flags=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300252
253 self.bridge(self.vxlan.sw_if_index, is_add=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300254 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300255 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
256 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200257 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300258 self.pg0.add_stream(pkts)
259
260 # Enable SPAN on pg0 sub if (mirrored to vxlan)
261 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200262 self.sub_if.sw_if_index, self.vxlan.sw_if_index, is_l2=1
263 )
Eyal Bari001fd402017-07-16 09:34:53 +0300264
265 self.logger.info(self.vapi.ppcli("show interface span"))
266 # Enable packet capturing and start packet sending
267 self.pg_enable_capture(self.pg_interfaces)
268 self.pg_start()
269
270 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300271 n_pkts = len(pkts)
272 pg1_pkts = self.pg1.get_capture(n_pkts)
273 pg2_pkts = [self.decap_vxlan(p) for p in self.pg2.get_capture(n_pkts)]
Eyal Bari001fd402017-07-16 09:34:53 +0300274
275 self.bridge(self.vxlan.sw_if_index, is_add=0)
276 # Disable SPAN on pg0 sub if (mirrored to vxlan)
277 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200278 self.sub_if.sw_if_index, self.vxlan.sw_if_index, state=0, is_l2=1
279 )
Eyal Bari001fd402017-07-16 09:34:53 +0300280 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300281 self.verify_capture(pg1_pkts, pg2_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300282
John Lo2bf8b812018-02-27 16:35:03 -0500283 def test_span_l2_rx_dst_gre_erspan(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200284 """SPAN l2 rx mirror into gre-erspan"""
John Lo2bf8b812018-02-27 16:35:03 -0500285
286 self.sub_if.admin_up()
287
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200288 gre_if = VppGreInterface(
289 self,
290 self.pg2.local_ip4,
291 self.pg2.remote_ip4,
292 session=543,
293 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_ERSPAN),
294 )
John Lo2bf8b812018-02-27 16:35:03 -0500295
296 gre_if.add_vpp_config()
297 gre_if.admin_up()
298
299 self.bridge(gre_if.sw_if_index)
300 # Create bi-directional cross-connects between pg0 and pg1
301 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
302
303 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200304 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
John Lo2bf8b812018-02-27 16:35:03 -0500305 self.pg0.add_stream(pkts)
306
307 # Enable SPAN on pg0 sub if (mirrored to gre-erspan)
308 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200309 self.sub_if.sw_if_index, gre_if.sw_if_index, is_l2=1
310 )
John Lo2bf8b812018-02-27 16:35:03 -0500311
312 # Enable packet capturing and start packet sending
313 self.pg_enable_capture(self.pg_interfaces)
314 self.pg_start()
315
316 # Verify packets outgoing packet streams on mirrored interface (pg2)
317 n_pkts = len(pkts)
318 pg1_pkts = self.pg1.get_capture(n_pkts)
319 pg2_pkts = self.pg2.get_capture(n_pkts)
320
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200321 def decap(p):
322 return self.decap_erspan(p, session=543)
323
John Lo2bf8b812018-02-27 16:35:03 -0500324 pg2_decaped = [decap(p) for p in pg2_pkts]
325
326 self.bridge(gre_if.sw_if_index, is_add=0)
327
328 # Disable SPAN on pg0 sub if
329 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200330 self.sub_if.sw_if_index, gre_if.sw_if_index, state=0, is_l2=1
331 )
John Lo2bf8b812018-02-27 16:35:03 -0500332 gre_if.remove_vpp_config()
333 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
334
335 self.verify_capture(pg1_pkts, pg2_decaped)
336
Eyal Bari001fd402017-07-16 09:34:53 +0300337 def test_span_l2_rx_dst_gre_subif_vtr(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200338 """SPAN l2 rx mirror into gre-subif+vtr"""
Eyal Bari001fd402017-07-16 09:34:53 +0300339
340 self.sub_if.admin_up()
341
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200342 gre_if = VppGreInterface(
343 self,
344 self.pg2.local_ip4,
345 self.pg2.remote_ip4,
346 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_TEB),
347 )
Eyal Bari001fd402017-07-16 09:34:53 +0300348
349 gre_if.add_vpp_config()
350 gre_if.admin_up()
351
352 gre_sub_if = VppDot1QSubint(self, gre_if, 500)
353 gre_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=500)
354 gre_sub_if.admin_up()
355
356 self.bridge(gre_sub_if.sw_if_index)
357 # Create bi-directional cross-connects between pg0 and pg1
358 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
359
360 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200361 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300362 self.pg0.add_stream(pkts)
363
John Lo2bf8b812018-02-27 16:35:03 -0500364 # Enable SPAN on pg0 sub if (mirrored to gre sub if)
Eyal Bari001fd402017-07-16 09:34:53 +0300365 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200366 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, is_l2=1
367 )
Eyal Bari001fd402017-07-16 09:34:53 +0300368
369 # Enable packet capturing and start packet sending
370 self.pg_enable_capture(self.pg_interfaces)
371 self.pg_start()
372
373 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300374 n_pkts = len(pkts)
375 pg1_pkts = self.pg1.get_capture(n_pkts)
376 pg2_pkts = self.pg2.get_capture(n_pkts)
377
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200378 def decap(p):
379 return self.remove_tags(self.decap_gre(p), [Tag(dot1=DOT1Q, vlan=500)])
380
Eyal Bari17142b22017-10-16 13:38:21 +0300381 pg2_decaped = [decap(p) for p in pg2_pkts]
382
Eyal Bari001fd402017-07-16 09:34:53 +0300383 self.bridge(gre_sub_if.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300384
Eyal Bari001fd402017-07-16 09:34:53 +0300385 # Disable SPAN on pg0 sub if
386 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200387 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, state=0, is_l2=1
388 )
Eyal Bari001fd402017-07-16 09:34:53 +0300389 gre_if.remove_vpp_config()
390 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
391
Eyal Baricdeb7f22017-10-15 16:55:11 +0300392 self.verify_capture(pg1_pkts, pg2_decaped)
393
Eyal Bari17142b22017-10-16 13:38:21 +0300394 def test_span_l2_rx_dst_1q_vtr(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200395 """SPAN l2 rx mirror into 1q subif+vtr"""
Eyal Bari001fd402017-07-16 09:34:53 +0300396
397 self.sub_if.admin_up()
Eyal Bari17142b22017-10-16 13:38:21 +0300398 self.vlan_sub_if.admin_up()
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)
Eyal Bari001fd402017-07-16 09:34:53 +0300401 # Create bi-directional cross-connects between pg0 and pg1
402 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
403
404 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200405 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300406 self.pg0.add_stream(pkts)
407
408 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200409 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, is_l2=1
410 )
Eyal Bari001fd402017-07-16 09:34:53 +0300411
412 # Enable packet capturing and start packet sending
413 self.pg_enable_capture(self.pg_interfaces)
414 self.pg_start()
415
416 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300417 n_pkts = len(pkts)
418 pg1_pkts = self.pg1.get_capture(n_pkts)
419 pg2_pkts = self.pg2.get_capture(n_pkts)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200420 pg2_untagged = [
421 self.remove_tags(p, [Tag(dot1=DOT1Q, vlan=300)]) for p in pg2_pkts
422 ]
Eyal Bari001fd402017-07-16 09:34:53 +0300423
Eyal Bari17142b22017-10-16 13:38:21 +0300424 self.bridge(self.vlan_sub_if.sw_if_index, is_add=0)
Eyal Bari001fd402017-07-16 09:34:53 +0300425 # Disable SPAN on pg0 sub if (mirrored to vxlan)
426 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200427 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, state=0, is_l2=1
428 )
Eyal Bari17142b22017-10-16 13:38:21 +0300429 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
430
431 self.verify_capture(pg1_pkts, pg2_untagged)
432
433 def test_span_l2_rx_dst_1ad_vtr(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200434 """SPAN l2 rx mirror into 1ad subif+vtr"""
Eyal Bari17142b22017-10-16 13:38:21 +0300435
436 self.sub_if.admin_up()
437 self.qinq_sub_if.admin_up()
438
439 self.bridge(self.qinq_sub_if.sw_if_index)
440 # Create bi-directional cross-connects between pg0 and pg1
441 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
442
443 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200444 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari17142b22017-10-16 13:38:21 +0300445 self.pg0.add_stream(pkts)
446
447 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200448 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, is_l2=1
449 )
Eyal Bari17142b22017-10-16 13:38:21 +0300450
451 # Enable packet capturing and start packet sending
452 self.pg_enable_capture(self.pg_interfaces)
453 self.pg_start()
454
455 # Verify packets outgoing packet streams on mirrored interface (pg2)
456 n_pkts = len(pkts)
457 pg1_pkts = self.pg1.get_capture(n_pkts)
458 pg2_pkts = self.pg2.get_capture(n_pkts)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200459 pg2_untagged = [
460 self.remove_tags(p, [Tag(dot1=DOT1AD, vlan=400), Tag(dot1=DOT1Q, vlan=500)])
461 for p in pg2_pkts
462 ]
Eyal Bari17142b22017-10-16 13:38:21 +0300463
464 self.bridge(self.qinq_sub_if.sw_if_index, is_add=0)
465 # Disable SPAN on pg0 sub if (mirrored to vxlan)
466 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200467 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, state=0, is_l2=1
468 )
Eyal Bari001fd402017-07-16 09:34:53 +0300469 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
470
Eyal Baricdeb7f22017-10-15 16:55:11 +0300471 self.verify_capture(pg1_pkts, pg2_untagged)
472
Eyal Bari001fd402017-07-16 09:34:53 +0300473 def test_l2_tx_span(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200474 """SPAN l2 tx mirror"""
Eyal Bari001fd402017-07-16 09:34:53 +0300475
476 self.sub_if.admin_up()
477 self.bridge(self.pg2.sw_if_index)
478 # Create bi-directional cross-connects between pg0 and pg1
479 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
480 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200481 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300482 self.pg0.add_stream(pkts)
483
Eyal Baricdeb7f22017-10-15 16:55:11 +0300484 # Enable SPAN on pg1 (mirrored to pg2)
Eyal Bari001fd402017-07-16 09:34:53 +0300485 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200486 self.pg1.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=2
487 )
Eyal Bari001fd402017-07-16 09:34:53 +0300488
489 self.logger.info(self.vapi.ppcli("show interface span"))
490 # Enable packet capturing and start packet sending
491 self.pg_enable_capture(self.pg_interfaces)
492 self.pg_start()
493
494 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300495 n_pkts = len(pkts)
496 pg1_pkts = self.pg1.get_capture(n_pkts)
497 pg2_pkts = self.pg2.get_capture(n_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300498 self.bridge(self.pg2.sw_if_index, is_add=0)
499 # Disable SPAN on pg0 (mirrored to pg2)
500 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200501 self.pg1.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
502 )
Eyal Bari001fd402017-07-16 09:34:53 +0300503 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
504
Eyal Baricdeb7f22017-10-15 16:55:11 +0300505 self.verify_capture(pg1_pkts, pg2_pkts)
506
507 def test_l2_rx_tx_span(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200508 """SPAN l2 rx tx mirror"""
Eyal Baricdeb7f22017-10-15 16:55:11 +0300509
510 self.sub_if.admin_up()
511 self.bridge(self.pg2.sw_if_index)
512 # Create bi-directional cross-connects between pg0 and pg1
513 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
514
515 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200516 pg0_pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300517 self.pg0.add_stream(pg0_pkts)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200518 pg1_pkts = self.create_stream(self.pg1, self.pg_if_packet_sizes, do_dot1=False)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300519 self.pg1.add_stream(pg1_pkts)
520
521 # Enable SPAN on pg0 (mirrored to pg2)
522 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200523 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3
524 )
Eyal Baricdeb7f22017-10-15 16:55:11 +0300525 self.logger.info(self.vapi.ppcli("show interface span"))
526
527 # Enable packet capturing and start packet sending
528 self.pg_enable_capture(self.pg_interfaces)
529 self.pg_start()
530
531 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300532 pg0_expected = len(pg1_pkts)
533 pg1_expected = len(pg0_pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300534 pg2_expected = pg0_expected + pg1_expected
535
536 pg0_pkts = self.pg0.get_capture(pg0_expected)
537 pg1_pkts = self.pg1.get_capture(pg1_expected)
538 pg2_pkts = self.pg2.get_capture(pg2_expected)
539
540 self.bridge(self.pg2.sw_if_index, is_add=0)
541 # Disable SPAN on pg0 (mirrored to pg2)
542 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200543 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
544 )
Eyal Baricdeb7f22017-10-15 16:55:11 +0300545 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
546
547 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
548
Eyal Bari17142b22017-10-16 13:38:21 +0300549 def test_l2_bcast_mirror(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200550 """SPAN l2 broadcast mirror"""
Eyal Bari17142b22017-10-16 13:38:21 +0300551
552 self.sub_if.admin_up()
553 self.bridge(self.pg2.sw_if_index)
554
555 # Create bi-directional cross-connects between pg0 and pg1
556 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200557 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=1
558 )
Eyal Bari17142b22017-10-16 13:38:21 +0300559 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200560 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=1
561 )
Eyal Bari17142b22017-10-16 13:38:21 +0300562
563 # Create incoming packet streams for packet-generator interfaces
564 pg0_pkts = self.create_stream(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200565 self.pg0, self.pg_if_packet_sizes, do_dot1=True, bcast=True
566 )
Eyal Bari17142b22017-10-16 13:38:21 +0300567 self.pg0.add_stream(pg0_pkts)
568 pg1_pkts = self.create_stream(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200569 self.pg1, self.pg_if_packet_sizes, do_dot1=False, bcast=True
570 )
Eyal Bari17142b22017-10-16 13:38:21 +0300571 self.pg1.add_stream(pg1_pkts)
572
573 # Enable SPAN on pg0 (mirrored to pg2)
574 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200575 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3
576 )
Eyal Bari17142b22017-10-16 13:38:21 +0300577 self.logger.info(self.vapi.ppcli("show interface span"))
578
579 # Enable packet capturing and start packet sending
580 self.pg_enable_capture(self.pg_interfaces)
581 self.pg_start()
582
583 # Verify packets outgoing packet streams on mirrored interface (pg2)
584 pg0_expected = len(pg1_pkts)
585 pg1_expected = len(pg0_pkts)
586 pg2_expected = pg0_expected + pg1_expected
587
588 pg0_pkts = self.pg0.get_capture(pg0_expected)
589 pg1_pkts = self.pg1.get_capture(pg1_expected)
590 pg2_pkts = self.pg2.get_capture(pg2_expected)
591
592 self.bridge(self.pg2.sw_if_index, is_add=0)
593 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200594 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=0
595 )
Eyal Bari17142b22017-10-16 13:38:21 +0300596 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200597 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=0
598 )
Eyal Bari17142b22017-10-16 13:38:21 +0300599 # Disable SPAN on pg0 (mirrored to pg2)
600 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200601 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
602 )
Eyal Bari17142b22017-10-16 13:38:21 +0300603
604 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
605
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100606
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200607if __name__ == "__main__":
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100608 unittest.main(testRunner=VppTestRunner)