blob: b181f6bced7758b5e2f1431968f5db54d5b7171a [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
Hongjun Ni2629c842018-03-08 00:25:56 +08008from vpp_pppoe_interface import VppPppoeInterface
Hongjun Ni62f9cdd2017-07-04 20:11:57 +08009from 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
Ole Troan7f991832018-12-06 17:35:12 +010017from util import ppp, ppc
Hongjun Ni62f9cdd2017-07-04 20:11:57 +080018import socket
19
20
21class TestPPPoE(VppTestCase):
22 """ PPPoE Test Case """
23
24 @classmethod
25 def setUpClass(cls):
26 super(TestPPPoE, cls).setUpClass()
27
28 cls.session_id = 1
29 cls.dst_ip = "100.1.1.100"
30 cls.dst_ipn = socket.inet_pton(socket.AF_INET, cls.dst_ip)
31
32 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)