summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Blakey <paulb@mellanox.com>2017-01-16 11:45:13 +0300
committerDavid S. Miller <davem@davemloft.net>2017-01-16 23:05:44 +0300
commita3308d8fd1f58c67aaae52d9468791c2082ab2c7 (patch)
treeebcbb501ccaa2c2aa9da54a9894c12ec5b90e684
parenta50a05f497a2a6e772900ffe93246fb7243d86d8 (diff)
downloadlinux-a3308d8fd1f58c67aaae52d9468791c2082ab2c7.tar.xz
net/sched: cls_flower: Disallow duplicate internal elements
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>
-rw-r--r--net/sched/cls_flower.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index a3bfda3091a4..27934456d984 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -134,6 +134,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)
{
@@ -181,9 +189,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);
@@ -875,6 +881,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)