My DSL connection, using a modem in "bridge" mode and pppoe(4), suffers from disconnections every few (5 or so) days. The following message is printed in the syslog:
pppoe0: LCP keepalive timeout which indicates that several Echo-Requests were not followed by replies, so the kernel considers the connection to be dead and tries to reestablish the PPP session. Perhaps this could be fixed by the ISP, or perhaps it comes from the modem, and perhaps it could be fixed by increasing either MAXALIVECNT or the sec parameter in the relevant timeout_add_sec(9) call in src/sys/net/if_spppsubr.c (currently these are hard-coded but it would be nice to make these parameters accessible through ifconfig(8): see the "bugs" section in sppp(4)). The disconnection itself is not the problem that I want to discuss right now. sppp(4) manages to reconnect (sometimes it takes a few minutes, presumably because the other end is not happy that the previous connection was not properly terminated), and so as long as the reconnections are not too frequent it is not too big of an issue. My main problem is that the default IPv6 route, configured by adding !/sbin/route add -inet6 default -ifp pppoe0 fe80::%pppoe0 to /etc/hostname.pppoe0 as suggested by the manual, does not survive the reconnection (to be precise, all IPv6 addresses are purged when the new IPv6CP dance succeeds, and so the routes are purged as well). This is surprising because the default IPv4 route does survive the reconnection (route -n monitor tells me that some magic happens with the "special" addresses 0.0.0.0 and 0.0.0.1). Of course running the above route command reinstates the default IPv6 route, but this has to be done manually. Is this problem known? Is it the case for all sppp(4) connections (with IPv6 enabled of course), or even for all similar point-to-point interfaces? If your connection is reliable, you can simply unplug the phone line for about 30 seconds to try to reproduce this issue. A detail that can make my case somewhat particular: for some reason none of the DHCPv6 clients in ports worked for me (even if I temporarily disable the firewall, my "solicit" remain unanswered) but since my ISP informed me of my prefix, I could simply configure the "local" interface of the router with a static IPv6 address, and similarly for rad(8). Fortunately my ISP is routing the IPv6 packets on my line even without prefix delegation. I considered the following possible solutions. 1) The kernel could have a way of remembering the default IPv6 route that was added, like for IPv4. I don't know what kind of complication to the routing code that would entail. 2) I considered using ifstated(8) to add the default route anytime pppoe0 comes up, but this does not seem to be the right event: if I understand correctly, the interface is marked as "up" when the PPP dance succeeds, before any one of the NCP dances succeeds. One could have a little nap between the "up" event and the addition of the default IPv6 route, but that does not seem right. One could add more interface events to ifstated(8), but perhaps that is too complicated for this particular tool? 3) As a temporary measure, I wrote a small program (with a lot of copy-paste from the source of ifstated(8) and route(8), see attachment) that waits for the addition of new route with destination fe80::%pppoe0, and subsequently adds the sought default route. It worked at least once, so I am hopeful that it will work always. I have no doubt that it could be improved (for starters, the name of the interface could be passed as argument). PS: although the route(4) man page was really useful to understand how to talk to the kernel, it does not give all the details to do so (e.g. alignment on "long" for the sockaddrs, the way scope ids are embedded in link-local addresses, and which fields in the sockaddrs are actually used by the kernel). That is not really preventing anyone to interact with the kernel because there are many examples of code in base (sys/net/rtsock.c, sbin/route/*.c, ...), but I thought I would point it out just in case the goal is to have the route(4) man page be self-contained.
pppoeroute.c.gz
Description: Binary data