Add test of the IP unnumbered dump
[vpp.git] / test / test_neighbor.py
1 #!/usr/bin/env python
2
3 import unittest
4 from socket import AF_INET, AF_INET6, inet_pton
5
6 from framework import VppTestCase, VppTestRunner
7 from vpp_neighbor import VppNeighbor, find_nbr
8 from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, \
9     VppIpTable
10
11 from scapy.packet import Raw
12 from scapy.layers.l2 import Ether, ARP, Dot1Q
13 from scapy.layers.inet import IP, UDP
14 from scapy.contrib.mpls import MPLS
15
16 # not exported by scapy, so redefined here
17 arp_opts = {"who-has": 1, "is-at": 2}
18
19
20 class ARPTestCase(VppTestCase):
21     """ ARP Test Case """
22
23     def setUp(self):
24         super(ARPTestCase, self).setUp()
25
26         # create 3 pg interfaces
27         self.create_pg_interfaces(range(4))
28
29         # pg0 configured with ip4 and 6 addresses used for input
30         # pg1 configured with ip4 and 6 addresses used for output
31         # pg2 is unnumbered to pg0
32         for i in self.pg_interfaces:
33             i.admin_up()
34
35         self.pg0.config_ip4()
36         self.pg0.config_ip6()
37         self.pg0.resolve_arp()
38
39         self.pg1.config_ip4()
40         self.pg1.config_ip6()
41
42         # pg3 in a different VRF
43         self.tbl = VppIpTable(self, 1)
44         self.tbl.add_vpp_config()
45
46         self.pg3.set_table_ip4(1)
47         self.pg3.config_ip4()
48
49     def tearDown(self):
50         self.pg0.unconfig_ip4()
51         self.pg0.unconfig_ip6()
52
53         self.pg1.unconfig_ip4()
54         self.pg1.unconfig_ip6()
55
56         self.pg3.unconfig_ip4()
57         self.pg3.set_table_ip4(0)
58
59         for i in self.pg_interfaces:
60             i.admin_down()
61
62         super(ARPTestCase, self).tearDown()
63
64     def verify_arp_req(self, rx, smac, sip, dip):
65         ether = rx[Ether]
66         self.assertEqual(ether.dst, "ff:ff:ff:ff:ff:ff")
67         self.assertEqual(ether.src, smac)
68
69         arp = rx[ARP]
70         self.assertEqual(arp.hwtype, 1)
71         self.assertEqual(arp.ptype, 0x800)
72         self.assertEqual(arp.hwlen, 6)
73         self.assertEqual(arp.plen, 4)
74         self.assertEqual(arp.op, arp_opts["who-has"])
75         self.assertEqual(arp.hwsrc, smac)
76         self.assertEqual(arp.hwdst, "00:00:00:00:00:00")
77         self.assertEqual(arp.psrc, sip)
78         self.assertEqual(arp.pdst, dip)
79
80     def verify_arp_resp(self, rx, smac, dmac, sip, dip):
81         ether = rx[Ether]
82         self.assertEqual(ether.dst, dmac)
83         self.assertEqual(ether.src, smac)
84
85         arp = rx[ARP]
86         self.assertEqual(arp.hwtype, 1)
87         self.assertEqual(arp.ptype, 0x800)
88         self.assertEqual(arp.hwlen, 6)
89         self.assertEqual(arp.plen, 4)
90         self.assertEqual(arp.op, arp_opts["is-at"])
91         self.assertEqual(arp.hwsrc, smac)
92         self.assertEqual(arp.hwdst, dmac)
93         self.assertEqual(arp.psrc, sip)
94         self.assertEqual(arp.pdst, dip)
95
96     def verify_arp_vrrp_resp(self, rx, smac, dmac, sip, dip):
97         ether = rx[Ether]
98         self.assertEqual(ether.dst, dmac)
99         self.assertEqual(ether.src, smac)
100
101         arp = rx[ARP]
102         self.assertEqual(arp.hwtype, 1)
103         self.assertEqual(arp.ptype, 0x800)
104         self.assertEqual(arp.hwlen, 6)
105         self.assertEqual(arp.plen, 4)
106         self.assertEqual(arp.op, arp_opts["is-at"])
107         self.assertNotEqual(arp.hwsrc, smac)
108         self.assertTrue("00:00:5e:00:01" in arp.hwsrc or
109                         "00:00:5E:00:01" in arp.hwsrc)
110         self.assertEqual(arp.hwdst, dmac)
111         self.assertEqual(arp.psrc, sip)
112         self.assertEqual(arp.pdst, dip)
113
114     def verify_ip(self, rx, smac, dmac, sip, dip):
115         ether = rx[Ether]
116         self.assertEqual(ether.dst, dmac)
117         self.assertEqual(ether.src, smac)
118
119         ip = rx[IP]
120         self.assertEqual(ip.src, sip)
121         self.assertEqual(ip.dst, dip)
122
123     def verify_ip_o_mpls(self, rx, smac, dmac, label, sip, dip):
124         ether = rx[Ether]
125         self.assertEqual(ether.dst, dmac)
126         self.assertEqual(ether.src, smac)
127
128         mpls = rx[MPLS]
129         self.assertTrue(mpls.label, label)
130
131         ip = rx[IP]
132         self.assertEqual(ip.src, sip)
133         self.assertEqual(ip.dst, dip)
134
135     def test_arp(self):
136         """ ARP """
137
138         #
139         # Generate some hosts on the LAN
140         #
141         self.pg1.generate_remote_hosts(11)
142
143         #
144         # Send IP traffic to one of these unresolved hosts.
145         #  expect the generation of an ARP request
146         #
147         p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
148              IP(src=self.pg0.remote_ip4, dst=self.pg1._remote_hosts[1].ip4) /
149              UDP(sport=1234, dport=1234) /
150              Raw())
151
152         self.pg0.add_stream(p)
153         self.pg_enable_capture(self.pg_interfaces)
154         self.pg_start()
155
156         rx = self.pg1.get_capture(1)
157
158         self.verify_arp_req(rx[0],
159                             self.pg1.local_mac,
160                             self.pg1.local_ip4,
161                             self.pg1._remote_hosts[1].ip4)
162
163         #
164         # And a dynamic ARP entry for host 1
165         #
166         dyn_arp = VppNeighbor(self,
167                               self.pg1.sw_if_index,
168                               self.pg1.remote_hosts[1].mac,
169                               self.pg1.remote_hosts[1].ip4)
170         dyn_arp.add_vpp_config()
171
172         #
173         # now we expect IP traffic forwarded
174         #
175         dyn_p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
176                  IP(src=self.pg0.remote_ip4,
177                     dst=self.pg1._remote_hosts[1].ip4) /
178                  UDP(sport=1234, dport=1234) /
179                  Raw())
180
181         self.pg0.add_stream(dyn_p)
182         self.pg_enable_capture(self.pg_interfaces)
183         self.pg_start()
184
185         rx = self.pg1.get_capture(1)
186
187         self.verify_ip(rx[0],
188                        self.pg1.local_mac,
189                        self.pg1.remote_hosts[1].mac,
190                        self.pg0.remote_ip4,
191                        self.pg1._remote_hosts[1].ip4)
192
193         #
194         # And a Static ARP entry for host 2
195         #
196         static_arp = VppNeighbor(self,
197                                  self.pg1.sw_if_index,
198                                  self.pg1.remote_hosts[2].mac,
199                                  self.pg1.remote_hosts[2].ip4,
200                                  is_static=1)
201         static_arp.add_vpp_config()
202
203         static_p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
204                     IP(src=self.pg0.remote_ip4,
205                        dst=self.pg1._remote_hosts[2].ip4) /
206                     UDP(sport=1234, dport=1234) /
207                     Raw())
208
209         self.pg0.add_stream(static_p)
210         self.pg_enable_capture(self.pg_interfaces)
211         self.pg_start()
212
213         rx = self.pg1.get_capture(1)
214
215         self.verify_ip(rx[0],
216                        self.pg1.local_mac,
217                        self.pg1.remote_hosts[2].mac,
218                        self.pg0.remote_ip4,
219                        self.pg1._remote_hosts[2].ip4)
220
221         #
222         # flap the link. dynamic ARPs get flush, statics don't
223         #
224         self.pg1.admin_down()
225         self.pg1.admin_up()
226
227         self.pg0.add_stream(static_p)
228         self.pg_enable_capture(self.pg_interfaces)
229         self.pg_start()
230         rx = self.pg1.get_capture(1)
231
232         self.verify_ip(rx[0],
233                        self.pg1.local_mac,
234                        self.pg1.remote_hosts[2].mac,
235                        self.pg0.remote_ip4,
236                        self.pg1._remote_hosts[2].ip4)
237
238         self.pg0.add_stream(dyn_p)
239         self.pg_enable_capture(self.pg_interfaces)
240         self.pg_start()
241
242         rx = self.pg1.get_capture(1)
243         self.verify_arp_req(rx[0],
244                             self.pg1.local_mac,
245                             self.pg1.local_ip4,
246                             self.pg1._remote_hosts[1].ip4)
247
248         #
249         # Send an ARP request from one of the so-far unlearned remote hosts
250         #
251         p = (Ether(dst="ff:ff:ff:ff:ff:ff",
252                    src=self.pg1._remote_hosts[3].mac) /
253              ARP(op="who-has",
254                  hwsrc=self.pg1._remote_hosts[3].mac,
255                  pdst=self.pg1.local_ip4,
256                  psrc=self.pg1._remote_hosts[3].ip4))
257
258         self.pg1.add_stream(p)
259         self.pg_enable_capture(self.pg_interfaces)
260         self.pg_start()
261
262         rx = self.pg1.get_capture(1)
263         self.verify_arp_resp(rx[0],
264                              self.pg1.local_mac,
265                              self.pg1._remote_hosts[3].mac,
266                              self.pg1.local_ip4,
267                              self.pg1._remote_hosts[3].ip4)
268
269         #
270         # VPP should have learned the mapping for the remote host
271         #
272         self.assertTrue(find_nbr(self,
273                                  self.pg1.sw_if_index,
274                                  self.pg1._remote_hosts[3].ip4))
275         #
276         # Fire in an ARP request before the interface becomes IP enabled
277         #
278         self.pg2.generate_remote_hosts(4)
279
280         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
281              ARP(op="who-has",
282                  hwsrc=self.pg2.remote_mac,
283                  pdst=self.pg1.local_ip4,
284                  psrc=self.pg2.remote_hosts[3].ip4))
285         pt = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
286               Dot1Q(vlan=0) /
287               ARP(op="who-has",
288                   hwsrc=self.pg2.remote_mac,
289                   pdst=self.pg1.local_ip4,
290                   psrc=self.pg2.remote_hosts[3].ip4))
291         self.send_and_assert_no_replies(self.pg2, p,
292                                         "interface not IP enabled")
293
294         #
295         # Make pg2 un-numbered to pg1
296         #
297         self.pg2.set_unnumbered(self.pg1.sw_if_index)
298
299         unnum = self.vapi.ip_unnumbered_dump()
300         self.assertEqual(unnum[0].ip_sw_if_index, self.pg1.sw_if_index)
301         self.assertEqual(unnum[0].sw_if_index, self.pg2.sw_if_index)
302
303         #
304         # We should respond to ARP requests for the unnumbered to address
305         # once an attached route to the source is known
306         #
307         self.send_and_assert_no_replies(
308             self.pg2, p,
309             "ARP req for unnumbered address - no source")
310
311         attached_host = VppIpRoute(self, self.pg2.remote_hosts[3].ip4, 32,
312                                    [VppRoutePath("0.0.0.0",
313                                                  self.pg2.sw_if_index)])
314         attached_host.add_vpp_config()
315
316         self.pg2.add_stream(p)
317         self.pg_enable_capture(self.pg_interfaces)
318         self.pg_start()
319
320         rx = self.pg2.get_capture(1)
321         self.verify_arp_resp(rx[0],
322                              self.pg2.local_mac,
323                              self.pg2.remote_mac,
324                              self.pg1.local_ip4,
325                              self.pg2.remote_hosts[3].ip4)
326
327         self.pg2.add_stream(pt)
328         self.pg_enable_capture(self.pg_interfaces)
329         self.pg_start()
330
331         rx = self.pg2.get_capture(1)
332         self.verify_arp_resp(rx[0],
333                              self.pg2.local_mac,
334                              self.pg2.remote_mac,
335                              self.pg1.local_ip4,
336                              self.pg2.remote_hosts[3].ip4)
337
338         #
339         # A neighbor entry that has no associated FIB-entry
340         #
341         arp_no_fib = VppNeighbor(self,
342                                  self.pg1.sw_if_index,
343                                  self.pg1.remote_hosts[4].mac,
344                                  self.pg1.remote_hosts[4].ip4,
345                                  is_no_fib_entry=1)
346         arp_no_fib.add_vpp_config()
347
348         #
349         # check we have the neighbor, but no route
350         #
351         self.assertTrue(find_nbr(self,
352                                  self.pg1.sw_if_index,
353                                  self.pg1._remote_hosts[4].ip4))
354         self.assertFalse(find_route(self,
355                                     self.pg1._remote_hosts[4].ip4,
356                                     32))
357         #
358         # pg2 is unnumbered to pg1, so we can form adjacencies out of pg2
359         # from within pg1's subnet
360         #
361         arp_unnum = VppNeighbor(self,
362                                 self.pg2.sw_if_index,
363                                 self.pg1.remote_hosts[5].mac,
364                                 self.pg1.remote_hosts[5].ip4)
365         arp_unnum.add_vpp_config()
366
367         p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
368              IP(src=self.pg0.remote_ip4,
369                 dst=self.pg1._remote_hosts[5].ip4) /
370              UDP(sport=1234, dport=1234) /
371              Raw())
372
373         self.pg0.add_stream(p)
374         self.pg_enable_capture(self.pg_interfaces)
375         self.pg_start()
376
377         rx = self.pg2.get_capture(1)
378
379         self.verify_ip(rx[0],
380                        self.pg2.local_mac,
381                        self.pg1.remote_hosts[5].mac,
382                        self.pg0.remote_ip4,
383                        self.pg1._remote_hosts[5].ip4)
384
385         #
386         # ARP requests from hosts in pg1's subnet sent on pg2 are replied to
387         # with the unnumbered interface's address as the source
388         #
389         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
390              ARP(op="who-has",
391                  hwsrc=self.pg2.remote_mac,
392                  pdst=self.pg1.local_ip4,
393                  psrc=self.pg1.remote_hosts[6].ip4))
394
395         self.pg2.add_stream(p)
396         self.pg_enable_capture(self.pg_interfaces)
397         self.pg_start()
398
399         rx = self.pg2.get_capture(1)
400         self.verify_arp_resp(rx[0],
401                              self.pg2.local_mac,
402                              self.pg2.remote_mac,
403                              self.pg1.local_ip4,
404                              self.pg1.remote_hosts[6].ip4)
405
406         #
407         # An attached host route out of pg2 for an undiscovered hosts generates
408         # an ARP request with the unnumbered address as the source
409         #
410         att_unnum = VppIpRoute(self, self.pg1.remote_hosts[7].ip4, 32,
411                                [VppRoutePath("0.0.0.0",
412                                              self.pg2.sw_if_index)])
413         att_unnum.add_vpp_config()
414
415         p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
416              IP(src=self.pg0.remote_ip4,
417                 dst=self.pg1._remote_hosts[7].ip4) /
418              UDP(sport=1234, dport=1234) /
419              Raw())
420
421         self.pg0.add_stream(p)
422         self.pg_enable_capture(self.pg_interfaces)
423         self.pg_start()
424
425         rx = self.pg2.get_capture(1)
426
427         self.verify_arp_req(rx[0],
428                             self.pg2.local_mac,
429                             self.pg1.local_ip4,
430                             self.pg1._remote_hosts[7].ip4)
431
432         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
433              ARP(op="who-has",
434                  hwsrc=self.pg2.remote_mac,
435                  pdst=self.pg1.local_ip4,
436                  psrc=self.pg1.remote_hosts[7].ip4))
437
438         self.pg2.add_stream(p)
439         self.pg_enable_capture(self.pg_interfaces)
440         self.pg_start()
441
442         rx = self.pg2.get_capture(1)
443         self.verify_arp_resp(rx[0],
444                              self.pg2.local_mac,
445                              self.pg2.remote_mac,
446                              self.pg1.local_ip4,
447                              self.pg1.remote_hosts[7].ip4)
448
449         #
450         # An attached host route as yet unresolved out of pg2 for an
451         # undiscovered host, an ARP requests begets a response.
452         #
453         att_unnum1 = VppIpRoute(self, self.pg1.remote_hosts[8].ip4, 32,
454                                 [VppRoutePath("0.0.0.0",
455                                               self.pg2.sw_if_index)])
456         att_unnum1.add_vpp_config()
457
458         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
459              ARP(op="who-has",
460                  hwsrc=self.pg2.remote_mac,
461                  pdst=self.pg1.local_ip4,
462                  psrc=self.pg1.remote_hosts[8].ip4))
463
464         self.pg2.add_stream(p)
465         self.pg_enable_capture(self.pg_interfaces)
466         self.pg_start()
467
468         rx = self.pg2.get_capture(1)
469         self.verify_arp_resp(rx[0],
470                              self.pg2.local_mac,
471                              self.pg2.remote_mac,
472                              self.pg1.local_ip4,
473                              self.pg1.remote_hosts[8].ip4)
474
475         #
476         # Send an ARP request from one of the so-far unlearned remote hosts
477         # with a VLAN0 tag
478         #
479         p = (Ether(dst="ff:ff:ff:ff:ff:ff",
480                    src=self.pg1._remote_hosts[9].mac) /
481              Dot1Q(vlan=0) /
482              ARP(op="who-has",
483                  hwsrc=self.pg1._remote_hosts[9].mac,
484                  pdst=self.pg1.local_ip4,
485                  psrc=self.pg1._remote_hosts[9].ip4))
486
487         self.pg1.add_stream(p)
488         self.pg_enable_capture(self.pg_interfaces)
489         self.pg_start()
490
491         rx = self.pg1.get_capture(1)
492         self.verify_arp_resp(rx[0],
493                              self.pg1.local_mac,
494                              self.pg1._remote_hosts[9].mac,
495                              self.pg1.local_ip4,
496                              self.pg1._remote_hosts[9].ip4)
497
498         #
499         # Add a hierachy of routes for a host in the sub-net.
500         # Should still get an ARP resp since the cover is attached
501         #
502         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg1.remote_mac) /
503              ARP(op="who-has",
504                  hwsrc=self.pg1.remote_mac,
505                  pdst=self.pg1.local_ip4,
506                  psrc=self.pg1.remote_hosts[10].ip4))
507
508         r1 = VppIpRoute(self, self.pg1.remote_hosts[10].ip4, 30,
509                         [VppRoutePath(self.pg1.remote_hosts[10].ip4,
510                                       self.pg1.sw_if_index)])
511         r1.add_vpp_config()
512
513         self.pg1.add_stream(p)
514         self.pg_enable_capture(self.pg_interfaces)
515         self.pg_start()
516         rx = self.pg1.get_capture(1)
517         self.verify_arp_resp(rx[0],
518                              self.pg1.local_mac,
519                              self.pg1.remote_mac,
520                              self.pg1.local_ip4,
521                              self.pg1.remote_hosts[10].ip4)
522
523         r2 = VppIpRoute(self, self.pg1.remote_hosts[10].ip4, 32,
524                         [VppRoutePath(self.pg1.remote_hosts[10].ip4,
525                                       self.pg1.sw_if_index)])
526         r2.add_vpp_config()
527
528         self.pg1.add_stream(p)
529         self.pg_enable_capture(self.pg_interfaces)
530         self.pg_start()
531         rx = self.pg1.get_capture(1)
532         self.verify_arp_resp(rx[0],
533                              self.pg1.local_mac,
534                              self.pg1.remote_mac,
535                              self.pg1.local_ip4,
536                              self.pg1.remote_hosts[10].ip4)
537
538         #
539         # add an ARP entry that's not on the sub-net and so whose
540         # adj-fib fails the refinement check. then send an ARP request
541         # from that source
542         #
543         a1 = VppNeighbor(self,
544                          self.pg0.sw_if_index,
545                          self.pg0.remote_mac,
546                          "100.100.100.50")
547         a1.add_vpp_config()
548
549         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
550              ARP(op="who-has",
551                  hwsrc=self.pg0.remote_mac,
552                  psrc="100.100.100.50",
553                  pdst=self.pg0.remote_ip4))
554         self.send_and_assert_no_replies(self.pg0, p,
555                                         "ARP req for from failed adj-fib")
556
557         #
558         # ERROR Cases
559         #  1 - don't respond to ARP request for address not within the
560         #      interface's sub-net
561         #  1b - nor within the unnumbered subnet
562         #  1c - nor within the subnet of a different interface
563         #
564         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
565              ARP(op="who-has",
566                  hwsrc=self.pg0.remote_mac,
567                  pdst="10.10.10.3",
568                  psrc=self.pg0.remote_ip4))
569         self.send_and_assert_no_replies(self.pg0, p,
570                                         "ARP req for non-local destination")
571         self.assertFalse(find_nbr(self,
572                                   self.pg0.sw_if_index,
573                                   "10.10.10.3"))
574
575         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
576              ARP(op="who-has",
577                  hwsrc=self.pg2.remote_mac,
578                  pdst="10.10.10.3",
579                  psrc=self.pg1.remote_hosts[7].ip4))
580         self.send_and_assert_no_replies(
581             self.pg0, p,
582             "ARP req for non-local destination - unnum")
583
584         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
585              ARP(op="who-has",
586                  hwsrc=self.pg0.remote_mac,
587                  pdst=self.pg1.local_ip4,
588                  psrc=self.pg1.remote_ip4))
589         self.send_and_assert_no_replies(self.pg0, p,
590                                         "ARP req diff sub-net")
591         self.assertFalse(find_nbr(self,
592                                   self.pg0.sw_if_index,
593                                   self.pg1.remote_ip4))
594
595         #
596         #  2 - don't respond to ARP request from an address not within the
597         #      interface's sub-net
598         #   2b - to a prxied address
599         #   2c - not within a differents interface's sub-net
600         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
601              ARP(op="who-has",
602                  hwsrc=self.pg0.remote_mac,
603                  psrc="10.10.10.3",
604                  pdst=self.pg0.local_ip4))
605         self.send_and_assert_no_replies(self.pg0, p,
606                                         "ARP req for non-local source")
607         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
608              ARP(op="who-has",
609                  hwsrc=self.pg2.remote_mac,
610                  psrc="10.10.10.3",
611                  pdst=self.pg0.local_ip4))
612         self.send_and_assert_no_replies(
613             self.pg0, p,
614             "ARP req for non-local source - unnum")
615         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
616              ARP(op="who-has",
617                  hwsrc=self.pg0.remote_mac,
618                  psrc=self.pg1.remote_ip4,
619                  pdst=self.pg0.local_ip4))
620         self.send_and_assert_no_replies(self.pg0, p,
621                                         "ARP req for non-local source 2c")
622
623         #
624         #  3 - don't respond to ARP request from an address that belongs to
625         #      the router
626         #
627         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
628              ARP(op="who-has",
629                  hwsrc=self.pg0.remote_mac,
630                  psrc=self.pg0.local_ip4,
631                  pdst=self.pg0.local_ip4))
632         self.send_and_assert_no_replies(self.pg0, p,
633                                         "ARP req for non-local source")
634
635         #
636         #  4 - don't respond to ARP requests that has mac source different
637         #      from ARP request HW source
638         #
639         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
640              ARP(op="who-has",
641                  hwsrc="00:00:00:DE:AD:BE",
642                  psrc=self.pg0.remote_ip4,
643                  pdst=self.pg0.local_ip4))
644         self.send_and_assert_no_replies(self.pg0, p,
645                                         "ARP req for non-local source")
646
647         #
648         #  5 - don't respond to ARP requests for address within the
649         #      interface's sub-net but not the interface's address
650         #
651         self.pg0.generate_remote_hosts(2)
652         p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
653              ARP(op="who-has",
654                  hwsrc=self.pg0.remote_mac,
655                  psrc=self.pg0.remote_hosts[0].ip4,
656                  pdst=self.pg0.remote_hosts[1].ip4))
657         self.send_and_assert_no_replies(self.pg0, p,
658                                         "ARP req for non-local destination")
659
660         #
661         # cleanup
662         #
663         dyn_arp.remove_vpp_config()
664         static_arp.remove_vpp_config()
665         self.pg2.unset_unnumbered(self.pg1.sw_if_index)
666
667         # need this to flush the adj-fibs
668         self.pg2.unset_unnumbered(self.pg1.sw_if_index)
669         self.pg2.admin_down()
670         self.pg1.admin_down()
671
672     def test_proxy_mirror_arp(self):
673         """ Interface Mirror Proxy ARP """
674
675         #
676         # When VPP has an interface whose address is also applied to a TAP
677         # interface on the host, then VPP's TAP interface will be unnumbered
678         # to the 'real' interface and do proxy ARP from the host.
679         # the curious aspect of this setup is that ARP requests from the host
680         # will come from the VPP's own address.
681         #
682         self.pg0.generate_remote_hosts(2)
683
684         arp_req_from_me = (Ether(src=self.pg2.remote_mac,
685                                  dst="ff:ff:ff:ff:ff:ff") /
686                            ARP(op="who-has",
687                                hwsrc=self.pg2.remote_mac,
688                                pdst=self.pg0.remote_hosts[1].ip4,
689                                psrc=self.pg0.local_ip4))
690
691         #
692         # Configure Proxy ARP for the subnet on PG0addresses on pg0
693         #
694         self.vapi.proxy_arp_add_del(self.pg0._local_ip4n_subnet,
695                                     self.pg0._local_ip4n_bcast)
696
697         # Make pg2 un-numbered to pg0
698         #
699         self.pg2.set_unnumbered(self.pg0.sw_if_index)
700
701         #
702         # Enable pg2 for proxy ARP
703         #
704         self.pg2.set_proxy_arp()
705
706         #
707         # Send the ARP request with an originating address that
708         # is VPP's own address
709         #
710         self.pg2.add_stream(arp_req_from_me)
711         self.pg_enable_capture(self.pg_interfaces)
712         self.pg_start()
713
714         rx = self.pg2.get_capture(1)
715         self.verify_arp_resp(rx[0],
716                              self.pg2.local_mac,
717                              self.pg2.remote_mac,
718                              self.pg0.remote_hosts[1].ip4,
719                              self.pg0.local_ip4)
720
721         #
722         # validate we have not learned an ARP entry as a result of this
723         #
724         self.assertFalse(find_nbr(self,
725                                   self.pg2.sw_if_index,
726                                   self.pg0.local_ip4))
727
728         #
729         # cleanup
730         #
731         self.pg2.set_proxy_arp(0)
732         self.vapi.proxy_arp_add_del(self.pg0._local_ip4n_subnet,
733                                     self.pg0._local_ip4n_bcast,
734                                     is_add=0)
735
736     def test_proxy_arp(self):
737         """ Proxy ARP """
738
739         self.pg1.generate_remote_hosts(2)
740
741         #
742         # Proxy ARP rewquest packets for each interface
743         #
744         arp_req_pg0 = (Ether(src=self.pg0.remote_mac,
745                              dst="ff:ff:ff:ff:ff:ff") /
746                        ARP(op="who-has",
747                            hwsrc=self.pg0.remote_mac,
748                            pdst="10.10.10.3",
749                            psrc=self.pg0.remote_ip4))
750         arp_req_pg0_tagged = (Ether(src=self.pg0.remote_mac,
751                                     dst="ff:ff:ff:ff:ff:ff") /
752                               Dot1Q(vlan=0) /
753                               ARP(op="who-has",
754                                   hwsrc=self.pg0.remote_mac,
755                                   pdst="10.10.10.3",
756                                   psrc=self.pg0.remote_ip4))
757         arp_req_pg1 = (Ether(src=self.pg1.remote_mac,
758                              dst="ff:ff:ff:ff:ff:ff") /
759                        ARP(op="who-has",
760                            hwsrc=self.pg1.remote_mac,
761                            pdst="10.10.10.3",
762                            psrc=self.pg1.remote_ip4))
763         arp_req_pg2 = (Ether(src=self.pg2.remote_mac,
764                              dst="ff:ff:ff:ff:ff:ff") /
765                        ARP(op="who-has",
766                            hwsrc=self.pg2.remote_mac,
767                            pdst="10.10.10.3",
768                            psrc=self.pg1.remote_hosts[1].ip4))
769         arp_req_pg3 = (Ether(src=self.pg3.remote_mac,
770                              dst="ff:ff:ff:ff:ff:ff") /
771                        ARP(op="who-has",
772                            hwsrc=self.pg3.remote_mac,
773                            pdst="10.10.10.3",
774                            psrc=self.pg3.remote_ip4))
775
776         #
777         # Configure Proxy ARP for 10.10.10.0 -> 10.10.10.124
778         #
779         self.vapi.proxy_arp_add_del(inet_pton(AF_INET, "10.10.10.2"),
780                                     inet_pton(AF_INET, "10.10.10.124"))
781
782         #
783         # No responses are sent when the interfaces are not enabled for proxy
784         # ARP
785         #
786         self.send_and_assert_no_replies(self.pg0, arp_req_pg0,
787                                         "ARP req from unconfigured interface")
788         self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
789                                         "ARP req from unconfigured interface")
790
791         #
792         # Make pg2 un-numbered to pg1
793         #  still won't reply.
794         #
795         self.pg2.set_unnumbered(self.pg1.sw_if_index)
796
797         self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
798                                         "ARP req from unnumbered interface")
799
800         #
801         # Enable each interface to reply to proxy ARPs
802         #
803         for i in self.pg_interfaces:
804             i.set_proxy_arp()
805
806         #
807         # Now each of the interfaces should reply to a request to a proxied
808         # address
809         #
810         self.pg0.add_stream(arp_req_pg0)
811         self.pg_enable_capture(self.pg_interfaces)
812         self.pg_start()
813
814         rx = self.pg0.get_capture(1)
815         self.verify_arp_resp(rx[0],
816                              self.pg0.local_mac,
817                              self.pg0.remote_mac,
818                              "10.10.10.3",
819                              self.pg0.remote_ip4)
820
821         self.pg0.add_stream(arp_req_pg0_tagged)
822         self.pg_enable_capture(self.pg_interfaces)
823         self.pg_start()
824
825         rx = self.pg0.get_capture(1)
826         self.verify_arp_resp(rx[0],
827                              self.pg0.local_mac,
828                              self.pg0.remote_mac,
829                              "10.10.10.3",
830                              self.pg0.remote_ip4)
831
832         self.pg1.add_stream(arp_req_pg1)
833         self.pg_enable_capture(self.pg_interfaces)
834         self.pg_start()
835
836         rx = self.pg1.get_capture(1)
837         self.verify_arp_resp(rx[0],
838                              self.pg1.local_mac,
839                              self.pg1.remote_mac,
840                              "10.10.10.3",
841                              self.pg1.remote_ip4)
842
843         self.pg2.add_stream(arp_req_pg2)
844         self.pg_enable_capture(self.pg_interfaces)
845         self.pg_start()
846
847         rx = self.pg2.get_capture(1)
848         self.verify_arp_resp(rx[0],
849                              self.pg2.local_mac,
850                              self.pg2.remote_mac,
851                              "10.10.10.3",
852                              self.pg1.remote_hosts[1].ip4)
853
854         #
855         # A request for an address out of the configured range
856         #
857         arp_req_pg1_hi = (Ether(src=self.pg1.remote_mac,
858                                 dst="ff:ff:ff:ff:ff:ff") /
859                           ARP(op="who-has",
860                               hwsrc=self.pg1.remote_mac,
861                               pdst="10.10.10.125",
862                               psrc=self.pg1.remote_ip4))
863         self.send_and_assert_no_replies(self.pg1, arp_req_pg1_hi,
864                                         "ARP req out of range HI")
865         arp_req_pg1_low = (Ether(src=self.pg1.remote_mac,
866                                  dst="ff:ff:ff:ff:ff:ff") /
867                            ARP(op="who-has",
868                                hwsrc=self.pg1.remote_mac,
869                                pdst="10.10.10.1",
870                                psrc=self.pg1.remote_ip4))
871         self.send_and_assert_no_replies(self.pg1, arp_req_pg1_low,
872                                         "ARP req out of range Low")
873
874         #
875         # Request for an address in the proxy range but from an interface
876         # in a different VRF
877         #
878         self.send_and_assert_no_replies(self.pg3, arp_req_pg3,
879                                         "ARP req from different VRF")
880
881         #
882         # Disable Each interface for proxy ARP
883         #  - expect none to respond
884         #
885         for i in self.pg_interfaces:
886             i.set_proxy_arp(0)
887
888         self.send_and_assert_no_replies(self.pg0, arp_req_pg0,
889                                         "ARP req from disable")
890         self.send_and_assert_no_replies(self.pg1, arp_req_pg1,
891                                         "ARP req from disable")
892         self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
893                                         "ARP req from disable")
894
895         #
896         # clean up on interface 2
897         #
898         self.pg2.unset_unnumbered(self.pg1.sw_if_index)
899
900     def test_mpls(self):
901         """ MPLS """
902
903         #
904         # Interface 2 does not yet have ip4 config
905         #
906         self.pg2.config_ip4()
907         self.pg2.generate_remote_hosts(2)
908
909         #
910         # Add a reoute with out going label via an ARP unresolved next-hop
911         #
912         ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
913                                  [VppRoutePath(self.pg2.remote_hosts[1].ip4,
914                                                self.pg2.sw_if_index,
915                                                labels=[55])])
916         ip_10_0_0_1.add_vpp_config()
917
918         #
919         # packets should generate an ARP request
920         #
921         p = (Ether(src=self.pg0.remote_mac,
922                    dst=self.pg0.local_mac) /
923              IP(src=self.pg0.remote_ip4, dst="10.0.0.1") /
924              UDP(sport=1234, dport=1234) /
925              Raw('\xa5' * 100))
926
927         self.pg0.add_stream(p)
928         self.pg_enable_capture(self.pg_interfaces)
929         self.pg_start()
930
931         rx = self.pg2.get_capture(1)
932         self.verify_arp_req(rx[0],
933                             self.pg2.local_mac,
934                             self.pg2.local_ip4,
935                             self.pg2._remote_hosts[1].ip4)
936
937         #
938         # now resolve the neighbours
939         #
940         self.pg2.configure_ipv4_neighbors()
941
942         #
943         # Now packet should be properly MPLS encapped.
944         #  This verifies that MPLS link-type adjacencies are completed
945         #  when the ARP entry resolves
946         #
947         self.pg0.add_stream(p)
948         self.pg_enable_capture(self.pg_interfaces)
949         self.pg_start()
950
951         rx = self.pg2.get_capture(1)
952         self.verify_ip_o_mpls(rx[0],
953                               self.pg2.local_mac,
954                               self.pg2.remote_hosts[1].mac,
955                               55,
956                               self.pg0.remote_ip4,
957                               "10.0.0.1")
958         self.pg2.unconfig_ip4()
959
960     def test_arp_vrrp(self):
961         """ ARP reply with VRRP virtual src hw addr """
962
963         #
964         # IP packet destined for pg1 remote host arrives on pg0 resulting
965         # in an ARP request for the address of the remote host on pg1
966         #
967         p0 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
968               IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
969               UDP(sport=1234, dport=1234) /
970               Raw())
971
972         self.pg0.add_stream(p0)
973         self.pg_enable_capture(self.pg_interfaces)
974         self.pg_start()
975
976         rx1 = self.pg1.get_capture(1)
977
978         self.verify_arp_req(rx1[0],
979                             self.pg1.local_mac,
980                             self.pg1.local_ip4,
981                             self.pg1.remote_ip4)
982
983         #
984         # ARP reply for address of pg1 remote host arrives on pg1 with
985         # the hw src addr set to a value in the VRRP IPv4 range of
986         # MAC addresses
987         #
988         p1 = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
989               ARP(op="is-at", hwdst=self.pg1.local_mac,
990                   hwsrc="00:00:5e:00:01:09", pdst=self.pg1.local_ip4,
991                   psrc=self.pg1.remote_ip4))
992
993         self.pg1.add_stream(p1)
994         self.pg_enable_capture(self.pg_interfaces)
995         self.pg_start()
996
997         #
998         # IP packet destined for pg1 remote host arrives on pg0 again.
999         # VPP should have an ARP entry for that address now and the packet
1000         # should be sent out pg1.
1001         #
1002         self.pg0.add_stream(p0)
1003         self.pg_enable_capture(self.pg_interfaces)
1004         self.pg_start()
1005
1006         rx1 = self.pg1.get_capture(1)
1007
1008         self.verify_ip(rx1[0],
1009                        self.pg1.local_mac,
1010                        "00:00:5e:00:01:09",
1011                        self.pg0.remote_ip4,
1012                        self.pg1.remote_ip4)
1013
1014         self.pg1.admin_down()
1015         self.pg1.admin_up()
1016
1017     def test_arp_duplicates(self):
1018         """ ARP Duplicates"""
1019
1020         #
1021         # Generate some hosts on the LAN
1022         #
1023         self.pg1.generate_remote_hosts(3)
1024
1025         #
1026         # Add host 1 on pg1 and pg2
1027         #
1028         arp_pg1 = VppNeighbor(self,
1029                               self.pg1.sw_if_index,
1030                               self.pg1.remote_hosts[1].mac,
1031                               self.pg1.remote_hosts[1].ip4)
1032         arp_pg1.add_vpp_config()
1033         arp_pg2 = VppNeighbor(self,
1034                               self.pg2.sw_if_index,
1035                               self.pg2.remote_mac,
1036                               self.pg1.remote_hosts[1].ip4)
1037         arp_pg2.add_vpp_config()
1038
1039         #
1040         # IP packet destined for pg1 remote host arrives on pg1 again.
1041         #
1042         p = (Ether(dst=self.pg0.local_mac,
1043                    src=self.pg0.remote_mac) /
1044              IP(src=self.pg0.remote_ip4,
1045                 dst=self.pg1.remote_hosts[1].ip4) /
1046              UDP(sport=1234, dport=1234) /
1047              Raw())
1048
1049         self.pg0.add_stream(p)
1050         self.pg_enable_capture(self.pg_interfaces)
1051         self.pg_start()
1052
1053         rx1 = self.pg1.get_capture(1)
1054
1055         self.verify_ip(rx1[0],
1056                        self.pg1.local_mac,
1057                        self.pg1.remote_hosts[1].mac,
1058                        self.pg0.remote_ip4,
1059                        self.pg1.remote_hosts[1].ip4)
1060
1061         #
1062         # remove the duplicate on pg1
1063         # packet stream shoud generate ARPs out of pg1
1064         #
1065         arp_pg1.remove_vpp_config()
1066
1067         self.pg0.add_stream(p)
1068         self.pg_enable_capture(self.pg_interfaces)
1069         self.pg_start()
1070
1071         rx1 = self.pg1.get_capture(1)
1072
1073         self.verify_arp_req(rx1[0],
1074                             self.pg1.local_mac,
1075                             self.pg1.local_ip4,
1076                             self.pg1.remote_hosts[1].ip4)
1077
1078         #
1079         # Add it back
1080         #
1081         arp_pg1.add_vpp_config()
1082
1083         self.pg0.add_stream(p)
1084         self.pg_enable_capture(self.pg_interfaces)
1085         self.pg_start()
1086
1087         rx1 = self.pg1.get_capture(1)
1088
1089         self.verify_ip(rx1[0],
1090                        self.pg1.local_mac,
1091                        self.pg1.remote_hosts[1].mac,
1092                        self.pg0.remote_ip4,
1093                        self.pg1.remote_hosts[1].ip4)
1094
1095     def test_arp_static(self):
1096         """ ARP Static"""
1097         self.pg2.generate_remote_hosts(3)
1098
1099         #
1100         # Add a static ARP entry
1101         #
1102         static_arp = VppNeighbor(self,
1103                                  self.pg2.sw_if_index,
1104                                  self.pg2.remote_hosts[1].mac,
1105                                  self.pg2.remote_hosts[1].ip4,
1106                                  is_static=1)
1107         static_arp.add_vpp_config()
1108
1109         #
1110         # Add the connected prefix to the interface
1111         #
1112         self.pg2.config_ip4()
1113
1114         #
1115         # We should now find the adj-fib
1116         #
1117         self.assertTrue(find_nbr(self,
1118                                  self.pg2.sw_if_index,
1119                                  self.pg2.remote_hosts[1].ip4,
1120                                  is_static=1))
1121         self.assertTrue(find_route(self,
1122                                    self.pg2.remote_hosts[1].ip4,
1123                                    32))
1124
1125         #
1126         # remove the connected
1127         #
1128         self.pg2.unconfig_ip4()
1129
1130         #
1131         # put the interface into table 1
1132         #
1133         self.pg2.set_table_ip4(1)
1134
1135         #
1136         # configure the same connected and expect to find the
1137         # adj fib in the new table
1138         #
1139         self.pg2.config_ip4()
1140         self.assertTrue(find_route(self,
1141                                    self.pg2.remote_hosts[1].ip4,
1142                                    32,
1143                                    table_id=1))
1144
1145         #
1146         # clean-up
1147         #
1148         self.pg2.unconfig_ip4()
1149         self.pg2.set_table_ip4(0)
1150
1151     def test_arp_incomplete(self):
1152         """ ARP Incomplete"""
1153         self.pg1.generate_remote_hosts(3)
1154
1155         p0 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1156               IP(src=self.pg0.remote_ip4,
1157                  dst=self.pg1.remote_hosts[1].ip4) /
1158               UDP(sport=1234, dport=1234) /
1159               Raw())
1160         p1 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1161               IP(src=self.pg0.remote_ip4,
1162                  dst=self.pg1.remote_hosts[2].ip4) /
1163               UDP(sport=1234, dport=1234) /
1164               Raw())
1165
1166         #
1167         # a packet to an unresolved destination generates an ARP request
1168         #
1169         rx = self.send_and_expect(self.pg0, [p0], self.pg1)
1170         self.verify_arp_req(rx[0],
1171                             self.pg1.local_mac,
1172                             self.pg1.local_ip4,
1173                             self.pg1._remote_hosts[1].ip4)
1174
1175         #
1176         # add a neighbour for remote host 1
1177         #
1178         static_arp = VppNeighbor(self,
1179                                  self.pg1.sw_if_index,
1180                                  self.pg1.remote_hosts[1].mac,
1181                                  self.pg1.remote_hosts[1].ip4,
1182                                  is_static=1)
1183         static_arp.add_vpp_config()
1184
1185         #
1186         # change the interface's MAC
1187         #
1188         mac = [chr(0x00), chr(0x00), chr(0x00),
1189                chr(0x33), chr(0x33), chr(0x33)]
1190         mac_string = ''.join(mac)
1191
1192         self.vapi.sw_interface_set_mac_address(self.pg1.sw_if_index,
1193                                                mac_string)
1194
1195         #
1196         # now ARP requests come from the new source mac
1197         #
1198         rx = self.send_and_expect(self.pg0, [p1], self.pg1)
1199         self.verify_arp_req(rx[0],
1200                             "00:00:00:33:33:33",
1201                             self.pg1.local_ip4,
1202                             self.pg1._remote_hosts[2].ip4)
1203
1204         #
1205         # packets to the resolved host also have the new source mac
1206         #
1207         rx = self.send_and_expect(self.pg0, [p0], self.pg1)
1208         self.verify_ip(rx[0],
1209                        "00:00:00:33:33:33",
1210                        self.pg1.remote_hosts[1].mac,
1211                        self.pg0.remote_ip4,
1212                        self.pg1.remote_hosts[1].ip4)
1213
1214         #
1215         # set the mac address on the inteface that does not have a
1216         # configured subnet and thus no glean
1217         #
1218         self.vapi.sw_interface_set_mac_address(self.pg2.sw_if_index,
1219                                                mac_string)
1220
1221     def test_garp(self):
1222         """ GARP """
1223
1224         #
1225         # Generate some hosts on the LAN
1226         #
1227         self.pg1.generate_remote_hosts(4)
1228
1229         #
1230         # And an ARP entry
1231         #
1232         arp = VppNeighbor(self,
1233                           self.pg1.sw_if_index,
1234                           self.pg1.remote_hosts[1].mac,
1235                           self.pg1.remote_hosts[1].ip4)
1236         arp.add_vpp_config()
1237
1238         self.assertTrue(find_nbr(self,
1239                                  self.pg1.sw_if_index,
1240                                  self.pg1.remote_hosts[1].ip4,
1241                                  mac=self.pg1.remote_hosts[1].mac))
1242
1243         #
1244         # Send a GARP (request) to swap the host 1's address to that of host 2
1245         #
1246         p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1247                     src=self.pg1.remote_hosts[2].mac) /
1248               ARP(op="who-has",
1249                   hwdst=self.pg1.local_mac,
1250                   hwsrc=self.pg1.remote_hosts[2].mac,
1251                   pdst=self.pg1.remote_hosts[1].ip4,
1252                   psrc=self.pg1.remote_hosts[1].ip4))
1253
1254         self.pg1.add_stream(p1)
1255         self.pg_enable_capture(self.pg_interfaces)
1256         self.pg_start()
1257
1258         self.assertTrue(find_nbr(self,
1259                                  self.pg1.sw_if_index,
1260                                  self.pg1.remote_hosts[1].ip4,
1261                                  mac=self.pg1.remote_hosts[2].mac))
1262
1263         #
1264         # Send a GARP (reply) to swap the host 1's address to that of host 3
1265         #
1266         p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1267                     src=self.pg1.remote_hosts[3].mac) /
1268               ARP(op="is-at",
1269                   hwdst=self.pg1.local_mac,
1270                   hwsrc=self.pg1.remote_hosts[3].mac,
1271                   pdst=self.pg1.remote_hosts[1].ip4,
1272                   psrc=self.pg1.remote_hosts[1].ip4))
1273
1274         self.pg1.add_stream(p1)
1275         self.pg_enable_capture(self.pg_interfaces)
1276         self.pg_start()
1277
1278         self.assertTrue(find_nbr(self,
1279                                  self.pg1.sw_if_index,
1280                                  self.pg1.remote_hosts[1].ip4,
1281                                  mac=self.pg1.remote_hosts[3].mac))
1282
1283         #
1284         # GARPs (requets nor replies) for host we don't know yet
1285         # don't result in new neighbour entries
1286         #
1287         p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1288                     src=self.pg1.remote_hosts[3].mac) /
1289               ARP(op="who-has",
1290                   hwdst=self.pg1.local_mac,
1291                   hwsrc=self.pg1.remote_hosts[3].mac,
1292                   pdst=self.pg1.remote_hosts[2].ip4,
1293                   psrc=self.pg1.remote_hosts[2].ip4))
1294
1295         self.pg1.add_stream(p1)
1296         self.pg_enable_capture(self.pg_interfaces)
1297         self.pg_start()
1298
1299         self.assertFalse(find_nbr(self,
1300                                   self.pg1.sw_if_index,
1301                                   self.pg1.remote_hosts[2].ip4))
1302
1303         p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1304                     src=self.pg1.remote_hosts[3].mac) /
1305               ARP(op="is-at",
1306                   hwdst=self.pg1.local_mac,
1307                   hwsrc=self.pg1.remote_hosts[3].mac,
1308                   pdst=self.pg1.remote_hosts[2].ip4,
1309                   psrc=self.pg1.remote_hosts[2].ip4))
1310
1311         self.pg1.add_stream(p1)
1312         self.pg_enable_capture(self.pg_interfaces)
1313         self.pg_start()
1314
1315         self.assertFalse(find_nbr(self,
1316                                   self.pg1.sw_if_index,
1317                                   self.pg1.remote_hosts[2].ip4))
1318
1319
1320 if __name__ == '__main__':
1321     unittest.main(testRunner=VppTestRunner)