From owner-freebsd-bugs Fri Jul 4 11:07:59 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.5/8.8.5) id LAA02798 for bugs-outgoing; Fri, 4 Jul 1997 11:07:59 -0700 (PDT) Received: from relay.ucb.crimea.ua (ru@relay.ucb.crimea.ua [194.93.177.113]) by hub.freebsd.org (8.8.5/8.8.5) with ESMTP id LAA02793; Fri, 4 Jul 1997 11:07:41 -0700 (PDT) Received: (from ru@localhost) by relay.ucb.crimea.ua (8.8.5/8.8.5) id VAA01496; Fri, 4 Jul 1997 21:02:03 +0300 (EET DST) From: Ruslan Ermilov Message-Id: <199707041802.VAA01496@relay.ucb.crimea.ua> Subject: SLIP DRIVER needs to be rewritten!!! To: freebsd-hackers@freebsd.org Date: Fri, 4 Jul 1997 21:02:02 +0300 (EET DST) Cc: freebsd-bugs@freebsd.org X-My-Interests: Unix,Oracle,Networking X-Mailer: ELM [version 2.4 PL24] Content-Type: text Sender: owner-bugs@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Hi! I'm using 2.2.1-RELEASE of FreeBSD now. I have a proposal of how to solve the problem when SC_STATIC flag is used. First, I'll try to explain the problem(s): I've configured 4 slip units in kernel and need to attach two slip interfaces. And I WANT to use STATIC FEATURE of the driver (using -S switch of slattach). Well, I run `slattach -s 38400 /dev/cuaa0 -S 1' and here is what I see: 1) netstat -in shows the sl0 and sl1 in the reversed order. This is because slopen() allocates first free element of slsoftc[], i.e. slsoftc[0], and then, when slattach proceeds the -S1 switch, sltioctl(SLIOCSUNIT) assigns to it "slip unit 1" and sets on it SC_STATIC flag. 2) `ifconfig -a' shows the sl0 and sl1 in the normal order. 3) what happens when I try to `ifconfig sl1 x.x.x.x y.y.y.y' is that ifconfig configures sl0 instead of sl1. (To be more exactly, `ifconfig -a' shows that sl0 (but not sl1) has been configured. 4) Moreover, when I then kill my slattach process and then start it again slopen() skips slsoftc[0] because it has SC_STATIC flag set. Note that SC_STATIC flag is not cleared in slclose() to avoid allocation of this unit to the "dynamic slip allocation requests" (i.e. when `slattach' started without -S switch, or when `sliplogin' is started). So, when I kill and start `slattach' 4 times (i.e. the number of slip units configured), slopen() returns ENXIO. If you don't believe me, try to run your kernel.GENERIC (it has been compiled with only 1 slip unit), then start `slattach' with -S switch, kill it, and then try to start `slattach' again. Oops... You'll believe me now ;-) In my point of view, there is the WRONG LOGIC in the if_sl.c. My patch uses the following ideas: 1) Do not `attach the given tty to the first available sl unit' when in the slopen(). 2) Attach the SPECIFIED sl unit to the tty if the sltioctl(SLIOCSUNIT) has been invoked. 3) Or attach `first free, not SC_STATIC sl unit' when the sltioctl(SLIOCGUNIT) has been invoked. The driver version which I've modified is: $Id: if_sl.c,v 1.45.2.1 1997/03/11 19:40:37 bde Exp $ I.e. this is the current version of this driver in RELENG_2_2 branch. My diff is: [**********cut here**********] --- if_sl.c.orig Thu Jul 3 11:10:34 1997 +++ if_sl.c Thu Jul 3 11:17:12 1997 @@ -186,6 +186,7 @@ static struct mbuf *sl_btom __P((struct sl_softc *, int)); static timeout_t sl_keepalive; static timeout_t sl_outfill; +static int slalloc __P((int, struct tty *)); static int slclose __P((struct tty *,int)); static int slinput __P((int, struct tty *)); static int slioctl __P((struct ifnet *, int, caddr_t)); @@ -265,8 +266,6 @@ register struct tty *tp; { struct proc *p = curproc; /* XXX */ - register struct sl_softc *sc; - register int nsl; int s, error; error = suser(p->p_ucred, &p->p_acflag); @@ -276,38 +275,62 @@ if (tp->t_line == SLIPDISC) return (0); - for (nsl = NSL, sc = sl_softc; --nsl >= 0; sc++) - if (sc->sc_ttyp == NULL && !(sc->sc_flags & SC_STATIC)) { - if (slinit(sc) == 0) - return (ENOBUFS); - tp->t_sc = (caddr_t)sc; - sc->sc_ttyp = tp; - sc->sc_if.if_baudrate = tp->t_ospeed; - ttyflush(tp, FREAD | FWRITE); - - tp->t_line = SLIPDISC; - /* - * We don't use t_canq or t_rawq, so reduce their - * cblock resources to 0. Reserve enough cblocks - * for t_outq to guarantee that we can fit a full - * packet if the SLIP_HIWAT check allows slstart() - * to loop. Use the same value for the cblock - * limit since the reserved blocks should always - * be enough. Reserving cblocks probably makes - * the CLISTRESERVE check unnecessary and wasteful. - */ - clist_alloc_cblocks(&tp->t_canq, 0, 0); - clist_alloc_cblocks(&tp->t_outq, - SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, - SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); - clist_alloc_cblocks(&tp->t_rawq, 0, 0); - - s = splnet(); - if_up(&sc->sc_if); - splx(s); - return (0); - } - return (ENXIO); + ttyflush(tp, FREAD | FWRITE); + + tp->t_line = SLIPDISC; + return (0); +} + +static int +slalloc(unit, tp) + int unit; + struct tty *tp; +{ + register struct sl_softc *sc; + int s, static_unit = 1; + + if (unit == -1) { + static_unit = 0; + for (unit = 0; unit < NSL; unit++) + if (sl_softc[unit].sc_ttyp == NULL && + !(sl_softc[unit].sc_flags & SC_STATIC) ) + break; + } + + if (unit < 0 || unit >= NSL || tp->t_sc != NULL) + return (ENXIO); + + sc = &sl_softc[unit]; + if (sc->sc_ttyp != NULL) + return (EBUSY); + if (slinit(sc) == 0) + return (ENOBUFS); + + tp->t_sc = (caddr_t)sc; + sc->sc_ttyp = tp; + sc->sc_if.if_baudrate = tp->t_ospeed; + if (static_unit != 0) + sc->sc_flags |= SC_STATIC; + /* + * We don't use t_canq or t_rawq, so reduce their + * cblock resources to 0. Reserve enough cblocks + * for t_outq to guarantee that we can fit a full + * packet if the SLIP_HIWAT check allows slstart() + * to loop. Use the same value for the cblock + * limit since the reserved blocks should always + * be enough. Reserving cblocks probably makes + * the CLISTRESERVE check unnecessary and wasteful. + */ + clist_alloc_cblocks(&tp->t_canq, 0, 0); + clist_alloc_cblocks(&tp->t_outq, + SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1, + SLIP_HIWAT + 2 * sc->sc_if.if_mtu + 1); + clist_alloc_cblocks(&tp->t_rawq, 0, 0); + + s = splnet(); + if_up(&sc->sc_if); + splx(s); + return (0); } /* @@ -368,34 +391,34 @@ struct proc *p; { struct sl_softc *sc = (struct sl_softc *)tp->t_sc, *nc; - int s, nsl; + int s, nsl, ret; + + if (sc == NULL && (cmd != SLIOCGUNIT && cmd != SLIOCSUNIT)) + return (ENXIO); s = splimp(); switch (cmd) { case SLIOCGUNIT: + if (sc == NULL) { + ret = slalloc(-1, tp); + if (ret != 0) { + splx(s); + return (ret); + } + sc = (struct sl_softc *)tp->t_sc; + } *(int *)data = sc->sc_if.if_unit; break; case SLIOCSUNIT: - if (sc->sc_if.if_unit != *(u_int *)data) { - for (nsl = NSL, nc = sl_softc; --nsl >= 0; nc++) { - if ( nc->sc_if.if_unit == *(u_int *)data - && nc->sc_ttyp == NULL - ) { - nc->sc_if.if_unit = sc->sc_if.if_unit; - nc->sc_flags &= ~SC_STATIC; - nc->sc_flags |= sc->sc_flags & SC_STATIC; - sc->sc_if.if_unit = *(u_int *)data; - goto slfound; - } - } - splx(s); - return (ENXIO); - } - slfound: - sc->sc_flags |= SC_STATIC; + if (sc == NULL) + ret = slalloc(*(int *)data, tp); + else + ret = EEXIST; + splx(s); + return (ret); break; - + case SLIOCSKEEPAL: sc->sc_keepalive = *(u_int *)data * hz; if (sc->sc_keepalive) { [**********cut here**********] Thanks in advance, --- Ruslan A. Ermilov System Administrator ru@ucb.crimea.ua United Commercial Bank +380-652-247 647 Simferopol, Crimea