diff options
author | Jiri Pirko <jiri@mellanox.com> | 2020-03-07 12:40:13 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-03-09 05:07:48 +0100 |
commit | 319a1d19471ec49b8a91a7f6a3fe2c4535e5c279 (patch) | |
tree | 79e4bd8825d56c9ff7662c60e7d129972e866621 /include/net/flow_offload.h | |
parent | ocelot_flower: use flow_offload_has_one_action() helper (diff) | |
download | linux-319a1d19471ec49b8a91a7f6a3fe2c4535e5c279.tar.xz linux-319a1d19471ec49b8a91a7f6a3fe2c4535e5c279.zip |
flow_offload: check for basic action hw stats type
Introduce flow_action_basic_hw_stats_types_check() helper and use it
in drivers. That sanitizes the drivers which do not have support
for action HW stats types.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/flow_offload.h')
-rw-r--r-- | include/net/flow_offload.h | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h index 93d17f37e980..8b40f612a565 100644 --- a/include/net/flow_offload.h +++ b/include/net/flow_offload.h @@ -3,6 +3,7 @@ #include <linux/kernel.h> #include <linux/list.h> +#include <linux/netlink.h> #include <net/flow_dissector.h> #include <linux/rhashtable.h> @@ -251,6 +252,66 @@ static inline bool flow_offload_has_one_action(const struct flow_action *action) return action->num_entries == 1; } +static inline bool +flow_action_mixed_hw_stats_types_check(const struct flow_action *action, + struct netlink_ext_ack *extack) +{ + const struct flow_action_entry *action_entry; + u8 uninitialized_var(last_hw_stats_type); + int i; + + if (flow_offload_has_one_action(action)) + return true; + + for (i = 0; i < action->num_entries; i++) { + action_entry = &action->entries[i]; + if (i && action_entry->hw_stats_type != last_hw_stats_type) { + NL_SET_ERR_MSG_MOD(extack, "Mixing HW stats types for actions is not supported"); + return false; + } + last_hw_stats_type = action_entry->hw_stats_type; + } + return true; +} + +static inline const struct flow_action_entry * +flow_action_first_entry_get(const struct flow_action *action) +{ + WARN_ON(!flow_action_has_entries(action)); + return &action->entries[0]; +} + +static inline bool +flow_action_hw_stats_types_check(const struct flow_action *action, + struct netlink_ext_ack *extack, + u8 allowed_hw_stats_type) +{ + const struct flow_action_entry *action_entry; + + if (!flow_action_has_entries(action)) + return true; + if (!flow_action_mixed_hw_stats_types_check(action, extack)) + return false; + action_entry = flow_action_first_entry_get(action); + if (allowed_hw_stats_type == 0 && + action_entry->hw_stats_type != FLOW_ACTION_HW_STATS_TYPE_ANY) { + NL_SET_ERR_MSG_MOD(extack, "Driver supports only default HW stats type \"any\""); + return false; + } else if (allowed_hw_stats_type != 0 && + action_entry->hw_stats_type != allowed_hw_stats_type) { + NL_SET_ERR_MSG_MOD(extack, "Driver does not support selected HW stats type"); + return false; + } + return true; +} + +static inline bool +flow_action_basic_hw_stats_types_check(const struct flow_action *action, + struct netlink_ext_ack *extack) +{ + return flow_action_hw_stats_types_check(action, extack, 0); +} + #define flow_action_for_each(__i, __act, __actions) \ for (__i = 0, __act = &(__actions)->entries[0]; __i < (__actions)->num_entries; __act = &(__actions)->entries[++__i]) |