* [PATCH v1 1/2] dts: update verbose output regex for VXLAN packets
@ 2026-03-12 20:36 Dean Marx
2026-03-12 20:36 ` [PATCH v1 2/2] dts: add VXLAN protocols to flow test suite Dean Marx
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Dean Marx @ 2026-03-12 20:36 UTC (permalink / raw)
To: probb, luca.vizzarro, yoan.picchi, Honnappa.Nagarahalli,
paul.szczepanek
Cc: dev, Dean Marx
The packet regex in extract_verbose_output could not
match verbose output from tunnel protocols like
VXLAN because it did not allow commas. VXLAN
verbose lines contain comma-separated fields,
which caused the regex to fail before reaching
the final field. This silently dropped the entire
packet from the parsed output. Added comma and
dot to the allowed characters in the regex.
Signed-off-by: Dean Marx <dmarx@iol.unh.edu>
---
dts/api/testpmd/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dts/api/testpmd/__init__.py b/dts/api/testpmd/__init__.py
index 703cae487e..bbcec7f969 100644
--- a/dts/api/testpmd/__init__.py
+++ b/dts/api/testpmd/__init__.py
@@ -817,7 +817,7 @@ def extract_verbose_output(output: str) -> list[TestPmdVerbosePacket]:
prev_header: str = ""
iter = re.finditer(
r"(?P<HEADER>(?:port \d+/queue \d+: (?:received|sent) \d+ packets)?)\s*"
- r"(?P<PACKET>src=[\w\s=:-]+?ol_flags: [\w ]+)",
+ r"(?P<PACKET>src=[\w\s=:,.-]+?ol_flags: [\w ]+)",
output,
)
for match in iter:
--
2.52.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v1 2/2] dts: add VXLAN protocols to flow test suite
2026-03-12 20:36 [PATCH v1 1/2] dts: update verbose output regex for VXLAN packets Dean Marx
@ 2026-03-12 20:36 ` Dean Marx
2026-03-16 15:14 ` Andrew Bailey
2026-04-10 14:56 ` Dean Marx
2026-03-16 15:14 ` [PATCH v1 1/2] dts: update verbose output regex for VXLAN packets Andrew Bailey
2026-05-30 20:11 ` [v1,1/2] " Patrick Robb
2 siblings, 2 replies; 6+ messages in thread
From: Dean Marx @ 2026-03-12 20:36 UTC (permalink / raw)
To: probb, luca.vizzarro, yoan.picchi, Honnappa.Nagarahalli,
paul.szczepanek
Cc: dev, Dean Marx
Add VXLAN protocol stacks to the list of test stacks
in the rte_flow test suite. Refactor the generator
to properly construct VXLAN flows and packets.
Signed-off-by: Dean Marx <dmarx@iol.unh.edu>
---
dts/tests/TestSuite_rte_flow.py | 202 ++++++++++++++++++++++++++++----
1 file changed, 180 insertions(+), 22 deletions(-)
diff --git a/dts/tests/TestSuite_rte_flow.py b/dts/tests/TestSuite_rte_flow.py
index 6255e4c36d..eef804e9d2 100644
--- a/dts/tests/TestSuite_rte_flow.py
+++ b/dts/tests/TestSuite_rte_flow.py
@@ -10,7 +10,7 @@
"""
-from dataclasses import dataclass
+from dataclasses import dataclass, field
from itertools import product
from typing import Any, Callable, Optional
@@ -18,6 +18,7 @@
from scapy.layers.inet6 import IPv6
from scapy.layers.l2 import ARP, Dot1Q, Ether
from scapy.layers.sctp import SCTP
+from scapy.layers.vxlan import VXLAN
from scapy.packet import Packet, Raw
from api.capabilities import NicCapability, requires_nic_capability
@@ -50,10 +51,16 @@ class Protocol:
scapy_class: type[Packet]
pattern_name: str
fields: list[PatternField]
+ default_values: dict[str, Any] = field(default_factory=dict)
def build_scapy_layer(self, field_values: dict[str, Any]) -> Packet:
- """Construct a Scapy layer with the given field values."""
- return self.scapy_class(**field_values)
+ """Construct a Scapy layer with the given field values.
+
+ Default values are applied first, then overridden by any
+ explicit field values so test parameters always win.
+ """
+ merged = {**self.default_values, **field_values}
+ return self.scapy_class(**merged)
@dataclass
@@ -125,6 +132,7 @@ class JumpTest:
PROTOCOLS: dict[str, Protocol] = {
+ # -------------------- Base Protocols --------------------
"eth": Protocol(
name="eth",
scapy_class=Ether,
@@ -215,6 +223,89 @@ class JumpTest:
PatternField("op", "opcode", [1, 2]),
],
),
+ # -------------------- VXLAN Outer Protocols --------------------
+ "eth_outer": Protocol(
+ name="eth_outer",
+ scapy_class=Ether,
+ pattern_name="eth",
+ fields=[
+ PatternField("src", "src", ["02:00:00:00:00:00"]),
+ PatternField("dst", "dst", ["02:00:00:00:00:02"]),
+ ],
+ ),
+ "ipv4_outer": Protocol(
+ name="ipv4_outer",
+ scapy_class=IP,
+ pattern_name="ipv4",
+ fields=[
+ PatternField("src", "src", ["10.0.0.1"]),
+ PatternField("dst", "dst", ["10.0.0.2"]),
+ PatternField("ttl", "ttl", [64, 128]),
+ PatternField("tos", "tos", [0, 4]),
+ ],
+ ),
+ "udp_outer": Protocol(
+ name="udp_outer",
+ scapy_class=UDP,
+ pattern_name="udp",
+ fields=[],
+ default_values={"dport": 4789},
+ ),
+ # -------------------- VXLAN Tunnel Header --------------------
+ "vxlan": Protocol(
+ name="vxlan",
+ scapy_class=VXLAN,
+ pattern_name="vxlan",
+ fields=[
+ PatternField("vni", "vni", [42, 100]),
+ ],
+ ),
+ # -------------------- VXLAN Inner Protocols --------------------
+ "eth_inner": Protocol(
+ name="eth_inner",
+ scapy_class=Ether,
+ pattern_name="eth",
+ fields=[
+ PatternField("src", "src", ["02:00:00:00:00:00"]),
+ PatternField("dst", "dst", ["02:00:00:00:00:02"]),
+ ],
+ ),
+ "ipv4_inner": Protocol(
+ name="ipv4_inner",
+ scapy_class=IP,
+ pattern_name="ipv4",
+ fields=[
+ PatternField("src", "src", ["192.168.1.1"]),
+ PatternField("dst", "dst", ["192.168.1.2"]),
+ ],
+ ),
+ "ipv6_inner": Protocol(
+ name="ipv6_inner",
+ scapy_class=IPv6,
+ pattern_name="ipv6",
+ fields=[
+ PatternField("src", "src", ["2001:db8::1"]),
+ PatternField("dst", "dst", ["2001:db8::2"]),
+ ],
+ ),
+ "tcp_inner": Protocol(
+ name="tcp_inner",
+ scapy_class=TCP,
+ pattern_name="tcp",
+ fields=[
+ PatternField("sport", "src", [1234]),
+ PatternField("dport", "dst", [80]),
+ ],
+ ),
+ "udp_inner": Protocol(
+ name="udp_inner",
+ scapy_class=UDP,
+ pattern_name="udp",
+ fields=[
+ PatternField("sport", "src", [5000]),
+ PatternField("dport", "dst", [53]),
+ ],
+ ),
}
@@ -234,6 +325,7 @@ class JumpTest:
}
PROTOCOL_STACKS = [
+ # -------------------- Non-tunnel stacks --------------------
[("eth", True)],
[("eth", False), ("ipv4", True)],
[("eth", False), ("ipv4", True), ("tcp", True)],
@@ -253,6 +345,66 @@ class JumpTest:
[("eth", False), ("vlan", False), ("ipv6", True), ("tcp", True)],
[("eth", False), ("vlan", False), ("ipv6", True), ("udp", True)],
[("eth", False), ("arp", True)],
+ # -------------------- VXLAN tunnel stacks --------------------
+ [
+ ("eth_outer", False),
+ ("ipv4_outer", True),
+ ("udp_outer", False),
+ ("vxlan", True),
+ ("eth_inner", False),
+ ("ipv4_inner", False),
+ ],
+ [
+ ("eth_outer", False),
+ ("ipv4_outer", True),
+ ("udp_outer", False),
+ ("vxlan", True),
+ ("eth_inner", False),
+ ("ipv4_inner", False),
+ ("tcp_inner", False),
+ ],
+ [
+ ("eth_outer", False),
+ ("ipv4_outer", True),
+ ("udp_outer", False),
+ ("vxlan", True),
+ ("eth_inner", False),
+ ("ipv4_inner", False),
+ ("udp_inner", False),
+ ],
+ [
+ ("eth_outer", False),
+ ("ipv4_outer", True),
+ ("udp_outer", False),
+ ("vxlan", True),
+ ("eth_inner", False),
+ ("ipv6_inner", False),
+ ],
+ [
+ ("eth_outer", False),
+ ("ipv4_outer", True),
+ ("udp_outer", False),
+ ("vxlan", True),
+ ("eth_inner", False),
+ ("ipv6_inner", False),
+ ("tcp_inner", False),
+ ],
+ [
+ ("eth_outer", False),
+ ("ipv4_outer", True),
+ ("udp_outer", False),
+ ("vxlan", True),
+ ("eth_inner", False),
+ ("ipv6_inner", False),
+ ("udp_inner", False),
+ ],
+ [
+ ("eth_outer", False),
+ ("ipv4_outer", True),
+ ("udp_outer", False),
+ ("vxlan", True),
+ ("eth_inner", False),
+ ],
]
@@ -304,6 +456,10 @@ def generate(
) -> list[FlowTest]:
"""Generate test cases for patterns matching fields across multiple protocols.
+ Pattern parts are assembled in stack order to preserve positional
+ correctness, which is required for tunnel encapsulations where
+ inner and outer layers share the same pattern_name.
+
Args:
protocol_stack: List of (protocol_name, test_fields) tuples.
If test_fields is True, iterate through field combinations.
@@ -316,15 +472,12 @@ def generate(
List of FlowTest objects ready for execution.
"""
action_spec = self.actions[action_name]
-
- wildcard_protocols = [name for name, test_fields in protocol_stack if not test_fields]
- field_test_protocols = [name for name, test_fields in protocol_stack if test_fields]
all_protocol_names = [name for name, _ in protocol_stack]
-
- wildcard_pattern_parts = [self.protocols[name].pattern_name for name in wildcard_protocols]
+ field_test_protocols = [name for name, test_fields in protocol_stack if test_fields]
if not field_test_protocols:
- pattern = " / ".join(wildcard_pattern_parts)
+ pattern_parts = [self.protocols[name].pattern_name for name, _ in protocol_stack]
+ pattern = " / ".join(pattern_parts)
flow_rule = FlowRule(
direction="ingress",
pattern=[pattern],
@@ -339,7 +492,7 @@ def generate(
packet=packet,
verification_type=action_spec.verification_type,
verification_params=action_spec.build_verification_params(action_value),
- description=" / ".join(wildcard_pattern_parts) + f" -> {action_spec.name}",
+ description=pattern + f" -> {action_spec.name}",
)
]
@@ -354,24 +507,32 @@ def generate(
max_vals = max(len(f_spec.test_parameters) for _, f_spec in field_combo)
for i in range(max_vals):
- field_pattern_parts = []
+ field_value_map: dict[str, tuple[Protocol, PatternField, Any]] = {}
all_field_values: dict[str, dict[str, Any]] = {}
- desc_parts = []
for protocol_spec, field_spec in field_combo:
val = field_spec.test_parameters[i % len(field_spec.test_parameters)]
-
- field_pattern_parts.append(
- f"{protocol_spec.pattern_name} {field_spec.pattern_field} is {val}"
- )
+ field_value_map[protocol_spec.name] = (protocol_spec, field_spec, val)
if protocol_spec.name not in all_field_values:
all_field_values[protocol_spec.name] = {}
all_field_values[protocol_spec.name][field_spec.scapy_field] = val
- desc_parts.append(f"{protocol_spec.name}[{field_spec.scapy_field}={val}]")
+ pattern_parts = []
+ desc_parts = []
+
+ for proto_name, test_fields in protocol_stack:
+ proto_spec = self.protocols[proto_name]
+ if test_fields and proto_name in field_value_map:
+ _, f_spec, val = field_value_map[proto_name]
+ pattern_parts.append(
+ f"{proto_spec.pattern_name} {f_spec.pattern_field} is {val}"
+ )
+ desc_parts.append(f"{proto_spec.name}[{f_spec.scapy_field}={val}]")
+ else:
+ pattern_parts.append(proto_spec.pattern_name)
- full_pattern = " / ".join(wildcard_pattern_parts + field_pattern_parts)
+ full_pattern = " / ".join(pattern_parts)
flow_rule = FlowRule(
direction="ingress",
@@ -384,10 +545,7 @@ def generate(
all_protocol_names, all_field_values, add_payload=True
)
- wildcard_desc = " / ".join(wildcard_pattern_parts)
- field_desc = " / ".join(desc_parts)
- full_desc = f"{wildcard_desc} / {field_desc}" if wildcard_desc else field_desc
-
+ full_desc = " / ".join(desc_parts)
test_cases.append(
FlowTest(
flow_rule=flow_rule,
--
2.52.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v1 2/2] dts: add VXLAN protocols to flow test suite
2026-03-12 20:36 ` [PATCH v1 2/2] dts: add VXLAN protocols to flow test suite Dean Marx
@ 2026-03-16 15:14 ` Andrew Bailey
2026-04-10 14:56 ` Dean Marx
1 sibling, 0 replies; 6+ messages in thread
From: Andrew Bailey @ 2026-03-16 15:14 UTC (permalink / raw)
To: Dean Marx
Cc: probb, luca.vizzarro, yoan.picchi, Honnappa.Nagarahalli,
paul.szczepanek, dev
[-- Attachment #1: Type: text/plain, Size: 49 bytes --]
Reviewed-by: Andrew Bailey <abailey@iol.unh.edu>
[-- Attachment #2: Type: text/html, Size: 138 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v1 1/2] dts: update verbose output regex for VXLAN packets
2026-03-12 20:36 [PATCH v1 1/2] dts: update verbose output regex for VXLAN packets Dean Marx
2026-03-12 20:36 ` [PATCH v1 2/2] dts: add VXLAN protocols to flow test suite Dean Marx
@ 2026-03-16 15:14 ` Andrew Bailey
2026-05-30 20:11 ` [v1,1/2] " Patrick Robb
2 siblings, 0 replies; 6+ messages in thread
From: Andrew Bailey @ 2026-03-16 15:14 UTC (permalink / raw)
To: Dean Marx
Cc: probb, luca.vizzarro, yoan.picchi, Honnappa.Nagarahalli,
paul.szczepanek, dev
[-- Attachment #1: Type: text/plain, Size: 49 bytes --]
Reviewed-by: Andrew Bailey <abailey@iol.unh.edu>
[-- Attachment #2: Type: text/html, Size: 138 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v1 2/2] dts: add VXLAN protocols to flow test suite
2026-03-12 20:36 ` [PATCH v1 2/2] dts: add VXLAN protocols to flow test suite Dean Marx
2026-03-16 15:14 ` Andrew Bailey
@ 2026-04-10 14:56 ` Dean Marx
1 sibling, 0 replies; 6+ messages in thread
From: Dean Marx @ 2026-04-10 14:56 UTC (permalink / raw)
To: probb, luca.vizzarro, yoan.picchi, Honnappa.Nagarahalli,
paul.szczepanek
Cc: dev
Update on this patch:
This is fully functional and tested on a Mellanox CX7. It applies
cleanly on top of the merged flow suite, and can be merged pending any
extra reviews.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [v1,1/2] dts: update verbose output regex for VXLAN packets
2026-03-12 20:36 [PATCH v1 1/2] dts: update verbose output regex for VXLAN packets Dean Marx
2026-03-12 20:36 ` [PATCH v1 2/2] dts: add VXLAN protocols to flow test suite Dean Marx
2026-03-16 15:14 ` [PATCH v1 1/2] dts: update verbose output regex for VXLAN packets Andrew Bailey
@ 2026-05-30 20:11 ` Patrick Robb
2 siblings, 0 replies; 6+ messages in thread
From: Patrick Robb @ 2026-05-30 20:11 UTC (permalink / raw)
To: dmarx
Cc: Honnappa.Nagarahalli, dev, luca.vizzarro, paul.szczepanek, probb,
yoan.picchi, Patrick Robb
Reviewed-by: Patrick Robb <patrickrobb1997@gmail.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-05-30 20:11 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-12 20:36 [PATCH v1 1/2] dts: update verbose output regex for VXLAN packets Dean Marx
2026-03-12 20:36 ` [PATCH v1 2/2] dts: add VXLAN protocols to flow test suite Dean Marx
2026-03-16 15:14 ` Andrew Bailey
2026-04-10 14:56 ` Dean Marx
2026-03-16 15:14 ` [PATCH v1 1/2] dts: update verbose output regex for VXLAN packets Andrew Bailey
2026-05-30 20:11 ` [v1,1/2] " Patrick Robb
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox