|
|
@@ -1213,47 +1213,47 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
|
|
|
if (err < 0)
|
|
|
goto errout;
|
|
|
|
|
|
- if (!handle) {
|
|
|
- handle = 1;
|
|
|
- err = idr_alloc_u32(&head->handle_idr, fnew, &handle,
|
|
|
- INT_MAX, GFP_KERNEL);
|
|
|
- } else if (!fold) {
|
|
|
- /* user specifies a handle and it doesn't exist */
|
|
|
- err = idr_alloc_u32(&head->handle_idr, fnew, &handle,
|
|
|
- handle, GFP_KERNEL);
|
|
|
- }
|
|
|
- if (err)
|
|
|
- goto errout;
|
|
|
- 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;
|
|
|
+ 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_idr;
|
|
|
+ goto errout;
|
|
|
|
|
|
err = fl_check_assign_mask(head, fnew, fold, mask);
|
|
|
if (err)
|
|
|
- goto errout_idr;
|
|
|
+ goto errout;
|
|
|
+
|
|
|
+ if (!handle) {
|
|
|
+ handle = 1;
|
|
|
+ err = idr_alloc_u32(&head->handle_idr, fnew, &handle,
|
|
|
+ INT_MAX, GFP_KERNEL);
|
|
|
+ } else if (!fold) {
|
|
|
+ /* user specifies a handle and it doesn't exist */
|
|
|
+ err = idr_alloc_u32(&head->handle_idr, fnew, &handle,
|
|
|
+ handle, GFP_KERNEL);
|
|
|
+ }
|
|
|
+ if (err)
|
|
|
+ goto errout_mask;
|
|
|
+ fnew->handle = handle;
|
|
|
|
|
|
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);
|