flow_offload: add control flag checking helpers

These helpers aim to help drivers, with checking
for the presence of unsupported control flags.

For drivers supporting at least one control flag:
  flow_rule_is_supp_control_flags()

For drivers using flow_rule_match_control(), but not using flags:
  flow_rule_has_control_flags()

For drivers not using flow_rule_match_control():
  flow_rule_match_has_control_flags()

While primarily aimed at FLOW_DISSECTOR_KEY_CONTROL
and flow_rule_match_control(), then the first two
can also be used with FLOW_DISSECTOR_KEY_ENC_CONTROL
and flow_rule_match_enc_control().

These helpers mirrors the existing check done in sfc:
  drivers/net/ethernet/sfc/tc.c +276

Only compile-tested.

Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
Reviewed-by: Louis Peens <louis.peens@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Asbjørn Sloth Tønnesen 2024-04-11 10:52:54 +00:00 committed by David S. Miller
parent 3db3b62955
commit d11e631194

View File

@ -449,6 +449,61 @@ static inline bool flow_rule_match_key(const struct flow_rule *rule,
return dissector_uses_key(rule->match.dissector, key);
}
/**
* flow_rule_is_supp_control_flags() - check for supported control flags
* @supp_flags: control flags supported by driver
* @ctrl_flags: control flags present in rule
* @extack: The netlink extended ACK for reporting errors.
*
* Return: true if only supported control flags are set, false otherwise.
*/
static inline bool flow_rule_is_supp_control_flags(const u32 supp_flags,
const u32 ctrl_flags,
struct netlink_ext_ack *extack)
{
if (likely((ctrl_flags & ~supp_flags) == 0))
return true;
NL_SET_ERR_MSG_FMT_MOD(extack,
"Unsupported match on control.flags %#x",
ctrl_flags);
return false;
}
/**
* flow_rule_has_control_flags() - check for presence of any control flags
* @ctrl_flags: control flags present in rule
* @extack: The netlink extended ACK for reporting errors.
*
* Return: true if control flags are set, false otherwise.
*/
static inline bool flow_rule_has_control_flags(const u32 ctrl_flags,
struct netlink_ext_ack *extack)
{
return !flow_rule_is_supp_control_flags(0, ctrl_flags, extack);
}
/**
* flow_rule_match_has_control_flags() - match and check for any control flags
* @rule: The flow_rule under evaluation.
* @extack: The netlink extended ACK for reporting errors.
*
* Return: true if control flags are set, false otherwise.
*/
static inline bool flow_rule_match_has_control_flags(struct flow_rule *rule,
struct netlink_ext_ack *extack)
{
struct flow_match_control match;
if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL))
return false;
flow_rule_match_control(rule, &match);
return flow_rule_has_control_flags(match.mask->flags, extack);
}
struct flow_stats {
u64 pkts;
u64 bytes;