diff options
Diffstat (limited to 'net/sched/cls_flower.c')
-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 475fe222a855..9dbc43388e57 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -1057,7 +1057,7 @@ static void fl_set_key_pppoe(struct nlattr **tb, * because ETH_P_PPP_SES was stored in basic.n_proto * which might get overwritten by ppp_proto * or might be set to 0, the role of key_val::type - * is simmilar to vlan_key::tpid + * is similar to vlan_key::tpid */ key_val->type = htons(ETH_P_PPP_SES); key_mask->type = cpu_to_be16(~0); @@ -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 @@ -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(); |