From: Nikolay Aleksandrov <razor@blackwall.org>
To: Artem Lytkin <iprintercanon@gmail.com>, netdev@vger.kernel.org
Cc: bridge@lists.linux.dev, idosch@nvidia.com, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, horms@kernel.org,
davem@davemloft.net, corbet@lwn.net, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next] net: bridge: bound the port VLAN lists in the IFLA_AF_SPEC nest
Date: Mon, 7 Sep 2026 11:47:24 +0300 [thread overview]
Message-ID: <ba2dcdb6-923d-4fc1-9c92-7a77c0b61a09@blackwall.org> (raw)
In-Reply-To: <20260906224246.21719-1-iprintercanon@gmail.com>
On 07/09/2026 01:42, Artem Lytkin wrote:
> br_fill_ifinfo() opens one IFLA_AF_SPEC nest, fills it with the VLAN
> information of a bridge port and closes it with nla_nest_end(), which
> stores the accumulated length into nla_len. That field is a u16, so for
> a nest larger than 65535 bytes the stored length wraps modulo 65536.
> The encoding has never been able to describe more than that; nothing
> regressed.
>
> Three per-VLAN lists share the one nest. An IFLA_BRIDGE_VLAN_INFO costs
> 8 bytes, an IFLA_BRIDGE_VLAN_TUNNEL_INFO 28 and an IFLA_BRIDGE_MST_ENTRY
> 20, on every architecture. A port takes at most 4094 VLANs, so the VLAN
> list alone is at most 32752 bytes, but the other two reach 65535: 2341
> tunnel mappings that are not consecutive in both VID and tunnel id, or
> 1821 with uncompressed VLAN information requested alongside, or 3277
> distinct MSTIs. A VXLAN leaf switch with one VXLAN device maps thousands
> of VLANs to VNIs, and "bridge vlan tunnelshow" and "bridge mst show"
> read these lists through the link dump.
>
> Nothing fails on the way there. br_get_link_af_size_filtered() accounts
> for all three lists and feeds both rtnl_calcit() for RTM_GETLINK dumps
> and nlmsg_new() in br_info_notify(), so the skb is large enough and no
> nla_put() fails. Userspace then walks the message with RTA_NEXT(),
> which advances by the stored length, so parsing resumes inside VLAN
> payload and everything after the nest is read out of it. A
> CONFIG_DEBUG_NET kernel warns once, in nla_nest_end(), via the check
> added in commit ff205bf8c554 ("netlink: add one debug check in
> nla_nest_end()").
>
> Measured on a port with 4093 VLAN to VNI mappings: the RTM_GETLINK reply
> for the port is 147776 bytes and carries an IFLA_AF_SPEC nla_len of
> 16280, and the top level attribute walk derails 16672 bytes in. The
> notification path is worse, because it broadcasts. A port flag change
> goes through br_ifinfo_notify(), which asks for compressed VLAN
> information, and the resulting RTM_NEWLINK is 115048 bytes with an
> nla_len of 49088; walking it yields 2342 attributes after the nest,
> 2341 of them read as IFLA_IFNAME, since IFLA_BRIDGE_VLAN_TUNNEL_INFO and
> IFLA_BRIDGE_VLAN_TUNNEL_FLAGS carry the same numeric type. Every
> RTNLGRP_LINK listener in the netns receives that. The DEBUG_NET warning
> fired from br_fill_ifinfo() while the mappings were being added, in the
> context of the process adding them, since each addition notifies too.
>
> Bound the three lists by length: stop adding entries once the next one
> would not fit in 65535 bytes, counted from the start of the nest so that
> the lists and the inner IFLA_BRIDGE_MST nest share the budget, and
> charge a range at its real cost of one or two entries. This is what
> commit bdd39576bf50a ("net: bridge: prevent too big nested attributes
> in br_fill_linkxstats()") did for the sibling nest in this file. A fixed
> cap on the number of entries, as IFLA_VFINFO_LIST got in
> commit 51e15308c6ae ("rtnetlink: cap IFLA_VFINFO_LIST at a documented
> number of VFs"), does not fit here: the lists share one nest, 4094 VLAN
> entries take half of it and 2340 tunnel entries fill it, so any set of
> per-list caps that is safe in the worst case cuts configurations that
> are described correctly today. The byte budget regresses none of them,
> and it is still a limit userspace can compute, since the per-entry
> costs are fixed. Documentation/networking/bridge.rst states them, along
> with the RTM_GETVLAN interface that does not have this limit.
>
> The MRP and CFM lists that br_fill_ifinfo() emits for the bridge device
> itself are not touched. They live in the same nest but never next to
> the port lists, and CFM peer status can grow past the limit on its own;
> that is a separate change.
>
> br_get_link_af_size_filtered() clamps the three lists to the same 65535
> bytes, so a dump of such a port no longer sizes the skb at 147 KB for a
> nest that holds 64 KB, and br_info_notify() no longer makes an
> oversized GFP_ATOMIC allocation from STP timer context for a message
> that would be truncated anyway. The clamp cannot cut into the MRP and
> CFM information: for the bridge device the VLAN list is the only one of
> the three and stays under 33 KB.
>
> With the bound, the same port dumps as 65932 bytes with an nla_len of
> 65508, the notification is 65936 bytes with 65512, both walk to the
> end, and nothing warns. A port above the bound reports shortened lists,
> so "bridge vlan tunnelshow" and "bridge mst show" print the first
> entries and stop instead of printing garbage, and the rest of the
> message parses. Read such a port with RTM_GETVLAN, which gives each
> entry its own attribute and continues in a new message once one fills
> up.
>
> Assisted-by: Claude:claude-opus-5
> Signed-off-by: Artem Lytkin <iprintercanon@gmail.com>
> ---
> Documentation/networking/bridge.rst | 17 ++++++++++
> net/bridge/br_mst.c | 12 +++----
> net/bridge/br_netlink.c | 49 ++++++++++++++++++++++++-----
> net/bridge/br_netlink_tunnel.c | 20 ++++++++++--
> net/bridge/br_private.h | 23 ++++++++++++--
> net/bridge/br_private_tunnel.h | 2 +-
> 6 files changed, 104 insertions(+), 19 deletions(-)
>
So much crap in a single patch, my eyes hurt... Yes, we know about this problem
and it is obvious to anyone who can count. This is not the right way to fix it,
it should probably be considered a corner case but still - IMO silently truncating
is very bad. I prefer a more explicit path - return error for both (RTM_GETLINK and notifications)
you'll have to plumb down extack but then user-space will know there are too many objects or lost
RTNL_LINK notifications and it should resync (e.g. use RTM_GETVLAN to dump the vlans if needed).
Cheers,
Nik
next prev parent reply other threads:[~2026-09-07 8:47 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-06 22:42 [PATCH net-next] net: bridge: bound the port VLAN lists in the IFLA_AF_SPEC nest Artem Lytkin
2026-09-07 8:47 ` Nikolay Aleksandrov [this message]
2026-09-07 13:35 ` Artem Lytkin
2026-09-07 13:46 ` Nikolay Aleksandrov
2026-09-07 13:50 ` Nikolay Aleksandrov
2026-09-10 6:44 ` netdev-bot+sashiko
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=ba2dcdb6-923d-4fc1-9c92-7a77c0b61a09@blackwall.org \
--to=razor@blackwall.org \
--cc=bridge@lists.linux.dev \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=iprintercanon@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@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.
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).