OpenVPN / OpenVPN/openvpn

Linux DCO: pre-existing ovpn interface handling is broken

Open
#1,064 1 comment 0 reactions 1 assignee View on GitHub

@ralflici is already working on this.

Since Jun 27, 2026.

Dominant language
C
Stars
14.6k
Forks
3.4k
PR merge metrics
No merged PRs in 30d

Description

When starting openvpn with a pre-existing Linux DCO interface, userspace appears to enter the intended "existing DCO device" path, but the interface is not actually adopted correctly.

Reproducer:

modprobe ovpn
ip link add tun0 type ovpn
openvpn --dev tun0 ...

The program seems to correctly detect the underlying interface:

open_tun_dco: tun0
net_iface_new: add tun0 type ovpn
sitnl_send: rtnl: generic error (-17): File exists
Cannot create DCO interface tun0: -17
DCO device tun0 already exists, won't be destroyed at shutdown
ovpn-dco device [tun0] opened

But when a client connects, DCO netlink operations fail:

dco_new_peer: peer-id 0 ...
kernel error: ovpn: ifindex does not match any interface
dco_new_peer: netlink reports device not found
Exiting due to fatal error

And despite the earlier "won't be destroyed at shutdown" message, shutdown deletes the interface:

Closing ovpn-dco interface
net_iface_del: delete tun0

So there seem to be two userspace bugs in this path:

  1. The -EEXIST branch in net_iface_new() marks the interface persistent, but does not set tt->dco.ifindex from the existing device. Later generic netlink messages are sent with an invalid ifindex.
  2. close_tun_dco() deletes the interface unconditionally and does not honor tt->persistent_if.

Note that there is also a mode wrinkle: ovpn interfaces need to be created with the correct mode (as a netlink parameter): MP for server and P2P for p2p/client. Userspace will likely need to verify that mode too when adopting a pre-existing ovpn interface.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.