blob: f2b1cfa47eed4c3d4a7ba30d88d9763f667a95ab [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 Rannsb3b2de72017-03-08 05:17:22 -08008from vpp_ip_route import VppIpRoute, VppRoutePath, find_route
Neale Ranns39f9d8b2017-02-16 21:57:05 -08009
10from scapy.packet import Raw
11from scapy.layers.l2 import Ether, ARP
12from scapy.layers.inet import IP, UDP
Neale Ranns37be7362017-02-21 17:30:26 -080013from scapy.contrib.mpls import MPLS
Neale Ranns39f9d8b2017-02-16 21:57:05 -080014
15# not exported by scapy, so redefined here
16arp_opts = {"who-has": 1, "is-at": 2}
17
18
19class ARPTestCase(VppTestCase):
20 """ ARP Test Case """
21
22 def setUp(self):
23 super(ARPTestCase, self).setUp()
24
25 # create 3 pg interfaces
26 self.create_pg_interfaces(range(4))
27
28 # pg0 configured with ip4 and 6 addresses used for input
29 # pg1 configured with ip4 and 6 addresses used for output
30 # pg2 is unnumbered to pg0
31 for i in self.pg_interfaces:
32 i.admin_up()
33
34 self.pg0.config_ip4()
35 self.pg0.config_ip6()
36 self.pg0.resolve_arp()
37
38 self.pg1.config_ip4()
39 self.pg1.config_ip6()
40
41 # pg3 in a different VRF
42 self.pg3.set_table_ip4(1)
43 self.pg3.config_ip4()
44
Neale Ranns4008ac92017-02-13 23:20:04 -080045 def tearDown(self):
46 super(ARPTestCase, self).tearDown()
Neale Ranns4b919a52017-03-11 05:55:21 -080047 self.pg0.unconfig_ip4()
48 self.pg0.unconfig_ip6()
49
50 self.pg1.unconfig_ip4()
51 self.pg1.unconfig_ip6()
52
53 self.pg3.unconfig_ip4()
54
Neale Ranns4008ac92017-02-13 23:20:04 -080055 for i in self.pg_interfaces:
Neale Ranns4008ac92017-02-13 23:20:04 -080056 i.admin_down()
57
Neale Ranns39f9d8b2017-02-16 21:57:05 -080058 def verify_arp_req(self, rx, smac, sip, dip):
59 ether = rx[Ether]
60 self.assertEqual(ether.dst, "ff:ff:ff:ff:ff:ff")
61 self.assertEqual(ether.src, smac)
62
63 arp = rx[ARP]
64 self.assertEqual(arp.hwtype, 1)
65 self.assertEqual(arp.ptype, 0x800)
66 self.assertEqual(arp.hwlen, 6)
67 self.assertEqual(arp.plen, 4)
68 self.assertEqual(arp.op, arp_opts["who-has"])
69 self.assertEqual(arp.hwsrc, smac)
70 self.assertEqual(arp.hwdst, "00:00:00:00:00:00")
71 self.assertEqual(arp.psrc, sip)
72 self.assertEqual(arp.pdst, dip)
73
74 def verify_arp_resp(self, rx, smac, dmac, sip, dip):
75 ether = rx[Ether]
76 self.assertEqual(ether.dst, dmac)
77 self.assertEqual(ether.src, smac)
78
79 arp = rx[ARP]
80 self.assertEqual(arp.hwtype, 1)
81 self.assertEqual(arp.ptype, 0x800)
82 self.assertEqual(arp.hwlen, 6)
83 self.assertEqual(arp.plen, 4)
84 self.assertEqual(arp.op, arp_opts["is-at"])
85 self.assertEqual(arp.hwsrc, smac)
86 self.assertEqual(arp.hwdst, dmac)
87 self.assertEqual(arp.psrc, sip)
88 self.assertEqual(arp.pdst, dip)
89
90 def verify_ip(self, rx, smac, dmac, sip, dip):
91 ether = rx[Ether]
92 self.assertEqual(ether.dst, dmac)
93 self.assertEqual(ether.src, smac)
94
95 ip = rx[IP]
96 self.assertEqual(ip.src, sip)
97 self.assertEqual(ip.dst, dip)
98
Neale Ranns37be7362017-02-21 17:30:26 -080099 def verify_ip_o_mpls(self, rx, smac, dmac, label, sip, dip):
100 ether = rx[Ether]
101 self.assertEqual(ether.dst, dmac)
102 self.assertEqual(ether.src, smac)
103
104 mpls = rx[MPLS]
105 self.assertTrue(mpls.label, label)
106
107 ip = rx[IP]
108 self.assertEqual(ip.src, sip)
109 self.assertEqual(ip.dst, dip)
110
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800111 def send_and_assert_no_replies(self, intf, pkts, remark):
112 intf.add_stream(pkts)
113 self.pg_enable_capture(self.pg_interfaces)
114 self.pg_start()
115 for i in self.pg_interfaces:
116 i.assert_nothing_captured(remark=remark)
117
118 def test_arp(self):
119 """ ARP """
120
121 #
122 # Generate some hosts on the LAN
123 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800124 self.pg1.generate_remote_hosts(9)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800125
126 #
127 # Send IP traffic to one of these unresolved hosts.
128 # expect the generation of an ARP request
129 #
130 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
131 IP(src=self.pg0.remote_ip4, dst=self.pg1._remote_hosts[1].ip4) /
132 UDP(sport=1234, dport=1234) /
133 Raw())
134
135 self.pg0.add_stream(p)
136 self.pg_enable_capture(self.pg_interfaces)
137 self.pg_start()
138
139 rx = self.pg1.get_capture(1)
140
141 self.verify_arp_req(rx[0],
142 self.pg1.local_mac,
143 self.pg1.local_ip4,
144 self.pg1._remote_hosts[1].ip4)
145
146 #
147 # And a dynamic ARP entry for host 1
148 #
149 dyn_arp = VppNeighbor(self,
150 self.pg1.sw_if_index,
151 self.pg1.remote_hosts[1].mac,
152 self.pg1.remote_hosts[1].ip4)
153 dyn_arp.add_vpp_config()
154
155 #
156 # now we expect IP traffic forwarded
157 #
158 dyn_p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
159 IP(src=self.pg0.remote_ip4,
160 dst=self.pg1._remote_hosts[1].ip4) /
161 UDP(sport=1234, dport=1234) /
162 Raw())
163
164 self.pg0.add_stream(dyn_p)
165 self.pg_enable_capture(self.pg_interfaces)
166 self.pg_start()
167
168 rx = self.pg1.get_capture(1)
169
170 self.verify_ip(rx[0],
171 self.pg1.local_mac,
172 self.pg1.remote_hosts[1].mac,
173 self.pg0.remote_ip4,
174 self.pg1._remote_hosts[1].ip4)
175
176 #
177 # And a Static ARP entry for host 2
178 #
179 static_arp = VppNeighbor(self,
180 self.pg1.sw_if_index,
181 self.pg1.remote_hosts[2].mac,
182 self.pg1.remote_hosts[2].ip4,
183 is_static=1)
184 static_arp.add_vpp_config()
185
186 static_p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
187 IP(src=self.pg0.remote_ip4,
188 dst=self.pg1._remote_hosts[2].ip4) /
189 UDP(sport=1234, dport=1234) /
190 Raw())
191
192 self.pg0.add_stream(static_p)
193 self.pg_enable_capture(self.pg_interfaces)
194 self.pg_start()
195
196 rx = self.pg1.get_capture(1)
197
198 self.verify_ip(rx[0],
199 self.pg1.local_mac,
200 self.pg1.remote_hosts[2].mac,
201 self.pg0.remote_ip4,
202 self.pg1._remote_hosts[2].ip4)
203
204 #
205 # flap the link. dynamic ARPs get flush, statics don't
206 #
207 self.pg1.admin_down()
208 self.pg1.admin_up()
209
210 self.pg0.add_stream(static_p)
211 self.pg_enable_capture(self.pg_interfaces)
212 self.pg_start()
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 self.pg0.add_stream(dyn_p)
222 self.pg_enable_capture(self.pg_interfaces)
223 self.pg_start()
224
225 rx = self.pg1.get_capture(1)
226 self.verify_arp_req(rx[0],
227 self.pg1.local_mac,
228 self.pg1.local_ip4,
229 self.pg1._remote_hosts[1].ip4)
230
231 #
232 # Send an ARP request from one of the so-far unlearned remote hosts
233 #
234 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
235 src=self.pg1._remote_hosts[3].mac) /
236 ARP(op="who-has",
237 hwsrc=self.pg1._remote_hosts[3].mac,
238 pdst=self.pg1.local_ip4,
239 psrc=self.pg1._remote_hosts[3].ip4))
240
241 self.pg1.add_stream(p)
242 self.pg_enable_capture(self.pg_interfaces)
243 self.pg_start()
244
245 rx = self.pg1.get_capture(1)
246 self.verify_arp_resp(rx[0],
247 self.pg1.local_mac,
248 self.pg1._remote_hosts[3].mac,
249 self.pg1.local_ip4,
250 self.pg1._remote_hosts[3].ip4)
251
252 #
253 # VPP should have learned the mapping for the remote host
254 #
255 self.assertTrue(find_nbr(self,
256 self.pg1.sw_if_index,
257 self.pg1._remote_hosts[3].ip4))
Neale Ranns4b919a52017-03-11 05:55:21 -0800258 #
259 # Fire in an ARP request before the interface becomes IP enabled
260 #
261 self.pg2.generate_remote_hosts(4)
262
263 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
264 ARP(op="who-has",
265 hwsrc=self.pg2.remote_mac,
266 pdst=self.pg1.local_ip4,
267 psrc=self.pg2.remote_hosts[3].ip4))
268 self.send_and_assert_no_replies(self.pg2, p,
269 "interface not IP enabled")
270
271 #
272 # Make pg2 un-numbered to pg1
273 #
274 self.pg2.set_unnumbered(self.pg1.sw_if_index)
275
276 #
277 # We should respond to ARP requests for the unnumbered to address
278 # once an attached route to the source is known
279 #
280 self.send_and_assert_no_replies(
281 self.pg2, p,
282 "ARP req for unnumbered address - no source")
283
284 attached_host = VppIpRoute(self, self.pg2.remote_hosts[3].ip4, 32,
285 [VppRoutePath("0.0.0.0",
286 self.pg2.sw_if_index)])
287 attached_host.add_vpp_config()
288
289 self.pg2.add_stream(p)
290 self.pg_enable_capture(self.pg_interfaces)
291 self.pg_start()
292
293 rx = self.pg2.get_capture(1)
294 self.verify_arp_resp(rx[0],
295 self.pg2.local_mac,
296 self.pg2.remote_mac,
297 self.pg1.local_ip4,
298 self.pg2.remote_hosts[3].ip4)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800299
300 #
Neale Ranns3983ac22017-03-10 11:53:27 -0800301 # A neighbor entry that has no associated FIB-entry
302 #
303 arp_no_fib = VppNeighbor(self,
304 self.pg1.sw_if_index,
305 self.pg1.remote_hosts[4].mac,
306 self.pg1.remote_hosts[4].ip4,
307 is_no_fib_entry=1)
308 arp_no_fib.add_vpp_config()
309
310 #
311 # check we have the neighbor, but no route
312 #
313 self.assertTrue(find_nbr(self,
314 self.pg1.sw_if_index,
315 self.pg1._remote_hosts[4].ip4))
316 self.assertFalse(find_route(self,
317 self.pg1._remote_hosts[4].ip4,
318 32))
319 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800320 # pg2 is unnumbered to pg1, so we can form adjacencies out of pg2
321 # from within pg1's subnet
Neale Ranns3983ac22017-03-10 11:53:27 -0800322 #
323 arp_unnum = VppNeighbor(self,
324 self.pg2.sw_if_index,
325 self.pg1.remote_hosts[5].mac,
326 self.pg1.remote_hosts[5].ip4)
327 arp_unnum.add_vpp_config()
328
329 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
330 IP(src=self.pg0.remote_ip4,
331 dst=self.pg1._remote_hosts[5].ip4) /
332 UDP(sport=1234, dport=1234) /
333 Raw())
334
335 self.pg0.add_stream(p)
336 self.pg_enable_capture(self.pg_interfaces)
337 self.pg_start()
338
339 rx = self.pg2.get_capture(1)
340
341 self.verify_ip(rx[0],
342 self.pg2.local_mac,
343 self.pg1.remote_hosts[5].mac,
344 self.pg0.remote_ip4,
345 self.pg1._remote_hosts[5].ip4)
346
347 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800348 # ARP requests from hosts in pg1's subnet sent on pg2 are replied to
349 # with the unnumbered interface's address as the source
350 #
351 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
352 ARP(op="who-has",
353 hwsrc=self.pg2.remote_mac,
354 pdst=self.pg1.local_ip4,
355 psrc=self.pg1.remote_hosts[6].ip4))
356
357 self.pg2.add_stream(p)
358 self.pg_enable_capture(self.pg_interfaces)
359 self.pg_start()
360
361 rx = self.pg2.get_capture(1)
362 self.verify_arp_resp(rx[0],
363 self.pg2.local_mac,
364 self.pg2.remote_mac,
365 self.pg1.local_ip4,
366 self.pg1.remote_hosts[6].ip4)
367
368 #
369 # An attached host route out of pg2 for an undiscovered hosts generates
370 # an ARP request with the unnumbered address as the source
371 #
372 att_unnum = VppIpRoute(self, self.pg1.remote_hosts[7].ip4, 32,
373 [VppRoutePath("0.0.0.0",
374 self.pg2.sw_if_index)])
375 att_unnum.add_vpp_config()
376
377 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
378 IP(src=self.pg0.remote_ip4,
379 dst=self.pg1._remote_hosts[7].ip4) /
380 UDP(sport=1234, dport=1234) /
381 Raw())
382
383 self.pg0.add_stream(p)
384 self.pg_enable_capture(self.pg_interfaces)
385 self.pg_start()
386
387 rx = self.pg2.get_capture(1)
388
389 self.verify_arp_req(rx[0],
390 self.pg2.local_mac,
391 self.pg1.local_ip4,
392 self.pg1._remote_hosts[7].ip4)
393
394 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
395 ARP(op="who-has",
396 hwsrc=self.pg2.remote_mac,
397 pdst=self.pg1.local_ip4,
398 psrc=self.pg1.remote_hosts[7].ip4))
399
400 self.pg2.add_stream(p)
401 self.pg_enable_capture(self.pg_interfaces)
402 self.pg_start()
403
404 rx = self.pg2.get_capture(1)
405 self.verify_arp_resp(rx[0],
406 self.pg2.local_mac,
407 self.pg2.remote_mac,
408 self.pg1.local_ip4,
409 self.pg1.remote_hosts[7].ip4)
410
411 #
412 # An attached host route as yet unresolved out of pg2 for an
413 # undiscovered host, an ARP requests begets a response.
414 #
415 att_unnum1 = VppIpRoute(self, self.pg1.remote_hosts[8].ip4, 32,
416 [VppRoutePath("0.0.0.0",
417 self.pg2.sw_if_index)])
418 att_unnum1.add_vpp_config()
419
420 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
421 ARP(op="who-has",
422 hwsrc=self.pg2.remote_mac,
423 pdst=self.pg1.local_ip4,
424 psrc=self.pg1.remote_hosts[8].ip4))
425
426 self.pg2.add_stream(p)
427 self.pg_enable_capture(self.pg_interfaces)
428 self.pg_start()
429
430 rx = self.pg2.get_capture(1)
431 self.verify_arp_resp(rx[0],
432 self.pg2.local_mac,
433 self.pg2.remote_mac,
434 self.pg1.local_ip4,
435 self.pg1.remote_hosts[8].ip4)
436
437 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800438 # ERROR Cases
439 # 1 - don't respond to ARP request for address not within the
440 # interface's sub-net
Neale Ranns4b919a52017-03-11 05:55:21 -0800441 # 1a - nor within the unnumbered subnet
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800442 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
443 ARP(op="who-has",
444 hwsrc=self.pg0.remote_mac,
445 pdst="10.10.10.3",
446 psrc=self.pg0.remote_ip4))
447 self.send_and_assert_no_replies(self.pg0, p,
448 "ARP req for non-local destination")
Neale Ranns4b919a52017-03-11 05:55:21 -0800449 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
450 ARP(op="who-has",
451 hwsrc=self.pg2.remote_mac,
452 pdst="10.10.10.3",
453 psrc=self.pg1.remote_hosts[7].ip4))
454 self.send_and_assert_no_replies(
455 self.pg0, p,
456 "ARP req for non-local destination - unnum")
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800457
458 #
459 # 2 - don't respond to ARP request from an address not within the
460 # interface's sub-net
461 #
462 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
463 ARP(op="who-has",
464 hwsrc=self.pg0.remote_mac,
465 psrc="10.10.10.3",
466 pdst=self.pg0.local_ip4))
467 self.send_and_assert_no_replies(self.pg0, p,
468 "ARP req for non-local source")
Neale Ranns4b919a52017-03-11 05:55:21 -0800469 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
470 ARP(op="who-has",
471 hwsrc=self.pg2.remote_mac,
472 psrc="10.10.10.3",
473 pdst=self.pg0.local_ip4))
474 self.send_and_assert_no_replies(
475 self.pg0, p,
476 "ARP req for non-local source - unnum")
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800477
478 #
479 # 3 - don't respond to ARP request from an address that belongs to
480 # the router
481 #
482 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
483 ARP(op="who-has",
484 hwsrc=self.pg0.remote_mac,
485 psrc=self.pg0.local_ip4,
486 pdst=self.pg0.local_ip4))
487 self.send_and_assert_no_replies(self.pg0, p,
488 "ARP req for non-local source")
489
490 #
491 # 4 - don't respond to ARP requests that has mac source different
492 # from ARP request HW source
493 # the router
494 #
495 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
496 ARP(op="who-has",
497 hwsrc="00:00:00:DE:AD:BE",
498 psrc=self.pg0.remote_ip4,
499 pdst=self.pg0.local_ip4))
500 self.send_and_assert_no_replies(self.pg0, p,
501 "ARP req for non-local source")
502
503 #
504 # cleanup
505 #
506 dyn_arp.remove_vpp_config()
507 static_arp.remove_vpp_config()
Neale Ranns3983ac22017-03-10 11:53:27 -0800508 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800509
Neale Ranns4b919a52017-03-11 05:55:21 -0800510 # need this to flush the adj-fibs
511 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
512 self.pg2.admin_down()
513
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800514 def test_proxy_arp(self):
515 """ Proxy ARP """
516
517 #
518 # Proxy ARP rewquest packets for each interface
519 #
520 arp_req_pg2 = (Ether(src=self.pg2.remote_mac,
521 dst="ff:ff:ff:ff:ff:ff") /
522 ARP(op="who-has",
523 hwsrc=self.pg2.remote_mac,
524 pdst="10.10.10.3",
525 psrc=self.pg1.remote_ip4))
526 arp_req_pg0 = (Ether(src=self.pg0.remote_mac,
527 dst="ff:ff:ff:ff:ff:ff") /
528 ARP(op="who-has",
529 hwsrc=self.pg0.remote_mac,
530 pdst="10.10.10.3",
531 psrc=self.pg0.remote_ip4))
532 arp_req_pg1 = (Ether(src=self.pg1.remote_mac,
533 dst="ff:ff:ff:ff:ff:ff") /
534 ARP(op="who-has",
535 hwsrc=self.pg1.remote_mac,
536 pdst="10.10.10.3",
537 psrc=self.pg1.remote_ip4))
538 arp_req_pg3 = (Ether(src=self.pg3.remote_mac,
539 dst="ff:ff:ff:ff:ff:ff") /
540 ARP(op="who-has",
541 hwsrc=self.pg3.remote_mac,
542 pdst="10.10.10.3",
543 psrc=self.pg3.remote_ip4))
544
545 #
546 # Configure Proxy ARP for 10.10.10.0 -> 10.10.10.124
547 #
548 self.vapi.proxy_arp_add_del(inet_pton(AF_INET, "10.10.10.2"),
549 inet_pton(AF_INET, "10.10.10.124"))
550
551 #
552 # No responses are sent when the interfaces are not enabled for proxy
553 # ARP
554 #
555 self.send_and_assert_no_replies(self.pg0, arp_req_pg0,
556 "ARP req from unconfigured interface")
557 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
558 "ARP req from unconfigured interface")
559
560 #
561 # Make pg2 un-numbered to pg1
562 # still won't reply.
563 #
564 self.pg2.set_unnumbered(self.pg1.sw_if_index)
565
566 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
567 "ARP req from unnumbered interface")
568
569 #
570 # Enable each interface to reply to proxy ARPs
571 #
572 for i in self.pg_interfaces:
573 i.set_proxy_arp()
574
575 #
576 # Now each of the interfaces should reply to a request to a proxied
577 # address
578 #
579 self.pg0.add_stream(arp_req_pg0)
580 self.pg_enable_capture(self.pg_interfaces)
581 self.pg_start()
582
583 rx = self.pg0.get_capture(1)
584 self.verify_arp_resp(rx[0],
585 self.pg0.local_mac,
586 self.pg0.remote_mac,
587 "10.10.10.3",
588 self.pg0.remote_ip4)
589
590 self.pg1.add_stream(arp_req_pg1)
591 self.pg_enable_capture(self.pg_interfaces)
592 self.pg_start()
593
594 rx = self.pg1.get_capture(1)
595 self.verify_arp_resp(rx[0],
596 self.pg1.local_mac,
597 self.pg1.remote_mac,
598 "10.10.10.3",
599 self.pg1.remote_ip4)
600
601 self.pg2.add_stream(arp_req_pg2)
602 self.pg_enable_capture(self.pg_interfaces)
603 self.pg_start()
604
605 rx = self.pg2.get_capture(1)
606 self.verify_arp_resp(rx[0],
607 self.pg2.local_mac,
608 self.pg2.remote_mac,
609 "10.10.10.3",
610 self.pg1.remote_ip4)
611
612 #
613 # A request for an address out of the configured range
614 #
615 arp_req_pg1_hi = (Ether(src=self.pg1.remote_mac,
616 dst="ff:ff:ff:ff:ff:ff") /
617 ARP(op="who-has",
618 hwsrc=self.pg1.remote_mac,
619 pdst="10.10.10.125",
620 psrc=self.pg1.remote_ip4))
621 self.send_and_assert_no_replies(self.pg1, arp_req_pg1_hi,
622 "ARP req out of range HI")
623 arp_req_pg1_low = (Ether(src=self.pg1.remote_mac,
624 dst="ff:ff:ff:ff:ff:ff") /
625 ARP(op="who-has",
626 hwsrc=self.pg1.remote_mac,
627 pdst="10.10.10.1",
628 psrc=self.pg1.remote_ip4))
629 self.send_and_assert_no_replies(self.pg1, arp_req_pg1_low,
630 "ARP req out of range Low")
631
632 #
633 # Request for an address in the proxy range but from an interface
634 # in a different VRF
635 #
636 self.send_and_assert_no_replies(self.pg3, arp_req_pg3,
637 "ARP req from different VRF")
638
639 #
640 # Disable Each interface for proxy ARP
641 # - expect none to respond
642 #
643 for i in self.pg_interfaces:
644 i.set_proxy_arp(0)
645
646 self.send_and_assert_no_replies(self.pg0, arp_req_pg0,
647 "ARP req from disable")
648 self.send_and_assert_no_replies(self.pg1, arp_req_pg1,
649 "ARP req from disable")
650 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
651 "ARP req from disable")
Neale Ranns37be7362017-02-21 17:30:26 -0800652
653 #
654 # clean up on interface 2
655 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800656 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
Neale Ranns37be7362017-02-21 17:30:26 -0800657
658 def test_mpls(self):
659 """ MPLS """
660
661 #
662 # Interface 2 does not yet have ip4 config
663 #
664 self.pg2.config_ip4()
665 self.pg2.generate_remote_hosts(2)
666
667 #
668 # Add a reoute with out going label via an ARP unresolved next-hop
669 #
670 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
671 [VppRoutePath(self.pg2.remote_hosts[1].ip4,
672 self.pg2.sw_if_index,
673 labels=[55])])
674 ip_10_0_0_1.add_vpp_config()
675
676 #
677 # packets should generate an ARP request
678 #
679 p = (Ether(src=self.pg0.remote_mac,
680 dst=self.pg0.local_mac) /
681 IP(src=self.pg0.remote_ip4, dst="10.0.0.1") /
682 UDP(sport=1234, dport=1234) /
683 Raw('\xa5' * 100))
684
685 self.pg0.add_stream(p)
686 self.pg_enable_capture(self.pg_interfaces)
687 self.pg_start()
688
689 rx = self.pg2.get_capture(1)
690 self.verify_arp_req(rx[0],
691 self.pg2.local_mac,
692 self.pg2.local_ip4,
693 self.pg2._remote_hosts[1].ip4)
694
695 #
696 # now resolve the neighbours
697 #
698 self.pg2.configure_ipv4_neighbors()
699
700 #
701 # Now packet should be properly MPLS encapped.
702 # This verifies that MPLS link-type adjacencies are completed
703 # when the ARP entry resolves
704 #
705 self.pg0.add_stream(p)
706 self.pg_enable_capture(self.pg_interfaces)
707 self.pg_start()
708
709 rx = self.pg2.get_capture(1)
710 self.verify_ip_o_mpls(rx[0],
711 self.pg2.local_mac,
712 self.pg2.remote_hosts[1].mac,
713 55,
714 self.pg0.remote_ip4,
715 "10.0.0.1")
Neale Ranns4b919a52017-03-11 05:55:21 -0800716 self.pg2.unconfig_ip4()
Neale Ranns37be7362017-02-21 17:30:26 -0800717
718if __name__ == '__main__':
719 unittest.main(testRunner=VppTestRunner)