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