blob: 517729d8591b7851eea0b9e6b844c88457c65944 [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
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +000015from framework import tag_fixme_vpp_workers
Pavel Kotucek89111d02017-06-12 08:26:13 +020016from framework import VppTestCase, VppTestRunner, running_extended_tests
Andrew Yourtchenko06f32812021-01-14 10:19:08 +000017from framework import tag_run_solo
Ole Troan5c749732017-03-13 13:39:52 +010018from vpp_object import VppObject
19from vpp_pg_interface import CaptureTimeoutError
20from util import ppp
21from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
Ole Troaned929252017-06-13 21:15:40 +020022from vpp_ip_route import VppIpRoute, VppRoutePath
Ole Troanb0d83f12019-10-21 23:13:46 +020023from vpp_papi.macaddress import mac_ntop
24from socket import inet_ntop
Ole Troan3013e692019-12-09 15:51:44 +010025from vpp_papi import VppEnum
Ole Troan5c749732017-03-13 13:39:52 +010026
27
28class VppCFLOW(VppObject):
29 """CFLOW object for IPFIX exporter and Flowprobe feature"""
30
Pavel Kotucek89111d02017-06-12 08:26:13 +020031 def __init__(self, test, intf='pg2', active=0, passive=0, timeout=100,
32 mtu=1024, datapath='l2', layer='l2 l3 l4'):
Ole Troan5c749732017-03-13 13:39:52 +010033 self._test = test
34 self._intf = intf
35 self._active = active
36 if passive == 0 or passive < active:
Pavel Kotucek89111d02017-06-12 08:26:13 +020037 self._passive = active+1
Ole Troan5c749732017-03-13 13:39:52 +010038 else:
39 self._passive = passive
40 self._datapath = datapath # l2 ip4 ip6
41 self._collect = layer # l2 l3 l4
42 self._timeout = timeout
43 self._mtu = mtu
44 self._configured = False
45
46 def add_vpp_config(self):
47 self.enable_exporter()
Ole Troan3013e692019-12-09 15:51:44 +010048 l2_flag = 0
49 l3_flag = 0
50 l4_flag = 0
51 if 'l2' in self._collect.lower():
52 l2_flag = (VppEnum.vl_api_flowprobe_record_flags_t.
53 FLOWPROBE_RECORD_FLAG_L2)
54 if 'l3' in self._collect.lower():
55 l3_flag = (VppEnum.vl_api_flowprobe_record_flags_t.
56 FLOWPROBE_RECORD_FLAG_L3)
57 if 'l4' in self._collect.lower():
58 l4_flag = (VppEnum.vl_api_flowprobe_record_flags_t.
59 FLOWPROBE_RECORD_FLAG_L4)
Paul Vinciguerraec850a82019-03-19 08:07:53 -070060 self._test.vapi.flowprobe_params(
Ole Troan3013e692019-12-09 15:51:44 +010061 record_flags=(l2_flag | l3_flag | l4_flag),
Paul Vinciguerraec850a82019-03-19 08:07:53 -070062 active_timer=self._active, passive_timer=self._passive)
Ole Troan5c749732017-03-13 13:39:52 +010063 self.enable_flowprobe_feature()
64 self._test.vapi.cli("ipfix flush")
65 self._configured = True
66
67 def remove_vpp_config(self):
68 self.disable_exporter()
69 self.disable_flowprobe_feature()
70 self._test.vapi.cli("ipfix flush")
71 self._configured = False
72
73 def enable_exporter(self):
74 self._test.vapi.set_ipfix_exporter(
Jakub Grajciar2f71a882019-10-10 14:21:22 +020075 collector_address=self._test.pg0.remote_ip4,
76 src_address=self._test.pg0.local_ip4,
Ole Troan5c749732017-03-13 13:39:52 +010077 path_mtu=self._mtu,
78 template_interval=self._timeout)
79
80 def enable_flowprobe_feature(self):
81 self._test.vapi.ppcli("flowprobe feature add-del %s %s" %
82 (self._intf, self._datapath))
83
84 def disable_exporter(self):
85 self._test.vapi.cli("set ipfix exporter collector 0.0.0.0")
86
87 def disable_flowprobe_feature(self):
88 self._test.vapi.cli("flowprobe feature add-del %s %s disable" %
89 (self._intf, self._datapath))
90
91 def object_id(self):
Paul Vinciguerrae3a0e6e2019-03-14 08:46:52 -070092 return "ipfix-collector-%s-%s" % (self._src, self.dst)
Ole Troan5c749732017-03-13 13:39:52 +010093
94 def query_vpp_config(self):
95 return self._configured
96
97 def verify_templates(self, decoder=None, timeout=1, count=3):
98 templates = []
99 p = self._test.wait_for_cflow_packet(self._test.collector, 2, timeout)
100 self._test.assertTrue(p.haslayer(IPFIX))
101 if decoder is not None and p.haslayer(Template):
102 templates.append(p[Template].templateID)
103 decoder.add_template(p.getlayer(Template))
104 if count > 1:
105 p = self._test.wait_for_cflow_packet(self._test.collector, 2)
106 self._test.assertTrue(p.haslayer(IPFIX))
107 if decoder is not None and p.haslayer(Template):
108 templates.append(p[Template].templateID)
109 decoder.add_template(p.getlayer(Template))
110 if count > 2:
111 p = self._test.wait_for_cflow_packet(self._test.collector, 2)
112 self._test.assertTrue(p.haslayer(IPFIX))
113 if decoder is not None and p.haslayer(Template):
114 templates.append(p[Template].templateID)
115 decoder.add_template(p.getlayer(Template))
116 return templates
117
118
119class MethodHolder(VppTestCase):
120 """ Flow-per-packet plugin: test L2, IP4, IP6 reporting """
121
122 # Test variables
123 debug_print = False
Pavel Kotucek89111d02017-06-12 08:26:13 +0200124 max_number_of_packets = 10
Ole Troan5c749732017-03-13 13:39:52 +0100125 pkts = []
126
127 @classmethod
128 def setUpClass(cls):
129 """
130 Perform standard class setup (defined by class method setUpClass in
131 class VppTestCase) before running the test case, set test case related
132 variables and configure VPP.
133 """
134 super(MethodHolder, cls).setUpClass()
135 try:
136 # Create pg interfaces
Ole Troaned929252017-06-13 21:15:40 +0200137 cls.create_pg_interfaces(range(9))
Ole Troan5c749732017-03-13 13:39:52 +0100138
139 # Packet sizes
140 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
141
142 # Create BD with MAC learning and unknown unicast flooding disabled
143 # and put interfaces to this BD
144 cls.vapi.bridge_domain_add_del(bd_id=1, uu_flood=1, learn=1)
Ole Troana5b2eec2019-03-11 19:23:25 +0100145 cls.vapi.sw_interface_set_l2_bridge(
146 rx_sw_if_index=cls.pg1._sw_if_index, bd_id=1)
147 cls.vapi.sw_interface_set_l2_bridge(
148 rx_sw_if_index=cls.pg2._sw_if_index, bd_id=1)
Ole Troan5c749732017-03-13 13:39:52 +0100149
150 # Set up all interfaces
151 for i in cls.pg_interfaces:
152 i.admin_up()
153
154 cls.pg0.config_ip4()
155 cls.pg0.configure_ipv4_neighbors()
156 cls.collector = cls.pg0
157
158 cls.pg1.config_ip4()
159 cls.pg1.resolve_arp()
160 cls.pg2.config_ip4()
161 cls.pg2.resolve_arp()
162 cls.pg3.config_ip4()
163 cls.pg3.resolve_arp()
164 cls.pg4.config_ip4()
165 cls.pg4.resolve_arp()
Ole Troaned929252017-06-13 21:15:40 +0200166 cls.pg7.config_ip4()
167 cls.pg8.config_ip4()
168 cls.pg8.configure_ipv4_neighbors()
Ole Troan5c749732017-03-13 13:39:52 +0100169
170 cls.pg5.config_ip6()
171 cls.pg5.resolve_ndp()
172 cls.pg5.disable_ipv6_ra()
173 cls.pg6.config_ip6()
174 cls.pg6.resolve_ndp()
175 cls.pg6.disable_ipv6_ra()
176 except Exception:
177 super(MethodHolder, cls).tearDownClass()
178 raise
179
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800180 @classmethod
181 def tearDownClass(cls):
182 super(MethodHolder, cls).tearDownClass()
183
Ole Troan5c749732017-03-13 13:39:52 +0100184 def create_stream(self, src_if=None, dst_if=None, packets=None,
185 size=None, ip_ver='v4'):
186 """Create a packet stream to tickle the plugin
187
188 :param VppInterface src_if: Source interface for packet stream
189 :param VppInterface src_if: Dst interface for packet stream
190 """
191 if src_if is None:
192 src_if = self.pg1
193 if dst_if is None:
194 dst_if = self.pg2
195 self.pkts = []
196 if packets is None:
197 packets = random.randint(1, self.max_number_of_packets)
198 pkt_size = size
199 for p in range(0, packets):
200 if size is None:
201 pkt_size = random.choice(self.pg_if_packet_sizes)
202 info = self.create_packet_info(src_if, dst_if)
203 payload = self.info_to_payload(info)
204 p = Ether(src=src_if.remote_mac, dst=src_if.local_mac)
205 if ip_ver == 'v4':
206 p /= IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
207 else:
208 p /= IPv6(src=src_if.remote_ip6, dst=dst_if.remote_ip6)
Ole Troaned929252017-06-13 21:15:40 +0200209 p /= UDP(sport=1234, dport=4321)
210 p /= Raw(payload)
Ole Troan5c749732017-03-13 13:39:52 +0100211 info.data = p.copy()
212 self.extend_packet(p, pkt_size)
213 self.pkts.append(p)
214
215 def verify_cflow_data(self, decoder, capture, cflow):
216 octets = 0
217 packets = 0
218 for p in capture:
219 octets += p[IP].len
220 packets += 1
221 if cflow.haslayer(Data):
222 data = decoder.decode_data_set(cflow.getlayer(Set))
223 for record in data:
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800224 self.assertEqual(int(binascii.hexlify(record[1]), 16), octets)
225 self.assertEqual(int(binascii.hexlify(record[2]), 16), packets)
Ole Troan5c749732017-03-13 13:39:52 +0100226
Pavel Kotucek89111d02017-06-12 08:26:13 +0200227 def send_packets(self, src_if=None, dst_if=None):
228 if src_if is None:
229 src_if = self.pg1
230 if dst_if is None:
231 dst_if = self.pg2
232 self.pg_enable_capture([dst_if])
233 src_if.add_stream(self.pkts)
234 self.pg_start()
235 return dst_if.get_capture(len(self.pkts))
236
Ole Troan5c749732017-03-13 13:39:52 +0100237 def verify_cflow_data_detail(self, decoder, capture, cflow,
238 data_set={1: 'octets', 2: 'packets'},
239 ip_ver='v4'):
240 if self.debug_print:
Paul Vinciguerra661f91f2018-11-28 19:06:41 -0800241 print(capture[0].show())
Ole Troan5c749732017-03-13 13:39:52 +0100242 if cflow.haslayer(Data):
243 data = decoder.decode_data_set(cflow.getlayer(Set))
244 if self.debug_print:
Paul Vinciguerra661f91f2018-11-28 19:06:41 -0800245 print(data)
Ole Troan5c749732017-03-13 13:39:52 +0100246 if ip_ver == 'v4':
247 ip_layer = capture[0][IP]
248 else:
249 ip_layer = capture[0][IPv6]
250 if data_set is not None:
251 for record in data:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700252 # skip flow if ingress/egress interface is 0
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800253 if int(binascii.hexlify(record[10]), 16) == 0:
Ole Troan5c749732017-03-13 13:39:52 +0100254 continue
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800255 if int(binascii.hexlify(record[14]), 16) == 0:
Ole Troan5c749732017-03-13 13:39:52 +0100256 continue
257
258 for field in data_set:
259 if field not in record.keys():
260 continue
261 value = data_set[field]
262 if value == 'octets':
263 value = ip_layer.len
264 if ip_ver == 'v6':
265 value += 40 # ??? is this correct
266 elif value == 'packets':
267 value = 1
268 elif value == 'src_ip':
269 if ip_ver == 'v4':
270 ip = socket.inet_pton(socket.AF_INET,
271 ip_layer.src)
272 else:
273 ip = socket.inet_pton(socket.AF_INET6,
274 ip_layer.src)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800275 value = int(binascii.hexlify(ip), 16)
Ole Troan5c749732017-03-13 13:39:52 +0100276 elif value == 'dst_ip':
277 if ip_ver == 'v4':
278 ip = socket.inet_pton(socket.AF_INET,
279 ip_layer.dst)
280 else:
281 ip = socket.inet_pton(socket.AF_INET6,
282 ip_layer.dst)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800283 value = int(binascii.hexlify(ip), 16)
Ole Troan5c749732017-03-13 13:39:52 +0100284 elif value == 'sport':
285 value = int(capture[0][UDP].sport)
286 elif value == 'dport':
287 value = int(capture[0][UDP].dport)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800288 self.assertEqual(int(binascii.hexlify(
289 record[field]), 16),
Ole Troan5c749732017-03-13 13:39:52 +0100290 value)
291
292 def verify_cflow_data_notimer(self, decoder, capture, cflows):
293 idx = 0
294 for cflow in cflows:
295 if cflow.haslayer(Data):
296 data = decoder.decode_data_set(cflow.getlayer(Set))
297 else:
298 raise Exception("No CFLOW data")
299
300 for rec in data:
301 p = capture[idx]
302 idx += 1
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800303 self.assertEqual(p[IP].len, int(
304 binascii.hexlify(rec[1]), 16))
305 self.assertEqual(1, int(
306 binascii.hexlify(rec[2]), 16))
Ole Troan5c749732017-03-13 13:39:52 +0100307 self.assertEqual(len(capture), idx)
308
309 def wait_for_cflow_packet(self, collector_intf, set_id=2, timeout=1,
310 expected=True):
311 """ wait for CFLOW packet and verify its correctness
312
313 :param timeout: how long to wait
314
315 :returns: tuple (packet, time spent waiting for packet)
316 """
317 self.logger.info("IPFIX: Waiting for CFLOW packet")
318 deadline = time.time() + timeout
319 counter = 0
320 # self.logger.debug(self.vapi.ppcli("show flow table"))
321 while True:
322 counter += 1
323 # sanity check
324 self.assert_in_range(counter, 0, 100, "number of packets ignored")
325 time_left = deadline - time.time()
326 try:
327 if time_left < 0 and expected:
328 # self.logger.debug(self.vapi.ppcli("show flow table"))
329 raise CaptureTimeoutError(
330 "Packet did not arrive within timeout")
331 p = collector_intf.wait_for_packet(timeout=time_left)
332 except CaptureTimeoutError:
333 if expected:
334 # self.logger.debug(self.vapi.ppcli("show flow table"))
335 raise CaptureTimeoutError(
336 "Packet did not arrive within timeout")
337 else:
338 return
339 if not expected:
340 raise CaptureTimeoutError("Packet arrived even not expected")
341 self.assertEqual(p[Set].setID, set_id)
342 # self.logger.debug(self.vapi.ppcli("show flow table"))
343 self.logger.debug(ppp("IPFIX: Got packet:", p))
344 break
345 return p
346
Ole Troan5c749732017-03-13 13:39:52 +0100347
Andrew Yourtchenko06f32812021-01-14 10:19:08 +0000348@tag_run_solo
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +0000349@tag_fixme_vpp_workers
Ole Troaned929252017-06-13 21:15:40 +0200350class Flowprobe(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +0100351 """Template verification, timer tests"""
352
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800353 @classmethod
354 def setUpClass(cls):
355 super(Flowprobe, cls).setUpClass()
356
357 @classmethod
358 def tearDownClass(cls):
359 super(Flowprobe, cls).tearDownClass()
360
Ole Troan5c749732017-03-13 13:39:52 +0100361 def test_0001(self):
Pavel Kotucek89111d02017-06-12 08:26:13 +0200362 """ timer less than template timeout"""
Ole Troaned929252017-06-13 21:15:40 +0200363 self.logger.info("FFP_TEST_START_0001")
Ole Troan5c749732017-03-13 13:39:52 +0100364 self.pg_enable_capture(self.pg_interfaces)
365 self.pkts = []
366
Pavel Kotucek89111d02017-06-12 08:26:13 +0200367 ipfix = VppCFLOW(test=self, active=2)
Ole Troan5c749732017-03-13 13:39:52 +0100368 ipfix.add_vpp_config()
369
370 ipfix_decoder = IPFIXDecoder()
371 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200372 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +0100373
Ole Troaned929252017-06-13 21:15:40 +0200374 self.create_stream(packets=1)
Pavel Kotucek89111d02017-06-12 08:26:13 +0200375 self.send_packets()
Ole Troaned929252017-06-13 21:15:40 +0200376 capture = self.pg2.get_capture(1)
Ole Troan5c749732017-03-13 13:39:52 +0100377
378 # make sure the one packet we expect actually showed up
Pavel Kotucek89111d02017-06-12 08:26:13 +0200379 cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
Ole Troan5c749732017-03-13 13:39:52 +0100380 self.verify_cflow_data(ipfix_decoder, capture, cflow)
381
382 ipfix.remove_vpp_config()
Ole Troaned929252017-06-13 21:15:40 +0200383 self.logger.info("FFP_TEST_FINISH_0001")
Ole Troan5c749732017-03-13 13:39:52 +0100384
Pavel Kotucek89111d02017-06-12 08:26:13 +0200385 def test_0002(self):
386 """ timer greater than template timeout"""
Ole Troaned929252017-06-13 21:15:40 +0200387 self.logger.info("FFP_TEST_START_0002")
Ole Troan5c749732017-03-13 13:39:52 +0100388 self.pg_enable_capture(self.pg_interfaces)
389 self.pkts = []
390
Pavel Kotucek89111d02017-06-12 08:26:13 +0200391 ipfix = VppCFLOW(test=self, timeout=3, active=4)
Ole Troan5c749732017-03-13 13:39:52 +0100392 ipfix.add_vpp_config()
393
394 ipfix_decoder = IPFIXDecoder()
395 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200396 ipfix.verify_templates()
Ole Troan5c749732017-03-13 13:39:52 +0100397
Pavel Kotucek89111d02017-06-12 08:26:13 +0200398 self.create_stream(packets=2)
399 self.send_packets()
400 capture = self.pg2.get_capture(2)
Ole Troan5c749732017-03-13 13:39:52 +0100401
402 # next set of template packet should arrive after 20 seconds
403 # template packet should arrive within 20 s
Pavel Kotucek89111d02017-06-12 08:26:13 +0200404 templates = ipfix.verify_templates(ipfix_decoder, timeout=5)
Ole Troan5c749732017-03-13 13:39:52 +0100405
406 # make sure the one packet we expect actually showed up
Pavel Kotucek89111d02017-06-12 08:26:13 +0200407 cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
Ole Troan5c749732017-03-13 13:39:52 +0100408 self.verify_cflow_data(ipfix_decoder, capture, cflow)
409
410 ipfix.remove_vpp_config()
Ole Troaned929252017-06-13 21:15:40 +0200411 self.logger.info("FFP_TEST_FINISH_0002")
412
413 def test_cflow_packet(self):
414 """verify cflow packet fields"""
415 self.logger.info("FFP_TEST_START_0000")
416 self.pg_enable_capture(self.pg_interfaces)
417 self.pkts = []
418
419 ipfix = VppCFLOW(test=self, intf='pg8', datapath="ip4",
420 layer='l2 l3 l4', active=2)
421 ipfix.add_vpp_config()
422
423 route_9001 = VppIpRoute(self, "9.0.0.0", 24,
424 [VppRoutePath(self.pg8._remote_hosts[0].ip4,
425 self.pg8.sw_if_index)])
426 route_9001.add_vpp_config()
427
428 ipfix_decoder = IPFIXDecoder()
429 templates = ipfix.verify_templates(ipfix_decoder, count=1)
430
431 self.pkts = [(Ether(dst=self.pg7.local_mac,
432 src=self.pg7.remote_mac) /
433 IP(src=self.pg7.remote_ip4, dst="9.0.0.100") /
434 TCP(sport=1234, dport=4321, flags=80) /
Ole Troan770a0de2019-11-07 13:52:21 +0100435 Raw(b'\xa5' * 100))]
Ole Troaned929252017-06-13 21:15:40 +0200436
437 nowUTC = int(time.time())
438 nowUNIX = nowUTC+2208988800
439 self.send_packets(src_if=self.pg7, dst_if=self.pg8)
440
441 cflow = self.wait_for_cflow_packet(self.collector, templates[0], 10)
442 self.collector.get_capture(2)
443
444 if cflow[0].haslayer(IPFIX):
445 self.assertEqual(cflow[IPFIX].version, 10)
446 self.assertEqual(cflow[IPFIX].observationDomainID, 1)
447 self.assertEqual(cflow[IPFIX].sequenceNumber, 0)
448 self.assertAlmostEqual(cflow[IPFIX].exportTime, nowUTC, delta=5)
449 if cflow.haslayer(Data):
450 record = ipfix_decoder.decode_data_set(cflow[0].getlayer(Set))[0]
451 # ingress interface
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800452 self.assertEqual(int(binascii.hexlify(record[10]), 16), 8)
Ole Troaned929252017-06-13 21:15:40 +0200453 # egress interface
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800454 self.assertEqual(int(binascii.hexlify(record[14]), 16), 9)
Ole Troaned929252017-06-13 21:15:40 +0200455 # packets
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800456 self.assertEqual(int(binascii.hexlify(record[2]), 16), 1)
Ole Troaned929252017-06-13 21:15:40 +0200457 # src mac
Ole Troanb0d83f12019-10-21 23:13:46 +0200458 self.assertEqual(mac_ntop(record[56]), self.pg8.local_mac)
Ole Troaned929252017-06-13 21:15:40 +0200459 # dst mac
Ole Troanb0d83f12019-10-21 23:13:46 +0200460 self.assertEqual(mac_ntop(record[80]), self.pg8.remote_mac)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800461 flowTimestamp = int(binascii.hexlify(record[156]), 16) >> 32
Ole Troaned929252017-06-13 21:15:40 +0200462 # flow start timestamp
463 self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800464 flowTimestamp = int(binascii.hexlify(record[157]), 16) >> 32
Ole Troaned929252017-06-13 21:15:40 +0200465 # flow end timestamp
466 self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
467 # ethernet type
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800468 self.assertEqual(int(binascii.hexlify(record[256]), 16), 8)
Ole Troaned929252017-06-13 21:15:40 +0200469 # src ip
Ole Troanb0d83f12019-10-21 23:13:46 +0200470 self.assertEqual(inet_ntop(socket.AF_INET, record[8]),
471 self.pg7.remote_ip4)
Ole Troaned929252017-06-13 21:15:40 +0200472 # dst ip
Ole Troanb0d83f12019-10-21 23:13:46 +0200473 self.assertEqual(inet_ntop(socket.AF_INET, record[12]),
474 "9.0.0.100")
Ole Troaned929252017-06-13 21:15:40 +0200475 # protocol (TCP)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800476 self.assertEqual(int(binascii.hexlify(record[4]), 16), 6)
Ole Troaned929252017-06-13 21:15:40 +0200477 # src port
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800478 self.assertEqual(int(binascii.hexlify(record[7]), 16), 1234)
Ole Troaned929252017-06-13 21:15:40 +0200479 # dst port
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800480 self.assertEqual(int(binascii.hexlify(record[11]), 16), 4321)
Ole Troaned929252017-06-13 21:15:40 +0200481 # tcp flags
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800482 self.assertEqual(int(binascii.hexlify(record[6]), 16), 80)
Ole Troaned929252017-06-13 21:15:40 +0200483
484 ipfix.remove_vpp_config()
485 self.logger.info("FFP_TEST_FINISH_0000")
Ole Troan5c749732017-03-13 13:39:52 +0100486
Ole Troan5c749732017-03-13 13:39:52 +0100487
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +0000488@tag_fixme_vpp_workers
Pavel Kotucek89111d02017-06-12 08:26:13 +0200489class Datapath(MethodHolder):
490 """collect information on Ethernet, IP4 and IP6 datapath (no timers)"""
Ole Troan5c749732017-03-13 13:39:52 +0100491
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800492 @classmethod
493 def setUpClass(cls):
494 super(Datapath, cls).setUpClass()
495
496 @classmethod
497 def tearDownClass(cls):
498 super(Datapath, cls).tearDownClass()
499
Pavel Kotucek89111d02017-06-12 08:26:13 +0200500 def test_templatesL2(self):
Ole Troan5c749732017-03-13 13:39:52 +0100501 """ verify template on L2 datapath"""
502 self.logger.info("FFP_TEST_START_0000")
503 self.pg_enable_capture(self.pg_interfaces)
504
Pavel Kotucek89111d02017-06-12 08:26:13 +0200505 ipfix = VppCFLOW(test=self, layer='l2')
Ole Troan5c749732017-03-13 13:39:52 +0100506 ipfix.add_vpp_config()
507
508 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400509 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200510 ipfix.verify_templates(timeout=3, count=1)
511 self.collector.get_capture(1)
Ole Troan5c749732017-03-13 13:39:52 +0100512
513 ipfix.remove_vpp_config()
514 self.logger.info("FFP_TEST_FINISH_0000")
515
Pavel Kotucek89111d02017-06-12 08:26:13 +0200516 def test_L2onL2(self):
Ole Troan5c749732017-03-13 13:39:52 +0100517 """ L2 data on L2 datapath"""
518 self.logger.info("FFP_TEST_START_0001")
519 self.pg_enable_capture(self.pg_interfaces)
520 self.pkts = []
521
Pavel Kotucek89111d02017-06-12 08:26:13 +0200522 ipfix = VppCFLOW(test=self, layer='l2')
Ole Troan5c749732017-03-13 13:39:52 +0100523 ipfix.add_vpp_config()
524
525 ipfix_decoder = IPFIXDecoder()
526 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200527 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100528
529 self.create_stream(packets=1)
530 capture = self.send_packets()
531
532 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400533 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200534 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Ole Troan5c749732017-03-13 13:39:52 +0100535 self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
536 {2: 'packets', 256: 8})
Ole Troan5c749732017-03-13 13:39:52 +0100537 self.collector.get_capture(2)
538
539 ipfix.remove_vpp_config()
540 self.logger.info("FFP_TEST_FINISH_0001")
541
Pavel Kotucek89111d02017-06-12 08:26:13 +0200542 def test_L3onL2(self):
Ole Troan5c749732017-03-13 13:39:52 +0100543 """ L3 data on L2 datapath"""
544 self.logger.info("FFP_TEST_START_0002")
545 self.pg_enable_capture(self.pg_interfaces)
546 self.pkts = []
547
Pavel Kotucek89111d02017-06-12 08:26:13 +0200548 ipfix = VppCFLOW(test=self, layer='l3')
Ole Troan5c749732017-03-13 13:39:52 +0100549 ipfix.add_vpp_config()
550
551 ipfix_decoder = IPFIXDecoder()
552 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200553 templates = ipfix.verify_templates(ipfix_decoder, count=2)
Ole Troan5c749732017-03-13 13:39:52 +0100554
555 self.create_stream(packets=1)
556 capture = self.send_packets()
557
558 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400559 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200560 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Ole Troan5c749732017-03-13 13:39:52 +0100561 self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
562 {2: 'packets', 4: 17,
563 8: 'src_ip', 12: 'dst_ip'})
564
Ole Troan5c749732017-03-13 13:39:52 +0100565 self.collector.get_capture(3)
566
567 ipfix.remove_vpp_config()
568 self.logger.info("FFP_TEST_FINISH_0002")
569
Pavel Kotucek89111d02017-06-12 08:26:13 +0200570 def test_L4onL2(self):
Ole Troan5c749732017-03-13 13:39:52 +0100571 """ L4 data on L2 datapath"""
572 self.logger.info("FFP_TEST_START_0003")
573 self.pg_enable_capture(self.pg_interfaces)
574 self.pkts = []
575
Pavel Kotucek89111d02017-06-12 08:26:13 +0200576 ipfix = VppCFLOW(test=self, layer='l4')
Ole Troan5c749732017-03-13 13:39:52 +0100577 ipfix.add_vpp_config()
578
579 ipfix_decoder = IPFIXDecoder()
580 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200581 templates = ipfix.verify_templates(ipfix_decoder, count=2)
Ole Troan5c749732017-03-13 13:39:52 +0100582
583 self.create_stream(packets=1)
584 capture = self.send_packets()
585
586 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400587 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200588 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Ole Troan5c749732017-03-13 13:39:52 +0100589 self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
590 {2: 'packets', 7: 'sport', 11: 'dport'})
591
Ole Troan5c749732017-03-13 13:39:52 +0100592 self.collector.get_capture(3)
593
594 ipfix.remove_vpp_config()
595 self.logger.info("FFP_TEST_FINISH_0003")
596
Pavel Kotucek89111d02017-06-12 08:26:13 +0200597 def test_templatesIp4(self):
Ole Troan5c749732017-03-13 13:39:52 +0100598 """ verify templates on IP4 datapath"""
599 self.logger.info("FFP_TEST_START_0000")
600
601 self.pg_enable_capture(self.pg_interfaces)
602
Pavel Kotucek89111d02017-06-12 08:26:13 +0200603 ipfix = VppCFLOW(test=self, datapath='ip4')
Ole Troan5c749732017-03-13 13:39:52 +0100604 ipfix.add_vpp_config()
605
606 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400607 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +0100608 ipfix.verify_templates(timeout=3, count=1)
609 self.collector.get_capture(1)
610
611 ipfix.remove_vpp_config()
612
613 self.logger.info("FFP_TEST_FINISH_0000")
614
Pavel Kotucek89111d02017-06-12 08:26:13 +0200615 def test_L2onIP4(self):
Ole Troan5c749732017-03-13 13:39:52 +0100616 """ L2 data on IP4 datapath"""
617 self.logger.info("FFP_TEST_START_0001")
618 self.pg_enable_capture(self.pg_interfaces)
619 self.pkts = []
620
Pavel Kotucek89111d02017-06-12 08:26:13 +0200621 ipfix = VppCFLOW(test=self, intf='pg4', layer='l2', datapath='ip4')
Ole Troan5c749732017-03-13 13:39:52 +0100622 ipfix.add_vpp_config()
623
624 ipfix_decoder = IPFIXDecoder()
625 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200626 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100627
628 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
629 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
630
631 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400632 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200633 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Ole Troan5c749732017-03-13 13:39:52 +0100634 self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
635 {2: 'packets', 256: 8})
636
637 # expected two templates and one cflow packet
638 self.collector.get_capture(2)
639
640 ipfix.remove_vpp_config()
641 self.logger.info("FFP_TEST_FINISH_0001")
642
Pavel Kotucek89111d02017-06-12 08:26:13 +0200643 def test_L3onIP4(self):
Ole Troan5c749732017-03-13 13:39:52 +0100644 """ L3 data on IP4 datapath"""
645 self.logger.info("FFP_TEST_START_0002")
646 self.pg_enable_capture(self.pg_interfaces)
647 self.pkts = []
648
Pavel Kotucek89111d02017-06-12 08:26:13 +0200649 ipfix = VppCFLOW(test=self, intf='pg4', layer='l3', datapath='ip4')
Ole Troan5c749732017-03-13 13:39:52 +0100650 ipfix.add_vpp_config()
651
652 ipfix_decoder = IPFIXDecoder()
653 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200654 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100655
656 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
657 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
658
659 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400660 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200661 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Ole Troan5c749732017-03-13 13:39:52 +0100662 self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
663 {1: 'octets', 2: 'packets',
664 8: 'src_ip', 12: 'dst_ip'})
665
666 # expected two templates and one cflow packet
667 self.collector.get_capture(2)
668
669 ipfix.remove_vpp_config()
670 self.logger.info("FFP_TEST_FINISH_0002")
671
Pavel Kotucek89111d02017-06-12 08:26:13 +0200672 def test_L4onIP4(self):
Ole Troan5c749732017-03-13 13:39:52 +0100673 """ L4 data on IP4 datapath"""
674 self.logger.info("FFP_TEST_START_0003")
675 self.pg_enable_capture(self.pg_interfaces)
676 self.pkts = []
677
Pavel Kotucek89111d02017-06-12 08:26:13 +0200678 ipfix = VppCFLOW(test=self, intf='pg4', layer='l4', datapath='ip4')
Ole Troan5c749732017-03-13 13:39:52 +0100679 ipfix.add_vpp_config()
680
681 ipfix_decoder = IPFIXDecoder()
682 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200683 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100684
685 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
686 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
687
688 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400689 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200690 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Ole Troan5c749732017-03-13 13:39:52 +0100691 self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
692 {2: 'packets', 7: 'sport', 11: 'dport'})
693
694 # expected two templates and one cflow packet
695 self.collector.get_capture(2)
696
697 ipfix.remove_vpp_config()
698 self.logger.info("FFP_TEST_FINISH_0003")
699
Pavel Kotucek89111d02017-06-12 08:26:13 +0200700 def test_templatesIP6(self):
Ole Troan5c749732017-03-13 13:39:52 +0100701 """ verify templates on IP6 datapath"""
702 self.logger.info("FFP_TEST_START_0000")
703 self.pg_enable_capture(self.pg_interfaces)
704
Pavel Kotucek89111d02017-06-12 08:26:13 +0200705 ipfix = VppCFLOW(test=self, datapath='ip6')
Ole Troan5c749732017-03-13 13:39:52 +0100706 ipfix.add_vpp_config()
707
708 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200709 ipfix.verify_templates(count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100710 self.collector.get_capture(1)
711
712 ipfix.remove_vpp_config()
713
714 self.logger.info("FFP_TEST_FINISH_0000")
715
Pavel Kotucek89111d02017-06-12 08:26:13 +0200716 def test_L2onIP6(self):
Ole Troan5c749732017-03-13 13:39:52 +0100717 """ L2 data on IP6 datapath"""
718 self.logger.info("FFP_TEST_START_0001")
719 self.pg_enable_capture(self.pg_interfaces)
720 self.pkts = []
721
Pavel Kotucek89111d02017-06-12 08:26:13 +0200722 ipfix = VppCFLOW(test=self, intf='pg6', layer='l2', datapath='ip6')
Ole Troan5c749732017-03-13 13:39:52 +0100723 ipfix.add_vpp_config()
724
725 ipfix_decoder = IPFIXDecoder()
726 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200727 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100728
729 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1,
730 ip_ver='IPv6')
731 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
732
733 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400734 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200735 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Ole Troan5c749732017-03-13 13:39:52 +0100736 self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
737 {2: 'packets', 256: 56710},
738 ip_ver='v6')
739
740 # expected two templates and one cflow packet
741 self.collector.get_capture(2)
742
743 ipfix.remove_vpp_config()
744 self.logger.info("FFP_TEST_FINISH_0001")
745
Pavel Kotucek89111d02017-06-12 08:26:13 +0200746 def test_L3onIP6(self):
Ole Troan5c749732017-03-13 13:39:52 +0100747 """ L3 data on IP6 datapath"""
748 self.logger.info("FFP_TEST_START_0002")
749 self.pg_enable_capture(self.pg_interfaces)
750 self.pkts = []
751
Pavel Kotucek89111d02017-06-12 08:26:13 +0200752 ipfix = VppCFLOW(test=self, intf='pg6', layer='l3', datapath='ip6')
Ole Troan5c749732017-03-13 13:39:52 +0100753 ipfix.add_vpp_config()
754
755 ipfix_decoder = IPFIXDecoder()
756 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200757 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100758
759 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1,
760 ip_ver='IPv6')
761 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
762
763 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400764 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200765 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Ole Troan5c749732017-03-13 13:39:52 +0100766 self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
767 {2: 'packets',
768 27: 'src_ip', 28: 'dst_ip'},
769 ip_ver='v6')
770
771 # expected two templates and one cflow packet
772 self.collector.get_capture(2)
773
774 ipfix.remove_vpp_config()
775 self.logger.info("FFP_TEST_FINISH_0002")
776
Pavel Kotucek89111d02017-06-12 08:26:13 +0200777 def test_L4onIP6(self):
Ole Troan5c749732017-03-13 13:39:52 +0100778 """ L4 data on IP6 datapath"""
779 self.logger.info("FFP_TEST_START_0003")
780 self.pg_enable_capture(self.pg_interfaces)
781 self.pkts = []
782
Pavel Kotucek89111d02017-06-12 08:26:13 +0200783 ipfix = VppCFLOW(test=self, intf='pg6', layer='l4', datapath='ip6')
Ole Troan5c749732017-03-13 13:39:52 +0100784 ipfix.add_vpp_config()
785
786 ipfix_decoder = IPFIXDecoder()
787 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200788 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100789
790 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1,
791 ip_ver='IPv6')
792 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
793
794 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400795 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200796 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Ole Troan5c749732017-03-13 13:39:52 +0100797 self.verify_cflow_data_detail(ipfix_decoder, capture, cflow,
798 {2: 'packets', 7: 'sport', 11: 'dport'},
799 ip_ver='v6')
800
801 # expected two templates and one cflow packet
802 self.collector.get_capture(2)
803
804 ipfix.remove_vpp_config()
805 self.logger.info("FFP_TEST_FINISH_0003")
806
Ole Troan5c749732017-03-13 13:39:52 +0100807 def test_0001(self):
808 """ no timers, one CFLOW packet, 9 Flows inside"""
809 self.logger.info("FFP_TEST_START_0001")
810 self.pg_enable_capture(self.pg_interfaces)
811 self.pkts = []
812
Pavel Kotucek89111d02017-06-12 08:26:13 +0200813 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +0100814 ipfix.add_vpp_config()
815
816 ipfix_decoder = IPFIXDecoder()
817 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200818 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +0100819
820 self.create_stream(packets=9)
821 capture = self.send_packets()
822
823 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400824 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200825 cflow = self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +0100826 self.verify_cflow_data_notimer(ipfix_decoder, capture, [cflow])
Ole Troan5c749732017-03-13 13:39:52 +0100827 self.collector.get_capture(4)
828
829 ipfix.remove_vpp_config()
830 self.logger.info("FFP_TEST_FINISH_0001")
831
832 def test_0002(self):
833 """ no timers, two CFLOW packets (mtu=256), 3 Flows in each"""
834 self.logger.info("FFP_TEST_START_0002")
835 self.pg_enable_capture(self.pg_interfaces)
836 self.pkts = []
837
Pavel Kotucek89111d02017-06-12 08:26:13 +0200838 ipfix = VppCFLOW(test=self, mtu=256)
Ole Troan5c749732017-03-13 13:39:52 +0100839 ipfix.add_vpp_config()
840
841 ipfix_decoder = IPFIXDecoder()
842 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400843 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200844 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +0100845
846 self.create_stream(packets=6)
847 capture = self.send_packets()
848
849 # make sure the one packet we expect actually showed up
850 cflows = []
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400851 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +0100852 cflows.append(self.wait_for_cflow_packet(self.collector,
Pavel Kotucek89111d02017-06-12 08:26:13 +0200853 templates[1]))
Ole Troan5c749732017-03-13 13:39:52 +0100854 cflows.append(self.wait_for_cflow_packet(self.collector,
Pavel Kotucek89111d02017-06-12 08:26:13 +0200855 templates[1]))
Ole Troan5c749732017-03-13 13:39:52 +0100856 self.verify_cflow_data_notimer(ipfix_decoder, capture, cflows)
857 self.collector.get_capture(5)
858
859 ipfix.remove_vpp_config()
860 self.logger.info("FFP_TEST_FINISH_0002")
861
862
Paul Vinciguerradefde0f2018-12-06 07:46:13 -0800863@unittest.skipUnless(running_extended_tests, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +0200864class DisableIPFIX(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +0100865 """Disable IPFIX"""
866
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800867 @classmethod
868 def setUpClass(cls):
869 super(DisableIPFIX, cls).setUpClass()
870
871 @classmethod
872 def tearDownClass(cls):
873 super(DisableIPFIX, cls).tearDownClass()
874
Ole Troan5c749732017-03-13 13:39:52 +0100875 def test_0001(self):
876 """ disable IPFIX after first packets"""
877 self.logger.info("FFP_TEST_START_0001")
878 self.pg_enable_capture(self.pg_interfaces)
879 self.pkts = []
880
Pavel Kotucek89111d02017-06-12 08:26:13 +0200881 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +0100882 ipfix.add_vpp_config()
883
884 ipfix_decoder = IPFIXDecoder()
885 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200886 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +0100887
888 self.create_stream()
889 self.send_packets()
890
891 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400892 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200893 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +0100894 self.collector.get_capture(4)
895
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700896 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +0100897 ipfix.disable_exporter()
898 self.pg_enable_capture([self.collector])
899
900 self.send_packets()
901
902 # make sure no one packet arrived in 1 minute
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400903 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200904 self.wait_for_cflow_packet(self.collector, templates[1],
Ole Troan5c749732017-03-13 13:39:52 +0100905 expected=False)
906 self.collector.get_capture(0)
907
908 ipfix.remove_vpp_config()
909 self.logger.info("FFP_TEST_FINISH_0001")
910
911
Paul Vinciguerradefde0f2018-12-06 07:46:13 -0800912@unittest.skipUnless(running_extended_tests, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +0200913class ReenableIPFIX(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +0100914 """Re-enable IPFIX"""
915
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800916 @classmethod
917 def setUpClass(cls):
918 super(ReenableIPFIX, cls).setUpClass()
919
920 @classmethod
921 def tearDownClass(cls):
922 super(ReenableIPFIX, cls).tearDownClass()
923
Pavel Kotucek89111d02017-06-12 08:26:13 +0200924 def test_0011(self):
Ole Troan5c749732017-03-13 13:39:52 +0100925 """ disable IPFIX after first packets and re-enable after few packets
926 """
927 self.logger.info("FFP_TEST_START_0001")
928 self.pg_enable_capture(self.pg_interfaces)
929 self.pkts = []
930
Pavel Kotucek89111d02017-06-12 08:26:13 +0200931 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +0100932 ipfix.add_vpp_config()
933
934 ipfix_decoder = IPFIXDecoder()
935 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200936 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +0100937
Pavel Kotucek89111d02017-06-12 08:26:13 +0200938 self.create_stream(packets=5)
Ole Troan5c749732017-03-13 13:39:52 +0100939 self.send_packets()
940
941 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400942 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200943 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +0100944 self.collector.get_capture(4)
945
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800946 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +0100947 ipfix.disable_exporter()
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400948 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +0100949 self.pg_enable_capture([self.collector])
950
951 self.send_packets()
952
953 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400954 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200955 self.wait_for_cflow_packet(self.collector, templates[1],
Ole Troan5c749732017-03-13 13:39:52 +0100956 expected=False)
957 self.collector.get_capture(0)
Pavel Kotucek89111d02017-06-12 08:26:13 +0200958 self.pg2.get_capture(5)
Ole Troan5c749732017-03-13 13:39:52 +0100959
960 # enable IPFIX
961 ipfix.enable_exporter()
Ole Troan5c749732017-03-13 13:39:52 +0100962
Pavel Kotucek89111d02017-06-12 08:26:13 +0200963 capture = self.collector.get_capture(4)
964 nr_templates = 0
965 nr_data = 0
966 for p in capture:
967 self.assertTrue(p.haslayer(IPFIX))
968 if p.haslayer(Template):
969 nr_templates += 1
970 self.assertTrue(nr_templates, 3)
971 for p in capture:
972 self.assertTrue(p.haslayer(IPFIX))
973 if p.haslayer(Data):
974 nr_data += 1
975 self.assertTrue(nr_templates, 1)
Ole Troan5c749732017-03-13 13:39:52 +0100976
977 ipfix.remove_vpp_config()
978 self.logger.info("FFP_TEST_FINISH_0001")
979
980
Paul Vinciguerradefde0f2018-12-06 07:46:13 -0800981@unittest.skipUnless(running_extended_tests, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +0200982class DisableFP(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +0100983 """Disable Flowprobe feature"""
984
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800985 @classmethod
986 def setUpClass(cls):
987 super(DisableFP, cls).setUpClass()
988
989 @classmethod
990 def tearDownClass(cls):
991 super(DisableFP, cls).tearDownClass()
992
Ole Troan5c749732017-03-13 13:39:52 +0100993 def test_0001(self):
994 """ disable flowprobe feature after first packets"""
995 self.logger.info("FFP_TEST_START_0001")
996 self.pg_enable_capture(self.pg_interfaces)
997 self.pkts = []
Pavel Kotucek89111d02017-06-12 08:26:13 +0200998 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +0100999 ipfix.add_vpp_config()
1000
1001 ipfix_decoder = IPFIXDecoder()
1002 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001003 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001004
1005 self.create_stream()
1006 self.send_packets()
1007
1008 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001009 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001010 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001011 self.collector.get_capture(4)
1012
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001013 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +01001014 ipfix.disable_flowprobe_feature()
1015 self.pg_enable_capture([self.collector])
1016
1017 self.send_packets()
1018
1019 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001020 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001021 self.wait_for_cflow_packet(self.collector, templates[1],
Ole Troan5c749732017-03-13 13:39:52 +01001022 expected=False)
1023 self.collector.get_capture(0)
1024
1025 ipfix.remove_vpp_config()
1026 self.logger.info("FFP_TEST_FINISH_0001")
1027
1028
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08001029@unittest.skipUnless(running_extended_tests, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001030class ReenableFP(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001031 """Re-enable Flowprobe feature"""
1032
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001033 @classmethod
1034 def setUpClass(cls):
1035 super(ReenableFP, cls).setUpClass()
1036
1037 @classmethod
1038 def tearDownClass(cls):
1039 super(ReenableFP, cls).tearDownClass()
1040
Ole Troan5c749732017-03-13 13:39:52 +01001041 def test_0001(self):
1042 """ disable flowprobe feature after first packets and re-enable
1043 after few packets """
1044 self.logger.info("FFP_TEST_START_0001")
1045 self.pg_enable_capture(self.pg_interfaces)
1046 self.pkts = []
1047
Pavel Kotucek89111d02017-06-12 08:26:13 +02001048 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001049 ipfix.add_vpp_config()
1050
1051 ipfix_decoder = IPFIXDecoder()
1052 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001053 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +01001054 templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
1055
1056 self.create_stream()
1057 self.send_packets()
1058
1059 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001060 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001061 self.wait_for_cflow_packet(self.collector, templates[1], 5)
Ole Troan5c749732017-03-13 13:39:52 +01001062 self.collector.get_capture(4)
1063
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001064 # disable FPP feature
Ole Troan5c749732017-03-13 13:39:52 +01001065 ipfix.disable_flowprobe_feature()
1066 self.pg_enable_capture([self.collector])
1067
1068 self.send_packets()
1069
1070 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001071 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001072 self.wait_for_cflow_packet(self.collector, templates[1], 5,
Ole Troan5c749732017-03-13 13:39:52 +01001073 expected=False)
1074 self.collector.get_capture(0)
1075
1076 # enable FPP feature
1077 ipfix.enable_flowprobe_feature()
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001078 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +01001079 templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
1080
1081 self.send_packets()
1082
1083 # make sure the next packets (templates and data) we expect actually
1084 # showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001085 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001086 self.wait_for_cflow_packet(self.collector, templates[1], 5)
Ole Troan5c749732017-03-13 13:39:52 +01001087 self.collector.get_capture(4)
1088
1089 ipfix.remove_vpp_config()
1090 self.logger.info("FFP_TEST_FINISH_0001")
1091
1092
1093if __name__ == '__main__':
1094 unittest.main(testRunner=VppTestRunner)