blob: 7c13f9ffb0a116d120227e7b0ef86b129afe06af [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Neale Ranns39f9d8b2017-02-16 21:57:05 -08002
3import unittest
Neale Rannscbe25aa2019-09-30 10:53:31 +00004import os
Neale Ranns39f9d8b2017-02-16 21:57:05 -08005from socket import AF_INET, AF_INET6, inet_pton
6
7from framework import VppTestCase, VppTestRunner
8from vpp_neighbor import VppNeighbor, find_nbr
Neale Ranns15002542017-09-10 04:39:11 -07009from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, \
Neale Ranns097fa662018-05-01 05:17:55 -070010 VppIpTable, DpoProto, FibPathType
Neale Ranns37029302018-08-10 05:30:06 -070011from vpp_papi import VppEnum
Jakub Grajciar2df2f752020-12-01 11:23:44 +010012from vpp_ip import VppIpPuntRedirect
Neale Ranns39f9d8b2017-02-16 21:57:05 -080013
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070014import scapy.compat
Neale Ranns39f9d8b2017-02-16 21:57:05 -080015from scapy.packet import Raw
Neale Ranns30d0fd42017-05-30 07:30:04 -070016from scapy.layers.l2 import Ether, ARP, Dot1Q
Neale Ranns240dcb22020-04-23 09:04:59 +000017from scapy.layers.inet import IP, UDP, TCP
Neale Rannscd35e532018-08-31 02:51:45 -070018from scapy.layers.inet6 import IPv6
Neale Ranns37be7362017-02-21 17:30:26 -080019from scapy.contrib.mpls import MPLS
Neale Ranns14260392018-09-28 05:00:57 -070020from scapy.layers.inet6 import IPv6
Neale Ranns39f9d8b2017-02-16 21:57:05 -080021
Paul Vinciguerra4271c972019-05-14 13:25:49 -040022
23NUM_PKTS = 67
24
Neale Ranns39f9d8b2017-02-16 21:57:05 -080025# not exported by scapy, so redefined here
26arp_opts = {"who-has": 1, "is-at": 2}
27
28
29class ARPTestCase(VppTestCase):
30 """ ARP Test Case """
31
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070032 @classmethod
33 def setUpClass(cls):
34 super(ARPTestCase, cls).setUpClass()
35
36 @classmethod
37 def tearDownClass(cls):
38 super(ARPTestCase, cls).tearDownClass()
39
Neale Ranns39f9d8b2017-02-16 21:57:05 -080040 def setUp(self):
41 super(ARPTestCase, self).setUp()
42
43 # create 3 pg interfaces
44 self.create_pg_interfaces(range(4))
45
46 # pg0 configured with ip4 and 6 addresses used for input
47 # pg1 configured with ip4 and 6 addresses used for output
48 # pg2 is unnumbered to pg0
49 for i in self.pg_interfaces:
50 i.admin_up()
51
52 self.pg0.config_ip4()
53 self.pg0.config_ip6()
54 self.pg0.resolve_arp()
55
56 self.pg1.config_ip4()
57 self.pg1.config_ip6()
58
59 # pg3 in a different VRF
Neale Ranns15002542017-09-10 04:39:11 -070060 self.tbl = VppIpTable(self, 1)
61 self.tbl.add_vpp_config()
62
Neale Ranns39f9d8b2017-02-16 21:57:05 -080063 self.pg3.set_table_ip4(1)
64 self.pg3.config_ip4()
65
Neale Ranns4008ac92017-02-13 23:20:04 -080066 def tearDown(self):
Neale Ranns4b919a52017-03-11 05:55:21 -080067 self.pg0.unconfig_ip4()
68 self.pg0.unconfig_ip6()
69
70 self.pg1.unconfig_ip4()
71 self.pg1.unconfig_ip6()
72
73 self.pg3.unconfig_ip4()
Neale Ranns15002542017-09-10 04:39:11 -070074 self.pg3.set_table_ip4(0)
Neale Ranns4b919a52017-03-11 05:55:21 -080075
Neale Ranns4008ac92017-02-13 23:20:04 -080076 for i in self.pg_interfaces:
Neale Ranns4008ac92017-02-13 23:20:04 -080077 i.admin_down()
78
Neale Ranns15002542017-09-10 04:39:11 -070079 super(ARPTestCase, self).tearDown()
80
Neale Ranns39f9d8b2017-02-16 21:57:05 -080081 def verify_arp_req(self, rx, smac, sip, dip):
82 ether = rx[Ether]
83 self.assertEqual(ether.dst, "ff:ff:ff:ff:ff:ff")
84 self.assertEqual(ether.src, smac)
85
86 arp = rx[ARP]
87 self.assertEqual(arp.hwtype, 1)
88 self.assertEqual(arp.ptype, 0x800)
89 self.assertEqual(arp.hwlen, 6)
90 self.assertEqual(arp.plen, 4)
91 self.assertEqual(arp.op, arp_opts["who-has"])
92 self.assertEqual(arp.hwsrc, smac)
93 self.assertEqual(arp.hwdst, "00:00:00:00:00:00")
94 self.assertEqual(arp.psrc, sip)
95 self.assertEqual(arp.pdst, dip)
96
97 def verify_arp_resp(self, rx, smac, dmac, sip, dip):
98 ether = rx[Ether]
99 self.assertEqual(ether.dst, dmac)
100 self.assertEqual(ether.src, smac)
101
102 arp = rx[ARP]
103 self.assertEqual(arp.hwtype, 1)
104 self.assertEqual(arp.ptype, 0x800)
105 self.assertEqual(arp.hwlen, 6)
106 self.assertEqual(arp.plen, 4)
107 self.assertEqual(arp.op, arp_opts["is-at"])
108 self.assertEqual(arp.hwsrc, smac)
109 self.assertEqual(arp.hwdst, dmac)
110 self.assertEqual(arp.psrc, sip)
111 self.assertEqual(arp.pdst, dip)
112
Matthew Smithcb9ab472017-05-16 21:35:56 -0500113 def verify_arp_vrrp_resp(self, rx, smac, dmac, sip, dip):
114 ether = rx[Ether]
115 self.assertEqual(ether.dst, dmac)
116 self.assertEqual(ether.src, smac)
117
118 arp = rx[ARP]
119 self.assertEqual(arp.hwtype, 1)
120 self.assertEqual(arp.ptype, 0x800)
121 self.assertEqual(arp.hwlen, 6)
122 self.assertEqual(arp.plen, 4)
123 self.assertEqual(arp.op, arp_opts["is-at"])
124 self.assertNotEqual(arp.hwsrc, smac)
125 self.assertTrue("00:00:5e:00:01" in arp.hwsrc or
126 "00:00:5E:00:01" in arp.hwsrc)
127 self.assertEqual(arp.hwdst, dmac)
128 self.assertEqual(arp.psrc, sip)
129 self.assertEqual(arp.pdst, dip)
130
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800131 def verify_ip(self, rx, smac, dmac, sip, dip):
132 ether = rx[Ether]
133 self.assertEqual(ether.dst, dmac)
134 self.assertEqual(ether.src, smac)
135
136 ip = rx[IP]
137 self.assertEqual(ip.src, sip)
138 self.assertEqual(ip.dst, dip)
139
Neale Ranns37be7362017-02-21 17:30:26 -0800140 def verify_ip_o_mpls(self, rx, smac, dmac, label, sip, dip):
141 ether = rx[Ether]
142 self.assertEqual(ether.dst, dmac)
143 self.assertEqual(ether.src, smac)
144
145 mpls = rx[MPLS]
146 self.assertTrue(mpls.label, label)
147
148 ip = rx[IP]
149 self.assertEqual(ip.src, sip)
150 self.assertEqual(ip.dst, dip)
151
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800152 def test_arp(self):
153 """ ARP """
154
155 #
156 # Generate some hosts on the LAN
157 #
Neale Rannsca193612017-06-14 06:50:08 -0700158 self.pg1.generate_remote_hosts(11)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800159
160 #
Neale Rannscbe25aa2019-09-30 10:53:31 +0000161 # watch for:
162 # - all neighbour events
163 # - all neighbor events on pg1
164 # - neighbor events for host[1] on pg1
165 #
166 self.vapi.want_ip_neighbor_events(enable=1,
167 pid=os.getpid())
168 self.vapi.want_ip_neighbor_events(enable=1,
169 pid=os.getpid(),
170 sw_if_index=self.pg1.sw_if_index)
171 self.vapi.want_ip_neighbor_events(enable=1,
172 pid=os.getpid(),
173 sw_if_index=self.pg1.sw_if_index,
174 ip=self.pg1.remote_hosts[1].ip4)
175
176 self.logger.info(self.vapi.cli("sh ip neighbor-watcher"))
177
178 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800179 # Send IP traffic to one of these unresolved hosts.
180 # expect the generation of an ARP request
181 #
182 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
183 IP(src=self.pg0.remote_ip4, dst=self.pg1._remote_hosts[1].ip4) /
184 UDP(sport=1234, dport=1234) /
185 Raw())
186
187 self.pg0.add_stream(p)
188 self.pg_enable_capture(self.pg_interfaces)
189 self.pg_start()
190
191 rx = self.pg1.get_capture(1)
192
193 self.verify_arp_req(rx[0],
194 self.pg1.local_mac,
195 self.pg1.local_ip4,
196 self.pg1._remote_hosts[1].ip4)
197
198 #
199 # And a dynamic ARP entry for host 1
200 #
201 dyn_arp = VppNeighbor(self,
202 self.pg1.sw_if_index,
203 self.pg1.remote_hosts[1].mac,
204 self.pg1.remote_hosts[1].ip4)
205 dyn_arp.add_vpp_config()
Neale Rannscbe25aa2019-09-30 10:53:31 +0000206 self.assertTrue(dyn_arp.query_vpp_config())
207
Neale Rannsdc617b82020-08-20 08:22:56 +0000208 self.logger.info(self.vapi.cli("show ip neighbor-watcher"))
209
Neale Rannscbe25aa2019-09-30 10:53:31 +0000210 # this matches all of the listnerers
211 es = [self.vapi.wait_for_event(1, "ip_neighbor_event")
212 for i in range(3)]
213 for e in es:
214 self.assertEqual(str(e.neighbor.ip_address),
215 self.pg1.remote_hosts[1].ip4)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800216
217 #
218 # now we expect IP traffic forwarded
219 #
220 dyn_p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
221 IP(src=self.pg0.remote_ip4,
222 dst=self.pg1._remote_hosts[1].ip4) /
223 UDP(sport=1234, dport=1234) /
224 Raw())
225
226 self.pg0.add_stream(dyn_p)
227 self.pg_enable_capture(self.pg_interfaces)
228 self.pg_start()
229
230 rx = self.pg1.get_capture(1)
231
232 self.verify_ip(rx[0],
233 self.pg1.local_mac,
234 self.pg1.remote_hosts[1].mac,
235 self.pg0.remote_ip4,
236 self.pg1._remote_hosts[1].ip4)
237
238 #
239 # And a Static ARP entry for host 2
240 #
241 static_arp = VppNeighbor(self,
242 self.pg1.sw_if_index,
243 self.pg1.remote_hosts[2].mac,
244 self.pg1.remote_hosts[2].ip4,
245 is_static=1)
246 static_arp.add_vpp_config()
Neale Rannscbe25aa2019-09-30 10:53:31 +0000247 es = [self.vapi.wait_for_event(1, "ip_neighbor_event")
248 for i in range(2)]
249 for e in es:
250 self.assertEqual(str(e.neighbor.ip_address),
251 self.pg1.remote_hosts[2].ip4)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800252
253 static_p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
254 IP(src=self.pg0.remote_ip4,
255 dst=self.pg1._remote_hosts[2].ip4) /
256 UDP(sport=1234, dport=1234) /
257 Raw())
258
259 self.pg0.add_stream(static_p)
260 self.pg_enable_capture(self.pg_interfaces)
261 self.pg_start()
262
263 rx = self.pg1.get_capture(1)
264
265 self.verify_ip(rx[0],
266 self.pg1.local_mac,
267 self.pg1.remote_hosts[2].mac,
268 self.pg0.remote_ip4,
269 self.pg1._remote_hosts[2].ip4)
270
271 #
Neale Rannscbe25aa2019-09-30 10:53:31 +0000272 # remove all the listeners
273 #
274 self.vapi.want_ip_neighbor_events(enable=0,
275 pid=os.getpid())
276 self.vapi.want_ip_neighbor_events(enable=0,
277 pid=os.getpid(),
278 sw_if_index=self.pg1.sw_if_index)
279 self.vapi.want_ip_neighbor_events(enable=0,
280 pid=os.getpid(),
281 sw_if_index=self.pg1.sw_if_index,
282 ip=self.pg1.remote_hosts[1].ip4)
283
284 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800285 # flap the link. dynamic ARPs get flush, statics don't
286 #
287 self.pg1.admin_down()
288 self.pg1.admin_up()
289
290 self.pg0.add_stream(static_p)
291 self.pg_enable_capture(self.pg_interfaces)
292 self.pg_start()
293 rx = self.pg1.get_capture(1)
294
295 self.verify_ip(rx[0],
296 self.pg1.local_mac,
297 self.pg1.remote_hosts[2].mac,
298 self.pg0.remote_ip4,
299 self.pg1._remote_hosts[2].ip4)
300
301 self.pg0.add_stream(dyn_p)
302 self.pg_enable_capture(self.pg_interfaces)
303 self.pg_start()
304
305 rx = self.pg1.get_capture(1)
306 self.verify_arp_req(rx[0],
307 self.pg1.local_mac,
308 self.pg1.local_ip4,
309 self.pg1._remote_hosts[1].ip4)
310
Neale Rannscbe25aa2019-09-30 10:53:31 +0000311 self.assertFalse(dyn_arp.query_vpp_config())
312 self.assertTrue(static_arp.query_vpp_config())
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800313 #
314 # Send an ARP request from one of the so-far unlearned remote hosts
315 #
316 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
317 src=self.pg1._remote_hosts[3].mac) /
318 ARP(op="who-has",
319 hwsrc=self.pg1._remote_hosts[3].mac,
320 pdst=self.pg1.local_ip4,
321 psrc=self.pg1._remote_hosts[3].ip4))
322
323 self.pg1.add_stream(p)
324 self.pg_enable_capture(self.pg_interfaces)
325 self.pg_start()
326
327 rx = self.pg1.get_capture(1)
328 self.verify_arp_resp(rx[0],
329 self.pg1.local_mac,
330 self.pg1._remote_hosts[3].mac,
331 self.pg1.local_ip4,
332 self.pg1._remote_hosts[3].ip4)
333
334 #
335 # VPP should have learned the mapping for the remote host
336 #
337 self.assertTrue(find_nbr(self,
338 self.pg1.sw_if_index,
339 self.pg1._remote_hosts[3].ip4))
Neale Ranns4b919a52017-03-11 05:55:21 -0800340 #
341 # Fire in an ARP request before the interface becomes IP enabled
342 #
343 self.pg2.generate_remote_hosts(4)
344
345 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
346 ARP(op="who-has",
347 hwsrc=self.pg2.remote_mac,
348 pdst=self.pg1.local_ip4,
349 psrc=self.pg2.remote_hosts[3].ip4))
Neale Ranns30d0fd42017-05-30 07:30:04 -0700350 pt = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
351 Dot1Q(vlan=0) /
352 ARP(op="who-has",
353 hwsrc=self.pg2.remote_mac,
354 pdst=self.pg1.local_ip4,
355 psrc=self.pg2.remote_hosts[3].ip4))
Neale Ranns4b919a52017-03-11 05:55:21 -0800356 self.send_and_assert_no_replies(self.pg2, p,
357 "interface not IP enabled")
358
359 #
360 # Make pg2 un-numbered to pg1
361 #
362 self.pg2.set_unnumbered(self.pg1.sw_if_index)
363
Neale Rannsac3e72c2019-10-06 01:04:26 -0700364 #
365 # test the unnumbered dump both by all interfaces and just the enabled
366 # one
367 #
Neale Ranns404d88e2018-08-08 06:37:33 -0700368 unnum = self.vapi.ip_unnumbered_dump()
Neale Rannsac3e72c2019-10-06 01:04:26 -0700369 self.assertTrue(len(unnum))
370 self.assertEqual(unnum[0].ip_sw_if_index, self.pg1.sw_if_index)
371 self.assertEqual(unnum[0].sw_if_index, self.pg2.sw_if_index)
372 unnum = self.vapi.ip_unnumbered_dump(self.pg2.sw_if_index)
373 self.assertTrue(len(unnum))
Neale Ranns404d88e2018-08-08 06:37:33 -0700374 self.assertEqual(unnum[0].ip_sw_if_index, self.pg1.sw_if_index)
375 self.assertEqual(unnum[0].sw_if_index, self.pg2.sw_if_index)
376
Neale Ranns4b919a52017-03-11 05:55:21 -0800377 #
378 # We should respond to ARP requests for the unnumbered to address
379 # once an attached route to the source is known
380 #
381 self.send_and_assert_no_replies(
382 self.pg2, p,
383 "ARP req for unnumbered address - no source")
384
385 attached_host = VppIpRoute(self, self.pg2.remote_hosts[3].ip4, 32,
386 [VppRoutePath("0.0.0.0",
387 self.pg2.sw_if_index)])
388 attached_host.add_vpp_config()
389
390 self.pg2.add_stream(p)
391 self.pg_enable_capture(self.pg_interfaces)
392 self.pg_start()
393
394 rx = self.pg2.get_capture(1)
395 self.verify_arp_resp(rx[0],
396 self.pg2.local_mac,
397 self.pg2.remote_mac,
398 self.pg1.local_ip4,
399 self.pg2.remote_hosts[3].ip4)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800400
Neale Ranns30d0fd42017-05-30 07:30:04 -0700401 self.pg2.add_stream(pt)
402 self.pg_enable_capture(self.pg_interfaces)
403 self.pg_start()
404
405 rx = self.pg2.get_capture(1)
406 self.verify_arp_resp(rx[0],
407 self.pg2.local_mac,
408 self.pg2.remote_mac,
409 self.pg1.local_ip4,
410 self.pg2.remote_hosts[3].ip4)
411
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800412 #
Neale Ranns3983ac22017-03-10 11:53:27 -0800413 # A neighbor entry that has no associated FIB-entry
414 #
415 arp_no_fib = VppNeighbor(self,
416 self.pg1.sw_if_index,
417 self.pg1.remote_hosts[4].mac,
418 self.pg1.remote_hosts[4].ip4,
419 is_no_fib_entry=1)
420 arp_no_fib.add_vpp_config()
421
422 #
423 # check we have the neighbor, but no route
424 #
425 self.assertTrue(find_nbr(self,
426 self.pg1.sw_if_index,
427 self.pg1._remote_hosts[4].ip4))
428 self.assertFalse(find_route(self,
429 self.pg1._remote_hosts[4].ip4,
430 32))
431 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800432 # pg2 is unnumbered to pg1, so we can form adjacencies out of pg2
433 # from within pg1's subnet
Neale Ranns3983ac22017-03-10 11:53:27 -0800434 #
435 arp_unnum = VppNeighbor(self,
436 self.pg2.sw_if_index,
437 self.pg1.remote_hosts[5].mac,
438 self.pg1.remote_hosts[5].ip4)
439 arp_unnum.add_vpp_config()
440
441 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
442 IP(src=self.pg0.remote_ip4,
443 dst=self.pg1._remote_hosts[5].ip4) /
444 UDP(sport=1234, dport=1234) /
445 Raw())
446
447 self.pg0.add_stream(p)
448 self.pg_enable_capture(self.pg_interfaces)
449 self.pg_start()
450
451 rx = self.pg2.get_capture(1)
452
453 self.verify_ip(rx[0],
454 self.pg2.local_mac,
455 self.pg1.remote_hosts[5].mac,
456 self.pg0.remote_ip4,
457 self.pg1._remote_hosts[5].ip4)
458
459 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800460 # ARP requests from hosts in pg1's subnet sent on pg2 are replied to
461 # with the unnumbered interface's address as the source
462 #
463 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
464 ARP(op="who-has",
465 hwsrc=self.pg2.remote_mac,
466 pdst=self.pg1.local_ip4,
467 psrc=self.pg1.remote_hosts[6].ip4))
468
469 self.pg2.add_stream(p)
470 self.pg_enable_capture(self.pg_interfaces)
471 self.pg_start()
472
473 rx = self.pg2.get_capture(1)
474 self.verify_arp_resp(rx[0],
475 self.pg2.local_mac,
476 self.pg2.remote_mac,
477 self.pg1.local_ip4,
478 self.pg1.remote_hosts[6].ip4)
479
480 #
481 # An attached host route out of pg2 for an undiscovered hosts generates
482 # an ARP request with the unnumbered address as the source
483 #
484 att_unnum = VppIpRoute(self, self.pg1.remote_hosts[7].ip4, 32,
485 [VppRoutePath("0.0.0.0",
486 self.pg2.sw_if_index)])
487 att_unnum.add_vpp_config()
488
489 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
490 IP(src=self.pg0.remote_ip4,
491 dst=self.pg1._remote_hosts[7].ip4) /
492 UDP(sport=1234, dport=1234) /
493 Raw())
494
495 self.pg0.add_stream(p)
496 self.pg_enable_capture(self.pg_interfaces)
497 self.pg_start()
498
499 rx = self.pg2.get_capture(1)
500
501 self.verify_arp_req(rx[0],
502 self.pg2.local_mac,
503 self.pg1.local_ip4,
504 self.pg1._remote_hosts[7].ip4)
505
506 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
507 ARP(op="who-has",
508 hwsrc=self.pg2.remote_mac,
509 pdst=self.pg1.local_ip4,
510 psrc=self.pg1.remote_hosts[7].ip4))
511
512 self.pg2.add_stream(p)
513 self.pg_enable_capture(self.pg_interfaces)
514 self.pg_start()
515
516 rx = self.pg2.get_capture(1)
517 self.verify_arp_resp(rx[0],
518 self.pg2.local_mac,
519 self.pg2.remote_mac,
520 self.pg1.local_ip4,
521 self.pg1.remote_hosts[7].ip4)
522
523 #
524 # An attached host route as yet unresolved out of pg2 for an
525 # undiscovered host, an ARP requests begets a response.
526 #
527 att_unnum1 = VppIpRoute(self, self.pg1.remote_hosts[8].ip4, 32,
528 [VppRoutePath("0.0.0.0",
529 self.pg2.sw_if_index)])
530 att_unnum1.add_vpp_config()
531
532 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
533 ARP(op="who-has",
534 hwsrc=self.pg2.remote_mac,
535 pdst=self.pg1.local_ip4,
536 psrc=self.pg1.remote_hosts[8].ip4))
537
538 self.pg2.add_stream(p)
539 self.pg_enable_capture(self.pg_interfaces)
540 self.pg_start()
541
542 rx = self.pg2.get_capture(1)
543 self.verify_arp_resp(rx[0],
544 self.pg2.local_mac,
545 self.pg2.remote_mac,
546 self.pg1.local_ip4,
547 self.pg1.remote_hosts[8].ip4)
548
549 #
Neale Ranns30d0fd42017-05-30 07:30:04 -0700550 # Send an ARP request from one of the so-far unlearned remote hosts
551 # with a VLAN0 tag
552 #
553 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
554 src=self.pg1._remote_hosts[9].mac) /
555 Dot1Q(vlan=0) /
556 ARP(op="who-has",
557 hwsrc=self.pg1._remote_hosts[9].mac,
558 pdst=self.pg1.local_ip4,
559 psrc=self.pg1._remote_hosts[9].ip4))
560
561 self.pg1.add_stream(p)
562 self.pg_enable_capture(self.pg_interfaces)
563 self.pg_start()
564
565 rx = self.pg1.get_capture(1)
566 self.verify_arp_resp(rx[0],
567 self.pg1.local_mac,
568 self.pg1._remote_hosts[9].mac,
569 self.pg1.local_ip4,
570 self.pg1._remote_hosts[9].ip4)
571
572 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700573 # Add a hierarchy of routes for a host in the sub-net.
Neale Rannsca193612017-06-14 06:50:08 -0700574 # Should still get an ARP resp since the cover is attached
575 #
576 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg1.remote_mac) /
577 ARP(op="who-has",
578 hwsrc=self.pg1.remote_mac,
579 pdst=self.pg1.local_ip4,
580 psrc=self.pg1.remote_hosts[10].ip4))
581
582 r1 = VppIpRoute(self, self.pg1.remote_hosts[10].ip4, 30,
583 [VppRoutePath(self.pg1.remote_hosts[10].ip4,
584 self.pg1.sw_if_index)])
585 r1.add_vpp_config()
586
587 self.pg1.add_stream(p)
588 self.pg_enable_capture(self.pg_interfaces)
589 self.pg_start()
590 rx = self.pg1.get_capture(1)
591 self.verify_arp_resp(rx[0],
592 self.pg1.local_mac,
593 self.pg1.remote_mac,
594 self.pg1.local_ip4,
595 self.pg1.remote_hosts[10].ip4)
596
597 r2 = VppIpRoute(self, self.pg1.remote_hosts[10].ip4, 32,
598 [VppRoutePath(self.pg1.remote_hosts[10].ip4,
599 self.pg1.sw_if_index)])
600 r2.add_vpp_config()
601
602 self.pg1.add_stream(p)
603 self.pg_enable_capture(self.pg_interfaces)
604 self.pg_start()
605 rx = self.pg1.get_capture(1)
606 self.verify_arp_resp(rx[0],
607 self.pg1.local_mac,
608 self.pg1.remote_mac,
609 self.pg1.local_ip4,
610 self.pg1.remote_hosts[10].ip4)
611
612 #
613 # add an ARP entry that's not on the sub-net and so whose
614 # adj-fib fails the refinement check. then send an ARP request
615 # from that source
616 #
617 a1 = VppNeighbor(self,
618 self.pg0.sw_if_index,
619 self.pg0.remote_mac,
620 "100.100.100.50")
621 a1.add_vpp_config()
622
623 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
624 ARP(op="who-has",
625 hwsrc=self.pg0.remote_mac,
626 psrc="100.100.100.50",
627 pdst=self.pg0.remote_ip4))
628 self.send_and_assert_no_replies(self.pg0, p,
629 "ARP req for from failed adj-fib")
630
631 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800632 # ERROR Cases
633 # 1 - don't respond to ARP request for address not within the
634 # interface's sub-net
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700635 # 1b - nor within the unnumbered subnet
636 # 1c - nor within the subnet of a different interface
637 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800638 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
639 ARP(op="who-has",
640 hwsrc=self.pg0.remote_mac,
641 pdst="10.10.10.3",
642 psrc=self.pg0.remote_ip4))
643 self.send_and_assert_no_replies(self.pg0, p,
644 "ARP req for non-local destination")
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700645 self.assertFalse(find_nbr(self,
646 self.pg0.sw_if_index,
647 "10.10.10.3"))
648
Neale Ranns4b919a52017-03-11 05:55:21 -0800649 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
650 ARP(op="who-has",
651 hwsrc=self.pg2.remote_mac,
652 pdst="10.10.10.3",
653 psrc=self.pg1.remote_hosts[7].ip4))
654 self.send_and_assert_no_replies(
655 self.pg0, p,
656 "ARP req for non-local destination - unnum")
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800657
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700658 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
659 ARP(op="who-has",
660 hwsrc=self.pg0.remote_mac,
661 pdst=self.pg1.local_ip4,
662 psrc=self.pg1.remote_ip4))
663 self.send_and_assert_no_replies(self.pg0, p,
664 "ARP req diff sub-net")
665 self.assertFalse(find_nbr(self,
666 self.pg0.sw_if_index,
667 self.pg1.remote_ip4))
668
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800669 #
670 # 2 - don't respond to ARP request from an address not within the
671 # interface's sub-net
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700672 # 2b - to a proxied address
673 # 2c - not within a different interface's sub-net
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800674 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
675 ARP(op="who-has",
676 hwsrc=self.pg0.remote_mac,
677 psrc="10.10.10.3",
678 pdst=self.pg0.local_ip4))
679 self.send_and_assert_no_replies(self.pg0, p,
680 "ARP req for non-local source")
Neale Ranns4b919a52017-03-11 05:55:21 -0800681 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
682 ARP(op="who-has",
683 hwsrc=self.pg2.remote_mac,
684 psrc="10.10.10.3",
685 pdst=self.pg0.local_ip4))
686 self.send_and_assert_no_replies(
687 self.pg0, p,
688 "ARP req for non-local source - unnum")
Neale Rannsca193612017-06-14 06:50:08 -0700689 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
690 ARP(op="who-has",
691 hwsrc=self.pg0.remote_mac,
692 psrc=self.pg1.remote_ip4,
693 pdst=self.pg0.local_ip4))
694 self.send_and_assert_no_replies(self.pg0, p,
695 "ARP req for non-local source 2c")
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800696
697 #
698 # 3 - don't respond to ARP request from an address that belongs to
699 # the router
700 #
701 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
702 ARP(op="who-has",
703 hwsrc=self.pg0.remote_mac,
704 psrc=self.pg0.local_ip4,
705 pdst=self.pg0.local_ip4))
706 self.send_and_assert_no_replies(self.pg0, p,
707 "ARP req for non-local source")
708
709 #
710 # 4 - don't respond to ARP requests that has mac source different
711 # from ARP request HW source
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800712 #
713 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
714 ARP(op="who-has",
715 hwsrc="00:00:00:DE:AD:BE",
716 psrc=self.pg0.remote_ip4,
717 pdst=self.pg0.local_ip4))
718 self.send_and_assert_no_replies(self.pg0, p,
719 "ARP req for non-local source")
720
721 #
zhaoqinglingb4c42cd2017-12-23 15:20:59 +0800722 # 5 - don't respond to ARP requests for address within the
723 # interface's sub-net but not the interface's address
724 #
725 self.pg0.generate_remote_hosts(2)
726 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
727 ARP(op="who-has",
728 hwsrc=self.pg0.remote_mac,
729 psrc=self.pg0.remote_hosts[0].ip4,
730 pdst=self.pg0.remote_hosts[1].ip4))
731 self.send_and_assert_no_replies(self.pg0, p,
732 "ARP req for non-local destination")
733
734 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800735 # cleanup
736 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800737 static_arp.remove_vpp_config()
Neale Ranns3983ac22017-03-10 11:53:27 -0800738 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800739
Neale Ranns4b919a52017-03-11 05:55:21 -0800740 # need this to flush the adj-fibs
741 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
742 self.pg2.admin_down()
Neale Rannsca193612017-06-14 06:50:08 -0700743 self.pg1.admin_down()
Neale Ranns4b919a52017-03-11 05:55:21 -0800744
Neale Ranns24b170a2017-08-15 05:33:11 -0700745 def test_proxy_mirror_arp(self):
746 """ Interface Mirror Proxy ARP """
747
748 #
749 # When VPP has an interface whose address is also applied to a TAP
750 # interface on the host, then VPP's TAP interface will be unnumbered
751 # to the 'real' interface and do proxy ARP from the host.
752 # the curious aspect of this setup is that ARP requests from the host
753 # will come from the VPP's own address.
754 #
755 self.pg0.generate_remote_hosts(2)
756
757 arp_req_from_me = (Ether(src=self.pg2.remote_mac,
758 dst="ff:ff:ff:ff:ff:ff") /
759 ARP(op="who-has",
760 hwsrc=self.pg2.remote_mac,
761 pdst=self.pg0.remote_hosts[1].ip4,
762 psrc=self.pg0.local_ip4))
763
764 #
765 # Configure Proxy ARP for the subnet on PG0addresses on pg0
766 #
Ole Troan5c2a2372020-11-19 16:01:23 +0100767 self.vapi.proxy_arp_add_del(proxy={'table_id': 0,
768 'low': self.pg0._local_ip4_subnet,
769 'hi': self.pg0._local_ip4_bcast},
770 is_add=1)
Neale Ranns24b170a2017-08-15 05:33:11 -0700771
772 # Make pg2 un-numbered to pg0
773 #
774 self.pg2.set_unnumbered(self.pg0.sw_if_index)
775
776 #
777 # Enable pg2 for proxy ARP
778 #
779 self.pg2.set_proxy_arp()
780
781 #
782 # Send the ARP request with an originating address that
783 # is VPP's own address
784 #
Neale Ranns240dcb22020-04-23 09:04:59 +0000785 rx = self.send_and_expect(self.pg2, [arp_req_from_me], self.pg2)
Neale Ranns24b170a2017-08-15 05:33:11 -0700786 self.verify_arp_resp(rx[0],
787 self.pg2.local_mac,
788 self.pg2.remote_mac,
789 self.pg0.remote_hosts[1].ip4,
790 self.pg0.local_ip4)
791
792 #
793 # validate we have not learned an ARP entry as a result of this
794 #
795 self.assertFalse(find_nbr(self,
796 self.pg2.sw_if_index,
797 self.pg0.local_ip4))
798
799 #
Neale Ranns240dcb22020-04-23 09:04:59 +0000800 # setup a punt redirect so packets from the uplink go to the tap
801 #
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100802 redirect = VppIpPuntRedirect(self, self.pg0.sw_if_index,
803 self.pg2.sw_if_index, self.pg0.local_ip4)
804 redirect.add_vpp_config()
Neale Ranns240dcb22020-04-23 09:04:59 +0000805
806 p_tcp = (Ether(src=self.pg0.remote_mac,
807 dst=self.pg0.local_mac,) /
808 IP(src=self.pg0.remote_ip4,
809 dst=self.pg0.local_ip4) /
810 TCP(sport=80, dport=80) /
811 Raw())
812 rx = self.send_and_expect(self.pg0, [p_tcp], self.pg2)
813
814 # there's no ARP entry so this is an ARP req
815 self.assertTrue(rx[0].haslayer(ARP))
816
817 # and ARP entry for VPP's pg0 address on the host interface
818 n1 = VppNeighbor(self,
819 self.pg2.sw_if_index,
820 self.pg2.remote_mac,
821 self.pg0.local_ip4,
822 is_no_fib_entry=True).add_vpp_config()
823 # now the packets shold forward
824 rx = self.send_and_expect(self.pg0, [p_tcp], self.pg2)
825 self.assertFalse(rx[0].haslayer(ARP))
826 self.assertEqual(rx[0][Ether].dst, self.pg2.remote_mac)
827
828 #
829 # flush the neighbor cache on the uplink
830 #
831 af = VppEnum.vl_api_address_family_t
832 self.vapi.ip_neighbor_flush(af.ADDRESS_IP4, self.pg0.sw_if_index)
833
834 # ensure we can still resolve the ARPs on the uplink
835 self.pg0.resolve_arp()
836
837 self.assertTrue(find_nbr(self,
838 self.pg0.sw_if_index,
839 self.pg0.remote_ip4))
840
841 #
Neale Ranns24b170a2017-08-15 05:33:11 -0700842 # cleanup
843 #
Ole Troan5c2a2372020-11-19 16:01:23 +0100844 self.vapi.proxy_arp_add_del(proxy={'table_id': 0,
845 'low': self.pg0._local_ip4_subnet,
846 'hi': self.pg0._local_ip4_bcast},
Neale Ranns24b170a2017-08-15 05:33:11 -0700847 is_add=0)
Jakub Grajciar2df2f752020-12-01 11:23:44 +0100848 redirect.remove_vpp_config()
Neale Ranns24b170a2017-08-15 05:33:11 -0700849
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800850 def test_proxy_arp(self):
851 """ Proxy ARP """
852
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700853 self.pg1.generate_remote_hosts(2)
854
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800855 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700856 # Proxy ARP request packets for each interface
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800857 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800858 arp_req_pg0 = (Ether(src=self.pg0.remote_mac,
859 dst="ff:ff:ff:ff:ff:ff") /
860 ARP(op="who-has",
861 hwsrc=self.pg0.remote_mac,
862 pdst="10.10.10.3",
863 psrc=self.pg0.remote_ip4))
Neale Ranns30d0fd42017-05-30 07:30:04 -0700864 arp_req_pg0_tagged = (Ether(src=self.pg0.remote_mac,
865 dst="ff:ff:ff:ff:ff:ff") /
866 Dot1Q(vlan=0) /
867 ARP(op="who-has",
868 hwsrc=self.pg0.remote_mac,
869 pdst="10.10.10.3",
870 psrc=self.pg0.remote_ip4))
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800871 arp_req_pg1 = (Ether(src=self.pg1.remote_mac,
872 dst="ff:ff:ff:ff:ff:ff") /
873 ARP(op="who-has",
874 hwsrc=self.pg1.remote_mac,
875 pdst="10.10.10.3",
876 psrc=self.pg1.remote_ip4))
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700877 arp_req_pg2 = (Ether(src=self.pg2.remote_mac,
878 dst="ff:ff:ff:ff:ff:ff") /
879 ARP(op="who-has",
880 hwsrc=self.pg2.remote_mac,
881 pdst="10.10.10.3",
882 psrc=self.pg1.remote_hosts[1].ip4))
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800883 arp_req_pg3 = (Ether(src=self.pg3.remote_mac,
884 dst="ff:ff:ff:ff:ff:ff") /
885 ARP(op="who-has",
886 hwsrc=self.pg3.remote_mac,
887 pdst="10.10.10.3",
888 psrc=self.pg3.remote_ip4))
889
890 #
891 # Configure Proxy ARP for 10.10.10.0 -> 10.10.10.124
892 #
Ole Troan5c2a2372020-11-19 16:01:23 +0100893 self.vapi.proxy_arp_add_del(proxy={'table_id': 0,
894 'low': "10.10.10.2",
895 'hi': "10.10.10.124"},
896 is_add=1)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800897
898 #
899 # No responses are sent when the interfaces are not enabled for proxy
900 # ARP
901 #
902 self.send_and_assert_no_replies(self.pg0, arp_req_pg0,
903 "ARP req from unconfigured interface")
904 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
905 "ARP req from unconfigured interface")
906
907 #
908 # Make pg2 un-numbered to pg1
909 # still won't reply.
910 #
911 self.pg2.set_unnumbered(self.pg1.sw_if_index)
912
913 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
914 "ARP req from unnumbered interface")
915
916 #
917 # Enable each interface to reply to proxy ARPs
918 #
919 for i in self.pg_interfaces:
920 i.set_proxy_arp()
921
922 #
923 # Now each of the interfaces should reply to a request to a proxied
924 # address
925 #
926 self.pg0.add_stream(arp_req_pg0)
927 self.pg_enable_capture(self.pg_interfaces)
928 self.pg_start()
929
930 rx = self.pg0.get_capture(1)
931 self.verify_arp_resp(rx[0],
932 self.pg0.local_mac,
933 self.pg0.remote_mac,
934 "10.10.10.3",
935 self.pg0.remote_ip4)
936
Neale Ranns30d0fd42017-05-30 07:30:04 -0700937 self.pg0.add_stream(arp_req_pg0_tagged)
938 self.pg_enable_capture(self.pg_interfaces)
939 self.pg_start()
940
941 rx = self.pg0.get_capture(1)
942 self.verify_arp_resp(rx[0],
943 self.pg0.local_mac,
944 self.pg0.remote_mac,
945 "10.10.10.3",
946 self.pg0.remote_ip4)
947
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800948 self.pg1.add_stream(arp_req_pg1)
949 self.pg_enable_capture(self.pg_interfaces)
950 self.pg_start()
951
952 rx = self.pg1.get_capture(1)
953 self.verify_arp_resp(rx[0],
954 self.pg1.local_mac,
955 self.pg1.remote_mac,
956 "10.10.10.3",
957 self.pg1.remote_ip4)
958
959 self.pg2.add_stream(arp_req_pg2)
960 self.pg_enable_capture(self.pg_interfaces)
961 self.pg_start()
962
963 rx = self.pg2.get_capture(1)
964 self.verify_arp_resp(rx[0],
965 self.pg2.local_mac,
966 self.pg2.remote_mac,
967 "10.10.10.3",
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700968 self.pg1.remote_hosts[1].ip4)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800969
970 #
971 # A request for an address out of the configured range
972 #
973 arp_req_pg1_hi = (Ether(src=self.pg1.remote_mac,
974 dst="ff:ff:ff:ff:ff:ff") /
975 ARP(op="who-has",
976 hwsrc=self.pg1.remote_mac,
977 pdst="10.10.10.125",
978 psrc=self.pg1.remote_ip4))
979 self.send_and_assert_no_replies(self.pg1, arp_req_pg1_hi,
980 "ARP req out of range HI")
981 arp_req_pg1_low = (Ether(src=self.pg1.remote_mac,
982 dst="ff:ff:ff:ff:ff:ff") /
983 ARP(op="who-has",
984 hwsrc=self.pg1.remote_mac,
985 pdst="10.10.10.1",
986 psrc=self.pg1.remote_ip4))
987 self.send_and_assert_no_replies(self.pg1, arp_req_pg1_low,
988 "ARP req out of range Low")
989
990 #
991 # Request for an address in the proxy range but from an interface
992 # in a different VRF
993 #
994 self.send_and_assert_no_replies(self.pg3, arp_req_pg3,
995 "ARP req from different VRF")
996
997 #
998 # Disable Each interface for proxy ARP
999 # - expect none to respond
1000 #
1001 for i in self.pg_interfaces:
1002 i.set_proxy_arp(0)
1003
1004 self.send_and_assert_no_replies(self.pg0, arp_req_pg0,
1005 "ARP req from disable")
1006 self.send_and_assert_no_replies(self.pg1, arp_req_pg1,
1007 "ARP req from disable")
1008 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
1009 "ARP req from disable")
Neale Ranns37be7362017-02-21 17:30:26 -08001010
1011 #
1012 # clean up on interface 2
1013 #
Neale Ranns4b919a52017-03-11 05:55:21 -08001014 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
Neale Ranns37be7362017-02-21 17:30:26 -08001015
1016 def test_mpls(self):
1017 """ MPLS """
1018
1019 #
1020 # Interface 2 does not yet have ip4 config
1021 #
1022 self.pg2.config_ip4()
1023 self.pg2.generate_remote_hosts(2)
1024
1025 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001026 # Add a route with out going label via an ARP unresolved next-hop
Neale Ranns37be7362017-02-21 17:30:26 -08001027 #
1028 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1029 [VppRoutePath(self.pg2.remote_hosts[1].ip4,
1030 self.pg2.sw_if_index,
1031 labels=[55])])
1032 ip_10_0_0_1.add_vpp_config()
1033
1034 #
1035 # packets should generate an ARP request
1036 #
1037 p = (Ether(src=self.pg0.remote_mac,
1038 dst=self.pg0.local_mac) /
1039 IP(src=self.pg0.remote_ip4, dst="10.0.0.1") /
1040 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001041 Raw(b'\xa5' * 100))
Neale Ranns37be7362017-02-21 17:30:26 -08001042
1043 self.pg0.add_stream(p)
1044 self.pg_enable_capture(self.pg_interfaces)
1045 self.pg_start()
1046
1047 rx = self.pg2.get_capture(1)
1048 self.verify_arp_req(rx[0],
1049 self.pg2.local_mac,
1050 self.pg2.local_ip4,
1051 self.pg2._remote_hosts[1].ip4)
1052
1053 #
1054 # now resolve the neighbours
1055 #
1056 self.pg2.configure_ipv4_neighbors()
1057
1058 #
1059 # Now packet should be properly MPLS encapped.
1060 # This verifies that MPLS link-type adjacencies are completed
1061 # when the ARP entry resolves
1062 #
1063 self.pg0.add_stream(p)
1064 self.pg_enable_capture(self.pg_interfaces)
1065 self.pg_start()
1066
1067 rx = self.pg2.get_capture(1)
1068 self.verify_ip_o_mpls(rx[0],
1069 self.pg2.local_mac,
1070 self.pg2.remote_hosts[1].mac,
1071 55,
1072 self.pg0.remote_ip4,
1073 "10.0.0.1")
Neale Ranns4b919a52017-03-11 05:55:21 -08001074 self.pg2.unconfig_ip4()
Neale Ranns37be7362017-02-21 17:30:26 -08001075
Matthew Smithcb9ab472017-05-16 21:35:56 -05001076 def test_arp_vrrp(self):
1077 """ ARP reply with VRRP virtual src hw addr """
1078
1079 #
1080 # IP packet destined for pg1 remote host arrives on pg0 resulting
1081 # in an ARP request for the address of the remote host on pg1
1082 #
1083 p0 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1084 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1085 UDP(sport=1234, dport=1234) /
1086 Raw())
1087
Neale Ranns37029302018-08-10 05:30:06 -07001088 rx1 = self.send_and_expect(self.pg0, [p0], self.pg1)
Matthew Smithcb9ab472017-05-16 21:35:56 -05001089
1090 self.verify_arp_req(rx1[0],
1091 self.pg1.local_mac,
1092 self.pg1.local_ip4,
1093 self.pg1.remote_ip4)
1094
1095 #
1096 # ARP reply for address of pg1 remote host arrives on pg1 with
1097 # the hw src addr set to a value in the VRRP IPv4 range of
1098 # MAC addresses
1099 #
1100 p1 = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1101 ARP(op="is-at", hwdst=self.pg1.local_mac,
1102 hwsrc="00:00:5e:00:01:09", pdst=self.pg1.local_ip4,
1103 psrc=self.pg1.remote_ip4))
1104
Neale Ranns37029302018-08-10 05:30:06 -07001105 self.send_and_assert_no_replies(self.pg1, p1, "ARP reply")
Matthew Smithcb9ab472017-05-16 21:35:56 -05001106
1107 #
1108 # IP packet destined for pg1 remote host arrives on pg0 again.
1109 # VPP should have an ARP entry for that address now and the packet
1110 # should be sent out pg1.
1111 #
Neale Ranns37029302018-08-10 05:30:06 -07001112 rx1 = self.send_and_expect(self.pg0, [p0], self.pg1)
Matthew Smithcb9ab472017-05-16 21:35:56 -05001113
1114 self.verify_ip(rx1[0],
1115 self.pg1.local_mac,
1116 "00:00:5e:00:01:09",
1117 self.pg0.remote_ip4,
1118 self.pg1.remote_ip4)
1119
1120 self.pg1.admin_down()
1121 self.pg1.admin_up()
1122
Neale Rannsdcd6d622017-05-26 02:59:16 -07001123 def test_arp_duplicates(self):
1124 """ ARP Duplicates"""
1125
1126 #
1127 # Generate some hosts on the LAN
1128 #
1129 self.pg1.generate_remote_hosts(3)
1130
1131 #
1132 # Add host 1 on pg1 and pg2
1133 #
1134 arp_pg1 = VppNeighbor(self,
1135 self.pg1.sw_if_index,
1136 self.pg1.remote_hosts[1].mac,
1137 self.pg1.remote_hosts[1].ip4)
1138 arp_pg1.add_vpp_config()
1139 arp_pg2 = VppNeighbor(self,
1140 self.pg2.sw_if_index,
1141 self.pg2.remote_mac,
1142 self.pg1.remote_hosts[1].ip4)
1143 arp_pg2.add_vpp_config()
1144
1145 #
1146 # IP packet destined for pg1 remote host arrives on pg1 again.
1147 #
1148 p = (Ether(dst=self.pg0.local_mac,
1149 src=self.pg0.remote_mac) /
1150 IP(src=self.pg0.remote_ip4,
1151 dst=self.pg1.remote_hosts[1].ip4) /
1152 UDP(sport=1234, dport=1234) /
1153 Raw())
1154
1155 self.pg0.add_stream(p)
1156 self.pg_enable_capture(self.pg_interfaces)
1157 self.pg_start()
1158
1159 rx1 = self.pg1.get_capture(1)
1160
1161 self.verify_ip(rx1[0],
1162 self.pg1.local_mac,
1163 self.pg1.remote_hosts[1].mac,
1164 self.pg0.remote_ip4,
1165 self.pg1.remote_hosts[1].ip4)
1166
1167 #
1168 # remove the duplicate on pg1
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001169 # packet stream should generate ARPs out of pg1
Neale Rannsdcd6d622017-05-26 02:59:16 -07001170 #
1171 arp_pg1.remove_vpp_config()
1172
1173 self.pg0.add_stream(p)
1174 self.pg_enable_capture(self.pg_interfaces)
1175 self.pg_start()
1176
1177 rx1 = self.pg1.get_capture(1)
1178
1179 self.verify_arp_req(rx1[0],
1180 self.pg1.local_mac,
1181 self.pg1.local_ip4,
1182 self.pg1.remote_hosts[1].ip4)
1183
1184 #
1185 # Add it back
1186 #
1187 arp_pg1.add_vpp_config()
1188
1189 self.pg0.add_stream(p)
1190 self.pg_enable_capture(self.pg_interfaces)
1191 self.pg_start()
1192
1193 rx1 = self.pg1.get_capture(1)
1194
1195 self.verify_ip(rx1[0],
1196 self.pg1.local_mac,
1197 self.pg1.remote_hosts[1].mac,
1198 self.pg0.remote_ip4,
1199 self.pg1.remote_hosts[1].ip4)
1200
Neale Ranns15002542017-09-10 04:39:11 -07001201 def test_arp_static(self):
1202 """ ARP Static"""
1203 self.pg2.generate_remote_hosts(3)
1204
1205 #
1206 # Add a static ARP entry
1207 #
1208 static_arp = VppNeighbor(self,
1209 self.pg2.sw_if_index,
1210 self.pg2.remote_hosts[1].mac,
1211 self.pg2.remote_hosts[1].ip4,
1212 is_static=1)
1213 static_arp.add_vpp_config()
1214
1215 #
1216 # Add the connected prefix to the interface
1217 #
1218 self.pg2.config_ip4()
1219
1220 #
1221 # We should now find the adj-fib
1222 #
1223 self.assertTrue(find_nbr(self,
1224 self.pg2.sw_if_index,
1225 self.pg2.remote_hosts[1].ip4,
1226 is_static=1))
1227 self.assertTrue(find_route(self,
1228 self.pg2.remote_hosts[1].ip4,
1229 32))
1230
1231 #
1232 # remove the connected
1233 #
1234 self.pg2.unconfig_ip4()
1235
1236 #
1237 # put the interface into table 1
1238 #
1239 self.pg2.set_table_ip4(1)
1240
1241 #
1242 # configure the same connected and expect to find the
1243 # adj fib in the new table
1244 #
1245 self.pg2.config_ip4()
1246 self.assertTrue(find_route(self,
1247 self.pg2.remote_hosts[1].ip4,
1248 32,
1249 table_id=1))
1250
1251 #
1252 # clean-up
1253 #
1254 self.pg2.unconfig_ip4()
Neale Rannscbe25aa2019-09-30 10:53:31 +00001255 static_arp.remove_vpp_config()
Neale Ranns15002542017-09-10 04:39:11 -07001256 self.pg2.set_table_ip4(0)
1257
Vladimir Isaevb2f44bd2020-07-16 17:05:18 +03001258 def test_arp_static_replace_dynamic_same_mac(self):
1259 """ ARP Static can replace Dynamic (same mac) """
1260 self.pg2.generate_remote_hosts(1)
1261
1262 dyn_arp = VppNeighbor(self,
1263 self.pg2.sw_if_index,
1264 self.pg2.remote_hosts[0].mac,
1265 self.pg2.remote_hosts[0].ip4)
1266 static_arp = VppNeighbor(self,
1267 self.pg2.sw_if_index,
1268 self.pg2.remote_hosts[0].mac,
1269 self.pg2.remote_hosts[0].ip4,
1270 is_static=1)
1271
1272 #
1273 # Add a dynamic ARP entry
1274 #
1275 dyn_arp.add_vpp_config()
1276
1277 #
1278 # We should find the dynamic nbr
1279 #
1280 self.assertFalse(find_nbr(self,
1281 self.pg2.sw_if_index,
1282 self.pg2.remote_hosts[0].ip4,
1283 is_static=1))
1284 self.assertTrue(find_nbr(self,
1285 self.pg2.sw_if_index,
1286 self.pg2.remote_hosts[0].ip4,
1287 is_static=0,
1288 mac=self.pg2.remote_hosts[0].mac))
1289
1290 #
1291 # Add a static ARP entry with the same mac
1292 #
1293 static_arp.add_vpp_config()
1294
1295 #
1296 # We should now find the static nbr with the same mac
1297 #
1298 self.assertFalse(find_nbr(self,
1299 self.pg2.sw_if_index,
1300 self.pg2.remote_hosts[0].ip4,
1301 is_static=0))
1302 self.assertTrue(find_nbr(self,
1303 self.pg2.sw_if_index,
1304 self.pg2.remote_hosts[0].ip4,
1305 is_static=1,
1306 mac=self.pg2.remote_hosts[0].mac))
1307
1308 #
1309 # clean-up
1310 #
1311 static_arp.remove_vpp_config()
1312
1313 def test_arp_static_replace_dynamic_diff_mac(self):
1314 """ ARP Static can replace Dynamic (diff mac) """
1315 self.pg2.generate_remote_hosts(2)
1316
1317 dyn_arp = VppNeighbor(self,
1318 self.pg2.sw_if_index,
1319 self.pg2.remote_hosts[0].mac,
1320 self.pg2.remote_hosts[0].ip4)
1321 static_arp = VppNeighbor(self,
1322 self.pg2.sw_if_index,
1323 self.pg2.remote_hosts[1].mac,
1324 self.pg2.remote_hosts[0].ip4,
1325 is_static=1)
1326
1327 #
1328 # Add a dynamic ARP entry
1329 #
1330 dyn_arp.add_vpp_config()
1331
1332 #
1333 # We should find the dynamic nbr
1334 #
1335 self.assertFalse(find_nbr(self,
1336 self.pg2.sw_if_index,
1337 self.pg2.remote_hosts[0].ip4,
1338 is_static=1))
1339 self.assertTrue(find_nbr(self,
1340 self.pg2.sw_if_index,
1341 self.pg2.remote_hosts[0].ip4,
1342 is_static=0,
1343 mac=self.pg2.remote_hosts[0].mac))
1344
1345 #
1346 # Add a static ARP entry with a changed mac
1347 #
1348 static_arp.add_vpp_config()
1349
1350 #
1351 # We should now find the static nbr with a changed mac
1352 #
1353 self.assertFalse(find_nbr(self,
1354 self.pg2.sw_if_index,
1355 self.pg2.remote_hosts[0].ip4,
1356 is_static=0))
1357 self.assertTrue(find_nbr(self,
1358 self.pg2.sw_if_index,
1359 self.pg2.remote_hosts[0].ip4,
1360 is_static=1,
1361 mac=self.pg2.remote_hosts[1].mac))
1362
1363 #
1364 # clean-up
1365 #
1366 static_arp.remove_vpp_config()
1367
Neale Rannsc819fc62018-02-16 02:44:05 -08001368 def test_arp_incomplete(self):
1369 """ ARP Incomplete"""
1370 self.pg1.generate_remote_hosts(3)
1371
1372 p0 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1373 IP(src=self.pg0.remote_ip4,
1374 dst=self.pg1.remote_hosts[1].ip4) /
1375 UDP(sport=1234, dport=1234) /
1376 Raw())
1377 p1 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1378 IP(src=self.pg0.remote_ip4,
1379 dst=self.pg1.remote_hosts[2].ip4) /
1380 UDP(sport=1234, dport=1234) /
1381 Raw())
1382
1383 #
1384 # a packet to an unresolved destination generates an ARP request
1385 #
1386 rx = self.send_and_expect(self.pg0, [p0], self.pg1)
1387 self.verify_arp_req(rx[0],
1388 self.pg1.local_mac,
1389 self.pg1.local_ip4,
1390 self.pg1._remote_hosts[1].ip4)
1391
1392 #
1393 # add a neighbour for remote host 1
1394 #
1395 static_arp = VppNeighbor(self,
1396 self.pg1.sw_if_index,
1397 self.pg1.remote_hosts[1].mac,
1398 self.pg1.remote_hosts[1].ip4,
1399 is_static=1)
1400 static_arp.add_vpp_config()
1401
1402 #
1403 # change the interface's MAC
1404 #
Neale Rannsc819fc62018-02-16 02:44:05 -08001405 self.vapi.sw_interface_set_mac_address(self.pg1.sw_if_index,
Neale Ranns77f91622020-11-23 16:25:27 +00001406 "00:00:00:33:33:33")
Neale Rannsc819fc62018-02-16 02:44:05 -08001407
1408 #
1409 # now ARP requests come from the new source mac
1410 #
1411 rx = self.send_and_expect(self.pg0, [p1], self.pg1)
1412 self.verify_arp_req(rx[0],
1413 "00:00:00:33:33:33",
1414 self.pg1.local_ip4,
1415 self.pg1._remote_hosts[2].ip4)
1416
1417 #
1418 # packets to the resolved host also have the new source mac
1419 #
1420 rx = self.send_and_expect(self.pg0, [p0], self.pg1)
1421 self.verify_ip(rx[0],
1422 "00:00:00:33:33:33",
1423 self.pg1.remote_hosts[1].mac,
1424 self.pg0.remote_ip4,
1425 self.pg1.remote_hosts[1].ip4)
1426
1427 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001428 # set the mac address on the interface that does not have a
Neale Rannsc819fc62018-02-16 02:44:05 -08001429 # configured subnet and thus no glean
1430 #
1431 self.vapi.sw_interface_set_mac_address(self.pg2.sw_if_index,
Neale Ranns77f91622020-11-23 16:25:27 +00001432 "00:00:00:33:33:33")
Neale Rannsc819fc62018-02-16 02:44:05 -08001433
Neale Ranns59ae61e2018-06-07 18:09:49 -07001434 def test_garp(self):
1435 """ GARP """
1436
1437 #
1438 # Generate some hosts on the LAN
1439 #
1440 self.pg1.generate_remote_hosts(4)
Neale Ranns22eefd72020-09-23 11:25:21 +00001441 self.pg2.generate_remote_hosts(4)
Neale Ranns59ae61e2018-06-07 18:09:49 -07001442
1443 #
1444 # And an ARP entry
1445 #
1446 arp = VppNeighbor(self,
1447 self.pg1.sw_if_index,
1448 self.pg1.remote_hosts[1].mac,
1449 self.pg1.remote_hosts[1].ip4)
1450 arp.add_vpp_config()
1451
1452 self.assertTrue(find_nbr(self,
1453 self.pg1.sw_if_index,
1454 self.pg1.remote_hosts[1].ip4,
1455 mac=self.pg1.remote_hosts[1].mac))
1456
1457 #
1458 # Send a GARP (request) to swap the host 1's address to that of host 2
1459 #
1460 p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1461 src=self.pg1.remote_hosts[2].mac) /
1462 ARP(op="who-has",
1463 hwdst=self.pg1.local_mac,
1464 hwsrc=self.pg1.remote_hosts[2].mac,
1465 pdst=self.pg1.remote_hosts[1].ip4,
1466 psrc=self.pg1.remote_hosts[1].ip4))
1467
1468 self.pg1.add_stream(p1)
1469 self.pg_enable_capture(self.pg_interfaces)
1470 self.pg_start()
1471
1472 self.assertTrue(find_nbr(self,
1473 self.pg1.sw_if_index,
1474 self.pg1.remote_hosts[1].ip4,
1475 mac=self.pg1.remote_hosts[2].mac))
1476
1477 #
1478 # Send a GARP (reply) to swap the host 1's address to that of host 3
1479 #
1480 p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1481 src=self.pg1.remote_hosts[3].mac) /
1482 ARP(op="is-at",
1483 hwdst=self.pg1.local_mac,
1484 hwsrc=self.pg1.remote_hosts[3].mac,
1485 pdst=self.pg1.remote_hosts[1].ip4,
1486 psrc=self.pg1.remote_hosts[1].ip4))
1487
1488 self.pg1.add_stream(p1)
1489 self.pg_enable_capture(self.pg_interfaces)
1490 self.pg_start()
1491
1492 self.assertTrue(find_nbr(self,
1493 self.pg1.sw_if_index,
1494 self.pg1.remote_hosts[1].ip4,
1495 mac=self.pg1.remote_hosts[3].mac))
1496
1497 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001498 # GARPs (request nor replies) for host we don't know yet
Neale Ranns59ae61e2018-06-07 18:09:49 -07001499 # don't result in new neighbour entries
1500 #
1501 p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1502 src=self.pg1.remote_hosts[3].mac) /
1503 ARP(op="who-has",
1504 hwdst=self.pg1.local_mac,
1505 hwsrc=self.pg1.remote_hosts[3].mac,
1506 pdst=self.pg1.remote_hosts[2].ip4,
1507 psrc=self.pg1.remote_hosts[2].ip4))
1508
1509 self.pg1.add_stream(p1)
1510 self.pg_enable_capture(self.pg_interfaces)
1511 self.pg_start()
1512
1513 self.assertFalse(find_nbr(self,
1514 self.pg1.sw_if_index,
1515 self.pg1.remote_hosts[2].ip4))
1516
1517 p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1518 src=self.pg1.remote_hosts[3].mac) /
1519 ARP(op="is-at",
1520 hwdst=self.pg1.local_mac,
1521 hwsrc=self.pg1.remote_hosts[3].mac,
1522 pdst=self.pg1.remote_hosts[2].ip4,
1523 psrc=self.pg1.remote_hosts[2].ip4))
1524
1525 self.pg1.add_stream(p1)
1526 self.pg_enable_capture(self.pg_interfaces)
1527 self.pg_start()
1528
1529 self.assertFalse(find_nbr(self,
1530 self.pg1.sw_if_index,
1531 self.pg1.remote_hosts[2].ip4))
1532
Neale Ranns22eefd72020-09-23 11:25:21 +00001533 #
1534 # IP address in different subnets are not learnt
1535 #
1536 self.pg2.configure_ipv4_neighbors()
1537
1538 for op in ["is-at", "who-has"]:
1539 p1 = [(Ether(dst="ff:ff:ff:ff:ff:ff",
1540 src=self.pg2.remote_hosts[1].mac) /
1541 ARP(op=op,
1542 hwdst=self.pg2.local_mac,
1543 hwsrc=self.pg2.remote_hosts[1].mac,
1544 pdst=self.pg2.remote_hosts[1].ip4,
1545 psrc=self.pg2.remote_hosts[1].ip4)),
1546 (Ether(dst="ff:ff:ff:ff:ff:ff",
1547 src=self.pg2.remote_hosts[1].mac) /
1548 ARP(op=op,
1549 hwdst="ff:ff:ff:ff:ff:ff",
1550 hwsrc=self.pg2.remote_hosts[1].mac,
1551 pdst=self.pg2.remote_hosts[1].ip4,
1552 psrc=self.pg2.remote_hosts[1].ip4))]
1553
1554 self.send_and_assert_no_replies(self.pg1, p1)
1555 self.assertFalse(find_nbr(self,
1556 self.pg1.sw_if_index,
1557 self.pg2.remote_hosts[1].ip4))
1558
1559 # they are all dropped because the subnet's don't match
1560 self.assertEqual(4, self.statistics.get_err_counter(
1561 "/err/arp-reply/IP4 destination address not local to subnet"))
1562
Neale Ranns77f91622020-11-23 16:25:27 +00001563 def test_arp_incomplete2(self):
Neale Ranns14260392018-09-28 05:00:57 -07001564 """ Incomplete Entries """
Neale Rannsc8352bc2018-08-29 10:23:58 -07001565
1566 #
Neale Rannscd35e532018-08-31 02:51:45 -07001567 # ensure that we throttle the ARP and ND requests
Neale Rannsc8352bc2018-08-29 10:23:58 -07001568 #
1569 self.pg0.generate_remote_hosts(2)
1570
Neale Rannscd35e532018-08-31 02:51:45 -07001571 #
1572 # IPv4/ARP
1573 #
Neale Rannsc8352bc2018-08-29 10:23:58 -07001574 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1575 [VppRoutePath(self.pg0.remote_hosts[1].ip4,
Neale Rannscd35e532018-08-31 02:51:45 -07001576 self.pg0.sw_if_index)])
Neale Rannsc8352bc2018-08-29 10:23:58 -07001577 ip_10_0_0_1.add_vpp_config()
1578
1579 p1 = (Ether(dst=self.pg1.local_mac,
1580 src=self.pg1.remote_mac) /
1581 IP(src=self.pg1.remote_ip4,
1582 dst="10.0.0.1") /
1583 UDP(sport=1234, dport=1234) /
1584 Raw())
1585
1586 self.pg1.add_stream(p1 * 257)
1587 self.pg_enable_capture(self.pg_interfaces)
1588 self.pg_start()
1589 rx = self.pg0._get_capture(1)
1590
1591 #
1592 # how many we get is going to be dependent on the time for packet
1593 # processing but it should be small
1594 #
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08001595 self.assertLess(len(rx), 64)
Neale Rannsc8352bc2018-08-29 10:23:58 -07001596
Neale Rannscd35e532018-08-31 02:51:45 -07001597 #
1598 # IPv6/ND
1599 #
1600 ip_10_1 = VppIpRoute(self, "10::1", 128,
1601 [VppRoutePath(self.pg0.remote_hosts[1].ip6,
1602 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07001603 proto=DpoProto.DPO_PROTO_IP6)])
Neale Rannscd35e532018-08-31 02:51:45 -07001604 ip_10_1.add_vpp_config()
1605
1606 p1 = (Ether(dst=self.pg1.local_mac,
1607 src=self.pg1.remote_mac) /
1608 IPv6(src=self.pg1.remote_ip6,
1609 dst="10::1") /
1610 UDP(sport=1234, dport=1234) /
1611 Raw())
1612
1613 self.pg1.add_stream(p1 * 257)
1614 self.pg_enable_capture(self.pg_interfaces)
1615 self.pg_start()
1616 rx = self.pg0._get_capture(1)
1617
1618 #
1619 # how many we get is going to be dependent on the time for packet
1620 # processing but it should be small
1621 #
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08001622 self.assertLess(len(rx), 64)
Neale Rannscd35e532018-08-31 02:51:45 -07001623
Neale Ranns7425f922019-01-23 00:36:16 -08001624 def test_arp_forus(self):
1625 """ ARP for for-us """
1626
1627 #
1628 # Test that VPP responds with ARP requests to addresses that
1629 # are connected and local routes.
1630 # Use one of the 'remote' addresses in the subnet as a local address
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001631 # The intention of this route is that it then acts like a secondary
Neale Ranns7425f922019-01-23 00:36:16 -08001632 # address added to an interface
1633 #
1634 self.pg0.generate_remote_hosts(2)
1635
Neale Ranns097fa662018-05-01 05:17:55 -07001636 forus = VppIpRoute(
1637 self, self.pg0.remote_hosts[1].ip4, 32,
1638 [VppRoutePath("0.0.0.0",
1639 self.pg0.sw_if_index,
1640 type=FibPathType.FIB_PATH_TYPE_LOCAL)])
Neale Ranns7425f922019-01-23 00:36:16 -08001641 forus.add_vpp_config()
1642
1643 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
1644 src=self.pg0.remote_mac) /
1645 ARP(op="who-has",
1646 hwdst=self.pg0.local_mac,
1647 hwsrc=self.pg0.remote_mac,
1648 pdst=self.pg0.remote_hosts[1].ip4,
1649 psrc=self.pg0.remote_ip4))
1650
1651 rx = self.send_and_expect(self.pg0, [p], self.pg0)
1652
1653 self.verify_arp_resp(rx[0],
1654 self.pg0.local_mac,
1655 self.pg0.remote_mac,
1656 self.pg0.remote_hosts[1].ip4,
1657 self.pg0.remote_ip4)
1658
Neale Rannsfca3c6a2019-12-31 03:49:34 +00001659 def test_arp_table_swap(self):
1660 #
1661 # Generate some hosts on the LAN
1662 #
1663 N_NBRS = 4
1664 self.pg1.generate_remote_hosts(N_NBRS)
1665
1666 for n in range(N_NBRS):
1667 # a route thru each neighbour
1668 VppIpRoute(self, "10.0.0.%d" % n, 32,
1669 [VppRoutePath(self.pg1.remote_hosts[n].ip4,
1670 self.pg1.sw_if_index)]).add_vpp_config()
1671
1672 # resolve each neighbour
1673 p1 = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1674 ARP(op="is-at", hwdst=self.pg1.local_mac,
1675 hwsrc="00:00:5e:00:01:09", pdst=self.pg1.local_ip4,
1676 psrc=self.pg1.remote_hosts[n].ip4))
1677
1678 self.send_and_assert_no_replies(self.pg1, p1, "ARP reply")
1679
1680 self.logger.info(self.vapi.cli("sh ip neighbors"))
1681
1682 #
1683 # swap the table pg1 is in
1684 #
1685 table = VppIpTable(self, 100).add_vpp_config()
1686
1687 self.pg1.unconfig_ip4()
1688 self.pg1.set_table_ip4(100)
1689 self.pg1.config_ip4()
1690
1691 #
1692 # all neighbours are cleared
1693 #
1694 for n in range(N_NBRS):
1695 self.assertFalse(find_nbr(self,
1696 self.pg1.sw_if_index,
1697 self.pg1.remote_hosts[n].ip4))
1698
1699 #
1700 # packets to all neighbours generate ARP requests
1701 #
1702 for n in range(N_NBRS):
1703 # a route thru each neighbour
1704 VppIpRoute(self, "10.0.0.%d" % n, 32,
1705 [VppRoutePath(self.pg1.remote_hosts[n].ip4,
1706 self.pg1.sw_if_index)],
1707 table_id=100).add_vpp_config()
1708
1709 p = (Ether(src=self.pg1.remote_hosts[n].mac,
1710 dst=self.pg1.local_mac) /
1711 IP(src=self.pg1.remote_hosts[n].ip4,
1712 dst="10.0.0.%d" % n) /
1713 Raw(b'0x5' * 100))
1714 rxs = self.send_and_expect(self.pg1, [p], self.pg1)
1715 for rx in rxs:
1716 self.verify_arp_req(rx,
1717 self.pg1.local_mac,
1718 self.pg1.local_ip4,
1719 self.pg1.remote_hosts[n].ip4)
1720
1721 self.pg1.unconfig_ip4()
1722 self.pg1.set_table_ip4(0)
1723
Neale Rannsdcd6d622017-05-26 02:59:16 -07001724
Neale Ranns14260392018-09-28 05:00:57 -07001725class NeighborStatsTestCase(VppTestCase):
Neale Ranns37029302018-08-10 05:30:06 -07001726 """ ARP/ND Counters """
Neale Ranns14260392018-09-28 05:00:57 -07001727
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001728 @classmethod
1729 def setUpClass(cls):
1730 super(NeighborStatsTestCase, cls).setUpClass()
1731
1732 @classmethod
1733 def tearDownClass(cls):
1734 super(NeighborStatsTestCase, cls).tearDownClass()
1735
Neale Ranns14260392018-09-28 05:00:57 -07001736 def setUp(self):
1737 super(NeighborStatsTestCase, self).setUp()
1738
1739 self.create_pg_interfaces(range(2))
1740
1741 # pg0 configured with ip4 and 6 addresses used for input
1742 # pg1 configured with ip4 and 6 addresses used for output
1743 # pg2 is unnumbered to pg0
1744 for i in self.pg_interfaces:
1745 i.admin_up()
1746 i.config_ip4()
1747 i.config_ip6()
1748 i.resolve_arp()
1749 i.resolve_ndp()
1750
1751 def tearDown(self):
1752 super(NeighborStatsTestCase, self).tearDown()
1753
1754 for i in self.pg_interfaces:
1755 i.unconfig_ip4()
1756 i.unconfig_ip6()
1757 i.admin_down()
1758
1759 def test_arp_stats(self):
1760 """ ARP Counters """
1761
1762 self.vapi.cli("adj counters enable")
1763 self.pg1.generate_remote_hosts(2)
1764
1765 arp1 = VppNeighbor(self,
1766 self.pg1.sw_if_index,
1767 self.pg1.remote_hosts[0].mac,
1768 self.pg1.remote_hosts[0].ip4)
1769 arp1.add_vpp_config()
1770 arp2 = VppNeighbor(self,
1771 self.pg1.sw_if_index,
1772 self.pg1.remote_hosts[1].mac,
1773 self.pg1.remote_hosts[1].ip4)
1774 arp2.add_vpp_config()
1775
1776 p1 = (Ether(dst=self.pg0.local_mac,
1777 src=self.pg0.remote_mac) /
1778 IP(src=self.pg0.remote_ip4,
1779 dst=self.pg1.remote_hosts[0].ip4) /
1780 UDP(sport=1234, dport=1234) /
1781 Raw())
1782 p2 = (Ether(dst=self.pg0.local_mac,
1783 src=self.pg0.remote_mac) /
1784 IP(src=self.pg0.remote_ip4,
1785 dst=self.pg1.remote_hosts[1].ip4) /
1786 UDP(sport=1234, dport=1234) /
1787 Raw())
1788
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001789 rx = self.send_and_expect(self.pg0, p1 * NUM_PKTS, self.pg1)
1790 rx = self.send_and_expect(self.pg0, p2 * NUM_PKTS, self.pg1)
Neale Ranns14260392018-09-28 05:00:57 -07001791
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001792 self.assertEqual(NUM_PKTS, arp1.get_stats()['packets'])
1793 self.assertEqual(NUM_PKTS, arp2.get_stats()['packets'])
Neale Ranns14260392018-09-28 05:00:57 -07001794
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001795 rx = self.send_and_expect(self.pg0, p1 * NUM_PKTS, self.pg1)
1796 self.assertEqual(NUM_PKTS*2, arp1.get_stats()['packets'])
Neale Ranns14260392018-09-28 05:00:57 -07001797
1798 def test_nd_stats(self):
1799 """ ND Counters """
1800
1801 self.vapi.cli("adj counters enable")
1802 self.pg0.generate_remote_hosts(3)
1803
1804 nd1 = VppNeighbor(self,
1805 self.pg0.sw_if_index,
1806 self.pg0.remote_hosts[1].mac,
Neale Ranns37029302018-08-10 05:30:06 -07001807 self.pg0.remote_hosts[1].ip6)
Neale Ranns14260392018-09-28 05:00:57 -07001808 nd1.add_vpp_config()
1809 nd2 = VppNeighbor(self,
1810 self.pg0.sw_if_index,
1811 self.pg0.remote_hosts[2].mac,
Neale Ranns37029302018-08-10 05:30:06 -07001812 self.pg0.remote_hosts[2].ip6)
Neale Ranns14260392018-09-28 05:00:57 -07001813 nd2.add_vpp_config()
1814
1815 p1 = (Ether(dst=self.pg1.local_mac,
1816 src=self.pg1.remote_mac) /
1817 IPv6(src=self.pg1.remote_ip6,
1818 dst=self.pg0.remote_hosts[1].ip6) /
1819 UDP(sport=1234, dport=1234) /
1820 Raw())
1821 p2 = (Ether(dst=self.pg1.local_mac,
1822 src=self.pg1.remote_mac) /
1823 IPv6(src=self.pg1.remote_ip6,
1824 dst=self.pg0.remote_hosts[2].ip6) /
1825 UDP(sport=1234, dport=1234) /
1826 Raw())
1827
1828 rx = self.send_and_expect(self.pg1, p1 * 16, self.pg0)
1829 rx = self.send_and_expect(self.pg1, p2 * 16, self.pg0)
1830
1831 self.assertEqual(16, nd1.get_stats()['packets'])
1832 self.assertEqual(16, nd2.get_stats()['packets'])
1833
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001834 rx = self.send_and_expect(self.pg1, p1 * NUM_PKTS, self.pg0)
1835 self.assertEqual(NUM_PKTS+16, nd1.get_stats()['packets'])
Neale Ranns14260392018-09-28 05:00:57 -07001836
1837
Neale Rannscbe25aa2019-09-30 10:53:31 +00001838class NeighborAgeTestCase(VppTestCase):
1839 """ ARP/ND Aging """
1840
1841 @classmethod
1842 def setUpClass(cls):
1843 super(NeighborAgeTestCase, cls).setUpClass()
1844
1845 @classmethod
1846 def tearDownClass(cls):
1847 super(NeighborAgeTestCase, cls).tearDownClass()
1848
1849 def setUp(self):
1850 super(NeighborAgeTestCase, self).setUp()
1851
1852 self.create_pg_interfaces(range(1))
1853
1854 # pg0 configured with ip4 and 6 addresses used for input
1855 # pg1 configured with ip4 and 6 addresses used for output
1856 # pg2 is unnumbered to pg0
1857 for i in self.pg_interfaces:
1858 i.admin_up()
1859 i.config_ip4()
1860 i.config_ip6()
1861 i.resolve_arp()
1862 i.resolve_ndp()
1863
1864 def tearDown(self):
1865 super(NeighborAgeTestCase, self).tearDown()
1866
1867 for i in self.pg_interfaces:
1868 i.unconfig_ip4()
1869 i.unconfig_ip6()
1870 i.admin_down()
1871
1872 def wait_for_no_nbr(self, intf, address,
1873 n_tries=50, s_time=1):
1874 while (n_tries):
1875 if not find_nbr(self, intf, address):
1876 return True
1877 n_tries = n_tries - 1
1878 self.sleep(s_time)
1879
1880 return False
1881
1882 def verify_arp_req(self, rx, smac, sip, dip):
1883 ether = rx[Ether]
1884 self.assertEqual(ether.dst, "ff:ff:ff:ff:ff:ff")
1885 self.assertEqual(ether.src, smac)
1886
1887 arp = rx[ARP]
1888 self.assertEqual(arp.hwtype, 1)
1889 self.assertEqual(arp.ptype, 0x800)
1890 self.assertEqual(arp.hwlen, 6)
1891 self.assertEqual(arp.plen, 4)
1892 self.assertEqual(arp.op, arp_opts["who-has"])
1893 self.assertEqual(arp.hwsrc, smac)
1894 self.assertEqual(arp.hwdst, "00:00:00:00:00:00")
1895 self.assertEqual(arp.psrc, sip)
1896 self.assertEqual(arp.pdst, dip)
1897
1898 def test_age(self):
1899 """ Aging/Recycle """
1900
1901 self.vapi.cli("set logging unthrottle 0")
1902 self.vapi.cli("set logging size %d" % 0xffff)
1903
1904 self.pg0.generate_remote_hosts(201)
1905
1906 vaf = VppEnum.vl_api_address_family_t
1907
1908 #
1909 # start listening on all interfaces
1910 #
1911 self.pg_enable_capture(self.pg_interfaces)
1912
1913 #
1914 # Set the neighbor configuration:
1915 # limi = 200
Vladimir Isaev1284f8c2020-02-18 15:26:12 +03001916 # age = 0 seconds
Neale Rannscbe25aa2019-09-30 10:53:31 +00001917 # recycle = false
1918 #
1919 self.vapi.ip_neighbor_config(af=vaf.ADDRESS_IP4,
1920 max_number=200,
1921 max_age=0,
1922 recycle=False)
1923
1924 self.vapi.cli("sh ip neighbor-config")
1925
1926 # add the 198 neighbours that should pass (-1 for one created in setup)
1927 for ii in range(200):
1928 VppNeighbor(self,
1929 self.pg0.sw_if_index,
1930 self.pg0.remote_hosts[ii].mac,
1931 self.pg0.remote_hosts[ii].ip4).add_vpp_config()
1932
1933 # one more neighbor over the limit should fail
1934 with self.vapi.assert_negative_api_retval():
1935 VppNeighbor(self,
1936 self.pg0.sw_if_index,
1937 self.pg0.remote_hosts[200].mac,
1938 self.pg0.remote_hosts[200].ip4).add_vpp_config()
1939
1940 #
1941 # change the config to allow recycling the old neighbors
1942 #
1943 self.vapi.ip_neighbor_config(af=vaf.ADDRESS_IP4,
1944 max_number=200,
1945 max_age=0,
1946 recycle=True)
1947
1948 # now new additions are allowed
1949 VppNeighbor(self,
1950 self.pg0.sw_if_index,
1951 self.pg0.remote_hosts[200].mac,
1952 self.pg0.remote_hosts[200].ip4).add_vpp_config()
1953
1954 # add the first neighbor we configured has been re-used
1955 self.assertFalse(find_nbr(self,
1956 self.pg0.sw_if_index,
1957 self.pg0.remote_hosts[0].ip4))
1958 self.assertTrue(find_nbr(self,
1959 self.pg0.sw_if_index,
1960 self.pg0.remote_hosts[200].ip4))
1961
1962 #
1963 # change the config to age old neighbors
1964 #
1965 self.vapi.ip_neighbor_config(af=vaf.ADDRESS_IP4,
1966 max_number=200,
1967 max_age=2,
1968 recycle=True)
1969
1970 self.vapi.cli("sh ip4 neighbor-sorted")
1971
1972 #
1973 # expect probes from all these ARP entries as they age
1974 # 3 probes for each neighbor 3*200 = 600
1975 rxs = self.pg0.get_capture(600, timeout=8)
1976
1977 for ii in range(3):
1978 for jj in range(200):
1979 rx = rxs[ii*200 + jj]
1980 # rx.show()
1981
1982 #
1983 # 3 probes sent then 1 more second to see if a reply comes, before
1984 # they age out
1985 #
1986 for jj in range(1, 201):
1987 self.wait_for_no_nbr(self.pg0.sw_if_index,
1988 self.pg0.remote_hosts[jj].ip4)
1989
1990 self.assertFalse(self.vapi.ip_neighbor_dump(sw_if_index=0xffffffff,
1991 af=vaf.ADDRESS_IP4))
1992
1993 #
Vladimir Isaev1284f8c2020-02-18 15:26:12 +03001994 # load up some neighbours again with 2s aging enabled
1995 # they should be removed after 10s (2s age + 4s for probes + gap)
Neale Ranns4ac36bc2020-11-20 13:05:59 +00001996 # check for the add and remove events
Vladimir Isaev1284f8c2020-02-18 15:26:12 +03001997 #
Neale Ranns4ac36bc2020-11-20 13:05:59 +00001998 enum = VppEnum.vl_api_ip_neighbor_event_flags_t
1999
2000 self.vapi.want_ip_neighbor_events_v2(enable=1)
Vladimir Isaev1284f8c2020-02-18 15:26:12 +03002001 for ii in range(10):
2002 VppNeighbor(self,
2003 self.pg0.sw_if_index,
2004 self.pg0.remote_hosts[ii].mac,
2005 self.pg0.remote_hosts[ii].ip4).add_vpp_config()
Neale Ranns4ac36bc2020-11-20 13:05:59 +00002006
2007 e = self.vapi.wait_for_event(1, "ip_neighbor_event_v2")
2008 self.assertEqual(e.flags,
2009 enum.IP_NEIGHBOR_API_EVENT_FLAG_ADDED)
2010 self.assertEqual(str(e.neighbor.ip_address),
2011 self.pg0.remote_hosts[ii].ip4)
2012 self.assertEqual(e.neighbor.mac_address,
2013 self.pg0.remote_hosts[ii].mac)
2014
Vladimir Isaev1284f8c2020-02-18 15:26:12 +03002015 self.sleep(10)
2016 self.assertFalse(self.vapi.ip_neighbor_dump(sw_if_index=0xffffffff,
2017 af=vaf.ADDRESS_IP4))
2018
Neale Ranns4ac36bc2020-11-20 13:05:59 +00002019 evs = []
2020 for ii in range(10):
2021 e = self.vapi.wait_for_event(1, "ip_neighbor_event_v2")
2022 self.assertEqual(e.flags,
2023 enum.IP_NEIGHBOR_API_EVENT_FLAG_REMOVED)
2024 evs.append(e)
2025
2026 # check we got the correct mac/ip pairs - done separately
2027 # because we don't care about the order the remove notifications
2028 # arrive
2029 for ii in range(10):
2030 found = False
2031 mac = self.pg0.remote_hosts[ii].mac
2032 ip = self.pg0.remote_hosts[ii].ip4
2033
2034 for e in evs:
2035 if (e.neighbor.mac_address == mac and
2036 str(e.neighbor.ip_address) == ip):
2037 found = True
2038 break
2039 self.assertTrue(found)
2040
Vladimir Isaev1284f8c2020-02-18 15:26:12 +03002041 #
2042 # check if we can set age and recycle with empty neighbor list
2043 #
2044 self.vapi.ip_neighbor_config(af=vaf.ADDRESS_IP4,
2045 max_number=200,
2046 max_age=1000,
2047 recycle=True)
2048
2049 #
Neale Rannscbe25aa2019-09-30 10:53:31 +00002050 # load up some neighbours again, then disable the aging
2051 # they should still be there in 10 seconds time
2052 #
2053 for ii in range(10):
2054 VppNeighbor(self,
2055 self.pg0.sw_if_index,
2056 self.pg0.remote_hosts[ii].mac,
2057 self.pg0.remote_hosts[ii].ip4).add_vpp_config()
2058 self.vapi.ip_neighbor_config(af=vaf.ADDRESS_IP4,
2059 max_number=200,
2060 max_age=0,
2061 recycle=False)
2062
2063 self.sleep(10)
2064 self.assertTrue(find_nbr(self,
2065 self.pg0.sw_if_index,
2066 self.pg0.remote_hosts[0].ip4))
2067
2068
Neale Rannsc87fbb42020-04-02 17:08:28 +00002069class NeighborReplaceTestCase(VppTestCase):
2070 """ ARP/ND Replacement """
2071
2072 @classmethod
2073 def setUpClass(cls):
2074 super(NeighborReplaceTestCase, cls).setUpClass()
2075
2076 @classmethod
2077 def tearDownClass(cls):
2078 super(NeighborReplaceTestCase, cls).tearDownClass()
2079
2080 def setUp(self):
2081 super(NeighborReplaceTestCase, self).setUp()
2082
2083 self.create_pg_interfaces(range(4))
2084
2085 # pg0 configured with ip4 and 6 addresses used for input
2086 # pg1 configured with ip4 and 6 addresses used for output
2087 # pg2 is unnumbered to pg0
2088 for i in self.pg_interfaces:
2089 i.admin_up()
2090 i.config_ip4()
2091 i.config_ip6()
2092 i.resolve_arp()
2093 i.resolve_ndp()
2094
2095 def tearDown(self):
2096 super(NeighborReplaceTestCase, self).tearDown()
2097
2098 for i in self.pg_interfaces:
2099 i.unconfig_ip4()
2100 i.unconfig_ip6()
2101 i.admin_down()
2102
2103 def test_replace(self):
2104 """ replace """
2105
2106 N_HOSTS = 16
2107
2108 for i in self.pg_interfaces:
2109 i.generate_remote_hosts(N_HOSTS)
2110 i.configure_ipv4_neighbors()
2111 i.configure_ipv6_neighbors()
2112
2113 # replace them all
2114 self.vapi.ip_neighbor_replace_begin()
2115 self.vapi.ip_neighbor_replace_end()
2116
2117 for i in self.pg_interfaces:
2118 for h in range(N_HOSTS):
2119 self.assertFalse(find_nbr(self,
2120 self.pg0.sw_if_index,
2121 self.pg0.remote_hosts[h].ip4))
2122 self.assertFalse(find_nbr(self,
2123 self.pg0.sw_if_index,
2124 self.pg0.remote_hosts[h].ip6))
2125
2126 #
2127 # and them all back via the API
2128 #
2129 for i in self.pg_interfaces:
2130 for h in range(N_HOSTS):
2131 VppNeighbor(self,
2132 i.sw_if_index,
2133 i.remote_hosts[h].mac,
2134 i.remote_hosts[h].ip4).add_vpp_config()
2135 VppNeighbor(self,
2136 i.sw_if_index,
2137 i.remote_hosts[h].mac,
2138 i.remote_hosts[h].ip6).add_vpp_config()
2139
2140 #
2141 # begin the replacement again, this time touch some
2142 # the neighbours on pg1 so they are not deleted
2143 #
2144 self.vapi.ip_neighbor_replace_begin()
2145
2146 # update from the API all neighbours on pg1
2147 for h in range(N_HOSTS):
2148 VppNeighbor(self,
2149 self.pg1.sw_if_index,
2150 self.pg1.remote_hosts[h].mac,
2151 self.pg1.remote_hosts[h].ip4).add_vpp_config()
2152 VppNeighbor(self,
2153 self.pg1.sw_if_index,
2154 self.pg1.remote_hosts[h].mac,
2155 self.pg1.remote_hosts[h].ip6).add_vpp_config()
2156
2157 # update from the data-plane all neighbours on pg3
2158 self.pg3.configure_ipv4_neighbors()
2159 self.pg3.configure_ipv6_neighbors()
2160
2161 # complete the replacement
2162 self.logger.info(self.vapi.cli("sh ip neighbors"))
2163 self.vapi.ip_neighbor_replace_end()
2164
2165 for i in self.pg_interfaces:
2166 if i == self.pg1 or i == self.pg3:
2167 # neighbours on pg1 and pg3 are still present
2168 for h in range(N_HOSTS):
2169 self.assertTrue(find_nbr(self,
2170 i.sw_if_index,
2171 i.remote_hosts[h].ip4))
2172 self.assertTrue(find_nbr(self,
2173 i.sw_if_index,
2174 i.remote_hosts[h].ip6))
2175 else:
2176 # all other neighbours are toast
2177 for h in range(N_HOSTS):
2178 self.assertFalse(find_nbr(self,
2179 i.sw_if_index,
2180 i.remote_hosts[h].ip4))
2181 self.assertFalse(find_nbr(self,
2182 i.sw_if_index,
2183 i.remote_hosts[h].ip6))
2184
2185
Neale Ranns240dcb22020-04-23 09:04:59 +00002186class NeighborFlush(VppTestCase):
2187 """ Neighbor Flush """
2188
2189 @classmethod
2190 def setUpClass(cls):
2191 super(NeighborFlush, cls).setUpClass()
2192
2193 @classmethod
2194 def tearDownClass(cls):
2195 super(NeighborFlush, cls).tearDownClass()
2196
2197 def setUp(self):
2198 super(NeighborFlush, self).setUp()
2199
2200 self.create_pg_interfaces(range(2))
2201
2202 for i in self.pg_interfaces:
2203 i.admin_up()
2204 i.config_ip4()
2205 i.config_ip6()
2206 i.resolve_arp()
2207 i.resolve_ndp()
2208
2209 def tearDown(self):
2210 super(NeighborFlush, self).tearDown()
2211
2212 for i in self.pg_interfaces:
2213 i.unconfig_ip4()
2214 i.unconfig_ip6()
2215 i.admin_down()
2216
2217 def test_flush(self):
2218 """ Neighbour Flush """
2219
2220 e = VppEnum
2221 nf = e.vl_api_ip_neighbor_flags_t
2222 af = e.vl_api_address_family_t
2223 N_HOSTS = 16
2224 static = [False, True]
2225 self.pg0.generate_remote_hosts(N_HOSTS)
2226 self.pg1.generate_remote_hosts(N_HOSTS)
2227
2228 for s in static:
2229 # a few v4 and v6 dynamic neoghbors
2230 for n in range(N_HOSTS):
2231 VppNeighbor(self,
2232 self.pg0.sw_if_index,
2233 self.pg0.remote_hosts[n].mac,
2234 self.pg0.remote_hosts[n].ip4,
2235 is_static=s).add_vpp_config()
2236 VppNeighbor(self,
2237 self.pg1.sw_if_index,
2238 self.pg1.remote_hosts[n].mac,
2239 self.pg1.remote_hosts[n].ip6,
2240 is_static=s).add_vpp_config()
2241
2242 # flush the interfaces individually
2243 self.vapi.ip_neighbor_flush(af.ADDRESS_IP4, self.pg0.sw_if_index)
2244
2245 # check we haven't flushed that which we shouldn't
2246 for n in range(N_HOSTS):
2247 self.assertTrue(find_nbr(self,
2248 self.pg1.sw_if_index,
2249 self.pg1.remote_hosts[n].ip6,
2250 is_static=s))
2251
2252 self.vapi.ip_neighbor_flush(af.ADDRESS_IP6, self.pg1.sw_if_index)
2253
2254 for n in range(N_HOSTS):
2255 self.assertFalse(find_nbr(self,
2256 self.pg0.sw_if_index,
2257 self.pg0.remote_hosts[n].ip4))
2258 self.assertFalse(find_nbr(self,
2259 self.pg1.sw_if_index,
2260 self.pg1.remote_hosts[n].ip6))
2261
2262 # add the nieghbours back
2263 for n in range(N_HOSTS):
2264 VppNeighbor(self,
2265 self.pg0.sw_if_index,
2266 self.pg0.remote_hosts[n].mac,
2267 self.pg0.remote_hosts[n].ip4,
2268 is_static=s).add_vpp_config()
2269 VppNeighbor(self,
2270 self.pg1.sw_if_index,
2271 self.pg1.remote_hosts[n].mac,
2272 self.pg1.remote_hosts[n].ip6,
2273 is_static=s).add_vpp_config()
2274
2275 self.logger.info(self.vapi.cli("sh ip neighbor"))
2276
2277 # flush both interfaces at the same time
2278 self.vapi.ip_neighbor_flush(af.ADDRESS_IP6, 0xffffffff)
2279
2280 # check we haven't flushed that which we shouldn't
2281 for n in range(N_HOSTS):
2282 self.assertTrue(find_nbr(self,
2283 self.pg0.sw_if_index,
2284 self.pg0.remote_hosts[n].ip4,
2285 is_static=s))
2286
2287 self.vapi.ip_neighbor_flush(af.ADDRESS_IP4, 0xffffffff)
2288
2289 for n in range(N_HOSTS):
2290 self.assertFalse(find_nbr(self,
2291 self.pg0.sw_if_index,
2292 self.pg0.remote_hosts[n].ip4))
2293 self.assertFalse(find_nbr(self,
2294 self.pg1.sw_if_index,
2295 self.pg1.remote_hosts[n].ip6))
2296
2297
Neale Ranns37be7362017-02-21 17:30:26 -08002298if __name__ == '__main__':
2299 unittest.main(testRunner=VppTestRunner)