blob: 941c94ad80ac32c53cabf1e683545160ffb77458 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Jan4af521d2016-11-15 17:05:00 +01002"""L2 FIB Test Case HLD:
3
4**config 1**
5 - add 4 pg-l2 interfaces
6 - configure them into l2bd
7 - configure 100 MAC entries in L2 fib - 25 MACs per interface
8 - L2 MAC learning and unknown unicast flooding disabled in l2bd
9 - configure 100 MAC entries in L2 fib - 25 MACs per interface
10
11**test 1**
12 - send L2 MAC frames between all 4 pg-l2 interfaces for all of 100 MAC \
13 entries in the FIB
14
15**verify 1**
16 - all packets received correctly
17
18**config 2**
19 - delete 12 MAC entries - 3 MACs per interface
20
21**test 2a**
22 - send L2 MAC frames between all 4 pg-l2 interfaces for non-deleted MAC \
23 entries
24
25**verify 2a**
26 - all packets received correctly
27
28**test 2b**
29 - send L2 MAC frames between all 4 pg-l2 interfaces for all of 12 deleted \
30 MAC entries
31
32**verify 2b**
33 - no packet received on all 4 pg-l2 interfaces
34
35**config 3**
36 - configure new 100 MAC entries in L2 fib - 25 MACs per interface
37
38**test 3**
39 - send L2 MAC frames between all 4 pg-l2 interfaces for all of 188 MAC \
40 entries in the FIB
41
42**verify 3**
43 - all packets received correctly
44
45**config 4**
46 - delete 160 MAC entries, 40 MACs per interface
47
48**test 4a**
49 - send L2 MAC frames between all 4 pg-l2 interfaces for all of 28 \
50 non-deleted MAC entries
51
52**verify 4a**
53 - all packets received correctly
54
55**test 4b**
56 - try send L2 MAC frames between all 4 pg-l2 interfaces for all of 172 \
57 deleted MAC entries
58
59**verify 4b**
60 - no packet received on all 4 pg-l2 interfaces
61"""
62
63import unittest
64import random
65
66from scapy.packet import Raw
67from scapy.layers.l2 import Ether
68from scapy.layers.inet import IP, UDP
69
70from framework import VppTestCase, VppTestRunner
Klement Sekera9225dee2016-12-12 08:36:58 +010071from util import Host, ppp
Jakub Grajciar145e3302019-10-24 13:52:42 +020072from vpp_papi import mac_pton, VppEnum
John Loe23c99e2018-03-13 21:53:18 -040073
Jan4af521d2016-11-15 17:05:00 +010074
75class TestL2fib(VppTestCase):
76 """ L2 FIB Test Case """
77
78 @classmethod
Eyal Bari93b503e2017-05-15 10:13:15 +030079 def bd_ifs(cls, bd_id):
Pavel Kotucek7303ee82018-11-21 13:20:41 +010080 return range((bd_id - 1) * cls.n_ifs_per_bd,
81 bd_id * cls.n_ifs_per_bd - 1)
Eyal Bari93b503e2017-05-15 10:13:15 +030082
83 @classmethod
Jan4af521d2016-11-15 17:05:00 +010084 def setUpClass(cls):
85 """
86 Perform standard class setup (defined by class method setUpClass in
87 class VppTestCase) before running the test case, set test case related
88 variables and configure VPP.
89
90 :var int bd_id: Bridge domain ID.
Jan4af521d2016-11-15 17:05:00 +010091 """
92 super(TestL2fib, cls).setUpClass()
93
Jan4af521d2016-11-15 17:05:00 +010094 try:
Eyal Bari93b503e2017-05-15 10:13:15 +030095 n_brs = cls.n_brs = range(1, 3)
96 cls.n_ifs_per_bd = 4
97 n_ifs = range(cls.n_ifs_per_bd * len(cls.n_brs))
Pavel Kotucek7303ee82018-11-21 13:20:41 +010098 # Create pg interfaces
Eyal Bari93b503e2017-05-15 10:13:15 +030099 cls.create_pg_interfaces(n_ifs)
Jan4af521d2016-11-15 17:05:00 +0100100
Jan4af521d2016-11-15 17:05:00 +0100101 cls.flows = dict()
Eyal Bari93b503e2017-05-15 10:13:15 +0300102 for bd_id in n_brs:
103 # Packet flows mapping pg0 -> pg1, pg2, pg3 etc.
104 ifs = cls.bd_ifs(bd_id)
105 for j in ifs:
106 cls.flows[cls.pg_interfaces[j]] = [
107 cls.pg_interfaces[x] for x in ifs if x != j]
Jan4af521d2016-11-15 17:05:00 +0100108
109 # Packet sizes
110 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
111
Eyal Bari93b503e2017-05-15 10:13:15 +0300112 for bd_id in n_brs:
113 # Create BD with MAC learning and unknown unicast flooding
114 # disabled and put interfaces to this BD
Ole Troana5b2eec2019-03-11 19:23:25 +0100115 cls.vapi.bridge_domain_add_del(bd_id=bd_id, uu_flood=0,
116 learn=0)
Eyal Bari93b503e2017-05-15 10:13:15 +0300117 ifs = [cls.pg_interfaces[i] for i in cls.bd_ifs(bd_id)]
118 for pg_if in ifs:
Ole Troana5b2eec2019-03-11 19:23:25 +0100119 cls.vapi.sw_interface_set_l2_bridge(
120 rx_sw_if_index=pg_if.sw_if_index, bd_id=bd_id)
Jan4af521d2016-11-15 17:05:00 +0100121
122 # Set up all interfaces
123 for i in cls.pg_interfaces:
124 i.admin_up()
Jan4af521d2016-11-15 17:05:00 +0100125 except Exception:
126 super(TestL2fib, cls).tearDownClass()
127 raise
128
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700129 @classmethod
130 def tearDownClass(cls):
131 super(TestL2fib, cls).tearDownClass()
132
Jan4af521d2016-11-15 17:05:00 +0100133 def setUp(self):
Jan4af521d2016-11-15 17:05:00 +0100134 super(TestL2fib, self).setUp()
Klement Sekeradab231a2016-12-21 08:50:14 +0100135 self.reset_packet_infos()
Jan4af521d2016-11-15 17:05:00 +0100136
137 def tearDown(self):
138 """
139 Show various debug prints after each test.
140 """
141 super(TestL2fib, self).tearDown()
142 if not self.vpp_dead:
Eyal Bari93b503e2017-05-15 10:13:15 +0300143 for bd_id in self.n_brs:
144 self.logger.info(self.vapi.ppcli("show bridge-domain %s detail"
145 % bd_id))
Jan4af521d2016-11-15 17:05:00 +0100146
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -0700147 def show_commands_at_teardown(self):
148 self.logger.info(self.vapi.ppcli("show l2fib verbose"))
149
Eyal Bari93b503e2017-05-15 10:13:15 +0300150 def create_hosts(self, n_hosts_per_if, subnet):
Jan4af521d2016-11-15 17:05:00 +0100151 """
152 Create required number of host MAC addresses and distribute them among
153 interfaces. Create host IPv4 address for every host MAC address.
154
Eyal Bari93b503e2017-05-15 10:13:15 +0300155 :param int n_hosts_per_if: Number of per interface hosts to
Dave Wallaced1706812021-08-12 18:36:02 -0400156 create MAC/IPv4 addresses for.
Jan4af521d2016-11-15 17:05:00 +0100157 """
Eyal Bari93b503e2017-05-15 10:13:15 +0300158
Eyal Bari755b1402017-10-08 15:53:34 +0300159 hosts = dict()
Jan4af521d2016-11-15 17:05:00 +0100160 for pg_if in self.pg_interfaces:
Eyal Bari93b503e2017-05-15 10:13:15 +0300161 swif = pg_if.sw_if_index
Jan4af521d2016-11-15 17:05:00 +0100162
Eyal Bari93b503e2017-05-15 10:13:15 +0300163 def mac(j): return "00:00:%02x:ff:%02x:%02x" % (subnet, swif, j)
164
165 def ip(j): return "172.%02u.1%02x.%u" % (subnet, swif, j)
166
167 def h(j): return Host(mac(j), ip(j))
Eyal Bari755b1402017-10-08 15:53:34 +0300168 hosts[swif] = [h(j) for j in range(n_hosts_per_if)]
169 return hosts
Eyal Bari93b503e2017-05-15 10:13:15 +0300170
Eyal Bari755b1402017-10-08 15:53:34 +0300171 def split_hosts(self, hosts, n):
172 splits = dict()
173 for pg_if in self.pg_interfaces:
174 swif = pg_if.sw_if_index
175 splits[swif] = hosts[swif][:n]
176 hosts[swif] = hosts[swif][n:]
177 return splits
178
179 def learn_hosts(self, bd_id, hosts):
Eyal Bari521202b2017-05-24 10:11:20 +0300180 """
Eyal Bari755b1402017-10-08 15:53:34 +0300181 Create and send per interface L2 MAC broadcast packet stream to
Eyal Bari521202b2017-05-24 10:11:20 +0300182 let the bridge domain learn these MAC addresses.
183
184 :param int bd_id: BD to teach
Eyal Bari755b1402017-10-08 15:53:34 +0300185 :param dict hosts: dict of hosts per interface
Eyal Bari521202b2017-05-24 10:11:20 +0300186 """
Ole Troana5b2eec2019-03-11 19:23:25 +0100187 self.vapi.bridge_flags(bd_id=bd_id, is_set=1, flags=1)
Eyal Bari521202b2017-05-24 10:11:20 +0300188 ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)]
189 for pg_if in ifs:
190 swif = pg_if.sw_if_index
Eyal Bari755b1402017-10-08 15:53:34 +0300191 packets = [Ether(dst="ff:ff:ff:ff:ff:ff", src=host.mac)
192 for host in hosts[swif]]
Eyal Bari521202b2017-05-24 10:11:20 +0300193 pg_if.add_stream(packets)
194 self.logger.info("Sending broadcast eth frames for MAC learning")
195 self.pg_start()
196
Eyal Bari755b1402017-10-08 15:53:34 +0300197 def config_l2_fib_entries(self, bd_id, hosts):
Jan4af521d2016-11-15 17:05:00 +0100198 """
Eyal Bari93b503e2017-05-15 10:13:15 +0300199 Config required number of L2 FIB entries.
Jan4af521d2016-11-15 17:05:00 +0100200
Eyal Bari93b503e2017-05-15 10:13:15 +0300201 :param int bd_id: BD's id
Jan4af521d2016-11-15 17:05:00 +0100202 :param int count: Number of L2 FIB entries to be created.
203 :param int start: Starting index of the host list. (Default value = 0)
204 """
Eyal Bari93b503e2017-05-15 10:13:15 +0300205 ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)]
206 for pg_if in ifs:
207 swif = pg_if.sw_if_index
Eyal Bari755b1402017-10-08 15:53:34 +0300208 for host in hosts[swif]:
Klement Sekerada505f62017-01-04 12:58:53 +0100209 self.vapi.l2fib_add_del(
Ole Troan8006c6a2018-12-17 12:02:26 +0100210 mac_pton(host.mac), bd_id, swif, static_mac=1)
Jan4af521d2016-11-15 17:05:00 +0100211
Eyal Bari755b1402017-10-08 15:53:34 +0300212 def delete_l2_fib_entry(self, bd_id, hosts):
Jan4af521d2016-11-15 17:05:00 +0100213 """
214 Delete required number of L2 FIB entries.
215
216 :param int count: Number of L2 FIB entries to be created.
217 """
Eyal Bari93b503e2017-05-15 10:13:15 +0300218 ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)]
219 for pg_if in ifs:
220 swif = pg_if.sw_if_index
Eyal Bari755b1402017-10-08 15:53:34 +0300221 for host in hosts[swif]:
Klement Sekerada505f62017-01-04 12:58:53 +0100222 self.vapi.l2fib_add_del(
Ole Troan8006c6a2018-12-17 12:02:26 +0100223 mac_pton(host.mac), bd_id, swif, is_add=0)
Eyal Bari93b503e2017-05-15 10:13:15 +0300224
Eyal Bari755b1402017-10-08 15:53:34 +0300225 def flush_int(self, swif, learned_hosts):
Eyal Bari93b503e2017-05-15 10:13:15 +0300226 """
227 Flush swif L2 FIB entries.
228
229 :param int swif: sw if index.
230 """
Eyal Bari521202b2017-05-24 10:11:20 +0300231 flushed = dict()
Eyal Bari93b503e2017-05-15 10:13:15 +0300232 self.vapi.l2fib_flush_int(swif)
Eyal Bari755b1402017-10-08 15:53:34 +0300233 flushed[swif] = learned_hosts[swif]
234 learned_hosts[swif] = []
Eyal Bari521202b2017-05-24 10:11:20 +0300235 return flushed
Eyal Bari93b503e2017-05-15 10:13:15 +0300236
Eyal Bari755b1402017-10-08 15:53:34 +0300237 def flush_bd(self, bd_id, learned_hosts):
Eyal Bari93b503e2017-05-15 10:13:15 +0300238 """
239 Flush bd_id L2 FIB entries.
240
241 :param int bd_id: Bridge Domain id.
242 """
243 self.vapi.l2fib_flush_bd(bd_id)
Eyal Bari521202b2017-05-24 10:11:20 +0300244 flushed = dict()
Eyal Bari93b503e2017-05-15 10:13:15 +0300245 ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)]
246 for pg_if in ifs:
247 swif = pg_if.sw_if_index
Eyal Bari755b1402017-10-08 15:53:34 +0300248 flushed[swif] = learned_hosts[swif]
249 learned_hosts[swif] = []
Eyal Bari521202b2017-05-24 10:11:20 +0300250 return flushed
Eyal Bari93b503e2017-05-15 10:13:15 +0300251
252 def flush_all(self):
253 """
254 Flush All L2 FIB entries.
255 """
256 self.vapi.l2fib_flush_all()
Jan4af521d2016-11-15 17:05:00 +0100257
Eyal Bari755b1402017-10-08 15:53:34 +0300258 def create_stream(self, src_if, packet_sizes, if_src_hosts, if_dst_hosts):
Jan4af521d2016-11-15 17:05:00 +0100259 """
260 Create input packet stream for defined interface using hosts or
261 deleted_hosts list.
262
263 :param object src_if: Interface to create packet stream for.
264 :param list packet_sizes: List of required packet sizes.
265 :param boolean deleted: Set to True if deleted_hosts list required.
266 :return: Stream of packets.
267 """
Eyal Bari521202b2017-05-24 10:11:20 +0300268 src_hosts = if_src_hosts[src_if.sw_if_index]
Eyal Bari93b503e2017-05-15 10:13:15 +0300269 if not src_hosts:
270 return []
Jan4af521d2016-11-15 17:05:00 +0100271 pkts = []
Jan4af521d2016-11-15 17:05:00 +0100272 for dst_if in self.flows[src_if]:
Eyal Bari521202b2017-05-24 10:11:20 +0300273 dst_swif = dst_if.sw_if_index
274 if dst_swif not in if_dst_hosts:
275 continue
276 dst_hosts = if_dst_hosts[dst_swif]
Eyal Bari755b1402017-10-08 15:53:34 +0300277 for dst_host in dst_hosts:
Jan4af521d2016-11-15 17:05:00 +0100278 src_host = random.choice(src_hosts)
Klement Sekeradab231a2016-12-21 08:50:14 +0100279 pkt_info = self.create_packet_info(src_if, dst_if)
Jan4af521d2016-11-15 17:05:00 +0100280 payload = self.info_to_payload(pkt_info)
281 p = (Ether(dst=dst_host.mac, src=src_host.mac) /
282 IP(src=src_host.ip4, dst=dst_host.ip4) /
283 UDP(sport=1234, dport=1234) /
284 Raw(payload))
285 pkt_info.data = p.copy()
286 size = random.choice(packet_sizes)
287 self.extend_packet(p, size)
288 pkts.append(p)
289 return pkts
290
291 def verify_capture(self, pg_if, capture):
292 """
293 Verify captured input packet stream for defined interface.
294
295 :param object pg_if: Interface to verify captured packet stream for.
296 :param list capture: Captured packet stream.
297 """
298 last_info = dict()
299 for i in self.pg_interfaces:
300 last_info[i.sw_if_index] = None
301 dst_sw_if_index = pg_if.sw_if_index
302 for packet in capture:
Paul Vinciguerraeaea4212019-03-06 11:58:06 -0800303 payload_info = self.payload_to_info(packet[Raw])
Jan4af521d2016-11-15 17:05:00 +0100304 try:
305 ip = packet[IP]
306 udp = packet[UDP]
307 packet_index = payload_info.index
308 self.assertEqual(payload_info.dst, dst_sw_if_index)
309 self.logger.debug("Got packet on port %s: src=%u (id=%u)" %
310 (pg_if.name, payload_info.src, packet_index))
311 next_info = self.get_next_packet_info_for_interface2(
312 payload_info.src, dst_sw_if_index,
313 last_info[payload_info.src])
314 last_info[payload_info.src] = next_info
315 self.assertTrue(next_info is not None)
316 self.assertEqual(packet_index, next_info.index)
317 saved_packet = next_info.data
318 # Check standard fields
319 self.assertEqual(ip.src, saved_packet[IP].src)
320 self.assertEqual(ip.dst, saved_packet[IP].dst)
321 self.assertEqual(udp.sport, saved_packet[UDP].sport)
322 self.assertEqual(udp.dport, saved_packet[UDP].dport)
Jakub Grajciar145e3302019-10-24 13:52:42 +0200323 except BaseException:
Klement Sekera9225dee2016-12-12 08:36:58 +0100324 self.logger.error(ppp("Unexpected or invalid packet:", packet))
Jan4af521d2016-11-15 17:05:00 +0100325 raise
326 for i in self.pg_interfaces:
327 remaining_packet = self.get_next_packet_info_for_interface2(
328 i, dst_sw_if_index, last_info[i.sw_if_index])
329 self.assertTrue(
330 remaining_packet is None,
331 "Port %u: Packet expected from source %u didn't arrive" %
332 (dst_sw_if_index, i.sw_if_index))
333
Eyal Bari755b1402017-10-08 15:53:34 +0300334 def run_verify_test(self, bd_id, src_hosts, dst_hosts):
Jan4af521d2016-11-15 17:05:00 +0100335 # Test
336 # Create incoming packet streams for packet-generator interfaces
Eyal Bari93b503e2017-05-15 10:13:15 +0300337 self.reset_packet_infos()
338 ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)]
339 for i in ifs:
Eyal Bari521202b2017-05-24 10:11:20 +0300340 pkts = self.create_stream(
Eyal Bari755b1402017-10-08 15:53:34 +0300341 i, self.pg_if_packet_sizes,
342 if_src_hosts=src_hosts,
343 if_dst_hosts=dst_hosts)
344 if pkts:
345 i.add_stream(pkts)
Jan4af521d2016-11-15 17:05:00 +0100346
Ole Troana5b2eec2019-03-11 19:23:25 +0100347 self.vapi.bridge_flags(bd_id=bd_id, is_set=0, flags=1)
Jan4af521d2016-11-15 17:05:00 +0100348 # Enable packet capture and start packet sending
Eyal Bari93b503e2017-05-15 10:13:15 +0300349 self.pg_enable_capture(ifs)
Jan4af521d2016-11-15 17:05:00 +0100350 self.pg_start()
351
352 # Verify
353 # Verify outgoing packet streams per packet-generator interface
Eyal Bari93b503e2017-05-15 10:13:15 +0300354 for i in ifs:
Eyal Bari521202b2017-05-24 10:11:20 +0300355 if not dst_hosts[i.sw_if_index]:
356 continue
Jan4af521d2016-11-15 17:05:00 +0100357 capture = i.get_capture()
358 self.logger.info("Verifying capture on interface %s" % i.name)
359 self.verify_capture(i, capture)
360
Eyal Bari755b1402017-10-08 15:53:34 +0300361 def run_verify_negat_test(self, bd_id, src_hosts, dst_hosts):
Jan4af521d2016-11-15 17:05:00 +0100362 # Test
363 # Create incoming packet streams for packet-generator interfaces for
364 # deleted MAC addresses
Klement Sekeradab231a2016-12-21 08:50:14 +0100365 self.reset_packet_infos()
Eyal Bari93b503e2017-05-15 10:13:15 +0300366 ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)]
367 for i in ifs:
Eyal Bari521202b2017-05-24 10:11:20 +0300368 pkts = self.create_stream(
Eyal Bari755b1402017-10-08 15:53:34 +0300369 i, self.pg_if_packet_sizes,
370 if_src_hosts=src_hosts,
371 if_dst_hosts=dst_hosts)
Eyal Bari93b503e2017-05-15 10:13:15 +0300372 if pkts:
373 i.add_stream(pkts)
Jan4af521d2016-11-15 17:05:00 +0100374
Ole Troana5b2eec2019-03-11 19:23:25 +0100375 self.vapi.bridge_flags(bd_id=bd_id, is_set=0, flags=1)
Jan4af521d2016-11-15 17:05:00 +0100376 # Enable packet capture and start packet sending
Eyal Bari93b503e2017-05-15 10:13:15 +0300377 self.pg_enable_capture(ifs)
Jan4af521d2016-11-15 17:05:00 +0100378 self.pg_start()
379
380 # Verify
381 # Verify outgoing packet streams per packet-generator interface
Neale Ranns4b8d3be2017-05-22 02:46:01 -0700382 timeout = 1
Eyal Bari93b503e2017-05-15 10:13:15 +0300383 for i in ifs:
Neale Ranns4b8d3be2017-05-22 02:46:01 -0700384 i.get_capture(0, timeout=timeout)
Klement Sekera9225dee2016-12-12 08:36:58 +0100385 i.assert_nothing_captured(remark="outgoing interface")
Neale Ranns4b8d3be2017-05-22 02:46:01 -0700386 timeout = 0.1
Jan4af521d2016-11-15 17:05:00 +0100387
Eyal Bari755b1402017-10-08 15:53:34 +0300388 def test_l2_fib_program100(self):
389 """ L2 FIB - program 100 MACs
Jan4af521d2016-11-15 17:05:00 +0100390 """
Eyal Bari755b1402017-10-08 15:53:34 +0300391 bd_id = 1
392 hosts = self.create_hosts(100, subnet=17)
393 self.config_l2_fib_entries(bd_id, hosts)
394 self.run_verify_test(bd_id, hosts, hosts)
Jan4af521d2016-11-15 17:05:00 +0100395
Pavel Kotucek7303ee82018-11-21 13:20:41 +0100396 def test_l2_fib_program100_delete12(self):
397 """ L2 FIB - program 100, delete 12 MACs
Jan4af521d2016-11-15 17:05:00 +0100398 """
Eyal Bari755b1402017-10-08 15:53:34 +0300399 bd_id = 1
400 hosts = self.create_hosts(100, subnet=17)
401 self.config_l2_fib_entries(bd_id, hosts)
402 del_hosts = self.split_hosts(hosts, 12)
403 self.delete_l2_fib_entry(bd_id, del_hosts)
Jan4af521d2016-11-15 17:05:00 +0100404
Eyal Bari755b1402017-10-08 15:53:34 +0300405 self.run_verify_test(bd_id, hosts, hosts)
406 self.run_verify_negat_test(bd_id, hosts, del_hosts)
Jan4af521d2016-11-15 17:05:00 +0100407
Pavel Kotucek7303ee82018-11-21 13:20:41 +0100408 def test_l2_fib_program100_add100(self):
409 """ L2 FIB - program 100, add 100 MACs
Jan4af521d2016-11-15 17:05:00 +0100410 """
Eyal Bari755b1402017-10-08 15:53:34 +0300411 bd_id = 1
412 hosts = self.create_hosts(100, subnet=17)
413 self.config_l2_fib_entries(bd_id, hosts)
414 hosts2 = self.create_hosts(100, subnet=22)
415 self.config_l2_fib_entries(bd_id, hosts2)
416 self.run_verify_test(bd_id, hosts, hosts2)
Jan4af521d2016-11-15 17:05:00 +0100417
Eyal Bari755b1402017-10-08 15:53:34 +0300418 def test_l2_fib_program10_learn10(self):
Pavel Kotucek7303ee82018-11-21 13:20:41 +0100419 """ L2 FIB - program 10 MACs, learn 10
Jan4af521d2016-11-15 17:05:00 +0100420 """
Eyal Bari755b1402017-10-08 15:53:34 +0300421 hosts = self.create_hosts(20, subnet=35)
422 lhosts = self.split_hosts(hosts, 10)
Jan4af521d2016-11-15 17:05:00 +0100423
Eyal Bari755b1402017-10-08 15:53:34 +0300424 bd1 = 1
425 bd2 = 2
426 self.learn_hosts(bd1, lhosts)
427 self.learn_hosts(bd2, lhosts)
428 self.config_l2_fib_entries(bd1, hosts)
429 self.config_l2_fib_entries(bd2, hosts)
430 self.run_verify_test(bd1, lhosts, hosts)
431 self.run_verify_test(bd2, lhosts, hosts)
Eyal Bari93b503e2017-05-15 10:13:15 +0300432
Eyal Bari755b1402017-10-08 15:53:34 +0300433 def test_l2_fib_flush_int(self):
434 """ L2 FIB - flush interface
Eyal Bari93b503e2017-05-15 10:13:15 +0300435 """
Eyal Bari755b1402017-10-08 15:53:34 +0300436 hosts = self.create_hosts(20, subnet=36)
437 lhosts = self.split_hosts(hosts, 10)
Eyal Bari93b503e2017-05-15 10:13:15 +0300438
Eyal Bari755b1402017-10-08 15:53:34 +0300439 bd1 = 1
440 self.learn_hosts(bd1, lhosts)
441 self.config_l2_fib_entries(bd1, hosts)
442 self.run_verify_test(bd1, lhosts, hosts)
443 flushed = self.flush_int(self.pg_interfaces[0].sw_if_index, lhosts)
444 self.run_verify_test(bd1, hosts, lhosts)
445 self.run_verify_negat_test(bd1, hosts, flushed)
Eyal Bari521202b2017-05-24 10:11:20 +0300446
Eyal Bari755b1402017-10-08 15:53:34 +0300447 def test_l2_fib_flush_bd(self):
448 """ L2 FIB - flush BD
Eyal Bari521202b2017-05-24 10:11:20 +0300449 """
Eyal Bari755b1402017-10-08 15:53:34 +0300450 hosts = self.create_hosts(20, subnet=37)
451 lhosts = self.split_hosts(hosts, 10)
Eyal Bari521202b2017-05-24 10:11:20 +0300452
Eyal Bari755b1402017-10-08 15:53:34 +0300453 bd1 = 1
454 self.learn_hosts(bd1, lhosts)
455 self.config_l2_fib_entries(bd1, hosts)
456 self.run_verify_test(bd1, lhosts, hosts)
457 flushed = self.flush_bd(bd1, lhosts)
458 self.run_verify_negat_test(bd1, hosts, flushed)
Eyal Bari521202b2017-05-24 10:11:20 +0300459
Eyal Bari755b1402017-10-08 15:53:34 +0300460 def test_l2_fib_flush_all(self):
461 """ L2 FIB - flush all
Eyal Bari521202b2017-05-24 10:11:20 +0300462 """
Eyal Bari755b1402017-10-08 15:53:34 +0300463 hosts = self.create_hosts(20, subnet=38)
464 lhosts = self.split_hosts(hosts, 10)
Eyal Bari521202b2017-05-24 10:11:20 +0300465
Eyal Bari755b1402017-10-08 15:53:34 +0300466 bd1 = 1
467 bd2 = 2
468 self.learn_hosts(bd1, lhosts)
469 self.learn_hosts(bd2, lhosts)
470 self.config_l2_fib_entries(bd1, hosts)
471 self.config_l2_fib_entries(bd2, hosts)
472 self.run_verify_test(bd1, hosts, lhosts)
473 self.run_verify_test(bd2, hosts, lhosts)
Eyal Bari521202b2017-05-24 10:11:20 +0300474
Eyal Bari755b1402017-10-08 15:53:34 +0300475 self.flush_all()
476
477 self.run_verify_negat_test(bd1, hosts, lhosts)
478 self.run_verify_negat_test(bd2, hosts, lhosts)
479
480 def test_l2_fib_mac_learn_evs(self):
481 """ L2 FIB - mac learning events
Eyal Bari521202b2017-05-24 10:11:20 +0300482 """
Eyal Bari755b1402017-10-08 15:53:34 +0300483 bd1 = 1
484 hosts = self.create_hosts(10, subnet=39)
Eyal Bari24db0ec2017-09-27 21:43:51 +0300485
Ole Troane1ade682019-03-04 23:55:43 +0100486 self.vapi.want_l2_macs_events()
Eyal Bari755b1402017-10-08 15:53:34 +0300487 self.learn_hosts(bd1, hosts)
Eyal Bari24db0ec2017-09-27 21:43:51 +0300488
489 self.sleep(1)
490 self.logger.info(self.vapi.ppcli("show l2fib"))
491 evs = self.vapi.collect_events()
Jakub Grajciar145e3302019-10-24 13:52:42 +0200492 action = VppEnum.vl_api_mac_event_action_t.MAC_EVENT_ACTION_API_ADD
Eyal Bari24db0ec2017-09-27 21:43:51 +0300493 learned_macs = {
Jakub Grajciar145e3302019-10-24 13:52:42 +0200494 e.mac[i].mac_addr.packed for e in evs for i in range(e.n_macs)
495 if e.mac[i].action == action}
Eyal Bari755b1402017-10-08 15:53:34 +0300496 macs = {h.bin_mac for swif in self.bd_ifs(bd1)
497 for h in hosts[self.pg_interfaces[swif].sw_if_index]}
Ole Troane1ade682019-03-04 23:55:43 +0100498 self.vapi.want_l2_macs_events(enable_disable=0)
Eyal Bari24db0ec2017-09-27 21:43:51 +0300499 self.assertEqual(len(learned_macs ^ macs), 0)
500
Jerome Tollet0f8d1002021-01-07 12:44:17 +0100501 def test_l2_fib_mac_learn_evs2(self):
502 """ L2 FIB - mac learning events using want_l2_macs_events2
503 """
504 bd1 = 1
505 hosts = self.create_hosts(10, subnet=39)
506
507 self.vapi.l2fib_set_scan_delay(scan_delay=10)
508 self.vapi.want_l2_macs_events2()
509 self.sleep(1)
510 self.learn_hosts(bd1, hosts)
511
512 self.sleep(1)
513 self.logger.info(self.vapi.ppcli("show l2fib"))
514 evs = self.vapi.collect_events()
515 action = VppEnum.vl_api_mac_event_action_t.MAC_EVENT_ACTION_API_ADD
516 learned_macs = {
517 e.mac[i].mac_addr.packed for e in evs for i in range(e.n_macs)
518 if e.mac[i].action == action}
519 macs = {h.bin_mac for swif in self.bd_ifs(bd1)
520 for h in hosts[self.pg_interfaces[swif].sw_if_index]}
521 self.vapi.want_l2_macs_events2(enable_disable=0)
522 self.assertEqual(len(learned_macs ^ macs), 0)
523
Eyal Bari755b1402017-10-08 15:53:34 +0300524 def test_l2_fib_macs_learn_max(self):
525 """ L2 FIB - mac learning max macs in event
eyal baric6038c92017-10-03 12:25:07 +0300526 """
Eyal Bari755b1402017-10-08 15:53:34 +0300527 bd1 = 1
528 hosts = self.create_hosts(10, subnet=40)
eyal baric6038c92017-10-03 12:25:07 +0300529
530 ev_macs = 1
Ole Troane1ade682019-03-04 23:55:43 +0100531 self.vapi.want_l2_macs_events(max_macs_in_event=ev_macs)
Eyal Bari755b1402017-10-08 15:53:34 +0300532 self.learn_hosts(bd1, hosts)
eyal baric6038c92017-10-03 12:25:07 +0300533
534 self.sleep(1)
535 self.logger.info(self.vapi.ppcli("show l2fib"))
536 evs = self.vapi.collect_events()
Ole Troane1ade682019-03-04 23:55:43 +0100537 self.vapi.want_l2_macs_events(enable_disable=0)
Eyal Bari755b1402017-10-08 15:53:34 +0300538
539 self.assertGreater(len(evs), 0)
Jakub Grajciar145e3302019-10-24 13:52:42 +0200540 action = VppEnum.vl_api_mac_event_action_t.MAC_EVENT_ACTION_API_ADD
Eyal Bari755b1402017-10-08 15:53:34 +0300541 learned_macs = {
Jakub Grajciar145e3302019-10-24 13:52:42 +0200542 e.mac[i].mac_addr.packed for e in evs for i in range(e.n_macs)
543 if e.mac[i].action == action}
Eyal Bari755b1402017-10-08 15:53:34 +0300544 macs = {h.bin_mac for swif in self.bd_ifs(bd1)
545 for h in hosts[self.pg_interfaces[swif].sw_if_index]}
546
eyal baric6038c92017-10-03 12:25:07 +0300547 for e in evs:
548 self.assertLess(len(e), ev_macs * 10)
549 self.assertEqual(len(learned_macs ^ macs), 0)
550
Jerome Tollet0f8d1002021-01-07 12:44:17 +0100551 def test_l2_fib_macs_learn_max2(self):
552 """ L2 FIB - mac learning max macs in event using want_l2_macs_events2
553 """
554 bd1 = 1
555 hosts = self.create_hosts(10, subnet=40)
556
557 ev_macs = 1
558 self.vapi.l2fib_set_scan_delay(scan_delay=10)
559 self.vapi.want_l2_macs_events2(max_macs_in_event=ev_macs)
560 self.sleep(1)
561 self.learn_hosts(bd1, hosts)
562
563 self.sleep(1)
564 self.logger.info(self.vapi.ppcli("show l2fib"))
565 evs = self.vapi.collect_events()
566 self.vapi.want_l2_macs_events2(enable_disable=0)
567
568 self.assertGreater(len(evs), 0)
569 action = VppEnum.vl_api_mac_event_action_t.MAC_EVENT_ACTION_API_ADD
570 learned_macs = {
571 e.mac[i].mac_addr.packed for e in evs for i in range(e.n_macs)
572 if e.mac[i].action == action}
573 macs = {h.bin_mac for swif in self.bd_ifs(bd1)
574 for h in hosts[self.pg_interfaces[swif].sw_if_index]}
575
576 for e in evs:
577 self.assertLess(len(e), ev_macs * 10)
578 self.assertEqual(len(learned_macs ^ macs), 0)
579
Jan4af521d2016-11-15 17:05:00 +0100580
581if __name__ == '__main__':
582 unittest.main(testRunner=VppTestRunner)