blob: 141d7458c39ef44d539a44e6f7b37aef01c4663f [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Paul Vinciguerra661f91f2018-11-28 19:06:41 -08002from __future__ import print_function
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -08003import binascii
Ole Troan5c749732017-03-13 13:39:52 +01004import random
5import socket
6import unittest
7import time
Ole Troaned929252017-06-13 21:15:40 +02008import re
Ole Troan5c749732017-03-13 13:39:52 +01009
10from scapy.packet import Raw
11from scapy.layers.l2 import Ether
Ole Troaned929252017-06-13 21:15:40 +020012from scapy.layers.inet import IP, TCP, UDP
Ole Troan5c749732017-03-13 13:39:52 +010013from scapy.layers.inet6 import IPv6
14
Klement Sekerab23ffd72021-05-31 16:08:53 +020015from config import config
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +000016from framework import tag_fixme_vpp_workers
Klement Sekerab23ffd72021-05-31 16:08:53 +020017from framework import VppTestCase, VppTestRunner
Andrew Yourtchenko06f32812021-01-14 10:19:08 +000018from framework import tag_run_solo
Ole Troan5c749732017-03-13 13:39:52 +010019from vpp_object import VppObject
20from vpp_pg_interface import CaptureTimeoutError
21from util import ppp
22from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
Ole Troaned929252017-06-13 21:15:40 +020023from vpp_ip_route import VppIpRoute, VppRoutePath
Ole Troanb0d83f12019-10-21 23:13:46 +020024from vpp_papi.macaddress import mac_ntop
25from socket import inet_ntop
Ole Troan3013e692019-12-09 15:51:44 +010026from vpp_papi import VppEnum
Ole Troan5c749732017-03-13 13:39:52 +010027
28
29class VppCFLOW(VppObject):
30 """CFLOW object for IPFIX exporter and Flowprobe feature"""
31
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020032 def __init__(
33 self,
34 test,
35 intf="pg2",
36 active=0,
37 passive=0,
38 timeout=100,
39 mtu=1024,
40 datapath="l2",
41 layer="l2 l3 l4",
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +000042 direction="tx",
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020043 ):
Ole Troan5c749732017-03-13 13:39:52 +010044 self._test = test
45 self._intf = intf
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +000046 self._intf_obj = getattr(self._test, intf)
Ole Troan5c749732017-03-13 13:39:52 +010047 self._active = active
48 if passive == 0 or passive < active:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020049 self._passive = active + 1
Ole Troan5c749732017-03-13 13:39:52 +010050 else:
51 self._passive = passive
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020052 self._datapath = datapath # l2 ip4 ip6
53 self._collect = layer # l2 l3 l4
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +000054 self._direction = direction # rx tx both
Ole Troan5c749732017-03-13 13:39:52 +010055 self._timeout = timeout
56 self._mtu = mtu
57 self._configured = False
58
59 def add_vpp_config(self):
60 self.enable_exporter()
Ole Troan3013e692019-12-09 15:51:44 +010061 l2_flag = 0
62 l3_flag = 0
63 l4_flag = 0
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020064 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
Alexander Chernavin86c78562022-05-12 14:56:24 +000070 self._test.vapi.flowprobe_set_params(
Ole Troan3013e692019-12-09 15:51:44 +010071 record_flags=(l2_flag | l3_flag | l4_flag),
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020072 active_timer=self._active,
73 passive_timer=self._passive,
74 )
Ole Troan5c749732017-03-13 13:39:52 +010075 self.enable_flowprobe_feature()
76 self._test.vapi.cli("ipfix flush")
77 self._configured = True
78
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
84
85 def enable_exporter(self):
86 self._test.vapi.set_ipfix_exporter(
Jakub Grajciar2f71a882019-10-10 14:21:22 +020087 collector_address=self._test.pg0.remote_ip4,
88 src_address=self._test.pg0.local_ip4,
Ole Troan5c749732017-03-13 13:39:52 +010089 path_mtu=self._mtu,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020090 template_interval=self._timeout,
91 )
Ole Troan5c749732017-03-13 13:39:52 +010092
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +000093 def _enable_disable_flowprobe_feature(self, is_add):
94 which_map = {
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,
98 }
99 direction_map = {
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,
103 }
104 self._test.vapi.flowprobe_interface_add_del(
105 is_add=is_add,
106 which=which_map[self._datapath],
107 direction=direction_map[self._direction],
108 sw_if_index=self._intf_obj.sw_if_index,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200109 )
Ole Troan5c749732017-03-13 13:39:52 +0100110
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000111 def enable_flowprobe_feature(self):
112 self._enable_disable_flowprobe_feature(is_add=True)
113
Ole Troan5c749732017-03-13 13:39:52 +0100114 def disable_exporter(self):
115 self._test.vapi.cli("set ipfix exporter collector 0.0.0.0")
116
117 def disable_flowprobe_feature(self):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000118 self._enable_disable_flowprobe_feature(is_add=False)
Ole Troan5c749732017-03-13 13:39:52 +0100119
120 def object_id(self):
Paul Vinciguerrae3a0e6e2019-03-14 08:46:52 -0700121 return "ipfix-collector-%s-%s" % (self._src, self.dst)
Ole Troan5c749732017-03-13 13:39:52 +0100122
123 def query_vpp_config(self):
124 return self._configured
125
126 def verify_templates(self, decoder=None, timeout=1, count=3):
127 templates = []
Klement Sekerac4794572021-09-08 15:15:59 +0200128 self._test.assertIn(count, (1, 2, 3))
129 for _ in range(count):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200130 p = self._test.wait_for_cflow_packet(self._test.collector, 2, timeout)
Ole Troan5c749732017-03-13 13:39:52 +0100131 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))
135 return templates
136
137
138class MethodHolder(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200139 """Flow-per-packet plugin: test L2, IP4, IP6 reporting"""
Ole Troan5c749732017-03-13 13:39:52 +0100140
141 # Test variables
142 debug_print = False
Pavel Kotucek89111d02017-06-12 08:26:13 +0200143 max_number_of_packets = 10
Ole Troan5c749732017-03-13 13:39:52 +0100144 pkts = []
145
146 @classmethod
147 def setUpClass(cls):
148 """
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.
152 """
153 super(MethodHolder, cls).setUpClass()
154 try:
155 # Create pg interfaces
Ole Troaned929252017-06-13 21:15:40 +0200156 cls.create_pg_interfaces(range(9))
Ole Troan5c749732017-03-13 13:39:52 +0100157
158 # Packet sizes
159 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
160
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)
Ole Troana5b2eec2019-03-11 19:23:25 +0100164 cls.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200165 rx_sw_if_index=cls.pg1._sw_if_index, bd_id=1
166 )
Ole Troana5b2eec2019-03-11 19:23:25 +0100167 cls.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200168 rx_sw_if_index=cls.pg2._sw_if_index, bd_id=1
169 )
Ole Troan5c749732017-03-13 13:39:52 +0100170
171 # Set up all interfaces
172 for i in cls.pg_interfaces:
173 i.admin_up()
174
175 cls.pg0.config_ip4()
176 cls.pg0.configure_ipv4_neighbors()
177 cls.collector = cls.pg0
178
179 cls.pg1.config_ip4()
180 cls.pg1.resolve_arp()
181 cls.pg2.config_ip4()
182 cls.pg2.resolve_arp()
183 cls.pg3.config_ip4()
184 cls.pg3.resolve_arp()
185 cls.pg4.config_ip4()
186 cls.pg4.resolve_arp()
Ole Troaned929252017-06-13 21:15:40 +0200187 cls.pg7.config_ip4()
188 cls.pg8.config_ip4()
189 cls.pg8.configure_ipv4_neighbors()
Ole Troan5c749732017-03-13 13:39:52 +0100190
191 cls.pg5.config_ip6()
192 cls.pg5.resolve_ndp()
193 cls.pg5.disable_ipv6_ra()
194 cls.pg6.config_ip6()
195 cls.pg6.resolve_ndp()
196 cls.pg6.disable_ipv6_ra()
197 except Exception:
198 super(MethodHolder, cls).tearDownClass()
199 raise
200
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800201 @classmethod
202 def tearDownClass(cls):
203 super(MethodHolder, cls).tearDownClass()
204
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200205 def create_stream(
206 self, src_if=None, dst_if=None, packets=None, size=None, ip_ver="v4"
207 ):
Ole Troan5c749732017-03-13 13:39:52 +0100208 """Create a packet stream to tickle the plugin
209
210 :param VppInterface src_if: Source interface for packet stream
211 :param VppInterface src_if: Dst interface for packet stream
212 """
213 if src_if is None:
214 src_if = self.pg1
215 if dst_if is None:
216 dst_if = self.pg2
217 self.pkts = []
218 if packets is None:
219 packets = random.randint(1, self.max_number_of_packets)
220 pkt_size = size
221 for p in range(0, packets):
222 if size is None:
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)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200227 if ip_ver == "v4":
Ole Troan5c749732017-03-13 13:39:52 +0100228 p /= IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
229 else:
230 p /= IPv6(src=src_if.remote_ip6, dst=dst_if.remote_ip6)
Ole Troaned929252017-06-13 21:15:40 +0200231 p /= UDP(sport=1234, dport=4321)
232 p /= Raw(payload)
Ole Troan5c749732017-03-13 13:39:52 +0100233 info.data = p.copy()
234 self.extend_packet(p, pkt_size)
235 self.pkts.append(p)
236
237 def verify_cflow_data(self, decoder, capture, cflow):
238 octets = 0
239 packets = 0
240 for p in capture:
241 octets += p[IP].len
242 packets += 1
243 if cflow.haslayer(Data):
244 data = decoder.decode_data_set(cflow.getlayer(Set))
245 for record in data:
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800246 self.assertEqual(int(binascii.hexlify(record[1]), 16), octets)
247 self.assertEqual(int(binascii.hexlify(record[2]), 16), packets)
Ole Troan5c749732017-03-13 13:39:52 +0100248
Pavel Kotucek89111d02017-06-12 08:26:13 +0200249 def send_packets(self, src_if=None, dst_if=None):
250 if src_if is None:
251 src_if = self.pg1
252 if dst_if is None:
253 dst_if = self.pg2
254 self.pg_enable_capture([dst_if])
255 src_if.add_stream(self.pkts)
256 self.pg_start()
257 return dst_if.get_capture(len(self.pkts))
258
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200259 def verify_cflow_data_detail(
260 self, decoder, capture, cflow, data_set={1: "octets", 2: "packets"}, ip_ver="v4"
261 ):
Ole Troan5c749732017-03-13 13:39:52 +0100262 if self.debug_print:
Paul Vinciguerra661f91f2018-11-28 19:06:41 -0800263 print(capture[0].show())
Ole Troan5c749732017-03-13 13:39:52 +0100264 if cflow.haslayer(Data):
265 data = decoder.decode_data_set(cflow.getlayer(Set))
266 if self.debug_print:
Paul Vinciguerra661f91f2018-11-28 19:06:41 -0800267 print(data)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200268 if ip_ver == "v4":
Ole Troan5c749732017-03-13 13:39:52 +0100269 ip_layer = capture[0][IP]
270 else:
271 ip_layer = capture[0][IPv6]
272 if data_set is not None:
273 for record in data:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700274 # skip flow if ingress/egress interface is 0
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800275 if int(binascii.hexlify(record[10]), 16) == 0:
Ole Troan5c749732017-03-13 13:39:52 +0100276 continue
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800277 if int(binascii.hexlify(record[14]), 16) == 0:
Ole Troan5c749732017-03-13 13:39:52 +0100278 continue
279
280 for field in data_set:
Ole Troan5c749732017-03-13 13:39:52 +0100281 value = data_set[field]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200282 if value == "octets":
Ole Troan5c749732017-03-13 13:39:52 +0100283 value = ip_layer.len
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200284 if ip_ver == "v6":
285 value += 40 # ??? is this correct
286 elif value == "packets":
Ole Troan5c749732017-03-13 13:39:52 +0100287 value = 1
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200288 elif value == "src_ip":
289 if ip_ver == "v4":
290 ip = socket.inet_pton(socket.AF_INET, ip_layer.src)
Ole Troan5c749732017-03-13 13:39:52 +0100291 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200292 ip = socket.inet_pton(socket.AF_INET6, ip_layer.src)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800293 value = int(binascii.hexlify(ip), 16)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200294 elif value == "dst_ip":
295 if ip_ver == "v4":
296 ip = socket.inet_pton(socket.AF_INET, ip_layer.dst)
Ole Troan5c749732017-03-13 13:39:52 +0100297 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200298 ip = socket.inet_pton(socket.AF_INET6, ip_layer.dst)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800299 value = int(binascii.hexlify(ip), 16)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200300 elif value == "sport":
Ole Troan5c749732017-03-13 13:39:52 +0100301 value = int(capture[0][UDP].sport)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200302 elif value == "dport":
Ole Troan5c749732017-03-13 13:39:52 +0100303 value = int(capture[0][UDP].dport)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200304 self.assertEqual(
305 int(binascii.hexlify(record[field]), 16), value
306 )
Ole Troan5c749732017-03-13 13:39:52 +0100307
308 def verify_cflow_data_notimer(self, decoder, capture, cflows):
309 idx = 0
310 for cflow in cflows:
311 if cflow.haslayer(Data):
312 data = decoder.decode_data_set(cflow.getlayer(Set))
313 else:
314 raise Exception("No CFLOW data")
315
316 for rec in data:
317 p = capture[idx]
318 idx += 1
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200319 self.assertEqual(p[IP].len, int(binascii.hexlify(rec[1]), 16))
320 self.assertEqual(1, int(binascii.hexlify(rec[2]), 16))
Ole Troan5c749732017-03-13 13:39:52 +0100321 self.assertEqual(len(capture), idx)
322
Klement Sekerac4794572021-09-08 15:15:59 +0200323 def wait_for_cflow_packet(self, collector_intf, set_id=2, timeout=1):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200324 """wait for CFLOW packet and verify its correctness
Ole Troan5c749732017-03-13 13:39:52 +0100325
326 :param timeout: how long to wait
327
Ole Troan5c749732017-03-13 13:39:52 +0100328 """
329 self.logger.info("IPFIX: Waiting for CFLOW packet")
Ole Troan5c749732017-03-13 13:39:52 +0100330 # self.logger.debug(self.vapi.ppcli("show flow table"))
Klement Sekerac4794572021-09-08 15:15:59 +0200331 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))
Ole Troan5c749732017-03-13 13:39:52 +0100335 return p
336
Ole Troan5c749732017-03-13 13:39:52 +0100337
Andrew Yourtchenko06f32812021-01-14 10:19:08 +0000338@tag_run_solo
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +0000339@tag_fixme_vpp_workers
Ole Troaned929252017-06-13 21:15:40 +0200340class Flowprobe(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +0100341 """Template verification, timer tests"""
342
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800343 @classmethod
344 def setUpClass(cls):
345 super(Flowprobe, cls).setUpClass()
346
347 @classmethod
348 def tearDownClass(cls):
349 super(Flowprobe, cls).tearDownClass()
350
Ole Troan5c749732017-03-13 13:39:52 +0100351 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200352 """timer less than template timeout"""
Ole Troaned929252017-06-13 21:15:40 +0200353 self.logger.info("FFP_TEST_START_0001")
Ole Troan5c749732017-03-13 13:39:52 +0100354 self.pg_enable_capture(self.pg_interfaces)
355 self.pkts = []
356
Pavel Kotucek89111d02017-06-12 08:26:13 +0200357 ipfix = VppCFLOW(test=self, active=2)
Ole Troan5c749732017-03-13 13:39:52 +0100358 ipfix.add_vpp_config()
359
360 ipfix_decoder = IPFIXDecoder()
361 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200362 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +0100363
Ole Troaned929252017-06-13 21:15:40 +0200364 self.create_stream(packets=1)
Pavel Kotucek89111d02017-06-12 08:26:13 +0200365 self.send_packets()
Ole Troaned929252017-06-13 21:15:40 +0200366 capture = self.pg2.get_capture(1)
Ole Troan5c749732017-03-13 13:39:52 +0100367
368 # make sure the one packet we expect actually showed up
Pavel Kotucek89111d02017-06-12 08:26:13 +0200369 cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
Ole Troan5c749732017-03-13 13:39:52 +0100370 self.verify_cflow_data(ipfix_decoder, capture, cflow)
371
372 ipfix.remove_vpp_config()
Ole Troaned929252017-06-13 21:15:40 +0200373 self.logger.info("FFP_TEST_FINISH_0001")
Ole Troan5c749732017-03-13 13:39:52 +0100374
Pavel Kotucek89111d02017-06-12 08:26:13 +0200375 def test_0002(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200376 """timer greater than template timeout"""
Ole Troaned929252017-06-13 21:15:40 +0200377 self.logger.info("FFP_TEST_START_0002")
Ole Troan5c749732017-03-13 13:39:52 +0100378 self.pg_enable_capture(self.pg_interfaces)
379 self.pkts = []
380
Pavel Kotucek89111d02017-06-12 08:26:13 +0200381 ipfix = VppCFLOW(test=self, timeout=3, active=4)
Ole Troan5c749732017-03-13 13:39:52 +0100382 ipfix.add_vpp_config()
383
384 ipfix_decoder = IPFIXDecoder()
385 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200386 ipfix.verify_templates()
Ole Troan5c749732017-03-13 13:39:52 +0100387
Pavel Kotucek89111d02017-06-12 08:26:13 +0200388 self.create_stream(packets=2)
389 self.send_packets()
390 capture = self.pg2.get_capture(2)
Ole Troan5c749732017-03-13 13:39:52 +0100391
392 # next set of template packet should arrive after 20 seconds
393 # template packet should arrive within 20 s
Pavel Kotucek89111d02017-06-12 08:26:13 +0200394 templates = ipfix.verify_templates(ipfix_decoder, timeout=5)
Ole Troan5c749732017-03-13 13:39:52 +0100395
396 # make sure the one packet we expect actually showed up
Pavel Kotucek89111d02017-06-12 08:26:13 +0200397 cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
Ole Troan5c749732017-03-13 13:39:52 +0100398 self.verify_cflow_data(ipfix_decoder, capture, cflow)
399
400 ipfix.remove_vpp_config()
Ole Troaned929252017-06-13 21:15:40 +0200401 self.logger.info("FFP_TEST_FINISH_0002")
402
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)
407 self.pkts = []
408
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200409 ipfix = VppCFLOW(
410 test=self, intf="pg8", datapath="ip4", layer="l2 l3 l4", active=2
411 )
Ole Troaned929252017-06-13 21:15:40 +0200412 ipfix.add_vpp_config()
413
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200414 route_9001 = VppIpRoute(
415 self,
416 "9.0.0.0",
417 24,
418 [VppRoutePath(self.pg8._remote_hosts[0].ip4, self.pg8.sw_if_index)],
419 )
Ole Troaned929252017-06-13 21:15:40 +0200420 route_9001.add_vpp_config()
421
422 ipfix_decoder = IPFIXDecoder()
423 templates = ipfix.verify_templates(ipfix_decoder, count=1)
424
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200425 self.pkts = [
426 (
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)
430 / Raw(b"\xa5" * 100)
431 )
432 ]
Ole Troaned929252017-06-13 21:15:40 +0200433
434 nowUTC = int(time.time())
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200435 nowUNIX = nowUTC + 2208988800
Ole Troaned929252017-06-13 21:15:40 +0200436 self.send_packets(src_if=self.pg7, dst_if=self.pg8)
437
438 cflow = self.wait_for_cflow_packet(self.collector, templates[0], 10)
439 self.collector.get_capture(2)
440
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]
448 # ingress interface
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800449 self.assertEqual(int(binascii.hexlify(record[10]), 16), 8)
Ole Troaned929252017-06-13 21:15:40 +0200450 # egress interface
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800451 self.assertEqual(int(binascii.hexlify(record[14]), 16), 9)
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000452 # direction
453 self.assertEqual(int(binascii.hexlify(record[61]), 16), 1)
Ole Troaned929252017-06-13 21:15:40 +0200454 # packets
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800455 self.assertEqual(int(binascii.hexlify(record[2]), 16), 1)
Ole Troaned929252017-06-13 21:15:40 +0200456 # src mac
Ole Troanb0d83f12019-10-21 23:13:46 +0200457 self.assertEqual(mac_ntop(record[56]), self.pg8.local_mac)
Ole Troaned929252017-06-13 21:15:40 +0200458 # dst mac
Ole Troanb0d83f12019-10-21 23:13:46 +0200459 self.assertEqual(mac_ntop(record[80]), self.pg8.remote_mac)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800460 flowTimestamp = int(binascii.hexlify(record[156]), 16) >> 32
Ole Troaned929252017-06-13 21:15:40 +0200461 # flow start timestamp
462 self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800463 flowTimestamp = int(binascii.hexlify(record[157]), 16) >> 32
Ole Troaned929252017-06-13 21:15:40 +0200464 # flow end timestamp
465 self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
466 # ethernet type
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800467 self.assertEqual(int(binascii.hexlify(record[256]), 16), 8)
Ole Troaned929252017-06-13 21:15:40 +0200468 # src ip
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200469 self.assertEqual(inet_ntop(socket.AF_INET, record[8]), self.pg7.remote_ip4)
Ole Troaned929252017-06-13 21:15:40 +0200470 # dst ip
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200471 self.assertEqual(inet_ntop(socket.AF_INET, record[12]), "9.0.0.100")
Ole Troaned929252017-06-13 21:15:40 +0200472 # protocol (TCP)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800473 self.assertEqual(int(binascii.hexlify(record[4]), 16), 6)
Ole Troaned929252017-06-13 21:15:40 +0200474 # src port
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800475 self.assertEqual(int(binascii.hexlify(record[7]), 16), 1234)
Ole Troaned929252017-06-13 21:15:40 +0200476 # dst port
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800477 self.assertEqual(int(binascii.hexlify(record[11]), 16), 4321)
Ole Troaned929252017-06-13 21:15:40 +0200478 # tcp flags
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800479 self.assertEqual(int(binascii.hexlify(record[6]), 16), 80)
Ole Troaned929252017-06-13 21:15:40 +0200480
481 ipfix.remove_vpp_config()
482 self.logger.info("FFP_TEST_FINISH_0000")
Ole Troan5c749732017-03-13 13:39:52 +0100483
Alexander Chernavin86c78562022-05-12 14:56:24 +0000484 def test_interface_dump(self):
485 """Dump interfaces with IPFIX flow record generation enabled"""
486 self.logger.info("FFP_TEST_START_0003")
487
488 # Enable feature for 3 interfaces
489 ipfix1 = VppCFLOW(test=self, intf="pg1", datapath="l2", direction="rx")
490 ipfix1.add_vpp_config()
491
492 ipfix2 = VppCFLOW(test=self, intf="pg2", datapath="ip4", direction="tx")
493 ipfix2.enable_flowprobe_feature()
494
495 ipfix3 = VppCFLOW(test=self, intf="pg3", datapath="ip6", direction="both")
496 ipfix3.enable_flowprobe_feature()
497
498 # When request "all", dump should contain all enabled interfaces
499 dump = self.vapi.flowprobe_interface_dump()
500 self.assertEqual(len(dump), 3)
501
502 # Verify 1st interface
503 self.assertEqual(dump[0].sw_if_index, self.pg1.sw_if_index)
504 self.assertEqual(
505 dump[0].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_L2
506 )
507 self.assertEqual(
508 dump[0].direction,
509 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_RX,
510 )
511
512 # Verify 2nd interface
513 self.assertEqual(dump[1].sw_if_index, self.pg2.sw_if_index)
514 self.assertEqual(
515 dump[1].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4
516 )
517 self.assertEqual(
518 dump[1].direction,
519 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
520 )
521
522 # Verify 3rd interface
523 self.assertEqual(dump[2].sw_if_index, self.pg3.sw_if_index)
524 self.assertEqual(
525 dump[2].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP6
526 )
527 self.assertEqual(
528 dump[2].direction,
529 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_BOTH,
530 )
531
532 # When request 2nd interface, dump should contain only the specified interface
533 dump = self.vapi.flowprobe_interface_dump(sw_if_index=self.pg2.sw_if_index)
534 self.assertEqual(len(dump), 1)
535
536 # Verify 2nd interface
537 self.assertEqual(dump[0].sw_if_index, self.pg2.sw_if_index)
538 self.assertEqual(
539 dump[0].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4
540 )
541 self.assertEqual(
542 dump[0].direction,
543 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
544 )
545
546 # When request 99th interface, dump should be empty
547 dump = self.vapi.flowprobe_interface_dump(sw_if_index=99)
548 self.assertEqual(len(dump), 0)
549
550 ipfix1.remove_vpp_config()
551 ipfix2.remove_vpp_config()
552 ipfix3.remove_vpp_config()
553 self.logger.info("FFP_TEST_FINISH_0003")
554
555 def test_get_params(self):
556 """Get IPFIX flow record generation parameters"""
557 self.logger.info("FFP_TEST_START_0004")
558
559 # Enable feature for an interface with custom parameters
560 ipfix = VppCFLOW(test=self, active=20, passive=40, layer="l2 l3 l4")
561 ipfix.add_vpp_config()
562
563 # Get and verify parameters
564 params = self.vapi.flowprobe_get_params()
565 self.assertEqual(params.active_timer, 20)
566 self.assertEqual(params.passive_timer, 40)
567 record_flags = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L2
568 record_flags |= VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L3
569 record_flags |= VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L4
570 self.assertEqual(params.record_flags, record_flags)
571
572 ipfix.remove_vpp_config()
573 self.logger.info("FFP_TEST_FINISH_0004")
574
Ole Troan5c749732017-03-13 13:39:52 +0100575
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000576class DatapathTestsHolder(object):
Pavel Kotucek89111d02017-06-12 08:26:13 +0200577 """collect information on Ethernet, IP4 and IP6 datapath (no timers)"""
Ole Troan5c749732017-03-13 13:39:52 +0100578
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800579 @classmethod
580 def setUpClass(cls):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000581 super(DatapathTestsHolder, cls).setUpClass()
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800582
583 @classmethod
584 def tearDownClass(cls):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000585 super(DatapathTestsHolder, cls).tearDownClass()
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800586
Pavel Kotucek89111d02017-06-12 08:26:13 +0200587 def test_templatesL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200588 """verify template on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100589 self.logger.info("FFP_TEST_START_0000")
590 self.pg_enable_capture(self.pg_interfaces)
591
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000592 ipfix = VppCFLOW(
593 test=self, intf=self.intf1, layer="l2", direction=self.direction
594 )
Ole Troan5c749732017-03-13 13:39:52 +0100595 ipfix.add_vpp_config()
596
597 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400598 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200599 ipfix.verify_templates(timeout=3, count=1)
600 self.collector.get_capture(1)
Ole Troan5c749732017-03-13 13:39:52 +0100601
602 ipfix.remove_vpp_config()
603 self.logger.info("FFP_TEST_FINISH_0000")
604
Pavel Kotucek89111d02017-06-12 08:26:13 +0200605 def test_L2onL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200606 """L2 data on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100607 self.logger.info("FFP_TEST_START_0001")
608 self.pg_enable_capture(self.pg_interfaces)
609 self.pkts = []
610
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000611 ipfix = VppCFLOW(
612 test=self, intf=self.intf1, layer="l2", direction=self.direction
613 )
Ole Troan5c749732017-03-13 13:39:52 +0100614 ipfix.add_vpp_config()
615
616 ipfix_decoder = IPFIXDecoder()
617 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200618 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100619
620 self.create_stream(packets=1)
621 capture = self.send_packets()
622
623 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400624 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200625 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200626 self.verify_cflow_data_detail(
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000627 ipfix_decoder,
628 capture,
629 cflow,
630 {2: "packets", 256: 8, 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200631 )
Ole Troan5c749732017-03-13 13:39:52 +0100632 self.collector.get_capture(2)
633
634 ipfix.remove_vpp_config()
635 self.logger.info("FFP_TEST_FINISH_0001")
636
Pavel Kotucek89111d02017-06-12 08:26:13 +0200637 def test_L3onL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200638 """L3 data on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100639 self.logger.info("FFP_TEST_START_0002")
640 self.pg_enable_capture(self.pg_interfaces)
641 self.pkts = []
642
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000643 ipfix = VppCFLOW(
644 test=self, intf=self.intf1, layer="l3", direction=self.direction
645 )
Ole Troan5c749732017-03-13 13:39:52 +0100646 ipfix.add_vpp_config()
647
648 ipfix_decoder = IPFIXDecoder()
649 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200650 templates = ipfix.verify_templates(ipfix_decoder, count=2)
Ole Troan5c749732017-03-13 13:39:52 +0100651
652 self.create_stream(packets=1)
653 capture = self.send_packets()
654
655 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400656 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200657 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200658 self.verify_cflow_data_detail(
659 ipfix_decoder,
660 capture,
661 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000662 {
663 2: "packets",
664 4: 17,
665 8: "src_ip",
666 12: "dst_ip",
667 61: (self.direction == "tx"),
668 },
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200669 )
Ole Troan5c749732017-03-13 13:39:52 +0100670
Ole Troan5c749732017-03-13 13:39:52 +0100671 self.collector.get_capture(3)
672
673 ipfix.remove_vpp_config()
674 self.logger.info("FFP_TEST_FINISH_0002")
675
Pavel Kotucek89111d02017-06-12 08:26:13 +0200676 def test_L4onL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200677 """L4 data on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100678 self.logger.info("FFP_TEST_START_0003")
679 self.pg_enable_capture(self.pg_interfaces)
680 self.pkts = []
681
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000682 ipfix = VppCFLOW(
683 test=self, intf=self.intf1, layer="l4", direction=self.direction
684 )
Ole Troan5c749732017-03-13 13:39:52 +0100685 ipfix.add_vpp_config()
686
687 ipfix_decoder = IPFIXDecoder()
688 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200689 templates = ipfix.verify_templates(ipfix_decoder, count=2)
Ole Troan5c749732017-03-13 13:39:52 +0100690
691 self.create_stream(packets=1)
692 capture = self.send_packets()
693
694 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400695 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200696 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200697 self.verify_cflow_data_detail(
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000698 ipfix_decoder,
699 capture,
700 cflow,
701 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200702 )
Ole Troan5c749732017-03-13 13:39:52 +0100703
Ole Troan5c749732017-03-13 13:39:52 +0100704 self.collector.get_capture(3)
705
706 ipfix.remove_vpp_config()
707 self.logger.info("FFP_TEST_FINISH_0003")
708
Pavel Kotucek89111d02017-06-12 08:26:13 +0200709 def test_templatesIp4(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200710 """verify templates on IP4 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100711 self.logger.info("FFP_TEST_START_0000")
712
713 self.pg_enable_capture(self.pg_interfaces)
714
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000715 ipfix = VppCFLOW(
716 test=self, intf=self.intf1, datapath="ip4", direction=self.direction
717 )
Ole Troan5c749732017-03-13 13:39:52 +0100718 ipfix.add_vpp_config()
719
720 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400721 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +0100722 ipfix.verify_templates(timeout=3, count=1)
723 self.collector.get_capture(1)
724
725 ipfix.remove_vpp_config()
726
727 self.logger.info("FFP_TEST_FINISH_0000")
728
Pavel Kotucek89111d02017-06-12 08:26:13 +0200729 def test_L2onIP4(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200730 """L2 data on IP4 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100731 self.logger.info("FFP_TEST_START_0001")
732 self.pg_enable_capture(self.pg_interfaces)
733 self.pkts = []
734
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000735 ipfix = VppCFLOW(
736 test=self,
737 intf=self.intf2,
738 layer="l2",
739 datapath="ip4",
740 direction=self.direction,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200741 )
Ole Troan5c749732017-03-13 13:39:52 +0100742 ipfix.add_vpp_config()
743
744 ipfix_decoder = IPFIXDecoder()
745 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200746 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100747
748 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
749 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
750
751 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400752 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200753 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200754 self.verify_cflow_data_detail(
755 ipfix_decoder,
756 capture,
757 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000758 {2: "packets", 256: 8, 61: (self.direction == "tx")},
759 )
760
761 # expected two templates and one cflow packet
762 self.collector.get_capture(2)
763
764 ipfix.remove_vpp_config()
765 self.logger.info("FFP_TEST_FINISH_0001")
766
767 def test_L3onIP4(self):
768 """L3 data on IP4 datapath"""
769 self.logger.info("FFP_TEST_START_0002")
770 self.pg_enable_capture(self.pg_interfaces)
771 self.pkts = []
772
773 ipfix = VppCFLOW(
774 test=self,
775 intf=self.intf2,
776 layer="l3",
777 datapath="ip4",
778 direction=self.direction,
779 )
780 ipfix.add_vpp_config()
781
782 ipfix_decoder = IPFIXDecoder()
783 # template packet should arrive immediately
784 templates = ipfix.verify_templates(ipfix_decoder, count=1)
785
786 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
787 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
788
789 # make sure the one packet we expect actually showed up
790 self.vapi.ipfix_flush()
791 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
792 self.verify_cflow_data_detail(
793 ipfix_decoder,
794 capture,
795 cflow,
796 {
797 1: "octets",
798 2: "packets",
799 8: "src_ip",
800 12: "dst_ip",
801 61: (self.direction == "tx"),
802 },
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200803 )
Ole Troan5c749732017-03-13 13:39:52 +0100804
805 # expected two templates and one cflow packet
806 self.collector.get_capture(2)
807
808 ipfix.remove_vpp_config()
809 self.logger.info("FFP_TEST_FINISH_0002")
810
Pavel Kotucek89111d02017-06-12 08:26:13 +0200811 def test_L4onIP4(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200812 """L4 data on IP4 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100813 self.logger.info("FFP_TEST_START_0003")
814 self.pg_enable_capture(self.pg_interfaces)
815 self.pkts = []
816
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000817 ipfix = VppCFLOW(
818 test=self,
819 intf=self.intf2,
820 layer="l4",
821 datapath="ip4",
822 direction=self.direction,
823 )
Ole Troan5c749732017-03-13 13:39:52 +0100824 ipfix.add_vpp_config()
825
826 ipfix_decoder = IPFIXDecoder()
827 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200828 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100829
830 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
831 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
832
833 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400834 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200835 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200836 self.verify_cflow_data_detail(
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000837 ipfix_decoder,
838 capture,
839 cflow,
840 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200841 )
Ole Troan5c749732017-03-13 13:39:52 +0100842
843 # expected two templates and one cflow packet
844 self.collector.get_capture(2)
845
846 ipfix.remove_vpp_config()
847 self.logger.info("FFP_TEST_FINISH_0003")
848
Pavel Kotucek89111d02017-06-12 08:26:13 +0200849 def test_templatesIP6(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200850 """verify templates on IP6 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100851 self.logger.info("FFP_TEST_START_0000")
852 self.pg_enable_capture(self.pg_interfaces)
853
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000854 ipfix = VppCFLOW(
855 test=self, intf=self.intf1, datapath="ip6", direction=self.direction
856 )
Ole Troan5c749732017-03-13 13:39:52 +0100857 ipfix.add_vpp_config()
858
859 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200860 ipfix.verify_templates(count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100861 self.collector.get_capture(1)
862
863 ipfix.remove_vpp_config()
864
865 self.logger.info("FFP_TEST_FINISH_0000")
866
Pavel Kotucek89111d02017-06-12 08:26:13 +0200867 def test_L2onIP6(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200868 """L2 data on IP6 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100869 self.logger.info("FFP_TEST_START_0001")
870 self.pg_enable_capture(self.pg_interfaces)
871 self.pkts = []
872
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000873 ipfix = VppCFLOW(
874 test=self,
875 intf=self.intf3,
876 layer="l2",
877 datapath="ip6",
878 direction=self.direction,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200879 )
Ole Troan5c749732017-03-13 13:39:52 +0100880 ipfix.add_vpp_config()
881
882 ipfix_decoder = IPFIXDecoder()
883 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200884 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100885
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200886 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
Ole Troan5c749732017-03-13 13:39:52 +0100887 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
888
889 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400890 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200891 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200892 self.verify_cflow_data_detail(
893 ipfix_decoder,
894 capture,
895 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000896 {2: "packets", 256: 56710, 61: (self.direction == "tx")},
897 ip_ver="v6",
898 )
899
900 # expected two templates and one cflow packet
901 self.collector.get_capture(2)
902
903 ipfix.remove_vpp_config()
904 self.logger.info("FFP_TEST_FINISH_0001")
905
906 def test_L3onIP6(self):
907 """L3 data on IP6 datapath"""
908 self.logger.info("FFP_TEST_START_0002")
909 self.pg_enable_capture(self.pg_interfaces)
910 self.pkts = []
911
912 ipfix = VppCFLOW(
913 test=self,
914 intf=self.intf3,
915 layer="l3",
916 datapath="ip6",
917 direction=self.direction,
918 )
919 ipfix.add_vpp_config()
920
921 ipfix_decoder = IPFIXDecoder()
922 # template packet should arrive immediately
923 templates = ipfix.verify_templates(ipfix_decoder, count=1)
924
925 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
926 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
927
928 # make sure the one packet we expect actually showed up
929 self.vapi.ipfix_flush()
930 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
931 self.verify_cflow_data_detail(
932 ipfix_decoder,
933 capture,
934 cflow,
935 {2: "packets", 27: "src_ip", 28: "dst_ip", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200936 ip_ver="v6",
937 )
Ole Troan5c749732017-03-13 13:39:52 +0100938
939 # expected two templates and one cflow packet
940 self.collector.get_capture(2)
941
942 ipfix.remove_vpp_config()
943 self.logger.info("FFP_TEST_FINISH_0002")
944
Pavel Kotucek89111d02017-06-12 08:26:13 +0200945 def test_L4onIP6(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200946 """L4 data on IP6 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100947 self.logger.info("FFP_TEST_START_0003")
948 self.pg_enable_capture(self.pg_interfaces)
949 self.pkts = []
950
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000951 ipfix = VppCFLOW(
952 test=self,
953 intf=self.intf3,
954 layer="l4",
955 datapath="ip6",
956 direction=self.direction,
957 )
Ole Troan5c749732017-03-13 13:39:52 +0100958 ipfix.add_vpp_config()
959
960 ipfix_decoder = IPFIXDecoder()
961 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200962 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100963
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200964 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
Ole Troan5c749732017-03-13 13:39:52 +0100965 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
966
967 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400968 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200969 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200970 self.verify_cflow_data_detail(
971 ipfix_decoder,
972 capture,
973 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000974 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200975 ip_ver="v6",
976 )
Ole Troan5c749732017-03-13 13:39:52 +0100977
978 # expected two templates and one cflow packet
979 self.collector.get_capture(2)
980
981 ipfix.remove_vpp_config()
982 self.logger.info("FFP_TEST_FINISH_0003")
983
Ole Troan5c749732017-03-13 13:39:52 +0100984 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200985 """no timers, one CFLOW packet, 9 Flows inside"""
Ole Troan5c749732017-03-13 13:39:52 +0100986 self.logger.info("FFP_TEST_START_0001")
987 self.pg_enable_capture(self.pg_interfaces)
988 self.pkts = []
989
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000990 ipfix = VppCFLOW(test=self, intf=self.intf1, direction=self.direction)
Ole Troan5c749732017-03-13 13:39:52 +0100991 ipfix.add_vpp_config()
992
993 ipfix_decoder = IPFIXDecoder()
994 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200995 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +0100996
997 self.create_stream(packets=9)
998 capture = self.send_packets()
999
1000 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001001 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001002 cflow = self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001003 self.verify_cflow_data_notimer(ipfix_decoder, capture, [cflow])
Ole Troan5c749732017-03-13 13:39:52 +01001004 self.collector.get_capture(4)
1005
1006 ipfix.remove_vpp_config()
1007 self.logger.info("FFP_TEST_FINISH_0001")
1008
1009 def test_0002(self):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001010 """no timers, two CFLOW packets (mtu=260), 3 Flows in each"""
Ole Troan5c749732017-03-13 13:39:52 +01001011 self.logger.info("FFP_TEST_START_0002")
1012 self.pg_enable_capture(self.pg_interfaces)
1013 self.pkts = []
1014
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001015 ipfix = VppCFLOW(test=self, intf=self.intf1, direction=self.direction, mtu=260)
Ole Troan5c749732017-03-13 13:39:52 +01001016 ipfix.add_vpp_config()
1017
1018 ipfix_decoder = IPFIXDecoder()
1019 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001020 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001021 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001022
1023 self.create_stream(packets=6)
1024 capture = self.send_packets()
1025
1026 # make sure the one packet we expect actually showed up
1027 cflows = []
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001028 self.vapi.ipfix_flush()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001029 cflows.append(self.wait_for_cflow_packet(self.collector, templates[1]))
1030 cflows.append(self.wait_for_cflow_packet(self.collector, templates[1]))
Ole Troan5c749732017-03-13 13:39:52 +01001031 self.verify_cflow_data_notimer(ipfix_decoder, capture, cflows)
1032 self.collector.get_capture(5)
1033
1034 ipfix.remove_vpp_config()
1035 self.logger.info("FFP_TEST_FINISH_0002")
1036
1037
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001038@tag_fixme_vpp_workers
1039class DatapathTx(MethodHolder, DatapathTestsHolder):
1040 """Collect info on Ethernet, IP4 and IP6 datapath (TX) (no timers)"""
1041
1042 intf1 = "pg2"
1043 intf2 = "pg4"
1044 intf3 = "pg6"
1045 direction = "tx"
1046
1047
1048@tag_fixme_vpp_workers
1049class DatapathRx(MethodHolder, DatapathTestsHolder):
1050 """Collect info on Ethernet, IP4 and IP6 datapath (RX) (no timers)"""
1051
1052 intf1 = "pg1"
1053 intf2 = "pg3"
1054 intf3 = "pg5"
1055 direction = "rx"
1056
1057
Klement Sekerab23ffd72021-05-31 16:08:53 +02001058@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001059class DisableIPFIX(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001060 """Disable IPFIX"""
1061
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001062 @classmethod
1063 def setUpClass(cls):
1064 super(DisableIPFIX, cls).setUpClass()
1065
1066 @classmethod
1067 def tearDownClass(cls):
1068 super(DisableIPFIX, cls).tearDownClass()
1069
Ole Troan5c749732017-03-13 13:39:52 +01001070 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001071 """disable IPFIX after first packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001072 self.logger.info("FFP_TEST_START_0001")
1073 self.pg_enable_capture(self.pg_interfaces)
1074 self.pkts = []
1075
Pavel Kotucek89111d02017-06-12 08:26:13 +02001076 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001077 ipfix.add_vpp_config()
1078
1079 ipfix_decoder = IPFIXDecoder()
1080 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001081 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001082
1083 self.create_stream()
1084 self.send_packets()
1085
1086 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001087 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001088 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001089 self.collector.get_capture(4)
1090
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001091 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +01001092 ipfix.disable_exporter()
1093 self.pg_enable_capture([self.collector])
1094
1095 self.send_packets()
1096
1097 # make sure no one packet arrived in 1 minute
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001098 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001099 self.sleep(1, "wait before verifying no packets sent")
1100 self.collector.assert_nothing_captured()
Ole Troan5c749732017-03-13 13:39:52 +01001101
1102 ipfix.remove_vpp_config()
1103 self.logger.info("FFP_TEST_FINISH_0001")
1104
1105
Klement Sekerab23ffd72021-05-31 16:08:53 +02001106@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001107class ReenableIPFIX(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001108 """Re-enable IPFIX"""
1109
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001110 @classmethod
1111 def setUpClass(cls):
1112 super(ReenableIPFIX, cls).setUpClass()
1113
1114 @classmethod
1115 def tearDownClass(cls):
1116 super(ReenableIPFIX, cls).tearDownClass()
1117
Pavel Kotucek89111d02017-06-12 08:26:13 +02001118 def test_0011(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001119 """disable IPFIX after first packets and re-enable after few packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001120 self.logger.info("FFP_TEST_START_0001")
1121 self.pg_enable_capture(self.pg_interfaces)
1122 self.pkts = []
1123
Pavel Kotucek89111d02017-06-12 08:26:13 +02001124 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001125 ipfix.add_vpp_config()
1126
1127 ipfix_decoder = IPFIXDecoder()
1128 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001129 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001130
Pavel Kotucek89111d02017-06-12 08:26:13 +02001131 self.create_stream(packets=5)
Ole Troan5c749732017-03-13 13:39:52 +01001132 self.send_packets()
1133
1134 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001135 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001136 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001137 self.collector.get_capture(4)
1138
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001139 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +01001140 ipfix.disable_exporter()
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001141 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +01001142 self.pg_enable_capture([self.collector])
1143
1144 self.send_packets()
1145
1146 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001147 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001148 self.sleep(1, "wait before verifying no packets sent")
1149 self.collector.assert_nothing_captured()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001150 self.pg2.get_capture(5)
Ole Troan5c749732017-03-13 13:39:52 +01001151
1152 # enable IPFIX
1153 ipfix.enable_exporter()
Ole Troan5c749732017-03-13 13:39:52 +01001154
Pavel Kotucek89111d02017-06-12 08:26:13 +02001155 capture = self.collector.get_capture(4)
1156 nr_templates = 0
1157 nr_data = 0
1158 for p in capture:
1159 self.assertTrue(p.haslayer(IPFIX))
1160 if p.haslayer(Template):
1161 nr_templates += 1
1162 self.assertTrue(nr_templates, 3)
1163 for p in capture:
1164 self.assertTrue(p.haslayer(IPFIX))
1165 if p.haslayer(Data):
1166 nr_data += 1
1167 self.assertTrue(nr_templates, 1)
Ole Troan5c749732017-03-13 13:39:52 +01001168
1169 ipfix.remove_vpp_config()
1170 self.logger.info("FFP_TEST_FINISH_0001")
1171
1172
Klement Sekerab23ffd72021-05-31 16:08:53 +02001173@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001174class DisableFP(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001175 """Disable Flowprobe feature"""
1176
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001177 @classmethod
1178 def setUpClass(cls):
1179 super(DisableFP, cls).setUpClass()
1180
1181 @classmethod
1182 def tearDownClass(cls):
1183 super(DisableFP, cls).tearDownClass()
1184
Ole Troan5c749732017-03-13 13:39:52 +01001185 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001186 """disable flowprobe feature after first packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001187 self.logger.info("FFP_TEST_START_0001")
1188 self.pg_enable_capture(self.pg_interfaces)
1189 self.pkts = []
Pavel Kotucek89111d02017-06-12 08:26:13 +02001190 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001191 ipfix.add_vpp_config()
1192
1193 ipfix_decoder = IPFIXDecoder()
1194 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001195 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001196
1197 self.create_stream()
1198 self.send_packets()
1199
1200 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001201 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001202 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001203 self.collector.get_capture(4)
1204
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001205 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +01001206 ipfix.disable_flowprobe_feature()
1207 self.pg_enable_capture([self.collector])
1208
1209 self.send_packets()
1210
1211 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001212 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001213 self.sleep(1, "wait before verifying no packets sent")
1214 self.collector.assert_nothing_captured()
Ole Troan5c749732017-03-13 13:39:52 +01001215
1216 ipfix.remove_vpp_config()
1217 self.logger.info("FFP_TEST_FINISH_0001")
1218
1219
Klement Sekerab23ffd72021-05-31 16:08:53 +02001220@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001221class ReenableFP(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001222 """Re-enable Flowprobe feature"""
1223
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001224 @classmethod
1225 def setUpClass(cls):
1226 super(ReenableFP, cls).setUpClass()
1227
1228 @classmethod
1229 def tearDownClass(cls):
1230 super(ReenableFP, cls).tearDownClass()
1231
Ole Troan5c749732017-03-13 13:39:52 +01001232 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001233 """disable flowprobe feature after first packets and re-enable
1234 after few packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001235 self.logger.info("FFP_TEST_START_0001")
1236 self.pg_enable_capture(self.pg_interfaces)
1237 self.pkts = []
1238
Pavel Kotucek89111d02017-06-12 08:26:13 +02001239 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001240 ipfix.add_vpp_config()
1241
1242 ipfix_decoder = IPFIXDecoder()
1243 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001244 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +01001245 templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
1246
1247 self.create_stream()
1248 self.send_packets()
1249
1250 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001251 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001252 self.wait_for_cflow_packet(self.collector, templates[1], 5)
Ole Troan5c749732017-03-13 13:39:52 +01001253 self.collector.get_capture(4)
1254
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001255 # disable FPP feature
Ole Troan5c749732017-03-13 13:39:52 +01001256 ipfix.disable_flowprobe_feature()
1257 self.pg_enable_capture([self.collector])
1258
1259 self.send_packets()
1260
1261 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001262 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001263 self.sleep(5, "wait before verifying no packets sent")
1264 self.collector.assert_nothing_captured()
Ole Troan5c749732017-03-13 13:39:52 +01001265
1266 # enable FPP feature
1267 ipfix.enable_flowprobe_feature()
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001268 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +01001269 templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
1270
1271 self.send_packets()
1272
1273 # make sure the next packets (templates and data) we expect actually
1274 # showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001275 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001276 self.wait_for_cflow_packet(self.collector, templates[1], 5)
Ole Troan5c749732017-03-13 13:39:52 +01001277 self.collector.get_capture(4)
1278
1279 ipfix.remove_vpp_config()
1280 self.logger.info("FFP_TEST_FINISH_0001")
1281
1282
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001283if __name__ == "__main__":
Ole Troan5c749732017-03-13 13:39:52 +01001284 unittest.main(testRunner=VppTestRunner)