blob: 99dba01cdc94f4baf8f062181404226a7b5a1b04 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Hongjun Ni62f9cdd2017-07-04 20:11:57 +08002
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
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -070046 for i in self.pg_interfaces:
47 i.unconfig_ip4()
48 i.admin_down()
49
50 def show_commands_at_teardown(self):
Hongjun Ni62f9cdd2017-07-04 20:11:57 +080051 self.logger.info(self.vapi.cli("show int"))
52 self.logger.info(self.vapi.cli("show pppoe fib"))
53 self.logger.info(self.vapi.cli("show pppoe session"))
54 self.logger.info(self.vapi.cli("show ip fib"))
55 self.logger.info(self.vapi.cli("show trace"))
56
Hongjun Ni62f9cdd2017-07-04 20:11:57 +080057 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()
Stanislav Zaikin938af5e2020-12-03 19:09:53 +0000214 pppoe_if.set_unnumbered(self.pg0.sw_if_index)
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800215
216 #
217 # Send tunneled packets that match the created tunnel and
218 # are decapped and forwarded
219 #
220 tx2 = self.create_stream_pppoe_ip4(self.pg0, self.pg1,
221 self.pg0.remote_mac,
222 self.session_id,
223 self.pg0.remote_ip4)
224 self.pg0.add_stream(tx2)
225
226 self.pg_enable_capture(self.pg_interfaces)
227 self.pg_start()
228
229 rx2 = self.pg1.get_capture(len(tx2))
230 self.verify_decapped_pppoe(self.pg0, rx2, tx2)
231
232 self.logger.info(self.vapi.cli("show pppoe fib"))
233 self.logger.info(self.vapi.cli("show pppoe session"))
234 self.logger.info(self.vapi.cli("show ip fib"))
235
236 #
237 # test case cleanup
238 #
239
240 # Delete PPPoE session
241 pppoe_if.remove_vpp_config()
242
243 # Delete a route that resolves the server's destination
244 route_sever_dst.remove_vpp_config()
245
246 def test_PPPoE_Encap(self):
247 """ PPPoE Encap Test """
248
249 self.vapi.cli("clear trace")
250
251 #
252 # Add a route that resolves the server's destination
253 #
254 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
255 [VppRoutePath(self.pg1.remote_ip4,
256 self.pg1.sw_if_index)])
257 route_sever_dst.add_vpp_config()
258
259 # Send PPPoE Discovery
260 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
261 self.pg0.remote_mac)
262 self.pg0.add_stream(tx0)
263 self.pg_start()
264
265 # Send PPPoE PPP LCP
266 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
267 self.pg0.remote_mac,
268 self.session_id)
269 self.pg0.add_stream(tx1)
270 self.pg_start()
271
272 # Create PPPoE session
273 pppoe_if = VppPppoeInterface(self,
274 self.pg0.remote_ip4,
275 self.pg0.remote_mac,
276 self.session_id)
277 pppoe_if.add_vpp_config()
Stanislav Zaikin938af5e2020-12-03 19:09:53 +0000278 pppoe_if.set_unnumbered(self.pg0.sw_if_index)
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800279
280 #
281 # Send a packet stream that is routed into the session
282 # - packets are PPPoE encapped
283 #
284 self.vapi.cli("clear trace")
285 tx2 = self.create_stream_ip4(self.pg1, self.pg0,
Neale Ranns43161a82017-08-12 02:12:00 -0700286 self.pg0.remote_ip4, self.dst_ip, 65)
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800287 self.pg1.add_stream(tx2)
288
289 self.pg_enable_capture(self.pg_interfaces)
290 self.pg_start()
291
292 rx2 = self.pg0.get_capture(len(tx2))
293 self.verify_encaped_pppoe(self.pg1, rx2, tx2, self.session_id)
294
295 self.logger.info(self.vapi.cli("show pppoe fib"))
296 self.logger.info(self.vapi.cli("show pppoe session"))
297 self.logger.info(self.vapi.cli("show ip fib"))
Neale Ranns43161a82017-08-12 02:12:00 -0700298 self.logger.info(self.vapi.cli("show adj"))
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800299
300 #
301 # test case cleanup
302 #
303
304 # Delete PPPoE session
305 pppoe_if.remove_vpp_config()
306
307 # Delete a route that resolves the server's destination
308 route_sever_dst.remove_vpp_config()
309
310 def test_PPPoE_Add_Twice(self):
311 """ PPPoE Add Same Session Twice Test """
312
313 self.vapi.cli("clear trace")
314
315 #
316 # Add a route that resolves the server's destination
317 #
318 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
319 [VppRoutePath(self.pg1.remote_ip4,
320 self.pg1.sw_if_index)])
321 route_sever_dst.add_vpp_config()
322
323 # Send PPPoE Discovery
324 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
325 self.pg0.remote_mac)
326 self.pg0.add_stream(tx0)
327 self.pg_start()
328
329 # Send PPPoE PPP LCP
330 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
331 self.pg0.remote_mac,
332 self.session_id)
333 self.pg0.add_stream(tx1)
334 self.pg_start()
335
336 # Create PPPoE session
337 pppoe_if = VppPppoeInterface(self,
338 self.pg0.remote_ip4,
339 self.pg0.remote_mac,
340 self.session_id)
341 pppoe_if.add_vpp_config()
Stanislav Zaikin938af5e2020-12-03 19:09:53 +0000342 pppoe_if.set_unnumbered(self.pg0.sw_if_index)
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800343
344 #
345 # The double create (create the same session twice) should fail,
346 # and we should still be able to use the original
347 #
348 try:
Hongjun Niad2ddb12017-11-17 23:43:11 +0800349 pppoe_if.add_vpp_config()
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800350 except Exception:
351 pass
352 else:
353 self.fail("Double GRE tunnel add does not fail")
354
355 #
356 # test case cleanup
357 #
358
359 # Delete PPPoE session
360 pppoe_if.remove_vpp_config()
361
362 # Delete a route that resolves the server's destination
363 route_sever_dst.remove_vpp_config()
364
365 def test_PPPoE_Del_Twice(self):
366 """ PPPoE Delete Same Session Twice Test """
367
368 self.vapi.cli("clear trace")
369
370 #
371 # Add a route that resolves the server's destination
372 #
373 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
374 [VppRoutePath(self.pg1.remote_ip4,
375 self.pg1.sw_if_index)])
376 route_sever_dst.add_vpp_config()
377
378 # Send PPPoE Discovery
379 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
380 self.pg0.remote_mac)
381 self.pg0.add_stream(tx0)
382 self.pg_start()
383
384 # Send PPPoE PPP LCP
385 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
386 self.pg0.remote_mac,
387 self.session_id)
388 self.pg0.add_stream(tx1)
389 self.pg_start()
390
391 # Create PPPoE session
392 pppoe_if = VppPppoeInterface(self,
393 self.pg0.remote_ip4,
394 self.pg0.remote_mac,
395 self.session_id)
396 pppoe_if.add_vpp_config()
397
398 # Delete PPPoE session
399 pppoe_if.remove_vpp_config()
400
401 #
402 # The double del (del the same session twice) should fail,
403 # and we should still be able to use the original
404 #
405 try:
Hongjun Niad2ddb12017-11-17 23:43:11 +0800406 pppoe_if.remove_vpp_config()
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800407 except Exception:
408 pass
409 else:
410 self.fail("Double GRE tunnel del does not fail")
411
412 #
413 # test case cleanup
414 #
415
416 # Delete a route that resolves the server's destination
417 route_sever_dst.remove_vpp_config()
418
419 def test_PPPoE_Decap_Multiple(self):
420 """ PPPoE Decap Multiple Sessions Test """
421
422 self.vapi.cli("clear trace")
423
424 #
425 # Add a route that resolves the server's destination
426 #
427 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
428 [VppRoutePath(self.pg1.remote_ip4,
429 self.pg1.sw_if_index)])
430 route_sever_dst.add_vpp_config()
431
432 # Send PPPoE Discovery 1
433 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
434 self.pg0.remote_mac)
435 self.pg0.add_stream(tx0)
436 self.pg_start()
437
438 # Send PPPoE PPP LCP 1
439 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
440 self.pg0.remote_mac,
441 self.session_id)
442 self.pg0.add_stream(tx1)
443 self.pg_start()
444
445 # Create PPPoE session 1
446 pppoe_if1 = VppPppoeInterface(self,
447 self.pg0.remote_ip4,
448 self.pg0.remote_mac,
449 self.session_id)
450 pppoe_if1.add_vpp_config()
Stanislav Zaikin938af5e2020-12-03 19:09:53 +0000451 pppoe_if1.set_unnumbered(self.pg0.sw_if_index)
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800452
453 # Send PPPoE Discovery 2
454 tx3 = self.create_stream_pppoe_discovery(self.pg2, self.pg1,
455 self.pg2.remote_mac)
456 self.pg2.add_stream(tx3)
457 self.pg_start()
458
459 # Send PPPoE PPP LCP 2
460 tx4 = self.create_stream_pppoe_lcp(self.pg2, self.pg1,
461 self.pg2.remote_mac,
462 self.session_id + 1)
463 self.pg2.add_stream(tx4)
464 self.pg_start()
465
466 # Create PPPoE session 2
467 pppoe_if2 = VppPppoeInterface(self,
468 self.pg2.remote_ip4,
469 self.pg2.remote_mac,
470 self.session_id + 1)
471 pppoe_if2.add_vpp_config()
Stanislav Zaikin938af5e2020-12-03 19:09:53 +0000472 pppoe_if2.set_unnumbered(self.pg0.sw_if_index)
Hongjun Ni62f9cdd2017-07-04 20:11:57 +0800473
474 #
475 # Send tunneled packets that match the created tunnel and
476 # are decapped and forwarded
477 #
478 tx2 = self.create_stream_pppoe_ip4(self.pg0, self.pg1,
479 self.pg0.remote_mac,
480 self.session_id,
481 self.pg0.remote_ip4)
482 self.pg0.add_stream(tx2)
483
484 self.pg_enable_capture(self.pg_interfaces)
485 self.pg_start()
486
487 rx2 = self.pg1.get_capture(len(tx2))
488 self.verify_decapped_pppoe(self.pg0, rx2, tx2)
489
490 tx5 = self.create_stream_pppoe_ip4(self.pg2, self.pg1,
491 self.pg2.remote_mac,
492 self.session_id + 1,
493 self.pg2.remote_ip4)
494 self.pg2.add_stream(tx5)
495
496 self.pg_enable_capture(self.pg_interfaces)
497 self.pg_start()
498
499 rx5 = self.pg1.get_capture(len(tx5))
500 self.verify_decapped_pppoe(self.pg2, rx5, tx5)
501
502 self.logger.info(self.vapi.cli("show pppoe fib"))
503 self.logger.info(self.vapi.cli("show pppoe session"))
504 self.logger.info(self.vapi.cli("show ip fib"))
505
506 #
507 # test case cleanup
508 #
509
510 # Delete PPPoE session
511 pppoe_if1.remove_vpp_config()
512 pppoe_if2.remove_vpp_config()
513
514 # Delete a route that resolves the server's destination
515 route_sever_dst.remove_vpp_config()
516
517 def test_PPPoE_Encap_Multiple(self):
518 """ PPPoE Encap Multiple Sessions Test """
519
520 self.vapi.cli("clear trace")
521
522 #
523 # Add a route that resolves the server's destination
524 #
525 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
526 [VppRoutePath(self.pg1.remote_ip4,
527 self.pg1.sw_if_index)])
528 route_sever_dst.add_vpp_config()
529
530 # Send PPPoE Discovery 1
531 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
532 self.pg0.remote_mac)
533 self.pg0.add_stream(tx0)
534 self.pg_start()
535
536 # Send PPPoE PPP LCP 1
537 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
538 self.pg0.remote_mac,
539 self.session_id)
540 self.pg0.add_stream(tx1)
541 self.pg_start()
542
543 # Create PPPoE session 1
544 pppoe_if1 = VppPppoeInterface(self,
545 self.pg0.remote_ip4,
546 self.pg0.remote_mac,
547 self.session_id)
548 pppoe_if1.add_vpp_config()
549
550 # Send PPPoE Discovery 2
551 tx3 = self.create_stream_pppoe_discovery(self.pg2, self.pg1,
552 self.pg2.remote_mac)
553 self.pg2.add_stream(tx3)
554 self.pg_start()
555
556 # Send PPPoE PPP LCP 2
557 tx4 = self.create_stream_pppoe_lcp(self.pg2, self.pg1,
558 self.pg2.remote_mac,
559 self.session_id + 1)
560 self.pg2.add_stream(tx4)
561 self.pg_start()
562
563 # Create PPPoE session 2
564 pppoe_if2 = VppPppoeInterface(self,
565 self.pg2.remote_ip4,
566 self.pg2.remote_mac,
567 self.session_id + 1)
568 pppoe_if2.add_vpp_config()
569
570 #
571 # Send a packet stream that is routed into the session
572 # - packets are PPPoE encapped
573 #
574 self.vapi.cli("clear trace")
575 tx2 = self.create_stream_ip4(self.pg1, self.pg0,
576 self.pg0.remote_ip4, self.dst_ip)
577 self.pg1.add_stream(tx2)
578
579 self.pg_enable_capture(self.pg_interfaces)
580 self.pg_start()
581
582 rx2 = self.pg0.get_capture(len(tx2))
583 self.verify_encaped_pppoe(self.pg1, rx2, tx2, self.session_id)
584
585 tx5 = self.create_stream_ip4(self.pg1, self.pg2,
586 self.pg2.remote_ip4, self.dst_ip)
587 self.pg1.add_stream(tx5)
588
589 self.pg_enable_capture(self.pg_interfaces)
590 self.pg_start()
591
592 rx5 = self.pg2.get_capture(len(tx5))
593 self.verify_encaped_pppoe(self.pg1, rx5, tx5, self.session_id + 1)
594
595 self.logger.info(self.vapi.cli("show pppoe fib"))
596 self.logger.info(self.vapi.cli("show pppoe session"))
597 self.logger.info(self.vapi.cli("show ip fib"))
598
599 #
600 # test case cleanup
601 #
602
603 # Delete PPPoE session
604 pppoe_if1.remove_vpp_config()
605 pppoe_if2.remove_vpp_config()
606
607 # Delete a route that resolves the server's destination
608 route_sever_dst.remove_vpp_config()
609
610if __name__ == '__main__':
611 unittest.main(testRunner=VppTestRunner)