From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Davide Caratti <dcaratti@redhat.com>
Cc: Patrick McHardy <kaber@trash.net>,
Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>,
"David S . Miller" <davem@davemloft.net>,
Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>,
James Morris <jmorris@namei.org>,
Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>,
netfilter-devel@vger.kernel.org, coreteam@netfilter.org
Subject: Re: [PATCH nf-next v2] netfilter: conntrack: simplify init/uninit of L4 protocol trackers
Date: Tue, 1 Nov 2016 23:11:02 +0100 [thread overview]
Message-ID: <20161101221102.GA26385@salvia> (raw)
In-Reply-To: <2b862e9bc046bc42def1a56611265ddbc640fddd.1477643522.git.dcaratti@redhat.com>
Minor nitpicks as I said, see below.
On Fri, Oct 28, 2016 at 10:42:09AM +0200, Davide Caratti wrote:
> modify registration and deregistration of layer-4 protocol trackers to
> facilitate inclusion of new elements into the current list of builtin
> protocols. Both builtin (TCP, UDP, ICMP) and non-builtin (DCCP, GRE, SCTP,
> UDPlite) layer-4 protocol trackers usually register/deregister themselves
> using consecutive calls to nf_ct_l4proto_{,pernet}_{,un}register(...).
> This sequence is interrupted and rolled back in case of error; in order to
> simplify addition of builtin protocols, the input of the above functions
> has been modified to allow registering/unregistering multiple protocols.
>
> Signed-off-by: Davide Caratti <dcaratti@redhat.com>
> ---
>
> Notes:
> v2:
> - reword commit message
> - change input of nf_ct_l4proto_{,pernet}_{,un}register(...) to
> accept arrays of struct nf_conntrack_l4proto *.
>
> please note:
> checkpatch.pl complains about coding style on some of the lines that
> were moved into a for() loop. This can be fixed too, but I propose to
> do that in a separate commit.
>
> include/net/netfilter/nf_conntrack_l4proto.h | 12 +-
> net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 76 +++-------
> net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 78 ++++------
> net/netfilter/nf_conntrack_proto.c | 191 +++++++++++++++----------
> net/netfilter/nf_conntrack_proto_dccp.c | 48 ++-----
> net/netfilter/nf_conntrack_proto_gre.c | 28 ++--
> net/netfilter/nf_conntrack_proto_sctp.c | 50 ++-----
> net/netfilter/nf_conntrack_proto_udplite.c | 50 ++-----
> 8 files changed, 222 insertions(+), 311 deletions(-)
>
> diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
> index de629f1..28f6d79 100644
> --- a/include/net/netfilter/nf_conntrack_l4proto.h
> +++ b/include/net/netfilter/nf_conntrack_l4proto.h
> @@ -126,13 +126,17 @@ void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p);
>
> /* Protocol pernet registration. */
> int nf_ct_l4proto_pernet_register(struct net *net,
> - struct nf_conntrack_l4proto *proto);
> + struct nf_conntrack_l4proto *proto[],
> + int num_proto);
You can use unsigned here:
unsigned int n);
> void nf_ct_l4proto_pernet_unregister(struct net *net,
> - struct nf_conntrack_l4proto *proto);
> + struct nf_conntrack_l4proto *proto[],
> + int num_proto);
Same here.
> /* Protocol global registration. */
> -int nf_ct_l4proto_register(struct nf_conntrack_l4proto *proto);
> -void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *proto);
> +int nf_ct_l4proto_register(struct nf_conntrack_l4proto *proto[],
> + int num_proto);
> +void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *proto[],
> + int num_proto);
Same thing here.
> /* Generic netlink helpers */
> int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
> diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
> index 713c09a..7130ed5 100644
> --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
> +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
> @@ -336,47 +336,34 @@ MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
> MODULE_ALIAS("ip_conntrack");
> MODULE_LICENSE("GPL");
>
> +static struct nf_conntrack_l4proto *builtin_l4proto4[] = {
> + &nf_conntrack_l4proto_tcp4,
> + &nf_conntrack_l4proto_udp4,
> + &nf_conntrack_l4proto_icmp,
> +};
> +
> static int ipv4_net_init(struct net *net)
> {
> int ret = 0;
>
> - ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_tcp4);
> - if (ret < 0) {
> - pr_err("nf_conntrack_tcp4: pernet registration failed\n");
> - goto out_tcp;
> - }
> - ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udp4);
> - if (ret < 0) {
> - pr_err("nf_conntrack_udp4: pernet registration failed\n");
> - goto out_udp;
> - }
> - ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_icmp);
> - if (ret < 0) {
> - pr_err("nf_conntrack_icmp4: pernet registration failed\n");
> - goto out_icmp;
> - }
> + ret = nf_ct_l4proto_pernet_register(net, builtin_l4proto4,
> + ARRAY_SIZE(builtin_l4proto4));
> + if (ret < 0)
> + return ret;
> ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv4);
> if (ret < 0) {
> pr_err("nf_conntrack_ipv4: pernet registration failed\n");
> - goto out_ipv4;
> + nf_ct_l4proto_pernet_unregister(net, builtin_l4proto4,
> + ARRAY_SIZE(builtin_l4proto4));
> }
> - return 0;
> -out_ipv4:
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmp);
> -out_icmp:
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp4);
> -out_udp:
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp4);
> -out_tcp:
> return ret;
> }
>
> static void ipv4_net_exit(struct net *net)
> {
> nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv4);
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmp);
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp4);
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp4);
> + nf_ct_l4proto_pernet_unregister(net, builtin_l4proto4,
> + ARRAY_SIZE(builtin_l4proto4));
> }
>
> static struct pernet_operations ipv4_net_ops = {
> @@ -410,37 +397,21 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
> goto cleanup_pernet;
> }
>
> - ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_tcp4);
> - if (ret < 0) {
> - pr_err("nf_conntrack_ipv4: can't register tcp4 proto.\n");
> + ret = nf_ct_l4proto_register(builtin_l4proto4,
> + ARRAY_SIZE(builtin_l4proto4));
> + if (ret < 0)
> goto cleanup_hooks;
> - }
> -
> - ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udp4);
> - if (ret < 0) {
> - pr_err("nf_conntrack_ipv4: can't register udp4 proto.\n");
> - goto cleanup_tcp4;
> - }
> -
> - ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_icmp);
> - if (ret < 0) {
> - pr_err("nf_conntrack_ipv4: can't register icmpv4 proto.\n");
> - goto cleanup_udp4;
> - }
>
> ret = nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv4);
> if (ret < 0) {
> pr_err("nf_conntrack_ipv4: can't register ipv4 proto.\n");
> - goto cleanup_icmpv4;
> + goto cleanup_l4proto;
Is this correct?
nf_ct_l4proto_register() has failed, then we jump to cleanup_l4proto ...
> }
>
> return ret;
> - cleanup_icmpv4:
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmp);
> - cleanup_udp4:
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp4);
> - cleanup_tcp4:
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
> +cleanup_l4proto:
> + nf_ct_l4proto_unregister(builtin_l4proto4,
> + ARRAY_SIZE(builtin_l4proto4));
... that is unregistering what we failed to register. So
nf_ct_l4proto_register() should clean up this internally.
> cleanup_hooks:
> nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
> cleanup_pernet:
> @@ -454,9 +425,8 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void)
> {
> synchronize_net();
> nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmp);
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp4);
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
> + nf_ct_l4proto_unregister(builtin_l4proto4,
> + ARRAY_SIZE(builtin_l4proto4));
> nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
> unregister_pernet_subsys(&ipv4_net_ops);
> nf_unregister_sockopt(&so_getorigdst);
> diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
> index 963ee38..500be28 100644
> --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
> +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
> @@ -336,47 +336,35 @@ static struct nf_sockopt_ops so_getorigdst6 = {
> .owner = THIS_MODULE,
> };
>
> +static struct nf_conntrack_l4proto *builtin_l4proto6[] = {
> + &nf_conntrack_l4proto_tcp6,
> + &nf_conntrack_l4proto_udp6,
> + &nf_conntrack_l4proto_icmpv6,
> +};
> +
> static int ipv6_net_init(struct net *net)
> {
> int ret = 0;
>
> - ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_tcp6);
> - if (ret < 0) {
> - pr_err("nf_conntrack_tcp6: pernet registration failed\n");
> - goto out;
> - }
> - ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udp6);
> - if (ret < 0) {
> - pr_err("nf_conntrack_udp6: pernet registration failed\n");
> - goto cleanup_tcp6;
> - }
> - ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_icmpv6);
> - if (ret < 0) {
> - pr_err("nf_conntrack_icmp6: pernet registration failed\n");
> - goto cleanup_udp6;
> - }
> + ret = nf_ct_l4proto_pernet_register(net, builtin_l4proto6,
> + ARRAY_SIZE(builtin_l4proto6));
> + if (ret < 0)
> + return ret;
> +
> ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv6);
> if (ret < 0) {
> pr_err("nf_conntrack_ipv6: pernet registration failed.\n");
> - goto cleanup_icmpv6;
> + nf_ct_l4proto_pernet_unregister(net, builtin_l4proto6,
> + ARRAY_SIZE(builtin_l4proto6));
> }
> - return 0;
> - cleanup_icmpv6:
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmpv6);
> - cleanup_udp6:
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp6);
> - cleanup_tcp6:
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp6);
> - out:
> return ret;
> }
>
> static void ipv6_net_exit(struct net *net)
> {
> nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv6);
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmpv6);
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp6);
> - nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp6);
> + nf_ct_l4proto_pernet_unregister(net, builtin_l4proto6,
> + ARRAY_SIZE(builtin_l4proto6));
> }
>
> static struct pernet_operations ipv6_net_ops = {
> @@ -409,37 +397,20 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
> goto cleanup_pernet;
> }
>
> - ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_tcp6);
> - if (ret < 0) {
> - pr_err("nf_conntrack_ipv6: can't register tcp6 proto.\n");
> + ret = nf_ct_l4proto_register(builtin_l4proto6,
> + ARRAY_SIZE(builtin_l4proto6));
> + if (ret < 0)
> goto cleanup_hooks;
> - }
> -
> - ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udp6);
> - if (ret < 0) {
> - pr_err("nf_conntrack_ipv6: can't register udp6 proto.\n");
> - goto cleanup_tcp6;
> - }
> -
> - ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_icmpv6);
> - if (ret < 0) {
> - pr_err("nf_conntrack_ipv6: can't register icmpv6 proto.\n");
> - goto cleanup_udp6;
> - }
>
> ret = nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv6);
> if (ret < 0) {
> pr_err("nf_conntrack_ipv6: can't register ipv6 proto.\n");
> - goto cleanup_icmpv6;
> + goto cleanup_l4proto;
Same thing here.
> }
> return ret;
> -
> - cleanup_icmpv6:
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
> - cleanup_udp6:
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp6);
> - cleanup_tcp6:
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
> +cleanup_l4proto:
> + nf_ct_l4proto_unregister(builtin_l4proto6,
> + ARRAY_SIZE(builtin_l4proto6));
> cleanup_hooks:
> nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
> cleanup_pernet:
> @@ -453,9 +424,8 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void)
> {
> synchronize_net();
> nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp6);
> - nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
> + nf_ct_l4proto_unregister(builtin_l4proto6,
> + ARRAY_SIZE(builtin_l4proto6));
> nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
> unregister_pernet_subsys(&ipv6_net_ops);
> nf_unregister_sockopt(&so_getorigdst6);
> diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
> index 8d2c7d8..10e609c 100644
> --- a/net/netfilter/nf_conntrack_proto.c
> +++ b/net/netfilter/nf_conntrack_proto.c
> @@ -281,99 +281,136 @@ void nf_ct_l4proto_unregister_sysctl(struct net *net,
>
> /* FIXME: Allow NULL functions and sub in pointers to generic for
> them. --RR */
> -int nf_ct_l4proto_register(struct nf_conntrack_l4proto *l4proto)
> +int nf_ct_l4proto_register(struct nf_conntrack_l4proto *l4proto[],
> + int num_proto)
> {
> - int ret = 0;
> -
> - if (l4proto->l3proto >= PF_MAX)
> - return -EBUSY;
> -
> - if ((l4proto->to_nlattr && !l4proto->nlattr_size)
> - || (l4proto->tuple_to_nlattr && !l4proto->nlattr_tuple_size))
> - return -EINVAL;
> + struct nf_conntrack_l4proto *l4;
> + int ret = 0, j;
> +
> + for (j = 0; j < num_proto; j++) {
> + l4 = l4proto[j];
> + if (l4->l3proto >= PF_MAX)
> + return -EBUSY;
> + if ((l4->to_nlattr && !l4->nlattr_size)
> + || (l4->tuple_to_nlattr && !l4->nlattr_tuple_size))
Not your fault, but while at it, fix this coding style:
if ((l4->to_nlattr && !l4->nlattr_size) ||
(l4->tuple_to_nlattr && !l4->nlattr_tuple_size))
> + return -EINVAL;
> + }
>
> mutex_lock(&nf_ct_proto_mutex);
> - if (!nf_ct_protos[l4proto->l3proto]) {
> - /* l3proto may be loaded latter. */
> - struct nf_conntrack_l4proto __rcu **proto_array;
> - int i;
> -
> - proto_array = kmalloc(MAX_NF_CT_PROTO *
> - sizeof(struct nf_conntrack_l4proto *),
> - GFP_KERNEL);
> - if (proto_array == NULL) {
> - ret = -ENOMEM;
> - goto out_unlock;
> - }
> + for (j = 0; j < num_proto; j++) {
I wonder if you can wrap this code below into a function, to save one
level of indentation and improve maintainability. Probably in an
initial patch so the indent happening here doesn't generate so many
changes. This becomes harder to review.
Suggested name: nf_ct_l4proto_register_one()
> + l4 = l4proto[j];
> + if (!nf_ct_protos[l4->l3proto]) {
> + /* l3proto may be loaded latter. */
> + struct nf_conntrack_l4proto __rcu **proto_array;
> + int i;
> +
> + proto_array = kmalloc(MAX_NF_CT_PROTO *
> + sizeof(l4), GFP_KERNEL);
> + if (proto_array == NULL) {
> + ret = -ENOMEM;
> + break;
> + }
>
> - for (i = 0; i < MAX_NF_CT_PROTO; i++)
> - RCU_INIT_POINTER(proto_array[i], &nf_conntrack_l4proto_generic);
> + for (i = 0; i < MAX_NF_CT_PROTO; i++)
> + RCU_INIT_POINTER(proto_array[i],
> + &nf_conntrack_l4proto_generic);
> +
> + /* Before making proto_array visible to lockless readers
> + * we must make sure its content is committed to memory.
> + */
> + smp_wmb();
> +
> + nf_ct_protos[l4->l3proto] = proto_array;
> + } else if (rcu_dereference_protected(
> + nf_ct_protos[l4->l3proto][l4->l4proto],
> + lockdep_is_held(&nf_ct_proto_mutex)
> + ) != &nf_conntrack_l4proto_generic) {
> + ret = -EBUSY;
> + break;
> + }
>
> - /* Before making proto_array visible to lockless readers,
> - * we must make sure its content is committed to memory.
> - */
> - smp_wmb();
> + l4->nla_size = 0;
> + if (l4->nlattr_size)
> + l4->nla_size += l4->nlattr_size();
> + if (l4->nlattr_tuple_size)
> + l4->nla_size += 3 * l4->nlattr_tuple_size();
>
> - nf_ct_protos[l4proto->l3proto] = proto_array;
> - } else if (rcu_dereference_protected(
> - nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
> - lockdep_is_held(&nf_ct_proto_mutex)
> - ) != &nf_conntrack_l4proto_generic) {
> - ret = -EBUSY;
> - goto out_unlock;
> + rcu_assign_pointer(nf_ct_protos[l4->l3proto][l4->l4proto], l4);
> + }
> + if (j < num_proto) {
> + int ver = l4->l3proto == PF_INET6 ? 6 : 4;
> +
> + pr_err("nf_conntrack_ipv%d: can't register %s%d proto.\n",
> + ver, l4->name, ver);
> + while (--j >= 0) {
> + l4 = l4proto[j];
> + BUG_ON(rcu_dereference_protected(
> + nf_ct_protos[l4->l3proto][l4->l4proto],
> + lockdep_is_held(&nf_ct_proto_mutex)
> + ) != l4);
> + rcu_assign_pointer(
> + nf_ct_protos[l4->l3proto][l4->l4proto],
> + &nf_conntrack_l4proto_generic);
> + }
> }
> -
> - l4proto->nla_size = 0;
> - if (l4proto->nlattr_size)
> - l4proto->nla_size += l4proto->nlattr_size();
> - if (l4proto->nlattr_tuple_size)
> - l4proto->nla_size += 3 * l4proto->nlattr_tuple_size();
> -
> - rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
> - l4proto);
> -out_unlock:
> mutex_unlock(&nf_ct_proto_mutex);
> return ret;
> }
> EXPORT_SYMBOL_GPL(nf_ct_l4proto_register);
>
> int nf_ct_l4proto_pernet_register(struct net *net,
> - struct nf_conntrack_l4proto *l4proto)
> + struct nf_conntrack_l4proto *l4proto[],
> + int num_proto)
> {
> - int ret = 0;
> struct nf_proto_net *pn = NULL;
> + int i, ret = 0;
>
> - if (l4proto->init_net) {
> - ret = l4proto->init_net(net, l4proto->l3proto);
> - if (ret < 0)
> - goto out;
> - }
> + for (i = 0; i < num_proto; i++) {
As above, same thing here.
> + if (l4proto[i]->init_net) {
> + ret = l4proto[i]->init_net(net, l4proto[i]->l3proto);
> + if (ret < 0)
> + break;
> + }
>
> - pn = nf_ct_l4proto_net(net, l4proto);
> - if (pn == NULL)
> - goto out;
> + pn = nf_ct_l4proto_net(net, l4proto[i]);
> + if (pn == NULL)
> + continue;
>
> - ret = nf_ct_l4proto_register_sysctl(net, pn, l4proto);
> - if (ret < 0)
> - goto out;
> + ret = nf_ct_l4proto_register_sysctl(net, pn, l4proto[i]);
> + if (ret < 0)
> + break;
>
> - pn->users++;
> -out:
> + pn->users++;
> + }
> + if (i < num_proto) {
> + pr_err("nf_conntrack_%s%d: pernet registration failed.\n",
> + l4proto[i]->name,
> + l4proto[i]->l3proto == PF_INET6 ? 6 : 4);
> + nf_ct_l4proto_pernet_unregister(net, l4proto, i);
> + }
> return ret;
> }
> EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_register);
>
> -void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
> +void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *l4proto[],
> + int num_proto)
> {
> - BUG_ON(l4proto->l3proto >= PF_MAX);
> + int i;
> +
> + for (i = 0; i < num_proto; i++)
> + BUG_ON(l4proto[i]->l3proto >= PF_MAX);
>
> mutex_lock(&nf_ct_proto_mutex);
> - BUG_ON(rcu_dereference_protected(
> - nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
> - lockdep_is_held(&nf_ct_proto_mutex)
> - ) != l4proto);
> - rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
> - &nf_conntrack_l4proto_generic);
> + while (--num_proto >= 0) {
> + struct nf_conntrack_l4proto *l4 = l4proto[num_proto];
> +
> + BUG_ON(rcu_dereference_protected(
> + nf_ct_protos[l4->l3proto][l4->l4proto],
> + lockdep_is_held(&nf_ct_proto_mutex)
> + ) != l4);
> + rcu_assign_pointer(nf_ct_protos[l4->l3proto][l4->l4proto],
> + &nf_conntrack_l4proto_generic);
> + }
And same comment as above here.
> mutex_unlock(&nf_ct_proto_mutex);
>
> synchronize_rcu();
> @@ -381,19 +418,23 @@ void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
> EXPORT_SYMBOL_GPL(nf_ct_l4proto_unregister);
>
> void nf_ct_l4proto_pernet_unregister(struct net *net,
> - struct nf_conntrack_l4proto *l4proto)
> + struct nf_conntrack_l4proto *l4proto[],
> + int num_proto)
> {
> struct nf_proto_net *pn = NULL;
>
> - pn = nf_ct_l4proto_net(net, l4proto);
> - if (pn == NULL)
> - return;
> + while (--num_proto >= 0) {
> + pn = nf_ct_l4proto_net(net, l4proto[num_proto]);
> + if (pn == NULL)
> + continue;
>
> - pn->users--;
> - nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
> + pn->users--;
> + nf_ct_l4proto_unregister_sysctl(net, pn, l4proto[num_proto]);
>
> - /* Remove all contrack entries for this protocol */
> - nf_ct_iterate_cleanup(net, kill_l4proto, l4proto, 0, 0);
> + /* Remove all contrack entries for this protocol */
> + nf_ct_iterate_cleanup(net, kill_l4proto, l4proto[num_proto],
> + 0, 0);
And same thing here, wrap this code into a function so you don't need
to reindent.
Thanks for your patience.
next prev parent reply other threads:[~2016-11-01 22:11 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-28 8:42 [PATCH nf-next v2] netfilter: conntrack: simplify init/uninit of L4 protocol trackers Davide Caratti
2016-10-28 8:47 ` Pablo Neira Ayuso
2016-10-28 9:03 ` Pablo Neira Ayuso
2016-11-01 22:11 ` Pablo Neira Ayuso [this message]
2016-11-02 10:38 ` Davide Caratti
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=20161101221102.GA26385@salvia \
--to=pablo@netfilter.org \
--cc=coreteam@netfilter.org \
--cc=davem@davemloft.net \
--cc=dcaratti@redhat.com \
--cc=jmorris@namei.org \
--cc=kaber@trash.net \
--cc=kadlec@blackhole.kfki.hu \
--cc=kuznet@ms2.inr.ac.ru \
--cc=netfilter-devel@vger.kernel.org \
--cc=yoshfuji@linux-ipv6.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).