blob: 234cb3b55c7b3aa05ca7b4ef1f23c5174c3336c6 [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
Alexander Chernavin120095d2023-10-11 12:15:55 +000014from scapy.contrib.lacp import SlowProtocol, LACP
Ole Troan5c749732017-03-13 13:39:52 +010015
Klement Sekerab23ffd72021-05-31 16:08:53 +020016from config import config
Dave Wallace670724c2022-09-20 21:52:18 -040017from framework import tag_fixme_vpp_workers, tag_fixme_ubuntu2204, tag_fixme_debian11
18from framework import is_distro_ubuntu2204, is_distro_debian11
Klement Sekerab23ffd72021-05-31 16:08:53 +020019from framework import VppTestCase, VppTestRunner
Andrew Yourtchenko06f32812021-01-14 10:19:08 +000020from framework import tag_run_solo
Ole Troan5c749732017-03-13 13:39:52 +010021from vpp_object import VppObject
22from vpp_pg_interface import CaptureTimeoutError
23from util import ppp
24from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
Ole Troaned929252017-06-13 21:15:40 +020025from vpp_ip_route import VppIpRoute, VppRoutePath
Ole Troanb0d83f12019-10-21 23:13:46 +020026from vpp_papi.macaddress import mac_ntop
27from socket import inet_ntop
Ole Troan3013e692019-12-09 15:51:44 +010028from vpp_papi import VppEnum
Ole Troan5c749732017-03-13 13:39:52 +010029
30
Alexander Chernavin6b027cf2023-10-17 08:54:33 +000031TMPL_COMMON_FIELD_COUNT = 6
32TMPL_L2_FIELD_COUNT = 3
33TMPL_L3_FIELD_COUNT = 4
34TMPL_L4_FIELD_COUNT = 3
35
Alexander Chernavin21922ce2023-10-26 11:18:19 +000036IPFIX_TCP_FLAGS_ID = 6
37IPFIX_SRC_TRANS_PORT_ID = 7
38IPFIX_DST_TRANS_PORT_ID = 11
39
40TCP_F_FIN = 0x01
41TCP_F_SYN = 0x02
42TCP_F_RST = 0x04
43TCP_F_PSH = 0x08
44TCP_F_ACK = 0x10
45TCP_F_URG = 0x20
46TCP_F_ECE = 0x40
47TCP_F_CWR = 0x80
48
Alexander Chernavin6b027cf2023-10-17 08:54:33 +000049
Ole Troan5c749732017-03-13 13:39:52 +010050class VppCFLOW(VppObject):
51 """CFLOW object for IPFIX exporter and Flowprobe feature"""
52
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020053 def __init__(
54 self,
55 test,
56 intf="pg2",
57 active=0,
58 passive=0,
59 timeout=100,
60 mtu=1024,
61 datapath="l2",
62 layer="l2 l3 l4",
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +000063 direction="tx",
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020064 ):
Ole Troan5c749732017-03-13 13:39:52 +010065 self._test = test
66 self._intf = intf
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +000067 self._intf_obj = getattr(self._test, intf)
Ole Troan5c749732017-03-13 13:39:52 +010068 self._active = active
69 if passive == 0 or passive < active:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020070 self._passive = active + 1
Ole Troan5c749732017-03-13 13:39:52 +010071 else:
72 self._passive = passive
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020073 self._datapath = datapath # l2 ip4 ip6
74 self._collect = layer # l2 l3 l4
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +000075 self._direction = direction # rx tx both
Ole Troan5c749732017-03-13 13:39:52 +010076 self._timeout = timeout
77 self._mtu = mtu
78 self._configured = False
79
80 def add_vpp_config(self):
81 self.enable_exporter()
Ole Troan3013e692019-12-09 15:51:44 +010082 l2_flag = 0
83 l3_flag = 0
84 l4_flag = 0
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020085 if "l2" in self._collect.lower():
86 l2_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L2
87 if "l3" in self._collect.lower():
88 l3_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L3
89 if "l4" in self._collect.lower():
90 l4_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L4
Alexander Chernavin86c78562022-05-12 14:56:24 +000091 self._test.vapi.flowprobe_set_params(
Ole Troan3013e692019-12-09 15:51:44 +010092 record_flags=(l2_flag | l3_flag | l4_flag),
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020093 active_timer=self._active,
94 passive_timer=self._passive,
95 )
Ole Troan5c749732017-03-13 13:39:52 +010096 self.enable_flowprobe_feature()
97 self._test.vapi.cli("ipfix flush")
98 self._configured = True
99
100 def remove_vpp_config(self):
101 self.disable_exporter()
102 self.disable_flowprobe_feature()
103 self._test.vapi.cli("ipfix flush")
104 self._configured = False
105
106 def enable_exporter(self):
107 self._test.vapi.set_ipfix_exporter(
Jakub Grajciar2f71a882019-10-10 14:21:22 +0200108 collector_address=self._test.pg0.remote_ip4,
109 src_address=self._test.pg0.local_ip4,
Ole Troan5c749732017-03-13 13:39:52 +0100110 path_mtu=self._mtu,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200111 template_interval=self._timeout,
112 )
Ole Troan5c749732017-03-13 13:39:52 +0100113
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000114 def _enable_disable_flowprobe_feature(self, is_add):
115 which_map = {
116 "l2": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_L2,
117 "ip4": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4,
118 "ip6": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP6,
119 }
120 direction_map = {
121 "rx": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_RX,
122 "tx": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
123 "both": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_BOTH,
124 }
125 self._test.vapi.flowprobe_interface_add_del(
126 is_add=is_add,
127 which=which_map[self._datapath],
128 direction=direction_map[self._direction],
129 sw_if_index=self._intf_obj.sw_if_index,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200130 )
Ole Troan5c749732017-03-13 13:39:52 +0100131
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000132 def enable_flowprobe_feature(self):
133 self._enable_disable_flowprobe_feature(is_add=True)
134
Ole Troan5c749732017-03-13 13:39:52 +0100135 def disable_exporter(self):
136 self._test.vapi.cli("set ipfix exporter collector 0.0.0.0")
137
138 def disable_flowprobe_feature(self):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000139 self._enable_disable_flowprobe_feature(is_add=False)
Ole Troan5c749732017-03-13 13:39:52 +0100140
141 def object_id(self):
Paul Vinciguerrae3a0e6e2019-03-14 08:46:52 -0700142 return "ipfix-collector-%s-%s" % (self._src, self.dst)
Ole Troan5c749732017-03-13 13:39:52 +0100143
144 def query_vpp_config(self):
145 return self._configured
146
Alexander Chernavin6b027cf2023-10-17 08:54:33 +0000147 def verify_templates(self, decoder=None, timeout=1, count=3, field_count_in=None):
Ole Troan5c749732017-03-13 13:39:52 +0100148 templates = []
Klement Sekerac4794572021-09-08 15:15:59 +0200149 self._test.assertIn(count, (1, 2, 3))
150 for _ in range(count):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200151 p = self._test.wait_for_cflow_packet(self._test.collector, 2, timeout)
Ole Troan5c749732017-03-13 13:39:52 +0100152 self._test.assertTrue(p.haslayer(IPFIX))
Alexander Chernavin6b027cf2023-10-17 08:54:33 +0000153 self._test.assertTrue(p.haslayer(Template))
154 if decoder is not None:
Ole Troan5c749732017-03-13 13:39:52 +0100155 templates.append(p[Template].templateID)
156 decoder.add_template(p.getlayer(Template))
Alexander Chernavin6b027cf2023-10-17 08:54:33 +0000157 if field_count_in is not None:
158 self._test.assertIn(p[Template].fieldCount, field_count_in)
Ole Troan5c749732017-03-13 13:39:52 +0100159 return templates
160
161
162class MethodHolder(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200163 """Flow-per-packet plugin: test L2, IP4, IP6 reporting"""
Ole Troan5c749732017-03-13 13:39:52 +0100164
165 # Test variables
166 debug_print = False
Pavel Kotucek89111d02017-06-12 08:26:13 +0200167 max_number_of_packets = 10
Ole Troan5c749732017-03-13 13:39:52 +0100168 pkts = []
169
170 @classmethod
171 def setUpClass(cls):
172 """
173 Perform standard class setup (defined by class method setUpClass in
174 class VppTestCase) before running the test case, set test case related
175 variables and configure VPP.
176 """
177 super(MethodHolder, cls).setUpClass()
Dave Wallace670724c2022-09-20 21:52:18 -0400178 if (is_distro_ubuntu2204 == True or is_distro_debian11 == True) and not hasattr(
179 cls, "vpp"
180 ):
181 return
Ole Troan5c749732017-03-13 13:39:52 +0100182 try:
183 # Create pg interfaces
Ole Troaned929252017-06-13 21:15:40 +0200184 cls.create_pg_interfaces(range(9))
Ole Troan5c749732017-03-13 13:39:52 +0100185
186 # Packet sizes
187 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
188
189 # Create BD with MAC learning and unknown unicast flooding disabled
190 # and put interfaces to this BD
Laszlo Kiraly0f8f4352022-09-16 13:20:07 +0200191 cls.vapi.bridge_domain_add_del_v2(
192 bd_id=1, uu_flood=1, learn=1, flood=1, forward=1, is_add=1
193 )
Ole Troana5b2eec2019-03-11 19:23:25 +0100194 cls.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200195 rx_sw_if_index=cls.pg1._sw_if_index, bd_id=1
196 )
Ole Troana5b2eec2019-03-11 19:23:25 +0100197 cls.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200198 rx_sw_if_index=cls.pg2._sw_if_index, bd_id=1
199 )
Ole Troan5c749732017-03-13 13:39:52 +0100200
201 # Set up all interfaces
202 for i in cls.pg_interfaces:
203 i.admin_up()
204
205 cls.pg0.config_ip4()
206 cls.pg0.configure_ipv4_neighbors()
207 cls.collector = cls.pg0
208
209 cls.pg1.config_ip4()
210 cls.pg1.resolve_arp()
211 cls.pg2.config_ip4()
212 cls.pg2.resolve_arp()
213 cls.pg3.config_ip4()
214 cls.pg3.resolve_arp()
215 cls.pg4.config_ip4()
216 cls.pg4.resolve_arp()
Ole Troaned929252017-06-13 21:15:40 +0200217 cls.pg7.config_ip4()
218 cls.pg8.config_ip4()
219 cls.pg8.configure_ipv4_neighbors()
Ole Troan5c749732017-03-13 13:39:52 +0100220
221 cls.pg5.config_ip6()
222 cls.pg5.resolve_ndp()
223 cls.pg5.disable_ipv6_ra()
224 cls.pg6.config_ip6()
225 cls.pg6.resolve_ndp()
226 cls.pg6.disable_ipv6_ra()
227 except Exception:
228 super(MethodHolder, cls).tearDownClass()
229 raise
230
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800231 @classmethod
232 def tearDownClass(cls):
233 super(MethodHolder, cls).tearDownClass()
234
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200235 def create_stream(
236 self, src_if=None, dst_if=None, packets=None, size=None, ip_ver="v4"
237 ):
Ole Troan5c749732017-03-13 13:39:52 +0100238 """Create a packet stream to tickle the plugin
239
240 :param VppInterface src_if: Source interface for packet stream
241 :param VppInterface src_if: Dst interface for packet stream
242 """
243 if src_if is None:
244 src_if = self.pg1
245 if dst_if is None:
246 dst_if = self.pg2
247 self.pkts = []
248 if packets is None:
249 packets = random.randint(1, self.max_number_of_packets)
250 pkt_size = size
251 for p in range(0, packets):
252 if size is None:
253 pkt_size = random.choice(self.pg_if_packet_sizes)
254 info = self.create_packet_info(src_if, dst_if)
255 payload = self.info_to_payload(info)
256 p = Ether(src=src_if.remote_mac, dst=src_if.local_mac)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200257 if ip_ver == "v4":
Ole Troan5c749732017-03-13 13:39:52 +0100258 p /= IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
259 else:
260 p /= IPv6(src=src_if.remote_ip6, dst=dst_if.remote_ip6)
Ole Troaned929252017-06-13 21:15:40 +0200261 p /= UDP(sport=1234, dport=4321)
262 p /= Raw(payload)
Ole Troan5c749732017-03-13 13:39:52 +0100263 info.data = p.copy()
264 self.extend_packet(p, pkt_size)
265 self.pkts.append(p)
266
267 def verify_cflow_data(self, decoder, capture, cflow):
268 octets = 0
269 packets = 0
270 for p in capture:
271 octets += p[IP].len
272 packets += 1
273 if cflow.haslayer(Data):
274 data = decoder.decode_data_set(cflow.getlayer(Set))
275 for record in data:
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800276 self.assertEqual(int(binascii.hexlify(record[1]), 16), octets)
277 self.assertEqual(int(binascii.hexlify(record[2]), 16), packets)
Ole Troan5c749732017-03-13 13:39:52 +0100278
Pavel Kotucek89111d02017-06-12 08:26:13 +0200279 def send_packets(self, src_if=None, dst_if=None):
280 if src_if is None:
281 src_if = self.pg1
282 if dst_if is None:
283 dst_if = self.pg2
284 self.pg_enable_capture([dst_if])
285 src_if.add_stream(self.pkts)
286 self.pg_start()
287 return dst_if.get_capture(len(self.pkts))
288
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200289 def verify_cflow_data_detail(
Alexander Chernavin6b027cf2023-10-17 08:54:33 +0000290 self,
291 decoder,
292 capture,
293 cflow,
294 data_set={1: "octets", 2: "packets"},
295 ip_ver="v4",
296 field_count=None,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200297 ):
Ole Troan5c749732017-03-13 13:39:52 +0100298 if self.debug_print:
Paul Vinciguerra661f91f2018-11-28 19:06:41 -0800299 print(capture[0].show())
Ole Troan5c749732017-03-13 13:39:52 +0100300 if cflow.haslayer(Data):
301 data = decoder.decode_data_set(cflow.getlayer(Set))
302 if self.debug_print:
Paul Vinciguerra661f91f2018-11-28 19:06:41 -0800303 print(data)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200304 if ip_ver == "v4":
Alexander Chernavin120095d2023-10-11 12:15:55 +0000305 ip_layer = capture[0][IP] if capture[0].haslayer(IP) else None
Ole Troan5c749732017-03-13 13:39:52 +0100306 else:
Alexander Chernavin120095d2023-10-11 12:15:55 +0000307 ip_layer = capture[0][IPv6] if capture[0].haslayer(IPv6) else None
Ole Troan5c749732017-03-13 13:39:52 +0100308 if data_set is not None:
309 for record in data:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700310 # skip flow if ingress/egress interface is 0
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800311 if int(binascii.hexlify(record[10]), 16) == 0:
Ole Troan5c749732017-03-13 13:39:52 +0100312 continue
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800313 if int(binascii.hexlify(record[14]), 16) == 0:
Ole Troan5c749732017-03-13 13:39:52 +0100314 continue
315
316 for field in data_set:
Ole Troan5c749732017-03-13 13:39:52 +0100317 value = data_set[field]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200318 if value == "octets":
Ole Troan5c749732017-03-13 13:39:52 +0100319 value = ip_layer.len
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200320 if ip_ver == "v6":
321 value += 40 # ??? is this correct
322 elif value == "packets":
Ole Troan5c749732017-03-13 13:39:52 +0100323 value = 1
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200324 elif value == "src_ip":
325 if ip_ver == "v4":
326 ip = socket.inet_pton(socket.AF_INET, ip_layer.src)
Ole Troan5c749732017-03-13 13:39:52 +0100327 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200328 ip = socket.inet_pton(socket.AF_INET6, ip_layer.src)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800329 value = int(binascii.hexlify(ip), 16)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200330 elif value == "dst_ip":
331 if ip_ver == "v4":
332 ip = socket.inet_pton(socket.AF_INET, ip_layer.dst)
Ole Troan5c749732017-03-13 13:39:52 +0100333 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200334 ip = socket.inet_pton(socket.AF_INET6, ip_layer.dst)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800335 value = int(binascii.hexlify(ip), 16)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200336 elif value == "sport":
Ole Troan5c749732017-03-13 13:39:52 +0100337 value = int(capture[0][UDP].sport)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200338 elif value == "dport":
Ole Troan5c749732017-03-13 13:39:52 +0100339 value = int(capture[0][UDP].dport)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200340 self.assertEqual(
341 int(binascii.hexlify(record[field]), 16), value
342 )
Alexander Chernavin6b027cf2023-10-17 08:54:33 +0000343 if field_count is not None:
344 for record in data:
345 self.assertEqual(len(record), field_count)
Ole Troan5c749732017-03-13 13:39:52 +0100346
347 def verify_cflow_data_notimer(self, decoder, capture, cflows):
348 idx = 0
349 for cflow in cflows:
350 if cflow.haslayer(Data):
351 data = decoder.decode_data_set(cflow.getlayer(Set))
352 else:
353 raise Exception("No CFLOW data")
354
355 for rec in data:
356 p = capture[idx]
357 idx += 1
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200358 self.assertEqual(p[IP].len, int(binascii.hexlify(rec[1]), 16))
359 self.assertEqual(1, int(binascii.hexlify(rec[2]), 16))
Ole Troan5c749732017-03-13 13:39:52 +0100360 self.assertEqual(len(capture), idx)
361
Klement Sekerac4794572021-09-08 15:15:59 +0200362 def wait_for_cflow_packet(self, collector_intf, set_id=2, timeout=1):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200363 """wait for CFLOW packet and verify its correctness
Ole Troan5c749732017-03-13 13:39:52 +0100364
365 :param timeout: how long to wait
366
Ole Troan5c749732017-03-13 13:39:52 +0100367 """
368 self.logger.info("IPFIX: Waiting for CFLOW packet")
Ole Troan5c749732017-03-13 13:39:52 +0100369 # self.logger.debug(self.vapi.ppcli("show flow table"))
Klement Sekerac4794572021-09-08 15:15:59 +0200370 p = collector_intf.wait_for_packet(timeout=timeout)
371 self.assertEqual(p[Set].setID, set_id)
372 # self.logger.debug(self.vapi.ppcli("show flow table"))
373 self.logger.debug(ppp("IPFIX: Got packet:", p))
Ole Troan5c749732017-03-13 13:39:52 +0100374 return p
375
Ole Troan5c749732017-03-13 13:39:52 +0100376
Andrew Yourtchenko06f32812021-01-14 10:19:08 +0000377@tag_run_solo
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +0000378@tag_fixme_vpp_workers
Dave Wallace670724c2022-09-20 21:52:18 -0400379@tag_fixme_ubuntu2204
380@tag_fixme_debian11
Ole Troaned929252017-06-13 21:15:40 +0200381class Flowprobe(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +0100382 """Template verification, timer tests"""
383
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800384 @classmethod
385 def setUpClass(cls):
386 super(Flowprobe, cls).setUpClass()
387
388 @classmethod
389 def tearDownClass(cls):
390 super(Flowprobe, cls).tearDownClass()
391
Ole Troan5c749732017-03-13 13:39:52 +0100392 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200393 """timer less than template timeout"""
Ole Troaned929252017-06-13 21:15:40 +0200394 self.logger.info("FFP_TEST_START_0001")
Ole Troan5c749732017-03-13 13:39:52 +0100395 self.pg_enable_capture(self.pg_interfaces)
396 self.pkts = []
397
Pavel Kotucek89111d02017-06-12 08:26:13 +0200398 ipfix = VppCFLOW(test=self, active=2)
Ole Troan5c749732017-03-13 13:39:52 +0100399 ipfix.add_vpp_config()
400
401 ipfix_decoder = IPFIXDecoder()
402 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200403 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +0100404
Ole Troaned929252017-06-13 21:15:40 +0200405 self.create_stream(packets=1)
Pavel Kotucek89111d02017-06-12 08:26:13 +0200406 self.send_packets()
Ole Troaned929252017-06-13 21:15:40 +0200407 capture = self.pg2.get_capture(1)
Ole Troan5c749732017-03-13 13:39:52 +0100408
409 # make sure the one packet we expect actually showed up
Pavel Kotucek89111d02017-06-12 08:26:13 +0200410 cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
Ole Troan5c749732017-03-13 13:39:52 +0100411 self.verify_cflow_data(ipfix_decoder, capture, cflow)
412
413 ipfix.remove_vpp_config()
Ole Troaned929252017-06-13 21:15:40 +0200414 self.logger.info("FFP_TEST_FINISH_0001")
Ole Troan5c749732017-03-13 13:39:52 +0100415
Pavel Kotucek89111d02017-06-12 08:26:13 +0200416 def test_0002(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200417 """timer greater than template timeout"""
Ole Troaned929252017-06-13 21:15:40 +0200418 self.logger.info("FFP_TEST_START_0002")
Ole Troan5c749732017-03-13 13:39:52 +0100419 self.pg_enable_capture(self.pg_interfaces)
420 self.pkts = []
421
Pavel Kotucek89111d02017-06-12 08:26:13 +0200422 ipfix = VppCFLOW(test=self, timeout=3, active=4)
Ole Troan5c749732017-03-13 13:39:52 +0100423 ipfix.add_vpp_config()
424
425 ipfix_decoder = IPFIXDecoder()
426 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200427 ipfix.verify_templates()
Ole Troan5c749732017-03-13 13:39:52 +0100428
Pavel Kotucek89111d02017-06-12 08:26:13 +0200429 self.create_stream(packets=2)
430 self.send_packets()
431 capture = self.pg2.get_capture(2)
Ole Troan5c749732017-03-13 13:39:52 +0100432
433 # next set of template packet should arrive after 20 seconds
434 # template packet should arrive within 20 s
Pavel Kotucek89111d02017-06-12 08:26:13 +0200435 templates = ipfix.verify_templates(ipfix_decoder, timeout=5)
Ole Troan5c749732017-03-13 13:39:52 +0100436
437 # make sure the one packet we expect actually showed up
Pavel Kotucek89111d02017-06-12 08:26:13 +0200438 cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
Ole Troan5c749732017-03-13 13:39:52 +0100439 self.verify_cflow_data(ipfix_decoder, capture, cflow)
440
441 ipfix.remove_vpp_config()
Ole Troaned929252017-06-13 21:15:40 +0200442 self.logger.info("FFP_TEST_FINISH_0002")
443
444 def test_cflow_packet(self):
445 """verify cflow packet fields"""
446 self.logger.info("FFP_TEST_START_0000")
447 self.pg_enable_capture(self.pg_interfaces)
448 self.pkts = []
449
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200450 ipfix = VppCFLOW(
451 test=self, intf="pg8", datapath="ip4", layer="l2 l3 l4", active=2
452 )
Ole Troaned929252017-06-13 21:15:40 +0200453 ipfix.add_vpp_config()
454
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200455 route_9001 = VppIpRoute(
456 self,
457 "9.0.0.0",
458 24,
459 [VppRoutePath(self.pg8._remote_hosts[0].ip4, self.pg8.sw_if_index)],
460 )
Ole Troaned929252017-06-13 21:15:40 +0200461 route_9001.add_vpp_config()
462
463 ipfix_decoder = IPFIXDecoder()
464 templates = ipfix.verify_templates(ipfix_decoder, count=1)
465
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200466 self.pkts = [
467 (
468 Ether(dst=self.pg7.local_mac, src=self.pg7.remote_mac)
469 / IP(src=self.pg7.remote_ip4, dst="9.0.0.100")
470 / TCP(sport=1234, dport=4321, flags=80)
471 / Raw(b"\xa5" * 100)
472 )
473 ]
Ole Troaned929252017-06-13 21:15:40 +0200474
475 nowUTC = int(time.time())
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200476 nowUNIX = nowUTC + 2208988800
Ole Troaned929252017-06-13 21:15:40 +0200477 self.send_packets(src_if=self.pg7, dst_if=self.pg8)
478
479 cflow = self.wait_for_cflow_packet(self.collector, templates[0], 10)
480 self.collector.get_capture(2)
481
482 if cflow[0].haslayer(IPFIX):
483 self.assertEqual(cflow[IPFIX].version, 10)
484 self.assertEqual(cflow[IPFIX].observationDomainID, 1)
485 self.assertEqual(cflow[IPFIX].sequenceNumber, 0)
486 self.assertAlmostEqual(cflow[IPFIX].exportTime, nowUTC, delta=5)
487 if cflow.haslayer(Data):
488 record = ipfix_decoder.decode_data_set(cflow[0].getlayer(Set))[0]
489 # ingress interface
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800490 self.assertEqual(int(binascii.hexlify(record[10]), 16), 8)
Ole Troaned929252017-06-13 21:15:40 +0200491 # egress interface
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800492 self.assertEqual(int(binascii.hexlify(record[14]), 16), 9)
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000493 # direction
494 self.assertEqual(int(binascii.hexlify(record[61]), 16), 1)
Ole Troaned929252017-06-13 21:15:40 +0200495 # packets
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800496 self.assertEqual(int(binascii.hexlify(record[2]), 16), 1)
Ole Troaned929252017-06-13 21:15:40 +0200497 # src mac
Ole Troanb0d83f12019-10-21 23:13:46 +0200498 self.assertEqual(mac_ntop(record[56]), self.pg8.local_mac)
Ole Troaned929252017-06-13 21:15:40 +0200499 # dst mac
Ole Troanb0d83f12019-10-21 23:13:46 +0200500 self.assertEqual(mac_ntop(record[80]), self.pg8.remote_mac)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800501 flowTimestamp = int(binascii.hexlify(record[156]), 16) >> 32
Ole Troaned929252017-06-13 21:15:40 +0200502 # flow start timestamp
503 self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800504 flowTimestamp = int(binascii.hexlify(record[157]), 16) >> 32
Ole Troaned929252017-06-13 21:15:40 +0200505 # flow end timestamp
506 self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
507 # ethernet type
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800508 self.assertEqual(int(binascii.hexlify(record[256]), 16), 8)
Ole Troaned929252017-06-13 21:15:40 +0200509 # src ip
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200510 self.assertEqual(inet_ntop(socket.AF_INET, record[8]), self.pg7.remote_ip4)
Ole Troaned929252017-06-13 21:15:40 +0200511 # dst ip
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200512 self.assertEqual(inet_ntop(socket.AF_INET, record[12]), "9.0.0.100")
Ole Troaned929252017-06-13 21:15:40 +0200513 # protocol (TCP)
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800514 self.assertEqual(int(binascii.hexlify(record[4]), 16), 6)
Ole Troaned929252017-06-13 21:15:40 +0200515 # src port
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800516 self.assertEqual(int(binascii.hexlify(record[7]), 16), 1234)
Ole Troaned929252017-06-13 21:15:40 +0200517 # dst port
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800518 self.assertEqual(int(binascii.hexlify(record[11]), 16), 4321)
Ole Troaned929252017-06-13 21:15:40 +0200519 # tcp flags
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800520 self.assertEqual(int(binascii.hexlify(record[6]), 16), 80)
Ole Troaned929252017-06-13 21:15:40 +0200521
522 ipfix.remove_vpp_config()
523 self.logger.info("FFP_TEST_FINISH_0000")
Ole Troan5c749732017-03-13 13:39:52 +0100524
Alexander Chernavin21922ce2023-10-26 11:18:19 +0000525 def test_flow_entry_reuse(self):
526 """Verify flow entry reuse doesn't accumulate meta info"""
527 self.pg_enable_capture(self.pg_interfaces)
528 self.pkts = []
529
530 # enable ip4 datapath for an interface
531 # set active and passive timers
532 ipfix = VppCFLOW(
533 test=self,
534 active=2,
535 passive=3,
536 intf="pg3",
537 layer="l3 l4",
538 datapath="ip4",
539 direction="rx",
540 mtu=100,
541 )
542 ipfix.add_vpp_config()
543
544 # template packet should arrive immediately
545 ipfix_decoder = IPFIXDecoder()
546 templates = ipfix.verify_templates(ipfix_decoder, count=1)
547
548 # make a tcp packet
549 self.pkts = [
550 (
551 Ether(src=self.pg3.remote_mac, dst=self.pg4.local_mac)
552 / IP(src=self.pg3.remote_ip4, dst=self.pg4.remote_ip4)
553 / TCP(sport=1234, dport=4321)
554 / Raw(b"\xa5" * 50)
555 )
556 ]
557
558 # send the tcp packet two times, each time with new set of flags
559 tcp_flags = (
560 TCP_F_SYN | TCP_F_ACK,
561 TCP_F_RST | TCP_F_PSH,
562 )
563 for f in tcp_flags:
564 self.pkts[0][TCP].flags = f
565 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
566
567 # verify meta info - packet/octet delta and tcp flags
568 cflow = self.wait_for_cflow_packet(self.collector, templates[0], timeout=6)
569 self.verify_cflow_data(ipfix_decoder, capture, cflow)
570 self.verify_cflow_data_detail(
571 ipfix_decoder,
572 capture,
573 cflow,
574 {
575 IPFIX_TCP_FLAGS_ID: f,
576 IPFIX_SRC_TRANS_PORT_ID: 1234,
577 IPFIX_DST_TRANS_PORT_ID: 4321,
578 },
579 )
580
581 self.collector.get_capture(3)
582
583 # cleanup
584 ipfix.remove_vpp_config()
585
Alexander Chernavin86c78562022-05-12 14:56:24 +0000586 def test_interface_dump(self):
587 """Dump interfaces with IPFIX flow record generation enabled"""
588 self.logger.info("FFP_TEST_START_0003")
589
590 # Enable feature for 3 interfaces
591 ipfix1 = VppCFLOW(test=self, intf="pg1", datapath="l2", direction="rx")
592 ipfix1.add_vpp_config()
593
594 ipfix2 = VppCFLOW(test=self, intf="pg2", datapath="ip4", direction="tx")
595 ipfix2.enable_flowprobe_feature()
596
597 ipfix3 = VppCFLOW(test=self, intf="pg3", datapath="ip6", direction="both")
598 ipfix3.enable_flowprobe_feature()
599
600 # When request "all", dump should contain all enabled interfaces
601 dump = self.vapi.flowprobe_interface_dump()
602 self.assertEqual(len(dump), 3)
603
604 # Verify 1st interface
605 self.assertEqual(dump[0].sw_if_index, self.pg1.sw_if_index)
606 self.assertEqual(
607 dump[0].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_L2
608 )
609 self.assertEqual(
610 dump[0].direction,
611 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_RX,
612 )
613
614 # Verify 2nd interface
615 self.assertEqual(dump[1].sw_if_index, self.pg2.sw_if_index)
616 self.assertEqual(
617 dump[1].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4
618 )
619 self.assertEqual(
620 dump[1].direction,
621 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
622 )
623
624 # Verify 3rd interface
625 self.assertEqual(dump[2].sw_if_index, self.pg3.sw_if_index)
626 self.assertEqual(
627 dump[2].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP6
628 )
629 self.assertEqual(
630 dump[2].direction,
631 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_BOTH,
632 )
633
634 # When request 2nd interface, dump should contain only the specified interface
635 dump = self.vapi.flowprobe_interface_dump(sw_if_index=self.pg2.sw_if_index)
636 self.assertEqual(len(dump), 1)
637
638 # Verify 2nd interface
639 self.assertEqual(dump[0].sw_if_index, self.pg2.sw_if_index)
640 self.assertEqual(
641 dump[0].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4
642 )
643 self.assertEqual(
644 dump[0].direction,
645 VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
646 )
647
648 # When request 99th interface, dump should be empty
649 dump = self.vapi.flowprobe_interface_dump(sw_if_index=99)
650 self.assertEqual(len(dump), 0)
651
652 ipfix1.remove_vpp_config()
653 ipfix2.remove_vpp_config()
654 ipfix3.remove_vpp_config()
655 self.logger.info("FFP_TEST_FINISH_0003")
656
657 def test_get_params(self):
658 """Get IPFIX flow record generation parameters"""
659 self.logger.info("FFP_TEST_START_0004")
660
661 # Enable feature for an interface with custom parameters
662 ipfix = VppCFLOW(test=self, active=20, passive=40, layer="l2 l3 l4")
663 ipfix.add_vpp_config()
664
665 # Get and verify parameters
666 params = self.vapi.flowprobe_get_params()
667 self.assertEqual(params.active_timer, 20)
668 self.assertEqual(params.passive_timer, 40)
669 record_flags = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L2
670 record_flags |= VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L3
671 record_flags |= VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L4
672 self.assertEqual(params.record_flags, record_flags)
673
674 ipfix.remove_vpp_config()
675 self.logger.info("FFP_TEST_FINISH_0004")
676
Ole Troan5c749732017-03-13 13:39:52 +0100677
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000678class DatapathTestsHolder(object):
Pavel Kotucek89111d02017-06-12 08:26:13 +0200679 """collect information on Ethernet, IP4 and IP6 datapath (no timers)"""
Ole Troan5c749732017-03-13 13:39:52 +0100680
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800681 @classmethod
682 def setUpClass(cls):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000683 super(DatapathTestsHolder, cls).setUpClass()
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800684
685 @classmethod
686 def tearDownClass(cls):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000687 super(DatapathTestsHolder, cls).tearDownClass()
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800688
Pavel Kotucek89111d02017-06-12 08:26:13 +0200689 def test_templatesL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200690 """verify template on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100691 self.logger.info("FFP_TEST_START_0000")
692 self.pg_enable_capture(self.pg_interfaces)
693
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000694 ipfix = VppCFLOW(
695 test=self, intf=self.intf1, layer="l2", direction=self.direction
696 )
Ole Troan5c749732017-03-13 13:39:52 +0100697 ipfix.add_vpp_config()
698
699 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400700 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200701 ipfix.verify_templates(timeout=3, count=1)
702 self.collector.get_capture(1)
Ole Troan5c749732017-03-13 13:39:52 +0100703
704 ipfix.remove_vpp_config()
705 self.logger.info("FFP_TEST_FINISH_0000")
706
Pavel Kotucek89111d02017-06-12 08:26:13 +0200707 def test_L2onL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200708 """L2 data on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100709 self.logger.info("FFP_TEST_START_0001")
710 self.pg_enable_capture(self.pg_interfaces)
711 self.pkts = []
712
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000713 ipfix = VppCFLOW(
714 test=self, intf=self.intf1, layer="l2", direction=self.direction
715 )
Ole Troan5c749732017-03-13 13:39:52 +0100716 ipfix.add_vpp_config()
717
718 ipfix_decoder = IPFIXDecoder()
719 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200720 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100721
722 self.create_stream(packets=1)
723 capture = self.send_packets()
724
725 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400726 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200727 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200728 self.verify_cflow_data_detail(
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000729 ipfix_decoder,
730 capture,
731 cflow,
732 {2: "packets", 256: 8, 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200733 )
Ole Troan5c749732017-03-13 13:39:52 +0100734 self.collector.get_capture(2)
735
736 ipfix.remove_vpp_config()
737 self.logger.info("FFP_TEST_FINISH_0001")
738
Pavel Kotucek89111d02017-06-12 08:26:13 +0200739 def test_L3onL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200740 """L3 data on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100741 self.logger.info("FFP_TEST_START_0002")
742 self.pg_enable_capture(self.pg_interfaces)
743 self.pkts = []
744
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000745 ipfix = VppCFLOW(
746 test=self, intf=self.intf1, layer="l3", direction=self.direction
747 )
Ole Troan5c749732017-03-13 13:39:52 +0100748 ipfix.add_vpp_config()
749
750 ipfix_decoder = IPFIXDecoder()
751 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200752 templates = ipfix.verify_templates(ipfix_decoder, count=2)
Ole Troan5c749732017-03-13 13:39:52 +0100753
754 self.create_stream(packets=1)
755 capture = self.send_packets()
756
757 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400758 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200759 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200760 self.verify_cflow_data_detail(
761 ipfix_decoder,
762 capture,
763 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000764 {
765 2: "packets",
766 4: 17,
767 8: "src_ip",
768 12: "dst_ip",
769 61: (self.direction == "tx"),
770 },
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200771 )
Ole Troan5c749732017-03-13 13:39:52 +0100772
Ole Troan5c749732017-03-13 13:39:52 +0100773 self.collector.get_capture(3)
774
775 ipfix.remove_vpp_config()
776 self.logger.info("FFP_TEST_FINISH_0002")
777
Alexander Chernavin6b027cf2023-10-17 08:54:33 +0000778 def test_L234onL2(self):
779 """L2/3/4 data on L2 datapath"""
Alexander Chernavin120095d2023-10-11 12:15:55 +0000780 self.pg_enable_capture(self.pg_interfaces)
781 self.pkts = []
782
783 ipfix = VppCFLOW(
Alexander Chernavin6b027cf2023-10-17 08:54:33 +0000784 test=self, intf=self.intf1, layer="l2 l3 l4", direction=self.direction
Alexander Chernavin120095d2023-10-11 12:15:55 +0000785 )
786 ipfix.add_vpp_config()
787
788 ipfix_decoder = IPFIXDecoder()
789 # template packet should arrive immediately
Alexander Chernavin6b027cf2023-10-17 08:54:33 +0000790 tmpl_l2_field_count = TMPL_COMMON_FIELD_COUNT + TMPL_L2_FIELD_COUNT
791 tmpl_ip_field_count = (
792 TMPL_COMMON_FIELD_COUNT
793 + TMPL_L2_FIELD_COUNT
794 + TMPL_L3_FIELD_COUNT
795 + TMPL_L4_FIELD_COUNT
796 )
797 templates = ipfix.verify_templates(
798 ipfix_decoder,
799 count=3,
800 field_count_in=(tmpl_l2_field_count, tmpl_ip_field_count),
801 )
Alexander Chernavin120095d2023-10-11 12:15:55 +0000802
803 # verify IPv4 and IPv6 flows
804 for ip_ver in ("v4", "v6"):
805 self.create_stream(packets=1, ip_ver=ip_ver)
806 capture = self.send_packets()
807
808 # make sure the one packet we expect actually showed up
809 self.vapi.ipfix_flush()
810 cflow = self.wait_for_cflow_packet(
811 self.collector, templates[1 if ip_ver == "v4" else 2]
812 )
813 src_ip_id = 8 if ip_ver == "v4" else 27
814 dst_ip_id = 12 if ip_ver == "v4" else 28
815 self.verify_cflow_data_detail(
816 ipfix_decoder,
817 capture,
818 cflow,
819 {
820 2: "packets",
821 256: 8 if ip_ver == "v4" else 56710,
822 4: 17,
Alexander Chernavin6b027cf2023-10-17 08:54:33 +0000823 7: "sport",
824 11: "dport",
Alexander Chernavin120095d2023-10-11 12:15:55 +0000825 src_ip_id: "src_ip",
826 dst_ip_id: "dst_ip",
827 61: (self.direction == "tx"),
828 },
829 ip_ver=ip_ver,
Alexander Chernavin6b027cf2023-10-17 08:54:33 +0000830 field_count=tmpl_ip_field_count,
Alexander Chernavin120095d2023-10-11 12:15:55 +0000831 )
832
833 # verify non-IP flow
834 self.pkts = [
835 (
836 Ether(dst=self.pg2.local_mac, src=self.pg1.remote_mac)
837 / SlowProtocol()
838 / LACP()
839 )
840 ]
841 capture = self.send_packets()
842
843 # make sure the one packet we expect actually showed up
844 self.vapi.ipfix_flush()
845 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
846 self.verify_cflow_data_detail(
847 ipfix_decoder,
848 capture,
849 cflow,
850 {2: "packets", 256: 2440, 61: (self.direction == "tx")},
Alexander Chernavin6b027cf2023-10-17 08:54:33 +0000851 field_count=tmpl_l2_field_count,
Alexander Chernavin120095d2023-10-11 12:15:55 +0000852 )
853
854 self.collector.get_capture(6)
855
856 ipfix.remove_vpp_config()
857
Pavel Kotucek89111d02017-06-12 08:26:13 +0200858 def test_L4onL2(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200859 """L4 data on L2 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100860 self.logger.info("FFP_TEST_START_0003")
861 self.pg_enable_capture(self.pg_interfaces)
862 self.pkts = []
863
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000864 ipfix = VppCFLOW(
865 test=self, intf=self.intf1, layer="l4", direction=self.direction
866 )
Ole Troan5c749732017-03-13 13:39:52 +0100867 ipfix.add_vpp_config()
868
869 ipfix_decoder = IPFIXDecoder()
870 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200871 templates = ipfix.verify_templates(ipfix_decoder, count=2)
Ole Troan5c749732017-03-13 13:39:52 +0100872
873 self.create_stream(packets=1)
874 capture = self.send_packets()
875
876 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400877 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200878 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200879 self.verify_cflow_data_detail(
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000880 ipfix_decoder,
881 capture,
882 cflow,
883 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200884 )
Ole Troan5c749732017-03-13 13:39:52 +0100885
Ole Troan5c749732017-03-13 13:39:52 +0100886 self.collector.get_capture(3)
887
888 ipfix.remove_vpp_config()
889 self.logger.info("FFP_TEST_FINISH_0003")
890
Pavel Kotucek89111d02017-06-12 08:26:13 +0200891 def test_templatesIp4(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200892 """verify templates on IP4 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100893 self.logger.info("FFP_TEST_START_0000")
894
895 self.pg_enable_capture(self.pg_interfaces)
896
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000897 ipfix = VppCFLOW(
898 test=self, intf=self.intf1, datapath="ip4", direction=self.direction
899 )
Ole Troan5c749732017-03-13 13:39:52 +0100900 ipfix.add_vpp_config()
901
902 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400903 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +0100904 ipfix.verify_templates(timeout=3, count=1)
905 self.collector.get_capture(1)
906
907 ipfix.remove_vpp_config()
908
909 self.logger.info("FFP_TEST_FINISH_0000")
910
Pavel Kotucek89111d02017-06-12 08:26:13 +0200911 def test_L2onIP4(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200912 """L2 data on IP4 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100913 self.logger.info("FFP_TEST_START_0001")
914 self.pg_enable_capture(self.pg_interfaces)
915 self.pkts = []
916
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000917 ipfix = VppCFLOW(
918 test=self,
919 intf=self.intf2,
920 layer="l2",
921 datapath="ip4",
922 direction=self.direction,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200923 )
Ole Troan5c749732017-03-13 13:39:52 +0100924 ipfix.add_vpp_config()
925
926 ipfix_decoder = IPFIXDecoder()
927 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +0200928 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +0100929
930 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
931 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
932
933 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -0400934 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +0200935 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200936 self.verify_cflow_data_detail(
937 ipfix_decoder,
938 capture,
939 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000940 {2: "packets", 256: 8, 61: (self.direction == "tx")},
941 )
942
943 # expected two templates and one cflow packet
944 self.collector.get_capture(2)
945
946 ipfix.remove_vpp_config()
947 self.logger.info("FFP_TEST_FINISH_0001")
948
949 def test_L3onIP4(self):
950 """L3 data on IP4 datapath"""
951 self.logger.info("FFP_TEST_START_0002")
952 self.pg_enable_capture(self.pg_interfaces)
953 self.pkts = []
954
955 ipfix = VppCFLOW(
956 test=self,
957 intf=self.intf2,
958 layer="l3",
959 datapath="ip4",
960 direction=self.direction,
961 )
962 ipfix.add_vpp_config()
963
964 ipfix_decoder = IPFIXDecoder()
965 # template packet should arrive immediately
966 templates = ipfix.verify_templates(ipfix_decoder, count=1)
967
968 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
969 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
970
971 # make sure the one packet we expect actually showed up
972 self.vapi.ipfix_flush()
973 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
974 self.verify_cflow_data_detail(
975 ipfix_decoder,
976 capture,
977 cflow,
978 {
979 1: "octets",
980 2: "packets",
981 8: "src_ip",
982 12: "dst_ip",
983 61: (self.direction == "tx"),
984 },
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200985 )
Ole Troan5c749732017-03-13 13:39:52 +0100986
987 # expected two templates and one cflow packet
988 self.collector.get_capture(2)
989
990 ipfix.remove_vpp_config()
991 self.logger.info("FFP_TEST_FINISH_0002")
992
Pavel Kotucek89111d02017-06-12 08:26:13 +0200993 def test_L4onIP4(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200994 """L4 data on IP4 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +0100995 self.logger.info("FFP_TEST_START_0003")
996 self.pg_enable_capture(self.pg_interfaces)
997 self.pkts = []
998
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +0000999 ipfix = VppCFLOW(
1000 test=self,
1001 intf=self.intf2,
1002 layer="l4",
1003 datapath="ip4",
1004 direction=self.direction,
1005 )
Ole Troan5c749732017-03-13 13:39:52 +01001006 ipfix.add_vpp_config()
1007
1008 ipfix_decoder = IPFIXDecoder()
1009 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001010 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +01001011
1012 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
1013 capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
1014
1015 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001016 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001017 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001018 self.verify_cflow_data_detail(
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001019 ipfix_decoder,
1020 capture,
1021 cflow,
1022 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001023 )
Ole Troan5c749732017-03-13 13:39:52 +01001024
1025 # expected two templates and one cflow packet
1026 self.collector.get_capture(2)
1027
1028 ipfix.remove_vpp_config()
1029 self.logger.info("FFP_TEST_FINISH_0003")
1030
Pavel Kotucek89111d02017-06-12 08:26:13 +02001031 def test_templatesIP6(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001032 """verify templates on IP6 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +01001033 self.logger.info("FFP_TEST_START_0000")
1034 self.pg_enable_capture(self.pg_interfaces)
1035
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001036 ipfix = VppCFLOW(
1037 test=self, intf=self.intf1, datapath="ip6", direction=self.direction
1038 )
Ole Troan5c749732017-03-13 13:39:52 +01001039 ipfix.add_vpp_config()
1040
1041 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001042 ipfix.verify_templates(count=1)
Ole Troan5c749732017-03-13 13:39:52 +01001043 self.collector.get_capture(1)
1044
1045 ipfix.remove_vpp_config()
1046
1047 self.logger.info("FFP_TEST_FINISH_0000")
1048
Pavel Kotucek89111d02017-06-12 08:26:13 +02001049 def test_L2onIP6(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001050 """L2 data on IP6 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +01001051 self.logger.info("FFP_TEST_START_0001")
1052 self.pg_enable_capture(self.pg_interfaces)
1053 self.pkts = []
1054
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001055 ipfix = VppCFLOW(
1056 test=self,
1057 intf=self.intf3,
1058 layer="l2",
1059 datapath="ip6",
1060 direction=self.direction,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001061 )
Ole Troan5c749732017-03-13 13:39:52 +01001062 ipfix.add_vpp_config()
1063
1064 ipfix_decoder = IPFIXDecoder()
1065 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001066 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +01001067
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001068 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
Ole Troan5c749732017-03-13 13:39:52 +01001069 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
1070
1071 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001072 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001073 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001074 self.verify_cflow_data_detail(
1075 ipfix_decoder,
1076 capture,
1077 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001078 {2: "packets", 256: 56710, 61: (self.direction == "tx")},
1079 ip_ver="v6",
1080 )
1081
1082 # expected two templates and one cflow packet
1083 self.collector.get_capture(2)
1084
1085 ipfix.remove_vpp_config()
1086 self.logger.info("FFP_TEST_FINISH_0001")
1087
1088 def test_L3onIP6(self):
1089 """L3 data on IP6 datapath"""
1090 self.logger.info("FFP_TEST_START_0002")
1091 self.pg_enable_capture(self.pg_interfaces)
1092 self.pkts = []
1093
1094 ipfix = VppCFLOW(
1095 test=self,
1096 intf=self.intf3,
1097 layer="l3",
1098 datapath="ip6",
1099 direction=self.direction,
1100 )
1101 ipfix.add_vpp_config()
1102
1103 ipfix_decoder = IPFIXDecoder()
1104 # template packet should arrive immediately
1105 templates = ipfix.verify_templates(ipfix_decoder, count=1)
1106
1107 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
1108 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
1109
1110 # make sure the one packet we expect actually showed up
1111 self.vapi.ipfix_flush()
1112 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
1113 self.verify_cflow_data_detail(
1114 ipfix_decoder,
1115 capture,
1116 cflow,
1117 {2: "packets", 27: "src_ip", 28: "dst_ip", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001118 ip_ver="v6",
1119 )
Ole Troan5c749732017-03-13 13:39:52 +01001120
1121 # expected two templates and one cflow packet
1122 self.collector.get_capture(2)
1123
1124 ipfix.remove_vpp_config()
1125 self.logger.info("FFP_TEST_FINISH_0002")
1126
Pavel Kotucek89111d02017-06-12 08:26:13 +02001127 def test_L4onIP6(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001128 """L4 data on IP6 datapath"""
Ole Troan5c749732017-03-13 13:39:52 +01001129 self.logger.info("FFP_TEST_START_0003")
1130 self.pg_enable_capture(self.pg_interfaces)
1131 self.pkts = []
1132
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001133 ipfix = VppCFLOW(
1134 test=self,
1135 intf=self.intf3,
1136 layer="l4",
1137 datapath="ip6",
1138 direction=self.direction,
1139 )
Ole Troan5c749732017-03-13 13:39:52 +01001140 ipfix.add_vpp_config()
1141
1142 ipfix_decoder = IPFIXDecoder()
1143 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001144 templates = ipfix.verify_templates(ipfix_decoder, count=1)
Ole Troan5c749732017-03-13 13:39:52 +01001145
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001146 self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
Ole Troan5c749732017-03-13 13:39:52 +01001147 capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)
1148
1149 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001150 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001151 cflow = self.wait_for_cflow_packet(self.collector, templates[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001152 self.verify_cflow_data_detail(
1153 ipfix_decoder,
1154 capture,
1155 cflow,
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001156 {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001157 ip_ver="v6",
1158 )
Ole Troan5c749732017-03-13 13:39:52 +01001159
1160 # expected two templates and one cflow packet
1161 self.collector.get_capture(2)
1162
1163 ipfix.remove_vpp_config()
1164 self.logger.info("FFP_TEST_FINISH_0003")
1165
Ole Troan5c749732017-03-13 13:39:52 +01001166 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001167 """no timers, one CFLOW packet, 9 Flows inside"""
Ole Troan5c749732017-03-13 13:39:52 +01001168 self.logger.info("FFP_TEST_START_0001")
1169 self.pg_enable_capture(self.pg_interfaces)
1170 self.pkts = []
1171
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001172 ipfix = VppCFLOW(test=self, intf=self.intf1, direction=self.direction)
Ole Troan5c749732017-03-13 13:39:52 +01001173 ipfix.add_vpp_config()
1174
1175 ipfix_decoder = IPFIXDecoder()
1176 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001177 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001178
1179 self.create_stream(packets=9)
1180 capture = self.send_packets()
1181
1182 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001183 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001184 cflow = self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001185 self.verify_cflow_data_notimer(ipfix_decoder, capture, [cflow])
Ole Troan5c749732017-03-13 13:39:52 +01001186 self.collector.get_capture(4)
1187
1188 ipfix.remove_vpp_config()
1189 self.logger.info("FFP_TEST_FINISH_0001")
1190
1191 def test_0002(self):
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001192 """no timers, two CFLOW packets (mtu=260), 3 Flows in each"""
Ole Troan5c749732017-03-13 13:39:52 +01001193 self.logger.info("FFP_TEST_START_0002")
1194 self.pg_enable_capture(self.pg_interfaces)
1195 self.pkts = []
1196
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001197 ipfix = VppCFLOW(test=self, intf=self.intf1, direction=self.direction, mtu=260)
Ole Troan5c749732017-03-13 13:39:52 +01001198 ipfix.add_vpp_config()
1199
1200 ipfix_decoder = IPFIXDecoder()
1201 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001202 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001203 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001204
1205 self.create_stream(packets=6)
1206 capture = self.send_packets()
1207
1208 # make sure the one packet we expect actually showed up
1209 cflows = []
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001210 self.vapi.ipfix_flush()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001211 cflows.append(self.wait_for_cflow_packet(self.collector, templates[1]))
1212 cflows.append(self.wait_for_cflow_packet(self.collector, templates[1]))
Ole Troan5c749732017-03-13 13:39:52 +01001213 self.verify_cflow_data_notimer(ipfix_decoder, capture, cflows)
1214 self.collector.get_capture(5)
1215
1216 ipfix.remove_vpp_config()
1217 self.logger.info("FFP_TEST_FINISH_0002")
1218
1219
Alexander Chernavin6f5ddf32022-05-06 11:35:59 +00001220@tag_fixme_vpp_workers
1221class DatapathTx(MethodHolder, DatapathTestsHolder):
1222 """Collect info on Ethernet, IP4 and IP6 datapath (TX) (no timers)"""
1223
1224 intf1 = "pg2"
1225 intf2 = "pg4"
1226 intf3 = "pg6"
1227 direction = "tx"
1228
1229
1230@tag_fixme_vpp_workers
1231class DatapathRx(MethodHolder, DatapathTestsHolder):
1232 """Collect info on Ethernet, IP4 and IP6 datapath (RX) (no timers)"""
1233
1234 intf1 = "pg1"
1235 intf2 = "pg3"
1236 intf3 = "pg5"
1237 direction = "rx"
1238
1239
Klement Sekerab23ffd72021-05-31 16:08:53 +02001240@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001241class DisableIPFIX(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001242 """Disable IPFIX"""
1243
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001244 @classmethod
1245 def setUpClass(cls):
1246 super(DisableIPFIX, cls).setUpClass()
1247
1248 @classmethod
1249 def tearDownClass(cls):
1250 super(DisableIPFIX, cls).tearDownClass()
1251
Ole Troan5c749732017-03-13 13:39:52 +01001252 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001253 """disable IPFIX after first packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001254 self.logger.info("FFP_TEST_START_0001")
1255 self.pg_enable_capture(self.pg_interfaces)
1256 self.pkts = []
1257
Pavel Kotucek89111d02017-06-12 08:26:13 +02001258 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001259 ipfix.add_vpp_config()
1260
1261 ipfix_decoder = IPFIXDecoder()
1262 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001263 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001264
1265 self.create_stream()
1266 self.send_packets()
1267
1268 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001269 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001270 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001271 self.collector.get_capture(4)
1272
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001273 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +01001274 ipfix.disable_exporter()
1275 self.pg_enable_capture([self.collector])
1276
1277 self.send_packets()
1278
1279 # make sure no one packet arrived in 1 minute
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001280 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001281 self.sleep(1, "wait before verifying no packets sent")
1282 self.collector.assert_nothing_captured()
Ole Troan5c749732017-03-13 13:39:52 +01001283
1284 ipfix.remove_vpp_config()
1285 self.logger.info("FFP_TEST_FINISH_0001")
1286
1287
Klement Sekerab23ffd72021-05-31 16:08:53 +02001288@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001289class ReenableIPFIX(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001290 """Re-enable IPFIX"""
1291
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001292 @classmethod
1293 def setUpClass(cls):
1294 super(ReenableIPFIX, cls).setUpClass()
1295
1296 @classmethod
1297 def tearDownClass(cls):
1298 super(ReenableIPFIX, cls).tearDownClass()
1299
Pavel Kotucek89111d02017-06-12 08:26:13 +02001300 def test_0011(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001301 """disable IPFIX after first packets and re-enable after few packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001302 self.logger.info("FFP_TEST_START_0001")
1303 self.pg_enable_capture(self.pg_interfaces)
1304 self.pkts = []
1305
Pavel Kotucek89111d02017-06-12 08:26:13 +02001306 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001307 ipfix.add_vpp_config()
1308
1309 ipfix_decoder = IPFIXDecoder()
1310 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001311 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001312
Pavel Kotucek89111d02017-06-12 08:26:13 +02001313 self.create_stream(packets=5)
Ole Troan5c749732017-03-13 13:39:52 +01001314 self.send_packets()
1315
1316 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001317 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001318 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001319 self.collector.get_capture(4)
1320
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001321 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +01001322 ipfix.disable_exporter()
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001323 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +01001324 self.pg_enable_capture([self.collector])
1325
1326 self.send_packets()
1327
1328 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001329 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001330 self.sleep(1, "wait before verifying no packets sent")
1331 self.collector.assert_nothing_captured()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001332 self.pg2.get_capture(5)
Ole Troan5c749732017-03-13 13:39:52 +01001333
1334 # enable IPFIX
1335 ipfix.enable_exporter()
Ole Troan5c749732017-03-13 13:39:52 +01001336
Pavel Kotucek89111d02017-06-12 08:26:13 +02001337 capture = self.collector.get_capture(4)
1338 nr_templates = 0
1339 nr_data = 0
1340 for p in capture:
1341 self.assertTrue(p.haslayer(IPFIX))
1342 if p.haslayer(Template):
1343 nr_templates += 1
1344 self.assertTrue(nr_templates, 3)
1345 for p in capture:
1346 self.assertTrue(p.haslayer(IPFIX))
1347 if p.haslayer(Data):
1348 nr_data += 1
1349 self.assertTrue(nr_templates, 1)
Ole Troan5c749732017-03-13 13:39:52 +01001350
1351 ipfix.remove_vpp_config()
1352 self.logger.info("FFP_TEST_FINISH_0001")
1353
1354
Klement Sekerab23ffd72021-05-31 16:08:53 +02001355@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001356class DisableFP(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001357 """Disable Flowprobe feature"""
1358
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001359 @classmethod
1360 def setUpClass(cls):
1361 super(DisableFP, cls).setUpClass()
1362
1363 @classmethod
1364 def tearDownClass(cls):
1365 super(DisableFP, cls).tearDownClass()
1366
Ole Troan5c749732017-03-13 13:39:52 +01001367 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001368 """disable flowprobe feature after first packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001369 self.logger.info("FFP_TEST_START_0001")
1370 self.pg_enable_capture(self.pg_interfaces)
1371 self.pkts = []
Pavel Kotucek89111d02017-06-12 08:26:13 +02001372 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001373 ipfix.add_vpp_config()
1374
1375 ipfix_decoder = IPFIXDecoder()
1376 # template packet should arrive immediately
Pavel Kotucek89111d02017-06-12 08:26:13 +02001377 templates = ipfix.verify_templates(ipfix_decoder)
Ole Troan5c749732017-03-13 13:39:52 +01001378
1379 self.create_stream()
1380 self.send_packets()
1381
1382 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001383 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001384 self.wait_for_cflow_packet(self.collector, templates[1])
Ole Troan5c749732017-03-13 13:39:52 +01001385 self.collector.get_capture(4)
1386
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001387 # disable IPFIX
Ole Troan5c749732017-03-13 13:39:52 +01001388 ipfix.disable_flowprobe_feature()
1389 self.pg_enable_capture([self.collector])
1390
1391 self.send_packets()
1392
1393 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001394 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001395 self.sleep(1, "wait before verifying no packets sent")
1396 self.collector.assert_nothing_captured()
Ole Troan5c749732017-03-13 13:39:52 +01001397
1398 ipfix.remove_vpp_config()
1399 self.logger.info("FFP_TEST_FINISH_0001")
1400
Alexander Chernavinf68afe82023-10-03 12:45:51 +00001401 def test_no_leftover_flows_after_disabling(self):
1402 """disable flowprobe feature and expect no leftover flows"""
1403 self.pg_enable_capture(self.pg_interfaces)
1404 self.pkts = []
1405
1406 # enable ip4 datapath for an interface
1407 # set active and passive timers
1408 ipfix = VppCFLOW(
1409 test=self,
1410 active=3,
1411 passive=4,
1412 intf="pg3",
1413 layer="l3",
1414 datapath="ip4",
1415 direction="rx",
1416 mtu=100,
1417 )
1418 ipfix.add_vpp_config()
1419
1420 # template packet should arrive immediately
1421 ipfix.verify_templates(count=1)
1422
1423 # send some ip4 packets
1424 self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=5)
1425 self.send_packets(src_if=self.pg3, dst_if=self.pg4)
1426
1427 # disable feature for the interface
1428 # currently stored ip4 flows should be removed
1429 ipfix.disable_flowprobe_feature()
1430
1431 # no leftover ip4 flows are expected
1432 self.pg_enable_capture([self.collector])
1433 self.sleep(12, "wait for leftover ip4 flows during three passive intervals")
1434 self.collector.assert_nothing_captured()
1435
1436 # cleanup
1437 ipfix.disable_exporter()
1438
Ole Troan5c749732017-03-13 13:39:52 +01001439
Klement Sekerab23ffd72021-05-31 16:08:53 +02001440@unittest.skipUnless(config.extended, "part of extended tests")
Pavel Kotucek89111d02017-06-12 08:26:13 +02001441class ReenableFP(MethodHolder):
Ole Troan5c749732017-03-13 13:39:52 +01001442 """Re-enable Flowprobe feature"""
1443
Paul Vinciguerra8d991d92019-01-25 14:05:48 -08001444 @classmethod
1445 def setUpClass(cls):
1446 super(ReenableFP, cls).setUpClass()
1447
1448 @classmethod
1449 def tearDownClass(cls):
1450 super(ReenableFP, cls).tearDownClass()
1451
Ole Troan5c749732017-03-13 13:39:52 +01001452 def test_0001(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001453 """disable flowprobe feature after first packets and re-enable
1454 after few packets"""
Ole Troan5c749732017-03-13 13:39:52 +01001455 self.logger.info("FFP_TEST_START_0001")
1456 self.pg_enable_capture(self.pg_interfaces)
1457 self.pkts = []
1458
Pavel Kotucek89111d02017-06-12 08:26:13 +02001459 ipfix = VppCFLOW(test=self)
Ole Troan5c749732017-03-13 13:39:52 +01001460 ipfix.add_vpp_config()
1461
1462 ipfix_decoder = IPFIXDecoder()
1463 # template packet should arrive immediately
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001464 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +01001465 templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
1466
1467 self.create_stream()
1468 self.send_packets()
1469
1470 # make sure the one packet we expect actually showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001471 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001472 self.wait_for_cflow_packet(self.collector, templates[1], 5)
Ole Troan5c749732017-03-13 13:39:52 +01001473 self.collector.get_capture(4)
1474
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001475 # disable FPP feature
Ole Troan5c749732017-03-13 13:39:52 +01001476 ipfix.disable_flowprobe_feature()
1477 self.pg_enable_capture([self.collector])
1478
1479 self.send_packets()
1480
1481 # make sure no one packet arrived in active timer span
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001482 self.vapi.ipfix_flush()
Klement Sekerac4794572021-09-08 15:15:59 +02001483 self.sleep(5, "wait before verifying no packets sent")
1484 self.collector.assert_nothing_captured()
Ole Troan5c749732017-03-13 13:39:52 +01001485
1486 # enable FPP feature
1487 ipfix.enable_flowprobe_feature()
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001488 self.vapi.ipfix_flush()
Ole Troan5c749732017-03-13 13:39:52 +01001489 templates = ipfix.verify_templates(ipfix_decoder, timeout=3)
1490
1491 self.send_packets()
1492
1493 # make sure the next packets (templates and data) we expect actually
1494 # showed up
Paul Vinciguerra21b83e92019-06-24 09:55:46 -04001495 self.vapi.ipfix_flush()
Pavel Kotucek89111d02017-06-12 08:26:13 +02001496 self.wait_for_cflow_packet(self.collector, templates[1], 5)
Ole Troan5c749732017-03-13 13:39:52 +01001497 self.collector.get_capture(4)
1498
1499 ipfix.remove_vpp_config()
1500 self.logger.info("FFP_TEST_FINISH_0001")
1501
1502
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001503if __name__ == "__main__":
Ole Troan5c749732017-03-13 13:39:52 +01001504 unittest.main(testRunner=VppTestRunner)