diff options
-rw-r--r-- | include/net/netfilter/nf_tables.h | 7 | ||||
-rw-r--r-- | net/netfilter/nf_tables_api.c | 38 |
2 files changed, 23 insertions, 22 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 79582d0b043e..81cd816554b9 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h | |||
@@ -49,11 +49,8 @@ struct nft_verdict { | |||
49 | 49 | ||
50 | struct nft_data { | 50 | struct nft_data { |
51 | union { | 51 | union { |
52 | u32 data[4]; | 52 | u32 data[4]; |
53 | struct { | 53 | struct nft_verdict verdict; |
54 | u32 verdict; | ||
55 | struct nft_chain *chain; | ||
56 | }; | ||
57 | }; | 54 | }; |
58 | } __attribute__((aligned(__alignof__(u64)))); | 55 | } __attribute__((aligned(__alignof__(u64)))); |
59 | 56 | ||
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index d47f12b2af25..0bb16a1561d2 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -4049,10 +4049,10 @@ static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx, | |||
4049 | return 0; | 4049 | return 0; |
4050 | 4050 | ||
4051 | data = nft_set_ext_data(ext); | 4051 | data = nft_set_ext_data(ext); |
4052 | switch (data->verdict) { | 4052 | switch (data->verdict.code) { |
4053 | case NFT_JUMP: | 4053 | case NFT_JUMP: |
4054 | case NFT_GOTO: | 4054 | case NFT_GOTO: |
4055 | return nf_tables_check_loops(ctx, data->chain); | 4055 | return nf_tables_check_loops(ctx, data->verdict.chain); |
4056 | default: | 4056 | default: |
4057 | return 0; | 4057 | return 0; |
4058 | } | 4058 | } |
@@ -4085,10 +4085,11 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx, | |||
4085 | if (data == NULL) | 4085 | if (data == NULL) |
4086 | continue; | 4086 | continue; |
4087 | 4087 | ||
4088 | switch (data->verdict) { | 4088 | switch (data->verdict.code) { |
4089 | case NFT_JUMP: | 4089 | case NFT_JUMP: |
4090 | case NFT_GOTO: | 4090 | case NFT_GOTO: |
4091 | err = nf_tables_check_loops(ctx, data->chain); | 4091 | err = nf_tables_check_loops(ctx, |
4092 | data->verdict.chain); | ||
4092 | if (err < 0) | 4093 | if (err < 0) |
4093 | return err; | 4094 | return err; |
4094 | default: | 4095 | default: |
@@ -4171,15 +4172,17 @@ int nft_validate_register_store(const struct nft_ctx *ctx, | |||
4171 | return -EINVAL; | 4172 | return -EINVAL; |
4172 | 4173 | ||
4173 | if (data != NULL && | 4174 | if (data != NULL && |
4174 | (data->verdict == NFT_GOTO || data->verdict == NFT_JUMP)) { | 4175 | (data->verdict.code == NFT_GOTO || |
4175 | err = nf_tables_check_loops(ctx, data->chain); | 4176 | data->verdict.code == NFT_JUMP)) { |
4177 | err = nf_tables_check_loops(ctx, data->verdict.chain); | ||
4176 | if (err < 0) | 4178 | if (err < 0) |
4177 | return err; | 4179 | return err; |
4178 | 4180 | ||
4179 | if (ctx->chain->level + 1 > data->chain->level) { | 4181 | if (ctx->chain->level + 1 > |
4182 | data->verdict.chain->level) { | ||
4180 | if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE) | 4183 | if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE) |
4181 | return -EMLINK; | 4184 | return -EMLINK; |
4182 | data->chain->level = ctx->chain->level + 1; | 4185 | data->verdict.chain->level = ctx->chain->level + 1; |
4183 | } | 4186 | } |
4184 | } | 4187 | } |
4185 | 4188 | ||
@@ -4220,11 +4223,11 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, | |||
4220 | 4223 | ||
4221 | if (!tb[NFTA_VERDICT_CODE]) | 4224 | if (!tb[NFTA_VERDICT_CODE]) |
4222 | return -EINVAL; | 4225 | return -EINVAL; |
4223 | data->verdict = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE])); | 4226 | data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE])); |
4224 | 4227 | ||
4225 | switch (data->verdict) { | 4228 | switch (data->verdict.code) { |
4226 | default: | 4229 | default: |
4227 | switch (data->verdict & NF_VERDICT_MASK) { | 4230 | switch (data->verdict.code & NF_VERDICT_MASK) { |
4228 | case NF_ACCEPT: | 4231 | case NF_ACCEPT: |
4229 | case NF_DROP: | 4232 | case NF_DROP: |
4230 | case NF_QUEUE: | 4233 | case NF_QUEUE: |
@@ -4250,7 +4253,7 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, | |||
4250 | return -EOPNOTSUPP; | 4253 | return -EOPNOTSUPP; |
4251 | 4254 | ||
4252 | chain->use++; | 4255 | chain->use++; |
4253 | data->chain = chain; | 4256 | data->verdict.chain = chain; |
4254 | desc->len = sizeof(data); | 4257 | desc->len = sizeof(data); |
4255 | break; | 4258 | break; |
4256 | } | 4259 | } |
@@ -4261,10 +4264,10 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, | |||
4261 | 4264 | ||
4262 | static void nft_verdict_uninit(const struct nft_data *data) | 4265 | static void nft_verdict_uninit(const struct nft_data *data) |
4263 | { | 4266 | { |
4264 | switch (data->verdict) { | 4267 | switch (data->verdict.code) { |
4265 | case NFT_JUMP: | 4268 | case NFT_JUMP: |
4266 | case NFT_GOTO: | 4269 | case NFT_GOTO: |
4267 | data->chain->use--; | 4270 | data->verdict.chain->use--; |
4268 | break; | 4271 | break; |
4269 | } | 4272 | } |
4270 | } | 4273 | } |
@@ -4277,13 +4280,14 @@ static int nft_verdict_dump(struct sk_buff *skb, const struct nft_data *data) | |||
4277 | if (!nest) | 4280 | if (!nest) |
4278 | goto nla_put_failure; | 4281 | goto nla_put_failure; |
4279 | 4282 | ||
4280 | if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict))) | 4283 | if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict.code))) |
4281 | goto nla_put_failure; | 4284 | goto nla_put_failure; |
4282 | 4285 | ||
4283 | switch (data->verdict) { | 4286 | switch (data->verdict.code) { |
4284 | case NFT_JUMP: | 4287 | case NFT_JUMP: |
4285 | case NFT_GOTO: | 4288 | case NFT_GOTO: |
4286 | if (nla_put_string(skb, NFTA_VERDICT_CHAIN, data->chain->name)) | 4289 | if (nla_put_string(skb, NFTA_VERDICT_CHAIN, |
4290 | data->verdict.chain->name)) | ||
4287 | goto nla_put_failure; | 4291 | goto nla_put_failure; |
4288 | } | 4292 | } |
4289 | nla_nest_end(skb, nest); | 4293 | nla_nest_end(skb, nest); |