blob: a3feb99a9c7333302945caae78aa343c3c72138c [file] [log] [blame]
Eyal Baric86e5922017-07-02 18:33:16 +03001#!/usr/bin/env python
2""" L2BD ARP term Test """
3
4import unittest
5import random
6import copy
7
Eyal Bari20197482017-09-13 12:29:08 +03008from socket import AF_INET, AF_INET6
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.utils import inet_pton, inet_ntop
14from scapy.utils6 import in6_getnsma, in6_getnsmac, in6_ptop, in6_islladdr, \
15 in6_mactoifaceid, in6_ismaddr
16from scapy.layers.inet6 import IPv6, UDP, ICMPv6ND_NS, ICMPv6ND_RS, \
17 ICMPv6ND_RA, ICMPv6NDOptSrcLLAddr, getmacbyip6, ICMPv6MRD_Solicitation, \
18 ICMPv6NDOptMTU, ICMPv6NDOptSrcLLAddr, ICMPv6NDOptPrefixInfo, \
19 ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, ICMPv6DestUnreach, icmp6types
Eyal Baric86e5922017-07-02 18:33:16 +030020
21from framework import VppTestCase, VppTestRunner
Ole Troan7f991832018-12-06 17:35:12 +010022from util import Host, ppp
Eyal Baric86e5922017-07-02 18:33:16 +030023
24
25class TestL2bdArpTerm(VppTestCase):
26 """ L2BD arp termination Test Case """
27
28 @classmethod
29 def setUpClass(cls):
30 """
31 Perform standard class setup (defined by class method setUpClass in
32 class VppTestCase) before running the test case, set test case related
33 variables and configure VPP.
34 """
35 super(TestL2bdArpTerm, cls).setUpClass()
36
37 try:
38 # Create pg interfaces
39 n_bd = 1
40 cls.ifs_per_bd = ifs_per_bd = 3
41 n_ifs = n_bd * ifs_per_bd
42 cls.create_pg_interfaces(range(n_ifs))
43
44 # Set up all interfaces
45 for i in cls.pg_interfaces:
46 i.admin_up()
47
48 cls.hosts = set()
49
50 except Exception:
51 super(TestL2bdArpTerm, cls).tearDownClass()
52 raise
53
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070054 @classmethod
55 def tearDownClass(cls):
56 super(TestL2bdArpTerm, cls).tearDownClass()
57
Eyal Baric86e5922017-07-02 18:33:16 +030058 def setUp(self):
59 """
60 Clear trace and packet infos before running each test.
61 """
62 self.reset_packet_infos()
63 super(TestL2bdArpTerm, self).setUp()
64
65 def tearDown(self):
66 """
67 Show various debug prints after each test.
68 """
69 super(TestL2bdArpTerm, self).tearDown()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -070070
71 def show_commands_at_teardown(self):
72 self.logger.info(self.vapi.ppcli("show l2fib verbose"))
73 self.logger.info(self.vapi.ppcli("show bridge-domain 1 detail"))
Eyal Baric86e5922017-07-02 18:33:16 +030074
Eyal Bari758137a2017-07-05 14:31:30 +030075 def add_del_arp_term_hosts(self, entries, bd_id=1, is_add=1, is_ipv6=0):
Eyal Baric86e5922017-07-02 18:33:16 +030076 for e in entries:
Neale Ranns4d5b9172018-10-24 02:57:49 -070077 ip = e.ip4 if is_ipv6 == 0 else e.ip6
Ole Troan9a475372019-03-05 16:58:24 +010078 self.vapi.bd_ip_mac_add_del(bd_id=bd_id, is_add=is_add, ip=ip,
79 mac=e.mac)
Eyal Baric86e5922017-07-02 18:33:16 +030080
81 @classmethod
82 def mac_list(cls, b6_range):
83 return ["00:00:ca:fe:00:%02x" % b6 for b6 in b6_range]
84
85 @classmethod
86 def ip4_host(cls, subnet, host, mac):
87 return Host(mac=mac,
88 ip4="172.17.1%02u.%u" % (subnet, host))
89
90 @classmethod
91 def ip4_hosts(cls, subnet, start, mac_list):
92 return {cls.ip4_host(subnet, start + j, mac_list[j])
93 for j in range(len(mac_list))}
94
95 @classmethod
Eyal Bari758137a2017-07-05 14:31:30 +030096 def ip6_host(cls, subnet, host, mac):
97 return Host(mac=mac,
98 ip6="fd01:%x::%x" % (subnet, host))
99
100 @classmethod
101 def ip6_hosts(cls, subnet, start, mac_list):
102 return {cls.ip6_host(subnet, start + j, mac_list[j])
103 for j in range(len(mac_list))}
104
105 @classmethod
Eyal Baric86e5922017-07-02 18:33:16 +0300106 def bd_swifs(cls, b):
107 n = cls.ifs_per_bd
108 start = (b - 1) * n
109 return [cls.pg_interfaces[j] for j in range(start, start + n)]
110
111 def bd_add_del(self, bd_id=1, is_add=1):
112 if is_add:
113 self.vapi.bridge_domain_add_del(bd_id=bd_id, is_add=is_add)
114 for swif in self.bd_swifs(bd_id):
115 swif_idx = swif.sw_if_index
Ole Troana5b2eec2019-03-11 19:23:25 +0100116 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=swif_idx,
117 bd_id=bd_id, enable=is_add)
Eyal Baric86e5922017-07-02 18:33:16 +0300118 if not is_add:
119 self.vapi.bridge_domain_add_del(bd_id=bd_id, is_add=is_add)
120
121 @classmethod
Eyal Bari20197482017-09-13 12:29:08 +0300122 def arp_req(cls, src_host, host):
Eyal Baric86e5922017-07-02 18:33:16 +0300123 return (Ether(dst="ff:ff:ff:ff:ff:ff", src=src_host.mac) /
124 ARP(op="who-has",
125 hwsrc=src_host.bin_mac,
126 pdst=host.ip4,
127 psrc=src_host.ip4))
128
129 @classmethod
130 def arp_reqs(cls, src_host, entries):
Eyal Bari20197482017-09-13 12:29:08 +0300131 return [cls.arp_req(src_host, e) for e in entries]
132
133 @classmethod
134 def garp_req(cls, host):
135 return cls.arp_req(host, host)
136
137 @classmethod
138 def garp_reqs(cls, entries):
139 return [cls.garp_req(e) for e in entries]
Eyal Baric86e5922017-07-02 18:33:16 +0300140
Eyal Bari758137a2017-07-05 14:31:30 +0300141 def arp_resp_host(self, src_host, arp_resp):
Eyal Baric86e5922017-07-02 18:33:16 +0300142 ether = arp_resp[Ether]
143 self.assertEqual(ether.dst, src_host.mac)
144
145 arp = arp_resp[ARP]
146 self.assertEqual(arp.hwtype, 1)
147 self.assertEqual(arp.ptype, 0x800)
148 self.assertEqual(arp.hwlen, 6)
149 self.assertEqual(arp.plen, 4)
150 arp_opts = {"who-has": 1, "is-at": 2}
151 self.assertEqual(arp.op, arp_opts["is-at"])
152 self.assertEqual(arp.hwdst, src_host.mac)
153 self.assertEqual(arp.pdst, src_host.ip4)
Eyal Bari758137a2017-07-05 14:31:30 +0300154 return Host(mac=arp.hwsrc, ip4=arp.psrc)
Eyal Baric86e5922017-07-02 18:33:16 +0300155
156 def arp_resp_hosts(self, src_host, pkts):
Eyal Bari758137a2017-07-05 14:31:30 +0300157 return {self.arp_resp_host(src_host, p) for p in pkts}
158
Paul Vinciguerra9db94452018-11-25 10:46:44 -0800159 @staticmethod
160 def inttoip4(ip):
Eyal Bari20197482017-09-13 12:29:08 +0300161 o1 = int(ip / 16777216) % 256
162 o2 = int(ip / 65536) % 256
163 o3 = int(ip / 256) % 256
164 o4 = int(ip) % 256
Paul Vinciguerra9db94452018-11-25 10:46:44 -0800165 return '%s.%s.%s.%s' % (o1, o2, o3, o4)
Eyal Bari20197482017-09-13 12:29:08 +0300166
167 def arp_event_host(self, e):
Neale Ranns37029302018-08-10 05:30:06 -0700168 return Host(str(e.mac), ip4=str(e.ip))
Eyal Bari20197482017-09-13 12:29:08 +0300169
170 def arp_event_hosts(self, evs):
171 return {self.arp_event_host(e) for e in evs}
172
Eyal Baric125ecc2017-09-20 11:29:17 +0300173 def nd_event_host(self, e):
Neale Ranns37029302018-08-10 05:30:06 -0700174 return Host(str(e.mac), ip6=str(e.ip))
Eyal Baric125ecc2017-09-20 11:29:17 +0300175
176 def nd_event_hosts(self, evs):
177 return {self.nd_event_host(e) for e in evs}
178
Eyal Bari758137a2017-07-05 14:31:30 +0300179 @classmethod
180 def ns_req(cls, src_host, host):
181 nsma = in6_getnsma(inet_pton(AF_INET6, "fd10::ffff"))
182 d = inet_ntop(AF_INET6, nsma)
183 return (Ether(dst="ff:ff:ff:ff:ff:ff", src=src_host.mac) /
184 IPv6(dst=d, src=src_host.ip6) /
185 ICMPv6ND_NS(tgt=host.ip6) /
186 ICMPv6NDOptSrcLLAddr(lladdr=src_host.mac))
187
188 @classmethod
Eyal Baric125ecc2017-09-20 11:29:17 +0300189 def ns_reqs_dst(cls, entries, dst_host):
190 return [cls.ns_req(e, dst_host) for e in entries]
191
192 @classmethod
193 def ns_reqs_src(cls, src_host, entries):
Eyal Bari758137a2017-07-05 14:31:30 +0300194 return [cls.ns_req(src_host, e) for e in entries]
195
196 def na_resp_host(self, src_host, rx):
197 self.assertEqual(rx[Ether].dst, src_host.mac)
198 self.assertEqual(in6_ptop(rx[IPv6].dst),
199 in6_ptop(src_host.ip6))
200
201 self.assertTrue(rx.haslayer(ICMPv6ND_NA))
202 self.assertTrue(rx.haslayer(ICMPv6NDOptDstLLAddr))
203
204 na = rx[ICMPv6ND_NA]
205 return Host(mac=na.lladdr, ip6=na.tgt)
206
207 def na_resp_hosts(self, src_host, pkts):
208 return {self.na_resp_host(src_host, p) for p in pkts}
Eyal Baric86e5922017-07-02 18:33:16 +0300209
210 def set_bd_flags(self, bd_id, **args):
211 """
212 Enable/disable defined feature(s) of the bridge domain.
213
214 :param int bd_id: Bridge domain ID.
215 :param list args: List of feature/status pairs. Allowed features: \
216 learn, forward, flood, uu_flood and arp_term. Status False means \
217 disable, status True means enable the feature.
218 :raise: ValueError in case of unknown feature in the input.
219 """
220 for flag in args:
221 if flag == "learn":
222 feature_bitmap = 1 << 0
223 elif flag == "forward":
224 feature_bitmap = 1 << 1
225 elif flag == "flood":
226 feature_bitmap = 1 << 2
227 elif flag == "uu_flood":
228 feature_bitmap = 1 << 3
229 elif flag == "arp_term":
230 feature_bitmap = 1 << 4
231 else:
232 raise ValueError("Unknown feature used: %s" % flag)
233 is_set = 1 if args[flag] else 0
Ole Troana5b2eec2019-03-11 19:23:25 +0100234 self.vapi.bridge_flags(bd_id=bd_id, is_set=is_set,
235 flags=feature_bitmap)
Eyal Baric86e5922017-07-02 18:33:16 +0300236 self.logger.info("Bridge domain ID %d updated" % bd_id)
237
238 def verify_arp(self, src_host, req_hosts, resp_hosts, bd_id=1):
239 reqs = self.arp_reqs(src_host, req_hosts)
240
241 for swif in self.bd_swifs(bd_id):
242 swif.add_stream(reqs)
243
244 self.pg_enable_capture(self.pg_interfaces)
245 self.pg_start()
246
247 for swif in self.bd_swifs(bd_id):
248 resp_pkts = swif.get_capture(len(resp_hosts))
249 resps = self.arp_resp_hosts(src_host, resp_pkts)
250 self.assertEqual(len(resps ^ resp_hosts), 0)
251
Eyal Bari758137a2017-07-05 14:31:30 +0300252 def verify_nd(self, src_host, req_hosts, resp_hosts, bd_id=1):
Eyal Baric125ecc2017-09-20 11:29:17 +0300253 reqs = self.ns_reqs_src(src_host, req_hosts)
Eyal Bari758137a2017-07-05 14:31:30 +0300254
255 for swif in self.bd_swifs(bd_id):
256 swif.add_stream(reqs)
257
258 self.pg_enable_capture(self.pg_interfaces)
259 self.pg_start()
260
261 for swif in self.bd_swifs(bd_id):
262 resp_pkts = swif.get_capture(len(resp_hosts))
263 resps = self.na_resp_hosts(src_host, resp_pkts)
264 self.assertEqual(len(resps ^ resp_hosts), 0)
265
Eyal Baric86e5922017-07-02 18:33:16 +0300266 def test_l2bd_arp_term_01(self):
267 """ L2BD arp term - add 5 hosts, verify arp responses
268 """
269 src_host = self.ip4_host(50, 50, "00:00:11:22:33:44")
270 self.bd_add_del(1, is_add=1)
271 self.set_bd_flags(1, arp_term=True, flood=False,
272 uu_flood=False, learn=False)
273 macs = self.mac_list(range(1, 5))
274 hosts = self.ip4_hosts(4, 1, macs)
275 self.add_del_arp_term_hosts(hosts, is_add=1)
Neale Ranns4d5b9172018-10-24 02:57:49 -0700276
Eyal Baric86e5922017-07-02 18:33:16 +0300277 self.verify_arp(src_host, hosts, hosts)
278 type(self).hosts = hosts
279
280 def test_l2bd_arp_term_02(self):
281 """ L2BD arp term - delete 3 hosts, verify arp responses
282 """
283 src_host = self.ip4_host(50, 50, "00:00:11:22:33:44")
284 macs = self.mac_list(range(1, 3))
285 deleted = self.ip4_hosts(4, 1, macs)
286 self.add_del_arp_term_hosts(deleted, is_add=0)
287 remaining = self.hosts - deleted
288 self.verify_arp(src_host, self.hosts, remaining)
289 type(self).hosts = remaining
290 self.bd_add_del(1, is_add=0)
291
292 def test_l2bd_arp_term_03(self):
293 """ L2BD arp term - recreate BD1, readd 3 hosts, verify arp responses
294 """
295 src_host = self.ip4_host(50, 50, "00:00:11:22:33:44")
296 self.bd_add_del(1, is_add=1)
297 self.set_bd_flags(1, arp_term=True, flood=False,
298 uu_flood=False, learn=False)
299 macs = self.mac_list(range(1, 3))
300 readded = self.ip4_hosts(4, 1, macs)
301 self.add_del_arp_term_hosts(readded, is_add=1)
302 self.verify_arp(src_host, self.hosts | readded, readded)
303 type(self).hosts = readded
304
305 def test_l2bd_arp_term_04(self):
306 """ L2BD arp term - 2 IP4 addrs per host
307 """
308 src_host = self.ip4_host(50, 50, "00:00:11:22:33:44")
309 macs = self.mac_list(range(1, 3))
310 sub5_hosts = self.ip4_hosts(5, 1, macs)
311 self.add_del_arp_term_hosts(sub5_hosts, is_add=1)
312 hosts = self.hosts | sub5_hosts
313 self.verify_arp(src_host, hosts, hosts)
314 type(self).hosts = hosts
315 self.bd_add_del(1, is_add=0)
316
317 def test_l2bd_arp_term_05(self):
318 """ L2BD arp term - create and update 10 IP4-mac pairs
319 """
320 src_host = self.ip4_host(50, 50, "00:00:11:22:33:44")
321 self.bd_add_del(1, is_add=1)
322 self.set_bd_flags(1, arp_term=True, flood=False,
323 uu_flood=False, learn=False)
324 macs1 = self.mac_list(range(10, 20))
325 hosts1 = self.ip4_hosts(5, 1, macs1)
326 self.add_del_arp_term_hosts(hosts1, is_add=1)
327 self.verify_arp(src_host, hosts1, hosts1)
328 macs2 = self.mac_list(range(20, 30))
329 hosts2 = self.ip4_hosts(5, 1, macs2)
330 self.add_del_arp_term_hosts(hosts2, is_add=1)
331 self.verify_arp(src_host, hosts1, hosts2)
332 self.bd_add_del(1, is_add=0)
333
Eyal Bari758137a2017-07-05 14:31:30 +0300334 def test_l2bd_arp_term_06(self):
335 """ L2BD arp/ND term - hosts with both ip4/ip6
336 """
337 src_host4 = self.ip4_host(50, 50, "00:00:11:22:33:44")
338 src_host6 = self.ip6_host(50, 50, "00:00:11:22:33:44")
339 self.bd_add_del(1, is_add=1)
340 # enable flood to make sure requests are not flooded
341 self.set_bd_flags(1, arp_term=True, flood=True,
342 uu_flood=False, learn=False)
343 macs = self.mac_list(range(10, 20))
344 hosts6 = self.ip6_hosts(5, 1, macs)
345 hosts4 = self.ip4_hosts(5, 1, macs)
346 self.add_del_arp_term_hosts(hosts4, is_add=1)
347 self.add_del_arp_term_hosts(hosts6, is_add=1, is_ipv6=1)
348 self.verify_arp(src_host4, hosts4, hosts4)
349 self.verify_nd(src_host6, hosts6, hosts6)
350 self.bd_add_del(1, is_add=0)
351
352 def test_l2bd_arp_term_07(self):
353 """ L2BD ND term - Add and Del hosts, verify ND replies
354 """
355 src_host6 = self.ip6_host(50, 50, "00:00:11:22:33:44")
356 self.bd_add_del(1, is_add=1)
357 self.set_bd_flags(1, arp_term=True, flood=False,
358 uu_flood=False, learn=False)
359 macs = self.mac_list(range(10, 20))
360 hosts6 = self.ip6_hosts(5, 1, macs)
361 self.add_del_arp_term_hosts(hosts6, is_add=1, is_ipv6=1)
362 self.verify_nd(src_host6, hosts6, hosts6)
363 del_macs = self.mac_list(range(10, 15))
364 deleted = self.ip6_hosts(5, 1, del_macs)
365 self.add_del_arp_term_hosts(deleted, is_add=0, is_ipv6=1)
366 self.verify_nd(src_host6, hosts6, hosts6 - deleted)
367 self.bd_add_del(1, is_add=0)
368
369 def test_l2bd_arp_term_08(self):
370 """ L2BD ND term - Add and update IP+mac, verify ND replies
371 """
372 src_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
373 self.bd_add_del(1, is_add=1)
374 self.set_bd_flags(1, arp_term=True, flood=False,
375 uu_flood=False, learn=False)
376 macs1 = self.mac_list(range(10, 20))
377 hosts = self.ip6_hosts(5, 1, macs1)
378 self.add_del_arp_term_hosts(hosts, is_add=1, is_ipv6=1)
379 self.verify_nd(src_host, hosts, hosts)
380 macs2 = self.mac_list(range(20, 30))
381 updated = self.ip6_hosts(5, 1, macs2)
382 self.add_del_arp_term_hosts(updated, is_add=1, is_ipv6=1)
383 self.verify_nd(src_host, hosts, updated)
384 self.bd_add_del(1, is_add=0)
385
Eyal Bari20197482017-09-13 12:29:08 +0300386 def test_l2bd_arp_term_09(self):
387 """ L2BD arp term - send garps, verify arp event reports
388 """
389 self.vapi.want_ip4_arp_events()
390 self.bd_add_del(1, is_add=1)
391 self.set_bd_flags(1, arp_term=True, flood=False,
392 uu_flood=False, learn=False)
393 macs = self.mac_list(range(90, 95))
394 hosts = self.ip4_hosts(5, 1, macs)
395
396 garps = self.garp_reqs(hosts)
397 self.bd_swifs(1)[0].add_stream(garps)
398
399 self.pg_enable_capture(self.pg_interfaces)
400 self.pg_start()
401 evs = [self.vapi.wait_for_event(1, "ip4_arp_event")
402 for i in range(len(hosts))]
403 ev_hosts = self.arp_event_hosts(evs)
404 self.assertEqual(len(ev_hosts ^ hosts), 0)
405
406 def test_l2bd_arp_term_10(self):
407 """ L2BD arp term - send duplicate garps, verify suppression
408 """
409 macs = self.mac_list(range(70, 71))
410 hosts = self.ip4_hosts(6, 1, macs)
411
412 """ send the packet 5 times expect one event
413 """
414 garps = self.garp_reqs(hosts) * 5
415 self.bd_swifs(1)[0].add_stream(garps)
416
417 self.pg_enable_capture(self.pg_interfaces)
418 self.pg_start()
419 evs = [self.vapi.wait_for_event(1, "ip4_arp_event")
420 for i in range(len(hosts))]
421 ev_hosts = self.arp_event_hosts(evs)
422 self.assertEqual(len(ev_hosts ^ hosts), 0)
423
424 def test_l2bd_arp_term_11(self):
425 """ L2BD arp term - disable ip4 arp events,send garps, verify no events
426 """
427 self.vapi.want_ip4_arp_events(enable_disable=0)
428 macs = self.mac_list(range(90, 95))
429 hosts = self.ip4_hosts(5, 1, macs)
430
431 garps = self.garp_reqs(hosts)
432 self.bd_swifs(1)[0].add_stream(garps)
433
434 self.pg_enable_capture(self.pg_interfaces)
435 self.pg_start()
436 self.sleep(1)
437 self.assertEqual(len(self.vapi.collect_events()), 0)
438 self.bd_add_del(1, is_add=0)
439
Eyal Baric125ecc2017-09-20 11:29:17 +0300440 def test_l2bd_arp_term_12(self):
441 """ L2BD ND term - send NS packets verify reports
442 """
Neale Ranns37029302018-08-10 05:30:06 -0700443 self.vapi.want_ip6_nd_events(ip="::")
Eyal Baric125ecc2017-09-20 11:29:17 +0300444 dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
445 self.bd_add_del(1, is_add=1)
446 self.set_bd_flags(1, arp_term=True, flood=False,
447 uu_flood=False, learn=False)
448 macs = self.mac_list(range(10, 15))
449 hosts = self.ip6_hosts(5, 1, macs)
450 reqs = self.ns_reqs_dst(hosts, dst_host)
451 self.bd_swifs(1)[0].add_stream(reqs)
452
453 self.pg_enable_capture(self.pg_interfaces)
454 self.pg_start()
455 evs = [self.vapi.wait_for_event(2, "ip6_nd_event")
456 for i in range(len(hosts))]
457 ev_hosts = self.nd_event_hosts(evs)
458 self.assertEqual(len(ev_hosts ^ hosts), 0)
459
460 def test_l2bd_arp_term_13(self):
461 """ L2BD ND term - send duplicate ns, verify suppression
462 """
463 dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
464 macs = self.mac_list(range(10, 11))
465 hosts = self.ip6_hosts(5, 1, macs)
466 reqs = self.ns_reqs_dst(hosts, dst_host) * 5
467 self.bd_swifs(1)[0].add_stream(reqs)
468
469 self.pg_enable_capture(self.pg_interfaces)
470 self.pg_start()
471 evs = [self.vapi.wait_for_event(2, "ip6_nd_event")
472 for i in range(len(hosts))]
473 ev_hosts = self.nd_event_hosts(evs)
474 self.assertEqual(len(ev_hosts ^ hosts), 0)
475
476 def test_l2bd_arp_term_14(self):
477 """ L2BD ND term - disable ip4 arp events,send ns, verify no events
478 """
Neale Ranns37029302018-08-10 05:30:06 -0700479 self.vapi.want_ip6_nd_events(enable_disable=0, ip="::")
Eyal Baric125ecc2017-09-20 11:29:17 +0300480 dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
481 macs = self.mac_list(range(10, 15))
482 hosts = self.ip6_hosts(5, 1, macs)
483 reqs = self.ns_reqs_dst(hosts, dst_host)
484 self.bd_swifs(1)[0].add_stream(reqs)
485
486 self.pg_enable_capture(self.pg_interfaces)
487 self.pg_start()
488 self.sleep(1)
489 self.assertEqual(len(self.vapi.collect_events()), 0)
490 self.bd_add_del(1, is_add=0)
491
Eyal Baric86e5922017-07-02 18:33:16 +0300492
493if __name__ == '__main__':
494 unittest.main(testRunner=VppTestRunner)