diff options
author | Or Gerlitz <ogerlitz@mellanox.com> | 2018-12-09 11:10:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-12-09 14:55:08 -0500 |
commit | 35cc3cefc4de90001c9137e2d01dd9d06b11acfb (patch) | |
tree | b7937759d6c916ac896be9f1ed97d65be6812c03 /net | |
parent | d4b60e94e9bbe8c3b57e9cd126bed4a411ac5f6e (diff) |
net/sched: cls_flower: Reject duplicated rules also under skip_sw
Currently, duplicated rules are rejected only for skip_hw or "none",
hence allowing users to push duplicates into HW for no reason.
Use the flower tables to protect for that.
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Paul Blakey <paulb@mellanox.com>
Reported-by: Chris Mi <chrism@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/sched/cls_flower.c | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index c6c327874abc..71312d7bd8f4 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c | |||
@@ -1238,18 +1238,16 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, | |||
1238 | if (err) | 1238 | if (err) |
1239 | goto errout_idr; | 1239 | goto errout_idr; |
1240 | 1240 | ||
1241 | if (!tc_skip_sw(fnew->flags)) { | 1241 | if (!fold && fl_lookup(fnew->mask, &fnew->mkey)) { |
1242 | if (!fold && fl_lookup(fnew->mask, &fnew->mkey)) { | 1242 | err = -EEXIST; |
1243 | err = -EEXIST; | 1243 | goto errout_mask; |
1244 | goto errout_mask; | ||
1245 | } | ||
1246 | |||
1247 | err = rhashtable_insert_fast(&fnew->mask->ht, &fnew->ht_node, | ||
1248 | fnew->mask->filter_ht_params); | ||
1249 | if (err) | ||
1250 | goto errout_mask; | ||
1251 | } | 1244 | } |
1252 | 1245 | ||
1246 | err = rhashtable_insert_fast(&fnew->mask->ht, &fnew->ht_node, | ||
1247 | fnew->mask->filter_ht_params); | ||
1248 | if (err) | ||
1249 | goto errout_mask; | ||
1250 | |||
1253 | if (!tc_skip_hw(fnew->flags)) { | 1251 | if (!tc_skip_hw(fnew->flags)) { |
1254 | err = fl_hw_replace_filter(tp, fnew, extack); | 1252 | err = fl_hw_replace_filter(tp, fnew, extack); |
1255 | if (err) | 1253 | if (err) |
@@ -1303,9 +1301,8 @@ static int fl_delete(struct tcf_proto *tp, void *arg, bool *last, | |||
1303 | struct cls_fl_head *head = rtnl_dereference(tp->root); | 1301 | struct cls_fl_head *head = rtnl_dereference(tp->root); |
1304 | struct cls_fl_filter *f = arg; | 1302 | struct cls_fl_filter *f = arg; |
1305 | 1303 | ||
1306 | if (!tc_skip_sw(f->flags)) | 1304 | rhashtable_remove_fast(&f->mask->ht, &f->ht_node, |
1307 | rhashtable_remove_fast(&f->mask->ht, &f->ht_node, | 1305 | f->mask->filter_ht_params); |
1308 | f->mask->filter_ht_params); | ||
1309 | __fl_delete(tp, f, extack); | 1306 | __fl_delete(tp, f, extack); |
1310 | *last = list_empty(&head->masks); | 1307 | *last = list_empty(&head->masks); |
1311 | return 0; | 1308 | return 0; |