blob: 0baf45467e5f6150391068473634c8a1646c80ce [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,
284 self.pg0.remote_ip4, self.dst_ip)
285 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"))
296
297 #
298 # test case cleanup
299 #
300
301 # Delete PPPoE session
302 pppoe_if.remove_vpp_config()
303
304 # Delete a route that resolves the server's destination
305 route_sever_dst.remove_vpp_config()
306
307 def test_PPPoE_Add_Twice(self):
308 """ PPPoE Add Same Session Twice Test """
309
310 self.vapi.cli("clear trace")
311
312 #
313 # Add a route that resolves the server's destination
314 #
315 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
316 [VppRoutePath(self.pg1.remote_ip4,
317 self.pg1.sw_if_index)])
318 route_sever_dst.add_vpp_config()
319
320 # Send PPPoE Discovery
321 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
322 self.pg0.remote_mac)
323 self.pg0.add_stream(tx0)
324 self.pg_start()
325
326 # Send PPPoE PPP LCP
327 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
328 self.pg0.remote_mac,
329 self.session_id)
330 self.pg0.add_stream(tx1)
331 self.pg_start()
332
333 # Create PPPoE session
334 pppoe_if = VppPppoeInterface(self,
335 self.pg0.remote_ip4,
336 self.pg0.remote_mac,
337 self.session_id)
338 pppoe_if.add_vpp_config()
339
340 #
341 # The double create (create the same session twice) should fail,
342 # and we should still be able to use the original
343 #
344 try:
345 gre_if.add_vpp_config()
346 except Exception:
347 pass
348 else:
349 self.fail("Double GRE tunnel add does not fail")
350
351 #
352 # test case cleanup
353 #
354
355 # Delete PPPoE session
356 pppoe_if.remove_vpp_config()
357
358 # Delete a route that resolves the server's destination
359 route_sever_dst.remove_vpp_config()
360
361 def test_PPPoE_Del_Twice(self):
362 """ PPPoE Delete Same Session Twice Test """
363
364 self.vapi.cli("clear trace")
365
366 #
367 # Add a route that resolves the server's destination
368 #
369 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
370 [VppRoutePath(self.pg1.remote_ip4,
371 self.pg1.sw_if_index)])
372 route_sever_dst.add_vpp_config()
373
374 # Send PPPoE Discovery
375 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
376 self.pg0.remote_mac)
377 self.pg0.add_stream(tx0)
378 self.pg_start()
379
380 # Send PPPoE PPP LCP
381 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
382 self.pg0.remote_mac,
383 self.session_id)
384 self.pg0.add_stream(tx1)
385 self.pg_start()
386
387 # Create PPPoE session
388 pppoe_if = VppPppoeInterface(self,
389 self.pg0.remote_ip4,
390 self.pg0.remote_mac,
391 self.session_id)
392 pppoe_if.add_vpp_config()
393
394 # Delete PPPoE session
395 pppoe_if.remove_vpp_config()
396
397 #
398 # The double del (del the same session twice) should fail,
399 # and we should still be able to use the original
400 #
401 try:
402 gre_if.remove_vpp_config()
403 except Exception:
404 pass
405 else:
406 self.fail("Double GRE tunnel del does not fail")
407
408 #
409 # test case cleanup
410 #
411
412 # Delete a route that resolves the server's destination
413 route_sever_dst.remove_vpp_config()
414
415 def test_PPPoE_Decap_Multiple(self):
416 """ PPPoE Decap Multiple Sessions Test """
417
418 self.vapi.cli("clear trace")
419
420 #
421 # Add a route that resolves the server's destination
422 #
423 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
424 [VppRoutePath(self.pg1.remote_ip4,
425 self.pg1.sw_if_index)])
426 route_sever_dst.add_vpp_config()
427
428 # Send PPPoE Discovery 1
429 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
430 self.pg0.remote_mac)
431 self.pg0.add_stream(tx0)
432 self.pg_start()
433
434 # Send PPPoE PPP LCP 1
435 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
436 self.pg0.remote_mac,
437 self.session_id)
438 self.pg0.add_stream(tx1)
439 self.pg_start()
440
441 # Create PPPoE session 1
442 pppoe_if1 = VppPppoeInterface(self,
443 self.pg0.remote_ip4,
444 self.pg0.remote_mac,
445 self.session_id)
446 pppoe_if1.add_vpp_config()
447
448 # Send PPPoE Discovery 2
449 tx3 = self.create_stream_pppoe_discovery(self.pg2, self.pg1,
450 self.pg2.remote_mac)
451 self.pg2.add_stream(tx3)
452 self.pg_start()
453
454 # Send PPPoE PPP LCP 2
455 tx4 = self.create_stream_pppoe_lcp(self.pg2, self.pg1,
456 self.pg2.remote_mac,
457 self.session_id + 1)
458 self.pg2.add_stream(tx4)
459 self.pg_start()
460
461 # Create PPPoE session 2
462 pppoe_if2 = VppPppoeInterface(self,
463 self.pg2.remote_ip4,
464 self.pg2.remote_mac,
465 self.session_id + 1)
466 pppoe_if2.add_vpp_config()
467
468 #
469 # Send tunneled packets that match the created tunnel and
470 # are decapped and forwarded
471 #
472 tx2 = self.create_stream_pppoe_ip4(self.pg0, self.pg1,
473 self.pg0.remote_mac,
474 self.session_id,
475 self.pg0.remote_ip4)
476 self.pg0.add_stream(tx2)
477
478 self.pg_enable_capture(self.pg_interfaces)
479 self.pg_start()
480
481 rx2 = self.pg1.get_capture(len(tx2))
482 self.verify_decapped_pppoe(self.pg0, rx2, tx2)
483
484 tx5 = self.create_stream_pppoe_ip4(self.pg2, self.pg1,
485 self.pg2.remote_mac,
486 self.session_id + 1,
487 self.pg2.remote_ip4)
488 self.pg2.add_stream(tx5)
489
490 self.pg_enable_capture(self.pg_interfaces)
491 self.pg_start()
492
493 rx5 = self.pg1.get_capture(len(tx5))
494 self.verify_decapped_pppoe(self.pg2, rx5, tx5)
495
496 self.logger.info(self.vapi.cli("show pppoe fib"))
497 self.logger.info(self.vapi.cli("show pppoe session"))
498 self.logger.info(self.vapi.cli("show ip fib"))
499
500 #
501 # test case cleanup
502 #
503
504 # Delete PPPoE session
505 pppoe_if1.remove_vpp_config()
506 pppoe_if2.remove_vpp_config()
507
508 # Delete a route that resolves the server's destination
509 route_sever_dst.remove_vpp_config()
510
511 def test_PPPoE_Encap_Multiple(self):
512 """ PPPoE Encap Multiple Sessions Test """
513
514 self.vapi.cli("clear trace")
515
516 #
517 # Add a route that resolves the server's destination
518 #
519 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
520 [VppRoutePath(self.pg1.remote_ip4,
521 self.pg1.sw_if_index)])
522 route_sever_dst.add_vpp_config()
523
524 # Send PPPoE Discovery 1
525 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
526 self.pg0.remote_mac)
527 self.pg0.add_stream(tx0)
528 self.pg_start()
529
530 # Send PPPoE PPP LCP 1
531 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
532 self.pg0.remote_mac,
533 self.session_id)
534 self.pg0.add_stream(tx1)
535 self.pg_start()
536
537 # Create PPPoE session 1
538 pppoe_if1 = VppPppoeInterface(self,
539 self.pg0.remote_ip4,
540 self.pg0.remote_mac,
541 self.session_id)
542 pppoe_if1.add_vpp_config()
543
544 # Send PPPoE Discovery 2
545 tx3 = self.create_stream_pppoe_discovery(self.pg2, self.pg1,
546 self.pg2.remote_mac)
547 self.pg2.add_stream(tx3)
548 self.pg_start()
549
550 # Send PPPoE PPP LCP 2
551 tx4 = self.create_stream_pppoe_lcp(self.pg2, self.pg1,
552 self.pg2.remote_mac,
553 self.session_id + 1)
554 self.pg2.add_stream(tx4)
555 self.pg_start()
556
557 # Create PPPoE session 2
558 pppoe_if2 = VppPppoeInterface(self,
559 self.pg2.remote_ip4,
560 self.pg2.remote_mac,
561 self.session_id + 1)
562 pppoe_if2.add_vpp_config()
563
564 #
565 # Send a packet stream that is routed into the session
566 # - packets are PPPoE encapped
567 #
568 self.vapi.cli("clear trace")
569 tx2 = self.create_stream_ip4(self.pg1, self.pg0,
570 self.pg0.remote_ip4, self.dst_ip)
571 self.pg1.add_stream(tx2)
572
573 self.pg_enable_capture(self.pg_interfaces)
574 self.pg_start()
575
576 rx2 = self.pg0.get_capture(len(tx2))
577 self.verify_encaped_pppoe(self.pg1, rx2, tx2, self.session_id)
578
579 tx5 = self.create_stream_ip4(self.pg1, self.pg2,
580 self.pg2.remote_ip4, self.dst_ip)
581 self.pg1.add_stream(tx5)
582
583 self.pg_enable_capture(self.pg_interfaces)
584 self.pg_start()
585
586 rx5 = self.pg2.get_capture(len(tx5))
587 self.verify_encaped_pppoe(self.pg1, rx5, tx5, self.session_id + 1)
588
589 self.logger.info(self.vapi.cli("show pppoe fib"))
590 self.logger.info(self.vapi.cli("show pppoe session"))
591 self.logger.info(self.vapi.cli("show ip fib"))
592
593 #
594 # test case cleanup
595 #
596
597 # Delete PPPoE session
598 pppoe_if1.remove_vpp_config()
599 pppoe_if2.remove_vpp_config()
600
601 # Delete a route that resolves the server's destination
602 route_sever_dst.remove_vpp_config()
603
604if __name__ == '__main__':
605 unittest.main(testRunner=VppTestRunner)