* [RFC net-next 0/7] selftests: net: Switch pmtu.sh to use the internal ovs script.
@ 2024-06-13 18:13 Aaron Conole
2024-06-13 18:13 ` [RFC net-next 1/7] selftests: openvswitch: Support explicit tunnel port creation Aaron Conole
` (6 more replies)
0 siblings, 7 replies; 21+ messages in thread
From: Aaron Conole @ 2024-06-13 18:13 UTC (permalink / raw)
To: netdev
Cc: dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Adrian Moreno, Stefano Brivio, Ilya Maximets
Currently, if a user wants to run pmtu.sh and cover all the provided test
cases, they need to install the Open vSwitch userspace utilities. This
dependency is difficult for users as well as CI environments, because the
userspace build and setup may require lots of support and devel packages
to be installed, system setup to be correct, and things like permissions
and selinux policies to be properly configured.
The kernel selftest suite includes an ovs-dpctl.py utility which can
interact with the openvswitch module directly. This lets developers and
CI environments run without needing too many extra dependencies - just
the pyroute2 python package.
This series enhances the ovs-dpctl utility to provide support for set()
and tunnel() flow specifiers, better ipv6 handling support, and the
ability to add tunnel vports, and LWT interfaces. Finally, it modifies
the pmtu.sh script to call the ovs-dpctl.py utility rather than the
typical OVS userspace utilities.
NOTE: This could also be applied as-is. I'm trying to get the vng test
working in my environment, so I submitted as RFC because I didn't
get to test with the config change in 7/7.
Aaron Conole (6):
selftests: openvswitch: Support explicit tunnel port creation.
selftests: openvswitch: Refactor actions parsing.
selftests: openvswitch: Add set() and set_masked() support.
selftests: openvswitch: Add support for tunnel() key.
selftests: openvswitch: Support implicit ipv6 arguments.
selftests: net: Use the provided dpctl rather than the vswitchd for
tests.
selftests: net: add config for openvswitch
.../selftests/net/openvswitch/ovs-dpctl.py | 370 +++++++++++++++---
tools/testing/selftests/net/config | 5 ++++
tools/testing/selftests/net/pmtu.sh | 87 +++-
3 files changed, 394 insertions(+), 68 deletions(-)
--
2.45.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* [RFC net-next 1/7] selftests: openvswitch: Support explicit tunnel port creation.
2024-06-13 18:13 [RFC net-next 0/7] selftests: net: Switch pmtu.sh to use the internal ovs script Aaron Conole
@ 2024-06-13 18:13 ` Aaron Conole
2024-06-16 16:25 ` [ovs-dev] " Simon Horman
2024-06-13 18:13 ` [RFC net-next 2/7] selftests: openvswitch: Refactor actions parsing Aaron Conole
` (5 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Aaron Conole @ 2024-06-13 18:13 UTC (permalink / raw)
To: netdev
Cc: dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Adrian Moreno, Stefano Brivio, Ilya Maximets
The OVS module can operate in conjunction with various types of
tunnel ports. These are created as either explicit tunnel vport
types, OR by creating a tunnel interface which acts as an anchor
for the lightweight tunnel support.
This patch adds the ability to add tunnel ports to an OVS
datapath for testing various scenarios with tunnel ports. With
this addition, the vswitch "plumbing" will at least be able to
push packets around using the tunnel vports. Future patches
will add support for setting required tunnel metadata for lwts
in the datapath. The end goal will be to push packets via these
tunnels, and will be used in an upcoming commit for testing the
path MTU.
Signed-off-by: Aaron Conole <aconole@redhat.com>
---
.../selftests/net/openvswitch/ovs-dpctl.py | 81 +++++++++++++++++--
1 file changed, 75 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index 1dd057afd3fb..56f6bd162d3e 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -10,6 +10,7 @@ import ipaddress
import logging
import multiprocessing
import re
+import socket
import struct
import sys
import time
@@ -29,6 +30,7 @@ try:
from pyroute2.netlink.exceptions import NetlinkError
from pyroute2.netlink.generic import GenericNetlinkSocket
import pyroute2
+ import pyroute2.iproute
except ModuleNotFoundError:
print("Need to install the python pyroute2 package >= 0.6.")
@@ -1617,7 +1619,7 @@ class OvsVport(GenericNetlinkSocket):
("OVS_VPORT_ATTR_PORT_NO", "uint32"),
("OVS_VPORT_ATTR_TYPE", "uint32"),
("OVS_VPORT_ATTR_NAME", "asciiz"),
- ("OVS_VPORT_ATTR_OPTIONS", "none"),
+ ("OVS_VPORT_ATTR_OPTIONS", "vportopts"),
("OVS_VPORT_ATTR_UPCALL_PID", "array(uint32)"),
("OVS_VPORT_ATTR_STATS", "vportstats"),
("OVS_VPORT_ATTR_PAD", "none"),
@@ -1625,6 +1627,13 @@ class OvsVport(GenericNetlinkSocket):
("OVS_VPORT_ATTR_NETNSID", "uint32"),
)
+ class vportopts(nla):
+ nla_map = (
+ ("OVS_TUNNEL_ATTR_UNSPEC", "none"),
+ ("OVS_TUNNEL_ATTR_DST_PORT", "uint16"),
+ ("OVS_TUNNEL_ATTR_EXTENSION", "none"),
+ )
+
class vportstats(nla):
fields = (
("rx_packets", "=Q"),
@@ -1693,7 +1702,7 @@ class OvsVport(GenericNetlinkSocket):
raise ne
return reply
- def attach(self, dpindex, vport_ifname, ptype):
+ def attach(self, dpindex, vport_ifname, ptype, dport, lwt):
msg = OvsVport.ovs_vport_msg()
msg["cmd"] = OVS_VPORT_CMD_NEW
@@ -1702,12 +1711,43 @@ class OvsVport(GenericNetlinkSocket):
msg["dpifindex"] = dpindex
port_type = OvsVport.str_to_type(ptype)
- msg["attrs"].append(["OVS_VPORT_ATTR_TYPE", port_type])
msg["attrs"].append(["OVS_VPORT_ATTR_NAME", vport_ifname])
msg["attrs"].append(
["OVS_VPORT_ATTR_UPCALL_PID", [self.upcall_packet.epid]]
)
+ TUNNEL_DEFAULTS = [("geneve", 6081),
+ ("vxlan", 4798)]
+
+ for tnl in TUNNEL_DEFAULTS:
+ if ptype == tnl[0]:
+ if not dport:
+ dport = tnl[1]
+
+ if not lwt:
+ vportopt = OvsVport.ovs_vport_msg.vportopts()
+ vportopt["attrs"].append(
+ ["OVS_TUNNEL_ATTR_DST_PORT", socket.htons(dport)]
+ )
+ msg["attrs"].append(
+ ["OVS_VPORT_ATTR_OPTIONS", vportopt]
+ )
+ else:
+ port_type = OvsVport.OVS_VPORT_TYPE_NETDEV
+ ipr = pyroute2.iproute.IPRoute()
+
+ if tnl[0] == "geneve":
+ ipr.link("add", ifname=vport_ifname, kind=tnl[0],
+ geneve_port=dport,
+ geneve_collect_metadata=True,
+ geneve_udp_zero_csum6_rx=1)
+ elif tnl[0] == "vxlan":
+ ipr.link("add", ifname=vport_ifname, kind=tnl[0],
+ vxlan_learning=0, vxlan_collect_metadata=1,
+ vxlan_udp_zero_csum6_rx=1, vxlan_port=dport)
+ break
+ msg["attrs"].append(["OVS_VPORT_ATTR_TYPE", port_type])
+
try:
reply = self.nlm_request(
msg, msg_type=self.prid, msg_flags=NLM_F_REQUEST | NLM_F_ACK
@@ -2053,12 +2093,19 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()):
for iface in ndb.interfaces:
rep = vpl.info(iface.ifname, ifindex)
if rep is not None:
+ opts = ""
+ vpo = rep.get_attr("OVS_VPORT_ATTR_OPTIONS")
+ if vpo:
+ dpo = vpo.get_attr("OVS_TUNNEL_ATTR_DST_PORT")
+ if dpo:
+ opts += " tnl-dport:%s" % socket.ntohs(dpo)
print(
- " port %d: %s (%s)"
+ " port %d: %s (%s%s)"
% (
rep.get_attr("OVS_VPORT_ATTR_PORT_NO"),
rep.get_attr("OVS_VPORT_ATTR_NAME"),
OvsVport.type_to_str(rep.get_attr("OVS_VPORT_ATTR_TYPE")),
+ opts,
)
)
@@ -2120,12 +2167,30 @@ def main(argv):
"--ptype",
type=str,
default="netdev",
- choices=["netdev", "internal"],
+ choices=["netdev", "internal", "geneve", "vxlan"],
help="Interface type (default netdev)",
)
+ addifcmd.add_argument(
+ "-p",
+ "--dport",
+ type=int,
+ default=0,
+ help="Destination port (0 for default)"
+ )
+ addifcmd.add_argument(
+ "-l",
+ "--lwt",
+ type=bool,
+ default=True,
+ help="Use LWT infrastructure instead of vport (default true)."
+ )
delifcmd = subparsers.add_parser("del-if")
delifcmd.add_argument("dpname", help="Datapath Name")
delifcmd.add_argument("delif", help="Interface name for adding")
+ delifcmd.add_argument("-d",
+ "--dellink",
+ type=bool, default=False,
+ help="Delete the link as well.")
dumpflcmd = subparsers.add_parser("dump-flows")
dumpflcmd.add_argument("dumpdp", help="Datapath Name")
@@ -2186,7 +2251,8 @@ def main(argv):
print("DP '%s' not found." % args.dpname)
return 1
dpindex = rep["dpifindex"]
- rep = ovsvp.attach(rep["dpifindex"], args.addif, args.ptype)
+ rep = ovsvp.attach(rep["dpifindex"], args.addif, args.ptype,
+ args.dport, args.lwt)
msg = "vport '%s'" % args.addif
if rep and rep["header"]["error"] is None:
msg += " added."
@@ -2207,6 +2273,9 @@ def main(argv):
msg += " removed."
else:
msg += " failed to remove."
+ if args.dellink:
+ ipr = pyroute2.iproute.IPRoute()
+ ipr.link("del", index=ipr.link_lookup(ifname=args.delif)[0])
elif hasattr(args, "dumpdp"):
rep = ovsdp.info(args.dumpdp, 0)
if rep is None:
--
2.45.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [RFC net-next 2/7] selftests: openvswitch: Refactor actions parsing.
2024-06-13 18:13 [RFC net-next 0/7] selftests: net: Switch pmtu.sh to use the internal ovs script Aaron Conole
2024-06-13 18:13 ` [RFC net-next 1/7] selftests: openvswitch: Support explicit tunnel port creation Aaron Conole
@ 2024-06-13 18:13 ` Aaron Conole
2024-06-16 16:29 ` [ovs-dev] " Simon Horman
2024-06-13 18:13 ` [RFC net-next 3/7] selftests: openvswitch: Add set() and set_masked() support Aaron Conole
` (4 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Aaron Conole @ 2024-06-13 18:13 UTC (permalink / raw)
To: netdev
Cc: dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Adrian Moreno, Stefano Brivio, Ilya Maximets
Until recently, the ovs-dpctl utility was used with a limited actions set
and didn't need to have support for multiple similar actions. However,
when adding support for tunnels, it will be important to support multiple
set() actions in a single flow. When printing these actions, the existing
code will be unable to print all of the sets - it will only print the
first.
Refactor this code to be easier to read and support multiple actions of the
same type in an action list.
Signed-off-by: Aaron Conole <aconole@redhat.com>
---
.../selftests/net/openvswitch/ovs-dpctl.py | 45 ++++++++++---------
1 file changed, 23 insertions(+), 22 deletions(-)
diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index 56f6bd162d3e..73768f3af6e5 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -439,32 +439,30 @@ class ovsactions(nla):
def dpstr(self, more=False):
print_str = ""
- for field in self.nla_map:
+ for field in self["attrs"]:
if field[1] == "none" or self.get_attr(field[0]) is None:
continue
if print_str != "":
print_str += ","
- if field[1] == "uint32":
- if field[0] == "OVS_ACTION_ATTR_OUTPUT":
- print_str += "%d" % int(self.get_attr(field[0]))
- elif field[0] == "OVS_ACTION_ATTR_RECIRC":
- print_str += "recirc(0x%x)" % int(self.get_attr(field[0]))
- elif field[0] == "OVS_ACTION_ATTR_TRUNC":
- print_str += "trunc(%d)" % int(self.get_attr(field[0]))
- elif field[0] == "OVS_ACTION_ATTR_DROP":
- print_str += "drop(%d)" % int(self.get_attr(field[0]))
- elif field[1] == "flag":
- if field[0] == "OVS_ACTION_ATTR_CT_CLEAR":
- print_str += "ct_clear"
- elif field[0] == "OVS_ACTION_ATTR_POP_VLAN":
- print_str += "pop_vlan"
- elif field[0] == "OVS_ACTION_ATTR_POP_ETH":
- print_str += "pop_eth"
- elif field[0] == "OVS_ACTION_ATTR_POP_NSH":
- print_str += "pop_nsh"
- elif field[0] == "OVS_ACTION_ATTR_POP_MPLS":
- print_str += "pop_mpls"
+ if field[0] == "OVS_ACTION_ATTR_OUTPUT":
+ print_str += "%d" % int(self.get_attr(field[0]))
+ elif field[0] == "OVS_ACTION_ATTR_RECIRC":
+ print_str += "recirc(0x%x)" % int(self.get_attr(field[0]))
+ elif field[0] == "OVS_ACTION_ATTR_TRUNC":
+ print_str += "trunc(%d)" % int(self.get_attr(field[0]))
+ elif field[0] == "OVS_ACTION_ATTR_DROP":
+ print_str += "drop(%d)" % int(self.get_attr(field[0]))
+ elif field[0] == "OVS_ACTION_ATTR_CT_CLEAR":
+ print_str += "ct_clear"
+ elif field[0] == "OVS_ACTION_ATTR_POP_VLAN":
+ print_str += "pop_vlan"
+ elif field[0] == "OVS_ACTION_ATTR_POP_ETH":
+ print_str += "pop_eth"
+ elif field[0] == "OVS_ACTION_ATTR_POP_NSH":
+ print_str += "pop_nsh"
+ elif field[0] == "OVS_ACTION_ATTR_POP_MPLS":
+ print_str += "pop_mpls"
else:
datum = self.get_attr(field[0])
if field[0] == "OVS_ACTION_ATTR_CLONE":
@@ -472,7 +470,10 @@ class ovsactions(nla):
print_str += datum.dpstr(more)
print_str += ")"
else:
- print_str += datum.dpstr(more)
+ try:
+ print_str += datum.dpstr(more)
+ except:
+ print_str += "{ATTR: %s not decoded}" % field[0]
return print_str
--
2.45.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [RFC net-next 3/7] selftests: openvswitch: Add set() and set_masked() support.
2024-06-13 18:13 [RFC net-next 0/7] selftests: net: Switch pmtu.sh to use the internal ovs script Aaron Conole
2024-06-13 18:13 ` [RFC net-next 1/7] selftests: openvswitch: Support explicit tunnel port creation Aaron Conole
2024-06-13 18:13 ` [RFC net-next 2/7] selftests: openvswitch: Refactor actions parsing Aaron Conole
@ 2024-06-13 18:13 ` Aaron Conole
2024-06-16 16:29 ` [ovs-dev] " Simon Horman
2024-06-17 12:18 ` Adrián Moreno
2024-06-13 18:13 ` [RFC net-next 4/7] selftests: openvswitch: Add support for tunnel() key Aaron Conole
` (3 subsequent siblings)
6 siblings, 2 replies; 21+ messages in thread
From: Aaron Conole @ 2024-06-13 18:13 UTC (permalink / raw)
To: netdev
Cc: dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Adrian Moreno, Stefano Brivio, Ilya Maximets
These will be used in upcoming commits to set specific attributes for
interacting with tunnels. Since set() will use the key parsing routine, we
also make sure to prepend it with an open paren, for the action parsing to
properly understand it.
Signed-off-by: Aaron Conole <aconole@redhat.com>
---
.../selftests/net/openvswitch/ovs-dpctl.py | 39 +++++++++++++++++--
1 file changed, 35 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index 73768f3af6e5..fee64c31d4d4 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -284,7 +284,7 @@ class ovsactions(nla):
("OVS_ACTION_ATTR_UNSPEC", "none"),
("OVS_ACTION_ATTR_OUTPUT", "uint32"),
("OVS_ACTION_ATTR_USERSPACE", "userspace"),
- ("OVS_ACTION_ATTR_SET", "none"),
+ ("OVS_ACTION_ATTR_SET", "ovskey"),
("OVS_ACTION_ATTR_PUSH_VLAN", "none"),
("OVS_ACTION_ATTR_POP_VLAN", "flag"),
("OVS_ACTION_ATTR_SAMPLE", "none"),
@@ -292,7 +292,7 @@ class ovsactions(nla):
("OVS_ACTION_ATTR_HASH", "none"),
("OVS_ACTION_ATTR_PUSH_MPLS", "none"),
("OVS_ACTION_ATTR_POP_MPLS", "flag"),
- ("OVS_ACTION_ATTR_SET_MASKED", "none"),
+ ("OVS_ACTION_ATTR_SET_MASKED", "ovskey"),
("OVS_ACTION_ATTR_CT", "ctact"),
("OVS_ACTION_ATTR_TRUNC", "uint32"),
("OVS_ACTION_ATTR_PUSH_ETH", "none"),
@@ -469,6 +469,14 @@ class ovsactions(nla):
print_str += "clone("
print_str += datum.dpstr(more)
print_str += ")"
+ elif field[0] == "OVS_ACTION_ATTR_SET" or \
+ field[0] == "OVS_ACTION_ATTR_SET_MASKED":
+ print_str += "set"
+ if field[0] == "OVS_ACTION_ATTR_SET_MASKED":
+ print_str += "_masked"
+ print_str += "("
+ print_str += datum.dpstr(more)
+ print_str += ")"
else:
try:
print_str += datum.dpstr(more)
@@ -547,6 +555,25 @@ class ovsactions(nla):
self["attrs"].append(("OVS_ACTION_ATTR_CLONE", subacts))
actstr = actstr[parsedLen:]
parsed = True
+ elif parse_starts_block(actstr, "set(", False):
+ parencount += 1
+ k = ovskey()
+ actstr = actstr[len("set("):]
+ actstr = k.parse(actstr, None)
+ self["attrs"].append(("OVS_ACTION_ATTR_SET", k))
+ if not actstr.startswith(")"):
+ actstr = ")" + actstr
+ parsed = True
+ elif parse_starts_block(actstr, "set_masked(", False):
+ parencount += 1
+ k = ovskey()
+ m = ovskey()
+ actstr = actstr[len("set_masked("):]
+ actstr = k.parse(actstr, m)
+ self["attrs"].append(("OVS_ACTION_ATTR_SET_MASKED", [k, m]))
+ if not actstr.startswith(")"):
+ actstr = ")" + actstr
+ parsed = True
elif parse_starts_block(actstr, "ct(", False):
parencount += 1
actstr = actstr[len("ct(") :]
@@ -1312,7 +1339,7 @@ class ovskey(nla):
mask["attrs"].append([field[0], m])
self["attrs"].append([field[0], k])
- flowstr = flowstr[strspn(flowstr, "),") :]
+ flowstr = flowstr[strspn(flowstr, "), ") :]
return flowstr
@@ -1898,7 +1925,11 @@ class OvsFlow(GenericNetlinkSocket):
):
print_str += "drop"
else:
- print_str += actsmsg.dpstr(more)
+ if type(actsmsg) == "list":
+ for act in actsmsg:
+ print_str += act.dpstr(more)
+ else:
+ print_str += actsmsg.dpstr(more)
return print_str
--
2.45.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [RFC net-next 4/7] selftests: openvswitch: Add support for tunnel() key.
2024-06-13 18:13 [RFC net-next 0/7] selftests: net: Switch pmtu.sh to use the internal ovs script Aaron Conole
` (2 preceding siblings ...)
2024-06-13 18:13 ` [RFC net-next 3/7] selftests: openvswitch: Add set() and set_masked() support Aaron Conole
@ 2024-06-13 18:13 ` Aaron Conole
2024-06-16 16:27 ` [ovs-dev] " Simon Horman
2024-06-13 18:13 ` [RFC net-next 5/7] selftests: openvswitch: Support implicit ipv6 arguments Aaron Conole
` (2 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Aaron Conole @ 2024-06-13 18:13 UTC (permalink / raw)
To: netdev
Cc: dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Adrian Moreno, Stefano Brivio, Ilya Maximets
This will be used when setting details about the tunnel to use as
transport. There is a difference between the ODP format between tunnel():
the 'key' flag is not actually a flag field, so we don't support it in the
same way that the vswitchd userspace supports displaying it.
Signed-off-by: Aaron Conole <aconole@redhat.com>
---
.../selftests/net/openvswitch/ovs-dpctl.py | 164 +++++++++++++++++-
1 file changed, 162 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index fee64c31d4d4..5545e5cab1d6 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -705,7 +705,7 @@ class ovskey(nla):
("OVS_KEY_ATTR_ARP", "ovs_key_arp"),
("OVS_KEY_ATTR_ND", "ovs_key_nd"),
("OVS_KEY_ATTR_SKB_MARK", "uint32"),
- ("OVS_KEY_ATTR_TUNNEL", "none"),
+ ("OVS_KEY_ATTR_TUNNEL", "ovs_key_tunnel"),
("OVS_KEY_ATTR_SCTP", "ovs_key_sctp"),
("OVS_KEY_ATTR_TCP_FLAGS", "be16"),
("OVS_KEY_ATTR_DP_HASH", "uint32"),
@@ -1265,6 +1265,165 @@ class ovskey(nla):
init=init,
)
+ class ovs_key_tunnel(nla):
+ nla_flags = NLA_F_NESTED
+
+ nla_map = (
+ ("OVS_TUNNEL_KEY_ATTR_ID", "be64"),
+ ("OVS_TUNNEL_KEY_ATTR_IPV4_SRC", "ipaddr"),
+ ("OVS_TUNNEL_KEY_ATTR_IPV4_DST", "ipaddr"),
+ ("OVS_TUNNEL_KEY_ATTR_TOS", "uint8"),
+ ("OVS_TUNNEL_KEY_ATTR_TTL", "uint8"),
+ ("OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT", "flag"),
+ ("OVS_TUNNEL_KEY_ATTR_CSUM", "flag"),
+ ("OVS_TUNNEL_KEY_ATTR_OAM", "flag"),
+ ("OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS", "array(uint32)"),
+ ("OVS_TUNNEL_KEY_ATTR_TP_SRC", "be16"),
+ ("OVS_TUNNEL_KEY_ATTR_TP_DST", "be16"),
+ ("OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS", "none"),
+ ("OVS_TUNNEL_KEY_ATTR_IPV6_SRC", "ipaddr"),
+ ("OVS_TUNNEL_KEY_ATTR_IPV6_DST", "ipaddr"),
+ ("OVS_TUNNEL_KEY_ATTR_PAD", "none"),
+ ("OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS", "none"),
+ ("OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE", "flag"),
+ )
+
+ def parse(self, flowstr, mask=None):
+ if not flowstr.startswith("tunnel("):
+ return None, None
+
+ k = ovskey.ovs_key_tunnel()
+ if mask is not None:
+ mask = ovskey.ovs_key_tunnel()
+
+ flowstr = flowstr[len("tunnel("):]
+
+ v6_address = None
+
+ fields = [
+ ("tun_id=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_ID",
+ 0xffffffffffffffff, None, None),
+
+ ("src=", r"([0-9a-fA-F\.]+)", str,
+ "OVS_TUNNEL_KEY_ATTR_IPV4_SRC", "255.255.255.255", "0.0.0.0",
+ False),
+ ("dst=", r"([0-9a-fA-F\.]+)", str,
+ "OVS_TUNNEL_KEY_ATTR_IPV4_DST", "255.255.255.255", "0.0.0.0",
+ False),
+
+ ("ipv6_src=", r"([0-9a-fA-F:]+)", str,
+ "OVS_TUNNEL_KEY_ATTR_IPV6_SRC",
+ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "::", True),
+ ("ipv6_dst=", r"([0-9a-fA-F:]+)", str,
+ "OVS_TUNNEL_KEY_ATTR_IPV6_DST",
+ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "::", True),
+
+ ("tos=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TOS", 255, 0,
+ None),
+ ("ttl=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TTL", 255, 0,
+ None),
+
+ ("tp_src=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TP_SRC",
+ 65535, 0, None),
+ ("tp_dst=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TP_DST",
+ 65535, 0, None),
+ ]
+
+ forced_include = ["OVS_TUNNEL_KEY_ATTR_TTL"]
+
+ for prefix, regex, typ, attr_name, mask_val, default_val, v46_flag in fields:
+ flowstr, value = parse_extract_field(flowstr, prefix, regex, typ, False)
+ if not attr_name:
+ raise Exception("Bad list value in tunnel fields")
+
+ if value is None and attr_name in forced_include:
+ value = default_val
+ mask_val = default_val
+
+ if value is not None:
+ if v6_address is None and v46_flag is not None:
+ v6_address = v46_flag
+ if v6_address is not None and v46_flag is not None \
+ and v46_flag != v6_address:
+ raise ValueError("Cannot mix v6 and v4 addresses")
+ k["attrs"].append([attr_name, value])
+ if mask is not None:
+ mask["attrs"].append([attr_name, mask_val])
+ else:
+ if v6_address is not None and v46_flag is not None \
+ and v46_flag != v6_address:
+ continue
+ if v6_address is None and v46_flag is not None:
+ continue
+ if mask is not None:
+ mask["attrs"].append([attr_name, default_val])
+
+ if k["attrs"][0][0] != "OVS_TUNNEL_KEY_ATTR_ID":
+ raise ValueError("Needs a tunid set")
+
+ if flowstr.startswith("flags("):
+ flowstr = flowstr[len("flags("):]
+ flagspos = flowstr.find(")")
+ flags = flowstr[:flagspos]
+ flowstr = flowstr[flagspos + 1:]
+
+ flag_attrs = {
+ "df": "OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT",
+ "csum": "OVS_TUNNEL_KEY_ATTR_CSUM",
+ "oam": "OVS_TUNNEL_KEY_ATTR_OAM"
+ }
+
+ for flag in flags.split("|"):
+ if flag in flag_attrs:
+ k["attrs"].append([flag_attrs[flag], True])
+ if mask is not None:
+ mask["attrs"].append([flag_attrs[flag], True])
+
+ flowstr = flowstr[strspn(flowstr, ", ") :]
+ return flowstr, k, mask
+
+ def dpstr(self, mask=None, more=False):
+ printstr = "tunnel("
+
+ flagsattrs = []
+ for k in self["attrs"]:
+ noprint = False
+ if k[0] == "OVS_TUNNEL_KEY_ATTR_ID":
+ print_str += "tun_id=%d" % k[1]
+ elif k[0] == "OVS_TUNNEL_KEY_ATTR_IPV4_SRC":
+ print_str += "src=%s" % k[1]
+ elif k[0] == "OVS_TUNNEL_KEY_ATTR_IPV4_DST":
+ print_str += "dst=%s" % k[1]
+ elif k[0] == "OVS_TUNNEL_KEY_ATTR_IPV6_SRC":
+ print_str += "ipv6_src=%s" % k[1]
+ elif k[0] == "OVS_TUNNEL_KEY_ATTR_IPV6_DST":
+ print_str += "ipv6_dst=%s" % k[1]
+ elif k[0] == "OVS_TUNNEL_KEY_ATTR_TOS":
+ print_str += "tos=%d" % k[1]
+ elif k[0] == "OVS_TUNNEL_KEY_ATTR_TTL":
+ print_str += "ttl=%d" % k[1]
+ elif k[0] == "OVS_TUNNEL_KEY_ATTR_TP_SRC":
+ print_str += "tp_src=%d" % k[1]
+ elif k[0] == "OVS_TUNNEL_KEY_ATTR_TP_DST":
+ print_str += "tp_dst=%d" % k[1]
+ elif k[0] == "OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT":
+ noprint = True
+ flagsattrs.append("df")
+ elif k[0] == "OVS_TUNNEL_KEY_ATTR_CSUM":
+ noprint = True
+ flagsattrs.append("csum")
+ elif k[0] == "OVS_TUNNEL_KEY_ATTR_OAM":
+ noprint = True
+ flagsattrs.append("oam")
+
+ if not noprint:
+ print_str += ","
+
+ if len(flagsattrs):
+ printstr += "flags(" + "|".join(flagsattrs) + ")"
+ printstr += ")"
+ return printstr
+
class ovs_key_mpls(nla):
fields = (("lse", ">I"),)
@@ -1273,6 +1432,7 @@ class ovskey(nla):
("OVS_KEY_ATTR_PRIORITY", "skb_priority", intparse),
("OVS_KEY_ATTR_SKB_MARK", "skb_mark", intparse),
("OVS_KEY_ATTR_RECIRC_ID", "recirc_id", intparse),
+ ("OVS_KEY_ATTR_TUNNEL", "tunnel", ovskey.ovs_key_tunnel),
("OVS_KEY_ATTR_DP_HASH", "dp_hash", intparse),
("OVS_KEY_ATTR_CT_STATE", "ct_state", parse_ct_state),
("OVS_KEY_ATTR_CT_ZONE", "ct_zone", intparse),
@@ -1745,7 +1905,7 @@ class OvsVport(GenericNetlinkSocket):
)
TUNNEL_DEFAULTS = [("geneve", 6081),
- ("vxlan", 4798)]
+ ("vxlan", 4789)]
for tnl in TUNNEL_DEFAULTS:
if ptype == tnl[0]:
--
2.45.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [RFC net-next 5/7] selftests: openvswitch: Support implicit ipv6 arguments.
2024-06-13 18:13 [RFC net-next 0/7] selftests: net: Switch pmtu.sh to use the internal ovs script Aaron Conole
` (3 preceding siblings ...)
2024-06-13 18:13 ` [RFC net-next 4/7] selftests: openvswitch: Add support for tunnel() key Aaron Conole
@ 2024-06-13 18:13 ` Aaron Conole
2024-06-16 16:28 ` [ovs-dev] " Simon Horman
2024-06-13 18:13 ` [RFC net-next 6/7] selftests: net: Use the provided dpctl rather than the vswitchd for tests Aaron Conole
2024-06-13 18:13 ` [RFC net-next 7/7] selftests: net: add config for openvswitch Aaron Conole
6 siblings, 1 reply; 21+ messages in thread
From: Aaron Conole @ 2024-06-13 18:13 UTC (permalink / raw)
To: netdev
Cc: dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Adrian Moreno, Stefano Brivio, Ilya Maximets
The current iteration of IPv6 support requires explicit fields to be set
in addition to not properly support the actual IPv6 addresses properly.
With this change, make it so that the ipv6() bare option is usable to
create wildcarded flows to match broad swaths of ipv6 traffic.
Signed-off-by: Aaron Conole <aconole@redhat.com>
---
.../selftests/net/openvswitch/ovs-dpctl.py | 43 ++++++++++++-------
1 file changed, 28 insertions(+), 15 deletions(-)
diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index 5545e5cab1d6..2577a06c58cf 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -200,6 +200,19 @@ def convert_ipv4(data):
return int(ipaddress.IPv4Address(ip)), int(ipaddress.IPv4Address(mask))
+def convert_ipv6(data):
+ ip, _, mask = data.partition('/')
+
+ if not ip:
+ ip = mask = 0
+ elif not mask:
+ mask = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
+ elif mask.isdigit():
+ mask = ipaddress.IPv6Network("::/" + mask).hostmask
+
+ return ipaddress.IPv6Address(ip).packed, ipaddress.IPv6Address(mask).packed
+
+
def convert_int(size):
def convert_int_sized(data):
value, _, mask = data.partition('/')
@@ -937,21 +950,21 @@ class ovskey(nla):
"src",
"src",
lambda x: str(ipaddress.IPv6Address(x)),
- lambda x: int.from_bytes(x, "big"),
- lambda x: ipaddress.IPv6Address(x),
+ lambda x: ipaddress.IPv6Address(x).packed if x else 0,
+ convert_ipv6,
),
(
"dst",
"dst",
lambda x: str(ipaddress.IPv6Address(x)),
- lambda x: int.from_bytes(x, "big"),
- lambda x: ipaddress.IPv6Address(x),
+ lambda x: ipaddress.IPv6Address(x).packed if x else 0,
+ convert_ipv6,
),
- ("label", "label", "%d", int),
- ("proto", "proto", "%d", int),
- ("tclass", "tclass", "%d", int),
- ("hlimit", "hlimit", "%d", int),
- ("frag", "frag", "%d", int),
+ ("label", "label", "%d", lambda x: int(x) if x else 0),
+ ("proto", "proto", "%d", lambda x: int(x) if x else 0),
+ ("tclass", "tclass", "%d", lambda x: int(x) if x else 0),
+ ("hlimit", "hlimit", "%d", lambda x: int(x) if x else 0),
+ ("frag", "frag", "%d", lambda x: int(x) if x else 0),
)
def __init__(
@@ -1148,8 +1161,8 @@ class ovskey(nla):
(
"target",
"target",
- lambda x: str(ipaddress.IPv6Address(x)),
- lambda x: int.from_bytes(x, "big"),
+ lambda x: ipaddress.IPv6Address(x).packed,
+ convert_ipv6,
),
("sll", "sll", macstr, lambda x: int.from_bytes(x, "big")),
("tll", "tll", macstr, lambda x: int.from_bytes(x, "big")),
@@ -1233,14 +1246,14 @@ class ovskey(nla):
(
"src",
"src",
- lambda x: str(ipaddress.IPv6Address(x)),
- lambda x: int.from_bytes(x, "big", convertmac),
+ lambda x: ipaddress.IPv6Address(x).packed,
+ convert_ipv6,
),
(
"dst",
"dst",
- lambda x: str(ipaddress.IPv6Address(x)),
- lambda x: int.from_bytes(x, "big"),
+ lambda x: ipaddress.IPv6Address(x).packed,
+ convert_ipv6,
),
("tp_src", "tp_src", "%d", int),
("tp_dst", "tp_dst", "%d", int),
--
2.45.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [RFC net-next 6/7] selftests: net: Use the provided dpctl rather than the vswitchd for tests.
2024-06-13 18:13 [RFC net-next 0/7] selftests: net: Switch pmtu.sh to use the internal ovs script Aaron Conole
` (4 preceding siblings ...)
2024-06-13 18:13 ` [RFC net-next 5/7] selftests: openvswitch: Support implicit ipv6 arguments Aaron Conole
@ 2024-06-13 18:13 ` Aaron Conole
2024-06-13 20:37 ` Stefano Brivio
2024-06-13 18:13 ` [RFC net-next 7/7] selftests: net: add config for openvswitch Aaron Conole
6 siblings, 1 reply; 21+ messages in thread
From: Aaron Conole @ 2024-06-13 18:13 UTC (permalink / raw)
To: netdev
Cc: dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Adrian Moreno, Stefano Brivio, Ilya Maximets
The current pmtu test infrastucture requires an installed copy of the
ovs-vswitchd userspace. This means that any automated or constrained
environments may not have the requisite tools to run the tests. However,
the pmtu tests don't require any special classifier processing. Indeed
they are only using the vswitchd in the most basic mode - as a NORMAL
switch.
However, the ovs-dpctl kernel utility can now program all the needed basic
flows to allow traffic to traverse the tunnels and provide support for at
least testing some basic pmtu scenarios. More complicated flow pipelines
can be added to the internal ovs test infrastructure, but that is work for
the future. For now, enable the most common cases - wide mega flows with
no other prerequisites.
Signed-off-by: Aaron Conole <aconole@redhat.com>
---
tools/testing/selftests/net/pmtu.sh | 87 ++++++++++++++++++++++-------
1 file changed, 67 insertions(+), 20 deletions(-)
diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
index cfc84958025a..7f4f35d88dcc 100755
--- a/tools/testing/selftests/net/pmtu.sh
+++ b/tools/testing/selftests/net/pmtu.sh
@@ -846,22 +846,73 @@ setup_ovs_vxlan_or_geneve() {
type="${1}"
a_addr="${2}"
b_addr="${3}"
+ dport="6081"
if [ "${type}" = "vxlan" ]; then
+ dport="4789"
opts="${opts} ttl 64 dstport 4789"
opts_b="local ${b_addr}"
fi
- run_cmd ovs-vsctl add-port ovs_br0 ${type}_a -- \
- set interface ${type}_a type=${type} \
- options:remote_ip=${b_addr} options:key=1 options:csum=true || return 1
-
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-if ovs_br0 ${type}_a -t ${type}
run_cmd ${ns_b} ip link add ${type}_b type ${type} id 1 ${opts_b} remote ${a_addr} ${opts} || return 1
run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ${type}_b
run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ${type}_b
+ run_cmd ip link set ${type}_a up
run_cmd ${ns_b} ip link set ${type}_b up
+
+ ports=$(python3 ./openvswitch/ovs-dpctl.py show)
+ br0_port=$(echo "$ports" | grep -E "\sovs_br0" | sed -e 's@port @@' | cut -d: -f1 | xargs)
+ type_a_port=$(echo "$ports" | grep ${type}_a | sed -e 's@port @@' | cut -d: -f1 | xargs)
+ veth_a_port=$(echo "$ports" | grep veth_A | sed -e 's@port @@' | cut -d: -f1 | xargs)
+
+ v4_a_tun="${prefix4}.${a_r1}.1"
+ v4_b_tun="${prefix4}.${b_r1}.1"
+
+ v6_a_tun="${prefix6}:${a_r1}::1"
+ v6_b_tun="${prefix6}:${b_r1}::1"
+
+ if [ "${v4_a_tun}" == "${a_addr}" ]; then
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0800),ipv4()" \
+ "set(tunnel(tun_id=1,dst=${v4_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x86dd),ipv6()" \
+ "set(tunnel(tun_id=1,dst=${v4_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),tunnel(tun_id=1,src=${v4_b_tun},dst=${v4_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0800),ipv4()" \
+ "${veth_a_port}"
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),tunnel(tun_id=1,src=${v4_b_tun},dst=${v4_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x86dd),ipv6()" \
+ "${veth_a_port}"
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),tunnel(tun_id=1,src=${v4_b_tun},dst=${v4_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0806),arp()" \
+ "${veth_a_port}"
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0806),arp(sip=${veth4_c_addr},tip=${tunnel4_b_addr})" \
+ "set(tunnel(tun_id=1,dst=${v4_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
+ else
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0800),ipv4()" \
+ "set(tunnel(tun_id=1,ipv6_dst=${v6_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x86dd),ipv6()" \
+ "set(tunnel(tun_id=1,ipv6_dst=${v6_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),tunnel(tun_id=1,ipv6_src=${v6_b_tun},ipv6_dst=${v6_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0800),ipv4()" \
+ "${veth_a_port}"
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),tunnel(tun_id=1,ipv6_src=${v6_b_tun},ipv6_dst=${v6_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x86dd),ipv6()" \
+ "${veth_a_port}"
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),tunnel(tun_id=1,ipv6_src=${v6_b_tun},ipv6_dst=${v6_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0806),arp()" \
+ "${veth_a_port}"
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
+ "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0806),arp(sip=${veth4_c_addr},tip=${tunnel4_b_addr})" \
+ "set(tunnel(tun_id=1,ipv6_dst=${v6_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
+ fi
}
setup_ovs_geneve4() {
@@ -881,7 +932,7 @@ setup_ovs_vxlan6() {
}
setup_ovs_bridge() {
- run_cmd ovs-vsctl add-br ovs_br0 || return $ksft_skip
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-dp ovs_br0 || return $ksft_skip
run_cmd ip link set ovs_br0 up
run_cmd ${ns_c} ip link add veth_C-A type veth peer name veth_A-C
@@ -891,7 +942,7 @@ setup_ovs_bridge() {
run_cmd ${ns_c} ip link set veth_C-A up
run_cmd ${ns_c} ip addr add ${veth4_c_addr}/${veth4_mask} dev veth_C-A
run_cmd ${ns_c} ip addr add ${veth6_c_addr}/${veth6_mask} dev veth_C-A
- run_cmd ovs-vsctl add-port ovs_br0 veth_A-C
+ run_cmd python3 ./openvswitch/ovs-dpctl.py add-if ovs_br0 veth_A-C
# Move veth_A-R1 to init
run_cmd ${ns_a} ip link set veth_A-R1 netns 1
@@ -942,8 +993,10 @@ cleanup() {
ip link del veth_A-C 2>/dev/null
ip link del veth_A-R1 2>/dev/null
- ovs-vsctl --if-exists del-port vxlan_a 2>/dev/null
- ovs-vsctl --if-exists del-br ovs_br0 2>/dev/null
+ # squelch the output of the del-if commands since it can be wordy
+ python3 ./openvswitch/ovs-dpctl.py del-if ovs_br0 -d true vxlan_a >/dev/null 2>&1
+ python3 ./openvswitch/ovs-dpctl.py del-if ovs_br0 -d true geneve_a >/dev/null 2>&1
+ python3 ./openvswitch/ovs-dpctl.py del-dp ovs_br0 >/dev/null 2>&1
rm -f "$tmpoutfile"
}
@@ -1407,16 +1460,10 @@ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception() {
exp_mtu=$((${ll_mtu} - 40 - 8 - 8 - 14))
fi
- if [ "${type}" = "vxlan" ]; then
- tun_a="vxlan_sys_4789"
- elif [ "${type}" = "geneve" ]; then
- tun_a="genev_sys_6081"
- fi
-
- trace "" "${tun_a}" "${ns_b}" ${type}_b \
- "" veth_A-R1 "${ns_r1}" veth_R1-A \
- "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B \
- "" ovs_br0 "" veth-A-C \
+ trace "" "${type}_a" "${ns_b}" ${type}_b \
+ "" veth_A-R1 "${ns_r1}" veth_R1-A \
+ "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B \
+ "" ovs_br0 "" veth-A_C \
"${ns_c}" veth_C-A
if [ ${family} -eq 4 ]; then
@@ -1436,8 +1483,8 @@ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception() {
mtu "${ns_b}" veth_B-R1 ${ll_mtu}
mtu "${ns_r1}" veth_R1-B ${ll_mtu}
- mtu "" ${tun_a} $((${ll_mtu} + 1000))
- mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
+ mtu "" ${type}_a $((${ll_mtu} + 1000))
+ mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
run_cmd ${ns_c} ${ping} -q -M want -i 0.1 -c 20 -s $((${ll_mtu} + 500)) ${dst} || return 1
--
2.45.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [RFC net-next 7/7] selftests: net: add config for openvswitch
2024-06-13 18:13 [RFC net-next 0/7] selftests: net: Switch pmtu.sh to use the internal ovs script Aaron Conole
` (5 preceding siblings ...)
2024-06-13 18:13 ` [RFC net-next 6/7] selftests: net: Use the provided dpctl rather than the vswitchd for tests Aaron Conole
@ 2024-06-13 18:13 ` Aaron Conole
2024-06-16 16:30 ` [ovs-dev] " Simon Horman
6 siblings, 1 reply; 21+ messages in thread
From: Aaron Conole @ 2024-06-13 18:13 UTC (permalink / raw)
To: netdev
Cc: dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Adrian Moreno, Stefano Brivio, Ilya Maximets
The pmtu testing will require that the OVS module is installed,
so do that.
Signed-off-by: Aaron Conole <aconole@redhat.com>
---
tools/testing/selftests/net/config | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config
index 04de7a6ba6f3..d85fb2d1f132 100644
--- a/tools/testing/selftests/net/config
+++ b/tools/testing/selftests/net/config
@@ -101,3 +101,8 @@ CONFIG_NETFILTER_XT_MATCH_POLICY=m
CONFIG_CRYPTO_ARIA=y
CONFIG_XFRM_INTERFACE=m
CONFIG_XFRM_USER=m
+CONFIG_OPENVSWITCH=m
+CONFIG_OPENVSWITCH_GRE=m
+CONFIG_OPENVSWITCH_VXLAN=m
+CONFIG_OPENVSWITCH_GENEVE=m
+CONFIG_NF_CONNTRACK_OVS=y
--
2.45.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [RFC net-next 6/7] selftests: net: Use the provided dpctl rather than the vswitchd for tests.
2024-06-13 18:13 ` [RFC net-next 6/7] selftests: net: Use the provided dpctl rather than the vswitchd for tests Aaron Conole
@ 2024-06-13 20:37 ` Stefano Brivio
2024-06-14 15:53 ` Aaron Conole
0 siblings, 1 reply; 21+ messages in thread
From: Stefano Brivio @ 2024-06-13 20:37 UTC (permalink / raw)
To: Aaron Conole
Cc: netdev, dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Adrian Moreno, Ilya Maximets
On Thu, 13 Jun 2024 14:13:32 -0400
Aaron Conole <aconole@redhat.com> wrote:
> The current pmtu test infrastucture requires an installed copy of the
> ovs-vswitchd userspace. This means that any automated or constrained
> environments may not have the requisite tools to run the tests. However,
> the pmtu tests don't require any special classifier processing. Indeed
> they are only using the vswitchd in the most basic mode - as a NORMAL
> switch.
>
> However, the ovs-dpctl kernel utility can now program all the needed basic
> flows to allow traffic to traverse the tunnels and provide support for at
> least testing some basic pmtu scenarios.
I didn't know about that tool, that looks like a nice improvement. A
few comments below (mostly nits):
> More complicated flow pipelines
> can be added to the internal ovs test infrastructure, but that is work for
> the future. For now, enable the most common cases - wide mega flows with
> no other prerequisites.
>
> Signed-off-by: Aaron Conole <aconole@redhat.com>
> ---
> tools/testing/selftests/net/pmtu.sh | 87 ++++++++++++++++++++++-------
> 1 file changed, 67 insertions(+), 20 deletions(-)
>
> diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
> index cfc84958025a..7f4f35d88dcc 100755
> --- a/tools/testing/selftests/net/pmtu.sh
> +++ b/tools/testing/selftests/net/pmtu.sh
> @@ -846,22 +846,73 @@ setup_ovs_vxlan_or_geneve() {
> type="${1}"
> a_addr="${2}"
> b_addr="${3}"
> + dport="6081"
>
> if [ "${type}" = "vxlan" ]; then
> + dport="4789"
> opts="${opts} ttl 64 dstport 4789"
> opts_b="local ${b_addr}"
> fi
>
> - run_cmd ovs-vsctl add-port ovs_br0 ${type}_a -- \
> - set interface ${type}_a type=${type} \
> - options:remote_ip=${b_addr} options:key=1 options:csum=true || return 1
> -
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-if ovs_br0 ${type}_a -t ${type}
In some restricted environments, it might actually be more convenient
to carry around ovs-vsctl than Python with (Python) libraries.
Nowadays I typically (albeit seldom) run kselftests in throw-away VM
images made by mbuto (https://mbuto.sh/, see demo on the right), and
while it copies python3 and dynamic libraries from the host, adding
Python libraries such as pyroute2 gets quite complicated.
So I'm wondering, if it's not too messy: could we have two functions
starting from approximately here (say, setup_ovs_dpctl() and
setup_ovs_vsctl()), try with ovs-dpctl first, and, if that fails,
fall back to ovs-vsctl?
> run_cmd ${ns_b} ip link add ${type}_b type ${type} id 1 ${opts_b} remote ${a_addr} ${opts} || return 1
>
> run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ${type}_b
> run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ${type}_b
>
> + run_cmd ip link set ${type}_a up
> run_cmd ${ns_b} ip link set ${type}_b up
> +
> + ports=$(python3 ./openvswitch/ovs-dpctl.py show)
> + br0_port=$(echo "$ports" | grep -E "\sovs_br0" | sed -e 's@port @@' | cut -d: -f1 | xargs)
> + type_a_port=$(echo "$ports" | grep ${type}_a | sed -e 's@port @@' | cut -d: -f1 | xargs)
> + veth_a_port=$(echo "$ports" | grep veth_A | sed -e 's@port @@' | cut -d: -f1 | xargs)
> +
> + v4_a_tun="${prefix4}.${a_r1}.1"
> + v4_b_tun="${prefix4}.${b_r1}.1"
> +
> + v6_a_tun="${prefix6}:${a_r1}::1"
> + v6_b_tun="${prefix6}:${b_r1}::1"
> +
> + if [ "${v4_a_tun}" == "${a_addr}" ]; then
I see now that 05d92cb0e919 ("selftests/net: change shebang to bash to
support "source"") turned this into a Bash script (for no real reason,
lib.sh could have simply been sourced with '.' instead).
Other than that, this happily runs with dash and possibly others, and:
$ checkbashisms -f pmtu.sh
possible bashism in pmtu.sh line 201 (should be '.', not 'source'):
source lib.sh
possible bashism in pmtu.sh line 202 (should be '.', not 'source'):
source net_helper.sh
Would it be possible to change this to POSIX shell:
if [ "${v4_a_tun}" = "${a_addr}" ]; then
even just for consistency with the rest of the file?
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0800),ipv4()" \
> + "set(tunnel(tun_id=1,dst=${v4_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x86dd),ipv6()" \
> + "set(tunnel(tun_id=1,dst=${v4_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),tunnel(tun_id=1,src=${v4_b_tun},dst=${v4_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0800),ipv4()" \
> + "${veth_a_port}"
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),tunnel(tun_id=1,src=${v4_b_tun},dst=${v4_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x86dd),ipv6()" \
> + "${veth_a_port}"
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),tunnel(tun_id=1,src=${v4_b_tun},dst=${v4_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0806),arp()" \
> + "${veth_a_port}"
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0806),arp(sip=${veth4_c_addr},tip=${tunnel4_b_addr})" \
> + "set(tunnel(tun_id=1,dst=${v4_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
> + else
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0800),ipv4()" \
> + "set(tunnel(tun_id=1,ipv6_dst=${v6_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x86dd),ipv6()" \
> + "set(tunnel(tun_id=1,ipv6_dst=${v6_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),tunnel(tun_id=1,ipv6_src=${v6_b_tun},ipv6_dst=${v6_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0800),ipv4()" \
> + "${veth_a_port}"
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),tunnel(tun_id=1,ipv6_src=${v6_b_tun},ipv6_dst=${v6_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x86dd),ipv6()" \
> + "${veth_a_port}"
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),tunnel(tun_id=1,ipv6_src=${v6_b_tun},ipv6_dst=${v6_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0806),arp()" \
> + "${veth_a_port}"
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0806),arp(sip=${veth4_c_addr},tip=${tunnel4_b_addr})" \
> + "set(tunnel(tun_id=1,ipv6_dst=${v6_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
> + fi
> }
>
> setup_ovs_geneve4() {
> @@ -881,7 +932,7 @@ setup_ovs_vxlan6() {
> }
>
> setup_ovs_bridge() {
> - run_cmd ovs-vsctl add-br ovs_br0 || return $ksft_skip
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-dp ovs_br0 || return $ksft_skip
> run_cmd ip link set ovs_br0 up
>
> run_cmd ${ns_c} ip link add veth_C-A type veth peer name veth_A-C
> @@ -891,7 +942,7 @@ setup_ovs_bridge() {
> run_cmd ${ns_c} ip link set veth_C-A up
> run_cmd ${ns_c} ip addr add ${veth4_c_addr}/${veth4_mask} dev veth_C-A
> run_cmd ${ns_c} ip addr add ${veth6_c_addr}/${veth6_mask} dev veth_C-A
> - run_cmd ovs-vsctl add-port ovs_br0 veth_A-C
> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-if ovs_br0 veth_A-C
>
> # Move veth_A-R1 to init
> run_cmd ${ns_a} ip link set veth_A-R1 netns 1
> @@ -942,8 +993,10 @@ cleanup() {
>
> ip link del veth_A-C 2>/dev/null
> ip link del veth_A-R1 2>/dev/null
> - ovs-vsctl --if-exists del-port vxlan_a 2>/dev/null
> - ovs-vsctl --if-exists del-br ovs_br0 2>/dev/null
> + # squelch the output of the del-if commands since it can be wordy
> + python3 ./openvswitch/ovs-dpctl.py del-if ovs_br0 -d true vxlan_a >/dev/null 2>&1
> + python3 ./openvswitch/ovs-dpctl.py del-if ovs_br0 -d true geneve_a >/dev/null 2>&1
> + python3 ./openvswitch/ovs-dpctl.py del-dp ovs_br0 >/dev/null 2>&1
The idea behind those tabs before 2>/dev/null was to keep them aligned
and make those redirections a bit easier on the eyes.
If you add more, you could keep those aligned as well -- or just decide
that lines are too long and drop the tabs altogether.
> rm -f "$tmpoutfile"
> }
>
> @@ -1407,16 +1460,10 @@ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception() {
> exp_mtu=$((${ll_mtu} - 40 - 8 - 8 - 14))
> fi
>
> - if [ "${type}" = "vxlan" ]; then
> - tun_a="vxlan_sys_4789"
> - elif [ "${type}" = "geneve" ]; then
> - tun_a="genev_sys_6081"
> - fi
> -
> - trace "" "${tun_a}" "${ns_b}" ${type}_b \
> - "" veth_A-R1 "${ns_r1}" veth_R1-A \
> - "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B \
> - "" ovs_br0 "" veth-A-C \
> + trace "" "${type}_a" "${ns_b}" ${type}_b \
> + "" veth_A-R1 "${ns_r1}" veth_R1-A \
> + "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B \
> + "" ovs_br0 "" veth-A_C \
> "${ns_c}" veth_C-A
>
> if [ ${family} -eq 4 ]; then
> @@ -1436,8 +1483,8 @@ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception() {
> mtu "${ns_b}" veth_B-R1 ${ll_mtu}
> mtu "${ns_r1}" veth_R1-B ${ll_mtu}
>
> - mtu "" ${tun_a} $((${ll_mtu} + 1000))
> - mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
> + mtu "" ${type}_a $((${ll_mtu} + 1000))
> + mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
>
> run_cmd ${ns_c} ${ping} -q -M want -i 0.1 -c 20 -s $((${ll_mtu} + 500)) ${dst} || return 1
>
--
Stefano
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC net-next 6/7] selftests: net: Use the provided dpctl rather than the vswitchd for tests.
2024-06-13 20:37 ` Stefano Brivio
@ 2024-06-14 15:53 ` Aaron Conole
0 siblings, 0 replies; 21+ messages in thread
From: Aaron Conole @ 2024-06-14 15:53 UTC (permalink / raw)
To: Stefano Brivio
Cc: netdev, dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Adrian Moreno, Ilya Maximets
Hi Stefano,
Thanks for the review!
Stefano Brivio <sbrivio@redhat.com> writes:
> On Thu, 13 Jun 2024 14:13:32 -0400
> Aaron Conole <aconole@redhat.com> wrote:
>
>> The current pmtu test infrastucture requires an installed copy of the
>> ovs-vswitchd userspace. This means that any automated or constrained
>> environments may not have the requisite tools to run the tests. However,
>> the pmtu tests don't require any special classifier processing. Indeed
>> they are only using the vswitchd in the most basic mode - as a NORMAL
>> switch.
>>
>> However, the ovs-dpctl kernel utility can now program all the needed basic
>> flows to allow traffic to traverse the tunnels and provide support for at
>> least testing some basic pmtu scenarios.
>
> I didn't know about that tool, that looks like a nice improvement. A
> few comments below (mostly nits):
It didn't at the time, so no worries :)
>> More complicated flow pipelines
>> can be added to the internal ovs test infrastructure, but that is work for
>> the future. For now, enable the most common cases - wide mega flows with
>> no other prerequisites.
>>
>> Signed-off-by: Aaron Conole <aconole@redhat.com>
>> ---
>> tools/testing/selftests/net/pmtu.sh | 87 ++++++++++++++++++++++-------
>> 1 file changed, 67 insertions(+), 20 deletions(-)
>>
>> diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
>> index cfc84958025a..7f4f35d88dcc 100755
>> --- a/tools/testing/selftests/net/pmtu.sh
>> +++ b/tools/testing/selftests/net/pmtu.sh
>> @@ -846,22 +846,73 @@ setup_ovs_vxlan_or_geneve() {
>> type="${1}"
>> a_addr="${2}"
>> b_addr="${3}"
>> + dport="6081"
>>
>> if [ "${type}" = "vxlan" ]; then
>> + dport="4789"
>> opts="${opts} ttl 64 dstport 4789"
>> opts_b="local ${b_addr}"
>> fi
>>
>> - run_cmd ovs-vsctl add-port ovs_br0 ${type}_a -- \
>> - set interface ${type}_a type=${type} \
>> - options:remote_ip=${b_addr} options:key=1 options:csum=true || return 1
>> -
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-if ovs_br0 ${type}_a -t ${type}
>
> In some restricted environments, it might actually be more convenient
> to carry around ovs-vsctl than Python with (Python) libraries.
>
> Nowadays I typically (albeit seldom) run kselftests in throw-away VM
> images made by mbuto (https://mbuto.sh/, see demo on the right), and
> while it copies python3 and dynamic libraries from the host, adding
> Python libraries such as pyroute2 gets quite complicated.
>
> So I'm wondering, if it's not too messy: could we have two functions
> starting from approximately here (say, setup_ovs_dpctl() and
> setup_ovs_vsctl()), try with ovs-dpctl first, and, if that fails,
> fall back to ovs-vsctl?
It didn't seem to be too bad - so I went ahead and made that change. It
tested well, so I'll resubmit it with that.
>> run_cmd ${ns_b} ip link add ${type}_b type ${type} id 1
>> ${opts_b} remote ${a_addr} ${opts} || return 1
>>
>> run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ${type}_b
>> run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ${type}_b
>>
>> + run_cmd ip link set ${type}_a up
>> run_cmd ${ns_b} ip link set ${type}_b up
>> +
>> + ports=$(python3 ./openvswitch/ovs-dpctl.py show)
>> + br0_port=$(echo "$ports" | grep -E "\sovs_br0" | sed -e 's@port @@' | cut -d: -f1 | xargs)
>> + type_a_port=$(echo "$ports" | grep ${type}_a | sed -e 's@port @@' | cut -d: -f1 | xargs)
>> + veth_a_port=$(echo "$ports" | grep veth_A | sed -e 's@port @@' | cut -d: -f1 | xargs)
>> +
>> + v4_a_tun="${prefix4}.${a_r1}.1"
>> + v4_b_tun="${prefix4}.${b_r1}.1"
>> +
>> + v6_a_tun="${prefix6}:${a_r1}::1"
>> + v6_b_tun="${prefix6}:${b_r1}::1"
>> +
>> + if [ "${v4_a_tun}" == "${a_addr}" ]; then
>
> I see now that 05d92cb0e919 ("selftests/net: change shebang to bash to
> support "source"") turned this into a Bash script (for no real reason,
> lib.sh could have simply been sourced with '.' instead).
>
> Other than that, this happily runs with dash and possibly others, and:
>
> $ checkbashisms -f pmtu.sh
> possible bashism in pmtu.sh line 201 (should be '.', not 'source'):
> source lib.sh
> possible bashism in pmtu.sh line 202 (should be '.', not 'source'):
> source net_helper.sh
>
> Would it be possible to change this to POSIX shell:
>
> if [ "${v4_a_tun}" = "${a_addr}" ]; then
>
> even just for consistency with the rest of the file?
done.
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0800),ipv4()" \
>> + "set(tunnel(tun_id=1,dst=${v4_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x86dd),ipv6()" \
>> + "set(tunnel(tun_id=1,dst=${v4_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),tunnel(tun_id=1,src=${v4_b_tun},dst=${v4_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0800),ipv4()" \
>> + "${veth_a_port}"
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),tunnel(tun_id=1,src=${v4_b_tun},dst=${v4_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x86dd),ipv6()" \
>> + "${veth_a_port}"
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),tunnel(tun_id=1,src=${v4_b_tun},dst=${v4_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0806),arp()" \
>> + "${veth_a_port}"
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0806),arp(sip=${veth4_c_addr},tip=${tunnel4_b_addr})" \
>> + "set(tunnel(tun_id=1,dst=${v4_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
>> + else
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0800),ipv4()" \
>> + "set(tunnel(tun_id=1,ipv6_dst=${v6_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x86dd),ipv6()" \
>> + "set(tunnel(tun_id=1,ipv6_dst=${v6_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),tunnel(tun_id=1,ipv6_src=${v6_b_tun},ipv6_dst=${v6_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0800),ipv4()" \
>> + "${veth_a_port}"
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),tunnel(tun_id=1,ipv6_src=${v6_b_tun},ipv6_dst=${v6_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x86dd),ipv6()" \
>> + "${veth_a_port}"
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),tunnel(tun_id=1,ipv6_src=${v6_b_tun},ipv6_dst=${v6_a_tun}),in_port(${type_a_port}),eth(),eth_type(0x0806),arp()" \
>> + "${veth_a_port}"
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-flow ovs_br0 \
>> + "recirc_id(0),in_port(${veth_a_port}),eth(),eth_type(0x0806),arp(sip=${veth4_c_addr},tip=${tunnel4_b_addr})" \
>> + "set(tunnel(tun_id=1,ipv6_dst=${v6_b_tun},ttl=64,tp_dst=${dport},flags(df|csum))),${type_a_port}"
>> + fi
>> }
>>
>> setup_ovs_geneve4() {
>> @@ -881,7 +932,7 @@ setup_ovs_vxlan6() {
>> }
>>
>> setup_ovs_bridge() {
>> - run_cmd ovs-vsctl add-br ovs_br0 || return $ksft_skip
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-dp ovs_br0 || return $ksft_skip
>> run_cmd ip link set ovs_br0 up
>>
>> run_cmd ${ns_c} ip link add veth_C-A type veth peer name veth_A-C
>> @@ -891,7 +942,7 @@ setup_ovs_bridge() {
>> run_cmd ${ns_c} ip link set veth_C-A up
>> run_cmd ${ns_c} ip addr add ${veth4_c_addr}/${veth4_mask} dev veth_C-A
>> run_cmd ${ns_c} ip addr add ${veth6_c_addr}/${veth6_mask} dev veth_C-A
>> - run_cmd ovs-vsctl add-port ovs_br0 veth_A-C
>> + run_cmd python3 ./openvswitch/ovs-dpctl.py add-if ovs_br0 veth_A-C
>>
>> # Move veth_A-R1 to init
>> run_cmd ${ns_a} ip link set veth_A-R1 netns 1
>> @@ -942,8 +993,10 @@ cleanup() {
>>
>> ip link del veth_A-C 2>/dev/null
>> ip link del veth_A-R1 2>/dev/null
>> - ovs-vsctl --if-exists del-port vxlan_a 2>/dev/null
>> - ovs-vsctl --if-exists del-br ovs_br0 2>/dev/null
>> + # squelch the output of the del-if commands since it can be wordy
>> + python3 ./openvswitch/ovs-dpctl.py del-if ovs_br0 -d true vxlan_a >/dev/null 2>&1
>> + python3 ./openvswitch/ovs-dpctl.py del-if ovs_br0 -d true geneve_a >/dev/null 2>&1
>> + python3 ./openvswitch/ovs-dpctl.py del-dp ovs_br0 >/dev/null 2>&1
>
> The idea behind those tabs before 2>/dev/null was to keep them aligned
> and make those redirections a bit easier on the eyes.
>
> If you add more, you could keep those aligned as well -- or just decide
> that lines are too long and drop the tabs altogether.
Yeah, looks like I missed the /dev/null tabs but those were supposed to
be lined up. Anyway, I rewrote this part so that it looks better (I
think).
>> rm -f "$tmpoutfile"
>> }
>>
>> @@ -1407,16 +1460,10 @@ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception() {
>> exp_mtu=$((${ll_mtu} - 40 - 8 - 8 - 14))
>> fi
>>
>> - if [ "${type}" = "vxlan" ]; then
>> - tun_a="vxlan_sys_4789"
>> - elif [ "${type}" = "geneve" ]; then
>> - tun_a="genev_sys_6081"
>> - fi
>> -
>> - trace "" "${tun_a}" "${ns_b}" ${type}_b \
>> - "" veth_A-R1 "${ns_r1}" veth_R1-A \
>> - "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B \
>> - "" ovs_br0 "" veth-A-C \
>> + trace "" "${type}_a" "${ns_b}" ${type}_b \
>> + "" veth_A-R1 "${ns_r1}" veth_R1-A \
>> + "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B \
>> + "" ovs_br0 "" veth-A_C \
>> "${ns_c}" veth_C-A
>>
>> if [ ${family} -eq 4 ]; then
>> @@ -1436,8 +1483,8 @@ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception() {
>> mtu "${ns_b}" veth_B-R1 ${ll_mtu}
>> mtu "${ns_r1}" veth_R1-B ${ll_mtu}
>>
>> - mtu "" ${tun_a} $((${ll_mtu} + 1000))
>> - mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
>> + mtu "" ${type}_a $((${ll_mtu} + 1000))
>> + mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
>>
>> run_cmd ${ns_c} ${ping} -q -M want -i 0.1 -c 20 -s $((${ll_mtu} + 500)) ${dst} || return 1
>>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [ovs-dev] [RFC net-next 1/7] selftests: openvswitch: Support explicit tunnel port creation.
2024-06-13 18:13 ` [RFC net-next 1/7] selftests: openvswitch: Support explicit tunnel port creation Aaron Conole
@ 2024-06-16 16:25 ` Simon Horman
2024-06-17 17:03 ` Aaron Conole
0 siblings, 1 reply; 21+ messages in thread
From: Simon Horman @ 2024-06-16 16:25 UTC (permalink / raw)
To: Aaron Conole
Cc: netdev, dev, linux-kernel, Ilya Maximets, Stefano Brivio,
Eric Dumazet, linux-kselftest, Jakub Kicinski, Paolo Abeni,
Shuah Khan, David S. Miller
On Thu, Jun 13, 2024 at 02:13:27PM -0400, Aaron Conole wrote:
> The OVS module can operate in conjunction with various types of
> tunnel ports. These are created as either explicit tunnel vport
> types, OR by creating a tunnel interface which acts as an anchor
> for the lightweight tunnel support.
>
> This patch adds the ability to add tunnel ports to an OVS
> datapath for testing various scenarios with tunnel ports. With
> this addition, the vswitch "plumbing" will at least be able to
> push packets around using the tunnel vports. Future patches
> will add support for setting required tunnel metadata for lwts
> in the datapath. The end goal will be to push packets via these
> tunnels, and will be used in an upcoming commit for testing the
> path MTU.
>
> Signed-off-by: Aaron Conole <aconole@redhat.com>
...
> @@ -1702,12 +1711,43 @@ class OvsVport(GenericNetlinkSocket):
> msg["dpifindex"] = dpindex
> port_type = OvsVport.str_to_type(ptype)
>
> - msg["attrs"].append(["OVS_VPORT_ATTR_TYPE", port_type])
> msg["attrs"].append(["OVS_VPORT_ATTR_NAME", vport_ifname])
> msg["attrs"].append(
> ["OVS_VPORT_ATTR_UPCALL_PID", [self.upcall_packet.epid]]
> )
>
> + TUNNEL_DEFAULTS = [("geneve", 6081),
> + ("vxlan", 4798)]
Hi Aaron,
It is corrected as part of another patch in this series, but
the correct port for vxlan is 4789 (i.e. 89 rather than 98).
With that fixed, feel free to add:
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Simon Horman <horms@kernel.org>
..
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [ovs-dev] [RFC net-next 4/7] selftests: openvswitch: Add support for tunnel() key.
2024-06-13 18:13 ` [RFC net-next 4/7] selftests: openvswitch: Add support for tunnel() key Aaron Conole
@ 2024-06-16 16:27 ` Simon Horman
2024-06-17 17:56 ` Aaron Conole
0 siblings, 1 reply; 21+ messages in thread
From: Simon Horman @ 2024-06-16 16:27 UTC (permalink / raw)
To: Aaron Conole
Cc: netdev, dev, linux-kernel, Ilya Maximets, Stefano Brivio,
Eric Dumazet, linux-kselftest, Jakub Kicinski, Paolo Abeni,
Shuah Khan, David S. Miller
On Thu, Jun 13, 2024 at 02:13:30PM -0400, Aaron Conole wrote:
> This will be used when setting details about the tunnel to use as
> transport. There is a difference between the ODP format between tunnel():
> the 'key' flag is not actually a flag field, so we don't support it in the
> same way that the vswitchd userspace supports displaying it.
>
> Signed-off-by: Aaron Conole <aconole@redhat.com>
...
> @@ -1265,6 +1265,165 @@ class ovskey(nla):
> init=init,
> )
>
> + class ovs_key_tunnel(nla):
> + nla_flags = NLA_F_NESTED
> +
> + nla_map = (
> + ("OVS_TUNNEL_KEY_ATTR_ID", "be64"),
> + ("OVS_TUNNEL_KEY_ATTR_IPV4_SRC", "ipaddr"),
> + ("OVS_TUNNEL_KEY_ATTR_IPV4_DST", "ipaddr"),
> + ("OVS_TUNNEL_KEY_ATTR_TOS", "uint8"),
> + ("OVS_TUNNEL_KEY_ATTR_TTL", "uint8"),
> + ("OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT", "flag"),
> + ("OVS_TUNNEL_KEY_ATTR_CSUM", "flag"),
> + ("OVS_TUNNEL_KEY_ATTR_OAM", "flag"),
> + ("OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS", "array(uint32)"),
> + ("OVS_TUNNEL_KEY_ATTR_TP_SRC", "be16"),
> + ("OVS_TUNNEL_KEY_ATTR_TP_DST", "be16"),
> + ("OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS", "none"),
> + ("OVS_TUNNEL_KEY_ATTR_IPV6_SRC", "ipaddr"),
> + ("OVS_TUNNEL_KEY_ATTR_IPV6_DST", "ipaddr"),
> + ("OVS_TUNNEL_KEY_ATTR_PAD", "none"),
> + ("OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS", "none"),
> + ("OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE", "flag"),
> + )
> +
> + def parse(self, flowstr, mask=None):
> + if not flowstr.startswith("tunnel("):
> + return None, None
> +
> + k = ovskey.ovs_key_tunnel()
> + if mask is not None:
> + mask = ovskey.ovs_key_tunnel()
> +
> + flowstr = flowstr[len("tunnel("):]
> +
> + v6_address = None
> +
> + fields = [
> + ("tun_id=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_ID",
> + 0xffffffffffffffff, None, None),
> +
> + ("src=", r"([0-9a-fA-F\.]+)", str,
> + "OVS_TUNNEL_KEY_ATTR_IPV4_SRC", "255.255.255.255", "0.0.0.0",
> + False),
> + ("dst=", r"([0-9a-fA-F\.]+)", str,
> + "OVS_TUNNEL_KEY_ATTR_IPV4_DST", "255.255.255.255", "0.0.0.0",
> + False),
> +
> + ("ipv6_src=", r"([0-9a-fA-F:]+)", str,
> + "OVS_TUNNEL_KEY_ATTR_IPV6_SRC",
> + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "::", True),
> + ("ipv6_dst=", r"([0-9a-fA-F:]+)", str,
> + "OVS_TUNNEL_KEY_ATTR_IPV6_DST",
> + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "::", True),
> +
> + ("tos=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TOS", 255, 0,
> + None),
> + ("ttl=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TTL", 255, 0,
> + None),
> +
> + ("tp_src=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TP_SRC",
> + 65535, 0, None),
> + ("tp_dst=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TP_DST",
> + 65535, 0, None),
> + ]
> +
> + forced_include = ["OVS_TUNNEL_KEY_ATTR_TTL"]
> +
> + for prefix, regex, typ, attr_name, mask_val, default_val, v46_flag in fields:
> + flowstr, value = parse_extract_field(flowstr, prefix, regex, typ, False)
> + if not attr_name:
> + raise Exception("Bad list value in tunnel fields")
> +
> + if value is None and attr_name in forced_include:
> + value = default_val
> + mask_val = default_val
> +
> + if value is not None:
> + if v6_address is None and v46_flag is not None:
> + v6_address = v46_flag
By my reading, at this point v6_address will only be None if v46_flag is
not None. IF so, the condition below seems excessive.
> + if v6_address is not None and v46_flag is not None \
> + and v46_flag != v6_address:
> + raise ValueError("Cannot mix v6 and v4 addresses")
I wonder if we can instead express this as (completely untested!):
if v46_flag is not None:
if v6_address is None:
v6_address = v46_flag
if v46_flag != v6_address:
raise ValueError("Cannot mix v6 and v4 addresses")
> + k["attrs"].append([attr_name, value])
> + if mask is not None:
> + mask["attrs"].append([attr_name, mask_val])
> + else:
> + if v6_address is not None and v46_flag is not None \
> + and v46_flag != v6_address:
> + continue
> + if v6_address is None and v46_flag is not None:
> + continue
And I wonder if this is a bit easier on the eyes (also completely untested):
if v46_flag is not None:
if v6_address is None or v46_flag != v6_address:
continue
> + if mask is not None:
> + mask["attrs"].append([attr_name, default_val])
> +
> + if k["attrs"][0][0] != "OVS_TUNNEL_KEY_ATTR_ID":
> + raise ValueError("Needs a tunid set")
...
> @@ -1745,7 +1905,7 @@ class OvsVport(GenericNetlinkSocket):
> )
>
> TUNNEL_DEFAULTS = [("geneve", 6081),
> - ("vxlan", 4798)]
> + ("vxlan", 4789)]
>
> for tnl in TUNNEL_DEFAULTS:
> if ptype == tnl[0]:
As noted in my response to PATCH 1/7, I think that the
change in the hunk above belongs there rather than here.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [ovs-dev] [RFC net-next 5/7] selftests: openvswitch: Support implicit ipv6 arguments.
2024-06-13 18:13 ` [RFC net-next 5/7] selftests: openvswitch: Support implicit ipv6 arguments Aaron Conole
@ 2024-06-16 16:28 ` Simon Horman
2024-06-17 17:03 ` Aaron Conole
0 siblings, 1 reply; 21+ messages in thread
From: Simon Horman @ 2024-06-16 16:28 UTC (permalink / raw)
To: Aaron Conole
Cc: netdev, dev, linux-kernel, Ilya Maximets, Stefano Brivio,
Eric Dumazet, linux-kselftest, Jakub Kicinski, Paolo Abeni,
Shuah Khan, David S. Miller
On Thu, Jun 13, 2024 at 02:13:31PM -0400, Aaron Conole wrote:
> The current iteration of IPv6 support requires explicit fields to be set
> in addition to not properly support the actual IPv6 addresses properly.
> With this change, make it so that the ipv6() bare option is usable to
> create wildcarded flows to match broad swaths of ipv6 traffic.
>
> Signed-off-by: Aaron Conole <aconole@redhat.com>
> ---
> .../selftests/net/openvswitch/ovs-dpctl.py | 43 ++++++++++++-------
> 1 file changed, 28 insertions(+), 15 deletions(-)
>
> diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> index 5545e5cab1d6..2577a06c58cf 100644
> --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> @@ -200,6 +200,19 @@ def convert_ipv4(data):
>
> return int(ipaddress.IPv4Address(ip)), int(ipaddress.IPv4Address(mask))
>
> +def convert_ipv6(data):
> + ip, _, mask = data.partition('/')
> +
> + if not ip:
> + ip = mask = 0
> + elif not mask:
> + mask = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
> + elif mask.isdigit():
> + mask = ipaddress.IPv6Network("::/" + mask).hostmask
> +
> + return ipaddress.IPv6Address(ip).packed, ipaddress.IPv6Address(mask).packed
> +
> +
nit: Perhaps one blank line is enough
> def convert_int(size):
> def convert_int_sized(data):
> value, _, mask = data.partition('/')
...
The nit above notwithstanding, this patch looks good to me.
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Simon Horman <horms@kernel.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [ovs-dev] [RFC net-next 2/7] selftests: openvswitch: Refactor actions parsing.
2024-06-13 18:13 ` [RFC net-next 2/7] selftests: openvswitch: Refactor actions parsing Aaron Conole
@ 2024-06-16 16:29 ` Simon Horman
0 siblings, 0 replies; 21+ messages in thread
From: Simon Horman @ 2024-06-16 16:29 UTC (permalink / raw)
To: Aaron Conole
Cc: netdev, dev, linux-kernel, Ilya Maximets, Stefano Brivio,
Eric Dumazet, linux-kselftest, Jakub Kicinski, Paolo Abeni,
Shuah Khan, David S. Miller
On Thu, Jun 13, 2024 at 02:13:28PM -0400, Aaron Conole wrote:
> Until recently, the ovs-dpctl utility was used with a limited actions set
> and didn't need to have support for multiple similar actions. However,
> when adding support for tunnels, it will be important to support multiple
> set() actions in a single flow. When printing these actions, the existing
> code will be unable to print all of the sets - it will only print the
> first.
>
> Refactor this code to be easier to read and support multiple actions of the
> same type in an action list.
>
> Signed-off-by: Aaron Conole <aconole@redhat.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Simon Horman <horms@kernel.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [ovs-dev] [RFC net-next 3/7] selftests: openvswitch: Add set() and set_masked() support.
2024-06-13 18:13 ` [RFC net-next 3/7] selftests: openvswitch: Add set() and set_masked() support Aaron Conole
@ 2024-06-16 16:29 ` Simon Horman
2024-06-17 12:18 ` Adrián Moreno
1 sibling, 0 replies; 21+ messages in thread
From: Simon Horman @ 2024-06-16 16:29 UTC (permalink / raw)
To: Aaron Conole
Cc: netdev, dev, linux-kernel, Ilya Maximets, Stefano Brivio,
Eric Dumazet, linux-kselftest, Jakub Kicinski, Paolo Abeni,
Shuah Khan, David S. Miller
On Thu, Jun 13, 2024 at 02:13:29PM -0400, Aaron Conole wrote:
> These will be used in upcoming commits to set specific attributes for
> interacting with tunnels. Since set() will use the key parsing routine, we
> also make sure to prepend it with an open paren, for the action parsing to
> properly understand it.
>
> Signed-off-by: Aaron Conole <aconole@redhat.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Simon Horman <horms@kernel.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [ovs-dev] [RFC net-next 7/7] selftests: net: add config for openvswitch
2024-06-13 18:13 ` [RFC net-next 7/7] selftests: net: add config for openvswitch Aaron Conole
@ 2024-06-16 16:30 ` Simon Horman
0 siblings, 0 replies; 21+ messages in thread
From: Simon Horman @ 2024-06-16 16:30 UTC (permalink / raw)
To: Aaron Conole
Cc: netdev, dev, linux-kernel, Ilya Maximets, Stefano Brivio,
Eric Dumazet, linux-kselftest, Jakub Kicinski, Paolo Abeni,
Shuah Khan, David S. Miller
On Thu, Jun 13, 2024 at 02:13:33PM -0400, Aaron Conole wrote:
> The pmtu testing will require that the OVS module is installed,
> so do that.
>
> Signed-off-by: Aaron Conole <aconole@redhat.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Simon Horman <horms@kernel.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC net-next 3/7] selftests: openvswitch: Add set() and set_masked() support.
2024-06-13 18:13 ` [RFC net-next 3/7] selftests: openvswitch: Add set() and set_masked() support Aaron Conole
2024-06-16 16:29 ` [ovs-dev] " Simon Horman
@ 2024-06-17 12:18 ` Adrián Moreno
2024-06-17 17:07 ` Aaron Conole
1 sibling, 1 reply; 21+ messages in thread
From: Adrián Moreno @ 2024-06-17 12:18 UTC (permalink / raw)
To: Aaron Conole
Cc: netdev, dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Stefano Brivio, Ilya Maximets
On Thu, Jun 13, 2024 at 02:13:29PM GMT, Aaron Conole wrote:
> These will be used in upcoming commits to set specific attributes for
> interacting with tunnels. Since set() will use the key parsing routine, we
> also make sure to prepend it with an open paren, for the action parsing to
> properly understand it.
>
> Signed-off-by: Aaron Conole <aconole@redhat.com>
> ---
> .../selftests/net/openvswitch/ovs-dpctl.py | 39 +++++++++++++++++--
> 1 file changed, 35 insertions(+), 4 deletions(-)
>
> diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> index 73768f3af6e5..fee64c31d4d4 100644
> --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> @@ -284,7 +284,7 @@ class ovsactions(nla):
> ("OVS_ACTION_ATTR_UNSPEC", "none"),
> ("OVS_ACTION_ATTR_OUTPUT", "uint32"),
> ("OVS_ACTION_ATTR_USERSPACE", "userspace"),
> - ("OVS_ACTION_ATTR_SET", "none"),
> + ("OVS_ACTION_ATTR_SET", "ovskey"),
> ("OVS_ACTION_ATTR_PUSH_VLAN", "none"),
> ("OVS_ACTION_ATTR_POP_VLAN", "flag"),
> ("OVS_ACTION_ATTR_SAMPLE", "none"),
> @@ -292,7 +292,7 @@ class ovsactions(nla):
> ("OVS_ACTION_ATTR_HASH", "none"),
> ("OVS_ACTION_ATTR_PUSH_MPLS", "none"),
> ("OVS_ACTION_ATTR_POP_MPLS", "flag"),
> - ("OVS_ACTION_ATTR_SET_MASKED", "none"),
> + ("OVS_ACTION_ATTR_SET_MASKED", "ovskey"),
> ("OVS_ACTION_ATTR_CT", "ctact"),
> ("OVS_ACTION_ATTR_TRUNC", "uint32"),
> ("OVS_ACTION_ATTR_PUSH_ETH", "none"),
> @@ -469,6 +469,14 @@ class ovsactions(nla):
> print_str += "clone("
> print_str += datum.dpstr(more)
> print_str += ")"
> + elif field[0] == "OVS_ACTION_ATTR_SET" or \
> + field[0] == "OVS_ACTION_ATTR_SET_MASKED":
> + print_str += "set"
> + if field[0] == "OVS_ACTION_ATTR_SET_MASKED":
> + print_str += "_masked"
> + print_str += "("
> + print_str += datum.dpstr(more)
> + print_str += ")"
> else:
> try:
> print_str += datum.dpstr(more)
> @@ -547,6 +555,25 @@ class ovsactions(nla):
> self["attrs"].append(("OVS_ACTION_ATTR_CLONE", subacts))
> actstr = actstr[parsedLen:]
> parsed = True
> + elif parse_starts_block(actstr, "set(", False):
> + parencount += 1
> + k = ovskey()
> + actstr = actstr[len("set("):]
> + actstr = k.parse(actstr, None)
> + self["attrs"].append(("OVS_ACTION_ATTR_SET", k))
> + if not actstr.startswith(")"):
> + actstr = ")" + actstr
> + parsed = True
> + elif parse_starts_block(actstr, "set_masked(", False):
> + parencount += 1
> + k = ovskey()
> + m = ovskey()
> + actstr = actstr[len("set_masked("):]
> + actstr = k.parse(actstr, m)
> + self["attrs"].append(("OVS_ACTION_ATTR_SET_MASKED", [k, m]))
> + if not actstr.startswith(")"):
> + actstr = ")" + actstr
> + parsed = True
> elif parse_starts_block(actstr, "ct(", False):
> parencount += 1
> actstr = actstr[len("ct(") :]
> @@ -1312,7 +1339,7 @@ class ovskey(nla):
> mask["attrs"].append([field[0], m])
> self["attrs"].append([field[0], k])
>
> - flowstr = flowstr[strspn(flowstr, "),") :]
> + flowstr = flowstr[strspn(flowstr, "), ") :]
>
> return flowstr
>
> @@ -1898,7 +1925,11 @@ class OvsFlow(GenericNetlinkSocket):
> ):
> print_str += "drop"
> else:
> - print_str += actsmsg.dpstr(more)
> + if type(actsmsg) == "list":
nit: I belive the recommended way of comparing types is using
"isinstance":
https://www.flake8rules.com/rules/E721.html
Also, I don't see what can make actmsg be a list. It should always be an
instance of "ovsactions", right?
> + for act in actsmsg:
> + print_str += act.dpstr(more)
> + else:
> + print_str += actsmsg.dpstr(more)
>
> return print_str
>
> --
> 2.45.1
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [ovs-dev] [RFC net-next 1/7] selftests: openvswitch: Support explicit tunnel port creation.
2024-06-16 16:25 ` [ovs-dev] " Simon Horman
@ 2024-06-17 17:03 ` Aaron Conole
0 siblings, 0 replies; 21+ messages in thread
From: Aaron Conole @ 2024-06-17 17:03 UTC (permalink / raw)
To: Simon Horman
Cc: netdev, dev, linux-kernel, Ilya Maximets, Stefano Brivio,
Eric Dumazet, linux-kselftest, Jakub Kicinski, Paolo Abeni,
Shuah Khan, David S. Miller
Simon Horman <horms@kernel.org> writes:
> On Thu, Jun 13, 2024 at 02:13:27PM -0400, Aaron Conole wrote:
>> The OVS module can operate in conjunction with various types of
>> tunnel ports. These are created as either explicit tunnel vport
>> types, OR by creating a tunnel interface which acts as an anchor
>> for the lightweight tunnel support.
>>
>> This patch adds the ability to add tunnel ports to an OVS
>> datapath for testing various scenarios with tunnel ports. With
>> this addition, the vswitch "plumbing" will at least be able to
>> push packets around using the tunnel vports. Future patches
>> will add support for setting required tunnel metadata for lwts
>> in the datapath. The end goal will be to push packets via these
>> tunnels, and will be used in an upcoming commit for testing the
>> path MTU.
>>
>> Signed-off-by: Aaron Conole <aconole@redhat.com>
>
> ...
>
>> @@ -1702,12 +1711,43 @@ class OvsVport(GenericNetlinkSocket):
>> msg["dpifindex"] = dpindex
>> port_type = OvsVport.str_to_type(ptype)
>>
>> - msg["attrs"].append(["OVS_VPORT_ATTR_TYPE", port_type])
>> msg["attrs"].append(["OVS_VPORT_ATTR_NAME", vport_ifname])
>> msg["attrs"].append(
>> ["OVS_VPORT_ATTR_UPCALL_PID", [self.upcall_packet.epid]]
>> )
>>
>> + TUNNEL_DEFAULTS = [("geneve", 6081),
>> + ("vxlan", 4798)]
>
> Hi Aaron,
>
> It is corrected as part of another patch in this series, but
> the correct port for vxlan is 4789 (i.e. 89 rather than 98).
>
> With that fixed, feel free to add:
Thanks Simon! Done.
> Reviewed-by: Simon Horman <horms@kernel.org>
> Tested-by: Simon Horman <horms@kernel.org>
>
> ..
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [ovs-dev] [RFC net-next 5/7] selftests: openvswitch: Support implicit ipv6 arguments.
2024-06-16 16:28 ` [ovs-dev] " Simon Horman
@ 2024-06-17 17:03 ` Aaron Conole
0 siblings, 0 replies; 21+ messages in thread
From: Aaron Conole @ 2024-06-17 17:03 UTC (permalink / raw)
To: Simon Horman
Cc: netdev, dev, linux-kernel, Ilya Maximets, Stefano Brivio,
Eric Dumazet, linux-kselftest, Jakub Kicinski, Paolo Abeni,
Shuah Khan, David S. Miller
Simon Horman <horms@kernel.org> writes:
> On Thu, Jun 13, 2024 at 02:13:31PM -0400, Aaron Conole wrote:
>> The current iteration of IPv6 support requires explicit fields to be set
>> in addition to not properly support the actual IPv6 addresses properly.
>> With this change, make it so that the ipv6() bare option is usable to
>> create wildcarded flows to match broad swaths of ipv6 traffic.
>>
>> Signed-off-by: Aaron Conole <aconole@redhat.com>
>> ---
>> .../selftests/net/openvswitch/ovs-dpctl.py | 43 ++++++++++++-------
>> 1 file changed, 28 insertions(+), 15 deletions(-)
>>
>> diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
>> index 5545e5cab1d6..2577a06c58cf 100644
>> --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
>> +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
>> @@ -200,6 +200,19 @@ def convert_ipv4(data):
>>
>> return int(ipaddress.IPv4Address(ip)), int(ipaddress.IPv4Address(mask))
>>
>> +def convert_ipv6(data):
>> + ip, _, mask = data.partition('/')
>> +
>> + if not ip:
>> + ip = mask = 0
>> + elif not mask:
>> + mask = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
>> + elif mask.isdigit():
>> + mask = ipaddress.IPv6Network("::/" + mask).hostmask
>> +
>> + return ipaddress.IPv6Address(ip).packed, ipaddress.IPv6Address(mask).packed
>> +
>> +
>
> nit: Perhaps one blank line is enough
Sure - dropped.
>> def convert_int(size):
>> def convert_int_sized(data):
>> value, _, mask = data.partition('/')
>
> ...
>
> The nit above notwithstanding, this patch looks good to me.
>
> Reviewed-by: Simon Horman <horms@kernel.org>
> Tested-by: Simon Horman <horms@kernel.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [RFC net-next 3/7] selftests: openvswitch: Add set() and set_masked() support.
2024-06-17 12:18 ` Adrián Moreno
@ 2024-06-17 17:07 ` Aaron Conole
0 siblings, 0 replies; 21+ messages in thread
From: Aaron Conole @ 2024-06-17 17:07 UTC (permalink / raw)
To: Adrián Moreno
Cc: netdev, dev, linux-kselftest, linux-kernel, Pravin B Shelar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan, Stefano Brivio, Ilya Maximets
Adrián Moreno <amorenoz@redhat.com> writes:
> On Thu, Jun 13, 2024 at 02:13:29PM GMT, Aaron Conole wrote:
>> These will be used in upcoming commits to set specific attributes for
>> interacting with tunnels. Since set() will use the key parsing routine, we
>> also make sure to prepend it with an open paren, for the action parsing to
>> properly understand it.
>>
>> Signed-off-by: Aaron Conole <aconole@redhat.com>
>> ---
>> .../selftests/net/openvswitch/ovs-dpctl.py | 39 +++++++++++++++++--
>> 1 file changed, 35 insertions(+), 4 deletions(-)
>>
>> diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
>> index 73768f3af6e5..fee64c31d4d4 100644
>> --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
>> +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
>> @@ -284,7 +284,7 @@ class ovsactions(nla):
>> ("OVS_ACTION_ATTR_UNSPEC", "none"),
>> ("OVS_ACTION_ATTR_OUTPUT", "uint32"),
>> ("OVS_ACTION_ATTR_USERSPACE", "userspace"),
>> - ("OVS_ACTION_ATTR_SET", "none"),
>> + ("OVS_ACTION_ATTR_SET", "ovskey"),
>> ("OVS_ACTION_ATTR_PUSH_VLAN", "none"),
>> ("OVS_ACTION_ATTR_POP_VLAN", "flag"),
>> ("OVS_ACTION_ATTR_SAMPLE", "none"),
>> @@ -292,7 +292,7 @@ class ovsactions(nla):
>> ("OVS_ACTION_ATTR_HASH", "none"),
>> ("OVS_ACTION_ATTR_PUSH_MPLS", "none"),
>> ("OVS_ACTION_ATTR_POP_MPLS", "flag"),
>> - ("OVS_ACTION_ATTR_SET_MASKED", "none"),
>> + ("OVS_ACTION_ATTR_SET_MASKED", "ovskey"),
>> ("OVS_ACTION_ATTR_CT", "ctact"),
>> ("OVS_ACTION_ATTR_TRUNC", "uint32"),
>> ("OVS_ACTION_ATTR_PUSH_ETH", "none"),
>> @@ -469,6 +469,14 @@ class ovsactions(nla):
>> print_str += "clone("
>> print_str += datum.dpstr(more)
>> print_str += ")"
>> + elif field[0] == "OVS_ACTION_ATTR_SET" or \
>> + field[0] == "OVS_ACTION_ATTR_SET_MASKED":
>> + print_str += "set"
>> + if field[0] == "OVS_ACTION_ATTR_SET_MASKED":
>> + print_str += "_masked"
>> + print_str += "("
>> + print_str += datum.dpstr(more)
>> + print_str += ")"
>> else:
>> try:
>> print_str += datum.dpstr(more)
>> @@ -547,6 +555,25 @@ class ovsactions(nla):
>> self["attrs"].append(("OVS_ACTION_ATTR_CLONE", subacts))
>> actstr = actstr[parsedLen:]
>> parsed = True
>> + elif parse_starts_block(actstr, "set(", False):
>> + parencount += 1
>> + k = ovskey()
>> + actstr = actstr[len("set("):]
>> + actstr = k.parse(actstr, None)
>> + self["attrs"].append(("OVS_ACTION_ATTR_SET", k))
>> + if not actstr.startswith(")"):
>> + actstr = ")" + actstr
>> + parsed = True
>> + elif parse_starts_block(actstr, "set_masked(", False):
>> + parencount += 1
>> + k = ovskey()
>> + m = ovskey()
>> + actstr = actstr[len("set_masked("):]
>> + actstr = k.parse(actstr, m)
>> + self["attrs"].append(("OVS_ACTION_ATTR_SET_MASKED", [k, m]))
>> + if not actstr.startswith(")"):
>> + actstr = ")" + actstr
>> + parsed = True
>> elif parse_starts_block(actstr, "ct(", False):
>> parencount += 1
>> actstr = actstr[len("ct(") :]
>> @@ -1312,7 +1339,7 @@ class ovskey(nla):
>> mask["attrs"].append([field[0], m])
>> self["attrs"].append([field[0], k])
>>
>> - flowstr = flowstr[strspn(flowstr, "),") :]
>> + flowstr = flowstr[strspn(flowstr, "), ") :]
>>
>> return flowstr
>>
>> @@ -1898,7 +1925,11 @@ class OvsFlow(GenericNetlinkSocket):
>> ):
>> print_str += "drop"
>> else:
>> - print_str += actsmsg.dpstr(more)
>> + if type(actsmsg) == "list":
>
> nit: I belive the recommended way of comparing types is using
> "isinstance":
>
> https://www.flake8rules.com/rules/E721.html
>
> Also, I don't see what can make actmsg be a list. It should always be an
> instance of "ovsactions", right?
Yes, you're right. This was some debug code that I was messing with and
it made it into this submission. I've dropped it :) Thanks for the review!
>
>> + for act in actsmsg:
>> + print_str += act.dpstr(more)
>> + else:
>> + print_str += actsmsg.dpstr(more)
>>
>> return print_str
>>
>> --
>> 2.45.1
>>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [ovs-dev] [RFC net-next 4/7] selftests: openvswitch: Add support for tunnel() key.
2024-06-16 16:27 ` [ovs-dev] " Simon Horman
@ 2024-06-17 17:56 ` Aaron Conole
0 siblings, 0 replies; 21+ messages in thread
From: Aaron Conole @ 2024-06-17 17:56 UTC (permalink / raw)
To: Simon Horman
Cc: netdev, dev, linux-kernel, Ilya Maximets, Stefano Brivio,
Eric Dumazet, linux-kselftest, Jakub Kicinski, Paolo Abeni,
Shuah Khan, David S. Miller
Simon Horman <horms@kernel.org> writes:
> On Thu, Jun 13, 2024 at 02:13:30PM -0400, Aaron Conole wrote:
>> This will be used when setting details about the tunnel to use as
>> transport. There is a difference between the ODP format between tunnel():
>> the 'key' flag is not actually a flag field, so we don't support it in the
>> same way that the vswitchd userspace supports displaying it.
>>
>> Signed-off-by: Aaron Conole <aconole@redhat.com>
>
> ...
>
>> @@ -1265,6 +1265,165 @@ class ovskey(nla):
>> init=init,
>> )
>>
>> + class ovs_key_tunnel(nla):
>> + nla_flags = NLA_F_NESTED
>> +
>> + nla_map = (
>> + ("OVS_TUNNEL_KEY_ATTR_ID", "be64"),
>> + ("OVS_TUNNEL_KEY_ATTR_IPV4_SRC", "ipaddr"),
>> + ("OVS_TUNNEL_KEY_ATTR_IPV4_DST", "ipaddr"),
>> + ("OVS_TUNNEL_KEY_ATTR_TOS", "uint8"),
>> + ("OVS_TUNNEL_KEY_ATTR_TTL", "uint8"),
>> + ("OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT", "flag"),
>> + ("OVS_TUNNEL_KEY_ATTR_CSUM", "flag"),
>> + ("OVS_TUNNEL_KEY_ATTR_OAM", "flag"),
>> + ("OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS", "array(uint32)"),
>> + ("OVS_TUNNEL_KEY_ATTR_TP_SRC", "be16"),
>> + ("OVS_TUNNEL_KEY_ATTR_TP_DST", "be16"),
>> + ("OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS", "none"),
>> + ("OVS_TUNNEL_KEY_ATTR_IPV6_SRC", "ipaddr"),
>> + ("OVS_TUNNEL_KEY_ATTR_IPV6_DST", "ipaddr"),
>> + ("OVS_TUNNEL_KEY_ATTR_PAD", "none"),
>> + ("OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS", "none"),
>> + ("OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE", "flag"),
>> + )
>> +
>> + def parse(self, flowstr, mask=None):
>> + if not flowstr.startswith("tunnel("):
>> + return None, None
>> +
>> + k = ovskey.ovs_key_tunnel()
>> + if mask is not None:
>> + mask = ovskey.ovs_key_tunnel()
>> +
>> + flowstr = flowstr[len("tunnel("):]
>> +
>> + v6_address = None
>> +
>> + fields = [
>> + ("tun_id=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_ID",
>> + 0xffffffffffffffff, None, None),
>> +
>> + ("src=", r"([0-9a-fA-F\.]+)", str,
>> + "OVS_TUNNEL_KEY_ATTR_IPV4_SRC", "255.255.255.255", "0.0.0.0",
>> + False),
>> + ("dst=", r"([0-9a-fA-F\.]+)", str,
>> + "OVS_TUNNEL_KEY_ATTR_IPV4_DST", "255.255.255.255", "0.0.0.0",
>> + False),
>> +
>> + ("ipv6_src=", r"([0-9a-fA-F:]+)", str,
>> + "OVS_TUNNEL_KEY_ATTR_IPV6_SRC",
>> + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "::", True),
>> + ("ipv6_dst=", r"([0-9a-fA-F:]+)", str,
>> + "OVS_TUNNEL_KEY_ATTR_IPV6_DST",
>> + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "::", True),
>> +
>> + ("tos=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TOS", 255, 0,
>> + None),
>> + ("ttl=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TTL", 255, 0,
>> + None),
>> +
>> + ("tp_src=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TP_SRC",
>> + 65535, 0, None),
>> + ("tp_dst=", r"(\d+)", int, "OVS_TUNNEL_KEY_ATTR_TP_DST",
>> + 65535, 0, None),
>> + ]
>> +
>> + forced_include = ["OVS_TUNNEL_KEY_ATTR_TTL"]
>> +
>> + for prefix, regex, typ, attr_name, mask_val, default_val, v46_flag in fields:
>> + flowstr, value = parse_extract_field(flowstr, prefix, regex, typ, False)
>> + if not attr_name:
>> + raise Exception("Bad list value in tunnel fields")
>> +
>> + if value is None and attr_name in forced_include:
>> + value = default_val
>> + mask_val = default_val
>> +
>> + if value is not None:
>> + if v6_address is None and v46_flag is not None:
>> + v6_address = v46_flag
>
> By my reading, at this point v6_address will only be None if v46_flag is
> not None. IF so, the condition below seems excessive.
Agreed - thanks for the suggestions.
>> + if v6_address is not None and v46_flag is not None \
>> + and v46_flag != v6_address:
>> + raise ValueError("Cannot mix v6 and v4 addresses")
>
> I wonder if we can instead express this as (completely untested!):
>
> if v46_flag is not None:
> if v6_address is None:
> v6_address = v46_flag
> if v46_flag != v6_address:
> raise ValueError("Cannot mix v6 and v4 addresses")
>
>> + k["attrs"].append([attr_name, value])
>> + if mask is not None:
>> + mask["attrs"].append([attr_name, mask_val])
>> + else:
>> + if v6_address is not None and v46_flag is not None \
>> + and v46_flag != v6_address:
>> + continue
>> + if v6_address is None and v46_flag is not None:
>> + continue
>
> And I wonder if this is a bit easier on the eyes (also completely untested):
>
> if v46_flag is not None:
> if v6_address is None or v46_flag != v6_address:
> continue
I folded both of these in and did some quick testing. Thanks Simon!
>> + if mask is not None:
>> + mask["attrs"].append([attr_name, default_val])
>> +
>> + if k["attrs"][0][0] != "OVS_TUNNEL_KEY_ATTR_ID":
>> + raise ValueError("Needs a tunid set")
>
> ...
>
>> @@ -1745,7 +1905,7 @@ class OvsVport(GenericNetlinkSocket):
>> )
>>
>> TUNNEL_DEFAULTS = [("geneve", 6081),
>> - ("vxlan", 4798)]
>> + ("vxlan", 4789)]
>>
>> for tnl in TUNNEL_DEFAULTS:
>> if ptype == tnl[0]:
>
> As noted in my response to PATCH 1/7, I think that the
> change in the hunk above belongs there rather than here.
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2024-06-17 17:56 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-13 18:13 [RFC net-next 0/7] selftests: net: Switch pmtu.sh to use the internal ovs script Aaron Conole
2024-06-13 18:13 ` [RFC net-next 1/7] selftests: openvswitch: Support explicit tunnel port creation Aaron Conole
2024-06-16 16:25 ` [ovs-dev] " Simon Horman
2024-06-17 17:03 ` Aaron Conole
2024-06-13 18:13 ` [RFC net-next 2/7] selftests: openvswitch: Refactor actions parsing Aaron Conole
2024-06-16 16:29 ` [ovs-dev] " Simon Horman
2024-06-13 18:13 ` [RFC net-next 3/7] selftests: openvswitch: Add set() and set_masked() support Aaron Conole
2024-06-16 16:29 ` [ovs-dev] " Simon Horman
2024-06-17 12:18 ` Adrián Moreno
2024-06-17 17:07 ` Aaron Conole
2024-06-13 18:13 ` [RFC net-next 4/7] selftests: openvswitch: Add support for tunnel() key Aaron Conole
2024-06-16 16:27 ` [ovs-dev] " Simon Horman
2024-06-17 17:56 ` Aaron Conole
2024-06-13 18:13 ` [RFC net-next 5/7] selftests: openvswitch: Support implicit ipv6 arguments Aaron Conole
2024-06-16 16:28 ` [ovs-dev] " Simon Horman
2024-06-17 17:03 ` Aaron Conole
2024-06-13 18:13 ` [RFC net-next 6/7] selftests: net: Use the provided dpctl rather than the vswitchd for tests Aaron Conole
2024-06-13 20:37 ` Stefano Brivio
2024-06-14 15:53 ` Aaron Conole
2024-06-13 18:13 ` [RFC net-next 7/7] selftests: net: add config for openvswitch Aaron Conole
2024-06-16 16:30 ` [ovs-dev] " Simon Horman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).