blob: 5c8495fed987773545ea7954657b4a31ecc764c6 [file] [log] [blame]
Hongjun Ni62f9cdd2017-07-04 20:11:57 +08001#!/usr/bin/env python
2
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -08003import socket
Hongjun Ni62f9cdd2017-07-04 20:11:57 +08004import unittest
Hongjun Ni62f9cdd2017-07-04 20:11:57 +08005
6from scapy.packet import Raw
7from scapy.layers.l2 import Ether
8from scapy.layers.ppp import PPPoE, PPPoED, PPP
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -08009from scapy.layers.inet import IP
10
11from framework import VppTestCase, VppTestRunner
12from vpp_ip_route import VppIpRoute, VppRoutePath
13from vpp_pppoe_interface import VppPppoeInterface
Ole Troan7f991832018-12-06 17:35:12 +010014from util import ppp, ppc
Hongjun Ni62f9cdd2017-07-04 20:11:57 +080015
16
17class TestPPPoE(VppTestCase):
18 """ PPPoE Test Case """
19
20 @classmethod
21 def setUpClass(cls):
22 super(TestPPPoE, cls).setUpClass()
23
24 cls.session_id = 1
25 cls.dst_ip = "100.1.1.100"
26 cls.dst_ipn = socket.inet_pton(socket.AF_INET, cls.dst_ip)
27
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070028 @classmethod
29 def tearDownClass(cls):
30 super(TestPPPoE, cls).tearDownClass()
31
Hongjun Ni62f9cdd2017-07-04 20:11:57 +080032 def setUp(self):
33 super(TestPPPoE, self).setUp()
34
35 # create 2 pg interfaces
36 self.create_pg_interfaces(range(3))
37
38 for i in self.pg_interfaces:
39 i.admin_up()
40 i.config_ip4()
41 i.resolve_arp()
42
43 def tearDown(self):
44 super(TestPPPoE, self).tearDown()
45
46 self.logger.info(self.vapi.cli("show int"))
47 self.logger.info(self.vapi.cli("show pppoe fib"))
48 self.logger.info(self.vapi.cli("show pppoe session"))
49 self.logger.info(self.vapi.cli("show ip fib"))
50 self.logger.info(self.vapi.cli("show trace"))
51
52 for i in self.pg_interfaces:
53 i.unconfig_ip4()
54 i.admin_down()
55
56 def create_stream_pppoe_discovery(self, src_if, dst_if,
57 client_mac, count=1):
58 packets = []
59 for i in range(count):
60 # create packet info stored in the test case instance
61 info = self.create_packet_info(src_if, dst_if)
62 # convert the info into packet payload
63 payload = self.info_to_payload(info)
64 # create the packet itself
65 p = (Ether(dst=src_if.local_mac, src=client_mac) /
66 PPPoED(sessionid=0) /
67 Raw(payload))
68 # store a copy of the packet in the packet info
69 info.data = p.copy()
70 # append the packet to the list
71 packets.append(p)
72
73 # return the created packet list
74 return packets
75
76 def create_stream_pppoe_lcp(self, src_if, dst_if,
77 client_mac, session_id, count=1):
78 packets = []
79 for i in range(count):
80 # create packet info stored in the test case instance
81 info = self.create_packet_info(src_if, dst_if)
82 # convert the info into packet payload
83 payload = self.info_to_payload(info)
84 # create the packet itself
85 p = (Ether(dst=src_if.local_mac, src=client_mac) /
86 PPPoE(sessionid=session_id) /
87 PPP(proto=0xc021) /
88 Raw(payload))
89 # store a copy of the packet in the packet info
90 info.data = p.copy()
91 # append the packet to the list
92 packets.append(p)
93
94 # return the created packet list
95 return packets
96
97 def create_stream_pppoe_ip4(self, src_if, dst_if,
98 client_mac, session_id, client_ip, count=1):
99 packets = []
100 for i in range(count):
101 # create packet info stored in the test case instance
102 info = self.create_packet_info(src_if, dst_if)
103 # convert the info into packet payload
104 payload = self.info_to_payload(info)
105 # create the packet itself
106 p = (Ether(dst=src_if.local_mac, src=client_mac) /
107 PPPoE(sessionid=session_id) /
108 PPP(proto=0x0021) /
109 IP(src=client_ip, dst=self.dst_ip) /
110 Raw(payload))
111 # store a copy of the packet in the packet info
112 info.data = p.copy()
113 # append the packet to the list
114 packets.append(p)
115
116 # return the created packet list
117 return packets
118
119 def create_stream_ip4(self, src_if, dst_if, client_ip, dst_ip, count=1):
120 pkts = []
121 for i in range(count):
122 # create packet info stored in the test case instance
123 info = self.create_packet_info(src_if, dst_if)
124 # convert the info into packet payload
125 payload = self.info_to_payload(info)
126 # create the packet itself
127 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
128 IP(src=dst_ip, dst=client_ip) /
129 Raw(payload))
130 # store a copy of the packet in the packet info
131 info.data = p.copy()
132 # append the packet to the list
133 pkts.append(p)
134
135 # return the created packet list
136 return pkts
137
138 def verify_decapped_pppoe(self, src_if, capture, sent):
139 self.assertEqual(len(capture), len(sent))
140
141 for i in range(len(capture)):
142 try:
143 tx = sent[i]
144 rx = capture[i]
145
146 tx_ip = tx[IP]
147 rx_ip = rx[IP]
148
149 self.assertEqual(rx_ip.src, tx_ip.src)
150 self.assertEqual(rx_ip.dst, tx_ip.dst)
151
152 except:
153 self.logger.error(ppp("Rx:", rx))
154 self.logger.error(ppp("Tx:", tx))
155 raise
156
157 def verify_encaped_pppoe(self, src_if, capture, sent, session_id):
158
159 self.assertEqual(len(capture), len(sent))
160
161 for i in range(len(capture)):
162 try:
163 tx = sent[i]
164 rx = capture[i]
165
166 tx_ip = tx[IP]
167 rx_ip = rx[IP]
168
169 self.assertEqual(rx_ip.src, tx_ip.src)
170 self.assertEqual(rx_ip.dst, tx_ip.dst)
171
172 rx_pppoe = rx[PPPoE]
173
174 self.assertEqual(rx_pppoe.sessionid, session_id)
175
176 except:
177 self.logger.error(ppp("Rx:", rx))
178 self.logger.error(ppp("Tx:", tx))
179 raise
180
181 def test_PPPoE_Decap(self):
182 """ PPPoE Decap Test """
183
184 self.vapi.cli("clear trace")
185
186 #
187 # Add a route that resolves the server's destination
188 #
189 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
190 [VppRoutePath(self.pg1.remote_ip4,
191 self.pg1.sw_if_index)])
192 route_sever_dst.add_vpp_config()
193
194 # Send PPPoE Discovery
195 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
196 self.pg0.remote_mac)
197 self.pg0.add_stream(tx0)
198 self.pg_start()
199
200 # Send PPPoE PPP LCP
201 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
202 self.pg0.remote_mac,
203 self.session_id)
204 self.pg0.add_stream(tx1)
205 self.pg_start()
206
207 # Create PPPoE session
208 pppoe_if = VppPppoeInterface(self,
209 self.pg0.remote_ip4,
210 self.pg0.remote_mac,
211 self.session_id)
212 pppoe_if.add_vpp_config()
213
214 #
215 # Send tunneled packets that match the created tunnel and
216 # are decapped and forwarded
217 #
218 tx2 = self.create_stream_pppoe_ip4(self.pg0, self.pg1,
219 self.pg0.remote_mac,
220 self.session_id,
221 self.pg0.remote_ip4)
222 self.pg0.add_stream(tx2)
223
224 self.pg_enable_capture(self.pg_interfaces)
225 self.pg_start()
226
227 rx2 = self.pg1.get_capture(len(tx2))
228 self.verify_decapped_pppoe(self.pg0, rx2, tx2)
229
230 self.logger.info(self.vapi.cli("show pppoe fib"))
231 self.logger.info(self.vapi.cli("show pppoe session"))
232 self.logger.info(self.vapi.cli("show ip fib"))
233
234 #
235 # test case cleanup
236 #
237
238 # Delete PPPoE session
239 pppoe_if.remove_vpp_config()
240
241 # Delete a route that resolves the server's destination
242 route_sever_dst.remove_vpp_config()
243
244 def test_PPPoE_Encap(self):
245 """ PPPoE Encap Test """
246
247 self.vapi.cli("clear trace")
248
249 #
250 # Add a route that resolves the server's destination
251 #
252 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
253 [VppRoutePath(self.pg1.remote_ip4,
254 self.pg1.sw_if_index)])
255 route_sever_dst.add_vpp_config()
256
257 # Send PPPoE Discovery
258 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
259 self.pg0.remote_mac)
260 self.pg0.add_stream(tx0)
261 self.pg_start()
262
263 # Send PPPoE PPP LCP
264 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
265 self.pg0.remote_mac,
266 self.session_id)
267 self.pg0.add_stream(tx1)
268 self.pg_start()
269
270 # Create PPPoE session
271 pppoe_if = VppPppoeInterface(self,
272 self.pg0.remote_ip4,
273 self.pg0.remote_mac,
274 self.session_id)
275 pppoe_if.add_vpp_config()
276
277 #
278 # Send a packet stream that is routed into the session
279 # - packets are PPPoE encapped
280 #
281 self.vapi.cli("clear trace")
282 tx2 = self.create_stream_ip4(self.pg1, self.pg0,
Neale Ranns43161a82017-08-12 02:12:00 -0700283 self.pg0.remote_ip4, self.dst_ip, 65)
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800284 self.pg1.add_stream(tx2)
285
286 self.pg_enable_capture(self.pg_interfaces)
287 self.pg_start()
288
289 rx2 = self.pg0.get_capture(len(tx2))
290 self.verify_encaped_pppoe(self.pg1, rx2, tx2, self.session_id)
291
292 self.logger.info(self.vapi.cli("show pppoe fib"))
293 self.logger.info(self.vapi.cli("show pppoe session"))
294 self.logger.info(self.vapi.cli("show ip fib"))
Neale Ranns43161a82017-08-12 02:12:00 -0700295 self.logger.info(self.vapi.cli("show adj"))
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800296
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:
Hongjun Niad2ddb12017-11-17 23:43:11 +0800345 pppoe_if.add_vpp_config()
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800346 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:
Hongjun Niad2ddb12017-11-17 23:43:11 +0800402 pppoe_if.remove_vpp_config()
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800403 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)