blob: 1d0aeffda3729695f80af1babf457d400f23e13d [file] [log] [blame]
Hongjun Ni62f9cdd2017-07-04 20:11:57 +08001#!/usr/bin/env python
2
3import unittest
4from logging import *
5
6from framework import VppTestCase, VppTestRunner
7from vpp_ip_route import VppIpRoute, VppRoutePath
8from vpp_pppoe_interface import VppPppoeInterface, VppPppoe6Interface
9from vpp_papi_provider import L2_VTR_OP
10
11from scapy.packet import Raw
12from scapy.layers.l2 import Ether
13from scapy.layers.ppp import PPPoE, PPPoED, PPP
14from scapy.layers.inet import IP, UDP
15from scapy.layers.inet6 import IPv6
16from scapy.volatile import RandMAC, RandIP
17
18from util import ppp, ppc, mactobinary
19import socket
20
21
22class TestPPPoE(VppTestCase):
23 """ PPPoE Test Case """
24
25 @classmethod
26 def setUpClass(cls):
27 super(TestPPPoE, cls).setUpClass()
28
29 cls.session_id = 1
30 cls.dst_ip = "100.1.1.100"
31 cls.dst_ipn = socket.inet_pton(socket.AF_INET, cls.dst_ip)
32
33 def setUp(self):
34 super(TestPPPoE, self).setUp()
35
36 # create 2 pg interfaces
37 self.create_pg_interfaces(range(3))
38
39 for i in self.pg_interfaces:
40 i.admin_up()
41 i.config_ip4()
42 i.resolve_arp()
43
44 def tearDown(self):
45 super(TestPPPoE, self).tearDown()
46
47 self.logger.info(self.vapi.cli("show int"))
48 self.logger.info(self.vapi.cli("show pppoe fib"))
49 self.logger.info(self.vapi.cli("show pppoe session"))
50 self.logger.info(self.vapi.cli("show ip fib"))
51 self.logger.info(self.vapi.cli("show trace"))
52
53 for i in self.pg_interfaces:
54 i.unconfig_ip4()
55 i.admin_down()
56
57 def create_stream_pppoe_discovery(self, src_if, dst_if,
58 client_mac, count=1):
59 packets = []
60 for i in range(count):
61 # create packet info stored in the test case instance
62 info = self.create_packet_info(src_if, dst_if)
63 # convert the info into packet payload
64 payload = self.info_to_payload(info)
65 # create the packet itself
66 p = (Ether(dst=src_if.local_mac, src=client_mac) /
67 PPPoED(sessionid=0) /
68 Raw(payload))
69 # store a copy of the packet in the packet info
70 info.data = p.copy()
71 # append the packet to the list
72 packets.append(p)
73
74 # return the created packet list
75 return packets
76
77 def create_stream_pppoe_lcp(self, src_if, dst_if,
78 client_mac, session_id, count=1):
79 packets = []
80 for i in range(count):
81 # create packet info stored in the test case instance
82 info = self.create_packet_info(src_if, dst_if)
83 # convert the info into packet payload
84 payload = self.info_to_payload(info)
85 # create the packet itself
86 p = (Ether(dst=src_if.local_mac, src=client_mac) /
87 PPPoE(sessionid=session_id) /
88 PPP(proto=0xc021) /
89 Raw(payload))
90 # store a copy of the packet in the packet info
91 info.data = p.copy()
92 # append the packet to the list
93 packets.append(p)
94
95 # return the created packet list
96 return packets
97
98 def create_stream_pppoe_ip4(self, src_if, dst_if,
99 client_mac, session_id, client_ip, count=1):
100 packets = []
101 for i in range(count):
102 # create packet info stored in the test case instance
103 info = self.create_packet_info(src_if, dst_if)
104 # convert the info into packet payload
105 payload = self.info_to_payload(info)
106 # create the packet itself
107 p = (Ether(dst=src_if.local_mac, src=client_mac) /
108 PPPoE(sessionid=session_id) /
109 PPP(proto=0x0021) /
110 IP(src=client_ip, dst=self.dst_ip) /
111 Raw(payload))
112 # store a copy of the packet in the packet info
113 info.data = p.copy()
114 # append the packet to the list
115 packets.append(p)
116
117 # return the created packet list
118 return packets
119
120 def create_stream_ip4(self, src_if, dst_if, client_ip, dst_ip, count=1):
121 pkts = []
122 for i in range(count):
123 # create packet info stored in the test case instance
124 info = self.create_packet_info(src_if, dst_if)
125 # convert the info into packet payload
126 payload = self.info_to_payload(info)
127 # create the packet itself
128 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
129 IP(src=dst_ip, dst=client_ip) /
130 Raw(payload))
131 # store a copy of the packet in the packet info
132 info.data = p.copy()
133 # append the packet to the list
134 pkts.append(p)
135
136 # return the created packet list
137 return pkts
138
139 def verify_decapped_pppoe(self, src_if, capture, sent):
140 self.assertEqual(len(capture), len(sent))
141
142 for i in range(len(capture)):
143 try:
144 tx = sent[i]
145 rx = capture[i]
146
147 tx_ip = tx[IP]
148 rx_ip = rx[IP]
149
150 self.assertEqual(rx_ip.src, tx_ip.src)
151 self.assertEqual(rx_ip.dst, tx_ip.dst)
152
153 except:
154 self.logger.error(ppp("Rx:", rx))
155 self.logger.error(ppp("Tx:", tx))
156 raise
157
158 def verify_encaped_pppoe(self, src_if, capture, sent, session_id):
159
160 self.assertEqual(len(capture), len(sent))
161
162 for i in range(len(capture)):
163 try:
164 tx = sent[i]
165 rx = capture[i]
166
167 tx_ip = tx[IP]
168 rx_ip = rx[IP]
169
170 self.assertEqual(rx_ip.src, tx_ip.src)
171 self.assertEqual(rx_ip.dst, tx_ip.dst)
172
173 rx_pppoe = rx[PPPoE]
174
175 self.assertEqual(rx_pppoe.sessionid, session_id)
176
177 except:
178 self.logger.error(ppp("Rx:", rx))
179 self.logger.error(ppp("Tx:", tx))
180 raise
181
182 def test_PPPoE_Decap(self):
183 """ PPPoE Decap Test """
184
185 self.vapi.cli("clear trace")
186
187 #
188 # Add a route that resolves the server's destination
189 #
190 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
191 [VppRoutePath(self.pg1.remote_ip4,
192 self.pg1.sw_if_index)])
193 route_sever_dst.add_vpp_config()
194
195 # Send PPPoE Discovery
196 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
197 self.pg0.remote_mac)
198 self.pg0.add_stream(tx0)
199 self.pg_start()
200
201 # Send PPPoE PPP LCP
202 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
203 self.pg0.remote_mac,
204 self.session_id)
205 self.pg0.add_stream(tx1)
206 self.pg_start()
207
208 # Create PPPoE session
209 pppoe_if = VppPppoeInterface(self,
210 self.pg0.remote_ip4,
211 self.pg0.remote_mac,
212 self.session_id)
213 pppoe_if.add_vpp_config()
214
215 #
216 # Send tunneled packets that match the created tunnel and
217 # are decapped and forwarded
218 #
219 tx2 = self.create_stream_pppoe_ip4(self.pg0, self.pg1,
220 self.pg0.remote_mac,
221 self.session_id,
222 self.pg0.remote_ip4)
223 self.pg0.add_stream(tx2)
224
225 self.pg_enable_capture(self.pg_interfaces)
226 self.pg_start()
227
228 rx2 = self.pg1.get_capture(len(tx2))
229 self.verify_decapped_pppoe(self.pg0, rx2, tx2)
230
231 self.logger.info(self.vapi.cli("show pppoe fib"))
232 self.logger.info(self.vapi.cli("show pppoe session"))
233 self.logger.info(self.vapi.cli("show ip fib"))
234
235 #
236 # test case cleanup
237 #
238
239 # Delete PPPoE session
240 pppoe_if.remove_vpp_config()
241
242 # Delete a route that resolves the server's destination
243 route_sever_dst.remove_vpp_config()
244
245 def test_PPPoE_Encap(self):
246 """ PPPoE Encap Test """
247
248 self.vapi.cli("clear trace")
249
250 #
251 # Add a route that resolves the server's destination
252 #
253 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
254 [VppRoutePath(self.pg1.remote_ip4,
255 self.pg1.sw_if_index)])
256 route_sever_dst.add_vpp_config()
257
258 # Send PPPoE Discovery
259 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
260 self.pg0.remote_mac)
261 self.pg0.add_stream(tx0)
262 self.pg_start()
263
264 # Send PPPoE PPP LCP
265 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
266 self.pg0.remote_mac,
267 self.session_id)
268 self.pg0.add_stream(tx1)
269 self.pg_start()
270
271 # Create PPPoE session
272 pppoe_if = VppPppoeInterface(self,
273 self.pg0.remote_ip4,
274 self.pg0.remote_mac,
275 self.session_id)
276 pppoe_if.add_vpp_config()
277
278 #
279 # Send a packet stream that is routed into the session
280 # - packets are PPPoE encapped
281 #
282 self.vapi.cli("clear trace")
283 tx2 = self.create_stream_ip4(self.pg1, self.pg0,
Neale Ranns43161a82017-08-12 02:12:00 -0700284 self.pg0.remote_ip4, self.dst_ip, 65)
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800285 self.pg1.add_stream(tx2)
286
287 self.pg_enable_capture(self.pg_interfaces)
288 self.pg_start()
289
290 rx2 = self.pg0.get_capture(len(tx2))
291 self.verify_encaped_pppoe(self.pg1, rx2, tx2, self.session_id)
292
293 self.logger.info(self.vapi.cli("show pppoe fib"))
294 self.logger.info(self.vapi.cli("show pppoe session"))
295 self.logger.info(self.vapi.cli("show ip fib"))
Neale Ranns43161a82017-08-12 02:12:00 -0700296 self.logger.info(self.vapi.cli("show adj"))
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800297
298 #
299 # test case cleanup
300 #
301
302 # Delete PPPoE session
303 pppoe_if.remove_vpp_config()
304
305 # Delete a route that resolves the server's destination
306 route_sever_dst.remove_vpp_config()
307
308 def test_PPPoE_Add_Twice(self):
309 """ PPPoE Add Same Session Twice Test """
310
311 self.vapi.cli("clear trace")
312
313 #
314 # Add a route that resolves the server's destination
315 #
316 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
317 [VppRoutePath(self.pg1.remote_ip4,
318 self.pg1.sw_if_index)])
319 route_sever_dst.add_vpp_config()
320
321 # Send PPPoE Discovery
322 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
323 self.pg0.remote_mac)
324 self.pg0.add_stream(tx0)
325 self.pg_start()
326
327 # Send PPPoE PPP LCP
328 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
329 self.pg0.remote_mac,
330 self.session_id)
331 self.pg0.add_stream(tx1)
332 self.pg_start()
333
334 # Create PPPoE session
335 pppoe_if = VppPppoeInterface(self,
336 self.pg0.remote_ip4,
337 self.pg0.remote_mac,
338 self.session_id)
339 pppoe_if.add_vpp_config()
340
341 #
342 # The double create (create the same session twice) should fail,
343 # and we should still be able to use the original
344 #
345 try:
346 gre_if.add_vpp_config()
347 except Exception:
348 pass
349 else:
350 self.fail("Double GRE tunnel add does not fail")
351
352 #
353 # test case cleanup
354 #
355
356 # Delete PPPoE session
357 pppoe_if.remove_vpp_config()
358
359 # Delete a route that resolves the server's destination
360 route_sever_dst.remove_vpp_config()
361
362 def test_PPPoE_Del_Twice(self):
363 """ PPPoE Delete Same Session Twice Test """
364
365 self.vapi.cli("clear trace")
366
367 #
368 # Add a route that resolves the server's destination
369 #
370 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
371 [VppRoutePath(self.pg1.remote_ip4,
372 self.pg1.sw_if_index)])
373 route_sever_dst.add_vpp_config()
374
375 # Send PPPoE Discovery
376 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
377 self.pg0.remote_mac)
378 self.pg0.add_stream(tx0)
379 self.pg_start()
380
381 # Send PPPoE PPP LCP
382 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
383 self.pg0.remote_mac,
384 self.session_id)
385 self.pg0.add_stream(tx1)
386 self.pg_start()
387
388 # Create PPPoE session
389 pppoe_if = VppPppoeInterface(self,
390 self.pg0.remote_ip4,
391 self.pg0.remote_mac,
392 self.session_id)
393 pppoe_if.add_vpp_config()
394
395 # Delete PPPoE session
396 pppoe_if.remove_vpp_config()
397
398 #
399 # The double del (del the same session twice) should fail,
400 # and we should still be able to use the original
401 #
402 try:
403 gre_if.remove_vpp_config()
404 except Exception:
405 pass
406 else:
407 self.fail("Double GRE tunnel del does not fail")
408
409 #
410 # test case cleanup
411 #
412
413 # Delete a route that resolves the server's destination
414 route_sever_dst.remove_vpp_config()
415
416 def test_PPPoE_Decap_Multiple(self):
417 """ PPPoE Decap Multiple Sessions Test """
418
419 self.vapi.cli("clear trace")
420
421 #
422 # Add a route that resolves the server's destination
423 #
424 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
425 [VppRoutePath(self.pg1.remote_ip4,
426 self.pg1.sw_if_index)])
427 route_sever_dst.add_vpp_config()
428
429 # Send PPPoE Discovery 1
430 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
431 self.pg0.remote_mac)
432 self.pg0.add_stream(tx0)
433 self.pg_start()
434
435 # Send PPPoE PPP LCP 1
436 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
437 self.pg0.remote_mac,
438 self.session_id)
439 self.pg0.add_stream(tx1)
440 self.pg_start()
441
442 # Create PPPoE session 1
443 pppoe_if1 = VppPppoeInterface(self,
444 self.pg0.remote_ip4,
445 self.pg0.remote_mac,
446 self.session_id)
447 pppoe_if1.add_vpp_config()
448
449 # Send PPPoE Discovery 2
450 tx3 = self.create_stream_pppoe_discovery(self.pg2, self.pg1,
451 self.pg2.remote_mac)
452 self.pg2.add_stream(tx3)
453 self.pg_start()
454
455 # Send PPPoE PPP LCP 2
456 tx4 = self.create_stream_pppoe_lcp(self.pg2, self.pg1,
457 self.pg2.remote_mac,
458 self.session_id + 1)
459 self.pg2.add_stream(tx4)
460 self.pg_start()
461
462 # Create PPPoE session 2
463 pppoe_if2 = VppPppoeInterface(self,
464 self.pg2.remote_ip4,
465 self.pg2.remote_mac,
466 self.session_id + 1)
467 pppoe_if2.add_vpp_config()
468
469 #
470 # Send tunneled packets that match the created tunnel and
471 # are decapped and forwarded
472 #
473 tx2 = self.create_stream_pppoe_ip4(self.pg0, self.pg1,
474 self.pg0.remote_mac,
475 self.session_id,
476 self.pg0.remote_ip4)
477 self.pg0.add_stream(tx2)
478
479 self.pg_enable_capture(self.pg_interfaces)
480 self.pg_start()
481
482 rx2 = self.pg1.get_capture(len(tx2))
483 self.verify_decapped_pppoe(self.pg0, rx2, tx2)
484
485 tx5 = self.create_stream_pppoe_ip4(self.pg2, self.pg1,
486 self.pg2.remote_mac,
487 self.session_id + 1,
488 self.pg2.remote_ip4)
489 self.pg2.add_stream(tx5)
490
491 self.pg_enable_capture(self.pg_interfaces)
492 self.pg_start()
493
494 rx5 = self.pg1.get_capture(len(tx5))
495 self.verify_decapped_pppoe(self.pg2, rx5, tx5)
496
497 self.logger.info(self.vapi.cli("show pppoe fib"))
498 self.logger.info(self.vapi.cli("show pppoe session"))
499 self.logger.info(self.vapi.cli("show ip fib"))
500
501 #
502 # test case cleanup
503 #
504
505 # Delete PPPoE session
506 pppoe_if1.remove_vpp_config()
507 pppoe_if2.remove_vpp_config()
508
509 # Delete a route that resolves the server's destination
510 route_sever_dst.remove_vpp_config()
511
512 def test_PPPoE_Encap_Multiple(self):
513 """ PPPoE Encap Multiple Sessions Test """
514
515 self.vapi.cli("clear trace")
516
517 #
518 # Add a route that resolves the server's destination
519 #
520 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
521 [VppRoutePath(self.pg1.remote_ip4,
522 self.pg1.sw_if_index)])
523 route_sever_dst.add_vpp_config()
524
525 # Send PPPoE Discovery 1
526 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
527 self.pg0.remote_mac)
528 self.pg0.add_stream(tx0)
529 self.pg_start()
530
531 # Send PPPoE PPP LCP 1
532 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
533 self.pg0.remote_mac,
534 self.session_id)
535 self.pg0.add_stream(tx1)
536 self.pg_start()
537
538 # Create PPPoE session 1
539 pppoe_if1 = VppPppoeInterface(self,
540 self.pg0.remote_ip4,
541 self.pg0.remote_mac,
542 self.session_id)
543 pppoe_if1.add_vpp_config()
544
545 # Send PPPoE Discovery 2
546 tx3 = self.create_stream_pppoe_discovery(self.pg2, self.pg1,
547 self.pg2.remote_mac)
548 self.pg2.add_stream(tx3)
549 self.pg_start()
550
551 # Send PPPoE PPP LCP 2
552 tx4 = self.create_stream_pppoe_lcp(self.pg2, self.pg1,
553 self.pg2.remote_mac,
554 self.session_id + 1)
555 self.pg2.add_stream(tx4)
556 self.pg_start()
557
558 # Create PPPoE session 2
559 pppoe_if2 = VppPppoeInterface(self,
560 self.pg2.remote_ip4,
561 self.pg2.remote_mac,
562 self.session_id + 1)
563 pppoe_if2.add_vpp_config()
564
565 #
566 # Send a packet stream that is routed into the session
567 # - packets are PPPoE encapped
568 #
569 self.vapi.cli("clear trace")
570 tx2 = self.create_stream_ip4(self.pg1, self.pg0,
571 self.pg0.remote_ip4, self.dst_ip)
572 self.pg1.add_stream(tx2)
573
574 self.pg_enable_capture(self.pg_interfaces)
575 self.pg_start()
576
577 rx2 = self.pg0.get_capture(len(tx2))
578 self.verify_encaped_pppoe(self.pg1, rx2, tx2, self.session_id)
579
580 tx5 = self.create_stream_ip4(self.pg1, self.pg2,
581 self.pg2.remote_ip4, self.dst_ip)
582 self.pg1.add_stream(tx5)
583
584 self.pg_enable_capture(self.pg_interfaces)
585 self.pg_start()
586
587 rx5 = self.pg2.get_capture(len(tx5))
588 self.verify_encaped_pppoe(self.pg1, rx5, tx5, self.session_id + 1)
589
590 self.logger.info(self.vapi.cli("show pppoe fib"))
591 self.logger.info(self.vapi.cli("show pppoe session"))
592 self.logger.info(self.vapi.cli("show ip fib"))
593
594 #
595 # test case cleanup
596 #
597
598 # Delete PPPoE session
599 pppoe_if1.remove_vpp_config()
600 pppoe_if2.remove_vpp_config()
601
602 # Delete a route that resolves the server's destination
603 route_sever_dst.remove_vpp_config()
604
605if __name__ == '__main__':
606 unittest.main(testRunner=VppTestRunner)