]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
ovpn: ensure packet delivery happens with BH disabled
authorRalf Lici <ralf@mandelbit.com>
Wed, 25 Mar 2026 16:49:18 +0000 (17:49 +0100)
committerAntonio Quartulli <antonio@openvpn.net>
Mon, 4 May 2026 22:31:06 +0000 (00:31 +0200)
commitc539cb30f93f119566f2ae9d016cce11f188d780
tree656c6a69256f0b6a665854c7c8fb2d008de0a6fe
parenta200cdbf95932631ec338d08a6e9e31b34c4e8a6
ovpn: ensure packet delivery happens with BH disabled

ovpn injects decrypted packets into the netdev RX path through
ovpn_netdev_write() which invokes gro_cells_receive() and
dev_dstats_rx_add().

ovpn_netdev_write() is normally called in softirq context,
however, in case of TCP connections it may also be invoked
process context.

When this happens gro_cells_receive() will throw a warning:

  [  230.183747][   T12] WARNING: net/core/gro_cells.c:30 at gro_cells_receive+0x708/0xaa0, CPU#1: kworker/u16:0/12

and lockdep will also report a potential inconsistent lock state:

  WARNING: inconsistent lock state
  7.0.0-rc4+ #246 Tainted: G        W
  --------------------------------
  inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.

because attempts to acquire gro_cells->bh_lock by both
contexts may lead to a deadlock.

At the same time, dev_dstats_rx_add() does not expect to race
with a softirq (which may happen when invoked in process context),
because the latter may access its per-cpu state and corrupt
it.

Fix all this by invoking local_bh_disable/enable() around
gro_cells_receive() and dev_dstats_rx_add() to ensure that
bottom halves are always disabled before calling both of
them.

Fixes: 11851cbd60ea ("ovpn: implement TCP transport")
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
drivers/net/ovpn/io.c