Blob Blame History Raw
From: Jiri Pirko <jiri@mellanox.com>
Date: Tue, 6 Jun 2017 14:12:02 +0200
Subject: net: sched: introduce a TRAP control action
Patch-mainline: v4.13-rc1
Git-commit: e25ea21ffa66a029acfa89d2611c0e7ef23e7d8c
References: bsc#1056787

There is need to instruct the HW offloaded path to push certain matched
packets to cpu/kernel for further analysis. So this patch introduces a
new TRAP control action to TC.

For kernel datapath, this action does not make much sense. So with the
same logic as in HW, new TRAP behaves similar to STOLEN. The skb is just
dropped in the datapath (and virtually ejected to an upper level, which
does not exist in case of kernel).

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Yotam Gigi <yotamg@mellanox.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
 include/uapi/linux/pkt_cls.h |    7 +++++++
 net/core/dev.c               |    2 ++
 net/sched/cls_bpf.c          |    1 +
 net/sched/sch_atm.c          |    1 +
 net/sched/sch_cbq.c          |    1 +
 net/sched/sch_drr.c          |    1 +
 net/sched/sch_dsmark.c       |    1 +
 net/sched/sch_fq_codel.c     |    1 +
 net/sched/sch_hfsc.c         |    1 +
 net/sched/sch_htb.c          |    1 +
 net/sched/sch_multiq.c       |    1 +
 net/sched/sch_prio.c         |    1 +
 net/sched/sch_qfq.c          |    1 +
 net/sched/sch_sfb.c          |    1 +
 net/sched/sch_sfq.c          |    1 +
 15 files changed, 22 insertions(+)

--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -37,6 +37,13 @@ enum {
 #define TC_ACT_QUEUED		5
 #define TC_ACT_REPEAT		6
 #define TC_ACT_REDIRECT		7
+#define TC_ACT_TRAP		8 /* For hw path, this means "trap to cpu"
+				   * and don't further process the frame
+				   * in hardware. For sw path, this is
+				   * equivalent of TC_ACT_STOLEN - drop
+				   * the skb and act like everything
+				   * is alright.
+				   */
 
 /* There is a special kind of actions called "extended actions",
  * which need a value parameter. These have a local opcode located in
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3270,6 +3270,7 @@ sch_handle_egress(struct sk_buff *skb, i
 		return NULL;
 	case TC_ACT_STOLEN:
 	case TC_ACT_QUEUED:
+	case TC_ACT_TRAP:
 		*ret = NET_XMIT_SUCCESS;
 		consume_skb(skb);
 		return NULL;
@@ -4039,6 +4040,7 @@ sch_handle_ingress(struct sk_buff *skb,
 		return NULL;
 	case TC_ACT_STOLEN:
 	case TC_ACT_QUEUED:
+	case TC_ACT_TRAP:
 		consume_skb(skb);
 		return NULL;
 	case TC_ACT_REDIRECT:
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -70,6 +70,7 @@ static int cls_bpf_exec_opcode(int code)
 	case TC_ACT_OK:
 	case TC_ACT_SHOT:
 	case TC_ACT_STOLEN:
+	case TC_ACT_TRAP:
 	case TC_ACT_REDIRECT:
 	case TC_ACT_UNSPEC:
 		return code;
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -406,6 +406,7 @@ done:
 		switch (result) {
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
+		case TC_ACT_TRAP:
 			__qdisc_drop(skb, to_free);
 			return NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -254,6 +254,7 @@ cbq_classify(struct sk_buff *skb, struct
 		switch (result) {
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
+		case TC_ACT_TRAP:
 			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return NULL;
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -339,6 +339,7 @@ static struct drr_class *drr_classify(st
 		switch (result) {
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
+		case TC_ACT_TRAP:
 			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return NULL;
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -243,6 +243,7 @@ static int dsmark_enqueue(struct sk_buff
 #ifdef CONFIG_NET_CLS_ACT
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
+		case TC_ACT_TRAP:
 			__qdisc_drop(skb, to_free);
 			return NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -103,6 +103,7 @@ static unsigned int fq_codel_classify(st
 		switch (result) {
 		case TC_ACT_STOLEN:
 		case TC_ACT_QUEUED:
+		case TC_ACT_TRAP:
 			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return 0;
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1155,6 +1155,7 @@ hfsc_classify(struct sk_buff *skb, struc
 		switch (result) {
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
+		case TC_ACT_TRAP:
 			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return NULL;
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -238,6 +238,7 @@ static struct htb_class *htb_classify(st
 		switch (result) {
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
+		case TC_ACT_TRAP:
 			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return NULL;
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -52,6 +52,7 @@ multiq_classify(struct sk_buff *skb, str
 	switch (err) {
 	case TC_ACT_STOLEN:
 	case TC_ACT_QUEUED:
+	case TC_ACT_TRAP:
 		*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 	case TC_ACT_SHOT:
 		return NULL;
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -48,6 +48,7 @@ prio_classify(struct sk_buff *skb, struc
 		switch (err) {
 		case TC_ACT_STOLEN:
 		case TC_ACT_QUEUED:
+		case TC_ACT_TRAP:
 			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return NULL;
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -726,6 +726,7 @@ static struct qfq_class *qfq_classify(st
 		switch (result) {
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
+		case TC_ACT_TRAP:
 			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return NULL;
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -266,6 +266,7 @@ static bool sfb_classify(struct sk_buff
 		switch (result) {
 		case TC_ACT_STOLEN:
 		case TC_ACT_QUEUED:
+		case TC_ACT_TRAP:
 			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return false;
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -187,6 +187,7 @@ static unsigned int sfq_classify(struct
 		switch (result) {
 		case TC_ACT_STOLEN:
 		case TC_ACT_QUEUED:
+		case TC_ACT_TRAP:
 			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return 0;