blob: df3d9dbfda829b9d0f81eef276a632b56ce4b797 [file] [log] [blame]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +01001#!/usr/bin/env python
2
3import unittest
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +01004
5from scapy.packet import Raw
Eyal Bari001fd402017-07-16 09:34:53 +03006from scapy.layers.l2 import Ether, Dot1Q, GRE
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
Eyal Bari001fd402017-07-16 09:34:53 +030012from vpp_sub_interface import VppDot1QSubint, VppDot1ADSubint
13from vpp_gre_interface import VppGreInterface, VppGre6Interface
14from vpp_papi_provider import L2_VTR_OP
15from collections import namedtuple
16
17Tag = namedtuple('Tag', ['dot1', 'vlan'])
18DOT1AD = 0x88A8
19DOT1Q = 0x8100
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010020
21
22class TestSpan(VppTestCase):
23 """ SPAN Test Case """
24
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010025 @classmethod
26 def setUpClass(cls):
27 super(TestSpan, cls).setUpClass()
Eyal Bari001fd402017-07-16 09:34:53 +030028 # Test variables
Eyal Bari001fd402017-07-16 09:34:53 +030029 cls.pkts_per_burst = 257 # Number of packets per burst
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010030 # create 3 pg interfaces
Eyal Bari001fd402017-07-16 09:34:53 +030031 cls.create_pg_interfaces(range(3))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010032
Eyal Bari001fd402017-07-16 09:34:53 +030033 cls.bd_id = 55
34 cls.sub_if = VppDot1QSubint(cls, cls.pg0, 100)
Eyal Bari17142b22017-10-16 13:38:21 +030035 cls.vlan_sub_if = VppDot1QSubint(cls, cls.pg2, 300)
36 cls.vlan_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=300)
37
38 cls.qinq_sub_if = VppDot1ADSubint(cls, cls.pg2, 33, 400, 500)
39 cls.qinq_sub_if.set_vtr(L2_VTR_OP.L2_POP_2, outer=500, inner=400)
40
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010041 # packet flows mapping pg0 -> pg1, pg2 -> pg3, etc.
Eyal Bari001fd402017-07-16 09:34:53 +030042 cls.flows = dict()
43 cls.flows[cls.pg0] = [cls.pg1]
Eyal Baricdeb7f22017-10-15 16:55:11 +030044 cls.flows[cls.pg1] = [cls.pg0]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010045
46 # packet sizes
Eyal Bari17142b22017-10-16 13:38:21 +030047 cls.pg_if_packet_sizes = [64, 512, 1518] # , 9018]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010048
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010049 # setup all interfaces
Eyal Bari17142b22017-10-16 13:38:21 +030050 for i in cls.pg_interfaces:
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010051 i.admin_up()
52 i.config_ip4()
53 i.resolve_arp()
54
Eyal Bari001fd402017-07-16 09:34:53 +030055 cls.vxlan = cls.vapi.vxlan_add_del_tunnel(
56 src_addr=cls.pg2.local_ip4n,
57 dst_addr=cls.pg2.remote_ip4n,
58 vni=1111,
59 is_add=1)
60
61 def setUp(self):
62 super(TestSpan, self).setUp()
63 self.reset_packet_infos()
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +010064
65 def tearDown(self):
66 super(TestSpan, self).tearDown()
Eyal Bari001fd402017-07-16 09:34:53 +030067 if not self.vpp_dead:
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):
75 self.vapi.sw_interface_set_l2_bridge(
76 sw_if_index, bd_id=self.bd_id, enable=is_add)
77
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
105 def decap_vxlan(self, pkt):
106 """
107 Decapsulate the original payload frame by removing VXLAN 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 return pkt[VXLAN].payload
116
Eyal Bari17142b22017-10-16 13:38:21 +0300117 def create_stream(self, src_if, packet_sizes, do_dot1=False, bcast=False):
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100118 pkts = []
Eyal Baricdeb7f22017-10-15 16:55:11 +0300119 dst_if = self.flows[src_if][0]
Eyal Bari17142b22017-10-16 13:38:21 +0300120 dst_mac = src_if.remote_mac
121 if bcast:
122 dst_mac = "ff:ff:ff:ff:ff:ff"
123
Eyal Bari001fd402017-07-16 09:34:53 +0300124 for i in range(0, self.pkts_per_burst):
Eyal Bari17142b22017-10-16 13:38:21 +0300125 payload = "span test"
Eyal Baricdeb7f22017-10-15 16:55:11 +0300126 size = packet_sizes[(i / 2) % len(packet_sizes)]
Eyal Bari17142b22017-10-16 13:38:21 +0300127 p = (Ether(src=src_if.local_mac, dst=dst_mac) /
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100128 IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4) /
Eyal Baricdeb7f22017-10-15 16:55:11 +0300129 UDP(sport=10000 + src_if.sw_if_index * 1000 + i, dport=1234) /
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100130 Raw(payload))
Eyal Bari001fd402017-07-16 09:34:53 +0300131 if do_dot1:
132 p = self.sub_if.add_dot1_layer(p)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100133 self.extend_packet(p, size)
134 pkts.append(p)
135 return pkts
136
Eyal Baricdeb7f22017-10-15 16:55:11 +0300137 def verify_capture(self, cap1, cap2):
138 self.assertEqual(len(cap1), len(cap2),
139 "Different number of sent and mirrored packets :"
140 "%u != %u" % (len(cap1), len(cap2)))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100141
Eyal Baricdeb7f22017-10-15 16:55:11 +0300142 pkts1 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap1]
143 pkts2 = [(pkt[Ether] / pkt[IP] / pkt[UDP]) for pkt in cap2]
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100144
Eyal Baricdeb7f22017-10-15 16:55:11 +0300145 self.assertEqual(pkts1.sort(), pkts2.sort())
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100146
Eyal Bari001fd402017-07-16 09:34:53 +0300147 def test_device_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300148 """ SPAN device rx mirror """
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100149
Eyal Bari001fd402017-07-16 09:34:53 +0300150 # Create bi-directional cross-connects between pg0 and pg1
151 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100152 # Create incoming packet streams for packet-generator interfaces
153 pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes)
154 self.pg0.add_stream(pkts)
155
Eyal Bari001fd402017-07-16 09:34:53 +0300156 # Enable SPAN on pg0 (mirrored to pg2)
157 self.vapi.sw_interface_span_enable_disable(
158 self.pg0.sw_if_index, self.pg2.sw_if_index)
159
160 self.logger.info(self.vapi.ppcli("show interface span"))
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100161 # Enable packet capturing and start packet sending
162 self.pg_enable_capture(self.pg_interfaces)
163 self.pg_start()
164
165 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300166 n_pkts = len(pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300167 pg1_pkts = self.pg1.get_capture(n_pkts)
168 pg2_pkts = self.pg2.get_capture(n_pkts)
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100169
Eyal Bari001fd402017-07-16 09:34:53 +0300170 # Disable SPAN on pg0 (mirrored to pg2)
171 self.vapi.sw_interface_span_enable_disable(
172 self.pg0.sw_if_index, self.pg2.sw_if_index, state=0)
173 self.xconnect(self.pg0.sw_if_index, self.pg1.sw_if_index, is_add=0)
174
Eyal Baricdeb7f22017-10-15 16:55:11 +0300175 self.verify_capture(pg1_pkts, pg2_pkts)
176
Eyal Bari001fd402017-07-16 09:34:53 +0300177 def test_span_l2_rx(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300178 """ SPAN l2 rx mirror """
Eyal Bari001fd402017-07-16 09:34:53 +0300179
180 self.sub_if.admin_up()
181
182 self.bridge(self.pg2.sw_if_index)
Eyal Bari17142b22017-10-16 13:38:21 +0300183 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300184 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
185 # Create incoming packet streams for packet-generator interfaces
186 pkts = self.create_stream(
187 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
188 self.pg0.add_stream(pkts)
189
190 # Enable SPAN on pg0 (mirrored to pg2)
191 self.vapi.sw_interface_span_enable_disable(
192 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1)
193
194 self.logger.info(self.vapi.ppcli("show interface span"))
195 # 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 Baricdeb7f22017-10-15 16:55:11 +0300200 pg2_expected = len(pkts)
201 pg1_pkts = self.pg1.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300202 pg2_pkts = self.pg2.get_capture(pg2_expected)
Eyal Bari001fd402017-07-16 09:34:53 +0300203 self.bridge(self.pg2.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300204
Eyal Bari001fd402017-07-16 09:34:53 +0300205 # Disable SPAN on pg0 (mirrored to pg2)
206 self.vapi.sw_interface_span_enable_disable(
207 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
208 self.xconnect(self.sub_if.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_dst_vxlan(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300213 """ SPAN l2 rx mirror into vxlan """
Eyal Bari001fd402017-07-16 09:34:53 +0300214
215 self.sub_if.admin_up()
216 self.vapi.sw_interface_set_flags(self.vxlan.sw_if_index,
217 admin_up_down=1)
218
219 self.bridge(self.vxlan.sw_if_index, is_add=1)
Eyal Bari17142b22017-10-16 13:38:21 +0300220 # Create bi-directional cross-connects between pg0 subif and pg1
Eyal Bari001fd402017-07-16 09:34:53 +0300221 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
222 # Create incoming packet streams for packet-generator interfaces
223 pkts = self.create_stream(
224 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
225 self.pg0.add_stream(pkts)
226
227 # Enable SPAN on pg0 sub if (mirrored to vxlan)
228 self.vapi.sw_interface_span_enable_disable(
229 self.sub_if.sw_if_index, self.vxlan.sw_if_index, is_l2=1)
230
231 self.logger.info(self.vapi.ppcli("show interface span"))
232 # Enable packet capturing and start packet sending
233 self.pg_enable_capture(self.pg_interfaces)
234 self.pg_start()
235
236 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300237 n_pkts = len(pkts)
238 pg1_pkts = self.pg1.get_capture(n_pkts)
239 pg2_pkts = [self.decap_vxlan(p) for p in self.pg2.get_capture(n_pkts)]
Eyal Bari001fd402017-07-16 09:34:53 +0300240
241 self.bridge(self.vxlan.sw_if_index, is_add=0)
242 # Disable SPAN on pg0 sub if (mirrored to vxlan)
243 self.vapi.sw_interface_span_enable_disable(
244 self.sub_if.sw_if_index, self.vxlan.sw_if_index, state=0, is_l2=1)
245 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300246 self.verify_capture(pg1_pkts, pg2_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300247
248 def test_span_l2_rx_dst_gre_subif_vtr(self):
249 """ SPAN l2 rx mirror into gre-subif+vtr """
250
251 self.sub_if.admin_up()
252
253 gre_if = VppGreInterface(self, self.pg2.local_ip4,
254 self.pg2.remote_ip4,
255 is_teb=1)
256
257 gre_if.add_vpp_config()
258 gre_if.admin_up()
259
260 gre_sub_if = VppDot1QSubint(self, gre_if, 500)
261 gre_sub_if.set_vtr(L2_VTR_OP.L2_POP_1, tag=500)
262 gre_sub_if.admin_up()
263
264 self.bridge(gre_sub_if.sw_if_index)
265 # Create bi-directional cross-connects between pg0 and pg1
266 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
267
268 # Create incoming packet streams for packet-generator interfaces
269 pkts = self.create_stream(
270 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
271 self.pg0.add_stream(pkts)
272
273 self.vapi.sw_interface_span_enable_disable(
274 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, is_l2=1)
275
276 # Enable packet capturing and start packet sending
277 self.pg_enable_capture(self.pg_interfaces)
278 self.pg_start()
279
280 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300281 n_pkts = len(pkts)
282 pg1_pkts = self.pg1.get_capture(n_pkts)
283 pg2_pkts = self.pg2.get_capture(n_pkts)
284
285 def decap(p): return self.remove_tags(
286 self.decap_gre(p), [Tag(dot1=DOT1Q, vlan=500)])
287 pg2_decaped = [decap(p) for p in pg2_pkts]
288
Eyal Bari001fd402017-07-16 09:34:53 +0300289 self.bridge(gre_sub_if.sw_if_index, is_add=0)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300290
Eyal Bari001fd402017-07-16 09:34:53 +0300291 # Disable SPAN on pg0 sub if
292 self.vapi.sw_interface_span_enable_disable(
Eyal Baricdeb7f22017-10-15 16:55:11 +0300293 self.sub_if.sw_if_index, gre_sub_if.sw_if_index, state=0, is_l2=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300294 gre_if.remove_vpp_config()
295 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
296
Eyal Baricdeb7f22017-10-15 16:55:11 +0300297 self.verify_capture(pg1_pkts, pg2_decaped)
298
Eyal Bari17142b22017-10-16 13:38:21 +0300299 def test_span_l2_rx_dst_1q_vtr(self):
300 """ SPAN l2 rx mirror into 1q subif+vtr """
Eyal Bari001fd402017-07-16 09:34:53 +0300301
302 self.sub_if.admin_up()
Eyal Bari17142b22017-10-16 13:38:21 +0300303 self.vlan_sub_if.admin_up()
Eyal Bari001fd402017-07-16 09:34:53 +0300304
Eyal Bari17142b22017-10-16 13:38:21 +0300305 self.bridge(self.vlan_sub_if.sw_if_index)
Eyal Bari001fd402017-07-16 09:34:53 +0300306 # Create bi-directional cross-connects between pg0 and pg1
307 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
308
309 # Create incoming packet streams for packet-generator interfaces
310 pkts = self.create_stream(
311 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
312 self.pg0.add_stream(pkts)
313
314 self.vapi.sw_interface_span_enable_disable(
Eyal Bari17142b22017-10-16 13:38:21 +0300315 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, is_l2=1)
Eyal Bari001fd402017-07-16 09:34:53 +0300316
317 # Enable packet capturing and start packet sending
318 self.pg_enable_capture(self.pg_interfaces)
319 self.pg_start()
320
321 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300322 n_pkts = len(pkts)
323 pg1_pkts = self.pg1.get_capture(n_pkts)
324 pg2_pkts = self.pg2.get_capture(n_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300325 pg2_untagged = [self.remove_tags(p, [Tag(dot1=DOT1Q, vlan=300)])
326 for p in pg2_pkts]
Eyal Bari001fd402017-07-16 09:34:53 +0300327
Eyal Bari17142b22017-10-16 13:38:21 +0300328 self.bridge(self.vlan_sub_if.sw_if_index, is_add=0)
Eyal Bari001fd402017-07-16 09:34:53 +0300329 # Disable SPAN on pg0 sub if (mirrored to vxlan)
330 self.vapi.sw_interface_span_enable_disable(
Eyal Bari17142b22017-10-16 13:38:21 +0300331 self.sub_if.sw_if_index, self.vlan_sub_if.sw_if_index, state=0,
332 is_l2=1)
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_untagged)
336
337 def test_span_l2_rx_dst_1ad_vtr(self):
338 """ SPAN l2 rx mirror into 1ad subif+vtr """
339
340 self.sub_if.admin_up()
341 self.qinq_sub_if.admin_up()
342
343 self.bridge(self.qinq_sub_if.sw_if_index)
344 # Create bi-directional cross-connects between pg0 and pg1
345 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=1)
346
347 # Create incoming packet streams for packet-generator interfaces
348 pkts = self.create_stream(
349 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
350 self.pg0.add_stream(pkts)
351
352 self.vapi.sw_interface_span_enable_disable(
353 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, is_l2=1)
354
355 # Enable packet capturing and start packet sending
356 self.pg_enable_capture(self.pg_interfaces)
357 self.pg_start()
358
359 # Verify packets outgoing packet streams on mirrored interface (pg2)
360 n_pkts = len(pkts)
361 pg1_pkts = self.pg1.get_capture(n_pkts)
362 pg2_pkts = self.pg2.get_capture(n_pkts)
363 pg2_untagged = [self.remove_tags(p, [Tag(dot1=DOT1AD, vlan=400),
364 Tag(dot1=DOT1Q, vlan=500)])
365 for p in pg2_pkts]
366
367 self.bridge(self.qinq_sub_if.sw_if_index, is_add=0)
368 # Disable SPAN on pg0 sub if (mirrored to vxlan)
369 self.vapi.sw_interface_span_enable_disable(
370 self.sub_if.sw_if_index, self.qinq_sub_if.sw_if_index, state=0,
Eyal Bari001fd402017-07-16 09:34:53 +0300371 is_l2=1)
372 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
373
Eyal Baricdeb7f22017-10-15 16:55:11 +0300374 self.verify_capture(pg1_pkts, pg2_untagged)
375
Eyal Bari001fd402017-07-16 09:34:53 +0300376 def test_l2_tx_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300377 """ SPAN l2 tx mirror """
Eyal Bari001fd402017-07-16 09:34:53 +0300378
379 self.sub_if.admin_up()
380 self.bridge(self.pg2.sw_if_index)
381 # Create bi-directional cross-connects between pg0 and pg1
382 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
383 # Create incoming packet streams for packet-generator interfaces
384 pkts = self.create_stream(
385 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
386 self.pg0.add_stream(pkts)
387
Eyal Baricdeb7f22017-10-15 16:55:11 +0300388 # Enable SPAN on pg1 (mirrored to pg2)
Eyal Bari001fd402017-07-16 09:34:53 +0300389 self.vapi.sw_interface_span_enable_disable(
390 self.pg1.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=2)
391
392 self.logger.info(self.vapi.ppcli("show interface span"))
393 # Enable packet capturing and start packet sending
394 self.pg_enable_capture(self.pg_interfaces)
395 self.pg_start()
396
397 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300398 n_pkts = len(pkts)
399 pg1_pkts = self.pg1.get_capture(n_pkts)
400 pg2_pkts = self.pg2.get_capture(n_pkts)
Eyal Bari001fd402017-07-16 09:34:53 +0300401 self.bridge(self.pg2.sw_if_index, is_add=0)
402 # Disable SPAN on pg0 (mirrored to pg2)
403 self.vapi.sw_interface_span_enable_disable(
404 self.pg1.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
405 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
406
Eyal Baricdeb7f22017-10-15 16:55:11 +0300407 self.verify_capture(pg1_pkts, pg2_pkts)
408
409 def test_l2_rx_tx_span(self):
Eyal Bari17142b22017-10-16 13:38:21 +0300410 """ SPAN l2 rx tx mirror """
Eyal Baricdeb7f22017-10-15 16:55:11 +0300411
412 self.sub_if.admin_up()
413 self.bridge(self.pg2.sw_if_index)
414 # Create bi-directional cross-connects between pg0 and pg1
415 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index)
416
417 # Create incoming packet streams for packet-generator interfaces
418 pg0_pkts = self.create_stream(
419 self.pg0, self.pg_if_packet_sizes, do_dot1=True)
420 self.pg0.add_stream(pg0_pkts)
421 pg1_pkts = self.create_stream(
422 self.pg1, self.pg_if_packet_sizes, do_dot1=False)
423 self.pg1.add_stream(pg1_pkts)
424
425 # Enable SPAN on pg0 (mirrored to pg2)
426 self.vapi.sw_interface_span_enable_disable(
427 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3)
428 self.logger.info(self.vapi.ppcli("show interface span"))
429
430 # Enable packet capturing and start packet sending
431 self.pg_enable_capture(self.pg_interfaces)
432 self.pg_start()
433
434 # Verify packets outgoing packet streams on mirrored interface (pg2)
Eyal Bari17142b22017-10-16 13:38:21 +0300435 pg0_expected = len(pg1_pkts)
436 pg1_expected = len(pg0_pkts)
Eyal Baricdeb7f22017-10-15 16:55:11 +0300437 pg2_expected = pg0_expected + pg1_expected
438
439 pg0_pkts = self.pg0.get_capture(pg0_expected)
440 pg1_pkts = self.pg1.get_capture(pg1_expected)
441 pg2_pkts = self.pg2.get_capture(pg2_expected)
442
443 self.bridge(self.pg2.sw_if_index, is_add=0)
444 # Disable SPAN on pg0 (mirrored to pg2)
445 self.vapi.sw_interface_span_enable_disable(
446 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
447 self.xconnect(self.sub_if.sw_if_index, self.pg1.sw_if_index, is_add=0)
448
449 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
450
Eyal Bari17142b22017-10-16 13:38:21 +0300451 def test_l2_bcast_mirror(self):
452 """ SPAN l2 broadcast mirror """
453
454 self.sub_if.admin_up()
455 self.bridge(self.pg2.sw_if_index)
456
457 # Create bi-directional cross-connects between pg0 and pg1
458 self.vapi.sw_interface_set_l2_bridge(
459 self.sub_if.sw_if_index, bd_id=99, enable=1)
460 self.vapi.sw_interface_set_l2_bridge(
461 self.pg1.sw_if_index, bd_id=99, enable=1)
462
463 # Create incoming packet streams for packet-generator interfaces
464 pg0_pkts = self.create_stream(
465 self.pg0, self.pg_if_packet_sizes, do_dot1=True, bcast=True)
466 self.pg0.add_stream(pg0_pkts)
467 pg1_pkts = self.create_stream(
468 self.pg1, self.pg_if_packet_sizes, do_dot1=False, bcast=True)
469 self.pg1.add_stream(pg1_pkts)
470
471 # Enable SPAN on pg0 (mirrored to pg2)
472 self.vapi.sw_interface_span_enable_disable(
473 self.sub_if.sw_if_index, self.pg2.sw_if_index, is_l2=1, state=3)
474 self.logger.info(self.vapi.ppcli("show interface span"))
475
476 # Enable packet capturing and start packet sending
477 self.pg_enable_capture(self.pg_interfaces)
478 self.pg_start()
479
480 # Verify packets outgoing packet streams on mirrored interface (pg2)
481 pg0_expected = len(pg1_pkts)
482 pg1_expected = len(pg0_pkts)
483 pg2_expected = pg0_expected + pg1_expected
484
485 pg0_pkts = self.pg0.get_capture(pg0_expected)
486 pg1_pkts = self.pg1.get_capture(pg1_expected)
487 pg2_pkts = self.pg2.get_capture(pg2_expected)
488
489 self.bridge(self.pg2.sw_if_index, is_add=0)
490 self.vapi.sw_interface_set_l2_bridge(
491 self.sub_if.sw_if_index, bd_id=99, enable=0)
492 self.vapi.sw_interface_set_l2_bridge(
493 self.pg1.sw_if_index, bd_id=99, enable=0)
494 # Disable SPAN on pg0 (mirrored to pg2)
495 self.vapi.sw_interface_span_enable_disable(
496 self.sub_if.sw_if_index, self.pg2.sw_if_index, state=0, is_l2=1)
497
498 self.verify_capture(pg0_pkts + pg1_pkts, pg2_pkts)
499
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100500
501if __name__ == '__main__':
502 unittest.main(testRunner=VppTestRunner)