@@ -692,6 +692,7 @@ struct flow_cls_offload {
struct flow_cls_common_offload common;
enum flow_cls_command command;
bool use_act_stats;
+ bool skip_sw;
unsigned long cookie;
struct flow_rule *rule;
struct flow_stats stats;
@@ -782,6 +782,7 @@ struct tc_cls_matchall_offload {
struct flow_rule *rule;
struct flow_stats stats;
bool use_act_stats;
+ bool skip_sw;
unsigned long cookie;
};
@@ -480,6 +480,7 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
cls_flower.rule->match.mask = &f->mask->key;
cls_flower.rule->match.key = &f->mkey;
cls_flower.classid = f->res.classid;
+ cls_flower.skip_sw = skip_sw;
err = tc_setup_offload_action(&cls_flower.rule->action, &f->exts,
cls_flower.common.extack);
@@ -98,6 +98,7 @@ static int mall_replace_hw_filter(struct tcf_proto *tp,
tc_cls_common_offload_init(&cls_mall.common, tp, head->flags, extack);
cls_mall.command = TC_CLSMATCHALL_REPLACE;
cls_mall.cookie = cookie;
+ cls_mall.skip_sw = skip_sw;
err = tc_setup_offload_action(&cls_mall.rule->action, &head->exts,
cls_mall.common.extack);
In some cases, an offloaded filter can only do half the work, and the rest must be handled by software. For example, redirecting/mirroring from the ingress of a switchdev port towards a virtual interface like veth/dummy/etc that is completely foreign to said switchdev port. The most that the switchdev port can do is to extract the matching packets from its data path and send them to the CPU. From there on, the software filter runs (a second time) on the packet and performs the mirred. It makes sense for switchdev drivers which allow this kind of "half offloading" to sense the "skip_sw" flag of the filter/action, and deny attempts from the user to install a filter that does not run in software, because that simply won't work. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> --- include/net/flow_offload.h | 1 + include/net/pkt_cls.h | 1 + net/sched/cls_flower.c | 1 + net/sched/cls_matchall.c | 1 + 4 files changed, 4 insertions(+)