diff options
author | David S. Miller <davem@davemloft.net> | 2023-05-05 10:01:31 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2023-05-05 10:01:31 +0100 |
commit | 1a304495082e7e73a96b9facac1eb93b6b0498a4 (patch) | |
tree | b1bd88643569881ff71174b82f00e9801d8069c3 | |
parent | 26312c685ae0bca61e06ac75ee158b1e69546415 (diff) | |
parent | fd741f0d9f702c193b2b44225c004f8c5d5be163 (diff) |
Merge branch 'tc-action-fixes'
Vlad Buslov says:
====================
Fixes for miss to tc action series
Changes V1 -> V2:
- Added new patch reverting Ivan's fix for the same issue.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sched/cls_flower.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 6ab6aadc07b8..9dbc43388e57 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -2210,10 +2210,10 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, spin_lock(&tp->lock); if (!handle) { handle = 1; - err = idr_alloc_u32(&head->handle_idr, fnew, &handle, + err = idr_alloc_u32(&head->handle_idr, NULL, &handle, INT_MAX, GFP_ATOMIC); } else { - err = idr_alloc_u32(&head->handle_idr, fnew, &handle, + err = idr_alloc_u32(&head->handle_idr, NULL, &handle, handle, GFP_ATOMIC); /* Filter with specified handle was concurrently @@ -2231,8 +2231,8 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, kfree(fnew); goto errout_tb; } - fnew->handle = handle; } + fnew->handle = handle; err = tcf_exts_init_ex(&fnew->exts, net, TCA_FLOWER_ACT, 0, tp, handle, !tc_skip_hw(fnew->flags)); @@ -2339,7 +2339,8 @@ errout_hw: errout_mask: fl_mask_put(head, fnew->mask); errout_idr: - idr_remove(&head->handle_idr, fnew->handle); + if (!fold) + idr_remove(&head->handle_idr, fnew->handle); __fl_put(fnew); errout_tb: kfree(tb); @@ -2378,7 +2379,7 @@ static void fl_walk(struct tcf_proto *tp, struct tcf_walker *arg, rcu_read_lock(); idr_for_each_entry_continue_ul(&head->handle_idr, f, tmp, id) { /* don't return filters that are being deleted */ - if (!refcount_inc_not_zero(&f->refcnt)) + if (!f || !refcount_inc_not_zero(&f->refcnt)) continue; rcu_read_unlock(); |