blob: e3ff2245ad1c5d9cde8bab8284192b7df6f76995 [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
Dave Wallace670724c2022-09-20 21:52:18 -040016from framework import tag_fixme_vpp_workers, tag_fixme_ubuntu2204, tag_fixme_debian11
17from framework import is_distro_ubuntu2204, is_distro_debian11
Klement Sekerab23ffd72021-05-31 16:08:53 +020018from framework import VppTestCase, VppTestRunner
Andrew Yourtchenko06f32812021-01-14 10:19:08 +000019from framework import tag_run_solo
Ole Troan5c749732017-03-13 13:39:52 +010020from vpp_object import VppObject
21from vpp_pg_interface import CaptureTimeoutError
22from util import ppp
23from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
Ole Troaned929252017-06-13 21:15:40 +020024from vpp_ip_route import VppIpRoute, VppRoutePath
Ole Troanb0d83f12019-10-21 23:13:46 +020025from vpp_papi.macaddress import mac_ntop
26from socket import inet_ntop
Ole Troan3013e692019-12-09 15:51:44 +010027from vpp_papi import VppEnum
Ole Troan5c749732017-03-13 13:39:52 +010028
29
30class VppCFLOW(VppObject):
31 """CFLOW object for IPFIX exporter and Flowprobe feature"""
32
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020033 def __init__(
34 self,
35 test,
36 intf="pg2",
37 active=0,
38 passive=0,
39 timeout=100,
40 mtu=1024,
41 datapath="l2",
42 layer="l2 l3 l4",
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +000043 direction="tx",
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020044 ):
Ole Troan5c749732017-03-13 13:39:52 +010045 self._test = test
46 self._intf = intf
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +000047 self._intf_obj = getattr(self._test, intf)
Ole Troan5c749732017-03-13 13:39:52 +010048 self._active = active
49 if passive == 0 or passive < active:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020050 self._passive = active + 1
Ole Troan5c749732017-03-13 13:39:52 +010051 else:
52 self._passive = passive
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020053 self._datapath = datapath # l2 ip4 ip6
54 self._collect = layer # l2 l3 l4
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +000055 self._direction = direction # rx tx both
Ole Troan5c749732017-03-13 13:39:52 +010056 self._timeout = timeout
57 self._mtu = mtu
58 self._configured = False
59
60 def add_vpp_config(self):
61 self.enable_exporter()
Ole Troan3013e692019-12-09 15:51:44 +010062 l2_flag = 0
63 l3_flag = 0
64 l4_flag = 0
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020065 if "l2" in self._collect.lower():
66 l2_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L2
67 if "l3" in self._collect.lower():
68 l3_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L3
69 if "l4" in self._collect.lower():
70 l4_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L4
Alexander Chernavin86c78562022-05-12 14:56:24 +000071 self._test.vapi.flowprobe_set_params(
Ole Troan3013e692019-12-09 15:51:44 +010072 record_flags=(l2_flag | l3_flag | l4_flag),
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020073 active_timer=self._active,
74 passive_timer=self._passive,
75 )
Ole Troan5c749732017-03-13 13:39:52 +010076 self.enable_flowprobe_feature()
77 self._test.vapi.cli("ipfix flush")
78 self._configured = True
79
80 def remove_vpp_config(self):
81 self.disable_exporter()
82 self.disable_flowprobe_feature()
83 self._test.vapi.cli("ipfix flush")
84 self._configured = False
85
86 def enable_exporter(self):
87 self._test.vapi.set_ipfix_exporter(
Jakub Grajciar2f71a882019-10-10 14:21:22 +020088 collector_address=self._test.pg0.remote_ip4,
89 src_address=self._test.pg0.local_ip4,
Ole Troan5c749732017-03-13 13:39:52 +010090 path_mtu=self._mtu,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020091 template_interval=self._timeout,
92 )
Ole Troan5c749732017-03-13 13:39:52 +010093
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +000094 def _enable_disable_flowprobe_feature(self, is_add):
95 which_map = {
96 "l2": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_L2,
97 "ip4": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4,
98 "ip6": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP6,
99 }
100 direction_map = {
101 "rx": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_RX,
102 "tx": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
103 "both": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_BOTH,
104 }
105 self._test.vapi.flowprobe_interface_add_del(
106 is_add=is_add,
107 which=which_map[self._datapath],
108 direction=direction_map[self._direction],
109 sw_if_index=self._intf_obj.sw_if_index,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200110 )
Ole Troan5c749732017-03-13 13:39:52 +0100111
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000112 def enable_flowprobe_feature(self):
113 self._enable_disable_flowprobe_feature(is_add=True)
114
Ole Troan5c749732017-03-13 13:39:52 +0100115 def disable_exporter(self):
116 self._test.vapi.cli("set ipfix exporter collector 0.0.0.0")
117
118 def disable_flowprobe_feature(self):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000119 self._enable_disable_flowprobe_feature(is_add=False)
Ole Troan5c749732017-03-13 13:39:52 +0100120
121 def object_id(self):
Paul Vinciguerrae3a0e6e2019-03-14 08:46:52 -0700122 return "ipfix-collector-%s-%s" % (self._src, self.dst)
Ole Troan5c749732017-03-13 13:39:52 +0100123
124 def query_vpp_config(self):
125 return self._configured
126
127 def verify_templates(self, decoder=None, timeout=1, count=3):
128 templates = []
Klement Sekerac4794572021-09-08 15:15:59 +0200129 self._test.assertIn(count, (1, 2, 3))
130 for _ in range(count):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200131 p = self._test.wait_for_cflow_packet(self._test.collector, 2, timeout)
Ole Troan5c749732017-03-13 13:39:52 +0100132 self._test.assertTrue(p.haslayer(IPFIX))
133 if decoder is not None and p.haslayer(Template):
134 templates.append(p[Template].templateID)
135 decoder.add_template(p.getlayer(Template))
136 return templates
137
138
139class MethodHolder(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200140 """Flow-per-packet plugin: test L2, IP4, IP6 reporting"""
Ole Troan5c749732017-03-13 13:39:52 +0100141
142 # Test variables
143 debug_print = False
Pavel Kotucek89111d02017-06-12 08:26:13 +0200144 max_number_of_packets = 10
Ole Troan5c749732017-03-13 13:39:52 +0100145 pkts = []
146
147 @classmethod
148 def setUpClass(cls):
149 """
150 Perform standard class setup (defined by class method setUpClass in
151 class VppTestCase) before running the test case, set test case related
152 variables and configure VPP.
153 """
154 super(MethodHolder, cls).setUpClass()
Dave Wallace670724c2022-09-20 21:52:18 -0400155 if (is_distro_ubuntu2204 == True or is_distro_debian11 == True) and not hasattr(
156 cls, "vpp"
157 ):
158 return
Ole Troan5c749732017-03-13 13:39:52 +0100159 try:
160 # Create pg interfaces
Ole Troaned929252017-06-13 21:15:40 +0200161 cls.create_pg_interfaces(range(9))
Ole Troan5c749732017-03-13 13:39:52 +0100162
163 # Packet sizes
164 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
165
166 # Create BD with MAC learning and unknown unicast flooding disabled
167 # and put interfaces to this BD
168 cls.vapi.bridge_domain_add_del(bd_id=1, uu_flood=1, learn=1)
Ole Troana5b2eec2019-03-11 19:23:25 +0100169 cls.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200170 rx_sw_if_index=cls.pg1._sw_if_index, bd_id=1
171 )
Ole Troana5b2eec2019-03-11 19:23:25 +0100172 cls.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200173 rx_sw_if_index=cls.pg2._sw_if_index, bd_id=1
174 )
Ole Troan5c749732017-03-13 13:39:52 +0100175
176 # Set up all interfaces
177 for i in cls.pg_interfaces:
178 i.admin_up()
179
180 cls.pg0.config_ip4()
181 cls.pg0.configure_ipv4_neighbors()
182 cls.collector = cls.pg0
183
184 cls.pg1.config_ip4()
185 cls.pg1.resolve_arp()
186 cls.pg2.config_ip4()
187 cls.pg2.resolve_arp()
188 cls.pg3.config_ip4()
189 cls.pg3.resolve_arp()
190 cls.pg4.config_ip4()
191 cls.pg4.resolve_arp()
Ole Troaned929252017-06-13 21:15:40 +0200192 cls.pg7.config_ip4()
193 cls.pg8.config_ip4()
194 cls.pg8.configure_ipv4_neighbors()
Ole Troan5c749732017-03-13 13:39:52 +0100195
196 cls.pg5.config_ip6()
197 cls.pg5.resolve_ndp()
198 cls.pg5.disable_ipv6_ra()
199 cls.pg6.config_ip6()
200 cls.pg6.resolve_ndp()
201 cls.pg6.disable_ipv6_ra()
202 except Exception:
203 super(MethodHolder, cls).tearDownClass()
204 raise
205
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800206 @classmethod
207 def tearDownClass(cls):
208 super(MethodHolder, cls).tearDownClass()
209
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200210 def create_stream(
211 self, src_if=None, dst_if=None, packets=None, size=None, ip_ver="v4"
212 ):
Ole Troan5c749732017-03-13 13:39:52 +0100213 """Create a packet stream to tickle the plugin
214
215 :param VppInterface src_if: Source interface for packet stream
216 :param VppInterface src_if: Dst interface for packet stream
217 """
218 if src_if is None:
219 src_if = self.pg1
220 if dst_if is None:
221 dst_if = self.pg2
222 self.pkts = []
223 if packets is None:
224 packets = random.randint(1, self.max_number_of_packets)
225 pkt_size = size
226 for p in range(0, packets):
227 if size is None:
228 pkt_size = random.choice(self.pg_if_packet_sizes)
229 info = self.create_packet_info(src_if, dst_if)
230 payload = self.info_to_payload(info)
231 p = Ether(src=src_if.remote_mac, dst=src_if.local_mac)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200232 if ip_ver == "v4":
Ole Troan5c749732017-03-13 13:39:52 +0100233 p /= IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
234 else:
235 p /= IPv6(src=src_if.remote_ip6, dst=dst_if.remote_ip6)
Ole Troaned929252017-06-13 21:15:40 +0200236 p /= UDP(sport=1234, dport=4321)
237 p /= Raw(payload)
Ole Troan5c749732017-03-13 13:39:52 +0100238 info.data = p.copy()
239 self.extend_packet(p, pkt_size)
240 self.pkts.append(p)
241
242 def verify_cflow_data(self, decoder, capture, cflow):
243 octets = 0
244 packets = 0
245 for p in capture:
246 octets += p[IP].len
247 packets += 1
248 if cflow.haslayer(Data):
249 data = decoder.decode_data_set(cflow.getlayer(Set))
250 for record in data:
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800251 self.assertEqual(int(binascii.hexlify(record[1]), 16), octets)
252 self.assertEqual(int(binascii.hexlify(record[2]), 16), packets)
Ole Troan5c749732017-03-13 13:39:52 +0100253
Pavel Kotucek89111d02017-06-12 08:26:13 +0200254 def send_packets(self, src_if=None, dst_if=None):
255 if src_if is None:
256 src_if = self.pg1
257 if dst_if is None:
258 dst_if = self.pg2
259 self.pg_enable_capture([dst_if])
260 src_if.add_stream(self.pkts)
261 self.pg_start()
262 return dst_if.get_capture(len(self.pkts))
263
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200264 def verify_cflow_data_detail(
265 self, decoder, capture, cflow, data_set={1: "octets", 2: "packets"}, ip_ver="v4"
266 ):
Ole Troan5c749732017-03-13 13:39:52 +0100267 if self.debug_print:
Paul Vinciguerra661f91f2018-11-28 19:06:41 -0800268 print(capture[0].show())
Ole Troan5c749732017-03-13 13:39:52 +0100269 if cflow.haslayer(Data):
270 data = decoder.decode_data_set(cflow.getlayer(Set))
271 if self.debug_print:
Paul Vinciguerra661f91f2018-11-28 19:06:41 -0800272 print(data)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200273 if ip_ver == "v4":
Ole Troan5c749732017-03-13 13:39:52 +0100274 ip_layer = capture[0][IP]
275 else:
276 ip_layer = capture[0][IPv6]
277 if data_set is not None:
278 for record in data:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700279 # skip flow if ingress/egress interface is 0
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800280 if int(binascii.hexlify(record[10]), 16) == 0:
Ole Troan5c749732017-03-13 13:39:52 +0100281 continue
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800282 if int(binascii.hexlify(record[14]), 16) == 0:
Ole Troan5c749732017-03-13 13:39:52 +0100283 continue
284
285 for field in data_set:
Ole Troan5c749732017-03-13 13:39:52 +0100286 value = data_set[field]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200287 if value == "octets":
Ole Troan5c749732017-03-13 13:39:52 +0100288 value = ip_layer.len
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200289 if ip_ver == "v6":
290 value += 40 # ??? is this correct
291 elif value == "packets":
Ole Troan5c749732017-03-13 13:39:52 +0100292 value = 1
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200293 elif value == "src_ip":
294 if ip_ver == "v4":
295 ip = socket.inet_pton(socket.AF_INET, ip_layer.src)
Ole Troan5c749732017-03-13 13:39:52 +0100296 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200297 ip = socket.inet_pton(socket.AF_INET6, ip_layer.src)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800298 value = int(binascii.hexlify(ip), 16)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200299 elif value == "dst_ip":
300 if ip_ver == "v4":
301 ip = socket.inet_pton(socket.AF_INET, ip_layer.dst)
Ole Troan5c749732017-03-13 13:39:52 +0100302 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200303 ip = socket.inet_pton(socket.AF_INET6, ip_layer.dst)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800304 value = int(binascii.hexlify(ip), 16)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200305 elif value == "sport":
Ole Troan5c749732017-03-13 13:39:52 +0100306 value = int(capture[0][UDP].sport)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200307 elif value == "dport":
Ole Troan5c749732017-03-13 13:39:52 +0100308 value = int(capture[0][UDP].dport)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200309 self.assertEqual(
310 int(binascii.hexlify(record[field]), 16), value
311 )
Ole Troan5c749732017-03-13 13:39:52 +0100312
313 def verify_cflow_data_notimer(self, decoder, capture, cflows):
314 idx = 0
315 for cflow in cflows:
316 if cflow.haslayer(Data):
317 data = decoder.decode_data_set(cflow.getlayer(Set))
318 else:
319 raise Exception("No CFLOW data")
320
321 for rec in data:
322 p = capture[idx]
323 idx += 1
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200324 self.assertEqual(p[IP].len, int(binascii.hexlify(rec[1]), 16))
325 self.assertEqual(1, int(binascii.hexlify(rec[2]), 16))
Ole Troan5c749732017-03-13 13:39:52 +0100326 self.assertEqual(len(capture), idx)
327
Klement Sekerac4794572021-09-08 15:15:59 +0200328 def wait_for_cflow_packet(self, collector_intf, set_id=2, timeout=1):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200329 """wait for CFLOW packet and verify its correctness
Ole Troan5c749732017-03-13 13:39:52 +0100330
331 :param timeout: how long to wait
332
Ole Troan5c749732017-03-13 13:39:52 +0100333 """
334 self.logger.info("IPFIX: Waiting for CFLOW packet")
Ole Troan5c749732017-03-13 13:39:52 +0100335 # self.logger.debug(self.vapi.ppcli("show flow table"))
Klement Sekerac4794572021-09-08 15:15:59 +0200336 p = collector_intf.wait_for_packet(timeout=timeout)
337 self.assertEqual(p[Set].setID, set_id)
338 # self.logger.debug(self.vapi.ppcli("show flow table"))
339 self.logger.debug(ppp("IPFIX: Got packet:", p))
Ole Troan5c749732017-03-13 13:39:52 +0100340 return p
341
Ole Troan5c749732017-03-13 13:39:52 +0100342
Andrew Yourtchenko06f32812021-01-14 10:19:08 +0000343@tag_run_solo
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +0000344@tag_fixme_vpp_workers
Dave Wallace670724c2022-09-20 21:52:18 -0400345@tag_fixme_ubuntu2204
346@tag_fixme_debian11
Ole Troaned929252017-06-13 21:15:40 +0200347class Flowprobe(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +0100348 """Template verification, timer tests"""
349
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800350 @classmethod
351 def setUpClass(cls):
352 super(Flowprobe, cls).setUpClass()
353
354 @classmethod
355 def tearDownClass(cls):
356 super(Flowprobe, cls).tearDownClass()
357
Ole Troan5c749732017-03-13 13:39:52 +0100358 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200359 """timer less than template timeout"""
Ole Troaned929252017-06-13 21:15:40 +0200360 self.logger.info("FFP_TEST_START_0001")
Ole Troan5c749732017-03-13 13:39:52 +0100361 self.pg_enable_capture(self.pg_interfaces)
362 self.pkts = []
363
Pavel Kotucek89111d02017-06-12 08:26:13 +0200364 ipfix = VppCFLOW(test=self, active=2)
Ole Troan5c749732017-03-13 13:39:52 +0100365 ipfix.add_vpp_config()
366
367 ipfix_decoder = IPFIXDecoder()
368 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200369 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +0100370
Ole Troaned929252017-06-13 21:15:40 +0200371 self.create_stream(packets=1)
Pavel Kotucek89111d02017-06-12 08:26:13 +0200372 self.send_packets()
Ole Troaned929252017-06-13 21:15:40 +0200373 capture = self.pg2.get_capture(1)
Ole Troan5c749732017-03-13 13:39:52 +0100374
375 # make sure the one packet we expect actually showed up
Pavel Kotucek89111d02017-06-12 08:26:13 +0200376 cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
Ole Troan5c749732017-03-13 13:39:52 +0100377 self.verify_cflow_data(ipfix_decoder, capture, cflow)
378
379 ipfix.remove_vpp_config()
Ole Troaned929252017-06-13 21:15:40 +0200380 self.logger.info("FFP_TEST_FINISH_0001")
Ole Troan5c749732017-03-13 13:39:52 +0100381
Pavel Kotucek89111d02017-06-12 08:26:13 +0200382 def test_0002(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200383 """timer greater than template timeout"""
Ole Troaned929252017-06-13 21:15:40 +0200384 self.logger.info("FFP_TEST_START_0002")
Ole Troan5c749732017-03-13 13:39:52 +0100385 self.pg_enable_capture(self.pg_interfaces)
386 self.pkts = []
387
Pavel Kotucek89111d02017-06-12 08:26:13 +0200388 ipfix = VppCFLOW(test=self, timeout=3, active=4)
Ole Troan5c749732017-03-13 13:39:52 +0100389 ipfix.add_vpp_config()
390
391 ipfix_decoder = IPFIXDecoder()
392 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200393 ipfix.verify_templates()
Ole Troan5c749732017-03-13 13:39:52 +0100394
Pavel Kotucek89111d02017-06-12 08:26:13 +0200395 self.create_stream(packets=2)
396 self.send_packets()
397 capture = self.pg2.get_capture(2)
Ole Troan5c749732017-03-13 13:39:52 +0100398
399 # next set of template packet should arrive after 20 seconds
400 # template packet should arrive within 20 s
Pavel Kotucek89111d02017-06-12 08:26:13 +0200401 templates = ipfix.verify_templates(ipfix_decoder, timeout=5)
Ole Troan5c749732017-03-13 13:39:52 +0100402
403 # make sure the one packet we expect actually showed up
Pavel Kotucek89111d02017-06-12 08:26:13 +0200404 cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
Ole Troan5c749732017-03-13 13:39:52 +0100405 self.verify_cflow_data(ipfix_decoder, capture, cflow)
406
407 ipfix.remove_vpp_config()
Ole Troaned929252017-06-13 21:15:40 +0200408 self.logger.info("FFP_TEST_FINISH_0002")
409
410 def test_cflow_packet(self):
411 """verify cflow packet fields"""
412 self.logger.info("FFP_TEST_START_0000")
413 self.pg_enable_capture(self.pg_interfaces)
414 self.pkts = []
415
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200416 ipfix = VppCFLOW(
417 test=self, intf="pg8", datapath="ip4", layer="l2 l3 l4", active=2
418 )
Ole Troaned929252017-06-13 21:15:40 +0200419 ipfix.add_vpp_config()
420
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200421 route_9001 = VppIpRoute(
422 self,
423 "9.0.0.0",
424 24,
425 [VppRoutePath(self.pg8._remote_hosts[0].ip4, self.pg8.sw_if_index)],
426 )
Ole Troaned929252017-06-13 21:15:40 +0200427 route_9001.add_vpp_config()
428
429 ipfix_decoder = IPFIXDecoder()
430 templates = ipfix.verify_templates(ipfix_decoder, count=1)
431
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200432 self.pkts = [
433 (
434 Ether(dst=self.pg7.local_mac, src=self.pg7.remote_mac)
435 / IP(src=self.pg7.remote_ip4, dst="9.0.0.100")
436 / TCP(sport=1234, dport=4321, flags=80)
437 / Raw(b"\xa5" * 100)
438 )
439 ]
Ole Troaned929252017-06-13 21:15:40 +0200440
441 nowUTC = int(time.time())
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200442 nowUNIX = nowUTC + 2208988800
Ole Troaned929252017-06-13 21:15:40 +0200443 self.send_packets(src_if=self.pg7, dst_if=self.pg8)
444
445 cflow = self.wait_for_cflow_packet(self.collector, templates[0], 10)
446 self.collector.get_capture(2)
447
448 if cflow[0].haslayer(IPFIX):
449 self.assertEqual(cflow[IPFIX].version, 10)
450 self.assertEqual(cflow[IPFIX].observationDomainID, 1)
451 self.assertEqual(cflow[IPFIX].sequenceNumber, 0)
452 self.assertAlmostEqual(cflow[IPFIX].exportTime, nowUTC, delta=5)
453 if cflow.haslayer(Data):
454 record = ipfix_decoder.decode_data_set(cflow[0].getlayer(Set))[0]
455 # ingress interface
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800456 self.assertEqual(int(binascii.hexlify(record[10]), 16), 8)
Ole Troaned929252017-06-13 21:15:40 +0200457 # egress interface
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800458 self.assertEqual(int(binascii.hexlify(record[14]), 16), 9)
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000459 # direction
460 self.assertEqual(int(binascii.hexlify(record[61]), 16), 1)
Ole Troaned929252017-06-13 21:15:40 +0200461 # packets
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800462 self.assertEqual(int(binascii.hexlify(record[2]), 16), 1)
Ole Troaned929252017-06-13 21:15:40 +0200463 # src mac
Ole Troanb0d83f12019-10-21 23:13:46 +0200464 self.assertEqual(mac_ntop(record[56]), self.pg8.local_mac)
Ole Troaned929252017-06-13 21:15:40 +0200465 # dst mac
Ole Troanb0d83f12019-10-21 23:13:46 +0200466 self.assertEqual(mac_ntop(record[80]), self.pg8.remote_mac)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800467 flowTimestamp = int(binascii.hexlify(record[156]), 16) >> 32
Ole Troaned929252017-06-13 21:15:40 +0200468 # flow start timestamp
469 self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800470 flowTimestamp = int(binascii.hexlify(record[157]), 16) >> 32
Ole Troaned929252017-06-13 21:15:40 +0200471 # flow end timestamp
472 self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
473 # ethernet type
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800474 self.assertEqual(int(binascii.hexlify(record[256]), 16), 8)
Ole Troaned929252017-06-13 21:15:40 +0200475 # src ip
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200476 self.assertEqual(inet_ntop(socket.AF_INET, record[8]), self.pg7.remote_ip4)
Ole Troaned929252017-06-13 21:15:40 +0200477 # dst ip
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200478 self.assertEqual(inet_ntop(socket.AF_INET, record[12]), "9.0.0.100")
Ole Troaned929252017-06-13 21:15:40 +0200479 # protocol (TCP)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800480 self.assertEqual(int(binascii.hexlify(record[4]), 16), 6)
Ole Troaned929252017-06-13 21:15:40 +0200481 # src port
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800482 self.assertEqual(int(binascii.hexlify(record[7]), 16), 1234)
Ole Troaned929252017-06-13 21:15:40 +0200483 # dst port
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800484 self.assertEqual(int(binascii.hexlify(record[11]), 16), 4321)
Ole Troaned929252017-06-13 21:15:40 +0200485 # tcp flags
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800486 self.assertEqual(int(binascii.hexlify(record[6]), 16), 80)
Ole Troaned929252017-06-13 21:15:40 +0200487
488 ipfix.remove_vpp_config()
489 self.logger.info("FFP_TEST_FINISH_0000")
Ole Troan5c749732017-03-13 13:39:52 +0100490
Alexander Chernavin86c78562022-05-12 14:56:24 +0000491 def test_interface_dump(self):
492 """Dump interfaces with IPFIX flow record generation enabled"""
493 self.logger.info("FFP_TEST_START_0003")
494
495 # Enable feature for 3 interfaces
496 ipfix1 = VppCFLOW(test=self, intf="pg1", datapath="l2", direction="rx")
497 ipfix1.add_vpp_config()
498
499 ipfix2 = VppCFLOW(test=self, intf="pg2", datapath="ip4", direction="tx")
500 ipfix2.enable_flowprobe_feature()
501
502 ipfix3 = VppCFLOW(test=self, intf="pg3", datapath="ip6", direction="both")
503 ipfix3.enable_flowprobe_feature()
504
505 # When request "all", dump should contain all enabled interfaces
506 dump = self.vapi.flowprobe_interface_dump()
507 self.assertEqual(len(dump), 3)
508
509 # Verify 1st interface
510 self.assertEqual(dump[0].sw_if_index, self.pg1.sw_if_index)
511 self.assertEqual(
512 dump[0].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_L2
513 )
514 self.assertEqual(
515 dump[0].direction,
516 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_RX,
517 )
518
519 # Verify 2nd interface
520 self.assertEqual(dump[1].sw_if_index, self.pg2.sw_if_index)
521 self.assertEqual(
522 dump[1].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4
523 )
524 self.assertEqual(
525 dump[1].direction,
526 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
527 )
528
529 # Verify 3rd interface
530 self.assertEqual(dump[2].sw_if_index, self.pg3.sw_if_index)
531 self.assertEqual(
532 dump[2].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP6
533 )
534 self.assertEqual(
535 dump[2].direction,
536 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_BOTH,
537 )
538
539 # When request 2nd interface, dump should contain only the specified interface
540 dump = self.vapi.flowprobe_interface_dump(sw_if_index=self.pg2.sw_if_index)
541 self.assertEqual(len(dump), 1)
542
543 # Verify 2nd interface
544 self.assertEqual(dump[0].sw_if_index, self.pg2.sw_if_index)
545 self.assertEqual(
546 dump[0].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4
547 )
548 self.assertEqual(
549 dump[0].direction,
550 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
551 )
552
553 # When request 99th interface, dump should be empty
554 dump = self.vapi.flowprobe_interface_dump(sw_if_index=99)
555 self.assertEqual(len(dump), 0)
556
557 ipfix1.remove_vpp_config()
558 ipfix2.remove_vpp_config()
559 ipfix3.remove_vpp_config()
560 self.logger.info("FFP_TEST_FINISH_0003")
561
562 def test_get_params(self):
563 """Get IPFIX flow record generation parameters"""
564 self.logger.info("FFP_TEST_START_0004")
565
566 # Enable feature for an interface with custom parameters
567 ipfix = VppCFLOW(test=self, active=20, passive=40, layer="l2 l3 l4")
568 ipfix.add_vpp_config()
569
570 # Get and verify parameters
571 params = self.vapi.flowprobe_get_params()
572 self.assertEqual(params.active_timer, 20)
573 self.assertEqual(params.passive_timer, 40)
574 record_flags = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L2
575 record_flags |= VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L3
576 record_flags |= VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L4
577 self.assertEqual(params.record_flags, record_flags)
578
579 ipfix.remove_vpp_config()
580 self.logger.info("FFP_TEST_FINISH_0004")
581
Ole Troan5c749732017-03-13 13:39:52 +0100582
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000583class DatapathTestsHolder(object):
Pavel Kotucek89111d02017-06-12 08:26:13 +0200584 """collect information on Ethernet, IP4 and IP6 datapath (no timers)"""
Ole Troan5c749732017-03-13 13:39:52 +0100585
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800586 @classmethod
587 def setUpClass(cls):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000588 super(DatapathTestsHolder, cls).setUpClass()
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800589
590 @classmethod
591 def tearDownClass(cls):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000592 super(DatapathTestsHolder, cls).tearDownClass()
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800593
Pavel Kotucek89111d02017-06-12 08:26:13 +0200594 def test_templatesL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200595 """verify template on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100596 self.logger.info("FFP_TEST_START_0000")
597 self.pg_enable_capture(self.pg_interfaces)
598
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000599 ipfix = VppCFLOW(
600 test=self, intf=self.intf1, layer="l2", direction=self.direction
601 )
Ole Troan5c749732017-03-13 13:39:52 +0100602 ipfix.add_vpp_config()
603
604 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400605 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200606 ipfix.verify_templates(timeout=3, count=1)
607 self.collector.get_capture(1)
Ole Troan5c749732017-03-13 13:39:52 +0100608
609 ipfix.remove_vpp_config()
610 self.logger.info("FFP_TEST_FINISH_0000")
611
Pavel Kotucek89111d02017-06-12 08:26:13 +0200612 def test_L2onL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200613 """L2 data on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100614 self.logger.info("FFP_TEST_START_0001")
615 self.pg_enable_capture(self.pg_interfaces)
616 self.pkts = []
617
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000618 ipfix = VppCFLOW(
619 test=self, intf=self.intf1, layer="l2", direction=self.direction
620 )
Ole Troan5c749732017-03-13 13:39:52 +0100621 ipfix.add_vpp_config()
622
623 ipfix_decoder = IPFIXDecoder()
624 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200625 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100626
627 self.create_stream(packets=1)
628 capture = self.send_packets()
629
630 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400631 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200632 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200633 self.verify_cflow_data_detail(
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000634 ipfix_decoder,
635 capture,
636 cflow,
637 {2: "packets", 256: 8, 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200638 )
Ole Troan5c749732017-03-13 13:39:52 +0100639 self.collector.get_capture(2)
640
641 ipfix.remove_vpp_config()
642 self.logger.info("FFP_TEST_FINISH_0001")
643
Pavel Kotucek89111d02017-06-12 08:26:13 +0200644 def test_L3onL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200645 """L3 data on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100646 self.logger.info("FFP_TEST_START_0002")
647 self.pg_enable_capture(self.pg_interfaces)
648 self.pkts = []
649
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000650 ipfix = VppCFLOW(
651 test=self, intf=self.intf1, layer="l3", direction=self.direction
652 )
Ole Troan5c749732017-03-13 13:39:52 +0100653 ipfix.add_vpp_config()
654
655 ipfix_decoder = IPFIXDecoder()
656 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200657 templates = ipfix.verify_templates(ipfix_decoder, count=2)
Ole Troan5c749732017-03-13 13:39:52 +0100658
659 self.create_stream(packets=1)
660 capture = self.send_packets()
661
662 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400663 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200664 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200665 self.verify_cflow_data_detail(
666 ipfix_decoder,
667 capture,
668 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000669 {
670 2: "packets",
671 4: 17,
672 8: "src_ip",
673 12: "dst_ip",
674 61: (self.direction == "tx"),
675 },
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200676 )
Ole Troan5c749732017-03-13 13:39:52 +0100677
Ole Troan5c749732017-03-13 13:39:52 +0100678 self.collector.get_capture(3)
679
680 ipfix.remove_vpp_config()
681 self.logger.info("FFP_TEST_FINISH_0002")
682
Pavel Kotucek89111d02017-06-12 08:26:13 +0200683 def test_L4onL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200684 """L4 data on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100685 self.logger.info("FFP_TEST_START_0003")
686 self.pg_enable_capture(self.pg_interfaces)
687 self.pkts = []
688
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000689 ipfix = VppCFLOW(
690 test=self, intf=self.intf1, layer="l4", direction=self.direction
691 )
Ole Troan5c749732017-03-13 13:39:52 +0100692 ipfix.add_vpp_config()
693
694 ipfix_decoder = IPFIXDecoder()
695 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200696 templates = ipfix.verify_templates(ipfix_decoder, count=2)
Ole Troan5c749732017-03-13 13:39:52 +0100697
698 self.create_stream(packets=1)
699 capture = self.send_packets()
700
701 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400702 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200703 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200704 self.verify_cflow_data_detail(
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000705 ipfix_decoder,
706 capture,
707 cflow,
708 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200709 )
Ole Troan5c749732017-03-13 13:39:52 +0100710
Ole Troan5c749732017-03-13 13:39:52 +0100711 self.collector.get_capture(3)
712
713 ipfix.remove_vpp_config()
714 self.logger.info("FFP_TEST_FINISH_0003")
715
Pavel Kotucek89111d02017-06-12 08:26:13 +0200716 def test_templatesIp4(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200717 """verify templates on IP4 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100718 self.logger.info("FFP_TEST_START_0000")
719
720 self.pg_enable_capture(self.pg_interfaces)
721
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000722 ipfix = VppCFLOW(
723 test=self, intf=self.intf1, datapath="ip4", direction=self.direction
724 )
Ole Troan5c749732017-03-13 13:39:52 +0100725 ipfix.add_vpp_config()
726
727 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400728 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +0100729 ipfix.verify_templates(timeout=3, count=1)
730 self.collector.get_capture(1)
731
732 ipfix.remove_vpp_config()
733
734 self.logger.info("FFP_TEST_FINISH_0000")
735
Pavel Kotucek89111d02017-06-12 08:26:13 +0200736 def test_L2onIP4(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200737 """L2 data on IP4 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100738 self.logger.info("FFP_TEST_START_0001")
739 self.pg_enable_capture(self.pg_interfaces)
740 self.pkts = []
741
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000742 ipfix = VppCFLOW(
743 test=self,
744 intf=self.intf2,
745 layer="l2",
746 datapath="ip4",
747 direction=self.direction,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200748 )
Ole Troan5c749732017-03-13 13:39:52 +0100749 ipfix.add_vpp_config()
750
751 ipfix_decoder = IPFIXDecoder()
752 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200753 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100754
755 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
756 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
757
758 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400759 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200760 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200761 self.verify_cflow_data_detail(
762 ipfix_decoder,
763 capture,
764 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000765 {2: "packets", 256: 8, 61: (self.direction == "tx")},
766 )
767
768 # expected two templates and one cflow packet
769 self.collector.get_capture(2)
770
771 ipfix.remove_vpp_config()
772 self.logger.info("FFP_TEST_FINISH_0001")
773
774 def test_L3onIP4(self):
775 """L3 data on IP4 datapath"""
776 self.logger.info("FFP_TEST_START_0002")
777 self.pg_enable_capture(self.pg_interfaces)
778 self.pkts = []
779
780 ipfix = VppCFLOW(
781 test=self,
782 intf=self.intf2,
783 layer="l3",
784 datapath="ip4",
785 direction=self.direction,
786 )
787 ipfix.add_vpp_config()
788
789 ipfix_decoder = IPFIXDecoder()
790 # template packet should arrive immediately
791 templates = ipfix.verify_templates(ipfix_decoder, count=1)
792
793 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
794 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
795
796 # make sure the one packet we expect actually showed up
797 self.vapi.ipfix_flush()
798 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
799 self.verify_cflow_data_detail(
800 ipfix_decoder,
801 capture,
802 cflow,
803 {
804 1: "octets",
805 2: "packets",
806 8: "src_ip",
807 12: "dst_ip",
808 61: (self.direction == "tx"),
809 },
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200810 )
Ole Troan5c749732017-03-13 13:39:52 +0100811
812 # expected two templates and one cflow packet
813 self.collector.get_capture(2)
814
815 ipfix.remove_vpp_config()
816 self.logger.info("FFP_TEST_FINISH_0002")
817
Pavel Kotucek89111d02017-06-12 08:26:13 +0200818 def test_L4onIP4(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200819 """L4 data on IP4 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100820 self.logger.info("FFP_TEST_START_0003")
821 self.pg_enable_capture(self.pg_interfaces)
822 self.pkts = []
823
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000824 ipfix = VppCFLOW(
825 test=self,
826 intf=self.intf2,
827 layer="l4",
828 datapath="ip4",
829 direction=self.direction,
830 )
Ole Troan5c749732017-03-13 13:39:52 +0100831 ipfix.add_vpp_config()
832
833 ipfix_decoder = IPFIXDecoder()
834 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200835 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100836
837 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
838 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
839
840 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400841 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200842 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200843 self.verify_cflow_data_detail(
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000844 ipfix_decoder,
845 capture,
846 cflow,
847 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200848 )
Ole Troan5c749732017-03-13 13:39:52 +0100849
850 # expected two templates and one cflow packet
851 self.collector.get_capture(2)
852
853 ipfix.remove_vpp_config()
854 self.logger.info("FFP_TEST_FINISH_0003")
855
Pavel Kotucek89111d02017-06-12 08:26:13 +0200856 def test_templatesIP6(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200857 """verify templates on IP6 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100858 self.logger.info("FFP_TEST_START_0000")
859 self.pg_enable_capture(self.pg_interfaces)
860
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000861 ipfix = VppCFLOW(
862 test=self, intf=self.intf1, datapath="ip6", direction=self.direction
863 )
Ole Troan5c749732017-03-13 13:39:52 +0100864 ipfix.add_vpp_config()
865
866 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200867 ipfix.verify_templates(count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100868 self.collector.get_capture(1)
869
870 ipfix.remove_vpp_config()
871
872 self.logger.info("FFP_TEST_FINISH_0000")
873
Pavel Kotucek89111d02017-06-12 08:26:13 +0200874 def test_L2onIP6(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200875 """L2 data on IP6 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100876 self.logger.info("FFP_TEST_START_0001")
877 self.pg_enable_capture(self.pg_interfaces)
878 self.pkts = []
879
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000880 ipfix = VppCFLOW(
881 test=self,
882 intf=self.intf3,
883 layer="l2",
884 datapath="ip6",
885 direction=self.direction,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200886 )
Ole Troan5c749732017-03-13 13:39:52 +0100887 ipfix.add_vpp_config()
888
889 ipfix_decoder = IPFIXDecoder()
890 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200891 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100892
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200893 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
Ole Troan5c749732017-03-13 13:39:52 +0100894 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
895
896 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400897 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200898 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200899 self.verify_cflow_data_detail(
900 ipfix_decoder,
901 capture,
902 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000903 {2: "packets", 256: 56710, 61: (self.direction == "tx")},
904 ip_ver="v6",
905 )
906
907 # expected two templates and one cflow packet
908 self.collector.get_capture(2)
909
910 ipfix.remove_vpp_config()
911 self.logger.info("FFP_TEST_FINISH_0001")
912
913 def test_L3onIP6(self):
914 """L3 data on IP6 datapath"""
915 self.logger.info("FFP_TEST_START_0002")
916 self.pg_enable_capture(self.pg_interfaces)
917 self.pkts = []
918
919 ipfix = VppCFLOW(
920 test=self,
921 intf=self.intf3,
922 layer="l3",
923 datapath="ip6",
924 direction=self.direction,
925 )
926 ipfix.add_vpp_config()
927
928 ipfix_decoder = IPFIXDecoder()
929 # template packet should arrive immediately
930 templates = ipfix.verify_templates(ipfix_decoder, count=1)
931
932 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
933 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
934
935 # make sure the one packet we expect actually showed up
936 self.vapi.ipfix_flush()
937 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
938 self.verify_cflow_data_detail(
939 ipfix_decoder,
940 capture,
941 cflow,
942 {2: "packets", 27: "src_ip", 28: "dst_ip", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200943 ip_ver="v6",
944 )
Ole Troan5c749732017-03-13 13:39:52 +0100945
946 # expected two templates and one cflow packet
947 self.collector.get_capture(2)
948
949 ipfix.remove_vpp_config()
950 self.logger.info("FFP_TEST_FINISH_0002")
951
Pavel Kotucek89111d02017-06-12 08:26:13 +0200952 def test_L4onIP6(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200953 """L4 data on IP6 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100954 self.logger.info("FFP_TEST_START_0003")
955 self.pg_enable_capture(self.pg_interfaces)
956 self.pkts = []
957
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000958 ipfix = VppCFLOW(
959 test=self,
960 intf=self.intf3,
961 layer="l4",
962 datapath="ip6",
963 direction=self.direction,
964 )
Ole Troan5c749732017-03-13 13:39:52 +0100965 ipfix.add_vpp_config()
966
967 ipfix_decoder = IPFIXDecoder()
968 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200969 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100970
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200971 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
Ole Troan5c749732017-03-13 13:39:52 +0100972 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
973
974 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400975 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200976 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200977 self.verify_cflow_data_detail(
978 ipfix_decoder,
979 capture,
980 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000981 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200982 ip_ver="v6",
983 )
Ole Troan5c749732017-03-13 13:39:52 +0100984
985 # expected two templates and one cflow packet
986 self.collector.get_capture(2)
987
988 ipfix.remove_vpp_config()
989 self.logger.info("FFP_TEST_FINISH_0003")
990
Ole Troan5c749732017-03-13 13:39:52 +0100991 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200992 """no timers, one CFLOW packet, 9 Flows inside"""
Ole Troan5c749732017-03-13 13:39:52 +0100993 self.logger.info("FFP_TEST_START_0001")
994 self.pg_enable_capture(self.pg_interfaces)
995 self.pkts = []
996
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000997 ipfix = VppCFLOW(test=self, intf=self.intf1, direction=self.direction)
Ole Troan5c749732017-03-13 13:39:52 +0100998 ipfix.add_vpp_config()
999
1000 ipfix_decoder = IPFIXDecoder()
1001 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001002 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001003
1004 self.create_stream(packets=9)
1005 capture = self.send_packets()
1006
1007 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001008 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001009 cflow = self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001010 self.verify_cflow_data_notimer(ipfix_decoder, capture, [cflow])
Ole Troan5c749732017-03-13 13:39:52 +01001011 self.collector.get_capture(4)
1012
1013 ipfix.remove_vpp_config()
1014 self.logger.info("FFP_TEST_FINISH_0001")
1015
1016 def test_0002(self):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001017 """no timers, two CFLOW packets (mtu=260), 3 Flows in each"""
Ole Troan5c749732017-03-13 13:39:52 +01001018 self.logger.info("FFP_TEST_START_0002")
1019 self.pg_enable_capture(self.pg_interfaces)
1020 self.pkts = []
1021
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001022 ipfix = VppCFLOW(test=self, intf=self.intf1, direction=self.direction, mtu=260)
Ole Troan5c749732017-03-13 13:39:52 +01001023 ipfix.add_vpp_config()
1024
1025 ipfix_decoder = IPFIXDecoder()
1026 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001027 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001028 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001029
1030 self.create_stream(packets=6)
1031 capture = self.send_packets()
1032
1033 # make sure the one packet we expect actually showed up
1034 cflows = []
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001035 self.vapi.ipfix_flush()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001036 cflows.append(self.wait_for_cflow_packet(self.collector, templates[1]))
1037 cflows.append(self.wait_for_cflow_packet(self.collector, templates[1]))
Ole Troan5c749732017-03-13 13:39:52 +01001038 self.verify_cflow_data_notimer(ipfix_decoder, capture, cflows)
1039 self.collector.get_capture(5)
1040
1041 ipfix.remove_vpp_config()
1042 self.logger.info("FFP_TEST_FINISH_0002")
1043
1044
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001045@tag_fixme_vpp_workers
1046class DatapathTx(MethodHolder, DatapathTestsHolder):
1047 """Collect info on Ethernet, IP4 and IP6 datapath (TX) (no timers)"""
1048
1049 intf1 = "pg2"
1050 intf2 = "pg4"
1051 intf3 = "pg6"
1052 direction = "tx"
1053
1054
1055@tag_fixme_vpp_workers
1056class DatapathRx(MethodHolder, DatapathTestsHolder):
1057 """Collect info on Ethernet, IP4 and IP6 datapath (RX) (no timers)"""
1058
1059 intf1 = "pg1"
1060 intf2 = "pg3"
1061 intf3 = "pg5"
1062 direction = "rx"
1063
1064
Klement Sekerab23ffd72021-05-31 16:08:53 +02001065@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001066class DisableIPFIX(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001067 """Disable IPFIX"""
1068
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001069 @classmethod
1070 def setUpClass(cls):
1071 super(DisableIPFIX, cls).setUpClass()
1072
1073 @classmethod
1074 def tearDownClass(cls):
1075 super(DisableIPFIX, cls).tearDownClass()
1076
Ole Troan5c749732017-03-13 13:39:52 +01001077 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001078 """disable IPFIX after first packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001079 self.logger.info("FFP_TEST_START_0001")
1080 self.pg_enable_capture(self.pg_interfaces)
1081 self.pkts = []
1082
Pavel Kotucek89111d02017-06-12 08:26:13 +02001083 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001084 ipfix.add_vpp_config()
1085
1086 ipfix_decoder = IPFIXDecoder()
1087 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001088 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001089
1090 self.create_stream()
1091 self.send_packets()
1092
1093 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001094 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001095 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001096 self.collector.get_capture(4)
1097
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001098 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +01001099 ipfix.disable_exporter()
1100 self.pg_enable_capture([self.collector])
1101
1102 self.send_packets()
1103
1104 # make sure no one packet arrived in 1 minute
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001105 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001106 self.sleep(1, "wait before verifying no packets sent")
1107 self.collector.assert_nothing_captured()
Ole Troan5c749732017-03-13 13:39:52 +01001108
1109 ipfix.remove_vpp_config()
1110 self.logger.info("FFP_TEST_FINISH_0001")
1111
1112
Klement Sekerab23ffd72021-05-31 16:08:53 +02001113@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001114class ReenableIPFIX(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001115 """Re-enable IPFIX"""
1116
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001117 @classmethod
1118 def setUpClass(cls):
1119 super(ReenableIPFIX, cls).setUpClass()
1120
1121 @classmethod
1122 def tearDownClass(cls):
1123 super(ReenableIPFIX, cls).tearDownClass()
1124
Pavel Kotucek89111d02017-06-12 08:26:13 +02001125 def test_0011(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001126 """disable IPFIX after first packets and re-enable after few packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001127 self.logger.info("FFP_TEST_START_0001")
1128 self.pg_enable_capture(self.pg_interfaces)
1129 self.pkts = []
1130
Pavel Kotucek89111d02017-06-12 08:26:13 +02001131 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001132 ipfix.add_vpp_config()
1133
1134 ipfix_decoder = IPFIXDecoder()
1135 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001136 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001137
Pavel Kotucek89111d02017-06-12 08:26:13 +02001138 self.create_stream(packets=5)
Ole Troan5c749732017-03-13 13:39:52 +01001139 self.send_packets()
1140
1141 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001142 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001143 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001144 self.collector.get_capture(4)
1145
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001146 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +01001147 ipfix.disable_exporter()
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001148 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +01001149 self.pg_enable_capture([self.collector])
1150
1151 self.send_packets()
1152
1153 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001154 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001155 self.sleep(1, "wait before verifying no packets sent")
1156 self.collector.assert_nothing_captured()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001157 self.pg2.get_capture(5)
Ole Troan5c749732017-03-13 13:39:52 +01001158
1159 # enable IPFIX
1160 ipfix.enable_exporter()
Ole Troan5c749732017-03-13 13:39:52 +01001161
Pavel Kotucek89111d02017-06-12 08:26:13 +02001162 capture = self.collector.get_capture(4)
1163 nr_templates = 0
1164 nr_data = 0
1165 for p in capture:
1166 self.assertTrue(p.haslayer(IPFIX))
1167 if p.haslayer(Template):
1168 nr_templates += 1
1169 self.assertTrue(nr_templates, 3)
1170 for p in capture:
1171 self.assertTrue(p.haslayer(IPFIX))
1172 if p.haslayer(Data):
1173 nr_data += 1
1174 self.assertTrue(nr_templates, 1)
Ole Troan5c749732017-03-13 13:39:52 +01001175
1176 ipfix.remove_vpp_config()
1177 self.logger.info("FFP_TEST_FINISH_0001")
1178
1179
Klement Sekerab23ffd72021-05-31 16:08:53 +02001180@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001181class DisableFP(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001182 """Disable Flowprobe feature"""
1183
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001184 @classmethod
1185 def setUpClass(cls):
1186 super(DisableFP, cls).setUpClass()
1187
1188 @classmethod
1189 def tearDownClass(cls):
1190 super(DisableFP, cls).tearDownClass()
1191
Ole Troan5c749732017-03-13 13:39:52 +01001192 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001193 """disable flowprobe feature after first packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001194 self.logger.info("FFP_TEST_START_0001")
1195 self.pg_enable_capture(self.pg_interfaces)
1196 self.pkts = []
Pavel Kotucek89111d02017-06-12 08:26:13 +02001197 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001198 ipfix.add_vpp_config()
1199
1200 ipfix_decoder = IPFIXDecoder()
1201 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001202 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001203
1204 self.create_stream()
1205 self.send_packets()
1206
1207 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001208 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001209 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001210 self.collector.get_capture(4)
1211
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001212 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +01001213 ipfix.disable_flowprobe_feature()
1214 self.pg_enable_capture([self.collector])
1215
1216 self.send_packets()
1217
1218 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001219 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001220 self.sleep(1, "wait before verifying no packets sent")
1221 self.collector.assert_nothing_captured()
Ole Troan5c749732017-03-13 13:39:52 +01001222
1223 ipfix.remove_vpp_config()
1224 self.logger.info("FFP_TEST_FINISH_0001")
1225
1226
Klement Sekerab23ffd72021-05-31 16:08:53 +02001227@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001228class ReenableFP(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001229 """Re-enable Flowprobe feature"""
1230
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001231 @classmethod
1232 def setUpClass(cls):
1233 super(ReenableFP, cls).setUpClass()
1234
1235 @classmethod
1236 def tearDownClass(cls):
1237 super(ReenableFP, cls).tearDownClass()
1238
Ole Troan5c749732017-03-13 13:39:52 +01001239 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001240 """disable flowprobe feature after first packets and re-enable
1241 after few packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001242 self.logger.info("FFP_TEST_START_0001")
1243 self.pg_enable_capture(self.pg_interfaces)
1244 self.pkts = []
1245
Pavel Kotucek89111d02017-06-12 08:26:13 +02001246 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001247 ipfix.add_vpp_config()
1248
1249 ipfix_decoder = IPFIXDecoder()
1250 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001251 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +01001252 templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
1253
1254 self.create_stream()
1255 self.send_packets()
1256
1257 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001258 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001259 self.wait_for_cflow_packet(self.collector, templates[1], 5)
Ole Troan5c749732017-03-13 13:39:52 +01001260 self.collector.get_capture(4)
1261
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001262 # disable FPP feature
Ole Troan5c749732017-03-13 13:39:52 +01001263 ipfix.disable_flowprobe_feature()
1264 self.pg_enable_capture([self.collector])
1265
1266 self.send_packets()
1267
1268 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001269 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001270 self.sleep(5, "wait before verifying no packets sent")
1271 self.collector.assert_nothing_captured()
Ole Troan5c749732017-03-13 13:39:52 +01001272
1273 # enable FPP feature
1274 ipfix.enable_flowprobe_feature()
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001275 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +01001276 templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
1277
1278 self.send_packets()
1279
1280 # make sure the next packets (templates and data) we expect actually
1281 # showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001282 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001283 self.wait_for_cflow_packet(self.collector, templates[1], 5)
Ole Troan5c749732017-03-13 13:39:52 +01001284 self.collector.get_capture(4)
1285
1286 ipfix.remove_vpp_config()
1287 self.logger.info("FFP_TEST_FINISH_0001")
1288
1289
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001290if __name__ == "__main__":
Ole Troan5c749732017-03-13 13:39:52 +01001291 unittest.main(testRunner=VppTestRunner)