View | Details | Raw Unified | Return to bug 1215420
Collapse All | Expand All

(-)a/net/netfilter/nf_tables_api.c (-30 / +77 lines)
Lines 2397-2404 struct nft_set *nf_tables_set_lookup(const struct nft_table *table, Link Here
2397
		return ERR_PTR(-EINVAL);
2397
		return ERR_PTR(-EINVAL);
2398
2398
2399
	list_for_each_entry(set, &table->sets, list) {
2399
	list_for_each_entry(set, &table->sets, list) {
2400
		if (!nla_strcmp(nla, set->name))
2400
		if (!nla_strcmp(nla, set->name)) {
2401
			if (!nft_set_get(set))
2402
				break;
2401
			return set;
2403
			return set;
2404
		}
2402
	}
2405
	}
2403
	return ERR_PTR(-ENOENT);
2406
	return ERR_PTR(-ENOENT);
2404
}
2407
}
Lines 2407-2418 struct nft_set *nf_tables_set_lookup_byid(const struct net *net, Link Here
2407
					  const struct nlattr *nla)
2410
					  const struct nlattr *nla)
2408
{
2411
{
2409
	struct nft_trans *trans;
2412
	struct nft_trans *trans;
2413
	struct nft_set *set;
2410
	u32 id = ntohl(nla_get_be32(nla));
2414
	u32 id = ntohl(nla_get_be32(nla));
2411
2415
2412
	list_for_each_entry(trans, &net->nft.commit_list, list) {
2416
	list_for_each_entry(trans, &net->nft.commit_list, list) {
2413
		if (trans->msg_type == NFT_MSG_NEWSET &&
2417
		if (trans->msg_type == NFT_MSG_NEWSET &&
2414
		    id == nft_trans_set_id(trans))
2418
		    id == nft_trans_set_id(trans)) {
2419
			set = nft_trans_set(trans);
2420
			if (!nft_set_get(set))
2421
				break;
2415
			return nft_trans_set(trans);
2422
			return nft_trans_set(trans);
2423
		}
2416
	}
2424
	}
2417
	return ERR_PTR(-ENOENT);
2425
	return ERR_PTR(-ENOENT);
2418
}
2426
}
Lines 2672-2692 static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb, Link Here
2672
	set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
2680
	set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
2673
	if (IS_ERR(set))
2681
	if (IS_ERR(set))
2674
		return PTR_ERR(set);
2682
		return PTR_ERR(set);
2675
	if (set->flags & NFT_SET_INACTIVE)
2683
	if (set->flags & NFT_SET_INACTIVE) {
2676
		return -ENOENT;
2684
		err = -ENOENT;
2685
		goto out_put;
2686
	}
2677
2687
2678
	skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
2688
	skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
2679
	if (skb2 == NULL)
2689
	if (skb2 == NULL) {
2680
		return -ENOMEM;
2690
		err = -ENOMEM;
2691
		goto out_put;
2692
	}
2681
2693
2682
	err = nf_tables_fill_set(skb2, &ctx, set, NFT_MSG_NEWSET, 0);
2694
	err = nf_tables_fill_set(skb2, &ctx, set, NFT_MSG_NEWSET, 0);
2683
	if (err < 0)
2695
	if (err < 0)
2684
		goto err;
2696
		goto err;
2685
2697
	nft_set_put((struct nft_set *)set);
2686
	return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
2698
	return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
2687
2699
2688
err:
2700
err:
2689
	kfree_skb(skb2);
2701
	kfree_skb(skb2);
2702
out_put:
2703
	nft_set_put((struct nft_set *)set);
2690
	return err;
2704
	return err;
2691
}
2705
}
2692
2706
Lines 2821-2831 static int nf_tables_newset(struct net *net, struct sock *nlsk, Link Here
2821
	}
2835
	}
2822
2836
2823
	if (set != NULL) {
2837
	if (set != NULL) {
2838
		err = 0;
2824
		if (nlh->nlmsg_flags & NLM_F_EXCL)
2839
		if (nlh->nlmsg_flags & NLM_F_EXCL)
2825
			return -EEXIST;
2840
			err = -EEXIST;
2826
		if (nlh->nlmsg_flags & NLM_F_REPLACE)
2841
		else if (nlh->nlmsg_flags & NLM_F_REPLACE)
2827
			return -EOPNOTSUPP;
2842
			err = -EOPNOTSUPP;
2828
		return 0;
2843
		nft_set_put(set);
2844
		return err;
2829
	}
2845
	}
2830
2846
2831
	if (!(nlh->nlmsg_flags & NLM_F_CREATE))
2847
	if (!(nlh->nlmsg_flags & NLM_F_CREATE))
Lines 2917-2928 static int nf_tables_delset(struct net *net, struct sock *nlsk, Link Here
2917
	set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
2933
	set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
2918
	if (IS_ERR(set))
2934
	if (IS_ERR(set))
2919
		return PTR_ERR(set);
2935
		return PTR_ERR(set);
2920
	if (set->flags & NFT_SET_INACTIVE)
2936
	if (set->flags & NFT_SET_INACTIVE) {
2921
		return -ENOENT;
2937
		err = -ENOENT;
2922
	if (!list_empty(&set->bindings))
2938
		goto out_put;
2923
		return -EBUSY;
2939
	}
2924
2940
	if (!list_empty(&set->bindings)) {
2925
	return nft_delset(&ctx, set);
2941
		err = -EBUSY;
2942
		goto out_put;
2943
	}
2944
	err = nft_delset(&ctx, set);
2945
out_put:
2946
	nft_set_put(set);
2947
	return err;
2926
}
2948
}
2927
2949
2928
static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
2950
static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
Lines 3172-3179 static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) Link Here
3172
	set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
3194
	set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
3173
	if (IS_ERR(set))
3195
	if (IS_ERR(set))
3174
		return PTR_ERR(set);
3196
		return PTR_ERR(set);
3175
	if (set->flags & NFT_SET_INACTIVE)
3197
	if (set->flags & NFT_SET_INACTIVE) {
3198
		nft_set_put((struct nft_set *)set);
3176
		return -ENOENT;
3199
		return -ENOENT;
3200
	}
3177
3201
3178
	event  = NFT_MSG_NEWSETELEM;
3202
	event  = NFT_MSG_NEWSETELEM;
3179
	event |= NFNL_SUBSYS_NFTABLES << 8;
3203
	event |= NFNL_SUBSYS_NFTABLES << 8;
Lines 3182-3203 static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) Link Here
3182
3206
3183
	nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
3207
	nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
3184
			NLM_F_MULTI);
3208
			NLM_F_MULTI);
3185
	if (nlh == NULL)
3209
	if (nlh == NULL) {
3210
		err = -ENOSPC;
3186
		goto nla_put_failure;
3211
		goto nla_put_failure;
3212
	}
3187
3213
3188
	nfmsg = nlmsg_data(nlh);
3214
	nfmsg = nlmsg_data(nlh);
3189
	nfmsg->nfgen_family = ctx.afi->family;
3215
	nfmsg->nfgen_family = ctx.afi->family;
3190
	nfmsg->version      = NFNETLINK_V0;
3216
	nfmsg->version      = NFNETLINK_V0;
3191
	nfmsg->res_id	    = htons(ctx.net->nft.base_seq & 0xffff);
3217
	nfmsg->res_id	    = htons(ctx.net->nft.base_seq & 0xffff);
3192
3218
3193
	if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, ctx.table->name))
3219
	if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, ctx.table->name)) {
3220
		err = -ENOSPC;
3194
		goto nla_put_failure;
3221
		goto nla_put_failure;
3195
	if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name))
3222
	}
3223
	if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name)) {
3224
		err = -ENOSPC;
3196
		goto nla_put_failure;
3225
		goto nla_put_failure;
3226
	}
3197
3227
3198
	nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
3228
	nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
3199
	if (nest == NULL)
3229
	if (nest == NULL) {
3230
		err = -ENOSPC;
3200
		goto nla_put_failure;
3231
		goto nla_put_failure;
3232
	}
3201
3233
3202
	args.cb		= cb;
3234
	args.cb		= cb;
3203
	args.skb	= skb;
3235
	args.skb	= skb;
Lines 3209-3214 static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) Link Here
3209
3241
3210
	nla_nest_end(skb, nest);
3242
	nla_nest_end(skb, nest);
3211
	nlmsg_end(skb, nlh);
3243
	nlmsg_end(skb, nlh);
3244
	nft_set_put((struct nft_set *)set);
3212
3245
3213
	if (args.iter.err && args.iter.err != -EMSGSIZE)
3246
	if (args.iter.err && args.iter.err != -EMSGSIZE)
3214
		return args.iter.err;
3247
		return args.iter.err;
Lines 3219-3224 static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) Link Here
3219
	return skb->len;
3252
	return skb->len;
3220
3253
3221
nla_put_failure:
3254
nla_put_failure:
3255
	nft_set_put((struct nft_set *)set);
3222
	return -ENOSPC;
3256
	return -ENOSPC;
3223
}
3257
}
3224
3258
Lines 3238-3253 static int nf_tables_getsetelem(struct sock *nlsk, struct sk_buff *skb, Link Here
3238
	set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
3272
	set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
3239
	if (IS_ERR(set))
3273
	if (IS_ERR(set))
3240
		return PTR_ERR(set);
3274
		return PTR_ERR(set);
3241
	if (set->flags & NFT_SET_INACTIVE)
3275
	if (set->flags & NFT_SET_INACTIVE) {
3242
		return -ENOENT;
3276
		err = -ENOENT;
3277
		goto out_put;
3278
	}
3243
3279
3244
	if (nlh->nlmsg_flags & NLM_F_DUMP) {
3280
	if (nlh->nlmsg_flags & NLM_F_DUMP) {
3245
		struct netlink_dump_control c = {
3281
		struct netlink_dump_control c = {
3246
			.dump = nf_tables_dump_set,
3282
			.dump = nf_tables_dump_set,
3247
		};
3283
		};
3248
		return netlink_dump_start(nlsk, skb, nlh, &c);
3284
		err = netlink_dump_start(nlsk, skb, nlh, &c);
3285
		goto out_put;
3249
	}
3286
	}
3250
	return -EOPNOTSUPP;
3287
	err = -EOPNOTSUPP;
3288
out_put:
3289
	nft_set_put((struct nft_set *)set);
3290
	return err;
3251
}
3291
}
3252
3292
3253
static int nf_tables_fill_setelem_info(struct sk_buff *skb,
3293
static int nf_tables_fill_setelem_info(struct sk_buff *skb,
Lines 3569-3581 static int nf_tables_newsetelem(struct net *net, struct sock *nlsk, Link Here
3569
			return PTR_ERR(set);
3609
			return PTR_ERR(set);
3570
	}
3610
	}
3571
3611
3572
	if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
3612
	if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT) {
3613
		nft_set_put(set);
3573
		return -EBUSY;
3614
		return -EBUSY;
3615
	}
3574
3616
3575
	nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
3617
	nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
3576
		if (set->size &&
3618
		if (set->size &&
3577
		    !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact))
3619
		    !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact)) {
3620
			nft_set_put(set);
3578
			return -ENFILE;
3621
			return -ENFILE;
3622
		}
3579
3623
3580
		err = nft_add_set_elem(&ctx, set, attr);
3624
		err = nft_add_set_elem(&ctx, set, attr);
3581
		if (err < 0) {
3625
		if (err < 0) {
Lines 3583-3588 static int nf_tables_newsetelem(struct net *net, struct sock *nlsk, Link Here
3583
			break;
3627
			break;
3584
		}
3628
		}
3585
	}
3629
	}
3630
	nft_set_put(set);
3586
	return err;
3631
	return err;
3587
}
3632
}
3588
3633
Lines 3656-3663 static int nf_tables_delsetelem(struct net *net, struct sock *nlsk, Link Here
3656
	set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
3701
	set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
3657
	if (IS_ERR(set))
3702
	if (IS_ERR(set))
3658
		return PTR_ERR(set);
3703
		return PTR_ERR(set);
3659
	if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
3704
	if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT) {
3705
		nft_set_put(set);
3660
		return -EBUSY;
3706
		return -EBUSY;
3707
	}
3661
3708
3662
	nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
3709
	nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
3663
		err = nft_del_setelem(&ctx, set, attr);
3710
		err = nft_del_setelem(&ctx, set, attr);
Lines 3666-3671 static int nf_tables_delsetelem(struct net *net, struct sock *nlsk, Link Here
3666
3713
3667
		set->ndeact++;
3714
		set->ndeact++;
3668
	}
3715
	}
3716
	nft_set_put(set);
3669
	return err;
3717
	return err;
3670
}
3718
}
3671
3719
3672
- 

Return to bug 1215420