From 55a10ba77b264dc66afcb6aa7a76ee0e2896731f Mon Sep 17 00:00:00 2001
From: "Rastogi, Deepansh" <deepansh.rastogi@intel.com>
Date: Mon, 19 Mar 2018 09:13:11 +0100
Subject: [PATCH] Merge pull request #262 in SW_PON/linux from
 feature/UGW_SW-20918-tc-extension-for-extmark to xrx500

* commit 'b68fc609bc49e3e2a34958e494237115d7f2b529':
  fixed review comments
  UGW_SW-20918 : Add extmark based classify in u32 filter of linux  Traffic Control system
---
 include/uapi/linux/pkt_cls.h |  1 +
 net/sched/Kconfig            |  6 ++++++
 net/sched/cls_u32.c          | 29 +++++++++++++++++++++++++++++
 3 files changed, 36 insertions(+)

diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 8fd715f80..cf45c4468 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -182,6 +182,7 @@ enum {
 	TCA_U32_MARK,
 	TCA_U32_FLAGS,
 	TCA_U32_PAD,
+	TCA_U32_EXTMARK,
 	__TCA_U32_MAX
 };
 
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 87956a768..a970e65eb 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -423,6 +423,12 @@ config CLS_U32_MARK
 	---help---
 	  Say Y here to be able to use netfilter marks as u32 key.
 
+config CLS_U32_EXTMARK
+	bool "Netfilter extended marks support"
+	depends on NET_CLS_U32
+	---help---
+	  Say Y here to be able to use netfilter marks as u32 key.
+
 config NET_CLS_RSVP
 	tristate "IPv4 Resource Reservation Protocol (RSVP)"
 	select NET_CLS
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index ae83c3aec..f1b770d2f 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -64,6 +64,9 @@ struct tc_u_knode {
 	u32			val;
 	u32			mask;
 	u32 __percpu		*pcpu_success;
+#endif
+#ifdef CONFIG_CLS_U32_EXTMARK
+	struct tc_u32_mark      extmark;
 #endif
 	struct tcf_proto	*tp;
 	struct rcu_head		rcu;
@@ -148,6 +151,14 @@ next_knode:
 			__this_cpu_inc(*n->pcpu_success);
 		}
 #endif
+#ifdef CONFIG_CLS_U32_EXTMARK
+		if ((skb->extmark & n->extmark.mask) != n->extmark.val) {
+			n = n->next;
+			goto next_knode;
+		} else {
+			n->extmark.success++;
+		}
+#endif
 
 		for (i = n->sel.nkeys; i > 0; i--, key++) {
 			int toff = off + key->off + (off2 & key->offmask);
@@ -697,6 +708,9 @@ static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = {
 	[TCA_U32_SEL]		= { .len = sizeof(struct tc_u32_sel) },
 	[TCA_U32_INDEV]		= { .type = NLA_STRING, .len = IFNAMSIZ },
 	[TCA_U32_MARK]		= { .len = sizeof(struct tc_u32_mark) },
+#ifdef CONFIG_CLS_U32_EXTMARK
+	[TCA_U32_EXTMARK]	= { .len = sizeof(struct tc_u32_mark) },
+#endif
 	[TCA_U32_FLAGS]		= { .type = NLA_U32 },
 };
 
@@ -1005,6 +1019,15 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
 		n->mask = mark->mask;
 	}
 #endif
+#ifdef CONFIG_CLS_U32_EXTMARK
+	if (tb[TCA_U32_EXTMARK]) {
+		struct tc_u32_mark *extmark;
+
+		extmark = nla_data(tb[TCA_U32_EXTMARK]);
+		memcpy(&n->extmark, extmark, sizeof(struct tc_u32_mark));
+		n->extmark.success = 0;
+	}
+#endif
 
 	err = u32_set_parms(net, tp, base, ht, n, tb, tca[TCA_RATE], ovr);
 	if (err == 0) {
@@ -1149,6 +1172,12 @@ static int u32_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 				goto nla_put_failure;
 		}
 #endif
+#ifdef CONFIG_CLS_U32_EXTMARK
+		if ((n->extmark.val || n->extmark.mask) &&
+			nla_put(skb, TCA_U32_EXTMARK,
+				sizeof(n->extmark), &n->extmark))
+			goto nla_put_failure;
+#endif
 
 		if (tcf_exts_dump(skb, &n->exts) < 0)
 			goto nla_put_failure;
-- 
GitLab