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