Merge tag 'Smack-for-6.5' of https://github.com/cschaufler/smack-next
[linux-2.6-microblaze.git] / net / sched / act_skbedit.c
index 7f59878..ce7008c 100644 (file)
@@ -16,6 +16,7 @@
 #include <net/ipv6.h>
 #include <net/dsfield.h>
 #include <net/pkt_cls.h>
+#include <net/tc_wrapper.h>
 
 #include <linux/tc_act/tc_skbedit.h>
 #include <net/tc_act/tc_skbedit.h>
@@ -36,8 +37,9 @@ static u16 tcf_skbedit_hash(struct tcf_skbedit_params *params,
        return netdev_cap_txqueue(skb->dev, queue_mapping);
 }
 
-static int tcf_skbedit_act(struct sk_buff *skb, const struct tc_action *a,
-                          struct tcf_result *res)
+TC_INDIRECT_SCOPE int tcf_skbedit_act(struct sk_buff *skb,
+                                     const struct tc_action *a,
+                                     struct tcf_result *res)
 {
        struct tcf_skbedit *d = to_skbedit(a);
        struct tcf_skbedit_params *params;
@@ -148,6 +150,11 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
        }
 
        if (tb[TCA_SKBEDIT_QUEUE_MAPPING] != NULL) {
+               if (is_tcf_skbedit_ingress(act_flags) &&
+                   !(act_flags & TCA_ACT_FLAGS_SKIP_SW)) {
+                       NL_SET_ERR_MSG_MOD(extack, "\"queue_mapping\" option on receive side is hardware only, use skip_sw");
+                       return -EOPNOTSUPP;
+               }
                flags |= SKBEDIT_F_QUEUE_MAPPING;
                queue_mapping = nla_data(tb[TCA_SKBEDIT_QUEUE_MAPPING]);
        }
@@ -374,9 +381,12 @@ static int tcf_skbedit_offload_act_setup(struct tc_action *act, void *entry_data
                } else if (is_tcf_skbedit_priority(act)) {
                        entry->id = FLOW_ACTION_PRIORITY;
                        entry->priority = tcf_skbedit_priority(act);
-               } else if (is_tcf_skbedit_queue_mapping(act)) {
-                       NL_SET_ERR_MSG_MOD(extack, "Offload not supported when \"queue_mapping\" option is used");
+               } else if (is_tcf_skbedit_tx_queue_mapping(act)) {
+                       NL_SET_ERR_MSG_MOD(extack, "Offload not supported when \"queue_mapping\" option is used on transmit side");
                        return -EOPNOTSUPP;
+               } else if (is_tcf_skbedit_rx_queue_mapping(act)) {
+                       entry->id = FLOW_ACTION_RX_QUEUE_MAPPING;
+                       entry->rx_queue = tcf_skbedit_rx_queue_mapping(act);
                } else if (is_tcf_skbedit_inheritdsfield(act)) {
                        NL_SET_ERR_MSG_MOD(extack, "Offload not supported when \"inheritdsfield\" option is used");
                        return -EOPNOTSUPP;
@@ -394,6 +404,8 @@ static int tcf_skbedit_offload_act_setup(struct tc_action *act, void *entry_data
                        fl_action->id = FLOW_ACTION_PTYPE;
                else if (is_tcf_skbedit_priority(act))
                        fl_action->id = FLOW_ACTION_PRIORITY;
+               else if (is_tcf_skbedit_rx_queue_mapping(act))
+                       fl_action->id = FLOW_ACTION_RX_QUEUE_MAPPING;
                else
                        return -EOPNOTSUPP;
        }