From: Marcelo Ricardo Leitner <mleitner@redhat.com>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Subject: Re: [PATCH v4 2/3] Do error handling if __build_packet_message fails
Date: Tue, 04 Nov 2014 16:52:31 -0200 [thread overview]
Message-ID: <5459206F.7080702@redhat.com> (raw)
In-Reply-To: <20141104182609.GA26344@salvia>
On 04-11-2014 16:26, Pablo Neira Ayuso wrote:
> On Tue, Nov 04, 2014 at 04:01:54PM -0200, Marcelo Ricardo Leitner wrote:
>>>> @@ -708,8 +707,9 @@ nfulnl_log_packet(struct net *net,
>>>>
>>>> inst->qlen++;
>>>>
>>>> - __build_packet_message(log, inst, skb, data_len, pf,
>>>> - hooknum, in, out, prefix, plen);
>>>> + if (__build_packet_message(log, inst, skb, data_len, pf,
>>>> + hooknum, in, out, prefix, plen))
>>>> + goto build_failure;
>>>>
>>>> if (inst->qlen >= qthreshold)
>>>> __nfulnl_flush(inst);
>>>> @@ -726,6 +726,15 @@ unlock_and_release:
>>>> instance_put(inst);
>>>> return;
>>>>
>>>> +build_failure:
>>>> + /* If no other messages in it, we're good to free it. */
>>>> + if (!inst->skb->len) {
>>>> + kfree_skb(inst->skb);
>>>> + inst->skb = NULL;
>>>> + }
>>>> +
>>>> + inst->qlen--;
>>>
>>> For each message that we put into the batch, we increase inst->qlen in
>>> one, so I think this decrement isn't enough to leave things in
>>> consistent state. If we at least have one message already in the
>>> batch, I think it's good to give it a try to deliver it to userspace:
>>>
>>> if (inst->skb)
>>> __nfulnl_flush(inst);
>>
>> The idea was to undo just the last attempt and leave the older ones
>> where they were...
>>
>> Currently we:
>> - allocate skb, if needed
>> - increment inst->qlen
>> - call __build_packet_message
>> - if (inst->qlen >= qthreshold)
>> we flush..
>>
>> Considering __build_packet_message now will call nlmsg_cancel and
>> undo all its work on fails, I thought on just dec'ing inst->qlen and
>> releasing the skbuff, if it's empty.
>>
>> I see your point on attempting the flush, good idea. Otherwise we
>> could hit a situation that it would be stuck on undoing the last
>> message and this situation would be fixed only after inst->timer
>> expires.
>>
>> It could be like:
>> build_failure:
>> inst->qlen--;
>
> We can inst->qlen++ after build_packet_message, so you can skip this
> line above.
Ack, okay
>
>> /* If no other messages in it, we're good to free it. */
>> if (!inst->skb->len) {
>
> Now I'd suggest:
>
> if (inst->qlen == 0) {
ack
>
>> kfree_skb(inst->skb);
>> inst->skb = NULL;
>> }
>> else {
>> __nfulnl_flush(inst);
>> }
>>
>> What do you think?
>>
>>> Then, the WARN_ON that Florian added recently should catch that we
>>> have size miscalculations from __nfulnl_send().
>>
>> Good point. It may not catch it always. If the failed message was
>> bigger than the DONE message, it may go on unnoticed. Actually, even
>> if it warns, we would have no idea that a message was dropped a bit
>> earlier, as the stats aren't there yet. Maybe another WARN_ONCE on
>> build_failure label?
>
> That will catch possible miscalculations too, I don't like we're
> polluting this with many WARN_ONCE, but I don't see any better way to
> catch this size miscalculation bugs, so ahead add it.
>
> BTW, we should also signal the userspace when we fail to build the
> message via:
>
> nfnetlink_set_err(net, 0, group, -ENOBUFS);
>
> so it knows that we're losing log messages for whatever reason.
> Basically, userspace hits -ENOBUFS when calling recv(), which means
> netlink is losing messages. I don't think we really need the
> statistics.
Cool. Then we probably don't need the WARN_ON unless we really want those
numbers, or even so. As we will be calling nfnetlink_set_err, we have other
ways of debugging. Wouldn't be as ready as a WARN_ONCE in there, yes.. but a
systemtap script can easily get a hold in there.
So no WARN_ONCE, just the nfnetlink_set_err() call? Like this?
> if (inst->qlen == 0) {
>> kfree_skb(inst->skb);
>> inst->skb = NULL;
>> }
>> else {
>> __nfulnl_flush(inst);
>> }
nfnetlink_set_err(net, 0, group, -ENOBUFS);
So we send whatever we had, and signal the failure..
>
> I can also see this line:
>
> nlh->nlmsg_len = inst->skb->tail - old_tail;
>
> that can be replaced by nlmsg_end(skb, nlh);
>
> It seems this code needs some care.
Agreed. I'll try :)
Thanks,
Marcelo
next prev parent reply other threads:[~2014-11-04 18:52 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-29 12:51 [PATCH v4 1/3] netfilter: log: protect nf_log_register against double registering Marcelo Ricardo Leitner
2014-10-29 12:51 ` [PATCH v4 2/3] Do error handling if __build_packet_message fails Marcelo Ricardo Leitner
2014-11-04 16:47 ` Pablo Neira Ayuso
2014-11-04 18:01 ` Marcelo Ricardo Leitner
2014-11-04 18:26 ` Pablo Neira Ayuso
2014-11-04 18:52 ` Marcelo Ricardo Leitner [this message]
2014-11-04 19:04 ` Pablo Neira Ayuso
2014-11-04 19:08 ` Marcelo Ricardo Leitner
2014-11-04 19:11 ` Florian Westphal
2014-11-06 1:07 ` Pablo Neira Ayuso
2014-11-06 2:19 ` Florian Westphal
2014-10-29 12:51 ` [PATCH v4 3/3] Make use of pr_fmt where applicable Marcelo Ricardo Leitner
2014-11-04 16:50 ` Pablo Neira Ayuso
2014-11-04 17:11 ` Marcelo Ricardo Leitner
2014-10-30 16:31 ` [PATCH v4 1/3] netfilter: log: protect nf_log_register against double registering 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=5459206F.7080702@redhat.com \
--to=mleitner@redhat.com \
--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).