summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2023-05-05 12:01:31 +0300
committerDavid S. Miller <davem@davemloft.net>2023-05-05 12:01:31 +0300
commit1a304495082e7e73a96b9facac1eb93b6b0498a4 (patch)
treeb1bd88643569881ff71174b82f00e9801d8069c3
parent26312c685ae0bca61e06ac75ee158b1e69546415 (diff)
parentfd741f0d9f702c193b2b44225c004f8c5d5be163 (diff)
downloadlinux-1a304495082e7e73a96b9facac1eb93b6b0498a4.tar.xz
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.c11
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();