Flowprobe - tests speed-up
[vpp.git] / test / test_flowprobe.py
1 #!/usr/bin/env python
2 import random
3 import socket
4 import unittest
5 import time
6
7 from scapy.packet import Raw
8 from scapy.layers.l2 import Ether
9 from scapy.layers.inet import IP, UDP
10 from scapy.layers.inet6 import IPv6
11
12 from framework import VppTestCase, VppTestRunner, running_extended_tests
13 from vpp_object import VppObject
14 from vpp_pg_interface import CaptureTimeoutError
15 from util import ppp
16 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
17
18
19 class VppCFLOW(VppObject):
20     """CFLOW object for IPFIX exporter and Flowprobe feature"""
21
22     def __init__(self, test, intf='pg2', active=0, passive=0, timeout=100,
23                  mtu=1024, datapath='l2', layer='l2 l3 l4'):
24         self._test = test
25         self._intf = intf
26         self._active = active
27         if passive == 0 or passive < active:
28             self._passive = active+1
29         else:
30             self._passive = passive
31         self._datapath = datapath           # l2 ip4 ip6
32         self._collect = layer               # l2 l3 l4
33         self._timeout = timeout
34         self._mtu = mtu
35         self._configured = False
36
37     def add_vpp_config(self):
38         self.enable_exporter()
39         self._test.vapi.ppcli("flowprobe params record %s active %s "
40                               "passive %s" % (self._collect, self._active,
41                                               self._passive))
42         self.enable_flowprobe_feature()
43         self._test.vapi.cli("ipfix flush")
44         self._configured = True
45
46     def remove_vpp_config(self):
47         self.disable_exporter()
48         self.disable_flowprobe_feature()
49         self._test.vapi.cli("ipfix flush")
50         self._configured = False
51
52     def enable_exporter(self):
53         self._test.vapi.set_ipfix_exporter(
54             collector_address=self._test.pg0.remote_ip4n,
55             src_address=self._test.pg0.local_ip4n,
56             path_mtu=self._mtu,
57             template_interval=self._timeout)
58
59     def enable_flowprobe_feature(self):
60         self._test.vapi.ppcli("flowprobe feature add-del %s %s" %
61                               (self._intf, self._datapath))
62
63     def disable_exporter(self):
64         self._test.vapi.cli("set ipfix exporter collector 0.0.0.0")
65
66     def disable_flowprobe_feature(self):
67         self._test.vapi.cli("flowprobe feature add-del %s %s disable" %
68                             (self._intf, self._datapath))
69
70     def object_id(self):
71         return "ipfix-collector-%s" % (self._src, self.dst)
72
73     def query_vpp_config(self):
74         return self._configured
75
76     def verify_templates(self, decoder=None, timeout=1, count=3):
77         templates = []
78         p = self._test.wait_for_cflow_packet(self._test.collector, 2, timeout)
79         self._test.assertTrue(p.haslayer(IPFIX))
80         if decoder is not None and p.haslayer(Template):
81             templates.append(p[Template].templateID)
82             decoder.add_template(p.getlayer(Template))
83         if count > 1:
84             p = self._test.wait_for_cflow_packet(self._test.collector, 2)
85             self._test.assertTrue(p.haslayer(IPFIX))
86             if decoder is not None and p.haslayer(Template):
87                 templates.append(p[Template].templateID)
88                 decoder.add_template(p.getlayer(Template))
89         if count > 2:
90             p = self._test.wait_for_cflow_packet(self._test.collector, 2)
91             self._test.assertTrue(p.haslayer(IPFIX))
92             if decoder is not None and p.haslayer(Template):
93                 templates.append(p[Template].templateID)
94                 decoder.add_template(p.getlayer(Template))
95         return templates
96
97
98 class MethodHolder(VppTestCase):
99     """ Flow-per-packet plugin: test L2, IP4, IP6 reporting """
100
101     # Test variables
102     debug_print = False
103     max_number_of_packets = 10
104     pkts = []
105
106     @classmethod
107     def setUpClass(cls):
108         """
109         Perform standard class setup (defined by class method setUpClass in
110         class VppTestCase) before running the test case, set test case related
111         variables and configure VPP.
112         """
113         super(MethodHolder, cls).setUpClass()
114         try:
115             # Create pg interfaces
116             cls.create_pg_interfaces(range(7))
117
118             # Packet sizes
119             cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
120
121             # Create BD with MAC learning and unknown unicast flooding disabled
122             # and put interfaces to this BD
123             cls.vapi.bridge_domain_add_del(bd_id=1, uu_flood=1, learn=1)
124             cls.vapi.sw_interface_set_l2_bridge(cls.pg1._sw_if_index, bd_id=1)
125             cls.vapi.sw_interface_set_l2_bridge(cls.pg2._sw_if_index, bd_id=1)
126
127             # Set up all interfaces
128             for i in cls.pg_interfaces:
129                 i.admin_up()
130
131             cls.pg0.config_ip4()
132             cls.pg0.configure_ipv4_neighbors()
133             cls.collector = cls.pg0
134
135             cls.pg1.config_ip4()
136             cls.pg1.resolve_arp()
137             cls.pg2.config_ip4()
138             cls.pg2.resolve_arp()
139             cls.pg3.config_ip4()
140             cls.pg3.resolve_arp()
141             cls.pg4.config_ip4()
142             cls.pg4.resolve_arp()
143
144             cls.pg5.config_ip6()
145             cls.pg5.resolve_ndp()
146             cls.pg5.disable_ipv6_ra()
147             cls.pg6.config_ip6()
148             cls.pg6.resolve_ndp()
149             cls.pg6.disable_ipv6_ra()
150         except Exception:
151             super(MethodHolder, cls).tearDownClass()
152             raise
153
154     def create_stream(self, src_if=None, dst_if=None, packets=None,
155                       size=None, ip_ver='v4'):
156         """Create a packet stream to tickle the plugin
157
158         :param VppInterface src_if: Source interface for packet stream
159         :param VppInterface src_if: Dst interface for packet stream
160         """
161         if src_if is None:
162             src_if = self.pg1
163         if dst_if is None:
164             dst_if = self.pg2
165         self.pkts = []
166         if packets is None:
167             packets = random.randint(1, self.max_number_of_packets)
168         pkt_size = size
169         for p in range(0, packets):
170             if size is None:
171                 pkt_size = random.choice(self.pg_if_packet_sizes)
172             info = self.create_packet_info(src_if, dst_if)
173             payload = self.info_to_payload(info)
174             p = Ether(src=src_if.remote_mac, dst=src_if.local_mac)
175             if ip_ver == 'v4':
176                 p /= IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
177             else:
178                 p /= IPv6(src=src_if.remote_ip6, dst=dst_if.remote_ip6)
179             p /= (UDP(sport=1234, dport=4321) / Raw(payload))
180             info.data = p.copy()
181             self.extend_packet(p, pkt_size)
182             self.pkts.append(p)
183
184     def verify_cflow_data(self, decoder, capture, cflow):
185         octets = 0
186         packets = 0
187         for p in capture:
188             octets += p[IP].len
189             packets += 1
190         if cflow.haslayer(Data):
191             data = decoder.decode_data_set(cflow.getlayer(Set))
192             for record in data:
193                 self.assertEqual(int(record[1].encode('hex'), 16), octets)
194                 self.assertEqual(int(record[2].encode('hex'), 16), packets)
195
196     def send_packets(self, src_if=None, dst_if=None):
197         if src_if is None:
198             src_if = self.pg1
199         if dst_if is None:
200             dst_if = self.pg2
201         self.pg_enable_capture([dst_if])
202         src_if.add_stream(self.pkts)
203         self.pg_start()
204         return dst_if.get_capture(len(self.pkts))
205
206     def verify_cflow_data_detail(self, decoder, capture, cflow,
207                                  data_set={1: 'octets', 2: 'packets'},
208                                  ip_ver='v4'):
209         if self.debug_print:
210             print capture[0].show()
211         if cflow.haslayer(Data):
212             data = decoder.decode_data_set(cflow.getlayer(Set))
213             if self.debug_print:
214                 print data
215             if ip_ver == 'v4':
216                 ip_layer = capture[0][IP]
217             else:
218                 ip_layer = capture[0][IPv6]
219             if data_set is not None:
220                 for record in data:
221                     # skip flow if in/out gress interface is 0
222                     if int(record[10].encode('hex'), 16) == 0:
223                         continue
224                     if int(record[14].encode('hex'), 16) == 0:
225                         continue
226
227                     for field in data_set:
228                         if field not in record.keys():
229                             continue
230                         value = data_set[field]
231                         if value == 'octets':
232                             value = ip_layer.len
233                             if ip_ver == 'v6':
234                                 value += 40        # ??? is this correct
235                         elif value == 'packets':
236                             value = 1
237                         elif value == 'src_ip':
238                             if ip_ver == 'v4':
239                                 ip = socket.inet_pton(socket.AF_INET,
240                                                       ip_layer.src)
241                             else:
242                                 ip = socket.inet_pton(socket.AF_INET6,
243                                                       ip_layer.src)
244                             value = int(ip.encode('hex'), 16)
245                         elif value == 'dst_ip':
246                             if ip_ver == 'v4':
247                                 ip = socket.inet_pton(socket.AF_INET,
248                                                       ip_layer.dst)
249                             else:
250                                 ip = socket.inet_pton(socket.AF_INET6,
251                                                       ip_layer.dst)
252                             value = int(ip.encode('hex'), 16)
253                         elif value == 'sport':
254                             value = int(capture[0][UDP].sport)
255                         elif value == 'dport':
256                             value = int(capture[0][UDP].dport)
257                         self.assertEqual(int(record[field].encode('hex'), 16),
258                                          value)
259
260     def verify_cflow_data_notimer(self, decoder, capture, cflows):
261         idx = 0
262         for cflow in cflows:
263             if cflow.haslayer(Data):
264                 data = decoder.decode_data_set(cflow.getlayer(Set))
265             else:
266                 raise Exception("No CFLOW data")
267
268             for rec in data:
269                 p = capture[idx]
270                 idx += 1
271                 self.assertEqual(p[IP].len, int(rec[1].encode('hex'), 16))
272                 self.assertEqual(1, int(rec[2].encode('hex'), 16))
273         self.assertEqual(len(capture), idx)
274
275     def wait_for_cflow_packet(self, collector_intf, set_id=2, timeout=1,
276                               expected=True):
277         """ wait for CFLOW packet and verify its correctness
278
279         :param timeout: how long to wait
280
281         :returns: tuple (packet, time spent waiting for packet)
282         """
283         self.logger.info("IPFIX: Waiting for CFLOW packet")
284         deadline = time.time() + timeout
285         counter = 0
286         # self.logger.debug(self.vapi.ppcli("show flow table"))
287         while True:
288             counter += 1
289             # sanity check
290             self.assert_in_range(counter, 0, 100, "number of packets ignored")
291             time_left = deadline - time.time()
292             try:
293                 if time_left < 0 and expected:
294                     # self.logger.debug(self.vapi.ppcli("show flow table"))
295                     raise CaptureTimeoutError(
296                           "Packet did not arrive within timeout")
297                 p = collector_intf.wait_for_packet(timeout=time_left)
298             except CaptureTimeoutError:
299                 if expected:
300                     # self.logger.debug(self.vapi.ppcli("show flow table"))
301                     raise CaptureTimeoutError(
302                           "Packet did not arrive within timeout")
303                 else:
304                     return
305             if not expected:
306                 raise CaptureTimeoutError("Packet arrived even not expected")
307             self.assertEqual(p[Set].setID, set_id)
308             # self.logger.debug(self.vapi.ppcli("show flow table"))
309             self.logger.debug(ppp("IPFIX: Got packet:", p))
310             break
311         return p
312
313
314 class Timers(MethodHolder):
315     """Template verification, timer tests"""
316
317     def test_0001(self):
318         """ timer less than template timeout"""
319         self.logger.info("FFP_TEST_START_0002")
320         self.pg_enable_capture(self.pg_interfaces)
321         self.pkts = []
322
323         ipfix = VppCFLOW(test=self, active=2)
324         ipfix.add_vpp_config()
325
326         ipfix_decoder = IPFIXDecoder()
327         # template packet should arrive immediately
328         templates = ipfix.verify_templates(ipfix_decoder)
329
330         self.create_stream(packets=2)
331         self.send_packets()
332         capture = self.pg2.get_capture(2)
333
334         # make sure the one packet we expect actually showed up
335         cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
336         self.verify_cflow_data(ipfix_decoder, capture, cflow)
337
338         ipfix.remove_vpp_config()
339         self.logger.info("FFP_TEST_FINISH_0002")
340
341     def test_0002(self):
342         """ timer greater than template timeout"""
343         self.logger.info("FFP_TEST_START_0003")
344         self.pg_enable_capture(self.pg_interfaces)
345         self.pkts = []
346
347         ipfix = VppCFLOW(test=self, timeout=3, active=4)
348         ipfix.add_vpp_config()
349
350         ipfix_decoder = IPFIXDecoder()
351         # template packet should arrive immediately
352         ipfix.verify_templates()
353
354         self.create_stream(packets=2)
355         self.send_packets()
356         capture = self.pg2.get_capture(2)
357
358         # next set of template packet should arrive after 20 seconds
359         # template packet should arrive within 20 s
360         templates = ipfix.verify_templates(ipfix_decoder, timeout=5)
361
362         # make sure the one packet we expect actually showed up
363         cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
364         self.verify_cflow_data(ipfix_decoder, capture, cflow)
365
366         ipfix.remove_vpp_config()
367         self.logger.info("FFP_TEST_FINISH_0003")
368
369
370 class Datapath(MethodHolder):
371     """collect information on Ethernet, IP4 and IP6 datapath (no timers)"""
372
373     def test_templatesL2(self):
374         """ verify template on L2 datapath"""
375         self.logger.info("FFP_TEST_START_0000")
376         self.pg_enable_capture(self.pg_interfaces)
377
378         ipfix = VppCFLOW(test=self, layer='l2')
379         ipfix.add_vpp_config()
380
381         # template packet should arrive immediately
382         self.vapi.cli("ipfix flush")
383         ipfix.verify_templates(timeout=3, count=1)
384         self.collector.get_capture(1)
385
386         ipfix.remove_vpp_config()
387         self.logger.info("FFP_TEST_FINISH_0000")
388
389     def test_L2onL2(self):
390         """ L2 data on L2 datapath"""
391         self.logger.info("FFP_TEST_START_0001")
392         self.pg_enable_capture(self.pg_interfaces)
393         self.pkts = []
394
395         ipfix = VppCFLOW(test=self, layer='l2')
396         ipfix.add_vpp_config()
397
398         ipfix_decoder = IPFIXDecoder()
399         # template packet should arrive immediately
400         templates = ipfix.verify_templates(ipfix_decoder, count=1)
401
402         self.create_stream(packets=1)
403         capture = self.send_packets()
404
405         # make sure the one packet we expect actually showed up
406         self.vapi.cli("ipfix flush")
407         cflow = self.wait_for_cflow_packet(self.collector, templates[0])
408         self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
409                                       {2: 'packets', 256: 8})
410         self.collector.get_capture(2)
411
412         ipfix.remove_vpp_config()
413         self.logger.info("FFP_TEST_FINISH_0001")
414
415     def test_L3onL2(self):
416         """ L3 data on L2 datapath"""
417         self.logger.info("FFP_TEST_START_0002")
418         self.pg_enable_capture(self.pg_interfaces)
419         self.pkts = []
420
421         ipfix = VppCFLOW(test=self, layer='l3')
422         ipfix.add_vpp_config()
423
424         ipfix_decoder = IPFIXDecoder()
425         # template packet should arrive immediately
426         templates = ipfix.verify_templates(ipfix_decoder, count=2)
427
428         self.create_stream(packets=1)
429         capture = self.send_packets()
430
431         # make sure the one packet we expect actually showed up
432         self.vapi.cli("ipfix flush")
433         cflow = self.wait_for_cflow_packet(self.collector, templates[0])
434         self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
435                                       {2: 'packets', 4: 17,
436                                        8: 'src_ip', 12: 'dst_ip'})
437
438         self.collector.get_capture(3)
439
440         ipfix.remove_vpp_config()
441         self.logger.info("FFP_TEST_FINISH_0002")
442
443     def test_L4onL2(self):
444         """ L4 data on L2 datapath"""
445         self.logger.info("FFP_TEST_START_0003")
446         self.pg_enable_capture(self.pg_interfaces)
447         self.pkts = []
448
449         ipfix = VppCFLOW(test=self, layer='l4')
450         ipfix.add_vpp_config()
451
452         ipfix_decoder = IPFIXDecoder()
453         # template packet should arrive immediately
454         templates = ipfix.verify_templates(ipfix_decoder, count=2)
455
456         self.create_stream(packets=1)
457         capture = self.send_packets()
458
459         # make sure the one packet we expect actually showed up
460         self.vapi.cli("ipfix flush")
461         cflow = self.wait_for_cflow_packet(self.collector, templates[0])
462         self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
463                                       {2: 'packets', 7: 'sport', 11: 'dport'})
464
465         self.collector.get_capture(3)
466
467         ipfix.remove_vpp_config()
468         self.logger.info("FFP_TEST_FINISH_0003")
469
470     def test_templatesIp4(self):
471         """ verify templates on IP4 datapath"""
472         self.logger.info("FFP_TEST_START_0000")
473
474         self.pg_enable_capture(self.pg_interfaces)
475
476         ipfix = VppCFLOW(test=self, datapath='ip4')
477         ipfix.add_vpp_config()
478
479         # template packet should arrive immediately
480         self.vapi.cli("ipfix flush")
481         ipfix.verify_templates(timeout=3, count=1)
482         self.collector.get_capture(1)
483
484         ipfix.remove_vpp_config()
485
486         self.logger.info("FFP_TEST_FINISH_0000")
487
488     def test_L2onIP4(self):
489         """ L2 data on IP4 datapath"""
490         self.logger.info("FFP_TEST_START_0001")
491         self.pg_enable_capture(self.pg_interfaces)
492         self.pkts = []
493
494         ipfix = VppCFLOW(test=self, intf='pg4', layer='l2', datapath='ip4')
495         ipfix.add_vpp_config()
496
497         ipfix_decoder = IPFIXDecoder()
498         # template packet should arrive immediately
499         templates = ipfix.verify_templates(ipfix_decoder, count=1)
500
501         self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
502         capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
503
504         # make sure the one packet we expect actually showed up
505         self.vapi.cli("ipfix flush")
506         cflow = self.wait_for_cflow_packet(self.collector, templates[0])
507         self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
508                                       {2: 'packets', 256: 8})
509
510         # expected two templates and one cflow packet
511         self.collector.get_capture(2)
512
513         ipfix.remove_vpp_config()
514         self.logger.info("FFP_TEST_FINISH_0001")
515
516     def test_L3onIP4(self):
517         """ L3 data on IP4 datapath"""
518         self.logger.info("FFP_TEST_START_0002")
519         self.pg_enable_capture(self.pg_interfaces)
520         self.pkts = []
521
522         ipfix = VppCFLOW(test=self, intf='pg4', layer='l3', datapath='ip4')
523         ipfix.add_vpp_config()
524
525         ipfix_decoder = IPFIXDecoder()
526         # template packet should arrive immediately
527         templates = ipfix.verify_templates(ipfix_decoder, count=1)
528
529         self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
530         capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
531
532         # make sure the one packet we expect actually showed up
533         self.vapi.cli("ipfix flush")
534         cflow = self.wait_for_cflow_packet(self.collector, templates[0])
535         self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
536                                       {1: 'octets', 2: 'packets',
537                                        8: 'src_ip', 12: 'dst_ip'})
538
539         # expected two templates and one cflow packet
540         self.collector.get_capture(2)
541
542         ipfix.remove_vpp_config()
543         self.logger.info("FFP_TEST_FINISH_0002")
544
545     def test_L4onIP4(self):
546         """ L4 data on IP4 datapath"""
547         self.logger.info("FFP_TEST_START_0003")
548         self.pg_enable_capture(self.pg_interfaces)
549         self.pkts = []
550
551         ipfix = VppCFLOW(test=self, intf='pg4', layer='l4', datapath='ip4')
552         ipfix.add_vpp_config()
553
554         ipfix_decoder = IPFIXDecoder()
555         # template packet should arrive immediately
556         templates = ipfix.verify_templates(ipfix_decoder, count=1)
557
558         self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
559         capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
560
561         # make sure the one packet we expect actually showed up
562         self.vapi.cli("ipfix flush")
563         cflow = self.wait_for_cflow_packet(self.collector, templates[0])
564         self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
565                                       {2: 'packets', 7: 'sport', 11: 'dport'})
566
567         # expected two templates and one cflow packet
568         self.collector.get_capture(2)
569
570         ipfix.remove_vpp_config()
571         self.logger.info("FFP_TEST_FINISH_0003")
572
573     def test_templatesIP6(self):
574         """ verify templates on IP6 datapath"""
575         self.logger.info("FFP_TEST_START_0000")
576         self.pg_enable_capture(self.pg_interfaces)
577
578         ipfix = VppCFLOW(test=self, datapath='ip6')
579         ipfix.add_vpp_config()
580
581         # template packet should arrive immediately
582         ipfix.verify_templates(count=1)
583         self.collector.get_capture(1)
584
585         ipfix.remove_vpp_config()
586
587         self.logger.info("FFP_TEST_FINISH_0000")
588
589     def test_L2onIP6(self):
590         """ L2 data on IP6 datapath"""
591         self.logger.info("FFP_TEST_START_0001")
592         self.pg_enable_capture(self.pg_interfaces)
593         self.pkts = []
594
595         ipfix = VppCFLOW(test=self, intf='pg6', layer='l2', datapath='ip6')
596         ipfix.add_vpp_config()
597
598         ipfix_decoder = IPFIXDecoder()
599         # template packet should arrive immediately
600         templates = ipfix.verify_templates(ipfix_decoder, count=1)
601
602         self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1,
603                            ip_ver='IPv6')
604         capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
605
606         # make sure the one packet we expect actually showed up
607         self.vapi.cli("ipfix flush")
608         cflow = self.wait_for_cflow_packet(self.collector, templates[0])
609         self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
610                                       {2: 'packets', 256: 56710},
611                                       ip_ver='v6')
612
613         # expected two templates and one cflow packet
614         self.collector.get_capture(2)
615
616         ipfix.remove_vpp_config()
617         self.logger.info("FFP_TEST_FINISH_0001")
618
619     def test_L3onIP6(self):
620         """ L3 data on IP6 datapath"""
621         self.logger.info("FFP_TEST_START_0002")
622         self.pg_enable_capture(self.pg_interfaces)
623         self.pkts = []
624
625         ipfix = VppCFLOW(test=self, intf='pg6', layer='l3', datapath='ip6')
626         ipfix.add_vpp_config()
627
628         ipfix_decoder = IPFIXDecoder()
629         # template packet should arrive immediately
630         templates = ipfix.verify_templates(ipfix_decoder, count=1)
631
632         self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1,
633                            ip_ver='IPv6')
634         capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
635
636         # make sure the one packet we expect actually showed up
637         self.vapi.cli("ipfix flush")
638         cflow = self.wait_for_cflow_packet(self.collector, templates[0])
639         self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
640                                       {2: 'packets',
641                                        27: 'src_ip', 28: 'dst_ip'},
642                                       ip_ver='v6')
643
644         # expected two templates and one cflow packet
645         self.collector.get_capture(2)
646
647         ipfix.remove_vpp_config()
648         self.logger.info("FFP_TEST_FINISH_0002")
649
650     def test_L4onIP6(self):
651         """ L4 data on IP6 datapath"""
652         self.logger.info("FFP_TEST_START_0003")
653         self.pg_enable_capture(self.pg_interfaces)
654         self.pkts = []
655
656         ipfix = VppCFLOW(test=self, intf='pg6', layer='l4', datapath='ip6')
657         ipfix.add_vpp_config()
658
659         ipfix_decoder = IPFIXDecoder()
660         # template packet should arrive immediately
661         templates = ipfix.verify_templates(ipfix_decoder, count=1)
662
663         self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1,
664                            ip_ver='IPv6')
665         capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
666
667         # make sure the one packet we expect actually showed up
668         self.vapi.cli("ipfix flush")
669         cflow = self.wait_for_cflow_packet(self.collector, templates[0])
670         self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
671                                       {2: 'packets', 7: 'sport', 11: 'dport'},
672                                       ip_ver='v6')
673
674         # expected two templates and one cflow packet
675         self.collector.get_capture(2)
676
677         ipfix.remove_vpp_config()
678         self.logger.info("FFP_TEST_FINISH_0003")
679
680     def test_0001(self):
681         """ no timers, one CFLOW packet, 9 Flows inside"""
682         self.logger.info("FFP_TEST_START_0001")
683         self.pg_enable_capture(self.pg_interfaces)
684         self.pkts = []
685
686         ipfix = VppCFLOW(test=self)
687         ipfix.add_vpp_config()
688
689         ipfix_decoder = IPFIXDecoder()
690         # template packet should arrive immediately
691         templates = ipfix.verify_templates(ipfix_decoder)
692
693         self.create_stream(packets=9)
694         capture = self.send_packets()
695
696         # make sure the one packet we expect actually showed up
697         self.vapi.cli("ipfix flush")
698         cflow = self.wait_for_cflow_packet(self.collector, templates[1])
699         self.verify_cflow_data_notimer(ipfix_decoder, capture, [cflow])
700         self.collector.get_capture(4)
701
702         ipfix.remove_vpp_config()
703         self.logger.info("FFP_TEST_FINISH_0001")
704
705     def test_0002(self):
706         """ no timers, two CFLOW packets (mtu=256), 3 Flows in each"""
707         self.logger.info("FFP_TEST_START_0002")
708         self.pg_enable_capture(self.pg_interfaces)
709         self.pkts = []
710
711         ipfix = VppCFLOW(test=self, mtu=256)
712         ipfix.add_vpp_config()
713
714         ipfix_decoder = IPFIXDecoder()
715         # template packet should arrive immediately
716         self.vapi.cli("ipfix flush")
717         templates = ipfix.verify_templates(ipfix_decoder)
718
719         self.create_stream(packets=6)
720         capture = self.send_packets()
721
722         # make sure the one packet we expect actually showed up
723         cflows = []
724         self.vapi.cli("ipfix flush")
725         cflows.append(self.wait_for_cflow_packet(self.collector,
726                                                  templates[1]))
727         cflows.append(self.wait_for_cflow_packet(self.collector,
728                                                  templates[1]))
729         self.verify_cflow_data_notimer(ipfix_decoder, capture, cflows)
730         self.collector.get_capture(5)
731
732         ipfix.remove_vpp_config()
733         self.logger.info("FFP_TEST_FINISH_0002")
734
735
736 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
737 class DisableIPFIX(MethodHolder):
738     """Disable IPFIX"""
739
740     def test_0001(self):
741         """ disable IPFIX after first packets"""
742         self.logger.info("FFP_TEST_START_0001")
743         self.pg_enable_capture(self.pg_interfaces)
744         self.pkts = []
745
746         ipfix = VppCFLOW(test=self)
747         ipfix.add_vpp_config()
748
749         ipfix_decoder = IPFIXDecoder()
750         # template packet should arrive immediately
751         templates = ipfix.verify_templates(ipfix_decoder)
752
753         self.create_stream()
754         self.send_packets()
755
756         # make sure the one packet we expect actually showed up
757         self.vapi.cli("ipfix flush")
758         self.wait_for_cflow_packet(self.collector, templates[1])
759         self.collector.get_capture(4)
760
761         # disble IPFIX
762         ipfix.disable_exporter()
763         self.pg_enable_capture([self.collector])
764
765         self.send_packets()
766
767         # make sure no one packet arrived in 1 minute
768         self.vapi.cli("ipfix flush")
769         self.wait_for_cflow_packet(self.collector, templates[1],
770                                    expected=False)
771         self.collector.get_capture(0)
772
773         ipfix.remove_vpp_config()
774         self.logger.info("FFP_TEST_FINISH_0001")
775
776
777 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
778 class ReenableIPFIX(MethodHolder):
779     """Re-enable IPFIX"""
780
781     def test_0011(self):
782         """ disable IPFIX after first packets and re-enable after few packets
783         """
784         self.logger.info("FFP_TEST_START_0001")
785         self.pg_enable_capture(self.pg_interfaces)
786         self.pkts = []
787
788         ipfix = VppCFLOW(test=self)
789         ipfix.add_vpp_config()
790
791         ipfix_decoder = IPFIXDecoder()
792         # template packet should arrive immediately
793         templates = ipfix.verify_templates(ipfix_decoder)
794
795         self.create_stream(packets=5)
796         self.send_packets()
797
798         # make sure the one packet we expect actually showed up
799         self.vapi.cli("ipfix flush")
800         self.wait_for_cflow_packet(self.collector, templates[1])
801         self.collector.get_capture(4)
802
803         # disble IPFIX
804         ipfix.disable_exporter()
805         self.vapi.cli("ipfix flush")
806         self.pg_enable_capture([self.collector])
807
808         self.send_packets()
809
810         # make sure no one packet arrived in active timer span
811         self.vapi.cli("ipfix flush")
812         self.wait_for_cflow_packet(self.collector, templates[1],
813                                    expected=False)
814         self.collector.get_capture(0)
815         self.pg2.get_capture(5)
816
817         # enable IPFIX
818         ipfix.enable_exporter()
819
820         capture = self.collector.get_capture(4)
821         nr_templates = 0
822         nr_data = 0
823         for p in capture:
824             self.assertTrue(p.haslayer(IPFIX))
825             if p.haslayer(Template):
826                 nr_templates += 1
827         self.assertTrue(nr_templates, 3)
828         for p in capture:
829             self.assertTrue(p.haslayer(IPFIX))
830             if p.haslayer(Data):
831                 nr_data += 1
832         self.assertTrue(nr_templates, 1)
833
834         ipfix.remove_vpp_config()
835         self.logger.info("FFP_TEST_FINISH_0001")
836
837
838 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
839 class DisableFP(MethodHolder):
840     """Disable Flowprobe feature"""
841
842     def test_0001(self):
843         """ disable flowprobe feature after first packets"""
844         self.logger.info("FFP_TEST_START_0001")
845         self.pg_enable_capture(self.pg_interfaces)
846         self.pkts = []
847         ipfix = VppCFLOW(test=self)
848         ipfix.add_vpp_config()
849
850         ipfix_decoder = IPFIXDecoder()
851         # template packet should arrive immediately
852         templates = ipfix.verify_templates(ipfix_decoder)
853
854         self.create_stream()
855         self.send_packets()
856
857         # make sure the one packet we expect actually showed up
858         self.vapi.cli("ipfix flush")
859         self.wait_for_cflow_packet(self.collector, templates[1])
860         self.collector.get_capture(4)
861
862         # disble IPFIX
863         ipfix.disable_flowprobe_feature()
864         self.pg_enable_capture([self.collector])
865
866         self.send_packets()
867
868         # make sure no one packet arrived in active timer span
869         self.vapi.cli("ipfix flush")
870         self.wait_for_cflow_packet(self.collector, templates[1],
871                                    expected=False)
872         self.collector.get_capture(0)
873
874         ipfix.remove_vpp_config()
875         self.logger.info("FFP_TEST_FINISH_0001")
876
877
878 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
879 class ReenableFP(MethodHolder):
880     """Re-enable Flowprobe feature"""
881
882     def test_0001(self):
883         """ disable flowprobe feature after first packets and re-enable
884         after few packets """
885         self.logger.info("FFP_TEST_START_0001")
886         self.pg_enable_capture(self.pg_interfaces)
887         self.pkts = []
888
889         ipfix = VppCFLOW(test=self)
890         ipfix.add_vpp_config()
891
892         ipfix_decoder = IPFIXDecoder()
893         # template packet should arrive immediately
894         self.vapi.cli("ipfix flush")
895         templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
896
897         self.create_stream()
898         self.send_packets()
899
900         # make sure the one packet we expect actually showed up
901         self.vapi.cli("ipfix flush")
902         self.wait_for_cflow_packet(self.collector, templates[1], 5)
903         self.collector.get_capture(4)
904
905         # disble FPP feature
906         ipfix.disable_flowprobe_feature()
907         self.pg_enable_capture([self.collector])
908
909         self.send_packets()
910
911         # make sure no one packet arrived in active timer span
912         self.vapi.cli("ipfix flush")
913         self.wait_for_cflow_packet(self.collector, templates[1], 5,
914                                    expected=False)
915         self.collector.get_capture(0)
916
917         # enable FPP feature
918         ipfix.enable_flowprobe_feature()
919         self.vapi.cli("ipfix flush")
920         templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
921
922         self.send_packets()
923
924         # make sure the next packets (templates and data) we expect actually
925         # showed up
926         self.vapi.cli("ipfix flush")
927         self.wait_for_cflow_packet(self.collector, templates[1], 5)
928         self.collector.get_capture(4)
929
930         ipfix.remove_vpp_config()
931         self.logger.info("FFP_TEST_FINISH_0001")
932
933
934 if __name__ == '__main__':
935     unittest.main(testRunner=VppTestRunner)