2 from __future__ import print_function
10 from scapy.packet import Raw
11 from scapy.layers.l2 import Ether
12 from scapy.layers.inet import IP, TCP, UDP
13 from scapy.layers.inet6 import IPv6
15 from config import config
16 from framework import tag_fixme_vpp_workers
17 from framework import VppTestCase, VppTestRunner
18 from framework import tag_run_solo
19 from vpp_object import VppObject
20 from vpp_pg_interface import CaptureTimeoutError
22 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
23 from vpp_ip_route import VppIpRoute, VppRoutePath
24 from vpp_papi.macaddress import mac_ntop
25 from socket import inet_ntop
26 from vpp_papi import VppEnum
29 class VppCFLOW(VppObject):
30 """CFLOW object for IPFIX exporter and Flowprobe feature"""
46 self._intf_obj = getattr(self._test, intf)
48 if passive == 0 or passive < active:
49 self._passive = active + 1
51 self._passive = passive
52 self._datapath = datapath # l2 ip4 ip6
53 self._collect = layer # l2 l3 l4
54 self._direction = direction # rx tx both
55 self._timeout = timeout
57 self._configured = False
59 def add_vpp_config(self):
60 self.enable_exporter()
64 if "l2" in self._collect.lower():
65 l2_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L2
66 if "l3" in self._collect.lower():
67 l3_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L3
68 if "l4" in self._collect.lower():
69 l4_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L4
70 self._test.vapi.flowprobe_params(
71 record_flags=(l2_flag | l3_flag | l4_flag),
72 active_timer=self._active,
73 passive_timer=self._passive,
75 self.enable_flowprobe_feature()
76 self._test.vapi.cli("ipfix flush")
77 self._configured = True
79 def remove_vpp_config(self):
80 self.disable_exporter()
81 self.disable_flowprobe_feature()
82 self._test.vapi.cli("ipfix flush")
83 self._configured = False
85 def enable_exporter(self):
86 self._test.vapi.set_ipfix_exporter(
87 collector_address=self._test.pg0.remote_ip4,
88 src_address=self._test.pg0.local_ip4,
90 template_interval=self._timeout,
93 def _enable_disable_flowprobe_feature(self, is_add):
95 "l2": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_L2,
96 "ip4": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4,
97 "ip6": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP6,
100 "rx": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_RX,
101 "tx": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
102 "both": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_BOTH,
104 self._test.vapi.flowprobe_interface_add_del(
106 which=which_map[self._datapath],
107 direction=direction_map[self._direction],
108 sw_if_index=self._intf_obj.sw_if_index,
111 def enable_flowprobe_feature(self):
112 self._enable_disable_flowprobe_feature(is_add=True)
114 def disable_exporter(self):
115 self._test.vapi.cli("set ipfix exporter collector 0.0.0.0")
117 def disable_flowprobe_feature(self):
118 self._enable_disable_flowprobe_feature(is_add=False)
121 return "ipfix-collector-%s-%s" % (self._src, self.dst)
123 def query_vpp_config(self):
124 return self._configured
126 def verify_templates(self, decoder=None, timeout=1, count=3):
128 self._test.assertIn(count, (1, 2, 3))
129 for _ in range(count):
130 p = self._test.wait_for_cflow_packet(self._test.collector, 2, timeout)
131 self._test.assertTrue(p.haslayer(IPFIX))
132 if decoder is not None and p.haslayer(Template):
133 templates.append(p[Template].templateID)
134 decoder.add_template(p.getlayer(Template))
138 class MethodHolder(VppTestCase):
139 """Flow-per-packet plugin: test L2, IP4, IP6 reporting"""
143 max_number_of_packets = 10
149 Perform standard class setup (defined by class method setUpClass in
150 class VppTestCase) before running the test case, set test case related
151 variables and configure VPP.
153 super(MethodHolder, cls).setUpClass()
155 # Create pg interfaces
156 cls.create_pg_interfaces(range(9))
159 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
161 # Create BD with MAC learning and unknown unicast flooding disabled
162 # and put interfaces to this BD
163 cls.vapi.bridge_domain_add_del(bd_id=1, uu_flood=1, learn=1)
164 cls.vapi.sw_interface_set_l2_bridge(
165 rx_sw_if_index=cls.pg1._sw_if_index, bd_id=1
167 cls.vapi.sw_interface_set_l2_bridge(
168 rx_sw_if_index=cls.pg2._sw_if_index, bd_id=1
171 # Set up all interfaces
172 for i in cls.pg_interfaces:
176 cls.pg0.configure_ipv4_neighbors()
177 cls.collector = cls.pg0
180 cls.pg1.resolve_arp()
182 cls.pg2.resolve_arp()
184 cls.pg3.resolve_arp()
186 cls.pg4.resolve_arp()
189 cls.pg8.configure_ipv4_neighbors()
192 cls.pg5.resolve_ndp()
193 cls.pg5.disable_ipv6_ra()
195 cls.pg6.resolve_ndp()
196 cls.pg6.disable_ipv6_ra()
198 super(MethodHolder, cls).tearDownClass()
202 def tearDownClass(cls):
203 super(MethodHolder, cls).tearDownClass()
206 self, src_if=None, dst_if=None, packets=None, size=None, ip_ver="v4"
208 """Create a packet stream to tickle the plugin
210 :param VppInterface src_if: Source interface for packet stream
211 :param VppInterface src_if: Dst interface for packet stream
219 packets = random.randint(1, self.max_number_of_packets)
221 for p in range(0, packets):
223 pkt_size = random.choice(self.pg_if_packet_sizes)
224 info = self.create_packet_info(src_if, dst_if)
225 payload = self.info_to_payload(info)
226 p = Ether(src=src_if.remote_mac, dst=src_if.local_mac)
228 p /= IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
230 p /= IPv6(src=src_if.remote_ip6, dst=dst_if.remote_ip6)
231 p /= UDP(sport=1234, dport=4321)
234 self.extend_packet(p, pkt_size)
237 def verify_cflow_data(self, decoder, capture, cflow):
243 if cflow.haslayer(Data):
244 data = decoder.decode_data_set(cflow.getlayer(Set))
246 self.assertEqual(int(binascii.hexlify(record[1]), 16), octets)
247 self.assertEqual(int(binascii.hexlify(record[2]), 16), packets)
249 def send_packets(self, src_if=None, dst_if=None):
254 self.pg_enable_capture([dst_if])
255 src_if.add_stream(self.pkts)
257 return dst_if.get_capture(len(self.pkts))
259 def verify_cflow_data_detail(
260 self, decoder, capture, cflow, data_set={1: "octets", 2: "packets"}, ip_ver="v4"
263 print(capture[0].show())
264 if cflow.haslayer(Data):
265 data = decoder.decode_data_set(cflow.getlayer(Set))
269 ip_layer = capture[0][IP]
271 ip_layer = capture[0][IPv6]
272 if data_set is not None:
274 # skip flow if ingress/egress interface is 0
275 if int(binascii.hexlify(record[10]), 16) == 0:
277 if int(binascii.hexlify(record[14]), 16) == 0:
280 for field in data_set:
281 value = data_set[field]
282 if value == "octets":
285 value += 40 # ??? is this correct
286 elif value == "packets":
288 elif value == "src_ip":
290 ip = socket.inet_pton(socket.AF_INET, ip_layer.src)
292 ip = socket.inet_pton(socket.AF_INET6, ip_layer.src)
293 value = int(binascii.hexlify(ip), 16)
294 elif value == "dst_ip":
296 ip = socket.inet_pton(socket.AF_INET, ip_layer.dst)
298 ip = socket.inet_pton(socket.AF_INET6, ip_layer.dst)
299 value = int(binascii.hexlify(ip), 16)
300 elif value == "sport":
301 value = int(capture[0][UDP].sport)
302 elif value == "dport":
303 value = int(capture[0][UDP].dport)
305 int(binascii.hexlify(record[field]), 16), value
308 def verify_cflow_data_notimer(self, decoder, capture, cflows):
311 if cflow.haslayer(Data):
312 data = decoder.decode_data_set(cflow.getlayer(Set))
314 raise Exception("No CFLOW data")
319 self.assertEqual(p[IP].len, int(binascii.hexlify(rec[1]), 16))
320 self.assertEqual(1, int(binascii.hexlify(rec[2]), 16))
321 self.assertEqual(len(capture), idx)
323 def wait_for_cflow_packet(self, collector_intf, set_id=2, timeout=1):
324 """wait for CFLOW packet and verify its correctness
326 :param timeout: how long to wait
329 self.logger.info("IPFIX: Waiting for CFLOW packet")
330 # self.logger.debug(self.vapi.ppcli("show flow table"))
331 p = collector_intf.wait_for_packet(timeout=timeout)
332 self.assertEqual(p[Set].setID, set_id)
333 # self.logger.debug(self.vapi.ppcli("show flow table"))
334 self.logger.debug(ppp("IPFIX: Got packet:", p))
339 @tag_fixme_vpp_workers
340 class Flowprobe(MethodHolder):
341 """Template verification, timer tests"""
345 super(Flowprobe, cls).setUpClass()
348 def tearDownClass(cls):
349 super(Flowprobe, cls).tearDownClass()
352 """timer less than template timeout"""
353 self.logger.info("FFP_TEST_START_0001")
354 self.pg_enable_capture(self.pg_interfaces)
357 ipfix = VppCFLOW(test=self, active=2)
358 ipfix.add_vpp_config()
360 ipfix_decoder = IPFIXDecoder()
361 # template packet should arrive immediately
362 templates = ipfix.verify_templates(ipfix_decoder)
364 self.create_stream(packets=1)
366 capture = self.pg2.get_capture(1)
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)
372 ipfix.remove_vpp_config()
373 self.logger.info("FFP_TEST_FINISH_0001")
376 """timer greater than template timeout"""
377 self.logger.info("FFP_TEST_START_0002")
378 self.pg_enable_capture(self.pg_interfaces)
381 ipfix = VppCFLOW(test=self, timeout=3, active=4)
382 ipfix.add_vpp_config()
384 ipfix_decoder = IPFIXDecoder()
385 # template packet should arrive immediately
386 ipfix.verify_templates()
388 self.create_stream(packets=2)
390 capture = self.pg2.get_capture(2)
392 # next set of template packet should arrive after 20 seconds
393 # template packet should arrive within 20 s
394 templates = ipfix.verify_templates(ipfix_decoder, timeout=5)
396 # make sure the one packet we expect actually showed up
397 cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
398 self.verify_cflow_data(ipfix_decoder, capture, cflow)
400 ipfix.remove_vpp_config()
401 self.logger.info("FFP_TEST_FINISH_0002")
403 def test_cflow_packet(self):
404 """verify cflow packet fields"""
405 self.logger.info("FFP_TEST_START_0000")
406 self.pg_enable_capture(self.pg_interfaces)
410 test=self, intf="pg8", datapath="ip4", layer="l2 l3 l4", active=2
412 ipfix.add_vpp_config()
414 route_9001 = VppIpRoute(
418 [VppRoutePath(self.pg8._remote_hosts[0].ip4, self.pg8.sw_if_index)],
420 route_9001.add_vpp_config()
422 ipfix_decoder = IPFIXDecoder()
423 templates = ipfix.verify_templates(ipfix_decoder, count=1)
427 Ether(dst=self.pg7.local_mac, src=self.pg7.remote_mac)
428 / IP(src=self.pg7.remote_ip4, dst="9.0.0.100")
429 / TCP(sport=1234, dport=4321, flags=80)
434 nowUTC = int(time.time())
435 nowUNIX = nowUTC + 2208988800
436 self.send_packets(src_if=self.pg7, dst_if=self.pg8)
438 cflow = self.wait_for_cflow_packet(self.collector, templates[0], 10)
439 self.collector.get_capture(2)
441 if cflow[0].haslayer(IPFIX):
442 self.assertEqual(cflow[IPFIX].version, 10)
443 self.assertEqual(cflow[IPFIX].observationDomainID, 1)
444 self.assertEqual(cflow[IPFIX].sequenceNumber, 0)
445 self.assertAlmostEqual(cflow[IPFIX].exportTime, nowUTC, delta=5)
446 if cflow.haslayer(Data):
447 record = ipfix_decoder.decode_data_set(cflow[0].getlayer(Set))[0]
449 self.assertEqual(int(binascii.hexlify(record[10]), 16), 8)
451 self.assertEqual(int(binascii.hexlify(record[14]), 16), 9)
453 self.assertEqual(int(binascii.hexlify(record[61]), 16), 1)
455 self.assertEqual(int(binascii.hexlify(record[2]), 16), 1)
457 self.assertEqual(mac_ntop(record[56]), self.pg8.local_mac)
459 self.assertEqual(mac_ntop(record[80]), self.pg8.remote_mac)
460 flowTimestamp = int(binascii.hexlify(record[156]), 16) >> 32
461 # flow start timestamp
462 self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
463 flowTimestamp = int(binascii.hexlify(record[157]), 16) >> 32
465 self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
467 self.assertEqual(int(binascii.hexlify(record[256]), 16), 8)
469 self.assertEqual(inet_ntop(socket.AF_INET, record[8]), self.pg7.remote_ip4)
471 self.assertEqual(inet_ntop(socket.AF_INET, record[12]), "9.0.0.100")
473 self.assertEqual(int(binascii.hexlify(record[4]), 16), 6)
475 self.assertEqual(int(binascii.hexlify(record[7]), 16), 1234)
477 self.assertEqual(int(binascii.hexlify(record[11]), 16), 4321)
479 self.assertEqual(int(binascii.hexlify(record[6]), 16), 80)
481 ipfix.remove_vpp_config()
482 self.logger.info("FFP_TEST_FINISH_0000")
485 class DatapathTestsHolder(object):
486 """collect information on Ethernet, IP4 and IP6 datapath (no timers)"""
490 super(DatapathTestsHolder, cls).setUpClass()
493 def tearDownClass(cls):
494 super(DatapathTestsHolder, cls).tearDownClass()
496 def test_templatesL2(self):
497 """verify template on L2 datapath"""
498 self.logger.info("FFP_TEST_START_0000")
499 self.pg_enable_capture(self.pg_interfaces)
502 test=self, intf=self.intf1, layer="l2", direction=self.direction
504 ipfix.add_vpp_config()
506 # template packet should arrive immediately
507 self.vapi.ipfix_flush()
508 ipfix.verify_templates(timeout=3, count=1)
509 self.collector.get_capture(1)
511 ipfix.remove_vpp_config()
512 self.logger.info("FFP_TEST_FINISH_0000")
514 def test_L2onL2(self):
515 """L2 data on L2 datapath"""
516 self.logger.info("FFP_TEST_START_0001")
517 self.pg_enable_capture(self.pg_interfaces)
521 test=self, intf=self.intf1, layer="l2", direction=self.direction
523 ipfix.add_vpp_config()
525 ipfix_decoder = IPFIXDecoder()
526 # template packet should arrive immediately
527 templates = ipfix.verify_templates(ipfix_decoder, count=1)
529 self.create_stream(packets=1)
530 capture = self.send_packets()
532 # make sure the one packet we expect actually showed up
533 self.vapi.ipfix_flush()
534 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
535 self.verify_cflow_data_detail(
539 {2: "packets", 256: 8, 61: (self.direction == "tx")},
541 self.collector.get_capture(2)
543 ipfix.remove_vpp_config()
544 self.logger.info("FFP_TEST_FINISH_0001")
546 def test_L3onL2(self):
547 """L3 data on L2 datapath"""
548 self.logger.info("FFP_TEST_START_0002")
549 self.pg_enable_capture(self.pg_interfaces)
553 test=self, intf=self.intf1, layer="l3", direction=self.direction
555 ipfix.add_vpp_config()
557 ipfix_decoder = IPFIXDecoder()
558 # template packet should arrive immediately
559 templates = ipfix.verify_templates(ipfix_decoder, count=2)
561 self.create_stream(packets=1)
562 capture = self.send_packets()
564 # make sure the one packet we expect actually showed up
565 self.vapi.ipfix_flush()
566 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
567 self.verify_cflow_data_detail(
576 61: (self.direction == "tx"),
580 self.collector.get_capture(3)
582 ipfix.remove_vpp_config()
583 self.logger.info("FFP_TEST_FINISH_0002")
585 def test_L4onL2(self):
586 """L4 data on L2 datapath"""
587 self.logger.info("FFP_TEST_START_0003")
588 self.pg_enable_capture(self.pg_interfaces)
592 test=self, intf=self.intf1, layer="l4", direction=self.direction
594 ipfix.add_vpp_config()
596 ipfix_decoder = IPFIXDecoder()
597 # template packet should arrive immediately
598 templates = ipfix.verify_templates(ipfix_decoder, count=2)
600 self.create_stream(packets=1)
601 capture = self.send_packets()
603 # make sure the one packet we expect actually showed up
604 self.vapi.ipfix_flush()
605 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
606 self.verify_cflow_data_detail(
610 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
613 self.collector.get_capture(3)
615 ipfix.remove_vpp_config()
616 self.logger.info("FFP_TEST_FINISH_0003")
618 def test_templatesIp4(self):
619 """verify templates on IP4 datapath"""
620 self.logger.info("FFP_TEST_START_0000")
622 self.pg_enable_capture(self.pg_interfaces)
625 test=self, intf=self.intf1, datapath="ip4", direction=self.direction
627 ipfix.add_vpp_config()
629 # template packet should arrive immediately
630 self.vapi.ipfix_flush()
631 ipfix.verify_templates(timeout=3, count=1)
632 self.collector.get_capture(1)
634 ipfix.remove_vpp_config()
636 self.logger.info("FFP_TEST_FINISH_0000")
638 def test_L2onIP4(self):
639 """L2 data on IP4 datapath"""
640 self.logger.info("FFP_TEST_START_0001")
641 self.pg_enable_capture(self.pg_interfaces)
649 direction=self.direction,
651 ipfix.add_vpp_config()
653 ipfix_decoder = IPFIXDecoder()
654 # template packet should arrive immediately
655 templates = ipfix.verify_templates(ipfix_decoder, count=1)
657 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
658 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
660 # make sure the one packet we expect actually showed up
661 self.vapi.ipfix_flush()
662 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
663 self.verify_cflow_data_detail(
667 {2: "packets", 256: 8, 61: (self.direction == "tx")},
670 # expected two templates and one cflow packet
671 self.collector.get_capture(2)
673 ipfix.remove_vpp_config()
674 self.logger.info("FFP_TEST_FINISH_0001")
676 def test_L3onIP4(self):
677 """L3 data on IP4 datapath"""
678 self.logger.info("FFP_TEST_START_0002")
679 self.pg_enable_capture(self.pg_interfaces)
687 direction=self.direction,
689 ipfix.add_vpp_config()
691 ipfix_decoder = IPFIXDecoder()
692 # template packet should arrive immediately
693 templates = ipfix.verify_templates(ipfix_decoder, count=1)
695 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
696 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
698 # make sure the one packet we expect actually showed up
699 self.vapi.ipfix_flush()
700 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
701 self.verify_cflow_data_detail(
710 61: (self.direction == "tx"),
714 # expected two templates and one cflow packet
715 self.collector.get_capture(2)
717 ipfix.remove_vpp_config()
718 self.logger.info("FFP_TEST_FINISH_0002")
720 def test_L4onIP4(self):
721 """L4 data on IP4 datapath"""
722 self.logger.info("FFP_TEST_START_0003")
723 self.pg_enable_capture(self.pg_interfaces)
731 direction=self.direction,
733 ipfix.add_vpp_config()
735 ipfix_decoder = IPFIXDecoder()
736 # template packet should arrive immediately
737 templates = ipfix.verify_templates(ipfix_decoder, count=1)
739 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
740 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
742 # make sure the one packet we expect actually showed up
743 self.vapi.ipfix_flush()
744 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
745 self.verify_cflow_data_detail(
749 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
752 # expected two templates and one cflow packet
753 self.collector.get_capture(2)
755 ipfix.remove_vpp_config()
756 self.logger.info("FFP_TEST_FINISH_0003")
758 def test_templatesIP6(self):
759 """verify templates on IP6 datapath"""
760 self.logger.info("FFP_TEST_START_0000")
761 self.pg_enable_capture(self.pg_interfaces)
764 test=self, intf=self.intf1, datapath="ip6", direction=self.direction
766 ipfix.add_vpp_config()
768 # template packet should arrive immediately
769 ipfix.verify_templates(count=1)
770 self.collector.get_capture(1)
772 ipfix.remove_vpp_config()
774 self.logger.info("FFP_TEST_FINISH_0000")
776 def test_L2onIP6(self):
777 """L2 data on IP6 datapath"""
778 self.logger.info("FFP_TEST_START_0001")
779 self.pg_enable_capture(self.pg_interfaces)
787 direction=self.direction,
789 ipfix.add_vpp_config()
791 ipfix_decoder = IPFIXDecoder()
792 # template packet should arrive immediately
793 templates = ipfix.verify_templates(ipfix_decoder, count=1)
795 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
796 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
798 # make sure the one packet we expect actually showed up
799 self.vapi.ipfix_flush()
800 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
801 self.verify_cflow_data_detail(
805 {2: "packets", 256: 56710, 61: (self.direction == "tx")},
809 # expected two templates and one cflow packet
810 self.collector.get_capture(2)
812 ipfix.remove_vpp_config()
813 self.logger.info("FFP_TEST_FINISH_0001")
815 def test_L3onIP6(self):
816 """L3 data on IP6 datapath"""
817 self.logger.info("FFP_TEST_START_0002")
818 self.pg_enable_capture(self.pg_interfaces)
826 direction=self.direction,
828 ipfix.add_vpp_config()
830 ipfix_decoder = IPFIXDecoder()
831 # template packet should arrive immediately
832 templates = ipfix.verify_templates(ipfix_decoder, count=1)
834 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
835 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
837 # make sure the one packet we expect actually showed up
838 self.vapi.ipfix_flush()
839 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
840 self.verify_cflow_data_detail(
844 {2: "packets", 27: "src_ip", 28: "dst_ip", 61: (self.direction == "tx")},
848 # expected two templates and one cflow packet
849 self.collector.get_capture(2)
851 ipfix.remove_vpp_config()
852 self.logger.info("FFP_TEST_FINISH_0002")
854 def test_L4onIP6(self):
855 """L4 data on IP6 datapath"""
856 self.logger.info("FFP_TEST_START_0003")
857 self.pg_enable_capture(self.pg_interfaces)
865 direction=self.direction,
867 ipfix.add_vpp_config()
869 ipfix_decoder = IPFIXDecoder()
870 # template packet should arrive immediately
871 templates = ipfix.verify_templates(ipfix_decoder, count=1)
873 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
874 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
876 # make sure the one packet we expect actually showed up
877 self.vapi.ipfix_flush()
878 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
879 self.verify_cflow_data_detail(
883 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
887 # expected two templates and one cflow packet
888 self.collector.get_capture(2)
890 ipfix.remove_vpp_config()
891 self.logger.info("FFP_TEST_FINISH_0003")
894 """no timers, one CFLOW packet, 9 Flows inside"""
895 self.logger.info("FFP_TEST_START_0001")
896 self.pg_enable_capture(self.pg_interfaces)
899 ipfix = VppCFLOW(test=self, intf=self.intf1, direction=self.direction)
900 ipfix.add_vpp_config()
902 ipfix_decoder = IPFIXDecoder()
903 # template packet should arrive immediately
904 templates = ipfix.verify_templates(ipfix_decoder)
906 self.create_stream(packets=9)
907 capture = self.send_packets()
909 # make sure the one packet we expect actually showed up
910 self.vapi.ipfix_flush()
911 cflow = self.wait_for_cflow_packet(self.collector, templates[1])
912 self.verify_cflow_data_notimer(ipfix_decoder, capture, [cflow])
913 self.collector.get_capture(4)
915 ipfix.remove_vpp_config()
916 self.logger.info("FFP_TEST_FINISH_0001")
919 """no timers, two CFLOW packets (mtu=260), 3 Flows in each"""
920 self.logger.info("FFP_TEST_START_0002")
921 self.pg_enable_capture(self.pg_interfaces)
924 ipfix = VppCFLOW(test=self, intf=self.intf1, direction=self.direction, mtu=260)
925 ipfix.add_vpp_config()
927 ipfix_decoder = IPFIXDecoder()
928 # template packet should arrive immediately
929 self.vapi.ipfix_flush()
930 templates = ipfix.verify_templates(ipfix_decoder)
932 self.create_stream(packets=6)
933 capture = self.send_packets()
935 # make sure the one packet we expect actually showed up
937 self.vapi.ipfix_flush()
938 cflows.append(self.wait_for_cflow_packet(self.collector, templates[1]))
939 cflows.append(self.wait_for_cflow_packet(self.collector, templates[1]))
940 self.verify_cflow_data_notimer(ipfix_decoder, capture, cflows)
941 self.collector.get_capture(5)
943 ipfix.remove_vpp_config()
944 self.logger.info("FFP_TEST_FINISH_0002")
947 @tag_fixme_vpp_workers
948 class DatapathTx(MethodHolder, DatapathTestsHolder):
949 """Collect info on Ethernet, IP4 and IP6 datapath (TX) (no timers)"""
957 @tag_fixme_vpp_workers
958 class DatapathRx(MethodHolder, DatapathTestsHolder):
959 """Collect info on Ethernet, IP4 and IP6 datapath (RX) (no timers)"""
967 @unittest.skipUnless(config.extended, "part of extended tests")
968 class DisableIPFIX(MethodHolder):
973 super(DisableIPFIX, cls).setUpClass()
976 def tearDownClass(cls):
977 super(DisableIPFIX, cls).tearDownClass()
980 """disable IPFIX after first packets"""
981 self.logger.info("FFP_TEST_START_0001")
982 self.pg_enable_capture(self.pg_interfaces)
985 ipfix = VppCFLOW(test=self)
986 ipfix.add_vpp_config()
988 ipfix_decoder = IPFIXDecoder()
989 # template packet should arrive immediately
990 templates = ipfix.verify_templates(ipfix_decoder)
995 # make sure the one packet we expect actually showed up
996 self.vapi.ipfix_flush()
997 self.wait_for_cflow_packet(self.collector, templates[1])
998 self.collector.get_capture(4)
1001 ipfix.disable_exporter()
1002 self.pg_enable_capture([self.collector])
1006 # make sure no one packet arrived in 1 minute
1007 self.vapi.ipfix_flush()
1008 self.sleep(1, "wait before verifying no packets sent")
1009 self.collector.assert_nothing_captured()
1011 ipfix.remove_vpp_config()
1012 self.logger.info("FFP_TEST_FINISH_0001")
1015 @unittest.skipUnless(config.extended, "part of extended tests")
1016 class ReenableIPFIX(MethodHolder):
1017 """Re-enable IPFIX"""
1020 def setUpClass(cls):
1021 super(ReenableIPFIX, cls).setUpClass()
1024 def tearDownClass(cls):
1025 super(ReenableIPFIX, cls).tearDownClass()
1027 def test_0011(self):
1028 """disable IPFIX after first packets and re-enable after few packets"""
1029 self.logger.info("FFP_TEST_START_0001")
1030 self.pg_enable_capture(self.pg_interfaces)
1033 ipfix = VppCFLOW(test=self)
1034 ipfix.add_vpp_config()
1036 ipfix_decoder = IPFIXDecoder()
1037 # template packet should arrive immediately
1038 templates = ipfix.verify_templates(ipfix_decoder)
1040 self.create_stream(packets=5)
1043 # make sure the one packet we expect actually showed up
1044 self.vapi.ipfix_flush()
1045 self.wait_for_cflow_packet(self.collector, templates[1])
1046 self.collector.get_capture(4)
1049 ipfix.disable_exporter()
1050 self.vapi.ipfix_flush()
1051 self.pg_enable_capture([self.collector])
1055 # make sure no one packet arrived in active timer span
1056 self.vapi.ipfix_flush()
1057 self.sleep(1, "wait before verifying no packets sent")
1058 self.collector.assert_nothing_captured()
1059 self.pg2.get_capture(5)
1062 ipfix.enable_exporter()
1064 capture = self.collector.get_capture(4)
1068 self.assertTrue(p.haslayer(IPFIX))
1069 if p.haslayer(Template):
1071 self.assertTrue(nr_templates, 3)
1073 self.assertTrue(p.haslayer(IPFIX))
1074 if p.haslayer(Data):
1076 self.assertTrue(nr_templates, 1)
1078 ipfix.remove_vpp_config()
1079 self.logger.info("FFP_TEST_FINISH_0001")
1082 @unittest.skipUnless(config.extended, "part of extended tests")
1083 class DisableFP(MethodHolder):
1084 """Disable Flowprobe feature"""
1087 def setUpClass(cls):
1088 super(DisableFP, cls).setUpClass()
1091 def tearDownClass(cls):
1092 super(DisableFP, cls).tearDownClass()
1094 def test_0001(self):
1095 """disable flowprobe feature after first packets"""
1096 self.logger.info("FFP_TEST_START_0001")
1097 self.pg_enable_capture(self.pg_interfaces)
1099 ipfix = VppCFLOW(test=self)
1100 ipfix.add_vpp_config()
1102 ipfix_decoder = IPFIXDecoder()
1103 # template packet should arrive immediately
1104 templates = ipfix.verify_templates(ipfix_decoder)
1106 self.create_stream()
1109 # make sure the one packet we expect actually showed up
1110 self.vapi.ipfix_flush()
1111 self.wait_for_cflow_packet(self.collector, templates[1])
1112 self.collector.get_capture(4)
1115 ipfix.disable_flowprobe_feature()
1116 self.pg_enable_capture([self.collector])
1120 # make sure no one packet arrived in active timer span
1121 self.vapi.ipfix_flush()
1122 self.sleep(1, "wait before verifying no packets sent")
1123 self.collector.assert_nothing_captured()
1125 ipfix.remove_vpp_config()
1126 self.logger.info("FFP_TEST_FINISH_0001")
1129 @unittest.skipUnless(config.extended, "part of extended tests")
1130 class ReenableFP(MethodHolder):
1131 """Re-enable Flowprobe feature"""
1134 def setUpClass(cls):
1135 super(ReenableFP, cls).setUpClass()
1138 def tearDownClass(cls):
1139 super(ReenableFP, cls).tearDownClass()
1141 def test_0001(self):
1142 """disable flowprobe feature after first packets and re-enable
1143 after few packets"""
1144 self.logger.info("FFP_TEST_START_0001")
1145 self.pg_enable_capture(self.pg_interfaces)
1148 ipfix = VppCFLOW(test=self)
1149 ipfix.add_vpp_config()
1151 ipfix_decoder = IPFIXDecoder()
1152 # template packet should arrive immediately
1153 self.vapi.ipfix_flush()
1154 templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
1156 self.create_stream()
1159 # make sure the one packet we expect actually showed up
1160 self.vapi.ipfix_flush()
1161 self.wait_for_cflow_packet(self.collector, templates[1], 5)
1162 self.collector.get_capture(4)
1164 # disable FPP feature
1165 ipfix.disable_flowprobe_feature()
1166 self.pg_enable_capture([self.collector])
1170 # make sure no one packet arrived in active timer span
1171 self.vapi.ipfix_flush()
1172 self.sleep(5, "wait before verifying no packets sent")
1173 self.collector.assert_nothing_captured()
1175 # enable FPP feature
1176 ipfix.enable_flowprobe_feature()
1177 self.vapi.ipfix_flush()
1178 templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
1182 # make sure the next packets (templates and data) we expect actually
1184 self.vapi.ipfix_flush()
1185 self.wait_for_cflow_packet(self.collector, templates[1], 5)
1186 self.collector.get_capture(4)
1188 ipfix.remove_vpp_config()
1189 self.logger.info("FFP_TEST_FINISH_0001")
1192 if __name__ == "__main__":
1193 unittest.main(testRunner=VppTestRunner)