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