|
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 |
- |
|
|