blob: 48c6a291248032b594341a0ec8a00a0f3ef92549 [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()
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700115 timeout = 1
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800116 for i in self.pg_interfaces:
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700117 i.get_capture(0, timeout=timeout)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800118 i.assert_nothing_captured(remark=remark)
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700119 timeout = 0.1
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800120
121 def test_arp(self):
122 """ ARP """
123
124 #
125 # Generate some hosts on the LAN
126 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800127 self.pg1.generate_remote_hosts(9)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800128
129 #
130 # Send IP traffic to one of these unresolved hosts.
131 # expect the generation of an ARP request
132 #
133 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
134 IP(src=self.pg0.remote_ip4, dst=self.pg1._remote_hosts[1].ip4) /
135 UDP(sport=1234, dport=1234) /
136 Raw())
137
138 self.pg0.add_stream(p)
139 self.pg_enable_capture(self.pg_interfaces)
140 self.pg_start()
141
142 rx = self.pg1.get_capture(1)
143
144 self.verify_arp_req(rx[0],
145 self.pg1.local_mac,
146 self.pg1.local_ip4,
147 self.pg1._remote_hosts[1].ip4)
148
149 #
150 # And a dynamic ARP entry for host 1
151 #
152 dyn_arp = VppNeighbor(self,
153 self.pg1.sw_if_index,
154 self.pg1.remote_hosts[1].mac,
155 self.pg1.remote_hosts[1].ip4)
156 dyn_arp.add_vpp_config()
157
158 #
159 # now we expect IP traffic forwarded
160 #
161 dyn_p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
162 IP(src=self.pg0.remote_ip4,
163 dst=self.pg1._remote_hosts[1].ip4) /
164 UDP(sport=1234, dport=1234) /
165 Raw())
166
167 self.pg0.add_stream(dyn_p)
168 self.pg_enable_capture(self.pg_interfaces)
169 self.pg_start()
170
171 rx = self.pg1.get_capture(1)
172
173 self.verify_ip(rx[0],
174 self.pg1.local_mac,
175 self.pg1.remote_hosts[1].mac,
176 self.pg0.remote_ip4,
177 self.pg1._remote_hosts[1].ip4)
178
179 #
180 # And a Static ARP entry for host 2
181 #
182 static_arp = VppNeighbor(self,
183 self.pg1.sw_if_index,
184 self.pg1.remote_hosts[2].mac,
185 self.pg1.remote_hosts[2].ip4,
186 is_static=1)
187 static_arp.add_vpp_config()
188
189 static_p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
190 IP(src=self.pg0.remote_ip4,
191 dst=self.pg1._remote_hosts[2].ip4) /
192 UDP(sport=1234, dport=1234) /
193 Raw())
194
195 self.pg0.add_stream(static_p)
196 self.pg_enable_capture(self.pg_interfaces)
197 self.pg_start()
198
199 rx = self.pg1.get_capture(1)
200
201 self.verify_ip(rx[0],
202 self.pg1.local_mac,
203 self.pg1.remote_hosts[2].mac,
204 self.pg0.remote_ip4,
205 self.pg1._remote_hosts[2].ip4)
206
207 #
208 # flap the link. dynamic ARPs get flush, statics don't
209 #
210 self.pg1.admin_down()
211 self.pg1.admin_up()
212
213 self.pg0.add_stream(static_p)
214 self.pg_enable_capture(self.pg_interfaces)
215 self.pg_start()
216 rx = self.pg1.get_capture(1)
217
218 self.verify_ip(rx[0],
219 self.pg1.local_mac,
220 self.pg1.remote_hosts[2].mac,
221 self.pg0.remote_ip4,
222 self.pg1._remote_hosts[2].ip4)
223
224 self.pg0.add_stream(dyn_p)
225 self.pg_enable_capture(self.pg_interfaces)
226 self.pg_start()
227
228 rx = self.pg1.get_capture(1)
229 self.verify_arp_req(rx[0],
230 self.pg1.local_mac,
231 self.pg1.local_ip4,
232 self.pg1._remote_hosts[1].ip4)
233
234 #
235 # Send an ARP request from one of the so-far unlearned remote hosts
236 #
237 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
238 src=self.pg1._remote_hosts[3].mac) /
239 ARP(op="who-has",
240 hwsrc=self.pg1._remote_hosts[3].mac,
241 pdst=self.pg1.local_ip4,
242 psrc=self.pg1._remote_hosts[3].ip4))
243
244 self.pg1.add_stream(p)
245 self.pg_enable_capture(self.pg_interfaces)
246 self.pg_start()
247
248 rx = self.pg1.get_capture(1)
249 self.verify_arp_resp(rx[0],
250 self.pg1.local_mac,
251 self.pg1._remote_hosts[3].mac,
252 self.pg1.local_ip4,
253 self.pg1._remote_hosts[3].ip4)
254
255 #
256 # VPP should have learned the mapping for the remote host
257 #
258 self.assertTrue(find_nbr(self,
259 self.pg1.sw_if_index,
260 self.pg1._remote_hosts[3].ip4))
Neale Ranns4b919a52017-03-11 05:55:21 -0800261 #
262 # Fire in an ARP request before the interface becomes IP enabled
263 #
264 self.pg2.generate_remote_hosts(4)
265
266 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
267 ARP(op="who-has",
268 hwsrc=self.pg2.remote_mac,
269 pdst=self.pg1.local_ip4,
270 psrc=self.pg2.remote_hosts[3].ip4))
271 self.send_and_assert_no_replies(self.pg2, p,
272 "interface not IP enabled")
273
274 #
275 # Make pg2 un-numbered to pg1
276 #
277 self.pg2.set_unnumbered(self.pg1.sw_if_index)
278
279 #
280 # We should respond to ARP requests for the unnumbered to address
281 # once an attached route to the source is known
282 #
283 self.send_and_assert_no_replies(
284 self.pg2, p,
285 "ARP req for unnumbered address - no source")
286
287 attached_host = VppIpRoute(self, self.pg2.remote_hosts[3].ip4, 32,
288 [VppRoutePath("0.0.0.0",
289 self.pg2.sw_if_index)])
290 attached_host.add_vpp_config()
291
292 self.pg2.add_stream(p)
293 self.pg_enable_capture(self.pg_interfaces)
294 self.pg_start()
295
296 rx = self.pg2.get_capture(1)
297 self.verify_arp_resp(rx[0],
298 self.pg2.local_mac,
299 self.pg2.remote_mac,
300 self.pg1.local_ip4,
301 self.pg2.remote_hosts[3].ip4)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800302
303 #
Neale Ranns3983ac22017-03-10 11:53:27 -0800304 # A neighbor entry that has no associated FIB-entry
305 #
306 arp_no_fib = VppNeighbor(self,
307 self.pg1.sw_if_index,
308 self.pg1.remote_hosts[4].mac,
309 self.pg1.remote_hosts[4].ip4,
310 is_no_fib_entry=1)
311 arp_no_fib.add_vpp_config()
312
313 #
314 # check we have the neighbor, but no route
315 #
316 self.assertTrue(find_nbr(self,
317 self.pg1.sw_if_index,
318 self.pg1._remote_hosts[4].ip4))
319 self.assertFalse(find_route(self,
320 self.pg1._remote_hosts[4].ip4,
321 32))
322 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800323 # pg2 is unnumbered to pg1, so we can form adjacencies out of pg2
324 # from within pg1's subnet
Neale Ranns3983ac22017-03-10 11:53:27 -0800325 #
326 arp_unnum = VppNeighbor(self,
327 self.pg2.sw_if_index,
328 self.pg1.remote_hosts[5].mac,
329 self.pg1.remote_hosts[5].ip4)
330 arp_unnum.add_vpp_config()
331
332 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
333 IP(src=self.pg0.remote_ip4,
334 dst=self.pg1._remote_hosts[5].ip4) /
335 UDP(sport=1234, dport=1234) /
336 Raw())
337
338 self.pg0.add_stream(p)
339 self.pg_enable_capture(self.pg_interfaces)
340 self.pg_start()
341
342 rx = self.pg2.get_capture(1)
343
344 self.verify_ip(rx[0],
345 self.pg2.local_mac,
346 self.pg1.remote_hosts[5].mac,
347 self.pg0.remote_ip4,
348 self.pg1._remote_hosts[5].ip4)
349
350 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800351 # ARP requests from hosts in pg1's subnet sent on pg2 are replied to
352 # with the unnumbered interface's address as the source
353 #
354 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
355 ARP(op="who-has",
356 hwsrc=self.pg2.remote_mac,
357 pdst=self.pg1.local_ip4,
358 psrc=self.pg1.remote_hosts[6].ip4))
359
360 self.pg2.add_stream(p)
361 self.pg_enable_capture(self.pg_interfaces)
362 self.pg_start()
363
364 rx = self.pg2.get_capture(1)
365 self.verify_arp_resp(rx[0],
366 self.pg2.local_mac,
367 self.pg2.remote_mac,
368 self.pg1.local_ip4,
369 self.pg1.remote_hosts[6].ip4)
370
371 #
372 # An attached host route out of pg2 for an undiscovered hosts generates
373 # an ARP request with the unnumbered address as the source
374 #
375 att_unnum = VppIpRoute(self, self.pg1.remote_hosts[7].ip4, 32,
376 [VppRoutePath("0.0.0.0",
377 self.pg2.sw_if_index)])
378 att_unnum.add_vpp_config()
379
380 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
381 IP(src=self.pg0.remote_ip4,
382 dst=self.pg1._remote_hosts[7].ip4) /
383 UDP(sport=1234, dport=1234) /
384 Raw())
385
386 self.pg0.add_stream(p)
387 self.pg_enable_capture(self.pg_interfaces)
388 self.pg_start()
389
390 rx = self.pg2.get_capture(1)
391
392 self.verify_arp_req(rx[0],
393 self.pg2.local_mac,
394 self.pg1.local_ip4,
395 self.pg1._remote_hosts[7].ip4)
396
397 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
398 ARP(op="who-has",
399 hwsrc=self.pg2.remote_mac,
400 pdst=self.pg1.local_ip4,
401 psrc=self.pg1.remote_hosts[7].ip4))
402
403 self.pg2.add_stream(p)
404 self.pg_enable_capture(self.pg_interfaces)
405 self.pg_start()
406
407 rx = self.pg2.get_capture(1)
408 self.verify_arp_resp(rx[0],
409 self.pg2.local_mac,
410 self.pg2.remote_mac,
411 self.pg1.local_ip4,
412 self.pg1.remote_hosts[7].ip4)
413
414 #
415 # An attached host route as yet unresolved out of pg2 for an
416 # undiscovered host, an ARP requests begets a response.
417 #
418 att_unnum1 = VppIpRoute(self, self.pg1.remote_hosts[8].ip4, 32,
419 [VppRoutePath("0.0.0.0",
420 self.pg2.sw_if_index)])
421 att_unnum1.add_vpp_config()
422
423 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
424 ARP(op="who-has",
425 hwsrc=self.pg2.remote_mac,
426 pdst=self.pg1.local_ip4,
427 psrc=self.pg1.remote_hosts[8].ip4))
428
429 self.pg2.add_stream(p)
430 self.pg_enable_capture(self.pg_interfaces)
431 self.pg_start()
432
433 rx = self.pg2.get_capture(1)
434 self.verify_arp_resp(rx[0],
435 self.pg2.local_mac,
436 self.pg2.remote_mac,
437 self.pg1.local_ip4,
438 self.pg1.remote_hosts[8].ip4)
439
440 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800441 # ERROR Cases
442 # 1 - don't respond to ARP request for address not within the
443 # interface's sub-net
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700444 # 1b - nor within the unnumbered subnet
445 # 1c - nor within the subnet of a different interface
446 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800447 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
448 ARP(op="who-has",
449 hwsrc=self.pg0.remote_mac,
450 pdst="10.10.10.3",
451 psrc=self.pg0.remote_ip4))
452 self.send_and_assert_no_replies(self.pg0, p,
453 "ARP req for non-local destination")
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700454 self.assertFalse(find_nbr(self,
455 self.pg0.sw_if_index,
456 "10.10.10.3"))
457
Neale Ranns4b919a52017-03-11 05:55:21 -0800458 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="10.10.10.3",
462 psrc=self.pg1.remote_hosts[7].ip4))
463 self.send_and_assert_no_replies(
464 self.pg0, p,
465 "ARP req for non-local destination - unnum")
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800466
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700467 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
468 ARP(op="who-has",
469 hwsrc=self.pg0.remote_mac,
470 pdst=self.pg1.local_ip4,
471 psrc=self.pg1.remote_ip4))
472 self.send_and_assert_no_replies(self.pg0, p,
473 "ARP req diff sub-net")
474 self.assertFalse(find_nbr(self,
475 self.pg0.sw_if_index,
476 self.pg1.remote_ip4))
477
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800478 #
479 # 2 - don't respond to ARP request from an address not within the
480 # interface's sub-net
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="10.10.10.3",
486 pdst=self.pg0.local_ip4))
487 self.send_and_assert_no_replies(self.pg0, p,
488 "ARP req for non-local source")
Neale Ranns4b919a52017-03-11 05:55:21 -0800489 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg2.remote_mac) /
490 ARP(op="who-has",
491 hwsrc=self.pg2.remote_mac,
492 psrc="10.10.10.3",
493 pdst=self.pg0.local_ip4))
494 self.send_and_assert_no_replies(
495 self.pg0, p,
496 "ARP req for non-local source - unnum")
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800497
498 #
499 # 3 - don't respond to ARP request from an address that belongs to
500 # the router
501 #
502 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
503 ARP(op="who-has",
504 hwsrc=self.pg0.remote_mac,
505 psrc=self.pg0.local_ip4,
506 pdst=self.pg0.local_ip4))
507 self.send_and_assert_no_replies(self.pg0, p,
508 "ARP req for non-local source")
509
510 #
511 # 4 - don't respond to ARP requests that has mac source different
512 # from ARP request HW source
513 # the router
514 #
515 p = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
516 ARP(op="who-has",
517 hwsrc="00:00:00:DE:AD:BE",
518 psrc=self.pg0.remote_ip4,
519 pdst=self.pg0.local_ip4))
520 self.send_and_assert_no_replies(self.pg0, p,
521 "ARP req for non-local source")
522
523 #
524 # cleanup
525 #
526 dyn_arp.remove_vpp_config()
527 static_arp.remove_vpp_config()
Neale Ranns3983ac22017-03-10 11:53:27 -0800528 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800529
Neale Ranns4b919a52017-03-11 05:55:21 -0800530 # need this to flush the adj-fibs
531 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
532 self.pg2.admin_down()
533
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800534 def test_proxy_arp(self):
535 """ Proxy ARP """
536
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700537 self.pg1.generate_remote_hosts(2)
538
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800539 #
540 # Proxy ARP rewquest packets for each interface
541 #
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800542 arp_req_pg0 = (Ether(src=self.pg0.remote_mac,
543 dst="ff:ff:ff:ff:ff:ff") /
544 ARP(op="who-has",
545 hwsrc=self.pg0.remote_mac,
546 pdst="10.10.10.3",
547 psrc=self.pg0.remote_ip4))
548 arp_req_pg1 = (Ether(src=self.pg1.remote_mac,
549 dst="ff:ff:ff:ff:ff:ff") /
550 ARP(op="who-has",
551 hwsrc=self.pg1.remote_mac,
552 pdst="10.10.10.3",
553 psrc=self.pg1.remote_ip4))
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700554 arp_req_pg2 = (Ether(src=self.pg2.remote_mac,
555 dst="ff:ff:ff:ff:ff:ff") /
556 ARP(op="who-has",
557 hwsrc=self.pg2.remote_mac,
558 pdst="10.10.10.3",
559 psrc=self.pg1.remote_hosts[1].ip4))
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800560 arp_req_pg3 = (Ether(src=self.pg3.remote_mac,
561 dst="ff:ff:ff:ff:ff:ff") /
562 ARP(op="who-has",
563 hwsrc=self.pg3.remote_mac,
564 pdst="10.10.10.3",
565 psrc=self.pg3.remote_ip4))
566
567 #
568 # Configure Proxy ARP for 10.10.10.0 -> 10.10.10.124
569 #
570 self.vapi.proxy_arp_add_del(inet_pton(AF_INET, "10.10.10.2"),
571 inet_pton(AF_INET, "10.10.10.124"))
572
573 #
574 # No responses are sent when the interfaces are not enabled for proxy
575 # ARP
576 #
577 self.send_and_assert_no_replies(self.pg0, arp_req_pg0,
578 "ARP req from unconfigured interface")
579 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
580 "ARP req from unconfigured interface")
581
582 #
583 # Make pg2 un-numbered to pg1
584 # still won't reply.
585 #
586 self.pg2.set_unnumbered(self.pg1.sw_if_index)
587
588 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
589 "ARP req from unnumbered interface")
590
591 #
592 # Enable each interface to reply to proxy ARPs
593 #
594 for i in self.pg_interfaces:
595 i.set_proxy_arp()
596
597 #
598 # Now each of the interfaces should reply to a request to a proxied
599 # address
600 #
601 self.pg0.add_stream(arp_req_pg0)
602 self.pg_enable_capture(self.pg_interfaces)
603 self.pg_start()
604
605 rx = self.pg0.get_capture(1)
606 self.verify_arp_resp(rx[0],
607 self.pg0.local_mac,
608 self.pg0.remote_mac,
609 "10.10.10.3",
610 self.pg0.remote_ip4)
611
612 self.pg1.add_stream(arp_req_pg1)
613 self.pg_enable_capture(self.pg_interfaces)
614 self.pg_start()
615
616 rx = self.pg1.get_capture(1)
617 self.verify_arp_resp(rx[0],
618 self.pg1.local_mac,
619 self.pg1.remote_mac,
620 "10.10.10.3",
621 self.pg1.remote_ip4)
622
623 self.pg2.add_stream(arp_req_pg2)
624 self.pg_enable_capture(self.pg_interfaces)
625 self.pg_start()
626
627 rx = self.pg2.get_capture(1)
628 self.verify_arp_resp(rx[0],
629 self.pg2.local_mac,
630 self.pg2.remote_mac,
631 "10.10.10.3",
Neale Rannsd5b6aa12017-05-16 08:46:45 -0700632 self.pg1.remote_hosts[1].ip4)
Neale Ranns39f9d8b2017-02-16 21:57:05 -0800633
634 #
635 # A request for an address out of the configured range
636 #
637 arp_req_pg1_hi = (Ether(src=self.pg1.remote_mac,
638 dst="ff:ff:ff:ff:ff:ff") /
639 ARP(op="who-has",
640 hwsrc=self.pg1.remote_mac,
641 pdst="10.10.10.125",
642 psrc=self.pg1.remote_ip4))
643 self.send_and_assert_no_replies(self.pg1, arp_req_pg1_hi,
644 "ARP req out of range HI")
645 arp_req_pg1_low = (Ether(src=self.pg1.remote_mac,
646 dst="ff:ff:ff:ff:ff:ff") /
647 ARP(op="who-has",
648 hwsrc=self.pg1.remote_mac,
649 pdst="10.10.10.1",
650 psrc=self.pg1.remote_ip4))
651 self.send_and_assert_no_replies(self.pg1, arp_req_pg1_low,
652 "ARP req out of range Low")
653
654 #
655 # Request for an address in the proxy range but from an interface
656 # in a different VRF
657 #
658 self.send_and_assert_no_replies(self.pg3, arp_req_pg3,
659 "ARP req from different VRF")
660
661 #
662 # Disable Each interface for proxy ARP
663 # - expect none to respond
664 #
665 for i in self.pg_interfaces:
666 i.set_proxy_arp(0)
667
668 self.send_and_assert_no_replies(self.pg0, arp_req_pg0,
669 "ARP req from disable")
670 self.send_and_assert_no_replies(self.pg1, arp_req_pg1,
671 "ARP req from disable")
672 self.send_and_assert_no_replies(self.pg2, arp_req_pg2,
673 "ARP req from disable")
Neale Ranns37be7362017-02-21 17:30:26 -0800674
675 #
676 # clean up on interface 2
677 #
Neale Ranns4b919a52017-03-11 05:55:21 -0800678 self.pg2.unset_unnumbered(self.pg1.sw_if_index)
Neale Ranns37be7362017-02-21 17:30:26 -0800679
680 def test_mpls(self):
681 """ MPLS """
682
683 #
684 # Interface 2 does not yet have ip4 config
685 #
686 self.pg2.config_ip4()
687 self.pg2.generate_remote_hosts(2)
688
689 #
690 # Add a reoute with out going label via an ARP unresolved next-hop
691 #
692 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
693 [VppRoutePath(self.pg2.remote_hosts[1].ip4,
694 self.pg2.sw_if_index,
695 labels=[55])])
696 ip_10_0_0_1.add_vpp_config()
697
698 #
699 # packets should generate an ARP request
700 #
701 p = (Ether(src=self.pg0.remote_mac,
702 dst=self.pg0.local_mac) /
703 IP(src=self.pg0.remote_ip4, dst="10.0.0.1") /
704 UDP(sport=1234, dport=1234) /
705 Raw('\xa5' * 100))
706
707 self.pg0.add_stream(p)
708 self.pg_enable_capture(self.pg_interfaces)
709 self.pg_start()
710
711 rx = self.pg2.get_capture(1)
712 self.verify_arp_req(rx[0],
713 self.pg2.local_mac,
714 self.pg2.local_ip4,
715 self.pg2._remote_hosts[1].ip4)
716
717 #
718 # now resolve the neighbours
719 #
720 self.pg2.configure_ipv4_neighbors()
721
722 #
723 # Now packet should be properly MPLS encapped.
724 # This verifies that MPLS link-type adjacencies are completed
725 # when the ARP entry resolves
726 #
727 self.pg0.add_stream(p)
728 self.pg_enable_capture(self.pg_interfaces)
729 self.pg_start()
730
731 rx = self.pg2.get_capture(1)
732 self.verify_ip_o_mpls(rx[0],
733 self.pg2.local_mac,
734 self.pg2.remote_hosts[1].mac,
735 55,
736 self.pg0.remote_ip4,
737 "10.0.0.1")
Neale Ranns4b919a52017-03-11 05:55:21 -0800738 self.pg2.unconfig_ip4()
Neale Ranns37be7362017-02-21 17:30:26 -0800739
740if __name__ == '__main__':
741 unittest.main(testRunner=VppTestRunner)