Tests Cleanup: Fix missing calls to setUpClass/tearDownClass.
[vpp.git] / test / test_pppoe.py
1 #!/usr/bin/env python
2
3 import socket
4 import unittest
5
6 from scapy.packet import Raw
7 from scapy.layers.l2 import Ether
8 from scapy.layers.ppp import PPPoE, PPPoED, PPP
9 from scapy.layers.inet import IP
10
11 from framework import VppTestCase, VppTestRunner
12 from vpp_ip_route import VppIpRoute, VppRoutePath
13 from vpp_pppoe_interface import VppPppoeInterface
14 from util import ppp, ppc
15
16
17 class 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     @classmethod
29     def tearDownClass(cls):
30         super(TestPPPoE, cls).tearDownClass()
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,
283                                      self.pg0.remote_ip4, self.dst_ip, 65)
284         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"))
295         self.logger.info(self.vapi.cli("show adj"))
296
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:
345             pppoe_if.add_vpp_config()
346         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:
402             pppoe_if.remove_vpp_config()
403         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
604 if __name__ == '__main__':
605     unittest.main(testRunner=VppTestRunner)