From: Florian Westphal <fw@strlen.de>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: Florian Westphal <fw@strlen.de>, netfilter-devel@vger.kernel.org
Subject: Re: [PATCH V2] netfilter: ctnetlink: force null nat binding on insert
Date: Mon, 17 Feb 2014 14:32:24 +0100 [thread overview]
Message-ID: <20140217133224.GD31125@breakpoint.cc> (raw)
In-Reply-To: <20140217132435.GA4083@localhost>
Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> I think we can simplify this, the nfnetlink_parse_nat_setup() hook
> function is always called under rcu_read_lock. See patch attached.
Right. The patch looks good to me.
Acked-by: Florian Westphal <fw@strlen.de>
> diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
> index bb322d0..b9f0e03 100644
> --- a/net/netfilter/nf_conntrack_netlink.c
> +++ b/net/netfilter/nf_conntrack_netlink.c
> @@ -1310,27 +1310,22 @@ ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[])
> }
>
> static int
> -ctnetlink_change_nat(struct nf_conn *ct, const struct nlattr * const cda[])
> +ctnetlink_setup_nat(struct nf_conn *ct, const struct nlattr * const cda[])
> {
> #ifdef CONFIG_NF_NAT_NEEDED
> int ret;
>
> - if (cda[CTA_NAT_DST]) {
> - ret = ctnetlink_parse_nat_setup(ct,
> - NF_NAT_MANIP_DST,
> - cda[CTA_NAT_DST]);
> - if (ret < 0)
> - return ret;
> - }
> - if (cda[CTA_NAT_SRC]) {
> - ret = ctnetlink_parse_nat_setup(ct,
> - NF_NAT_MANIP_SRC,
> - cda[CTA_NAT_SRC]);
> - if (ret < 0)
> - return ret;
> - }
> - return 0;
> + ret = ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_DST,
> + cda[CTA_NAT_DST]);
> + if (ret < 0)
> + return ret;
> +
> + ret = ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_SRC,
> + cda[CTA_NAT_SRC]);
> + return ret;
> #else
> + if (!cda[CTA_NAT_DST] && !cda[CTA_NAT_SRC])
> + return 0;
> return -EOPNOTSUPP;
> #endif
> }
> @@ -1659,11 +1654,9 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
> goto err2;
> }
>
> - if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
> - err = ctnetlink_change_nat(ct, cda);
> - if (err < 0)
> - goto err2;
> - }
> + err = ctnetlink_setup_nat(ct, cda);
> + if (err < 0)
> + goto err2;
>
> nf_ct_acct_ext_add(ct, GFP_ATOMIC);
> nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
> diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
> index d3f5cd6..52ca952 100644
> --- a/net/netfilter/nf_nat_core.c
> +++ b/net/netfilter/nf_nat_core.c
> @@ -432,15 +432,15 @@ nf_nat_setup_info(struct nf_conn *ct,
> }
> EXPORT_SYMBOL(nf_nat_setup_info);
>
> -unsigned int
> -nf_nat_alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
> +static unsigned int
> +__nf_nat_alloc_null_binding(struct nf_conn *ct, enum nf_nat_manip_type manip)
> {
> /* Force range to this IP; let proto decide mapping for
> * per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED).
> * Use reply in case it's already been mangled (eg local packet).
> */
> union nf_inet_addr ip =
> - (HOOK2MANIP(hooknum) == NF_NAT_MANIP_SRC ?
> + (manip == NF_NAT_MANIP_SRC ?
> ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3 :
> ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3);
> struct nf_nat_range range = {
> @@ -448,7 +448,13 @@ nf_nat_alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
> .min_addr = ip,
> .max_addr = ip,
> };
> - return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
> + return nf_nat_setup_info(ct, &range, manip);
> +}
> +
> +unsigned int
> +nf_nat_alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
> +{
> + return __nf_nat_alloc_null_binding(ct, HOOK2MANIP(hooknum));
> }
> EXPORT_SYMBOL_GPL(nf_nat_alloc_null_binding);
>
> @@ -702,9 +708,9 @@ static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
>
> static int
> nfnetlink_parse_nat(const struct nlattr *nat,
> - const struct nf_conn *ct, struct nf_nat_range *range)
> + const struct nf_conn *ct, struct nf_nat_range *range,
> + const struct nf_nat_l3proto *l3proto)
> {
> - const struct nf_nat_l3proto *l3proto;
> struct nlattr *tb[CTA_NAT_MAX+1];
> int err;
>
> @@ -714,38 +720,46 @@ nfnetlink_parse_nat(const struct nlattr *nat,
> if (err < 0)
> return err;
>
> - rcu_read_lock();
> - l3proto = __nf_nat_l3proto_find(nf_ct_l3num(ct));
> - if (l3proto == NULL) {
> - err = -EAGAIN;
> - goto out;
> - }
> err = l3proto->nlattr_to_range(tb, range);
> if (err < 0)
> - goto out;
> + return err;
>
> if (!tb[CTA_NAT_PROTO])
> - goto out;
> + return 0;
>
> - err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
> -out:
> - rcu_read_unlock();
> - return err;
> + return nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
> }
>
> +/* This function is called under rcu_read_lock() */
> static int
> nfnetlink_parse_nat_setup(struct nf_conn *ct,
> enum nf_nat_manip_type manip,
> const struct nlattr *attr)
> {
> struct nf_nat_range range;
> + const struct nf_nat_l3proto *l3proto;
> int err;
>
> - err = nfnetlink_parse_nat(attr, ct, &range);
> + /* Should not happen, restricted to creating new conntracks
> + * via ctnetlink.
> + */
> + if (WARN_ON_ONCE(nf_nat_initialized(ct, manip)))
> + return -EEXIST;
> +
> + /* Make sure that L3 NAT is there by when we call nf_nat_setup_info to
> + * attach the null binding, otherwise this may oops.
> + */
> + l3proto = __nf_nat_l3proto_find(nf_ct_l3num(ct));
> + if (l3proto == NULL)
> + return -EAGAIN;
> +
> + /* No NAT information has been passed, allocate the null-binding */
> + if (attr == NULL)
> + return __nf_nat_alloc_null_binding(ct, manip);
> +
> + err = nfnetlink_parse_nat(attr, ct, &range, l3proto);
> if (err < 0)
> return err;
> - if (nf_nat_initialized(ct, manip))
> - return -EEXIST;
>
> return nf_nat_setup_info(ct, &range, manip);
> }
> --
> 1.7.10.4
>
--
Florian Westphal <fw@strlen.de> // http://www.strlen.de
1024D/F260502D 2005-10-20
Key fingerprint = 1C81 1AD5 EA8F 3047 7555 E8EE 5E2F DA6C F260 502D
Phone: +49 151 11132303
next prev parent reply other threads:[~2014-02-17 13:32 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-16 11:15 [PATCH V2] netfilter: ctnetlink: force null nat binding on insert Florian Westphal
2014-02-17 10:37 ` Pablo Neira Ayuso
2014-02-17 10:45 ` Florian Westphal
2014-02-17 10:58 ` Pablo Neira Ayuso
2014-02-17 11:15 ` Florian Westphal
2014-02-17 13:24 ` Pablo Neira Ayuso
2014-02-17 13:32 ` Florian Westphal [this message]
2014-02-18 1:14 ` Pablo Neira Ayuso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140217133224.GD31125@breakpoint.cc \
--to=fw@strlen.de \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).