Skip to content

Linux DCO: pre-existing ovpn interface handling is broken #1064

Description

@ralflici

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions