diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-04-18 14:38:10 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-04-18 14:38:10 +0000 |
commit | 6405e8b90397f3943aa701358eda5b609c2b1de3 (patch) | |
tree | 243ad2e2467758a3e99dfabc265d1956a803d3f3 /sys/net | |
parent | c32d48043bc5d3981d3b40f36f14da0e2573d292 (diff) |
Remove the hack that prevents changing pppoe params at runtime.
The EBUSY hack imposes an order on the ifconfig commands issued
against the pppoe interface used to configure the sppp layer below.
To counter this we use the ENETRESET trick that other drivers use
to tell the pppoe layer that sppp has requested a stop/init reset
sequence to proceed which we oblige with in case pppoe is UP and
RUNNING.
Tested by semarie@ and Jan Schreiber <jes@posteo.de>, thanks!
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_pppoe.c | 33 | ||||
-rw-r--r-- | sys/net/if_spppsubr.c | 17 |
2 files changed, 32 insertions, 18 deletions
diff --git a/sys/net/if_pppoe.c b/sys/net/if_pppoe.c index 7e2bb27806b..74a89bc7fff 100644 --- a/sys/net/if_pppoe.c +++ b/sys/net/if_pppoe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pppoe.c,v 1.54 2016/04/13 11:41:15 mpi Exp $ */ +/* $OpenBSD: if_pppoe.c,v 1.55 2016/04/18 14:38:08 mikeb Exp $ */ /* $NetBSD: if_pppoe.c,v 1.51 2003/11/28 08:56:48 keihan Exp $ */ /* @@ -792,7 +792,7 @@ pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data) struct proc *p = curproc; /* XXX */ struct pppoe_softc *sc = (struct pppoe_softc *)ifp; struct ifnet *eth_if; - int error = 0; + int s, error = 0; switch (cmd) { case PPPOESETPARMS: @@ -923,7 +923,34 @@ pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data) return (sppp_ioctl(ifp, cmd, data)); } default: - return (sppp_ioctl(ifp, cmd, data)); + error = sppp_ioctl(ifp, cmd, data); + if (error == ENETRESET) { + error = 0; + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == + (IFF_UP | IFF_RUNNING)) { + s = splnet(); + if_down(ifp); + splx(s); + if (sc->sc_state >= PPPOE_STATE_PADI_SENT && + sc->sc_state < PPPOE_STATE_SESSION) { + timeout_del(&sc->sc_timeout); + sc->sc_state = PPPOE_STATE_INITIAL; + sc->sc_padi_retried = 0; + sc->sc_padr_retried = 0; + memcpy(&sc->sc_dest, + etherbroadcastaddr, + sizeof(sc->sc_dest)); + } + error = sppp_ioctl(ifp, SIOCSIFFLAGS, NULL); + if (error) + return (error); + s = splnet(); + if_up(ifp); + splx(s); + return (sppp_ioctl(ifp, SIOCSIFFLAGS, NULL)); + } + } + return (error); } return (0); } diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index ae8b589a2fa..8846a4bd4e1 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_spppsubr.c,v 1.149 2015/11/23 14:41:05 sthen Exp $ */ +/* $OpenBSD: if_spppsubr.c,v 1.150 2016/04/18 14:38:09 mikeb Exp $ */ /* * Synchronous PPP link level subroutines. * @@ -4529,19 +4529,6 @@ sppp_set_params(struct sppp *sp, struct ifreq *ifr) if (copyin((caddr_t)ifr->ifr_data, &cmd, sizeof cmd) != 0) return EFAULT; - /* - * We have a very specific idea of which fields we allow - * being passed back from userland, so to not clobber our - * current state. For one, we only allow setting - * anything if LCP is in dead phase. Once the LCP - * negotiations started, the authentication settings must - * not be changed again. (The administrator can force an - * ifconfig down in order to get LCP back into dead - * phase.) - */ - if (sp->pp_phase != PHASE_DEAD) - return EBUSY; - switch (cmd) { case SPPPIOSDEFS: { @@ -4638,7 +4625,7 @@ sppp_set_params(struct sppp *sp, struct ifreq *ifr) return EINVAL; } - return 0; + return (ENETRESET); } void |