diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 84893bc67531..09b359784629 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -1213,6 +1213,24 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, if (err < 0) goto errout; + if (tb[TCA_FLOWER_FLAGS]) { + fnew->flags = nla_get_u32(tb[TCA_FLOWER_FLAGS]); + + if (!tc_flags_valid(fnew->flags)) { + err = -EINVAL; + goto errout; + } + } + + err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], ovr, + tp->chain->tmplt_priv, extack); + if (err) + goto errout; + + err = fl_check_assign_mask(head, fnew, fold, mask); + if (err) + goto errout; + if (!handle) { handle = 1; err = idr_alloc_u32(&head->handle_idr, fnew, &handle, @@ -1223,37 +1241,19 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, handle, GFP_KERNEL); } if (err) - goto errout; + goto errout_mask; fnew->handle = handle; - if (tb[TCA_FLOWER_FLAGS]) { - fnew->flags = nla_get_u32(tb[TCA_FLOWER_FLAGS]); - - if (!tc_flags_valid(fnew->flags)) { - err = -EINVAL; - goto errout_idr; - } - } - - err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], ovr, - tp->chain->tmplt_priv, extack); - if (err) - goto errout_idr; - - err = fl_check_assign_mask(head, fnew, fold, mask); - if (err) - goto errout_idr; - if (!tc_skip_sw(fnew->flags)) { if (!fold && fl_lookup(fnew->mask, &fnew->mkey)) { err = -EEXIST; - goto errout_mask; + goto errout_idr; } err = rhashtable_insert_fast(&fnew->mask->ht, &fnew->ht_node, fnew->mask->filter_ht_params); if (err) - goto errout_mask; + goto errout_idr; } if (!tc_skip_hw(fnew->flags)) { @@ -1290,12 +1290,13 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, kfree(mask); return 0; -errout_mask: - fl_mask_put(head, fnew->mask, false); - errout_idr: if (!fold) idr_remove(&head->handle_idr, fnew->handle); + +errout_mask: + fl_mask_put(head, fnew->mask, false); + errout: tcf_exts_destroy(&fnew->exts); kfree(fnew);