6 from framework import VppTestCase, VppTestRunner
7 from vpp_ip_route import VppIpRoute, VppRoutePath
8 from vpp_pppoe_interface import VppPppoeInterface
9 from vpp_papi_provider import L2_VTR_OP
11 from scapy.packet import Raw
12 from scapy.layers.l2 import Ether
13 from scapy.layers.ppp import PPPoE, PPPoED, PPP
14 from scapy.layers.inet import IP, UDP
15 from scapy.layers.inet6 import IPv6
16 from scapy.volatile import RandMAC, RandIP
18 from util import ppp, ppc, mactobinary
22 class TestPPPoE(VppTestCase):
23 """ PPPoE Test Case """
27 super(TestPPPoE, cls).setUpClass()
30 cls.dst_ip = "100.1.1.100"
31 cls.dst_ipn = socket.inet_pton(socket.AF_INET, cls.dst_ip)
34 super(TestPPPoE, self).setUp()
36 # create 2 pg interfaces
37 self.create_pg_interfaces(range(3))
39 for i in self.pg_interfaces:
45 super(TestPPPoE, self).tearDown()
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"))
53 for i in self.pg_interfaces:
57 def create_stream_pppoe_discovery(self, src_if, dst_if,
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) /
69 # store a copy of the packet in the packet info
71 # append the packet to the list
74 # return the created packet list
77 def create_stream_pppoe_lcp(self, src_if, dst_if,
78 client_mac, session_id, count=1):
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) /
90 # store a copy of the packet in the packet info
92 # append the packet to the list
95 # return the created packet list
98 def create_stream_pppoe_ip4(self, src_if, dst_if,
99 client_mac, session_id, client_ip, count=1):
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) /
110 IP(src=client_ip, dst=self.dst_ip) /
112 # store a copy of the packet in the packet info
114 # append the packet to the list
117 # return the created packet list
120 def create_stream_ip4(self, src_if, dst_if, client_ip, dst_ip, count=1):
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) /
131 # store a copy of the packet in the packet info
133 # append the packet to the list
136 # return the created packet list
139 def verify_decapped_pppoe(self, src_if, capture, sent):
140 self.assertEqual(len(capture), len(sent))
142 for i in range(len(capture)):
150 self.assertEqual(rx_ip.src, tx_ip.src)
151 self.assertEqual(rx_ip.dst, tx_ip.dst)
154 self.logger.error(ppp("Rx:", rx))
155 self.logger.error(ppp("Tx:", tx))
158 def verify_encaped_pppoe(self, src_if, capture, sent, session_id):
160 self.assertEqual(len(capture), len(sent))
162 for i in range(len(capture)):
170 self.assertEqual(rx_ip.src, tx_ip.src)
171 self.assertEqual(rx_ip.dst, tx_ip.dst)
175 self.assertEqual(rx_pppoe.sessionid, session_id)
178 self.logger.error(ppp("Rx:", rx))
179 self.logger.error(ppp("Tx:", tx))
182 def test_PPPoE_Decap(self):
183 """ PPPoE Decap Test """
185 self.vapi.cli("clear trace")
188 # Add a route that resolves the server's destination
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()
195 # Send PPPoE Discovery
196 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
198 self.pg0.add_stream(tx0)
202 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
205 self.pg0.add_stream(tx1)
208 # Create PPPoE session
209 pppoe_if = VppPppoeInterface(self,
213 pppoe_if.add_vpp_config()
216 # Send tunneled packets that match the created tunnel and
217 # are decapped and forwarded
219 tx2 = self.create_stream_pppoe_ip4(self.pg0, self.pg1,
223 self.pg0.add_stream(tx2)
225 self.pg_enable_capture(self.pg_interfaces)
228 rx2 = self.pg1.get_capture(len(tx2))
229 self.verify_decapped_pppoe(self.pg0, rx2, tx2)
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"))
239 # Delete PPPoE session
240 pppoe_if.remove_vpp_config()
242 # Delete a route that resolves the server's destination
243 route_sever_dst.remove_vpp_config()
245 def test_PPPoE_Encap(self):
246 """ PPPoE Encap Test """
248 self.vapi.cli("clear trace")
251 # Add a route that resolves the server's destination
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()
258 # Send PPPoE Discovery
259 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
261 self.pg0.add_stream(tx0)
265 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
268 self.pg0.add_stream(tx1)
271 # Create PPPoE session
272 pppoe_if = VppPppoeInterface(self,
276 pppoe_if.add_vpp_config()
279 # Send a packet stream that is routed into the session
280 # - packets are PPPoE encapped
282 self.vapi.cli("clear trace")
283 tx2 = self.create_stream_ip4(self.pg1, self.pg0,
284 self.pg0.remote_ip4, self.dst_ip, 65)
285 self.pg1.add_stream(tx2)
287 self.pg_enable_capture(self.pg_interfaces)
290 rx2 = self.pg0.get_capture(len(tx2))
291 self.verify_encaped_pppoe(self.pg1, rx2, tx2, self.session_id)
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 self.logger.info(self.vapi.cli("show adj"))
302 # Delete PPPoE session
303 pppoe_if.remove_vpp_config()
305 # Delete a route that resolves the server's destination
306 route_sever_dst.remove_vpp_config()
308 def test_PPPoE_Add_Twice(self):
309 """ PPPoE Add Same Session Twice Test """
311 self.vapi.cli("clear trace")
314 # Add a route that resolves the server's destination
316 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
317 [VppRoutePath(self.pg1.remote_ip4,
318 self.pg1.sw_if_index)])
319 route_sever_dst.add_vpp_config()
321 # Send PPPoE Discovery
322 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
324 self.pg0.add_stream(tx0)
328 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
331 self.pg0.add_stream(tx1)
334 # Create PPPoE session
335 pppoe_if = VppPppoeInterface(self,
339 pppoe_if.add_vpp_config()
342 # The double create (create the same session twice) should fail,
343 # and we should still be able to use the original
346 pppoe_if.add_vpp_config()
350 self.fail("Double GRE tunnel add does not fail")
356 # Delete PPPoE session
357 pppoe_if.remove_vpp_config()
359 # Delete a route that resolves the server's destination
360 route_sever_dst.remove_vpp_config()
362 def test_PPPoE_Del_Twice(self):
363 """ PPPoE Delete Same Session Twice Test """
365 self.vapi.cli("clear trace")
368 # Add a route that resolves the server's destination
370 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
371 [VppRoutePath(self.pg1.remote_ip4,
372 self.pg1.sw_if_index)])
373 route_sever_dst.add_vpp_config()
375 # Send PPPoE Discovery
376 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
378 self.pg0.add_stream(tx0)
382 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
385 self.pg0.add_stream(tx1)
388 # Create PPPoE session
389 pppoe_if = VppPppoeInterface(self,
393 pppoe_if.add_vpp_config()
395 # Delete PPPoE session
396 pppoe_if.remove_vpp_config()
399 # The double del (del the same session twice) should fail,
400 # and we should still be able to use the original
403 pppoe_if.remove_vpp_config()
407 self.fail("Double GRE tunnel del does not fail")
413 # Delete a route that resolves the server's destination
414 route_sever_dst.remove_vpp_config()
416 def test_PPPoE_Decap_Multiple(self):
417 """ PPPoE Decap Multiple Sessions Test """
419 self.vapi.cli("clear trace")
422 # Add a route that resolves the server's destination
424 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
425 [VppRoutePath(self.pg1.remote_ip4,
426 self.pg1.sw_if_index)])
427 route_sever_dst.add_vpp_config()
429 # Send PPPoE Discovery 1
430 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
432 self.pg0.add_stream(tx0)
435 # Send PPPoE PPP LCP 1
436 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
439 self.pg0.add_stream(tx1)
442 # Create PPPoE session 1
443 pppoe_if1 = VppPppoeInterface(self,
447 pppoe_if1.add_vpp_config()
449 # Send PPPoE Discovery 2
450 tx3 = self.create_stream_pppoe_discovery(self.pg2, self.pg1,
452 self.pg2.add_stream(tx3)
455 # Send PPPoE PPP LCP 2
456 tx4 = self.create_stream_pppoe_lcp(self.pg2, self.pg1,
459 self.pg2.add_stream(tx4)
462 # Create PPPoE session 2
463 pppoe_if2 = VppPppoeInterface(self,
467 pppoe_if2.add_vpp_config()
470 # Send tunneled packets that match the created tunnel and
471 # are decapped and forwarded
473 tx2 = self.create_stream_pppoe_ip4(self.pg0, self.pg1,
477 self.pg0.add_stream(tx2)
479 self.pg_enable_capture(self.pg_interfaces)
482 rx2 = self.pg1.get_capture(len(tx2))
483 self.verify_decapped_pppoe(self.pg0, rx2, tx2)
485 tx5 = self.create_stream_pppoe_ip4(self.pg2, self.pg1,
489 self.pg2.add_stream(tx5)
491 self.pg_enable_capture(self.pg_interfaces)
494 rx5 = self.pg1.get_capture(len(tx5))
495 self.verify_decapped_pppoe(self.pg2, rx5, tx5)
497 self.logger.info(self.vapi.cli("show pppoe fib"))
498 self.logger.info(self.vapi.cli("show pppoe session"))
499 self.logger.info(self.vapi.cli("show ip fib"))
505 # Delete PPPoE session
506 pppoe_if1.remove_vpp_config()
507 pppoe_if2.remove_vpp_config()
509 # Delete a route that resolves the server's destination
510 route_sever_dst.remove_vpp_config()
512 def test_PPPoE_Encap_Multiple(self):
513 """ PPPoE Encap Multiple Sessions Test """
515 self.vapi.cli("clear trace")
518 # Add a route that resolves the server's destination
520 route_sever_dst = VppIpRoute(self, "100.1.1.100", 32,
521 [VppRoutePath(self.pg1.remote_ip4,
522 self.pg1.sw_if_index)])
523 route_sever_dst.add_vpp_config()
525 # Send PPPoE Discovery 1
526 tx0 = self.create_stream_pppoe_discovery(self.pg0, self.pg1,
528 self.pg0.add_stream(tx0)
531 # Send PPPoE PPP LCP 1
532 tx1 = self.create_stream_pppoe_lcp(self.pg0, self.pg1,
535 self.pg0.add_stream(tx1)
538 # Create PPPoE session 1
539 pppoe_if1 = VppPppoeInterface(self,
543 pppoe_if1.add_vpp_config()
545 # Send PPPoE Discovery 2
546 tx3 = self.create_stream_pppoe_discovery(self.pg2, self.pg1,
548 self.pg2.add_stream(tx3)
551 # Send PPPoE PPP LCP 2
552 tx4 = self.create_stream_pppoe_lcp(self.pg2, self.pg1,
555 self.pg2.add_stream(tx4)
558 # Create PPPoE session 2
559 pppoe_if2 = VppPppoeInterface(self,
563 pppoe_if2.add_vpp_config()
566 # Send a packet stream that is routed into the session
567 # - packets are PPPoE encapped
569 self.vapi.cli("clear trace")
570 tx2 = self.create_stream_ip4(self.pg1, self.pg0,
571 self.pg0.remote_ip4, self.dst_ip)
572 self.pg1.add_stream(tx2)
574 self.pg_enable_capture(self.pg_interfaces)
577 rx2 = self.pg0.get_capture(len(tx2))
578 self.verify_encaped_pppoe(self.pg1, rx2, tx2, self.session_id)
580 tx5 = self.create_stream_ip4(self.pg1, self.pg2,
581 self.pg2.remote_ip4, self.dst_ip)
582 self.pg1.add_stream(tx5)
584 self.pg_enable_capture(self.pg_interfaces)
587 rx5 = self.pg2.get_capture(len(tx5))
588 self.verify_encaped_pppoe(self.pg1, rx5, tx5, self.session_id + 1)
590 self.logger.info(self.vapi.cli("show pppoe fib"))
591 self.logger.info(self.vapi.cli("show pppoe session"))
592 self.logger.info(self.vapi.cli("show ip fib"))
598 # Delete PPPoE session
599 pppoe_if1.remove_vpp_config()
600 pppoe_if2.remove_vpp_config()
602 # Delete a route that resolves the server's destination
603 route_sever_dst.remove_vpp_config()
605 if __name__ == '__main__':
606 unittest.main(testRunner=VppTestRunner)