diff mbox

[01/18] net/sched: cls_flower: Disallow duplicate internal elements

Message ID 1488100203-31976-1-git-send-email-talatb@mellanox.com
State New
Headers show

Commit Message

Talat Batheesh Feb. 26, 2017, 9:09 a.m. UTC
From: Paul Blakey <paulb@mellanox.com>

BugLink: https://bugs.launchpad.net/ubuntu/1668019

Flower currently allows having the same filter twice with the same
priority. Actions (and statistics update) will always execute on the
first inserted rule leaving the second rule unused.
This patch disallows that.

Signed-off-by: Paul Blakey <paulb@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit a3308d8fd1f58c67aaae52d9468791c2082ab2c7)
Signed-off-by: Talat Batheesh <talatb@mellanox.com>
---
 net/sched/cls_flower.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

Comments

Tim Gardner March 1, 2017, 2:04 p.m. UTC | #1
I fixed the BugLink and reordered the net/sched patches to be first on
the assumption that net/mlx5e depends on them.
diff mbox

Patch

diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 5752789..a9a3790 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -133,6 +133,14 @@  static void fl_clear_masked_range(struct fl_flow_key *key,
 	memset(fl_key_get_start(key, mask), 0, fl_mask_range(mask));
 }
 
+static struct cls_fl_filter *fl_lookup(struct cls_fl_head *head,
+				       struct fl_flow_key *mkey)
+{
+	return rhashtable_lookup_fast(&head->ht,
+				      fl_key_get_start(mkey, &head->mask),
+				      head->ht_params);
+}
+
 static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 		       struct tcf_result *res)
 {
@@ -180,9 +188,7 @@  static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 
 	fl_set_masked_key(&skb_mkey, &skb_key, &head->mask);
 
-	f = rhashtable_lookup_fast(&head->ht,
-				   fl_key_get_start(&skb_mkey, &head->mask),
-				   head->ht_params);
+	f = fl_lookup(head, &skb_mkey);
 	if (f && !tc_skip_sw(f->flags)) {
 		*res = f->res;
 		return tcf_exts_exec(skb, &f->exts, res);
@@ -845,6 +851,11 @@  static int fl_change(struct net *net, struct sk_buff *in_skb,
 		goto errout;
 
 	if (!tc_skip_sw(fnew->flags)) {
+		if (!fold && fl_lookup(head, &fnew->mkey)) {
+			err = -EEXIST;
+			goto errout;
+		}
+
 		err = rhashtable_insert_fast(&head->ht, &fnew->ht_node,
 					     head->ht_params);
 		if (err)