Skip to content

Misc: PPPoE client, DHCPv6 routes through netd, and fixes - #1682

Open
troglobit wants to merge 14 commits into
mainfrom
misc
Open

troglobit wants to merge 14 commits into
mainfrom
misc

Conversation

@troglobit

@troglobit troglobit commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

PPPoE client, #1569

A PPPoE session is an interface of type pppoe on top of the interface facing the provider. pppoeN names infer the type in the CLI.

How it fits with dagger:

  • dagger creates the interface with pppmon, which holds it open, and removes it by stopping pppmon. The rest of the setup is as usual
  • pppd is a Finit service, pppd@IFNAME, that attaches to the existing interface with a new pppd option, attach-unit
  • pppd owns the link state and MTU of the interface

Tested against a scapy PPPoE server in the test container.

Also on this branch

Checklist

Tick relevant boxes, this PR is-a or has-a:

  • Bugfix
    • Regression tests
    • ChangeLog updates (for next release)
  • Feature
    • YANG model change => revision updated?
    • Regression tests added?
    • ChangeLog updates (for next release)
    • Documentation added?
  • Test changes
    • Checked in changed Readme.adoc (make test-spec)
    • Added new test to group Readme.adoc and yaml file
  • Code style update (formatting, renaming)
  • Refactoring (please detail in commit messages)
  • Build related changes
  • Documentation content changes
    • ChangeLog updated (for major changes)
  • Other (please describe):

Every use case test combines features, so the word adds nothing to the
name of this one.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
confd now subscribes to watchdogd while it loads the startup config,
so it needs libwdog to build, and the scan stopped at configure.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The kernel backend left the control fields of the route dump message
uninitialized, so whether the dump worked depended on what was on the
stack.  When it failed, with ENOBUFS, netd saw none of the routes it
had installed and never removed or replaced any of them.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A gateway learned from a router advertisement is link-local, so it is
only reachable on a given interface, and a route through it may apply
only to traffic from a delegated prefix.  netd could express neither,
which is why DHCPv6 routes bypassed it.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Routes from DHCPv6 and router advertisements went straight into the
kernel, so they showed up as kernel routes, ignored the DHCPv6 route
preference, and FRR could neither see nor redistribute them.  odhcp6c
now hands them to netd, the way the DHCPv4 client does, and like that
client it starts only once netd runs.

Fixes #1423

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The DHCPv6 tests only checked that a default route existed, which also
held while it bypassed netd as a kernel route.  Check that it is a
static route with the DHCPv6 route preference, that a new preference
reaches it, that it goes away with the client, and that a delegated
prefix gets its unreachable route.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Infix accepts router advertisements on all interfaces, so the kernel
adds a default route of its own next to the one the DHCPv6 client hands
to netd.  The kernel route always wins, and the DHCPv6 route preference
never takes effect.  While the client runs, it owns the default route
on its interface.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
odhcp6c runs its stopped hook in the background and exits, so the hook
does not survive the service being stopped.  The client's routes stayed,
and the kernel no longer learned a default route from router
advertisements on that interface.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The PPPoE client needs both.  pppd's own PPPoE plugin is the client,
rp-pppoe is only needed for a server.  The minimal images get it too,
a small switch on a PPPoE uplink is a likely use.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
@troglobit troglobit changed the title Misc fixes Misc: PPPoE client, DHCPv6 routes through netd, and fixes Oct 3, 2026
@troglobit
troglobit requested a review from mattiaswal October 3, 2026 17:00
@troglobit
troglobit marked this pull request as ready for review October 3, 2026 17:06
Infix sets up routes, firewall rules, and interface settings when the
configuration is applied, before any traffic flows.  pppd creates its
ppp interface when a session comes up and removes it when the session
ends, so there is nothing to apply them to until then, and they are
lost on every reconnect.

With attach-unit, another process creates and owns the interface, and
pppd attaches to it for each session.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A real PPPoE server needs /dev/ppp and PPP support in the kernel the
test container runs on, which a rootless container never has.  This one
speaks just enough PPPoE and PPP from userspace, over a raw socket.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Many ISPs still connect their customers with PPPoE.  A session is an
interface of type pppoe on top of the interface facing the provider.
The type derives from IANA ppp, so other PPP transports can later share
the common ppp settings.

The kernel removes a ppp interface when the file that created it is
closed, so the interface needs a process to own it.  dagger creates it
with pppmon, which only holds it, and pppd runs as a Finit service that
attaches to it.  The interface then exists as soon as it is configured,
is set up like any other, and stays across reconnects, while Finit
still supervises pppd.

The default route and DNS servers go through netd and resolvconf like
those from DHCP.  The TCP MSS of forwarded connections is clamped to
the session MTU, since PPPoE's lower MTU otherwise stalls TCP wherever
ICMP is blocked.

Fixes #1569

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
statd only provided /ietf-routing:routing/ribs, so sysrepo never asked
it about anything else in the routing tree.  The interfaces list, which
yanger produced along with the routes, showed up when the whole tree was
requested, but a request for /ietf-routing:routing/interfaces came back
empty.

Provide each part on its own path, with yanger producing only the part
asked for, so a request for the whole tree does not get any part twice.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Covers session setup with PAP and CHAP, the default route, DNS,
forwarding, MSS clamping, reconnect after the server drops the session,
disabling and deleting the interface, and a wrong password.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DHCPv6 client routes bypass netd/FRR — no full route integration

1 participant