On Tue, 2016-11-01 at 23:11 +0100, Pablo Neira Ayuso wrote:
> Minor nitpicks as I said, see below.
>
hello Pablo,
thank you for reviewing!
> On Fri, Oct 28, 2016 at 10:42:09AM +0200, Davide Caratti wrote:
> >
> > 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 ...
>
It looks correct to me - and the behavior is not changed with this patch:
when the code hits
if (ret < 0) {
pr_err("nf_conntrack_ipv4: can't register ipv4 proto.\n");
goto cleanup_icmpv4; /* before patch */
}
or
if (ret < 0) {
pr_err("nf_conntrack_ipv4: can't register ipv4 proto.\n");
goto cleanup_l4proto; /* after patch */
}
nf_ct_l4proto_register() surely didn't fail: 'ret' is return value of
nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv4). 'cleanup_l4proto'
label is there to unregister all L4 protocols in the builtin list, in case
any failure follows a successful call to nf_ct_l4proto_register().
> >
> > }
> >
> > 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.
Yes, and the patched code already does this actually. If a failure happens
in nf_ct_l4proto_register(), rollback of all previously registered L4
protocols in the builtin list is done before function returns a negative
value of 'ret':
if (j < num_proto) {
int ver = l4->l3proto == PF_INET6 ? 6 : 4;
pr_err(".... "); /* <-- same printout as before patch */
while (--j >= 0) {
l4 = l4proto[j];
rcu_assign_pointer(
nf_ct_protos[l4->l3proto][l4->l4proto],
&nf_conntrack_l4proto_generic);
}
}
and in this case
if (ret < 0)
goto cleanup_hooks;
is hit.
But I understand it's not so evident, nf_ct_l4proto_register() is very
long
and contains two lines copypasted from nf_ct_l4proto_unregister().
So I will follow the advice you did below and write
nf_ct_l4proto_unregister_one()
that will be called in the while() loops of nf_ct_l4proto_register()
when the function is going to return a negative value, and in
nf_ct_l4proto_unregister().
> > + 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()
ok,
<...>
> And same thing here, wrap this code into a function so you don't need
> to reindent.
and ok. Also this one is a preparatory commit for something else (i.e.
builtinization of conntrack for SCTP, DCCP, UDPlite), so I'm going to
repost this patch as a series.
regards,
--
davide
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html