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