mirror of
https://github.com/torvalds/linux
synced 2024-10-15 07:47:34 +00:00
selftests: openvswitch: Add validation for the recursion test
Add a test case into the netlink checks that will show the number of nested action recursions won't exceed 16. Going to 17 on a small clone call isn't enough to exhaust the stack on (most) systems, so it should be safe to run even on systems that don't have the fix applied. Signed-off-by: Aaron Conole <aconole@redhat.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://lore.kernel.org/r/20240207132416.1488485-3-aconole@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
6e2f90d31f
commit
bd128f62c3
|
@ -502,7 +502,20 @@ test_netlink_checks () {
|
|||
wc -l) == 2 ] || \
|
||||
return 1
|
||||
|
||||
info "Checking clone depth"
|
||||
ERR_MSG="Flow actions may not be safe on all matching packets"
|
||||
PRE_TEST=$(dmesg | grep -c "${ERR_MSG}")
|
||||
ovs_add_flow "test_netlink_checks" nv0 \
|
||||
'in_port(1),eth(),eth_type(0x800),ipv4()' \
|
||||
'clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(drop)))))))))))))))))' \
|
||||
>/dev/null 2>&1 && return 1
|
||||
POST_TEST=$(dmesg | grep -c "${ERR_MSG}")
|
||||
|
||||
if [ "$PRE_TEST" == "$POST_TEST" ]; then
|
||||
info "failed - clone depth too large"
|
||||
return 1
|
||||
fi
|
||||
|
||||
PRE_TEST=$(dmesg | grep -c "${ERR_MSG}")
|
||||
ovs_add_flow "test_netlink_checks" nv0 \
|
||||
'in_port(1),eth(),eth_type(0x0806),arp()' 'drop(0),2' \
|
||||
|
|
|
@ -299,7 +299,7 @@ class ovsactions(nla):
|
|||
("OVS_ACTION_ATTR_PUSH_NSH", "none"),
|
||||
("OVS_ACTION_ATTR_POP_NSH", "flag"),
|
||||
("OVS_ACTION_ATTR_METER", "none"),
|
||||
("OVS_ACTION_ATTR_CLONE", "none"),
|
||||
("OVS_ACTION_ATTR_CLONE", "recursive"),
|
||||
("OVS_ACTION_ATTR_CHECK_PKT_LEN", "none"),
|
||||
("OVS_ACTION_ATTR_ADD_MPLS", "none"),
|
||||
("OVS_ACTION_ATTR_DEC_TTL", "none"),
|
||||
|
@ -465,29 +465,42 @@ class ovsactions(nla):
|
|||
print_str += "pop_mpls"
|
||||
else:
|
||||
datum = self.get_attr(field[0])
|
||||
print_str += datum.dpstr(more)
|
||||
if field[0] == "OVS_ACTION_ATTR_CLONE":
|
||||
print_str += "clone("
|
||||
print_str += datum.dpstr(more)
|
||||
print_str += ")"
|
||||
else:
|
||||
print_str += datum.dpstr(more)
|
||||
|
||||
return print_str
|
||||
|
||||
def parse(self, actstr):
|
||||
totallen = len(actstr)
|
||||
while len(actstr) != 0:
|
||||
parsed = False
|
||||
parencount = 0
|
||||
if actstr.startswith("drop"):
|
||||
# If no reason is provided, the implicit drop is used (i.e no
|
||||
# action). If some reason is given, an explicit action is used.
|
||||
actstr, reason = parse_extract_field(
|
||||
actstr,
|
||||
"drop(",
|
||||
"([0-9]+)",
|
||||
lambda x: int(x, 0),
|
||||
False,
|
||||
None,
|
||||
)
|
||||
reason = None
|
||||
if actstr.startswith("drop("):
|
||||
parencount += 1
|
||||
|
||||
actstr, reason = parse_extract_field(
|
||||
actstr,
|
||||
"drop(",
|
||||
"([0-9]+)",
|
||||
lambda x: int(x, 0),
|
||||
False,
|
||||
None,
|
||||
)
|
||||
|
||||
if reason is not None:
|
||||
self["attrs"].append(["OVS_ACTION_ATTR_DROP", reason])
|
||||
parsed = True
|
||||
else:
|
||||
return
|
||||
actstr = actstr[len("drop"): ]
|
||||
return (totallen - len(actstr))
|
||||
|
||||
elif parse_starts_block(actstr, "^(\d+)", False, True):
|
||||
actstr, output = parse_extract_field(
|
||||
|
@ -504,6 +517,7 @@ class ovsactions(nla):
|
|||
False,
|
||||
0,
|
||||
)
|
||||
parencount += 1
|
||||
self["attrs"].append(["OVS_ACTION_ATTR_RECIRC", recircid])
|
||||
parsed = True
|
||||
|
||||
|
@ -516,12 +530,22 @@ class ovsactions(nla):
|
|||
|
||||
for flat_act in parse_flat_map:
|
||||
if parse_starts_block(actstr, flat_act[0], False):
|
||||
actstr += len(flat_act[0])
|
||||
actstr = actstr[len(flat_act[0]):]
|
||||
self["attrs"].append([flat_act[1]])
|
||||
actstr = actstr[strspn(actstr, ", ") :]
|
||||
parsed = True
|
||||
|
||||
if parse_starts_block(actstr, "ct(", False):
|
||||
if parse_starts_block(actstr, "clone(", False):
|
||||
parencount += 1
|
||||
subacts = ovsactions()
|
||||
actstr = actstr[len("clone("):]
|
||||
parsedLen = subacts.parse(actstr)
|
||||
lst = []
|
||||
self["attrs"].append(("OVS_ACTION_ATTR_CLONE", subacts))
|
||||
actstr = actstr[parsedLen:]
|
||||
parsed = True
|
||||
elif parse_starts_block(actstr, "ct(", False):
|
||||
parencount += 1
|
||||
actstr = actstr[len("ct(") :]
|
||||
ctact = ovsactions.ctact()
|
||||
|
||||
|
@ -553,6 +577,7 @@ class ovsactions(nla):
|
|||
natact = ovsactions.ctact.natattr()
|
||||
|
||||
if actstr.startswith("("):
|
||||
parencount += 1
|
||||
t = None
|
||||
actstr = actstr[1:]
|
||||
if actstr.startswith("src"):
|
||||
|
@ -607,15 +632,29 @@ class ovsactions(nla):
|
|||
actstr = actstr[strspn(actstr, ", ") :]
|
||||
|
||||
ctact["attrs"].append(["OVS_CT_ATTR_NAT", natact])
|
||||
actstr = actstr[strspn(actstr, ",) ") :]
|
||||
actstr = actstr[strspn(actstr, ", ") :]
|
||||
|
||||
self["attrs"].append(["OVS_ACTION_ATTR_CT", ctact])
|
||||
parsed = True
|
||||
|
||||
actstr = actstr[strspn(actstr, "), ") :]
|
||||
actstr = actstr[strspn(actstr, ", ") :]
|
||||
while parencount > 0:
|
||||
parencount -= 1
|
||||
actstr = actstr[strspn(actstr, " "):]
|
||||
if len(actstr) and actstr[0] != ")":
|
||||
raise ValueError("Action str: '%s' unbalanced" % actstr)
|
||||
actstr = actstr[1:]
|
||||
|
||||
if len(actstr) and actstr[0] == ")":
|
||||
return (totallen - len(actstr))
|
||||
|
||||
actstr = actstr[strspn(actstr, ", ") :]
|
||||
|
||||
if not parsed:
|
||||
raise ValueError("Action str: '%s' not supported" % actstr)
|
||||
|
||||
return (totallen - len(actstr))
|
||||
|
||||
|
||||
class ovskey(nla):
|
||||
nla_flags = NLA_F_NESTED
|
||||
|
@ -2111,6 +2150,8 @@ def main(argv):
|
|||
ovsflow = OvsFlow()
|
||||
ndb = NDB()
|
||||
|
||||
sys.setrecursionlimit(100000)
|
||||
|
||||
if hasattr(args, "showdp"):
|
||||
found = False
|
||||
for iface in ndb.interfaces:
|
||||
|
|
Loading…
Reference in a new issue