From: Bjorn Ketelaars Subject: pppoe(4): replace PPPOE_TERM_UNKNOWN_SESSIONS with ifconfig knob To: tech@openbsd.org Date: Fri, 27 Dec 2024 20:32:01 +0100 The pppoe(4) manpage describes the kernel option PPPOE_TERM_UNKNOWN_SESSIONS, which addresses an issue with re-establishing a connection after a power failure. Rather than requiring a kernel recompile, the proposal is to make this fix configurable via an ifconfig(8) knob. This fix provides a convenient solution for resolving issues I encounter with reconnecting to my ISP. The diff below includes the necessary changes to implement this and updates to relevant manpages. Comments/tests/OK? diff --git share/man/man4/options.4 share/man/man4/options.4 index a6ed33cc497..f84807ab181 100644 --- share/man/man4/options.4 +++ share/man/man4/options.4 @@ -412,10 +412,6 @@ Enables BSD compressor for PPP connections. .It Cd option PPP_DEFLATE For use in conjunction with PPP_BSDCOMP; provides an interface to zlib for PPP for deflate compression/decompression. -.It Cd option PPPOE_TERM_UNKNOWN_SESSIONS -Send PADT to terminate open sessions before connecting. -See -.Xr pppoe 4 . .It Cd option SOCKET_SPLICE Enables zero-copy socket splicing in the kernel. See diff --git share/man/man4/pppoe.4 share/man/man4/pppoe.4 index ca0cd209d5d..a5684fee726 100644 --- share/man/man4/pppoe.4 +++ share/man/man4/pppoe.4 @@ -126,7 +126,7 @@ the gateway will be changed to the suggested address as well. .Pp Otherwise, PPP negotiation will only agree to exactly the IPv4 addresses which are configured on the interface. -.Sh KERNEL OPTIONS +.Pp .Nm does not interfere with other PPPoE implementations running on the same machine. @@ -138,12 +138,11 @@ because there is already an open session. This would be indicated by the client sending a high number of PADI packets before successfully connecting. The +.Em link2 +switch lets the .Nm -driver can be told to kill all unknown PPPoE sessions -by sending a PADT packet to explicitly terminate the old session. -Add the following to the kernel config file: -.Pp -.Dl option PPPOE_TERM_UNKNOWN_SESSIONS +driver terminate unknown sessions on its parent interface with a PADT +packet. .Sh PPPOE AND MTU/MSS PPPoE has an 8-byte header. When run over a network interface with the diff --git sys/net/if_pppoe.c sys/net/if_pppoe.c index ba194a5fec4..c5005788583 100644 --- sys/net/if_pppoe.c +++ sys/net/if_pppoe.c @@ -684,17 +684,15 @@ pppoe_data_input(struct mbuf *m) struct pppoe_softc *sc; struct pppoehdr *ph; u_int16_t session, plen; -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS u_int8_t shost[ETHER_ADDR_LEN]; -#endif + if (LIST_EMPTY(&pppoe_softc_list)) goto drop; KASSERT(m->m_flags & M_PKTHDR); -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN); -#endif + m_adj(m, sizeof(struct ether_header)); if (m->m_pkthdr.len <= PPPOE_HEADERLEN) { printf("pppoe (data): dropping too short packet: %d bytes\n", @@ -720,11 +718,22 @@ pppoe_data_input(struct mbuf *m) session = ntohs(ph->session); sc = pppoe_find_softc_by_session(session, m->m_pkthdr.ph_ifidx); if (sc == NULL) { -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS - printf("pppoe (data): input for unknown session 0x%x, sending PADT\n", - session); - pppoe_send_padt(m->m_pkthdr.ph_ifidx, session, shost, 0); -#endif + /* + * Using a data packet from an unknown session, iterate through + * the pppoe_softc_list to find a matching parent interface. If + * IFF_LINK2 is set on a PPPoE interface on that parent + * interface, send a PADT packet to terminate the unknown PPPoE + * session. + */ + LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + if (ISSET(sc->sc_sppp.pp_if.if_flags, IFF_LINK2) && + sc->sc_eth_ifidx == m->m_pkthdr.ph_ifidx) { + printf("pppoe (data): input for unknown " + "session 0x%x, sending PADT\n", session); + pppoe_send_padt(m->m_pkthdr.ph_ifidx, session, + shost, 0); + } + } goto drop; }