From: Martin Schitter <ms+git@mur.at>
To: Stefano Brivio <sbrivio@redhat.com>
Cc: passt-dev@passt.top
Subject: Re: [PATCH v2 1/3] Fix handling of netlink multipart route dumps.
Date: Sat, 19 Sep 2026 14:56:36 +0200 [thread overview]
Message-ID: <c99ffc07-1a42-4e3e-8850-1eea68680ebc@mur.at> (raw)
In-Reply-To: <20260917210812.44e10453@elisabeth>
On 9/17/26 21:08, Stefano Brivio wrote:
> Here's my review, sorry for the delay.
Thanks for your really extensive review!
I'll try to respect and solve most of your remarks in my next patch series.
In the meanwhile I also did a lot of additional recherche. At the end of
this replay you'll see, that I'll simply have to rewrite everything
again because this new insights.
> I have mostly coding style remarks on this patch, and more substantial
> comments in the following patches.
Please don't hesitate to modify and improve all these suggested patches
anytime. It's often more efficient to simply correct little style issues
and docstring flaws on the fly in a well configured development
environment than communicating all needed changes.
Even in cases where I don't share your view, simply change it to your needs.
> Here, and in following patches: missing Signed-off-by: tag (see
> CONTRIBUTING.md).
o.k. I'll add it -- although I'm not convinced that it makes much sense
in a modern jj based patch description workflow.
>> + #define NLMSG_DONE_SIZE NLMSG_LENGTH(4)
>
> It's just a header with no data, right? Shouldn't it be 0? Am I missing
> something?
4 is correct -- it stands for header size + 4*8bit (int) error code
(see:
https://docs.kernel.org/userspace-api/netlink/intro.html#netlink-message-types)
> By the way we tend to group all the defines that are generally valid
> for a compilation unit towards the beginning of the relevant file (so
> that they can be used in all the functions), see #define directives
> earlier in netlink.c.
>
> Exceptions are macros that are only relevant or valid for a given
> function (see e.g. tap6_handler() in tap.c).
I wouldn't move it. It is a helpful hint to easily grasp this particular
code section and isn't very useful outside this scope.
>> +
>> + while(collected + NLBUFSIZ < buflen){
>
> Coding style: space before {.
>
> It's not really idiomatic to "do something as long as we have space"
> and, with this structure, we won't stop on errors or mismatching
> sequence numbers (see nl_status()).
>
> Would there be a way to encode this as a loop on nl_status() perhaps? I
> haven't tried but it would look cleaner and less bug-prone.
Hmm -- I'm also not very happy about this solution, but for much less
cosmetic reasons.
I simply don't like this arbitrary set hard-coded memory resp. route
entry capacity limit that doesn't correspond to any limitation given by
the operating system.
Well -- it's at least an improvement, but it doesn't solve the
fundamental issue as long as it doesn't handle routing tables of any size.
But within the given constraints of this code base (i.e. strict avoiding
any dynamic memory allocation and not using a more memory save
programming language) I don't see any better solution until now.
>> + nh = nl_next(s, &buf[collected], NULL, &n);
>> + debug("collect: add chunk of size n=%ld at offset=%ld, seq=%d nlmsg_len=%d",
>> + n, collected, seq, ((const struct nlmsghdr *)&buf[collected])->nlmsg_len);
>
> At some point, we should get a netlink monitor (see
> https://bugs.passt.top/show_bug.cgi?id=141) which might run this function
> quite frequently at runtime, and having this as debug() message would
> risk flooding debug logs and making them otherwise unusable.
You can eliminate all my debug print commands just as you like.
But as long as we do not have suitable unit tests to control at least a
subset of common cases in advance, debug logs could be very helpful to
iron out remaining mistakes and false assumptions.
btw.: I don't think you should run this kind of routines frequently.
Kernel-userspace-transfers are rather expensive. Perhaps you could try
to utilize eBPF to handle these route table duplication resp. transfer
between namespaces in a more efficient manner.
> I think we could consider trace(). My preference would actually to drop
> this altogether because it seems to be specific to some particular
> phase of your development and not something of general relevance.
That's o.k. for me.
But please consider, that we do not have much control about many details
of the actual kernel behavior in respect to this complex netlink
multipart dumps. It can be rather challenging to reproduce and solve all
related issues without useful debug log capabilities.
> If we want to keep this for some reason: "collect" isn't very
> descriptive (mind that it will just be printed among other messages
> coming from completely different parts of the code). I would rather use
> __func__.
__func__ and similar more precise code location prefixes would IMHO make
the output even more dense, confusing, and cluttering.
But again: just change it however you like!
>> + res = nl_status(nh, n, seq);
>> + if (res < 0) /* error */
>> + return res;
>
> Looping on nl_status() directly would get rid of this.
Respecting the capacity limits of the given interim buffer is IMHO the
most important aspect of this function. That's why I have chosen this
particular loop design.
Nevertheless, we have to catch a few other less critical error
conditions resp. return conditions as well.
>> + tail = (const struct nlmsghdr*)&buf[collected - NLMSG_DONE_SIZE];
>
> Cppcheck and clang-tidy (try also 'make clang-tidy') aren't
> particularly impressed here. Cppcheck says:
>
> netlink.c:266:22: style: Variable 'tail' is reassigned a value before the old one has been used. [redundantAssignment]
Yes -- this line is indeed wrong.
I'll replace it by a simple declaration for '*tail'.
>> + if (res == 0 || (
>> + collected >= NLMSG_DONE_SIZE
>> + && (tail = (const struct nlmsghdr*)&buf[collected - NLMSG_DONE_SIZE])
>> + && NLMSG_OK(tail, NLMSG_DONE_SIZE)
>> + && (nl_status(tail, NLMSG_DONE_SIZE, seq) == 0))
>
> For readability: could we perhaps split this into different 'if'
> conditions with gotos dealing with specific errors (for example if
> !NLMSG_OK(tail, NLMSG_DONE_SIZE), we should report error and return
> early I guess)?
It's a rather simple logical chain of tests to look out for NLMSG_DONE
at the end of an input chunk if not already found in the previous
nl_status() call. In both cases it will stop collecting datagrams.
Additionally, it would catch an illegal pointer arithmetic condition,
although this case should never happen in practice.
>> - char buf[NLBUFSIZ];
>> + char buf[NLBUFSIZ * 8];
>
> Reasonable, but perhaps it should be a #define just after #define
> NLBUFSIZ.
o.k. -- I'll use a macro (NLBUFBLOCKS) for the buffsize multiplier.
next prev parent reply other threads:[~2026-09-19 12:56 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-08 18:13 [PATCH v2] Fix for Bug #221 -- Issue concerning bigger routing tables Martin Schitter
2026-09-08 18:13 ` [PATCH v2 1/3] Fix handling of netlink multipart route dumps Martin Schitter
2026-09-17 19:08 ` Stefano Brivio
2026-09-19 12:56 ` Martin Schitter [this message]
2026-09-08 18:13 ` [PATCH v2 2/3] Timekeeping: Resolving Route Dependencies Martin Schitter
2026-09-17 19:08 ` Stefano Brivio
2026-09-19 12:56 ` Martin Schitter
2026-09-08 18:13 ` [PATCH v2 3/3] Optimize route dependency solver Martin Schitter
2026-09-17 19:08 ` Stefano Brivio
2026-09-19 12:56 ` Martin Schitter
2026-09-19 13:07 ` Stefano Brivio
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=c99ffc07-1a42-4e3e-8850-1eea68680ebc@mur.at \
--to=ms+git@mur.at \
--cc=passt-dev@passt.top \
--cc=sbrivio@redhat.com \
/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.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
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 IMAP folder(s).