blob: b151ef4f7a1bfb9a0a981b2703367669a7358644 [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 Wallacecf9356d2024-07-23 01:28:19 -04006from scapy.layers.l2 import Ether, GRE
7from scapy.contrib.erspan import ERSPAN
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +01008from scapy.layers.inet import IP, UDP
Eyal Bari001fd402017-07-16 09:34:53 +03009from scapy.layers.vxlan import VXLAN
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010010
Dave Wallace8800f732023-08-31 00:47:44 -040011from framework import VppTestCase
12from asfframework import VppTestRunner
Paul Vinciguerra95c0ca42019-03-28 13:07:00 -070013from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint, VppDot1ADSubint
Neale Ranns5a8844b2019-04-16 07:15:35 +000014from vpp_gre_interface import VppGreInterface
Jakub Grajciar7c0eb562020-03-02 13:55:31 +010015from vpp_vxlan_tunnel import VppVxlanTunnel
Eyal Bari001fd402017-07-16 09:34:53 +030016from collections import namedtuple
Neale Ranns5a8844b2019-04-16 07:15:35 +000017from vpp_papi import VppEnum
Dmitry Valter34fa0ce2024-03-11 10:38:46 +000018from config import config
Neale Ranns5a8844b2019-04-16 07:15:35 +000019
Eyal Bari001fd402017-07-16 09:34:53 +030020
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020021Tag = namedtuple("Tag", ["dot1", "vlan"])
Eyal Bari001fd402017-07-16 09:34:53 +030022DOT1AD = 0x88A8
23DOT1Q = 0x8100
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010024
25
Dmitry Valter34fa0ce2024-03-11 10:38:46 +000026@unittest.skipIf(
27 "vxlan" in config.excluded_plugins, "Exclude tests requiring VXLAN plugin"
28)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010029class TestSpan(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020030 """SPAN Test Case"""
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010031
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010032 @classmethod
33 def setUpClass(cls):
34 super(TestSpan, cls).setUpClass()
Eyal Bari001fd402017-07-16 09:34:53 +030035 # Test variables
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020036 cls.pkts_per_burst = 257 # Number of packets per burst
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010037 # create 3 pg interfaces
Eyal Bari001fd402017-07-16 09:34:53 +030038 cls.create_pg_interfaces(range(3))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010039
Eyal Bari001fd402017-07-16 09:34:53 +030040 cls.bd_id = 55
41 cls.sub_if = VppDot1QSubint(cls, cls.pg0, 100)
Eyal Bari17142b22017-10-16 13:38:21 +030042 cls.vlan_sub_if = VppDot1QSubint(cls, cls.pg2, 300)
43 cls.vlan_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=300)
44
45 cls.qinq_sub_if = VppDot1ADSubint(cls, cls.pg2, 33, 400, 500)
46 cls.qinq_sub_if.set_vtr(L2_VTR_OP.L2_POP_2, outer=500, inner=400)
47
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010048 # packet flows mapping pg0 -> pg1, pg2 -> pg3, etc.
Eyal Bari001fd402017-07-16 09:34:53 +030049 cls.flows = dict()
50 cls.flows[cls.pg0] = [cls.pg1]
Eyal Baricdeb7f22017-10-15 16:55:11 +030051 cls.flows[cls.pg1] = [cls.pg0]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010052
53 # packet sizes
Eyal Bari17142b22017-10-16 13:38:21 +030054 cls.pg_if_packet_sizes = [64, 512, 1518] # , 9018]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010055
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010056 # setup all interfaces
Eyal Bari17142b22017-10-16 13:38:21 +030057 for i in cls.pg_interfaces:
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010058 i.admin_up()
59 i.config_ip4()
60 i.resolve_arp()
61
Eyal Bari001fd402017-07-16 09:34:53 +030062 def setUp(self):
63 super(TestSpan, self).setUp()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020064 self.vxlan = VppVxlanTunnel(
65 self, src=self.pg2.local_ip4, dst=self.pg2.remote_ip4, vni=1111
66 )
Jakub Grajciar7c0eb562020-03-02 13:55:31 +010067 self.vxlan.add_vpp_config()
Eyal Bari001fd402017-07-16 09:34:53 +030068 self.reset_packet_infos()
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010069
70 def tearDown(self):
71 super(TestSpan, self).tearDown()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -070072
73 def show_commands_at_teardown(self):
74 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010075
Eyal Bari001fd402017-07-16 09:34:53 +030076 def xconnect(self, a, b, is_add=1):
77 self.vapi.sw_interface_set_l2_xconnect(a, b, enable=is_add)
78 self.vapi.sw_interface_set_l2_xconnect(b, a, enable=is_add)
79
80 def bridge(self, sw_if_index, is_add=1):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020081 self.vapi.sw_interface_set_l2_bridge(
82 rx_sw_if_index=sw_if_index, bd_id=self.bd_id, enable=is_add
83 )
Eyal Bari001fd402017-07-16 09:34:53 +030084
85 def _remove_tag(self, packet, vlan, tag_type):
86 self.assertEqual(packet.type, tag_type)
87 payload = packet.payload
88 self.assertEqual(payload.vlan, vlan)
89 inner_type = payload.type
90 payload = payload.payload
91 packet.remove_payload()
92 packet.add_payload(payload)
93 packet.type = inner_type
94
95 def remove_tags(self, packet, tags):
96 for t in tags:
97 self._remove_tag(packet, t.vlan, t.dot1)
98 return packet
99
100 def decap_gre(self, pkt):
101 """
102 Decapsulate the original payload frame by removing GRE header
103 """
104 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
105 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
106
107 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
108 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
109
110 return pkt[GRE].payload
111
John Lo2bf8b812018-02-27 16:35:03 -0500112 def decap_erspan(self, pkt, session):
113 """
114 Decapsulate the original payload frame by removing ERSPAN header
115 """
116 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
117 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
118
119 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
120 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
121
122 self.assertEqual(pkt[ERSPAN].ver, 1)
123 self.assertEqual(pkt[ERSPAN].vlan, 0)
124 self.assertEqual(pkt[ERSPAN].cos, 0)
125 self.assertEqual(pkt[ERSPAN].en, 3)
126 self.assertEqual(pkt[ERSPAN].t, 0)
127 self.assertEqual(pkt[ERSPAN].session_id, session)
128 self.assertEqual(pkt[ERSPAN].reserved, 0)
129 self.assertEqual(pkt[ERSPAN].index, 0)
130
131 return pkt[ERSPAN].payload
132
Eyal Bari001fd402017-07-16 09:34:53 +0300133 def decap_vxlan(self, pkt):
134 """
135 Decapsulate the original payload frame by removing VXLAN header
136 """
137 self.assertEqual(pkt[Ether].src, self.pg2.local_mac)
138 self.assertEqual(pkt[Ether].dst, self.pg2.remote_mac)
139
140 self.assertEqual(pkt[IP].src, self.pg2.local_ip4)
141 self.assertEqual(pkt[IP].dst, self.pg2.remote_ip4)
142
143 return pkt[VXLAN].payload
144
Eyal Bari17142b22017-10-16 13:38:21 +0300145 def create_stream(self, src_if, packet_sizes, do_dot1=False, bcast=False):
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100146 pkts = []
Eyal Baricdeb7f22017-10-15 16:55:11 +0300147 dst_if = self.flows[src_if][0]
Eyal Bari17142b22017-10-16 13:38:21 +0300148 dst_mac = src_if.remote_mac
149 if bcast:
150 dst_mac = "ff:ff:ff:ff:ff:ff"
151
Eyal Bari001fd402017-07-16 09:34:53 +0300152 for i in range(0, self.pkts_per_burst):
Eyal Bari17142b22017-10-16 13:38:21 +0300153 payload = "span test"
snaramre2bb71512019-10-16 22:15:43 +0000154 size = packet_sizes[int((i / 2) % len(packet_sizes))]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200155 p = (
156 Ether(src=src_if.local_mac, dst=dst_mac)
157 / IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
158 / UDP(sport=10000 + src_if.sw_if_index * 1000 + i, dport=1234)
159 / Raw(payload)
160 )
Eyal Bari001fd402017-07-16 09:34:53 +0300161 if do_dot1:
162 p = self.sub_if.add_dot1_layer(p)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100163 self.extend_packet(p, size)
164 pkts.append(p)
165 return pkts
166
Eyal Baricdeb7f22017-10-15 16:55:11 +0300167 def verify_capture(self, cap1, cap2):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200168 self.assertEqual(
169 len(cap1),
170 len(cap2),
171 "Different number of sent and mirrored packets :"
172 "%u != %u" % (len(cap1), len(cap2)),
173 )
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100174
Eyal Baricdeb7f22017-10-15 16:55:11 +0300175 pkts1 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap1]
176 pkts2 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap2]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100177
Eyal Baricdeb7f22017-10-15 16:55:11 +0300178 self.assertEqual(pkts1.sort(), pkts2.sort())
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100179
Eyal Bari001fd402017-07-16 09:34:53 +0300180 def test_device_span(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200181 """SPAN device rx mirror"""
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100182
Eyal Bari001fd402017-07-16 09:34:53 +0300183 # Create bi-directional cross-connects between pg0 and pg1
184 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100185 # Create incoming packet streams for packet-generator interfaces
186 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
187 self.pg0.add_stream(pkts)
188
Eyal Bari001fd402017-07-16 09:34:53 +0300189 # Enable SPAN on pg0 (mirrored to pg2)
190 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200191 self.pg0.sw_if_index, self.pg2.sw_if_index
192 )
Eyal Bari001fd402017-07-16 09:34:53 +0300193
194 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100195 # Enable packet capturing and start packet sending
196 self.pg_enable_capture(self.pg_interfaces)
197 self.pg_start()
198
199 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300200 n_pkts = len(pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300201 pg1_pkts = self.pg1.get_capture(n_pkts)
202 pg2_pkts = self.pg2.get_capture(n_pkts)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100203
Eyal Bari001fd402017-07-16 09:34:53 +0300204 # Disable SPAN on pg0 (mirrored to pg2)
205 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200206 self.pg0.sw_if_index, self.pg2.sw_if_index, state=0
207 )
Eyal Bari001fd402017-07-16 09:34:53 +0300208 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index, is_add=0)
209
Eyal Baricdeb7f22017-10-15 16:55:11 +0300210 self.verify_capture(pg1_pkts, pg2_pkts)
211
Eyal Bari001fd402017-07-16 09:34:53 +0300212 def test_span_l2_rx(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200213 """SPAN l2 rx mirror"""
Eyal Bari001fd402017-07-16 09:34:53 +0300214
215 self.sub_if.admin_up()
216
217 self.bridge(self.pg2.sw_if_index)
Eyal Bari17142b22017-10-16 13:38:21 +0300218 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300219 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
220 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200221 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300222 self.pg0.add_stream(pkts)
223
224 # Enable SPAN on pg0 (mirrored to pg2)
225 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200226 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1
227 )
Eyal Bari001fd402017-07-16 09:34:53 +0300228
229 self.logger.info(self.vapi.ppcli("show interface span"))
230 # Enable packet capturing and start packet sending
231 self.pg_enable_capture(self.pg_interfaces)
232 self.pg_start()
233
234 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300235 pg2_expected = len(pkts)
236 pg1_pkts = self.pg1.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300237 pg2_pkts = self.pg2.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300238 self.bridge(self.pg2.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300239
Eyal Bari001fd402017-07-16 09:34:53 +0300240 # Disable SPAN on pg0 (mirrored to pg2)
241 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200242 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
243 )
Eyal Bari001fd402017-07-16 09:34:53 +0300244 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
245
Eyal Baricdeb7f22017-10-15 16:55:11 +0300246 self.verify_capture(pg1_pkts, pg2_pkts)
247
Eyal Bari001fd402017-07-16 09:34:53 +0300248 def test_span_l2_rx_dst_vxlan(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200249 """SPAN l2 rx mirror into vxlan"""
Eyal Bari001fd402017-07-16 09:34:53 +0300250
251 self.sub_if.admin_up()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200252 self.vapi.sw_interface_set_flags(self.vxlan.sw_if_index, flags=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300253
254 self.bridge(self.vxlan.sw_if_index, is_add=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300255 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300256 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
257 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200258 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300259 self.pg0.add_stream(pkts)
260
261 # Enable SPAN on pg0 sub if (mirrored to vxlan)
262 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200263 self.sub_if.sw_if_index, self.vxlan.sw_if_index, is_l2=1
264 )
Eyal Bari001fd402017-07-16 09:34:53 +0300265
266 self.logger.info(self.vapi.ppcli("show interface span"))
267 # Enable packet capturing and start packet sending
268 self.pg_enable_capture(self.pg_interfaces)
269 self.pg_start()
270
271 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300272 n_pkts = len(pkts)
273 pg1_pkts = self.pg1.get_capture(n_pkts)
274 pg2_pkts = [self.decap_vxlan(p) for p in self.pg2.get_capture(n_pkts)]
Eyal Bari001fd402017-07-16 09:34:53 +0300275
276 self.bridge(self.vxlan.sw_if_index, is_add=0)
277 # Disable SPAN on pg0 sub if (mirrored to vxlan)
278 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200279 self.sub_if.sw_if_index, self.vxlan.sw_if_index, state=0, is_l2=1
280 )
Eyal Bari001fd402017-07-16 09:34:53 +0300281 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300282 self.verify_capture(pg1_pkts, pg2_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300283
John Lo2bf8b812018-02-27 16:35:03 -0500284 def test_span_l2_rx_dst_gre_erspan(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200285 """SPAN l2 rx mirror into gre-erspan"""
John Lo2bf8b812018-02-27 16:35:03 -0500286
287 self.sub_if.admin_up()
288
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200289 gre_if = VppGreInterface(
290 self,
291 self.pg2.local_ip4,
292 self.pg2.remote_ip4,
293 session=543,
294 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_ERSPAN),
295 )
John Lo2bf8b812018-02-27 16:35:03 -0500296
297 gre_if.add_vpp_config()
298 gre_if.admin_up()
299
300 self.bridge(gre_if.sw_if_index)
301 # Create bi-directional cross-connects between pg0 and pg1
302 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
303
304 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200305 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
John Lo2bf8b812018-02-27 16:35:03 -0500306 self.pg0.add_stream(pkts)
307
308 # Enable SPAN on pg0 sub if (mirrored to gre-erspan)
309 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200310 self.sub_if.sw_if_index, gre_if.sw_if_index, is_l2=1
311 )
John Lo2bf8b812018-02-27 16:35:03 -0500312
313 # Enable packet capturing and start packet sending
314 self.pg_enable_capture(self.pg_interfaces)
315 self.pg_start()
316
317 # Verify packets outgoing packet streams on mirrored interface (pg2)
318 n_pkts = len(pkts)
319 pg1_pkts = self.pg1.get_capture(n_pkts)
320 pg2_pkts = self.pg2.get_capture(n_pkts)
321
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200322 def decap(p):
323 return self.decap_erspan(p, session=543)
324
John Lo2bf8b812018-02-27 16:35:03 -0500325 pg2_decaped = [decap(p) for p in pg2_pkts]
326
327 self.bridge(gre_if.sw_if_index, is_add=0)
328
329 # Disable SPAN on pg0 sub if
330 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200331 self.sub_if.sw_if_index, gre_if.sw_if_index, state=0, is_l2=1
332 )
John Lo2bf8b812018-02-27 16:35:03 -0500333 gre_if.remove_vpp_config()
334 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
335
336 self.verify_capture(pg1_pkts, pg2_decaped)
337
Eyal Bari001fd402017-07-16 09:34:53 +0300338 def test_span_l2_rx_dst_gre_subif_vtr(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200339 """SPAN l2 rx mirror into gre-subif+vtr"""
Eyal Bari001fd402017-07-16 09:34:53 +0300340
341 self.sub_if.admin_up()
342
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200343 gre_if = VppGreInterface(
344 self,
345 self.pg2.local_ip4,
346 self.pg2.remote_ip4,
347 type=(VppEnum.vl_api_gre_tunnel_type_t.GRE_API_TUNNEL_TYPE_TEB),
348 )
Eyal Bari001fd402017-07-16 09:34:53 +0300349
350 gre_if.add_vpp_config()
351 gre_if.admin_up()
352
353 gre_sub_if = VppDot1QSubint(self, gre_if, 500)
354 gre_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=500)
355 gre_sub_if.admin_up()
356
357 self.bridge(gre_sub_if.sw_if_index)
358 # Create bi-directional cross-connects between pg0 and pg1
359 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
360
361 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200362 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300363 self.pg0.add_stream(pkts)
364
John Lo2bf8b812018-02-27 16:35:03 -0500365 # Enable SPAN on pg0 sub if (mirrored to gre sub if)
Eyal Bari001fd402017-07-16 09:34:53 +0300366 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200367 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, is_l2=1
368 )
Eyal Bari001fd402017-07-16 09:34:53 +0300369
370 # Enable packet capturing and start packet sending
371 self.pg_enable_capture(self.pg_interfaces)
372 self.pg_start()
373
374 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300375 n_pkts = len(pkts)
376 pg1_pkts = self.pg1.get_capture(n_pkts)
377 pg2_pkts = self.pg2.get_capture(n_pkts)
378
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200379 def decap(p):
380 return self.remove_tags(self.decap_gre(p), [Tag(dot1=DOT1Q, vlan=500)])
381
Eyal Bari17142b22017-10-16 13:38:21 +0300382 pg2_decaped = [decap(p) for p in pg2_pkts]
383
Eyal Bari001fd402017-07-16 09:34:53 +0300384 self.bridge(gre_sub_if.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300385
Eyal Bari001fd402017-07-16 09:34:53 +0300386 # Disable SPAN on pg0 sub if
387 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200388 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, state=0, is_l2=1
389 )
Eyal Bari001fd402017-07-16 09:34:53 +0300390 gre_if.remove_vpp_config()
391 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
392
Eyal Baricdeb7f22017-10-15 16:55:11 +0300393 self.verify_capture(pg1_pkts, pg2_decaped)
394
Eyal Bari17142b22017-10-16 13:38:21 +0300395 def test_span_l2_rx_dst_1q_vtr(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200396 """SPAN l2 rx mirror into 1q subif+vtr"""
Eyal Bari001fd402017-07-16 09:34:53 +0300397
398 self.sub_if.admin_up()
Eyal Bari17142b22017-10-16 13:38:21 +0300399 self.vlan_sub_if.admin_up()
Eyal Bari001fd402017-07-16 09:34:53 +0300400
Eyal Bari17142b22017-10-16 13:38:21 +0300401 self.bridge(self.vlan_sub_if.sw_if_index)
Eyal Bari001fd402017-07-16 09:34:53 +0300402 # Create bi-directional cross-connects between pg0 and pg1
403 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
404
405 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200406 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300407 self.pg0.add_stream(pkts)
408
409 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200410 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, is_l2=1
411 )
Eyal Bari001fd402017-07-16 09:34:53 +0300412
413 # Enable packet capturing and start packet sending
414 self.pg_enable_capture(self.pg_interfaces)
415 self.pg_start()
416
417 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300418 n_pkts = len(pkts)
419 pg1_pkts = self.pg1.get_capture(n_pkts)
420 pg2_pkts = self.pg2.get_capture(n_pkts)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200421 pg2_untagged = [
422 self.remove_tags(p, [Tag(dot1=DOT1Q, vlan=300)]) for p in pg2_pkts
423 ]
Eyal Bari001fd402017-07-16 09:34:53 +0300424
Eyal Bari17142b22017-10-16 13:38:21 +0300425 self.bridge(self.vlan_sub_if.sw_if_index, is_add=0)
Eyal Bari001fd402017-07-16 09:34:53 +0300426 # Disable SPAN on pg0 sub if (mirrored to vxlan)
427 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200428 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, state=0, is_l2=1
429 )
Eyal Bari17142b22017-10-16 13:38:21 +0300430 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
431
432 self.verify_capture(pg1_pkts, pg2_untagged)
433
434 def test_span_l2_rx_dst_1ad_vtr(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200435 """SPAN l2 rx mirror into 1ad subif+vtr"""
Eyal Bari17142b22017-10-16 13:38:21 +0300436
437 self.sub_if.admin_up()
438 self.qinq_sub_if.admin_up()
439
440 self.bridge(self.qinq_sub_if.sw_if_index)
441 # Create bi-directional cross-connects between pg0 and pg1
442 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
443
444 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200445 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari17142b22017-10-16 13:38:21 +0300446 self.pg0.add_stream(pkts)
447
448 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200449 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, is_l2=1
450 )
Eyal Bari17142b22017-10-16 13:38:21 +0300451
452 # Enable packet capturing and start packet sending
453 self.pg_enable_capture(self.pg_interfaces)
454 self.pg_start()
455
456 # Verify packets outgoing packet streams on mirrored interface (pg2)
457 n_pkts = len(pkts)
458 pg1_pkts = self.pg1.get_capture(n_pkts)
459 pg2_pkts = self.pg2.get_capture(n_pkts)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200460 pg2_untagged = [
461 self.remove_tags(p, [Tag(dot1=DOT1AD, vlan=400), Tag(dot1=DOT1Q, vlan=500)])
462 for p in pg2_pkts
463 ]
Eyal Bari17142b22017-10-16 13:38:21 +0300464
465 self.bridge(self.qinq_sub_if.sw_if_index, is_add=0)
466 # Disable SPAN on pg0 sub if (mirrored to vxlan)
467 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200468 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, state=0, is_l2=1
469 )
Eyal Bari001fd402017-07-16 09:34:53 +0300470 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
471
Eyal Baricdeb7f22017-10-15 16:55:11 +0300472 self.verify_capture(pg1_pkts, pg2_untagged)
473
Eyal Bari001fd402017-07-16 09:34:53 +0300474 def test_l2_tx_span(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200475 """SPAN l2 tx mirror"""
Eyal Bari001fd402017-07-16 09:34:53 +0300476
477 self.sub_if.admin_up()
478 self.bridge(self.pg2.sw_if_index)
479 # Create bi-directional cross-connects between pg0 and pg1
480 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
481 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200482 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Bari001fd402017-07-16 09:34:53 +0300483 self.pg0.add_stream(pkts)
484
Eyal Baricdeb7f22017-10-15 16:55:11 +0300485 # Enable SPAN on pg1 (mirrored to pg2)
Eyal Bari001fd402017-07-16 09:34:53 +0300486 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200487 self.pg1.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=2
488 )
Eyal Bari001fd402017-07-16 09:34:53 +0300489
490 self.logger.info(self.vapi.ppcli("show interface span"))
491 # Enable packet capturing and start packet sending
492 self.pg_enable_capture(self.pg_interfaces)
493 self.pg_start()
494
495 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300496 n_pkts = len(pkts)
497 pg1_pkts = self.pg1.get_capture(n_pkts)
498 pg2_pkts = self.pg2.get_capture(n_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300499 self.bridge(self.pg2.sw_if_index, is_add=0)
500 # Disable SPAN on pg0 (mirrored to pg2)
501 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200502 self.pg1.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
503 )
Eyal Bari001fd402017-07-16 09:34:53 +0300504 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
505
Eyal Baricdeb7f22017-10-15 16:55:11 +0300506 self.verify_capture(pg1_pkts, pg2_pkts)
507
508 def test_l2_rx_tx_span(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200509 """SPAN l2 rx tx mirror"""
Eyal Baricdeb7f22017-10-15 16:55:11 +0300510
511 self.sub_if.admin_up()
512 self.bridge(self.pg2.sw_if_index)
513 # Create bi-directional cross-connects between pg0 and pg1
514 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
515
516 # Create incoming packet streams for packet-generator interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200517 pg0_pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes, do_dot1=True)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300518 self.pg0.add_stream(pg0_pkts)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200519 pg1_pkts = self.create_stream(self.pg1, self.pg_if_packet_sizes, do_dot1=False)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300520 self.pg1.add_stream(pg1_pkts)
521
522 # Enable SPAN on pg0 (mirrored to pg2)
523 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200524 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3
525 )
Eyal Baricdeb7f22017-10-15 16:55:11 +0300526 self.logger.info(self.vapi.ppcli("show interface span"))
527
528 # Enable packet capturing and start packet sending
529 self.pg_enable_capture(self.pg_interfaces)
530 self.pg_start()
531
532 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300533 pg0_expected = len(pg1_pkts)
534 pg1_expected = len(pg0_pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300535 pg2_expected = pg0_expected + pg1_expected
536
537 pg0_pkts = self.pg0.get_capture(pg0_expected)
538 pg1_pkts = self.pg1.get_capture(pg1_expected)
539 pg2_pkts = self.pg2.get_capture(pg2_expected)
540
541 self.bridge(self.pg2.sw_if_index, is_add=0)
542 # Disable SPAN on pg0 (mirrored to pg2)
543 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200544 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
545 )
Eyal Baricdeb7f22017-10-15 16:55:11 +0300546 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
547
548 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
549
Eyal Bari17142b22017-10-16 13:38:21 +0300550 def test_l2_bcast_mirror(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200551 """SPAN l2 broadcast mirror"""
Eyal Bari17142b22017-10-16 13:38:21 +0300552
553 self.sub_if.admin_up()
554 self.bridge(self.pg2.sw_if_index)
555
556 # Create bi-directional cross-connects between pg0 and pg1
557 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200558 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=1
559 )
Eyal Bari17142b22017-10-16 13:38:21 +0300560 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200561 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=1
562 )
Eyal Bari17142b22017-10-16 13:38:21 +0300563
564 # Create incoming packet streams for packet-generator interfaces
565 pg0_pkts = self.create_stream(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200566 self.pg0, self.pg_if_packet_sizes, do_dot1=True, bcast=True
567 )
Eyal Bari17142b22017-10-16 13:38:21 +0300568 self.pg0.add_stream(pg0_pkts)
569 pg1_pkts = self.create_stream(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200570 self.pg1, self.pg_if_packet_sizes, do_dot1=False, bcast=True
571 )
Eyal Bari17142b22017-10-16 13:38:21 +0300572 self.pg1.add_stream(pg1_pkts)
573
574 # Enable SPAN on pg0 (mirrored to pg2)
575 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200576 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3
577 )
Eyal Bari17142b22017-10-16 13:38:21 +0300578 self.logger.info(self.vapi.ppcli("show interface span"))
579
580 # Enable packet capturing and start packet sending
581 self.pg_enable_capture(self.pg_interfaces)
582 self.pg_start()
583
584 # Verify packets outgoing packet streams on mirrored interface (pg2)
585 pg0_expected = len(pg1_pkts)
586 pg1_expected = len(pg0_pkts)
587 pg2_expected = pg0_expected + pg1_expected
588
589 pg0_pkts = self.pg0.get_capture(pg0_expected)
590 pg1_pkts = self.pg1.get_capture(pg1_expected)
591 pg2_pkts = self.pg2.get_capture(pg2_expected)
592
593 self.bridge(self.pg2.sw_if_index, is_add=0)
594 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200595 rx_sw_if_index=self.sub_if.sw_if_index, bd_id=99, enable=0
596 )
Eyal Bari17142b22017-10-16 13:38:21 +0300597 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200598 rx_sw_if_index=self.pg1.sw_if_index, bd_id=99, enable=0
599 )
Eyal Bari17142b22017-10-16 13:38:21 +0300600 # Disable SPAN on pg0 (mirrored to pg2)
601 self.vapi.sw_interface_span_enable_disable(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200602 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1
603 )
Eyal Bari17142b22017-10-16 13:38:21 +0300604
605 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
606
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100607
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200608if __name__ == "__main__":
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100609 unittest.main(testRunner=VppTestRunner)