<feed xmlns='http://www.w3.org/2005/Atom'>
<title>accel-ppp.git/accel-pppd/ctrl/ipoe, branch master</title>
<subtitle>High performance PPTP/L2TP/SSTP/PPPoE/IPoE server for Linux (mirror of https://github.com/accel-ppp/accel-ppp.git)
</subtitle>
<id>https://git.amelek.net/accel-ppp/accel-ppp.git/atom?h=master</id>
<link rel='self' href='https://git.amelek.net/accel-ppp/accel-ppp.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/'/>
<updated>2026-09-09T15:42:09+00:00</updated>
<entry>
<title>utils: centralize max macro</title>
<updated>2026-09-09T15:42:09+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-29T23:46:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=78d75b1dcf0d42e6ad5ce8b7203a19e17b9c87dc'/>
<id>urn:sha1:78d75b1dcf0d42e6ad5ce8b7203a19e17b9c87dc</id>
<content type='text'>
Closes #354
</content>
</entry>
<entry>
<title>ipoe: harden DHCPv4 option decoding</title>
<updated>2026-09-01T05:55:54+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-09-01T05:49:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=3bbf61a373290d63382a4d1bfa8712566eb31c7b'/>
<id>urn:sha1:3bbf61a373290d63382a4d1bfa8712566eb31c7b</id>
<content type='text'>
Validate known options before extracting fields, bound Relay-Agent and classless-route subformats, and replace unaligned DHCP option accesses in notification, relay, and session paths.
</content>
</entry>
<entry>
<title>Merge pull request #351 from nuclearcat/various-fixes-on-compiler-warnings</title>
<updated>2026-09-01T05:52:55+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-09-01T05:52:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=57ae56148c5519b9207ede623098d3cfad5211b8'/>
<id>urn:sha1:57ae56148c5519b9207ede623098d3cfad5211b8</id>
<content type='text'>
Various fixes on compiler warnings</content>
</entry>
<entry>
<title>ipoe: harden local-net prefix length parsing</title>
<updated>2026-08-10T05:55:22+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-10T05:55:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=3aa2a84122a48e28aef252b8777d5e57f28fafe5'/>
<id>urn:sha1:3aa2a84122a48e28aef252b8777d5e57f28fafe5</id>
<content type='text'>
The netmask was built by shifting ~0, which is a signed int holding -1,
and left shifting a negative value is undefined in C. Every compiler we
build with produces the expected mask, so this is not a behaviour fix,
but it trips -fsanitize=shift and relies on latitude the standard does
not grant. Shift an unsigned operand instead.

The prefix length itself was not validated properly either. strtoul()
accepts a leading minus and negates, so 'local-net=10.0.0.0/-1' yields
ULONG_MAX, which truncates to -1 in the int and passes the 'mask &gt; 32'
test. The shift count then becomes 33, which is out of range whether the
operand is signed or unsigned. endptr was set but never looked at, so
trailing garbage was silently ignored and '/abc' quietly became a /0.

Keep the parsed value unsigned, reject anything that is not a complete
number in 0..32, and only then narrow it.
</content>
</entry>
<entry>
<title>ipoe: bounds check classless routes and avoid unaligned reads</title>
<updated>2026-08-10T05:44:13+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-10T05:44:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=4600e779e801b51405ed51d421ecfe8e33e5059d'/>
<id>urn:sha1:4600e779e801b51405ed51d421ecfe8e33e5059d</id>
<content type='text'>
The destination was always read as a 32 bit word regardless of how many
significant octets the prefix length implies, and the gateway was read
without checking that four bytes remain in the option. Neither read was
bounded by the end of the option, so a client could make the decoder run
past it. dhcpv4_check_options() only enforces a minimum length of 5 for
option 121, which is short of the 9 bytes a /32 route needs.

Reading the destination as a word was also wrong for any prefix shorter
than /32, as it pulled in the first octets of the gateway: 10.0.1.0/24
via 1.1.1.1 printed as 10.0.0.1/24.

Read only the significant octets, check the remaining length before both
reads, and copy the gateway rather than dereferencing a possibly
unaligned pointer.
</content>
</entry>
<entry>
<title>ipoe: fix netmask computation for classless routes</title>
<updated>2026-08-10T05:43:17+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-10T05:43:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=0dd152a83012764a77ef2a7ae7bf7c20c3d43c35'/>
<id>urn:sha1:0dd152a83012764a77ef2a7ae7bf7c20c3d43c35</id>
<content type='text'>
The netmask was built with a loop shifting 1 into place, which was wrong
in three ways. At i == 0 it evaluated 1 &lt;&lt; 32, undefined for a 32 bit
int, and at i == 1 it shifted into the sign bit of a signed value. The
shift amount was off by one, so a /24 produced 0xfffffe00 rather than
0xffffff00. And mask1 was initialized once before the loop over the
routes and only ever OR'ed into, so the mask of every route accumulated
into the routes that followed it.

A well formed option carrying 10.0.1.0/24 via 1.1.1.1 and 172.16.0.0/12
via 2.2.2.2 printed as 10.0.0.1/24 and 172.16.2.0/12.

Compute the mask directly instead, and reject a prefix length above 32
rather than shifting by a negative amount.
</content>
</entry>
<entry>
<title>fixup! ipoe: flush sessions left by a previous instance with a single command</title>
<updated>2026-08-08T21:18:35+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-08T21:18:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=2b46f1c69ca77efc317673b080d4773db09a4a3e'/>
<id>urn:sha1:2b46f1c69ca77efc317673b080d4773db09a4a3e</id>
<content type='text'>
</content>
</entry>
<entry>
<title>fixup! ipoe: flush sessions left by a previous instance with a single command</title>
<updated>2026-08-08T20:57:09+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-08T20:57:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=811f87f071659410f9126d51b6ef72a4c64a02a9'/>
<id>urn:sha1:811f87f071659410f9126d51b6ef72a4c64a02a9</id>
<content type='text'>
</content>
</entry>
<entry>
<title>fixup! ipoe: flush sessions left by a previous instance with a single command</title>
<updated>2026-08-08T20:17:46+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-08T20:17:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=fc465210fb77af7d6a12780f3f256d17be2ce480'/>
<id>urn:sha1:fc465210fb77af7d6a12780f3f256d17be2ce480</id>
<content type='text'>
</content>
</entry>
<entry>
<title>ipoe: flush sessions left by a previous instance with a single command</title>
<updated>2026-08-08T14:47:49+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-08T14:47:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=6693d18ae0232da2c6febc0decf099e4fd064381'/>
<id>urn:sha1:6693d18ae0232da2c6febc0decf099e4fd064381</id>
<content type='text'>
On startup accel-pppd is expected to drop everything a previous instance
left behind in the kernel. For sessions it did so by dumping them with
IPOE_CMD_GET and sending one IPOE_CMD_DELETE per ifindex. That dump was
written for the session backup code removed in 1972a7e5c and was never
adapted to its new, destructive role:

 - it was issued on the socket subscribed to the packet multicast group,
   so it competed with the notifications that the still attached stale
   rx handlers keep generating; on a loaded box the receive buffer
   overruns and rtnl_dump_filter() gives up with ENOBUFS,
 - its return value was discarded, so such a failure was silent,
 - it ran before the interfaces were detached, which is what produces
   those notifications in the first place,
 - it was skipped entirely when the multicast group could not be
   resolved, again with nothing but a warning about packet handling,
 - and every session cost a socket, a round trip, a grace period and a
   full unregister_netdev().

Whatever it missed stays in the kernel forever: the daemon has no record
of those sessions, so nothing ever deletes them, and every subscriber
later assigned one of their addresses is refused with EEXIST by
IPOE_CMD_MODIFY.

Add IPOE_CMD_FLUSH, which unlinks all sessions in one go, waits for a
single grace period and unregisters the devices with
unregister_netdevice_many(), and use it instead. The old path is kept as
a fallback for a module predating the command, which is reported as
EOPNOTSUPP, and now checks its return value and uses a private socket.

Reorder init() so the interfaces are detached before the multicast group
is joined, and so the flush also runs when only the group lookup failed.
</content>
</entry>
</feed>
