All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ali Firas <alishmery18@gmail.com>
To: netdev@vger.kernel.org, idosch@nvidia.com
Cc: kuba@kernel.org, pabeni@redhat.com, davem@davemloft.net,
	edumazet@google.com, andrew+netdev@lunn.ch, razor@blackwall.org,
	roopa@nvidia.com, linux-kernel@vger.kernel.org,
	Ali Firas <alishmery18@gmail.com>
Subject: [PATCH net 0/3] vxlan: vnifilter: bound the VNI range per request
Date: Wed,  9 Sep 2026 12:26:42 +0300	[thread overview]
Message-ID: <20260909092645.3105263-1-alishmery18@gmail.com> (raw)
In-Reply-To: <20260907141001.GA708129@shredder>

A single RTM_NEWTUNNEL or RTM_DELTUNNEL message can currently ask the
vnifilter code for the whole 24-bit VNI space, and vxlan_vni_add_del()
loops over that span under rtnl_lock creating one VNI node and one
per-CPU stats block per iteration. That is reachable by an unprivileged
user in a user+network namespace and it costs roughly 2.1 GiB + 1 GiB
per possible CPU (128 B slab plus 64 B per possible CPU per VNI): on
2, 4 and 8 CPU guests every full-range request
ended in a global OOM, with no errno returned because the caller is
itself OOM-killed, and with unrelated root-owned processes killed on the
way down. Because rtnl_lock is global rather than per-netns, it also
stalled network configuration everywhere: a plain "ip link add dummy0
type dummy" in a different network namespace takes 0.011 s normally,
4.472 s while a 1,000,000 VNI request runs, and never completed at all
during a full-range one. Patch 1 caps the span of a single request at
4096 VNIs, which closes both. The cap is on one request, not on the
device: a device can still hold the whole VNI space, it just takes more
than one message.

Patch 2 charges the VNI node and its per-CPU stats to the caller's memcg.
With the cap in place this is no longer the primary defence, but nothing
limits how many capped requests a task may issue, so an unprivileged user
can still accumulate VNIs 4096 at a time with none of it charged to them.
It is also the same class fix as commit 1beb81947eb4 ("net/sched: account
classifier filter allocations to memcg"). One limitation is worth stating
up front: try_charge() reclaims and then invokes the memcg OOM killer
rather than returning -ENOMEM, so accounting confines the blast radius
without producing a graceful failure.

Patch 3 adds the selftest coverage Ido asked for, in the existing API
test: a range of exactly the maximum is accepted and one VNI more is
rejected, for both add and delete.

The limit is a driver-local constant rather than VLAN_N_VID: the values
coincide today, but a bound on a VXLAN netlink request is not a count of
VLAN IDs, and coupling them would make a change to one silently change
the other.

Patch 1 does tighten uAPI: a request spanning more than 4096 VNIs used
to succeed and now returns -EINVAL. Ido's assessment was that the limit
is unlikely to break anyone, since vnifilter is mainly used on bridged
VXLAN devices where the VNI is derived from the VLAN, capped at 4094.
I am sending the series to net because the stall is reachable by an
unprivileged user and crosses namespaces.

What I am less sure about is that Fixes: in net means this reaches
stable, where a script issuing one large range would start failing
across a point release. If that is the wrong trade, I am happy to respin
patch 1 against net-next without the Fixes tag.

Two things the series does not address. A single-VNI request with
START == END >= VXLAN_N_VID still passes the span check, and
vxlan_vni_field() shifts without masking, so such an entry is silently
truncated on the wire while holding its own rhashtable slot. That wants
a netlink policy range check, which I will send separately to net-next
as a pure uAPI tightening.

Measured worst case at the cap, on a 2 CPU / 2G guest: a request of
exactly 4096 VNIs takes 0.031 s to add and 0.022 s to delete, and the
cross-namespace "ip link add" blocks for 0.024 s during it. The old
full-range request is now rejected outright with

  Error: VNI range spans more than 4096 VNIs.

for both add and delete.

The whole selftest file passes before and after: 27 tests passed and 0
failed on the base, 31 passed and 0 failed with the series applied.

The 4096 limit follows Ido Schimmel's suggestion:
https://lore.kernel.org/netdev/20260907141001.GA708129@shredder/

Ali Firas (3):
  vxlan: vnifilter: limit the VNI range of a single request
  vxlan: vnifilter: account VNI node and per-CPU stats to memcg
  selftests: net: test the vxlan vnifilter VNI range limit

 drivers/net/vxlan/vxlan_vnifilter.c           | 24 +++++++++++++++++--
 .../selftests/net/test_vxlan_vnifiltering.sh  | 13 ++++++++++
 2 files changed, 35 insertions(+), 2 deletions(-)

-- 
2.53.0


  reply	other threads:[~2026-09-09  9:27 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02 15:46 [PATCH net v2] vxlan: vnifilter: validate the VNI range in vni_filter_entry_policy Ali Firas
2026-09-05 19:36 ` netdev-bot+sashiko
2026-09-05 19:39   ` Jakub Kicinski
2026-09-06 23:16 ` Ali Firas
2026-09-07 10:52   ` Ali Firas
2026-09-07 14:10     ` Ido Schimmel
2026-09-09  9:26       ` Ali Firas [this message]
2026-09-09  9:26         ` [PATCH net 1/3] vxlan: vnifilter: limit the VNI range of a single request Ali Firas
2026-09-10  9:38           ` netdev-bot+sashiko
2026-09-15  0:31           ` Jakub Kicinski
2026-09-09  9:26         ` [PATCH net 2/3] vxlan: vnifilter: account VNI node and per-CPU stats to memcg Ali Firas
2026-09-10  9:38           ` netdev-bot+sashiko
2026-09-15  0:31           ` Jakub Kicinski
2026-09-09  9:26         ` [PATCH net 3/3] selftests: net: test the vxlan vnifilter VNI range limit Ali Firas
2026-09-10  9:39           ` 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=20260909092645.3105263-1-alishmery18@gmail.com \
    --to=alishmery18@gmail.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=idosch@nvidia.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=razor@blackwall.org \
    --cc=roopa@nvidia.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.