flow_offload: add control flag checking helpers
authorAsbjørn Sloth Tønnesen <ast@fiberby.net>
Thu, 11 Apr 2024 10:52:54 +0000 (10:52 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 15 Apr 2024 09:33:14 +0000 (10:33 +0100)
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>
include/net/flow_offload.h

index 7726b4a97050e3e142f1d493a90267ac89f2c11c..ec9f80509f60c61dee606e40ac53332dbb982348 100644 (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;