summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@mellanox.com>2018-12-09 11:10:24 -0500
committerDavid S. Miller <davem@davemloft.net>2018-12-09 14:55:08 -0500
commit35cc3cefc4de90001c9137e2d01dd9d06b11acfb (patch)
treeb7937759d6c916ac896be9f1ed97d65be6812c03 /net
parentd4b60e94e9bbe8c3b57e9cd126bed4a411ac5f6e (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.c23
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;