blob: c64d5d4f01c57d70ae368eb1499a572cc26c07d1 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Eyal Baric86e5922017-07-02 18:33:16 +03002""" L2BD ARP term Test """
3
4import unittest
5import random
6import copy
7
snaramre5d4b8912019-12-13 23:39:35 +00008from socket import AF_INET, AF_INET6, inet_pton, inet_ntop
Eyal Bari758137a2017-07-05 14:31:30 +03009
Eyal Baric86e5922017-07-02 18:33:16 +030010from scapy.packet import Raw
11from scapy.layers.l2 import Ether, ARP
12from scapy.layers.inet import IP
Eyal Bari758137a2017-07-05 14:31:30 +030013from scapy.utils6 import in6_getnsma, in6_getnsmac, in6_ptop, in6_islladdr, \
14 in6_mactoifaceid, in6_ismaddr
15from scapy.layers.inet6 import IPv6, UDP, ICMPv6ND_NS, ICMPv6ND_RS, \
16 ICMPv6ND_RA, ICMPv6NDOptSrcLLAddr, getmacbyip6, ICMPv6MRD_Solicitation, \
17 ICMPv6NDOptMTU, ICMPv6NDOptSrcLLAddr, ICMPv6NDOptPrefixInfo, \
18 ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, ICMPv6DestUnreach, icmp6types
Eyal Baric86e5922017-07-02 18:33:16 +030019
20from framework import VppTestCase, VppTestRunner
Ole Troan7f991832018-12-06 17:35:12 +010021from util import Host, ppp
Eyal Baric86e5922017-07-02 18:33:16 +030022
23
24class TestL2bdArpTerm(VppTestCase):
25 """ L2BD arp termination Test Case """
26
27 @classmethod
28 def setUpClass(cls):
29 """
30 Perform standard class setup (defined by class method setUpClass in
31 class VppTestCase) before running the test case, set test case related
32 variables and configure VPP.
33 """
34 super(TestL2bdArpTerm, cls).setUpClass()
35
36 try:
37 # Create pg interfaces
38 n_bd = 1
39 cls.ifs_per_bd = ifs_per_bd = 3
40 n_ifs = n_bd * ifs_per_bd
41 cls.create_pg_interfaces(range(n_ifs))
42
43 # Set up all interfaces
44 for i in cls.pg_interfaces:
45 i.admin_up()
46
47 cls.hosts = set()
48
49 except Exception:
50 super(TestL2bdArpTerm, cls).tearDownClass()
51 raise
52
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070053 @classmethod
54 def tearDownClass(cls):
55 super(TestL2bdArpTerm, cls).tearDownClass()
56
Eyal Baric86e5922017-07-02 18:33:16 +030057 def setUp(self):
58 """
59 Clear trace and packet infos before running each test.
60 """
61 self.reset_packet_infos()
62 super(TestL2bdArpTerm, self).setUp()
63
64 def tearDown(self):
65 """
66 Show various debug prints after each test.
67 """
68 super(TestL2bdArpTerm, self).tearDown()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -070069
70 def show_commands_at_teardown(self):
71 self.logger.info(self.vapi.ppcli("show l2fib verbose"))
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -040072 # many tests delete bridge-domain 1 as the last task. don't output
73 # the details of a non-existent bridge-domain.
74 if self.vapi.l2_fib_table_dump(bd_id=1):
75 self.logger.info(self.vapi.ppcli("show bridge-domain 1 detail"))
Eyal Baric86e5922017-07-02 18:33:16 +030076
Eyal Bari758137a2017-07-05 14:31:30 +030077 def add_del_arp_term_hosts(self, entries, bd_id=1, is_add=1, is_ipv6=0):
Eyal Baric86e5922017-07-02 18:33:16 +030078 for e in entries:
Neale Ranns4d5b9172018-10-24 02:57:49 -070079 ip = e.ip4 if is_ipv6 == 0 else e.ip6
Neale Rannsbc764c82019-06-19 07:07:13 -070080 self.vapi.bd_ip_mac_add_del(is_add=is_add,
81 entry={
82 'bd_id': bd_id,
83 'ip': ip,
84 'mac': e.mac})
Eyal Baric86e5922017-07-02 18:33:16 +030085
86 @classmethod
87 def mac_list(cls, b6_range):
88 return ["00:00:ca:fe:00:%02x" % b6 for b6 in b6_range]
89
90 @classmethod
91 def ip4_host(cls, subnet, host, mac):
92 return Host(mac=mac,
93 ip4="172.17.1%02u.%u" % (subnet, host))
94
95 @classmethod
96 def ip4_hosts(cls, subnet, start, mac_list):
97 return {cls.ip4_host(subnet, start + j, mac_list[j])
98 for j in range(len(mac_list))}
99
100 @classmethod
Eyal Bari758137a2017-07-05 14:31:30 +0300101 def ip6_host(cls, subnet, host, mac):
102 return Host(mac=mac,
103 ip6="fd01:%x::%x" % (subnet, host))
104
105 @classmethod
106 def ip6_hosts(cls, subnet, start, mac_list):
107 return {cls.ip6_host(subnet, start + j, mac_list[j])
108 for j in range(len(mac_list))}
109
110 @classmethod
Eyal Baric86e5922017-07-02 18:33:16 +0300111 def bd_swifs(cls, b):
112 n = cls.ifs_per_bd
113 start = (b - 1) * n
114 return [cls.pg_interfaces[j] for j in range(start, start + n)]
115
116 def bd_add_del(self, bd_id=1, is_add=1):
117 if is_add:
118 self.vapi.bridge_domain_add_del(bd_id=bd_id, is_add=is_add)
119 for swif in self.bd_swifs(bd_id):
120 swif_idx = swif.sw_if_index
Ole Troana5b2eec2019-03-11 19:23:25 +0100121 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=swif_idx,
122 bd_id=bd_id, enable=is_add)
Eyal Baric86e5922017-07-02 18:33:16 +0300123 if not is_add:
124 self.vapi.bridge_domain_add_del(bd_id=bd_id, is_add=is_add)
125
126 @classmethod
Eyal Bari20197482017-09-13 12:29:08 +0300127 def arp_req(cls, src_host, host):
Eyal Baric86e5922017-07-02 18:33:16 +0300128 return (Ether(dst="ff:ff:ff:ff:ff:ff", src=src_host.mac) /
129 ARP(op="who-has",
130 hwsrc=src_host.bin_mac,
131 pdst=host.ip4,
132 psrc=src_host.ip4))
133
134 @classmethod
135 def arp_reqs(cls, src_host, entries):
Eyal Bari20197482017-09-13 12:29:08 +0300136 return [cls.arp_req(src_host, e) for e in entries]
137
138 @classmethod
139 def garp_req(cls, host):
140 return cls.arp_req(host, host)
141
142 @classmethod
143 def garp_reqs(cls, entries):
144 return [cls.garp_req(e) for e in entries]
Eyal Baric86e5922017-07-02 18:33:16 +0300145
Eyal Bari758137a2017-07-05 14:31:30 +0300146 def arp_resp_host(self, src_host, arp_resp):
Eyal Baric86e5922017-07-02 18:33:16 +0300147 ether = arp_resp[Ether]
148 self.assertEqual(ether.dst, src_host.mac)
149
150 arp = arp_resp[ARP]
151 self.assertEqual(arp.hwtype, 1)
152 self.assertEqual(arp.ptype, 0x800)
153 self.assertEqual(arp.hwlen, 6)
154 self.assertEqual(arp.plen, 4)
155 arp_opts = {"who-has": 1, "is-at": 2}
156 self.assertEqual(arp.op, arp_opts["is-at"])
157 self.assertEqual(arp.hwdst, src_host.mac)
158 self.assertEqual(arp.pdst, src_host.ip4)
Eyal Bari758137a2017-07-05 14:31:30 +0300159 return Host(mac=arp.hwsrc, ip4=arp.psrc)
Eyal Baric86e5922017-07-02 18:33:16 +0300160
161 def arp_resp_hosts(self, src_host, pkts):
Eyal Bari758137a2017-07-05 14:31:30 +0300162 return {self.arp_resp_host(src_host, p) for p in pkts}
163
Paul Vinciguerra9db94452018-11-25 10:46:44 -0800164 @staticmethod
165 def inttoip4(ip):
Eyal Bari20197482017-09-13 12:29:08 +0300166 o1 = int(ip / 16777216) % 256
167 o2 = int(ip / 65536) % 256
168 o3 = int(ip / 256) % 256
169 o4 = int(ip) % 256
Paul Vinciguerra9db94452018-11-25 10:46:44 -0800170 return '%s.%s.%s.%s' % (o1, o2, o3, o4)
Eyal Bari20197482017-09-13 12:29:08 +0300171
172 def arp_event_host(self, e):
Neale Ranns37029302018-08-10 05:30:06 -0700173 return Host(str(e.mac), ip4=str(e.ip))
Eyal Bari20197482017-09-13 12:29:08 +0300174
175 def arp_event_hosts(self, evs):
176 return {self.arp_event_host(e) for e in evs}
177
Eyal Baric125ecc2017-09-20 11:29:17 +0300178 def nd_event_host(self, e):
Neale Ranns37029302018-08-10 05:30:06 -0700179 return Host(str(e.mac), ip6=str(e.ip))
Eyal Baric125ecc2017-09-20 11:29:17 +0300180
181 def nd_event_hosts(self, evs):
182 return {self.nd_event_host(e) for e in evs}
183
Eyal Bari758137a2017-07-05 14:31:30 +0300184 @classmethod
185 def ns_req(cls, src_host, host):
186 nsma = in6_getnsma(inet_pton(AF_INET6, "fd10::ffff"))
187 d = inet_ntop(AF_INET6, nsma)
188 return (Ether(dst="ff:ff:ff:ff:ff:ff", src=src_host.mac) /
189 IPv6(dst=d, src=src_host.ip6) /
190 ICMPv6ND_NS(tgt=host.ip6) /
191 ICMPv6NDOptSrcLLAddr(lladdr=src_host.mac))
192
193 @classmethod
Eyal Baric125ecc2017-09-20 11:29:17 +0300194 def ns_reqs_dst(cls, entries, dst_host):
195 return [cls.ns_req(e, dst_host) for e in entries]
196
197 @classmethod
198 def ns_reqs_src(cls, src_host, entries):
Eyal Bari758137a2017-07-05 14:31:30 +0300199 return [cls.ns_req(src_host, e) for e in entries]
200
201 def na_resp_host(self, src_host, rx):
202 self.assertEqual(rx[Ether].dst, src_host.mac)
203 self.assertEqual(in6_ptop(rx[IPv6].dst),
204 in6_ptop(src_host.ip6))
205
206 self.assertTrue(rx.haslayer(ICMPv6ND_NA))
207 self.assertTrue(rx.haslayer(ICMPv6NDOptDstLLAddr))
208
209 na = rx[ICMPv6ND_NA]
210 return Host(mac=na.lladdr, ip6=na.tgt)
211
212 def na_resp_hosts(self, src_host, pkts):
213 return {self.na_resp_host(src_host, p) for p in pkts}
Eyal Baric86e5922017-07-02 18:33:16 +0300214
215 def set_bd_flags(self, bd_id, **args):
216 """
217 Enable/disable defined feature(s) of the bridge domain.
218
219 :param int bd_id: Bridge domain ID.
220 :param list args: List of feature/status pairs. Allowed features: \
221 learn, forward, flood, uu_flood and arp_term. Status False means \
222 disable, status True means enable the feature.
223 :raise: ValueError in case of unknown feature in the input.
224 """
225 for flag in args:
226 if flag == "learn":
227 feature_bitmap = 1 << 0
228 elif flag == "forward":
229 feature_bitmap = 1 << 1
230 elif flag == "flood":
231 feature_bitmap = 1 << 2
232 elif flag == "uu_flood":
233 feature_bitmap = 1 << 3
234 elif flag == "arp_term":
235 feature_bitmap = 1 << 4
236 else:
237 raise ValueError("Unknown feature used: %s" % flag)
238 is_set = 1 if args[flag] else 0
Ole Troana5b2eec2019-03-11 19:23:25 +0100239 self.vapi.bridge_flags(bd_id=bd_id, is_set=is_set,
240 flags=feature_bitmap)
Eyal Baric86e5922017-07-02 18:33:16 +0300241 self.logger.info("Bridge domain ID %d updated" % bd_id)
242
243 def verify_arp(self, src_host, req_hosts, resp_hosts, bd_id=1):
244 reqs = self.arp_reqs(src_host, req_hosts)
245
246 for swif in self.bd_swifs(bd_id):
247 swif.add_stream(reqs)
248
249 self.pg_enable_capture(self.pg_interfaces)
250 self.pg_start()
251
252 for swif in self.bd_swifs(bd_id):
253 resp_pkts = swif.get_capture(len(resp_hosts))
254 resps = self.arp_resp_hosts(src_host, resp_pkts)
255 self.assertEqual(len(resps ^ resp_hosts), 0)
256
Eyal Bari758137a2017-07-05 14:31:30 +0300257 def verify_nd(self, src_host, req_hosts, resp_hosts, bd_id=1):
Eyal Baric125ecc2017-09-20 11:29:17 +0300258 reqs = self.ns_reqs_src(src_host, req_hosts)
Eyal Bari758137a2017-07-05 14:31:30 +0300259
260 for swif in self.bd_swifs(bd_id):
261 swif.add_stream(reqs)
262
263 self.pg_enable_capture(self.pg_interfaces)
264 self.pg_start()
265
266 for swif in self.bd_swifs(bd_id):
267 resp_pkts = swif.get_capture(len(resp_hosts))
268 resps = self.na_resp_hosts(src_host, resp_pkts)
269 self.assertEqual(len(resps ^ resp_hosts), 0)
270
Eyal Baric86e5922017-07-02 18:33:16 +0300271 def test_l2bd_arp_term_01(self):
272 """ L2BD arp term - add 5 hosts, verify arp responses
273 """
274 src_host = self.ip4_host(50, 50, "00:00:11:22:33:44")
275 self.bd_add_del(1, is_add=1)
276 self.set_bd_flags(1, arp_term=True, flood=False,
277 uu_flood=False, learn=False)
278 macs = self.mac_list(range(1, 5))
279 hosts = self.ip4_hosts(4, 1, macs)
280 self.add_del_arp_term_hosts(hosts, is_add=1)
Neale Ranns4d5b9172018-10-24 02:57:49 -0700281
Eyal Baric86e5922017-07-02 18:33:16 +0300282 self.verify_arp(src_host, hosts, hosts)
283 type(self).hosts = hosts
284
285 def test_l2bd_arp_term_02(self):
286 """ L2BD arp term - delete 3 hosts, verify arp responses
287 """
288 src_host = self.ip4_host(50, 50, "00:00:11:22:33:44")
289 macs = self.mac_list(range(1, 3))
290 deleted = self.ip4_hosts(4, 1, macs)
291 self.add_del_arp_term_hosts(deleted, is_add=0)
292 remaining = self.hosts - deleted
293 self.verify_arp(src_host, self.hosts, remaining)
294 type(self).hosts = remaining
295 self.bd_add_del(1, is_add=0)
296
297 def test_l2bd_arp_term_03(self):
298 """ L2BD arp term - recreate BD1, readd 3 hosts, verify arp responses
299 """
300 src_host = self.ip4_host(50, 50, "00:00:11:22:33:44")
301 self.bd_add_del(1, is_add=1)
302 self.set_bd_flags(1, arp_term=True, flood=False,
303 uu_flood=False, learn=False)
304 macs = self.mac_list(range(1, 3))
305 readded = self.ip4_hosts(4, 1, macs)
306 self.add_del_arp_term_hosts(readded, is_add=1)
307 self.verify_arp(src_host, self.hosts | readded, readded)
308 type(self).hosts = readded
309
310 def test_l2bd_arp_term_04(self):
311 """ L2BD arp term - 2 IP4 addrs per host
312 """
313 src_host = self.ip4_host(50, 50, "00:00:11:22:33:44")
314 macs = self.mac_list(range(1, 3))
315 sub5_hosts = self.ip4_hosts(5, 1, macs)
316 self.add_del_arp_term_hosts(sub5_hosts, is_add=1)
317 hosts = self.hosts | sub5_hosts
318 self.verify_arp(src_host, hosts, hosts)
319 type(self).hosts = hosts
320 self.bd_add_del(1, is_add=0)
321
322 def test_l2bd_arp_term_05(self):
323 """ L2BD arp term - create and update 10 IP4-mac pairs
324 """
325 src_host = self.ip4_host(50, 50, "00:00:11:22:33:44")
326 self.bd_add_del(1, is_add=1)
327 self.set_bd_flags(1, arp_term=True, flood=False,
328 uu_flood=False, learn=False)
329 macs1 = self.mac_list(range(10, 20))
330 hosts1 = self.ip4_hosts(5, 1, macs1)
331 self.add_del_arp_term_hosts(hosts1, is_add=1)
332 self.verify_arp(src_host, hosts1, hosts1)
333 macs2 = self.mac_list(range(20, 30))
334 hosts2 = self.ip4_hosts(5, 1, macs2)
335 self.add_del_arp_term_hosts(hosts2, is_add=1)
336 self.verify_arp(src_host, hosts1, hosts2)
337 self.bd_add_del(1, is_add=0)
338
Eyal Bari758137a2017-07-05 14:31:30 +0300339 def test_l2bd_arp_term_06(self):
340 """ L2BD arp/ND term - hosts with both ip4/ip6
341 """
342 src_host4 = self.ip4_host(50, 50, "00:00:11:22:33:44")
343 src_host6 = self.ip6_host(50, 50, "00:00:11:22:33:44")
344 self.bd_add_del(1, is_add=1)
345 # enable flood to make sure requests are not flooded
346 self.set_bd_flags(1, arp_term=True, flood=True,
347 uu_flood=False, learn=False)
348 macs = self.mac_list(range(10, 20))
349 hosts6 = self.ip6_hosts(5, 1, macs)
350 hosts4 = self.ip4_hosts(5, 1, macs)
351 self.add_del_arp_term_hosts(hosts4, is_add=1)
352 self.add_del_arp_term_hosts(hosts6, is_add=1, is_ipv6=1)
353 self.verify_arp(src_host4, hosts4, hosts4)
354 self.verify_nd(src_host6, hosts6, hosts6)
355 self.bd_add_del(1, is_add=0)
356
357 def test_l2bd_arp_term_07(self):
358 """ L2BD ND term - Add and Del hosts, verify ND replies
359 """
360 src_host6 = self.ip6_host(50, 50, "00:00:11:22:33:44")
361 self.bd_add_del(1, is_add=1)
362 self.set_bd_flags(1, arp_term=True, flood=False,
363 uu_flood=False, learn=False)
364 macs = self.mac_list(range(10, 20))
365 hosts6 = self.ip6_hosts(5, 1, macs)
366 self.add_del_arp_term_hosts(hosts6, is_add=1, is_ipv6=1)
367 self.verify_nd(src_host6, hosts6, hosts6)
368 del_macs = self.mac_list(range(10, 15))
369 deleted = self.ip6_hosts(5, 1, del_macs)
370 self.add_del_arp_term_hosts(deleted, is_add=0, is_ipv6=1)
371 self.verify_nd(src_host6, hosts6, hosts6 - deleted)
372 self.bd_add_del(1, is_add=0)
373
374 def test_l2bd_arp_term_08(self):
375 """ L2BD ND term - Add and update IP+mac, verify ND replies
376 """
377 src_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
378 self.bd_add_del(1, is_add=1)
379 self.set_bd_flags(1, arp_term=True, flood=False,
380 uu_flood=False, learn=False)
381 macs1 = self.mac_list(range(10, 20))
382 hosts = self.ip6_hosts(5, 1, macs1)
383 self.add_del_arp_term_hosts(hosts, is_add=1, is_ipv6=1)
384 self.verify_nd(src_host, hosts, hosts)
385 macs2 = self.mac_list(range(20, 30))
386 updated = self.ip6_hosts(5, 1, macs2)
387 self.add_del_arp_term_hosts(updated, is_add=1, is_ipv6=1)
388 self.verify_nd(src_host, hosts, updated)
389 self.bd_add_del(1, is_add=0)
390
Eyal Bari20197482017-09-13 12:29:08 +0300391 def test_l2bd_arp_term_09(self):
392 """ L2BD arp term - send garps, verify arp event reports
393 """
Neale Rannscbe25aa2019-09-30 10:53:31 +0000394 self.vapi.want_l2_arp_term_events(enable=1)
Eyal Bari20197482017-09-13 12:29:08 +0300395 self.bd_add_del(1, is_add=1)
396 self.set_bd_flags(1, arp_term=True, flood=False,
397 uu_flood=False, learn=False)
398 macs = self.mac_list(range(90, 95))
399 hosts = self.ip4_hosts(5, 1, macs)
400
401 garps = self.garp_reqs(hosts)
402 self.bd_swifs(1)[0].add_stream(garps)
403
404 self.pg_enable_capture(self.pg_interfaces)
405 self.pg_start()
Neale Rannscbe25aa2019-09-30 10:53:31 +0000406 evs = [self.vapi.wait_for_event(1, "l2_arp_term_event")
Eyal Bari20197482017-09-13 12:29:08 +0300407 for i in range(len(hosts))]
408 ev_hosts = self.arp_event_hosts(evs)
409 self.assertEqual(len(ev_hosts ^ hosts), 0)
410
411 def test_l2bd_arp_term_10(self):
412 """ L2BD arp term - send duplicate garps, verify suppression
413 """
414 macs = self.mac_list(range(70, 71))
415 hosts = self.ip4_hosts(6, 1, macs)
416
417 """ send the packet 5 times expect one event
418 """
419 garps = self.garp_reqs(hosts) * 5
420 self.bd_swifs(1)[0].add_stream(garps)
421
422 self.pg_enable_capture(self.pg_interfaces)
423 self.pg_start()
Neale Rannscbe25aa2019-09-30 10:53:31 +0000424 evs = [self.vapi.wait_for_event(1, "l2_arp_term_event")
Eyal Bari20197482017-09-13 12:29:08 +0300425 for i in range(len(hosts))]
426 ev_hosts = self.arp_event_hosts(evs)
427 self.assertEqual(len(ev_hosts ^ hosts), 0)
428
429 def test_l2bd_arp_term_11(self):
430 """ L2BD arp term - disable ip4 arp events,send garps, verify no events
431 """
Neale Rannscbe25aa2019-09-30 10:53:31 +0000432 self.vapi.want_l2_arp_term_events(enable=0)
Eyal Bari20197482017-09-13 12:29:08 +0300433 macs = self.mac_list(range(90, 95))
434 hosts = self.ip4_hosts(5, 1, macs)
435
436 garps = self.garp_reqs(hosts)
437 self.bd_swifs(1)[0].add_stream(garps)
438
439 self.pg_enable_capture(self.pg_interfaces)
440 self.pg_start()
441 self.sleep(1)
442 self.assertEqual(len(self.vapi.collect_events()), 0)
443 self.bd_add_del(1, is_add=0)
444
Eyal Baric125ecc2017-09-20 11:29:17 +0300445 def test_l2bd_arp_term_12(self):
446 """ L2BD ND term - send NS packets verify reports
447 """
Neale Rannscbe25aa2019-09-30 10:53:31 +0000448 self.vapi.want_l2_arp_term_events(enable=1)
Eyal Baric125ecc2017-09-20 11:29:17 +0300449 dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
450 self.bd_add_del(1, is_add=1)
451 self.set_bd_flags(1, arp_term=True, flood=False,
452 uu_flood=False, learn=False)
453 macs = self.mac_list(range(10, 15))
454 hosts = self.ip6_hosts(5, 1, macs)
455 reqs = self.ns_reqs_dst(hosts, dst_host)
456 self.bd_swifs(1)[0].add_stream(reqs)
457
458 self.pg_enable_capture(self.pg_interfaces)
459 self.pg_start()
Neale Rannscbe25aa2019-09-30 10:53:31 +0000460 evs = [self.vapi.wait_for_event(2, "l2_arp_term_event")
Eyal Baric125ecc2017-09-20 11:29:17 +0300461 for i in range(len(hosts))]
462 ev_hosts = self.nd_event_hosts(evs)
463 self.assertEqual(len(ev_hosts ^ hosts), 0)
464
465 def test_l2bd_arp_term_13(self):
466 """ L2BD ND term - send duplicate ns, verify suppression
467 """
468 dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
Ole Troandf0191e2019-10-25 17:03:54 +0200469 macs = self.mac_list(range(16, 17))
Eyal Baric125ecc2017-09-20 11:29:17 +0300470 hosts = self.ip6_hosts(5, 1, macs)
471 reqs = self.ns_reqs_dst(hosts, dst_host) * 5
472 self.bd_swifs(1)[0].add_stream(reqs)
473
474 self.pg_enable_capture(self.pg_interfaces)
475 self.pg_start()
Neale Rannscbe25aa2019-09-30 10:53:31 +0000476 evs = [self.vapi.wait_for_event(2, "l2_arp_term_event")
Eyal Baric125ecc2017-09-20 11:29:17 +0300477 for i in range(len(hosts))]
478 ev_hosts = self.nd_event_hosts(evs)
479 self.assertEqual(len(ev_hosts ^ hosts), 0)
480
481 def test_l2bd_arp_term_14(self):
482 """ L2BD ND term - disable ip4 arp events,send ns, verify no events
483 """
Neale Rannscbe25aa2019-09-30 10:53:31 +0000484 self.vapi.want_l2_arp_term_events(enable=0)
Eyal Baric125ecc2017-09-20 11:29:17 +0300485 dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
486 macs = self.mac_list(range(10, 15))
487 hosts = self.ip6_hosts(5, 1, macs)
488 reqs = self.ns_reqs_dst(hosts, dst_host)
489 self.bd_swifs(1)[0].add_stream(reqs)
490
491 self.pg_enable_capture(self.pg_interfaces)
492 self.pg_start()
493 self.sleep(1)
494 self.assertEqual(len(self.vapi.collect_events()), 0)
495 self.bd_add_del(1, is_add=0)
496
Eyal Baric86e5922017-07-02 18:33:16 +0300497
498if __name__ == '__main__':
499 unittest.main(testRunner=VppTestRunner)