aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Chernavin <achernavin@netgate.com>2023-10-26 11:18:19 +0000
committerDave Wallace <dwallacelf@gmail.com>2023-12-01 19:28:52 +0000
commitb8b02937b1a0ef8b02cc1dcf09e93e512d6fc234 (patch)
treefa84efeee9ebcc6176ba5645ac9cff7ee7f690f1
parent0d7d22cf677c9b88139d907b9c079a7c81afe136 (diff)
flowprobe: fix accumulation of tcp flags in flow entries
Currently, TCP flags of a flow entry don't get reset once the flow is exported (unlike other meta information about a flow - packet delta count and octet delta count). So TCP flags are accumulated as long as the flow is active. When the flow expires, it is exported the last time, and its pool entry is freed for further reuse. The next flow that gets this pool entry will already have non-zero TCP flags. If it's a TCP flow, the flags will keep being accumulated. This might look fine when exported. If it's a non-TCP flow, that will definitely look erroneous. With this fix, reset TCP flags once the flow is exported. Also, cover the reuse case with tests. Type: fix Change-Id: I5f8560afffcfe107909117d3d063e8a69793437e Signed-off-by: Alexander Chernavin <achernavin@netgate.com> (cherry picked from commit 21922cec7339f48989f230248de36a98816c4b1b)
-rw-r--r--src/plugins/flowprobe/node.c1
-rw-r--r--test/test_flowprobe.py74
2 files changed, 75 insertions, 0 deletions
diff --git a/src/plugins/flowprobe/node.c b/src/plugins/flowprobe/node.c
index 8466eda3792..274ea388ccd 100644
--- a/src/plugins/flowprobe/node.c
+++ b/src/plugins/flowprobe/node.c
@@ -740,6 +740,7 @@ flowprobe_export_entry (vlib_main_t * vm, flowprobe_entry_t * e)
e->packetcount = 0;
e->octetcount = 0;
e->last_exported = vlib_time_now (vm);
+ e->prot.tcp.flags = 0;
b0->current_length = offset;
diff --git a/test/test_flowprobe.py b/test/test_flowprobe.py
index 5da0f74944b..234cb3b55c7 100644
--- a/test/test_flowprobe.py
+++ b/test/test_flowprobe.py
@@ -33,6 +33,19 @@ TMPL_L2_FIELD_COUNT = 3
TMPL_L3_FIELD_COUNT = 4
TMPL_L4_FIELD_COUNT = 3
+IPFIX_TCP_FLAGS_ID = 6
+IPFIX_SRC_TRANS_PORT_ID = 7
+IPFIX_DST_TRANS_PORT_ID = 11
+
+TCP_F_FIN = 0x01
+TCP_F_SYN = 0x02
+TCP_F_RST = 0x04
+TCP_F_PSH = 0x08
+TCP_F_ACK = 0x10
+TCP_F_URG = 0x20
+TCP_F_ECE = 0x40
+TCP_F_CWR = 0x80
+
class VppCFLOW(VppObject):
"""CFLOW object for IPFIX exporter and Flowprobe feature"""
@@ -509,6 +522,67 @@ class Flowprobe(MethodHolder):
ipfix.remove_vpp_config()
self.logger.info("FFP_TEST_FINISH_0000")
+ def test_flow_entry_reuse(self):
+ """Verify flow entry reuse doesn't accumulate meta info"""
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pkts = []
+
+ # enable ip4 datapath for an interface
+ # set active and passive timers
+ ipfix = VppCFLOW(
+ test=self,
+ active=2,
+ passive=3,
+ intf="pg3",
+ layer="l3 l4",
+ datapath="ip4",
+ direction="rx",
+ mtu=100,
+ )
+ ipfix.add_vpp_config()
+
+ # template packet should arrive immediately
+ ipfix_decoder = IPFIXDecoder()
+ templates = ipfix.verify_templates(ipfix_decoder, count=1)
+
+ # make a tcp packet
+ self.pkts = [
+ (
+ Ether(src=self.pg3.remote_mac, dst=self.pg4.local_mac)
+ / IP(src=self.pg3.remote_ip4, dst=self.pg4.remote_ip4)
+ / TCP(sport=1234, dport=4321)
+ / Raw(b"\xa5" * 50)
+ )
+ ]
+
+ # send the tcp packet two times, each time with new set of flags
+ tcp_flags = (
+ TCP_F_SYN | TCP_F_ACK,
+ TCP_F_RST | TCP_F_PSH,
+ )
+ for f in tcp_flags:
+ self.pkts[0][TCP].flags = f
+ capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)
+
+ # verify meta info - packet/octet delta and tcp flags
+ cflow = self.wait_for_cflow_packet(self.collector, templates[0], timeout=6)
+ self.verify_cflow_data(ipfix_decoder, capture, cflow)
+ self.verify_cflow_data_detail(
+ ipfix_decoder,
+ capture,
+ cflow,
+ {
+ IPFIX_TCP_FLAGS_ID: f,
+ IPFIX_SRC_TRANS_PORT_ID: 1234,
+ IPFIX_DST_TRANS_PORT_ID: 4321,
+ },
+ )
+
+ self.collector.get_capture(3)
+
+ # cleanup
+ ipfix.remove_vpp_config()
+
def test_interface_dump(self):
"""Dump interfaces with IPFIX flow record generation enabled"""
self.logger.info("FFP_TEST_START_0003")