pppd: Add support for registering ppp interface via Linux rtnetlink API
authorPali Rohár <pali@kernel.org>
Sat, 9 Jul 2022 11:40:24 +0000 (13:40 +0200)
committerPali Rohár <pali@kernel.org>
Sat, 9 Jul 2022 11:40:24 +0000 (13:40 +0200)
commit4a54e34cf5629f9fed61f0b7d69ee3ba4d874bc6
tree74bbe909e206dd70ba964a2ced3f4a965e7aaa8e
parenta6622771e2dc03a2682c86c4bcf6bf6ae9e85df7
pppd: Add support for registering ppp interface via Linux rtnetlink API

pppd currently creates ppp network interface via PPPIOCNEWUNIT ioctl API.
This API creates a new ppp network interface named "ppp<unit_id>". If user
supply option "ifname" with custom network name then pppd calls SIOCSIFNAME
ioctl to rename "ppp<unit_id>" to custom name immediately after successful
PPPIOCNEWUNIT ioctl call. If custom name is already registered then
SIOCSIFNAME ioctl fails and pppd close current channel (which destroy also
network interface).

This has side effect that in the first few miliseconds interface has
different name as what user supplied.

Tools like systemd, udev or NetworkManager are trying to query
interface attributes based on interface name immediately when new
network interface is created.

But if interface is renamed immediately after creation then these tools
fails. For example when running pppd with option "ifname ppp-wan" following
error is reported by systemd / udev into dmesg log:

    [   35.718732] PPP generic driver version 2.4.2
    [   35.793914] NET: Registered protocol family 24
    [   35.889924] systemd-udevd[1852]: link_config: autonegotiation is unset or enabled, the speed and duplex are not writable.
    [   35.901450] ppp-wan: renamed from ppp0
    [   35.930332] systemd-udevd[1852]: link_config: could not get ethtool features for ppp0
    [   35.939473] systemd-udevd[1852]: Could not set offload features of ppp0: No such device

There is an easy way to fix this issue: Use new rtnetlink API.

Via rtnetlink API it is possible to create ppp network interface with
custom ifname atomically. Just it is not possible to specify custom ppp
unit id.

So use new rtnetlink API when user requested custom ifname without custom
ppp unit id. This will avoid system issues with interface renaming as ppp
interface is directly registered with specified final name.

This has also advantage that if requested interface name already exists
then pppd fail during registering of networking interface and not during
renaming network interface which happens after successful registration.

If user supply custom ppp unit id then it is required to use old ioctl API
as currently it is the only API which allows specifying ppp unit id.

When user does not specify custom ifname stay also with old ioctl API.
There is currently a bug in kernel which cause that when empty interface is
specified in rtnetlink message for creating ppp interface then kernel
creates ppp interface but with pseudo-random name, not derived from ppp
unit id. And therefore it is not possible to retrieve what is the name of
newly created network interface. So when user does not specify interface
name via "ifname" option (which means that want from kernel to choose some
"free" interface name) it is needed to use old ioctl API which do it
correctly for now.

Signed-off-by: Pali Rohár <pali@kernel.org>
pppd/sys-linux.c