From: Patrick McHardy <kaber@xxxxxxxxx> Non-base-chains can not have a policy, so move the policy member to struct nft_base_chain. Also return an error when trying to add a policy to a non-base-chain. Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx> --- include/net/netfilter/nf_tables.h | 4 +++- net/netfilter/nf_tables_api.c | 26 +++++++++++++++----------- net/netfilter/nf_tables_core.c | 2 +- 3 Dateien geändert, 19 Zeilen hinzugefügt(+), 13 Zeilen entfernt(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 86fd951..d1a8e9e 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -355,7 +355,6 @@ struct nft_chain { struct list_head rules; struct list_head list; u8 flags; - u8 policy; u16 use; u16 level; char name[NFT_CHAIN_MAXNAMELEN]; @@ -372,11 +371,14 @@ enum nft_chain_type { * struct nft_base_chain - nf_tables base chain * * @ops: netfilter hook ops + * @type: chain type + * @policy: default policy * @chain: the chain */ struct nft_base_chain { struct nf_hook_ops ops; enum nft_chain_type type; + u8 policy; struct nft_chain chain; }; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 9768881..11502db 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -531,8 +531,11 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, u32 portid, u32 seq, goto nla_put_failure; if (chain->flags & NFT_BASE_CHAIN) { - const struct nf_hook_ops *ops = &nft_base_chain(chain)->ops; - struct nlattr *nest = nla_nest_start(skb, NFTA_CHAIN_HOOK); + const struct nft_base_chain *basechain = nft_base_chain(chain); + const struct nf_hook_ops *ops = &basechain->ops; + struct nlattr *nest; + + nest = nla_nest_start(skb, NFTA_CHAIN_HOOK); if (nest == NULL) goto nla_put_failure; if (nla_put_be32(skb, NFTA_HOOK_HOOKNUM, htonl(ops->hooknum))) @@ -541,7 +544,8 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, u32 portid, u32 seq, goto nla_put_failure; nla_nest_end(skb, nest); - if (nla_put_be32(skb, NFTA_CHAIN_POLICY, htonl(chain->policy))) + if (nla_put_be32(skb, NFTA_CHAIN_POLICY, + htonl(basechain->policy))) goto nla_put_failure; if (nla_put_string(skb, NFTA_CHAIN_TYPE, @@ -682,7 +686,7 @@ err: } static int -nf_tables_chain_policy(struct nft_chain *chain, const struct nlattr *attr) +nf_tables_chain_policy(struct nft_base_chain *chain, const struct nlattr *attr) { switch (ntohl(nla_get_be32(attr))) { case NF_DROP: @@ -776,8 +780,10 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, if (nlh->nlmsg_flags & NLM_F_REPLACE) return nf_tables_mvchain(skb, nlh, table, chain, nla); - if ((chain->flags & NFT_BASE_CHAIN) && nla[NFTA_CHAIN_POLICY]) { - return nf_tables_chain_policy(chain, + if (nla[NFTA_CHAIN_POLICY]) { + if (!(chain->flags & NFT_BASE_CHAIN)) + return -EOPNOTSUPP; + return nf_tables_chain_policy(nft_base_chain(chain), nla[NFTA_CHAIN_POLICY]); } return 0; @@ -830,23 +836,21 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, if (afi->hooks[ops->hooknum]) ops->hook = afi->hooks[ops->hooknum]; - chain->policy = NF_ACCEPT; chain->flags |= NFT_BASE_CHAIN; if (nla[NFTA_CHAIN_POLICY]) { - err = nf_tables_chain_policy(chain, + err = nf_tables_chain_policy(basechain, nla[NFTA_CHAIN_POLICY]); if (err < 0) { kfree(basechain); return err; } - } + } else + basechain->policy = NF_ACCEPT; } else { chain = kzalloc(sizeof(*chain), GFP_KERNEL); if (chain == NULL) return -ENOMEM; - - chain->policy = NF_ACCEPT; } INIT_LIST_HEAD(&chain->rules); diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 65e5385..a860769 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c @@ -136,7 +136,7 @@ next_rule: goto next_rule; } - return chain->policy; + return nft_base_chain(chain)->policy; } EXPORT_SYMBOL_GPL(nft_do_chain); -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html