blob: 9d91f031571ba866b1c648b346811cac9f561403 [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
Neale Ranns404d88e2018-08-08 06:37:33 -0700299 unnum = self.vapi.ip_unnumbered_dump()
300 self.assertEqual(unnum[0].ip_sw_if_index, self.pg1.sw_if_index)
301 self.assertEqual(unnum[0].sw_if_index, self.pg2.sw_if_index)
302
Neale Ranns4b919a52017-03-11 05:55:21 -0800303 #
304 # We should respond to ARP requests for the unnumbered to address
305 # once an attached route to the source is known
306 #
307 self.send_and_assert_no_replies(
308 self.pg2, p,
309 "ARP req for unnumbered address - no source")
310
311 attached_host = VppIpRoute(self, self.pg2.remote_hosts[3].ip4, 32,
312 [VppRoutePath("0.0.0.0",
313 self.pg2.sw_if_index)])
314 attached_host.add_vpp_config()
315
316 self.pg2.add_stream(p)
317 self.pg_enable_capture(self.pg_interfaces)
318 self.pg_start()
319
320 rx = self.pg2.get_capture(1)
321 self.verify_arp_resp(rx[0],
322 self.pg2.local_mac,
323 self.pg2.remote_mac,
324 self.pg1.local_ip4,
325 self.pg2.remote_hosts[3].ip4)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800326
Neale Ranns30d0fd42017-05-30 07:30:04 -0700327 self.pg2.add_stream(pt)
328 self.pg_enable_capture(self.pg_interfaces)
329 self.pg_start()
330
331 rx = self.pg2.get_capture(1)
332 self.verify_arp_resp(rx[0],
333 self.pg2.local_mac,
334 self.pg2.remote_mac,
335 self.pg1.local_ip4,
336 self.pg2.remote_hosts[3].ip4)
337
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800338 #
Neale Ranns3983ac22017-03-10 11:53:27 -0800339 # A neighbor entry that has no associated FIB-entry
340 #
341 arp_no_fib = VppNeighbor(self,
342 self.pg1.sw_if_index,
343 self.pg1.remote_hosts[4].mac,
344 self.pg1.remote_hosts[4].ip4,
345 is_no_fib_entry=1)
346 arp_no_fib.add_vpp_config()
347
348 #
349 # check we have the neighbor, but no route
350 #
351 self.assertTrue(find_nbr(self,
352 self.pg1.sw_if_index,
353 self.pg1._remote_hosts[4].ip4))
354 self.assertFalse(find_route(self,
355 self.pg1._remote_hosts[4].ip4,
356 32))
357 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800358 # pg2 is unnumbered to pg1, so we can form adjacencies out of pg2
359 # from within pg1's subnet
Neale Ranns3983ac22017-03-10 11:53:27 -0800360 #
361 arp_unnum = VppNeighbor(self,
362 self.pg2.sw_if_index,
363 self.pg1.remote_hosts[5].mac,
364 self.pg1.remote_hosts[5].ip4)
365 arp_unnum.add_vpp_config()
366
367 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
368 IP(src=self.pg0.remote_ip4,
369 dst=self.pg1._remote_hosts[5].ip4) /
370 UDP(sport=1234, dport=1234) /
371 Raw())
372
373 self.pg0.add_stream(p)
374 self.pg_enable_capture(self.pg_interfaces)
375 self.pg_start()
376
377 rx = self.pg2.get_capture(1)
378
379 self.verify_ip(rx[0],
380 self.pg2.local_mac,
381 self.pg1.remote_hosts[5].mac,
382 self.pg0.remote_ip4,
383 self.pg1._remote_hosts[5].ip4)
384
385 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800386 # ARP requests from hosts in pg1's subnet sent on pg2 are replied to
387 # with the unnumbered interface's address as the source
388 #
389 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
390 ARP(op="who-has",
391 hwsrc=self.pg2.remote_mac,
392 pdst=self.pg1.local_ip4,
393 psrc=self.pg1.remote_hosts[6].ip4))
394
395 self.pg2.add_stream(p)
396 self.pg_enable_capture(self.pg_interfaces)
397 self.pg_start()
398
399 rx = self.pg2.get_capture(1)
400 self.verify_arp_resp(rx[0],
401 self.pg2.local_mac,
402 self.pg2.remote_mac,
403 self.pg1.local_ip4,
404 self.pg1.remote_hosts[6].ip4)
405
406 #
407 # An attached host route out of pg2 for an undiscovered hosts generates
408 # an ARP request with the unnumbered address as the source
409 #
410 att_unnum = VppIpRoute(self, self.pg1.remote_hosts[7].ip4, 32,
411 [VppRoutePath("0.0.0.0",
412 self.pg2.sw_if_index)])
413 att_unnum.add_vpp_config()
414
415 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
416 IP(src=self.pg0.remote_ip4,
417 dst=self.pg1._remote_hosts[7].ip4) /
418 UDP(sport=1234, dport=1234) /
419 Raw())
420
421 self.pg0.add_stream(p)
422 self.pg_enable_capture(self.pg_interfaces)
423 self.pg_start()
424
425 rx = self.pg2.get_capture(1)
426
427 self.verify_arp_req(rx[0],
428 self.pg2.local_mac,
429 self.pg1.local_ip4,
430 self.pg1._remote_hosts[7].ip4)
431
432 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
433 ARP(op="who-has",
434 hwsrc=self.pg2.remote_mac,
435 pdst=self.pg1.local_ip4,
436 psrc=self.pg1.remote_hosts[7].ip4))
437
438 self.pg2.add_stream(p)
439 self.pg_enable_capture(self.pg_interfaces)
440 self.pg_start()
441
442 rx = self.pg2.get_capture(1)
443 self.verify_arp_resp(rx[0],
444 self.pg2.local_mac,
445 self.pg2.remote_mac,
446 self.pg1.local_ip4,
447 self.pg1.remote_hosts[7].ip4)
448
449 #
450 # An attached host route as yet unresolved out of pg2 for an
451 # undiscovered host, an ARP requests begets a response.
452 #
453 att_unnum1 = VppIpRoute(self, self.pg1.remote_hosts[8].ip4, 32,
454 [VppRoutePath("0.0.0.0",
455 self.pg2.sw_if_index)])
456 att_unnum1.add_vpp_config()
457
458 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
459 ARP(op="who-has",
460 hwsrc=self.pg2.remote_mac,
461 pdst=self.pg1.local_ip4,
462 psrc=self.pg1.remote_hosts[8].ip4))
463
464 self.pg2.add_stream(p)
465 self.pg_enable_capture(self.pg_interfaces)
466 self.pg_start()
467
468 rx = self.pg2.get_capture(1)
469 self.verify_arp_resp(rx[0],
470 self.pg2.local_mac,
471 self.pg2.remote_mac,
472 self.pg1.local_ip4,
473 self.pg1.remote_hosts[8].ip4)
474
475 #
Neale Ranns30d0fd42017-05-30 07:30:04 -0700476 # Send an ARP request from one of the so-far unlearned remote hosts
477 # with a VLAN0 tag
478 #
479 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
480 src=self.pg1._remote_hosts[9].mac) /
481 Dot1Q(vlan=0) /
482 ARP(op="who-has",
483 hwsrc=self.pg1._remote_hosts[9].mac,
484 pdst=self.pg1.local_ip4,
485 psrc=self.pg1._remote_hosts[9].ip4))
486
487 self.pg1.add_stream(p)
488 self.pg_enable_capture(self.pg_interfaces)
489 self.pg_start()
490
491 rx = self.pg1.get_capture(1)
492 self.verify_arp_resp(rx[0],
493 self.pg1.local_mac,
494 self.pg1._remote_hosts[9].mac,
495 self.pg1.local_ip4,
496 self.pg1._remote_hosts[9].ip4)
497
498 #
Neale Rannsca193612017-06-14 06:50:08 -0700499 # Add a hierachy of routes for a host in the sub-net.
500 # Should still get an ARP resp since the cover is attached
501 #
502 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg1.remote_mac) /
503 ARP(op="who-has",
504 hwsrc=self.pg1.remote_mac,
505 pdst=self.pg1.local_ip4,
506 psrc=self.pg1.remote_hosts[10].ip4))
507
508 r1 = VppIpRoute(self, self.pg1.remote_hosts[10].ip4, 30,
509 [VppRoutePath(self.pg1.remote_hosts[10].ip4,
510 self.pg1.sw_if_index)])
511 r1.add_vpp_config()
512
513 self.pg1.add_stream(p)
514 self.pg_enable_capture(self.pg_interfaces)
515 self.pg_start()
516 rx = self.pg1.get_capture(1)
517 self.verify_arp_resp(rx[0],
518 self.pg1.local_mac,
519 self.pg1.remote_mac,
520 self.pg1.local_ip4,
521 self.pg1.remote_hosts[10].ip4)
522
523 r2 = VppIpRoute(self, self.pg1.remote_hosts[10].ip4, 32,
524 [VppRoutePath(self.pg1.remote_hosts[10].ip4,
525 self.pg1.sw_if_index)])
526 r2.add_vpp_config()
527
528 self.pg1.add_stream(p)
529 self.pg_enable_capture(self.pg_interfaces)
530 self.pg_start()
531 rx = self.pg1.get_capture(1)
532 self.verify_arp_resp(rx[0],
533 self.pg1.local_mac,
534 self.pg1.remote_mac,
535 self.pg1.local_ip4,
536 self.pg1.remote_hosts[10].ip4)
537
538 #
539 # add an ARP entry that's not on the sub-net and so whose
540 # adj-fib fails the refinement check. then send an ARP request
541 # from that source
542 #
543 a1 = VppNeighbor(self,
544 self.pg0.sw_if_index,
545 self.pg0.remote_mac,
546 "100.100.100.50")
547 a1.add_vpp_config()
548
549 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
550 ARP(op="who-has",
551 hwsrc=self.pg0.remote_mac,
552 psrc="100.100.100.50",
553 pdst=self.pg0.remote_ip4))
554 self.send_and_assert_no_replies(self.pg0, p,
555 "ARP req for from failed adj-fib")
556
557 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800558 # ERROR Cases
559 # 1 - don't respond to ARP request for address not within the
560 # interface's sub-net
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700561 # 1b - nor within the unnumbered subnet
562 # 1c - nor within the subnet of a different interface
563 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800564 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
565 ARP(op="who-has",
566 hwsrc=self.pg0.remote_mac,
567 pdst="10.10.10.3",
568 psrc=self.pg0.remote_ip4))
569 self.send_and_assert_no_replies(self.pg0, p,
570 "ARP req for non-local destination")
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700571 self.assertFalse(find_nbr(self,
572 self.pg0.sw_if_index,
573 "10.10.10.3"))
574
Neale Ranns4b919a52017-03-11 05:55:21 -0800575 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
576 ARP(op="who-has",
577 hwsrc=self.pg2.remote_mac,
578 pdst="10.10.10.3",
579 psrc=self.pg1.remote_hosts[7].ip4))
580 self.send_and_assert_no_replies(
581 self.pg0, p,
582 "ARP req for non-local destination - unnum")
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800583
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700584 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
585 ARP(op="who-has",
586 hwsrc=self.pg0.remote_mac,
587 pdst=self.pg1.local_ip4,
588 psrc=self.pg1.remote_ip4))
589 self.send_and_assert_no_replies(self.pg0, p,
590 "ARP req diff sub-net")
591 self.assertFalse(find_nbr(self,
592 self.pg0.sw_if_index,
593 self.pg1.remote_ip4))
594
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800595 #
596 # 2 - don't respond to ARP request from an address not within the
597 # interface's sub-net
Neale Rannsca193612017-06-14 06:50:08 -0700598 # 2b - to a prxied address
599 # 2c - not within a differents interface's sub-net
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800600 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
601 ARP(op="who-has",
602 hwsrc=self.pg0.remote_mac,
603 psrc="10.10.10.3",
604 pdst=self.pg0.local_ip4))
605 self.send_and_assert_no_replies(self.pg0, p,
606 "ARP req for non-local source")
Neale Ranns4b919a52017-03-11 05:55:21 -0800607 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
608 ARP(op="who-has",
609 hwsrc=self.pg2.remote_mac,
610 psrc="10.10.10.3",
611 pdst=self.pg0.local_ip4))
612 self.send_and_assert_no_replies(
613 self.pg0, p,
614 "ARP req for non-local source - unnum")
Neale Rannsca193612017-06-14 06:50:08 -0700615 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
616 ARP(op="who-has",
617 hwsrc=self.pg0.remote_mac,
618 psrc=self.pg1.remote_ip4,
619 pdst=self.pg0.local_ip4))
620 self.send_and_assert_no_replies(self.pg0, p,
621 "ARP req for non-local source 2c")
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800622
623 #
624 # 3 - don't respond to ARP request from an address that belongs to
625 # the router
626 #
627 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
628 ARP(op="who-has",
629 hwsrc=self.pg0.remote_mac,
630 psrc=self.pg0.local_ip4,
631 pdst=self.pg0.local_ip4))
632 self.send_and_assert_no_replies(self.pg0, p,
633 "ARP req for non-local source")
634
635 #
636 # 4 - don't respond to ARP requests that has mac source different
637 # from ARP request HW source
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800638 #
639 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
640 ARP(op="who-has",
641 hwsrc="00:00:00:DE:AD:BE",
642 psrc=self.pg0.remote_ip4,
643 pdst=self.pg0.local_ip4))
644 self.send_and_assert_no_replies(self.pg0, p,
645 "ARP req for non-local source")
646
647 #
zhaoqinglingb4c42cd2017-12-23 15:20:59 +0800648 # 5 - don't respond to ARP requests for address within the
649 # interface's sub-net but not the interface's address
650 #
651 self.pg0.generate_remote_hosts(2)
652 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
653 ARP(op="who-has",
654 hwsrc=self.pg0.remote_mac,
655 psrc=self.pg0.remote_hosts[0].ip4,
656 pdst=self.pg0.remote_hosts[1].ip4))
657 self.send_and_assert_no_replies(self.pg0, p,
658 "ARP req for non-local destination")
659
660 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800661 # cleanup
662 #
663 dyn_arp.remove_vpp_config()
664 static_arp.remove_vpp_config()
Neale Ranns3983ac22017-03-10 11:53:27 -0800665 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800666
Neale Ranns4b919a52017-03-11 05:55:21 -0800667 # need this to flush the adj-fibs
668 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
669 self.pg2.admin_down()
Neale Rannsca193612017-06-14 06:50:08 -0700670 self.pg1.admin_down()
Neale Ranns4b919a52017-03-11 05:55:21 -0800671
Neale Ranns24b170a2017-08-15 05:33:11 -0700672 def test_proxy_mirror_arp(self):
673 """ Interface Mirror Proxy ARP """
674
675 #
676 # When VPP has an interface whose address is also applied to a TAP
677 # interface on the host, then VPP's TAP interface will be unnumbered
678 # to the 'real' interface and do proxy ARP from the host.
679 # the curious aspect of this setup is that ARP requests from the host
680 # will come from the VPP's own address.
681 #
682 self.pg0.generate_remote_hosts(2)
683
684 arp_req_from_me = (Ether(src=self.pg2.remote_mac,
685 dst="ff:ff:ff:ff:ff:ff") /
686 ARP(op="who-has",
687 hwsrc=self.pg2.remote_mac,
688 pdst=self.pg0.remote_hosts[1].ip4,
689 psrc=self.pg0.local_ip4))
690
691 #
692 # Configure Proxy ARP for the subnet on PG0addresses on pg0
693 #
694 self.vapi.proxy_arp_add_del(self.pg0._local_ip4n_subnet,
695 self.pg0._local_ip4n_bcast)
696
697 # Make pg2 un-numbered to pg0
698 #
699 self.pg2.set_unnumbered(self.pg0.sw_if_index)
700
701 #
702 # Enable pg2 for proxy ARP
703 #
704 self.pg2.set_proxy_arp()
705
706 #
707 # Send the ARP request with an originating address that
708 # is VPP's own address
709 #
710 self.pg2.add_stream(arp_req_from_me)
711 self.pg_enable_capture(self.pg_interfaces)
712 self.pg_start()
713
714 rx = self.pg2.get_capture(1)
715 self.verify_arp_resp(rx[0],
716 self.pg2.local_mac,
717 self.pg2.remote_mac,
718 self.pg0.remote_hosts[1].ip4,
719 self.pg0.local_ip4)
720
721 #
722 # validate we have not learned an ARP entry as a result of this
723 #
724 self.assertFalse(find_nbr(self,
725 self.pg2.sw_if_index,
726 self.pg0.local_ip4))
727
728 #
729 # cleanup
730 #
731 self.pg2.set_proxy_arp(0)
732 self.vapi.proxy_arp_add_del(self.pg0._local_ip4n_subnet,
733 self.pg0._local_ip4n_bcast,
734 is_add=0)
735
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800736 def test_proxy_arp(self):
737 """ Proxy ARP """
738
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700739 self.pg1.generate_remote_hosts(2)
740
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800741 #
742 # Proxy ARP rewquest packets for each interface
743 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800744 arp_req_pg0 = (Ether(src=self.pg0.remote_mac,
745 dst="ff:ff:ff:ff:ff:ff") /
746 ARP(op="who-has",
747 hwsrc=self.pg0.remote_mac,
748 pdst="10.10.10.3",
749 psrc=self.pg0.remote_ip4))
Neale Ranns30d0fd42017-05-30 07:30:04 -0700750 arp_req_pg0_tagged = (Ether(src=self.pg0.remote_mac,
751 dst="ff:ff:ff:ff:ff:ff") /
752 Dot1Q(vlan=0) /
753 ARP(op="who-has",
754 hwsrc=self.pg0.remote_mac,
755 pdst="10.10.10.3",
756 psrc=self.pg0.remote_ip4))
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800757 arp_req_pg1 = (Ether(src=self.pg1.remote_mac,
758 dst="ff:ff:ff:ff:ff:ff") /
759 ARP(op="who-has",
760 hwsrc=self.pg1.remote_mac,
761 pdst="10.10.10.3",
762 psrc=self.pg1.remote_ip4))
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700763 arp_req_pg2 = (Ether(src=self.pg2.remote_mac,
764 dst="ff:ff:ff:ff:ff:ff") /
765 ARP(op="who-has",
766 hwsrc=self.pg2.remote_mac,
767 pdst="10.10.10.3",
768 psrc=self.pg1.remote_hosts[1].ip4))
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800769 arp_req_pg3 = (Ether(src=self.pg3.remote_mac,
770 dst="ff:ff:ff:ff:ff:ff") /
771 ARP(op="who-has",
772 hwsrc=self.pg3.remote_mac,
773 pdst="10.10.10.3",
774 psrc=self.pg3.remote_ip4))
775
776 #
777 # Configure Proxy ARP for 10.10.10.0 -> 10.10.10.124
778 #
779 self.vapi.proxy_arp_add_del(inet_pton(AF_INET, "10.10.10.2"),
780 inet_pton(AF_INET, "10.10.10.124"))
781
782 #
783 # No responses are sent when the interfaces are not enabled for proxy
784 # ARP
785 #
786 self.send_and_assert_no_replies(self.pg0, arp_req_pg0,
787 "ARP req from unconfigured interface")
788 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
789 "ARP req from unconfigured interface")
790
791 #
792 # Make pg2 un-numbered to pg1
793 # still won't reply.
794 #
795 self.pg2.set_unnumbered(self.pg1.sw_if_index)
796
797 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
798 "ARP req from unnumbered interface")
799
800 #
801 # Enable each interface to reply to proxy ARPs
802 #
803 for i in self.pg_interfaces:
804 i.set_proxy_arp()
805
806 #
807 # Now each of the interfaces should reply to a request to a proxied
808 # address
809 #
810 self.pg0.add_stream(arp_req_pg0)
811 self.pg_enable_capture(self.pg_interfaces)
812 self.pg_start()
813
814 rx = self.pg0.get_capture(1)
815 self.verify_arp_resp(rx[0],
816 self.pg0.local_mac,
817 self.pg0.remote_mac,
818 "10.10.10.3",
819 self.pg0.remote_ip4)
820
Neale Ranns30d0fd42017-05-30 07:30:04 -0700821 self.pg0.add_stream(arp_req_pg0_tagged)
822 self.pg_enable_capture(self.pg_interfaces)
823 self.pg_start()
824
825 rx = self.pg0.get_capture(1)
826 self.verify_arp_resp(rx[0],
827 self.pg0.local_mac,
828 self.pg0.remote_mac,
829 "10.10.10.3",
830 self.pg0.remote_ip4)
831
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800832 self.pg1.add_stream(arp_req_pg1)
833 self.pg_enable_capture(self.pg_interfaces)
834 self.pg_start()
835
836 rx = self.pg1.get_capture(1)
837 self.verify_arp_resp(rx[0],
838 self.pg1.local_mac,
839 self.pg1.remote_mac,
840 "10.10.10.3",
841 self.pg1.remote_ip4)
842
843 self.pg2.add_stream(arp_req_pg2)
844 self.pg_enable_capture(self.pg_interfaces)
845 self.pg_start()
846
847 rx = self.pg2.get_capture(1)
848 self.verify_arp_resp(rx[0],
849 self.pg2.local_mac,
850 self.pg2.remote_mac,
851 "10.10.10.3",
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700852 self.pg1.remote_hosts[1].ip4)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800853
854 #
855 # A request for an address out of the configured range
856 #
857 arp_req_pg1_hi = (Ether(src=self.pg1.remote_mac,
858 dst="ff:ff:ff:ff:ff:ff") /
859 ARP(op="who-has",
860 hwsrc=self.pg1.remote_mac,
861 pdst="10.10.10.125",
862 psrc=self.pg1.remote_ip4))
863 self.send_and_assert_no_replies(self.pg1, arp_req_pg1_hi,
864 "ARP req out of range HI")
865 arp_req_pg1_low = (Ether(src=self.pg1.remote_mac,
866 dst="ff:ff:ff:ff:ff:ff") /
867 ARP(op="who-has",
868 hwsrc=self.pg1.remote_mac,
869 pdst="10.10.10.1",
870 psrc=self.pg1.remote_ip4))
871 self.send_and_assert_no_replies(self.pg1, arp_req_pg1_low,
872 "ARP req out of range Low")
873
874 #
875 # Request for an address in the proxy range but from an interface
876 # in a different VRF
877 #
878 self.send_and_assert_no_replies(self.pg3, arp_req_pg3,
879 "ARP req from different VRF")
880
881 #
882 # Disable Each interface for proxy ARP
883 # - expect none to respond
884 #
885 for i in self.pg_interfaces:
886 i.set_proxy_arp(0)
887
888 self.send_and_assert_no_replies(self.pg0, arp_req_pg0,
889 "ARP req from disable")
890 self.send_and_assert_no_replies(self.pg1, arp_req_pg1,
891 "ARP req from disable")
892 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
893 "ARP req from disable")
Neale Ranns37be7362017-02-21 17:30:26 -0800894
895 #
896 # clean up on interface 2
897 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800898 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
Neale Ranns37be7362017-02-21 17:30:26 -0800899
900 def test_mpls(self):
901 """ MPLS """
902
903 #
904 # Interface 2 does not yet have ip4 config
905 #
906 self.pg2.config_ip4()
907 self.pg2.generate_remote_hosts(2)
908
909 #
910 # Add a reoute with out going label via an ARP unresolved next-hop
911 #
912 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
913 [VppRoutePath(self.pg2.remote_hosts[1].ip4,
914 self.pg2.sw_if_index,
915 labels=[55])])
916 ip_10_0_0_1.add_vpp_config()
917
918 #
919 # packets should generate an ARP request
920 #
921 p = (Ether(src=self.pg0.remote_mac,
922 dst=self.pg0.local_mac) /
923 IP(src=self.pg0.remote_ip4, dst="10.0.0.1") /
924 UDP(sport=1234, dport=1234) /
925 Raw('\xa5' * 100))
926
927 self.pg0.add_stream(p)
928 self.pg_enable_capture(self.pg_interfaces)
929 self.pg_start()
930
931 rx = self.pg2.get_capture(1)
932 self.verify_arp_req(rx[0],
933 self.pg2.local_mac,
934 self.pg2.local_ip4,
935 self.pg2._remote_hosts[1].ip4)
936
937 #
938 # now resolve the neighbours
939 #
940 self.pg2.configure_ipv4_neighbors()
941
942 #
943 # Now packet should be properly MPLS encapped.
944 # This verifies that MPLS link-type adjacencies are completed
945 # when the ARP entry resolves
946 #
947 self.pg0.add_stream(p)
948 self.pg_enable_capture(self.pg_interfaces)
949 self.pg_start()
950
951 rx = self.pg2.get_capture(1)
952 self.verify_ip_o_mpls(rx[0],
953 self.pg2.local_mac,
954 self.pg2.remote_hosts[1].mac,
955 55,
956 self.pg0.remote_ip4,
957 "10.0.0.1")
Neale Ranns4b919a52017-03-11 05:55:21 -0800958 self.pg2.unconfig_ip4()
Neale Ranns37be7362017-02-21 17:30:26 -0800959
Matthew Smithcb9ab472017-05-16 21:35:56 -0500960 def test_arp_vrrp(self):
961 """ ARP reply with VRRP virtual src hw addr """
962
963 #
964 # IP packet destined for pg1 remote host arrives on pg0 resulting
965 # in an ARP request for the address of the remote host on pg1
966 #
967 p0 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
968 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
969 UDP(sport=1234, dport=1234) /
970 Raw())
971
972 self.pg0.add_stream(p0)
973 self.pg_enable_capture(self.pg_interfaces)
974 self.pg_start()
975
976 rx1 = self.pg1.get_capture(1)
977
978 self.verify_arp_req(rx1[0],
979 self.pg1.local_mac,
980 self.pg1.local_ip4,
981 self.pg1.remote_ip4)
982
983 #
984 # ARP reply for address of pg1 remote host arrives on pg1 with
985 # the hw src addr set to a value in the VRRP IPv4 range of
986 # MAC addresses
987 #
988 p1 = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
989 ARP(op="is-at", hwdst=self.pg1.local_mac,
990 hwsrc="00:00:5e:00:01:09", pdst=self.pg1.local_ip4,
991 psrc=self.pg1.remote_ip4))
992
993 self.pg1.add_stream(p1)
994 self.pg_enable_capture(self.pg_interfaces)
995 self.pg_start()
996
997 #
998 # IP packet destined for pg1 remote host arrives on pg0 again.
999 # VPP should have an ARP entry for that address now and the packet
1000 # should be sent out pg1.
1001 #
1002 self.pg0.add_stream(p0)
1003 self.pg_enable_capture(self.pg_interfaces)
1004 self.pg_start()
1005
1006 rx1 = self.pg1.get_capture(1)
1007
1008 self.verify_ip(rx1[0],
1009 self.pg1.local_mac,
1010 "00:00:5e:00:01:09",
1011 self.pg0.remote_ip4,
1012 self.pg1.remote_ip4)
1013
1014 self.pg1.admin_down()
1015 self.pg1.admin_up()
1016
Neale Rannsdcd6d622017-05-26 02:59:16 -07001017 def test_arp_duplicates(self):
1018 """ ARP Duplicates"""
1019
1020 #
1021 # Generate some hosts on the LAN
1022 #
1023 self.pg1.generate_remote_hosts(3)
1024
1025 #
1026 # Add host 1 on pg1 and pg2
1027 #
1028 arp_pg1 = VppNeighbor(self,
1029 self.pg1.sw_if_index,
1030 self.pg1.remote_hosts[1].mac,
1031 self.pg1.remote_hosts[1].ip4)
1032 arp_pg1.add_vpp_config()
1033 arp_pg2 = VppNeighbor(self,
1034 self.pg2.sw_if_index,
1035 self.pg2.remote_mac,
1036 self.pg1.remote_hosts[1].ip4)
1037 arp_pg2.add_vpp_config()
1038
1039 #
1040 # IP packet destined for pg1 remote host arrives on pg1 again.
1041 #
1042 p = (Ether(dst=self.pg0.local_mac,
1043 src=self.pg0.remote_mac) /
1044 IP(src=self.pg0.remote_ip4,
1045 dst=self.pg1.remote_hosts[1].ip4) /
1046 UDP(sport=1234, dport=1234) /
1047 Raw())
1048
1049 self.pg0.add_stream(p)
1050 self.pg_enable_capture(self.pg_interfaces)
1051 self.pg_start()
1052
1053 rx1 = self.pg1.get_capture(1)
1054
1055 self.verify_ip(rx1[0],
1056 self.pg1.local_mac,
1057 self.pg1.remote_hosts[1].mac,
1058 self.pg0.remote_ip4,
1059 self.pg1.remote_hosts[1].ip4)
1060
1061 #
1062 # remove the duplicate on pg1
1063 # packet stream shoud generate ARPs out of pg1
1064 #
1065 arp_pg1.remove_vpp_config()
1066
1067 self.pg0.add_stream(p)
1068 self.pg_enable_capture(self.pg_interfaces)
1069 self.pg_start()
1070
1071 rx1 = self.pg1.get_capture(1)
1072
1073 self.verify_arp_req(rx1[0],
1074 self.pg1.local_mac,
1075 self.pg1.local_ip4,
1076 self.pg1.remote_hosts[1].ip4)
1077
1078 #
1079 # Add it back
1080 #
1081 arp_pg1.add_vpp_config()
1082
1083 self.pg0.add_stream(p)
1084 self.pg_enable_capture(self.pg_interfaces)
1085 self.pg_start()
1086
1087 rx1 = self.pg1.get_capture(1)
1088
1089 self.verify_ip(rx1[0],
1090 self.pg1.local_mac,
1091 self.pg1.remote_hosts[1].mac,
1092 self.pg0.remote_ip4,
1093 self.pg1.remote_hosts[1].ip4)
1094
Neale Ranns15002542017-09-10 04:39:11 -07001095 def test_arp_static(self):
1096 """ ARP Static"""
1097 self.pg2.generate_remote_hosts(3)
1098
1099 #
1100 # Add a static ARP entry
1101 #
1102 static_arp = VppNeighbor(self,
1103 self.pg2.sw_if_index,
1104 self.pg2.remote_hosts[1].mac,
1105 self.pg2.remote_hosts[1].ip4,
1106 is_static=1)
1107 static_arp.add_vpp_config()
1108
1109 #
1110 # Add the connected prefix to the interface
1111 #
1112 self.pg2.config_ip4()
1113
1114 #
1115 # We should now find the adj-fib
1116 #
1117 self.assertTrue(find_nbr(self,
1118 self.pg2.sw_if_index,
1119 self.pg2.remote_hosts[1].ip4,
1120 is_static=1))
1121 self.assertTrue(find_route(self,
1122 self.pg2.remote_hosts[1].ip4,
1123 32))
1124
1125 #
1126 # remove the connected
1127 #
1128 self.pg2.unconfig_ip4()
1129
1130 #
1131 # put the interface into table 1
1132 #
1133 self.pg2.set_table_ip4(1)
1134
1135 #
1136 # configure the same connected and expect to find the
1137 # adj fib in the new table
1138 #
1139 self.pg2.config_ip4()
1140 self.assertTrue(find_route(self,
1141 self.pg2.remote_hosts[1].ip4,
1142 32,
1143 table_id=1))
1144
1145 #
1146 # clean-up
1147 #
1148 self.pg2.unconfig_ip4()
1149 self.pg2.set_table_ip4(0)
1150
Neale Rannsc819fc62018-02-16 02:44:05 -08001151 def test_arp_incomplete(self):
1152 """ ARP Incomplete"""
1153 self.pg1.generate_remote_hosts(3)
1154
1155 p0 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1156 IP(src=self.pg0.remote_ip4,
1157 dst=self.pg1.remote_hosts[1].ip4) /
1158 UDP(sport=1234, dport=1234) /
1159 Raw())
1160 p1 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1161 IP(src=self.pg0.remote_ip4,
1162 dst=self.pg1.remote_hosts[2].ip4) /
1163 UDP(sport=1234, dport=1234) /
1164 Raw())
1165
1166 #
1167 # a packet to an unresolved destination generates an ARP request
1168 #
1169 rx = self.send_and_expect(self.pg0, [p0], self.pg1)
1170 self.verify_arp_req(rx[0],
1171 self.pg1.local_mac,
1172 self.pg1.local_ip4,
1173 self.pg1._remote_hosts[1].ip4)
1174
1175 #
1176 # add a neighbour for remote host 1
1177 #
1178 static_arp = VppNeighbor(self,
1179 self.pg1.sw_if_index,
1180 self.pg1.remote_hosts[1].mac,
1181 self.pg1.remote_hosts[1].ip4,
1182 is_static=1)
1183 static_arp.add_vpp_config()
1184
1185 #
1186 # change the interface's MAC
1187 #
1188 mac = [chr(0x00), chr(0x00), chr(0x00),
1189 chr(0x33), chr(0x33), chr(0x33)]
1190 mac_string = ''.join(mac)
1191
1192 self.vapi.sw_interface_set_mac_address(self.pg1.sw_if_index,
1193 mac_string)
1194
1195 #
1196 # now ARP requests come from the new source mac
1197 #
1198 rx = self.send_and_expect(self.pg0, [p1], self.pg1)
1199 self.verify_arp_req(rx[0],
1200 "00:00:00:33:33:33",
1201 self.pg1.local_ip4,
1202 self.pg1._remote_hosts[2].ip4)
1203
1204 #
1205 # packets to the resolved host also have the new source mac
1206 #
1207 rx = self.send_and_expect(self.pg0, [p0], self.pg1)
1208 self.verify_ip(rx[0],
1209 "00:00:00:33:33:33",
1210 self.pg1.remote_hosts[1].mac,
1211 self.pg0.remote_ip4,
1212 self.pg1.remote_hosts[1].ip4)
1213
1214 #
1215 # set the mac address on the inteface that does not have a
1216 # configured subnet and thus no glean
1217 #
1218 self.vapi.sw_interface_set_mac_address(self.pg2.sw_if_index,
1219 mac_string)
1220
Neale Ranns59ae61e2018-06-07 18:09:49 -07001221 def test_garp(self):
1222 """ GARP """
1223
1224 #
1225 # Generate some hosts on the LAN
1226 #
1227 self.pg1.generate_remote_hosts(4)
1228
1229 #
1230 # And an ARP entry
1231 #
1232 arp = VppNeighbor(self,
1233 self.pg1.sw_if_index,
1234 self.pg1.remote_hosts[1].mac,
1235 self.pg1.remote_hosts[1].ip4)
1236 arp.add_vpp_config()
1237
1238 self.assertTrue(find_nbr(self,
1239 self.pg1.sw_if_index,
1240 self.pg1.remote_hosts[1].ip4,
1241 mac=self.pg1.remote_hosts[1].mac))
1242
1243 #
1244 # Send a GARP (request) to swap the host 1's address to that of host 2
1245 #
1246 p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1247 src=self.pg1.remote_hosts[2].mac) /
1248 ARP(op="who-has",
1249 hwdst=self.pg1.local_mac,
1250 hwsrc=self.pg1.remote_hosts[2].mac,
1251 pdst=self.pg1.remote_hosts[1].ip4,
1252 psrc=self.pg1.remote_hosts[1].ip4))
1253
1254 self.pg1.add_stream(p1)
1255 self.pg_enable_capture(self.pg_interfaces)
1256 self.pg_start()
1257
1258 self.assertTrue(find_nbr(self,
1259 self.pg1.sw_if_index,
1260 self.pg1.remote_hosts[1].ip4,
1261 mac=self.pg1.remote_hosts[2].mac))
1262
1263 #
1264 # Send a GARP (reply) to swap the host 1's address to that of host 3
1265 #
1266 p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1267 src=self.pg1.remote_hosts[3].mac) /
1268 ARP(op="is-at",
1269 hwdst=self.pg1.local_mac,
1270 hwsrc=self.pg1.remote_hosts[3].mac,
1271 pdst=self.pg1.remote_hosts[1].ip4,
1272 psrc=self.pg1.remote_hosts[1].ip4))
1273
1274 self.pg1.add_stream(p1)
1275 self.pg_enable_capture(self.pg_interfaces)
1276 self.pg_start()
1277
1278 self.assertTrue(find_nbr(self,
1279 self.pg1.sw_if_index,
1280 self.pg1.remote_hosts[1].ip4,
1281 mac=self.pg1.remote_hosts[3].mac))
1282
1283 #
1284 # GARPs (requets nor replies) for host we don't know yet
1285 # don't result in new neighbour entries
1286 #
1287 p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1288 src=self.pg1.remote_hosts[3].mac) /
1289 ARP(op="who-has",
1290 hwdst=self.pg1.local_mac,
1291 hwsrc=self.pg1.remote_hosts[3].mac,
1292 pdst=self.pg1.remote_hosts[2].ip4,
1293 psrc=self.pg1.remote_hosts[2].ip4))
1294
1295 self.pg1.add_stream(p1)
1296 self.pg_enable_capture(self.pg_interfaces)
1297 self.pg_start()
1298
1299 self.assertFalse(find_nbr(self,
1300 self.pg1.sw_if_index,
1301 self.pg1.remote_hosts[2].ip4))
1302
1303 p1 = (Ether(dst="ff:ff:ff:ff:ff:ff",
1304 src=self.pg1.remote_hosts[3].mac) /
1305 ARP(op="is-at",
1306 hwdst=self.pg1.local_mac,
1307 hwsrc=self.pg1.remote_hosts[3].mac,
1308 pdst=self.pg1.remote_hosts[2].ip4,
1309 psrc=self.pg1.remote_hosts[2].ip4))
1310
1311 self.pg1.add_stream(p1)
1312 self.pg_enable_capture(self.pg_interfaces)
1313 self.pg_start()
1314
1315 self.assertFalse(find_nbr(self,
1316 self.pg1.sw_if_index,
1317 self.pg1.remote_hosts[2].ip4))
1318
Neale Rannsdcd6d622017-05-26 02:59:16 -07001319
Neale Ranns37be7362017-02-21 17:30:26 -08001320if __name__ == '__main__':
1321 unittest.main(testRunner=VppTestRunner)