mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
selftests: openvswitch: add dec_ttl action support and test
Add dec_ttl action support to the OVS kernel datapath selftest
framework:
- Add dec_ttl nested NLA class to ovs-dpctl.py with proper
OVS_DEC_TTL_ATTR_ACTION sub-attribute handling
- Add parse support for dec_ttl(le_1(<inner_actions>)) action
string, consistent with the odp-util.c format where le_1()
holds the actions taken when TTL reaches 1
- Add dpstr output formatting for dec_ttl actions
- Add test_dec_ttl() to openvswitch.sh that verifies:
* Normal TTL packets are forwarded after decrement
* TTL=1 packets are dropped (TTL expiry)
* Graceful skip via ksft_skip if kernel lacks dec_ttl support
The dec_ttl class uses late-binding type resolution to reference
ovsactions for its inner action list, avoiding circular references
at class definition time.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260530021443.1734484-1-houminxi@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
b736e34b96
commit
d6f6d71233
|
|
@ -29,6 +29,7 @@ tests="
|
|||
tunnel_refcount ovs: test tunnel vport reference cleanup
|
||||
drop_reason drop: test drop reasons are emitted
|
||||
pop_vlan vlan: POP_VLAN action strips tag
|
||||
dec_ttl ttl: dec_ttl decrements IP TTL
|
||||
psample psample: Sampling packets with psample"
|
||||
|
||||
info() {
|
||||
|
|
@ -245,6 +246,60 @@ usage() {
|
|||
}
|
||||
|
||||
|
||||
test_dec_ttl() {
|
||||
sbx_add "test_dec_ttl" || return $?
|
||||
ovs_add_dp "test_dec_ttl" decttl || return 1
|
||||
|
||||
info "create namespaces"
|
||||
for ns in client server; do
|
||||
ovs_add_netns_and_veths "test_dec_ttl" "decttl" "$ns" \
|
||||
"${ns:0:1}0" "${ns:0:1}1" || return 1
|
||||
done
|
||||
|
||||
ip netns exec client ip addr add 10.0.0.1/24 dev c1
|
||||
ip netns exec client ip link set c1 up
|
||||
ip netns exec server ip addr add 10.0.0.2/24 dev s1
|
||||
ip netns exec server ip link set s1 up
|
||||
|
||||
# Probe: check if kernel supports dec_ttl action.
|
||||
ovs_add_flow "test_dec_ttl" decttl \
|
||||
'in_port(1),eth(),eth_type(0x0800),ipv4()' \
|
||||
'dec_ttl(le_1())' &>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
info "no support for dec_ttl - skipping"
|
||||
ovs_exit_sig
|
||||
return $ksft_skip
|
||||
fi
|
||||
|
||||
ovs_del_flows "test_dec_ttl" decttl
|
||||
|
||||
# ARP flows (bidirectional)
|
||||
ovs_add_flow "test_dec_ttl" decttl \
|
||||
'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
|
||||
ovs_add_flow "test_dec_ttl" decttl \
|
||||
'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
|
||||
|
||||
# IP flows with dec_ttl action
|
||||
ovs_add_flow "test_dec_ttl" decttl \
|
||||
'in_port(1),eth(),eth_type(0x0800),ipv4()' \
|
||||
'dec_ttl(le_1()),2' || return 1
|
||||
ovs_add_flow "test_dec_ttl" decttl \
|
||||
'in_port(2),eth(),eth_type(0x0800),ipv4()' \
|
||||
'dec_ttl(le_1()),1' || return 1
|
||||
|
||||
info "verify connectivity with dec_ttl"
|
||||
ovs_sbx "test_dec_ttl" ip netns exec client ping -c 1 -W 2 \
|
||||
10.0.0.2 || return 1
|
||||
|
||||
info "verify TTL=1 is dropped by dec_ttl"
|
||||
ovs_sbx "test_dec_ttl" ip netns exec client ping -c 1 -W 2 \
|
||||
-t 1 10.0.0.2 >/dev/null 2>&1 \
|
||||
&& { info "FAIL: ping should fail with TTL=1 and dec_ttl"
|
||||
return 1; }
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# psample test
|
||||
# - use psample to observe packets
|
||||
test_psample() {
|
||||
|
|
|
|||
|
|
@ -388,11 +388,21 @@ class ovsactions(nla):
|
|||
("OVS_ACTION_ATTR_CLONE", "recursive"),
|
||||
("OVS_ACTION_ATTR_CHECK_PKT_LEN", "none"),
|
||||
("OVS_ACTION_ATTR_ADD_MPLS", "none"),
|
||||
("OVS_ACTION_ATTR_DEC_TTL", "none"),
|
||||
("OVS_ACTION_ATTR_DEC_TTL", "dec_ttl"),
|
||||
("OVS_ACTION_ATTR_DROP", "uint32"),
|
||||
("OVS_ACTION_ATTR_PSAMPLE", "psample"),
|
||||
)
|
||||
|
||||
class dec_ttl(nla): # pylint: disable=invalid-name
|
||||
"""Nested OVS_DEC_TTL_ATTR_* sub-attributes."""
|
||||
|
||||
nla_flags = NLA_F_NESTED
|
||||
|
||||
nla_map = (
|
||||
("OVS_DEC_TTL_ATTR_UNSPEC", "none"),
|
||||
("OVS_DEC_TTL_ATTR_ACTION", "actions"),
|
||||
)
|
||||
|
||||
class psample(nla):
|
||||
nla_flags = NLA_F_NESTED
|
||||
|
||||
|
|
@ -635,6 +645,13 @@ class ovsactions(nla):
|
|||
print_str += "ct_clear"
|
||||
elif field[0] == "OVS_ACTION_ATTR_POP_VLAN":
|
||||
print_str += "pop_vlan"
|
||||
elif field[0] == "OVS_ACTION_ATTR_DEC_TTL":
|
||||
datum = self.get_attr(field[0])
|
||||
print_str += "dec_ttl(le_1("
|
||||
subacts = datum.get_attr("OVS_DEC_TTL_ATTR_ACTION")
|
||||
if subacts and subacts.get("attrs"):
|
||||
print_str += subacts.dpstr(more)
|
||||
print_str += "))"
|
||||
elif field[0] == "OVS_ACTION_ATTR_PUSH_VLAN":
|
||||
datum = self.get_attr(field[0])
|
||||
tpid = datum["vlan_tpid"]
|
||||
|
|
@ -786,6 +803,20 @@ class ovsactions(nla):
|
|||
actstr = actstr[paren + 1:]
|
||||
parsed = True
|
||||
|
||||
elif parse_starts_block(actstr, "dec_ttl(le_1(", False):
|
||||
parencount += 2
|
||||
subacts = ovsactions()
|
||||
actstr = actstr[len("dec_ttl(le_1("):]
|
||||
parsed_len = subacts.parse(actstr)
|
||||
decttl = ovsactions.dec_ttl()
|
||||
decttl["attrs"].append(
|
||||
("OVS_DEC_TTL_ATTR_ACTION", subacts)
|
||||
)
|
||||
self["attrs"].append(
|
||||
("OVS_ACTION_ATTR_DEC_TTL", decttl)
|
||||
)
|
||||
actstr = actstr[parsed_len:]
|
||||
parsed = True
|
||||
elif parse_starts_block(actstr, "clone(", False):
|
||||
parencount += 1
|
||||
subacts = ovsactions()
|
||||
|
|
@ -957,6 +988,12 @@ class ovsactions(nla):
|
|||
return (totallen - len(actstr))
|
||||
|
||||
|
||||
# pyroute2 resolves nla_map types via getattr(self, name).
|
||||
# dec_ttl needs "actions" to resolve to ovsactions, but
|
||||
# ovsactions is not defined when dec_ttl class body runs.
|
||||
ovsactions.dec_ttl.actions = ovsactions
|
||||
|
||||
|
||||
class ovskey(nla):
|
||||
nla_flags = NLA_F_NESTED
|
||||
nla_map = (
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user