diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-08-08 18:12:56 +0300 |
|---|---|---|
| committer | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-08-08 18:12:56 +0300 |
| commit | 4969b65c3f55c739a0c9178086f42ba3de906119 (patch) | |
| tree | 2a64151f9739a0f0f71c5680638a99b2bc198e71 /.github/workflows | |
| parent | 6693d18ae0232da2c6febc0decf099e4fd064381 (diff) | |
| download | accel-ppp-4969b65c3f55c739a0c9178086f42ba3de906119.tar.gz accel-ppp-4969b65c3f55c739a0c9178086f42ba3de906119.zip | |
ipoe: allow session interfaces to be removed with ip link del
Sessions left in the kernel by a dead daemon could only be got rid of by
restarting accel-pppd, which flushes all of them and so drops everyone
still online, or by unloading the module. Neither is of much use when a
single stale interface is holding an address and every subscriber that
is later handed it is refused with EEXIST.
Register rtnl_link_ops, so that RTM_DELLINK reaches the driver:
ip link show type ipoe enumerate them
ip -d link show ipoe42 reports kind "ipoe"
ip link del ipoe42 remove a single one
newlink returns EOPNOTSUPP rather than being left out. A session carries
private state that IPOE_CMD_CREATE sets up, and a kernel that falls back
to register_netdevice() when newlink is NULL would hand out a device
with zeroed private state and no percpu counters, which oopses on the
first packet or on ip -s link show.
dellink runs under rtnl and outside genl_mutex, and is therefore the
first writer in this driver that does not serialise against the genl
handlers: it can unlink a session that IPOE_CMD_DELETE is about to
unlink as well, since the device stays registered until both are done.
Add ipoe_session.dying, set under ipoe_wlock by whichever path starts
the teardown, and let the other one bail out.
That leaves rtnl nested inside ipoe_wlock, which is safe because no path
does it the other way round: ipoe_create() releases rtnl before taking
ipoe_wlock, ipoe_nl_cmd_delete() releases ipoe_wlock before calling
unregister_netdev(), and the interface commands use rtnl alone. dellink
does have to sleep in synchronize_rcu() and while draining the session
refcount with rtnl held, which the genl path avoids by deferring both
until after it has dropped everything.
A session left behind by a dead daemon is indistinguishable from one
that is still in use - same peer address, same lists, same flags - so
the removal cannot be refused on state alone. Warn instead, and only
when somebody is still subscribed to the packet multicast group, so that
clearing stale interfaces on a box where accel-pppd is not running stays
quiet.
Diffstat (limited to '.github/workflows')
0 files changed, 0 insertions, 0 deletions
