From owner-freebsd-net Sun Mar 7 5:27:59 1999 Delivered-To: freebsd-net@freebsd.org Received: from picalon.gun.de (picalon.gun.de [194.77.0.18]) by hub.freebsd.org (Postfix) with ESMTP id 63E4114D52 for ; Sun, 7 Mar 1999 05:27:45 -0800 (PST) (envelope-from andreas@klemm.gtn.com) Received: from klemm.gtn.com (pppak04.gtn.com [194.231.123.169]) by picalon.gun.de (8.8.6/8.8.6) with ESMTP id OAA07467; Sun, 7 Mar 1999 14:27:16 +0100 (MET) Received: (from andreas@localhost) by klemm.gtn.com (8.9.2/8.9.2) id OAA05352; Sun, 7 Mar 1999 14:26:18 +0100 (CET) (envelope-from andreas) Date: Sun, 7 Mar 1999 14:26:18 +0100 From: Andreas Klemm To: julian@whistle.com Cc: freebsd-net@FreeBSD.ORG Subject: ALTQ 1.1.3, support for FreeBSD 3.1-STABLE, started the work Message-ID: <19990307142618.A4807@titan.klemm.gtn.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="lrZ03NoBR/3+SXJZ" X-Mailer: Mutt 0.95.3i X-Disclaimer: A free society is one where it is safe to be unpopular X-Operating-System: FreeBSD 3.1-STABLE SMP Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org --lrZ03NoBR/3+SXJZ Content-Type: text/plain; charset=us-ascii Hi Julian (and the others on the list), I started to port your ALTQ 1.1.3 patches for FreeBSD 3.0 to FreeBSD-3.1. Patching the sys dir went very smoothly after bumping patch's Fuzz factor up to 100. A smaller value might be ok as well, but I didn't want to waste time by playing around with different parameters. With a Fuzz of 100 only 2 rejects occurred: ./net/if_ethersubr.c.rej --- applied manually... For this a Fuzz of ~300 would have been needed ./pci/if_en_pci.c.rej --- most or all of the changes went already into the driver, when browsing through it. So I simply ignored it. Well, so far so good (I hope ;-). But the ALTQ kernel doesn't compile well and I'm lacking of experience how to handle with the remaining errors. Managing the first problem was trivial. if_spppsubr.c has a define of it's own for TIMEOUT and UNTIMEOUT, which is already defined by an altq file. Solution is a wrapper like this: --- if_spppsubr.c.orig Sun Dec 27 22:30:44 1998 +++ if_spppsubr.c Sun Mar 7 13:55:59 1999 @@ -100,9 +104,11 @@ #include #if defined(__FreeBSD__) && __FreeBSD__ >= 3 +#if !defined (ALTQ) # define UNTIMEOUT(fun, arg, handle) untimeout(fun, arg, handle) # define TIMEOUT(fun, arg1, arg2, handle) handle = timeout(fun, arg1, arg2) # define IOCTL_CMD_T u_long +#endif ...but the remaining compilation errors scare me a bit. Could you or somebody else please have a look into this ?! root{434} /sys/compile/TITANALTQ make cc -c -O -pipe -Wreturn-type -Wcomment -Wredundant-decls -Wimplicit -Wnested-ex terns -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline -Wunini tialized -Wformat -Wunused -fformat-extensions -ansi -g -nostdinc -I- -I. -I../ .. -I../../../include -DKERNEL -DVM_STACK -include opt_global.h -elf ../../net /if_spppsubr.c ../../net/if_spppsubr.c:629: parameter `pr_hdr' has just a forward declaration ../../net/if_spppsubr.c:627: parameter `m' has just a forward declaration ../../net/if_spppsubr.c:627: parameter `ifp' has just a forward declaration ../../net/if_spppsubr.c:632: conflicting types for `sppp_output' ../../net/if_spppsubr.c:299: previous declaration of `sppp_output' ../../net/if_spppsubr.c: In function `sppp_output': ../../net/if_spppsubr.c:635: warning: `ifq' might be used uninitialized in this function ../../net/if_spppsubr.c: In function `sppp_attach': ../../net/if_spppsubr.c:856: warning: assignment from incompatible pointer type ../../net/if_spppsubr.c: At top level: ../../net/if_spppsubr.c:999: parse error before `IOCTL_CMD_T' ../../net/if_spppsubr.c: In function `sppp_ioctl': ../../net/if_spppsubr.c:1000: number of arguments doesn't match prototype ../../net/if_sppp.h:168: prototype declaration ../../net/if_spppsubr.c:1001: `data' undeclared (first use this function) ../../net/if_spppsubr.c:1001: (Each undeclared identifier is reported only once ../../net/if_spppsubr.c:1001: for each function it appears in.) ../../net/if_spppsubr.c:1002: `ifp' undeclared (first use this function) ../../net/if_spppsubr.c:1007: `cmd' undeclared (first use this function) *** Error code 1 Fine would be to get a working set of patches, to get FreeBSD 3.1 support for ALTQ 1.1.3. In the attachement is my new set of diffs... Andreas /// P.S.: I just read about yout netgraph work, so I don't know if you have time for this (so Cc'd to freebsd-net). BTW, just curious, did you or somebody else play with WFQ ? The authors say in the docu, WFQ isn't well maintained and is missing hashing ... Do you thing using ALTQ brings advantages like Cisco's implementation does ? All I want is, to get better telnet / ssh performance over a 64 KBit ISDN line if UUCP/ftp sessions saturate the link. -- Andreas Klemm http://www.FreeBSD.ORG/~andreas What gives you 90% more speed, for example, in kernel compilation ? http://www.FreeBSD.ORG/~fsmp/SMP/akgraph-a/graph1.html "NT = Not Today" (Maggie Biggs) ``powered by FreeBSD SMP'' --lrZ03NoBR/3+SXJZ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="FreeBSD-3.1-990306.diff" --- ./conf/files.orig Sun Jan 24 06:11:31 1999 +++ ./conf/files Sun Mar 7 12:58:10 1999 @@ -387,6 +387,7 @@ net/bpf_filter.c optional bpfilter net/bridge.c optional bridge net/bsd_comp.c optional ppp_bsdcomp +net/altq_conf.c optional altq #net/hostcache.c standard net/if.c standard net/if_atmsubr.c optional atm @@ -498,6 +499,15 @@ netatm/uni/unisig_subr.c optional atm_uni atm_core netatm/uni/unisig_util.c optional atm_uni atm_core netatm/uni/unisig_vc_state.c optional atm_uni atm_core +netinet/altq_afmap.c optional altq +netinet/altq_cbq.c optional altq +netinet/altq_fifoq.c optional altq +netinet/altq_localq.c optional altq +netinet/altq_red.c optional altq +netinet/altq_rio.c optional altq +netinet/altq_rmclass.c optional altq +netinet/altq_subr.c optional altq +netinet/altq_wfq.c optional altq netinet/fil.c optional ipfilter inet netinet/if_atm.c optional atm netinet/if_ether.c optional ether --- ./conf/options.orig Mon Feb 8 20:05:55 1999 +++ ./conf/options Sun Mar 7 12:58:10 1999 @@ -182,6 +182,22 @@ MAXDSIZ opt_rlimit.h # Net stuff. +# altq stuff +ALTQ opt_global.h +ALTQ_ECN opt_global.h +CBQ opt_altq.h +WFQ opt_altq.h +AFMAP opt_altq.h +FIFOQ opt_altq.h +RED opt_altq.h +FLOWVALVE opt_altq.h +CBQ_RED opt_altq.h +RIO opt_altq.h +CBQ_RIO opt_altq.h +ALTQ_ACCOUNT opt_altq.h +ALTQ_IPSEC opt_altq.h +LOCALQ opt_altq.h + BOOTP opt_bootp.h BOOTP_COMPAT opt_bootp.h BOOTP_NFSROOT opt_bootp.h --- ./dev/en/midway.c.orig Fri Dec 4 23:54:45 1998 +++ ./dev/en/midway.c Sun Mar 7 12:58:10 1999 @@ -164,6 +164,10 @@ #include #endif +#if defined(ALTQ) && defined(AFMAP) +#include +#endif + #if !defined(sparc) && !defined(__FreeBSD__) #include #endif @@ -323,6 +327,12 @@ static int en_txspeed2pcr __P((int)); #endif +#if defined(ALTQ) && defined(AFMAP) +static int en_flowmap_add __P((struct en_softc *, struct atm_flowmap *)); +static int en_flowmap_delete __P((struct en_softc *, int, int)); +static int en_flowmap_get __P((struct en_softc *, struct atm_flowmap *)); +#endif + /* * macros/inline */ @@ -757,6 +767,9 @@ ifp->if_ioctl = en_ioctl; ifp->if_output = atm_output; ifp->if_start = en_start; +#ifdef ALTQ + ifp->if_altqflags |= ALTQF_READY; +#endif /* ALTQ */ /* * init softc @@ -854,6 +867,9 @@ #if NBPFILTER > 0 BPFATTACH(ifp, DLT_ATM_RFC1483, sizeof(struct atmllc)); #endif +#if defined(ALTQ) && defined(AFMAP) + afm_alloc(ifp); +#endif } @@ -1288,6 +1304,43 @@ #endif /* ATM_PVCEXT */ +#if defined(ALTQ) && defined(AFMAP) + case AFM_ADDFMAP: + do { + struct afm *afm = afm_top(ifp); + error = en_flowmap_add(sc, (struct atm_flowmap *)data); + if (afm == NULL && error == 0) + ifp->if_altqflags |= ALTQF_DRIVER1; + } while (0); + break; + + case AFM_DELFMAP: + do { + struct atm_flowmap *fmap = (struct atm_flowmap *)data; + error = en_flowmap_delete(sc, fmap->af_vpi, fmap->af_vci); + + if (afm_top(ifp) == NULL) + ifp->if_altqflags &= ~ALTQF_DRIVER1; + + } while (0); + break; + + case AFM_CLEANFMAP: + do { + struct afm *afm; + while ((afm = afm_top(ifp)) != NULL) + en_flowmap_delete(sc, afm->afm_vpi, afm->afm_vci); + + ifp->if_altqflags &= ~ALTQF_DRIVER1; + } while (0); + break; + + case AFM_GETFMAP: + error = en_flowmap_get(sc, (struct atm_flowmap *)data); + break; + +#endif /* ALTQ && AFMAP */ + default: error = EINVAL; break; @@ -1464,6 +1517,14 @@ m_freem(m); } +#ifdef ALTQ + do { + struct ifnet *ifp = &sc->enif; + + if (ALTQ_IS_ON(ifp)) + (void)(*ifp->if_altqdequeue)(ifp, ALTDQ_FLUSH); + } while (0); +#endif /* ALTQ */ sc->txslot[lcv].mbsize = 0; } @@ -1629,6 +1690,33 @@ while (1) { +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + struct mbuf *tmp; + /* + * when altq is used, don't dequeue the packet until we + * know we have enough buffer space. this makes packet + * dropping is done in altq_enqueue. + * also make the internal buffer smaller (20KB instead of 64KB) + * to keep packets remaining in altq. + */ + m = (*ifp->if_altqdequeue)(ifp, ALTDQ_PEEK); + if (m != NULL) { + ap = mtod(m, struct atm_pseudohdr *); + atm_vci = ATM_PH_VCI(ap); + txchan = sc->txvc2slot[atm_vci]; + if (sc->txslot[txchan].mbsize > 20*1024) { + EN_COUNT(sc->txmbovr); /* this isn't a right stat counter */ + return; + } + + tmp = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + if (tmp != m) + panic("en_start: different mbuf dequeued!"); + } + } + else +#endif IF_DEQUEUE(ifq, m); if (m == NULL) return; /* EMPTY: >>> exit here <<< */ @@ -1765,6 +1853,35 @@ txchan = sc->txvc2slot[atm_vci]; if (sc->txslot[txchan].mbsize > EN_TXHIWAT) { +#ifdef ALTQ_ACCOUNT + /* + * special process for altq drop accounting. + * re-extract flow and do drop-accounting here. + */ + struct pr_hdr pr_hdr; + int size; + + pr_hdr.ph_family = AF_INET; /* XXX */ + if (ifp->if_altqflags & ALTQF_ACCOUNTING) { + size = sizeof(struct atm_pseudohdr); + if (atm_flags & ATM_PH_LLCSNAP) + size += 8; /* sizeof snap == 8 */ + if (atm_flags & EN_OBHDR) + size += MID_TBD_SIZE; + if (m->m_len >= size + 20) + /* ip header in the first mbuf */ + pr_hdr.ph_hdr = mtod(m, caddr_t) + size; + else if (m->m_len == size && m->m_next->m_len >= 20) + /* ip header is in the second mbuf */ + pr_hdr.ph_hdr = mtod(m->m_next, caddr_t); + else + /* give up otherwise */ + pr_hdr.ph_hdr = NULL; + } + else + pr_hdr.ph_hdr = NULL; + ALTQ_ACCOUNTING(ifp, m, &pr_hdr, ALTEQ_ACCDROP); +#endif EN_COUNT(sc->txmbovr); m_freem(m); #ifdef EN_DEBUG @@ -2847,6 +2964,12 @@ sc->vtrash += MID_VTRASH(reg); #endif +#ifdef ALTQ + /* when altq is used, better try to dequeue the next packet. */ + if (ALTQ_IS_ON(&sc->enif) && kick) + en_start(&sc->enif); +#endif + EN_INTR_RET(1); /* for us */ } @@ -3708,5 +3831,98 @@ } #endif /* ATM_PVCEXT */ + +#if defined(ALTQ) && defined(AFMAP) + +static int en_flowmap_add(sc, fmap) + struct en_softc *sc; + struct atm_flowmap *fmap; +{ + struct afm *afm; + struct atm_pseudoioctl api; + int error = 0; + + afm = afm_lookup(&sc->enif, fmap->af_vpi, fmap->af_vci); + if (afm) + /* already in use */ + return (EEXIST); + + if ((error = afm_add(&sc->enif, fmap))) + return error; + + /* enable rx */ + ATM_PH_FLAGS(&api.aph) = ATM_PH_AAL5 | ATM_PH_LLCSNAP; + ATM_PH_VPI(&api.aph) = fmap->af_vpi; + ATM_PH_SETVCI(&api.aph, fmap->af_vci); + api.rxhand = NULL; +#ifdef ATM_PVCEXT + if (fmap->af_ifname[0] == 'p' && fmap->af_ifname[1] == 'v' && + fmap->af_ifname[2] == 'c') { + struct ifnet *shadow; + + if ((shadow = ifunit(fmap->af_ifname)) == NULL) + return (EINVAL); + ATM_PH_FLAGS(&api.aph) |= ATM_PH_PVCSIF; + api.rxhand = shadow; + } +#endif + error = en_rxctl(sc, &api, 1); + if (error) + return error; + error = en_txctl(sc, fmap->af_vci, 0, fmap->af_pcr); + return error; +} + +static int en_flowmap_delete(sc, vpi, vci) + struct en_softc *sc; + int vpi, vci; +{ + struct afm *afm; + struct atm_pseudoioctl api; + int error = 0; + + afm = afm_lookup(&sc->enif, vpi, vci); + if (afm == NULL) + return (ENOENT); + + afm_remove(afm); + + /* disable rx */ + ATM_PH_FLAGS(&api.aph) = 0; + ATM_PH_VPI(&api.aph) = vpi; + ATM_PH_SETVCI(&api.aph, vci); + api.rxhand = NULL; + error = en_rxctl(sc, &api, 0); + + return error; +} + +static int en_flowmap_get(sc, fmap) + struct en_softc *sc; + struct atm_flowmap *fmap; +{ + struct afm *afm; + int error = 0; + + afm = afm_lookup(&sc->enif, fmap->af_vpi, fmap->af_vci); + if (afm == NULL) + return (ENOENT); + + bcopy(&afm->afm_flowinfo, &fmap->af_flowinfo, sizeof(struct flowinfo)); + + /* get pcr value */ + if (sc->txspeed[fmap->af_vci] != 0) + fmap->af_pcr = en_txspeed2pcr(sc->txspeed[fmap->af_vci]); + else + fmap->af_pcr = 0; + + /* get stats */ + fmap->afs_packets = afm->afms_packets; + fmap->afs_bytes = afm->afms_bytes; + + return error; +} + +#endif /* ALTQ && AFMAP */ #endif /* NEN > 0 || !defined(__FreeBSD__) */ --- ./dev/vx/if_vx.c.orig Tue Jan 12 03:09:31 1999 +++ ./dev/vx/if_vx.c Sun Mar 7 12:58:10 1999 @@ -212,6 +212,9 @@ ifp->if_init = vxinit; ifp->if_watchdog = vxwatchdog; ifp->if_softc = sc; +#ifdef ALTQ + ifp->if_altqflags |= ALTQF_READY; +#endif if_attach(ifp); ether_ifattach(ifp); @@ -453,6 +456,11 @@ startagain: /* Sneak a peek at the next packet */ +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) + m0 = (*ifp->if_altqdequeue)(ifp, ALTDQ_PEEK); + else +#endif m0 = ifp->if_snd.ifq_head; if (m0 == 0) { return; @@ -472,6 +480,14 @@ if (len + pad > ETHER_MAX_LEN) { /* packet is obviously too large: toss it */ ++ifp->if_oerrors; +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + struct mbuf *tmp = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + if (tmp != m0) + panic("vxstart: different mbuf dequeued!"); + } + else +#endif IF_DEQUEUE(&ifp->if_snd, m0); m_freem(m0); goto readcheck; @@ -487,6 +503,14 @@ } } outw(BASE + VX_COMMAND, SET_TX_AVAIL_THRESH | (8188 >> 2)); +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + struct mbuf *tmp = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + if (tmp != m0) + panic("vxstart: different mbuf dequeued!"); + } + else +#endif IF_DEQUEUE(&ifp->if_snd, m0); if (m0 == 0) { /* not really needed */ return; --- ./i386/conf/ALTQ.orig Sun Mar 7 12:58:10 1999 +++ ./i386/conf/ALTQ Sun Mar 7 12:58:10 1999 @@ -0,0 +1,219 @@ +# +# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks +# +# For more information read the handbook part System Administration -> +# Configuring the FreeBSD Kernel -> The Configuration File. +# The handbook is available in /usr/share/doc/handbook or online as +# latest version from the FreeBSD World Wide Web server +# +# +# An exhaustive list of options and more detailed explanations of the +# device lines is present in the ./LINT configuration file. If you are +# in doubt as to the purpose or necessity of a line, check first in LINT. +# +# $Id: GENERIC,v 1.125 1998/10/16 01:30:11 obrien Exp $ + +machine "i386" +cpu "I386_CPU" +cpu "I486_CPU" +cpu "I586_CPU" +cpu "I686_CPU" +ident GENERIC +maxusers 32 + +options MATH_EMULATE #Support for x87 emulation +options INET #InterNETworking +options FFS #Berkeley Fast Filesystem +options FFS_ROOT #FFS usable as root device [keep this!] +options MFS #Memory Filesystem +options MFS_ROOT #MFS usable as root device, "MFS" req'ed +options NFS #Network Filesystem +options NFS_ROOT #NFS usable as root device, "NFS" req'ed +options MSDOSFS #MSDOS Filesystem +options "CD9660" #ISO 9660 Filesystem +options "CD9660_ROOT" #CD-ROM usable as root. "CD9660" req'ed +options PROCFS #Process filesystem +options "COMPAT_43" #Compatible with BSD 4.3 [KEEP THIS!] +options SCSI_DELAY=15000 #Be pessimistic about Joe SCSI device +options UCONSOLE #Allow users to grab the console +options FAILSAFE #Be conservative +options USERCONFIG #boot -c editor +options VISUAL_USERCONFIG #visual boot -c editor + +options NMBCLUSTERS=2048 +options MROUTING # Multicast routing +options NATM #native mode atm + +options ALTQ #alternate queueing +options CBQ #class based queueing +options WFQ #weighted fair queueing +options FIFOQ #fifo queueing +options RED #random early detection +options FLOWVALVE #flowvalve for RED (needs RED) +options CBQ_RED #red for cbq (needs CBQ and RED) +options RIO #twin red for diffserv (needs RED) +options CBQ_RIO #rio for cbq (needs CBQ, RIO, RED, CBQ_RED) +options LOCALQ #local use +options ALTQ_ACCOUNT #altq accounting +options ALTQ_ECN #ecn extention to tcp + +config kernel root on wd0 + +controller isa0 +controller eisa0 +controller pci0 + +controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr +disk fd0 at fdc0 drive 0 +disk fd1 at fdc0 drive 1 +# Unless you know very well what you're doing, leave ft0 at drive 2, or +# remove the line entirely if you don't need it. Trying to configure +# it on another unit might cause surprises, see PR kern/7176. +tape ft0 at fdc0 drive 2 + +options "CMD640" # work around CMD640 chip deficiency +controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr +disk wd0 at wdc0 drive 0 +disk wd1 at wdc0 drive 1 + +controller wdc1 at isa? port "IO_WD2" bio irq 15 vector wdintr +disk wd2 at wdc1 drive 0 +disk wd3 at wdc1 drive 1 + +options ATAPI #Enable ATAPI support for IDE bus +options ATAPI_STATIC #Don't do it as an LKM +device wcd0 #IDE CD-ROM +device wfd0 #IDE Floppy (e.g. LS-120) + +# A single entry for any of these controllers (ncr, ahb, ahc, amd) is +# sufficient for any number of installed devices. +controller ncr0 +#controller amd0 +controller ahb0 +controller ahc0 +controller isp0 + +# This controller offers a number of configuration options, too many to +# document here - see the LINT file in this directory and look up the +# dpt0 entry there for much fuller documentation on this. +controller dpt0 + +controller adv0 at isa? port ? cam irq ? +controller adw0 +controller bt0 at isa? port ? cam irq ? +controller aha0 at isa? port ? cam irq ? +#controller uha0 at isa? port "IO_UHA0" bio irq ? drq 5 vector uhaintr +#controller aic0 at isa? port 0x340 bio irq 11 vector aicintr +#controller nca0 at isa? port 0x1f88 bio irq 10 vector ncaintr +#controller nca1 at isa? port 0x350 bio irq 5 vector ncaintr +#controller sea0 at isa? bio irq 5 iomem 0xc8000 iosiz 0x2000 vector seaintr + +controller scbus0 + +device da0 + +device sa0 + +device pass0 + +device cd0 #Only need one of these, the code dynamically grows + +device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr +device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr + +controller matcd0 at isa? port 0x230 bio + +device scd0 at isa? port 0x230 bio + +# syscons is the default console driver, resembling an SCO console +device sc0 at isa? port "IO_KBD" conflicts tty irq 1 vector scintr +# Enable this and PCVT_FREEBSD for pcvt vt220 compatible console driver +#device vt0 at isa? port "IO_KBD" conflicts tty irq 1 vector pcrint +#options XSERVER # support for X server +#options FAT_CURSOR # start with block cursor +# If you have a ThinkPAD, uncomment this along with the rest of the PCVT lines +#options PCVT_SCANSET=2 # IBM keyboards are non-std + +device npx0 at isa? port "IO_NPX" irq 13 vector npxintr + +# +# Laptop support (see LINT for more options) +# +device apm0 at isa? disable flags 0x31 # Advanced Power Management + +# PCCARD (PCMCIA) support +#controller card0 +#device pcic0 at card? +#device pcic1 at card? + +device sio0 at isa? port "IO_COM1" flags 0x10 tty irq 4 vector siointr +device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr +device sio2 at isa? disable port "IO_COM3" tty irq 5 vector siointr +device sio3 at isa? disable port "IO_COM4" tty irq 9 vector siointr + +device lpt0 at isa? port? tty irq 7 vector lptintr + +device psm0 at isa? port "IO_KBD" conflicts tty irq 12 vector psmintr + +# Order is important here due to intrusive probes, do *not* alphabetize +# this list of network interfaces until the probes have been fixed. +# Right now it appears that the ie0 must be probed before ep0. See +# revision 1.20 of this file. +device de0 +device fxp0 +device tl0 +device tx0 +device vx0 +device xl0 + +# ATM (en*) support +device en0 +device en1 + +device ed0 at isa? port 0x280 net irq 10 iomem 0xd8000 vector edintr +device ie0 at isa? port 0x300 net irq 10 iomem 0xd0000 vector ieintr +device ep0 at isa? port 0x300 net irq 10 vector epintr +device ex0 at isa? port? net irq? vector exintr +device fe0 at isa? port 0x300 net irq ? vector feintr +device le0 at isa? port 0x300 net irq 5 iomem 0xd0000 vector le_intr +device lnc0 at isa? port 0x280 net irq 10 drq 0 vector lncintr +device ze0 at isa? port 0x300 net irq 10 iomem 0xd8000 vector zeintr +device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000 vector zpintr +device cs0 at isa? port 0x300 net irq ? vector csintr + +pseudo-device loop +pseudo-device ether +pseudo-device atm +pseudo-device sl 1 +pseudo-device ppp 1 +pseudo-device tun 1 +pseudo-device pty 16 +pseudo-device gzip # Exec gzipped a.out's + +# +# Enable the kernel debugger. +# +options DDB + +# +# Don't drop into DDB for a panic. Intended for unattended operation +# where you may want to drop to DDB from the console, but still want +# the machine to recover from a panic +# +#options DDB_UNATTENDED + +# KTRACE enables the system-call tracing facility ktrace(2). +# This adds 4 KB bloat to your kernel, and slightly increases +# the costs of each syscall. +options KTRACE #kernel tracing + +# This provides support for System V shared memory. +# +options SYSVSHM + +# The `bpfilter' pseudo-device enables the Berkeley Packet Filter. Be +# aware of the legal and administrative consequences of enabling this +# option. The number of devices determines the maximum number of +# simultaneous BPF clients programs runnable. +pseudo-device bpfilter 4 #Berkeley packet filter + --- ./i386/conf/LINT.orig Sun Feb 21 22:12:26 1999 +++ ./i386/conf/LINT Sun Mar 7 12:58:10 1999 @@ -1929,6 +1929,22 @@ options SPX_HACK options VFS_BIO_DEBUG +# ALTQ options +options ALTQ #alternate queueing +options CBQ #class based queueing +options WFQ #weighted fair queueing +options AFMAP #atm flow mapping +options FIFOQ #fifo queueing +options RED #random early detection +options CBQ_RED #red for cbq (needs CBQ and RED) +options RIO #twin red for diffserv (needs RED) +options CBQ_RIO #rio for cbq (needs CBQ, RIO, RED, CBQ_RED) +options LOCALQ #local use +options ALTQ_ACCOUNT #altq accounting +options ALTQ_ECN #ecn extention to tcp (needs RED) +options ALTQ_IPSEC #check ipsec in IPv4 +options ALTQ_PPP #sio modification for userland ppp + # The 'dpt' driver provides support for DPT controllers (http://www.dpt.com/). # These have hardware RAID-{0,1,5} support, and do multi-initiator I/O. # The DPT controllers are commonly re-licensed under other brand-names - --- ./i386/isa/if_ar.c.orig Wed Dec 16 19:42:38 1998 +++ ./i386/isa/if_ar.c Sun Mar 7 12:58:10 1999 @@ -346,6 +346,9 @@ ifp->if_ioctl = arioctl; ifp->if_start = arstart; ifp->if_watchdog = arwatchdog; +#ifdef ALTQ + ifp->if_altqflags |= ALTQF_READY; +#endif sc->ifsppp.pp_flags = PP_KEEPALIVE; --- ./i386/isa/if_cx.c.orig Wed Dec 16 19:42:38 1998 +++ ./i386/isa/if_cx.c Sun Mar 7 12:58:10 1999 @@ -281,6 +281,9 @@ c->ifp->if_ioctl = cxsioctl; c->ifp->if_start = (start_func_t) cxstart; c->ifp->if_watchdog = (watchdog_func_t) cxwatchdog; +#ifdef ALTQ + c->ifp->if_altqflags |= ALTQF_READY; +#endif /* Init routine is never called by upper level? */ sppp_attach (c->ifp); if_attach (c->ifp); --- ./i386/isa/if_ed.c.orig Tue Jan 19 01:21:38 1999 +++ ./i386/isa/if_ed.c Sun Mar 7 12:58:10 1999 @@ -1684,6 +1684,9 @@ ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); +#ifdef ALTQ + ifp->if_altqflags |= ALTQF_READY; +#endif /* * Attach the interface */ @@ -2071,6 +2074,12 @@ ifp->if_flags |= IFF_OACTIVE; return; } +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + m = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + } + else +#endif IF_DEQUEUE(&ifp->if_snd, m); if (m == 0) { --- ./i386/isa/if_ep.c.orig Tue Jan 19 01:21:39 1999 +++ ./i386/isa/if_ep.c Sun Mar 7 12:58:10 1999 @@ -615,6 +615,9 @@ ifp->if_start = epstart; ifp->if_ioctl = epioctl; ifp->if_watchdog = epwatchdog; +#ifdef ALTQ + ifp->if_altqflags |= ALTQF_READY; +#endif if (!attached) { if_attach(ifp); @@ -810,6 +813,11 @@ } startagain: /* Sneak a peek at the next packet */ +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) + m = (*ifp->if_altqdequeue)(ifp, ALTDQ_PEEK); + else +#endif m = ifp->if_snd.ifq_head; if (m == 0) { splx(s); @@ -828,6 +836,14 @@ if (len + pad > ETHER_MAX_LEN) { /* packet is obviously too large: toss it */ ++ifp->if_oerrors; +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + m = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + if (m != top) + panic("epstart: different mbuf dequeued!"); + } + else +#endif IF_DEQUEUE(&ifp->if_snd, m); m_freem(m); goto readcheck; @@ -842,6 +858,14 @@ return; } } +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + m = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + if (m != top) + panic("epstart: different mbuf dequeued!"); + } + else +#endif IF_DEQUEUE(&ifp->if_snd, m); outw(BASE + EP_W1_TX_PIO_WR_1, len); --- ./i386/isa/if_lnc.c.orig Sun Jan 31 01:57:46 1999 +++ ./i386/isa/if_lnc.c Sun Mar 7 12:58:10 1999 @@ -1240,6 +1240,9 @@ sc->arpcom.ac_if.if_type = IFT_ETHER; sc->arpcom.ac_if.if_addrlen = ETHER_ADDR_LEN; sc->arpcom.ac_if.if_hdrlen = ETHER_HDR_LEN; +#ifdef ALTQ + sc->arpcom.ac_if.if_altqflags |= ALTQF_READY; +#endif /* * XXX -- should check return status of if_attach @@ -1646,6 +1649,11 @@ do { +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) + head = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + else +#endif IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, head); if (!head) return; --- ./i386/isa/if_sr.c.orig Mon Jan 18 22:27:03 1999 +++ ./i386/isa/if_sr.c Sun Mar 7 12:58:10 1999 @@ -825,6 +825,9 @@ ifp->if_ioctl = srioctl; ifp->if_start = srstart; ifp->if_watchdog = srwatchdog; +#ifdef ALTQ + ifp->if_altqflags |= ALTQF_READY; +#endif printf("sr%d: Adapter %d, port %d.\n", sc->unit, hc->cunit, sc->subunit); @@ -1173,7 +1176,13 @@ * hardcoded. A packet can't be larger than 3 buffers (3 x * 512). */ +#if 0 /* defined(ALTQ) */ + /* XXX use 6KB buffer instead of 16KB to reduce latency */ + /* quick dirty hack, but very effective! */ + if ((i + 3) >= (blkp->txmax * 6 / 16)) { /* enough remains? */ +#else if ((i + 3) >= blkp->txmax) { /* enough remains? */ +#endif #if BUGGY > 9 printf("sr%d.srstart: i=%d (%d pkts); card full.\n", sc->unit, i, pkts); --- ./net/if.h.orig Sat Mar 21 14:36:20 1998 +++ ./net/if.h Sun Mar 7 12:58:11 1999 @@ -44,6 +44,9 @@ #ifndef KERNEL #include #endif +#if 1 /* ALTQ */ +#include +#endif /* * Structure describing information about an interface --- ./net/if_atmsubr.c.orig Fri Dec 4 23:54:52 1998 +++ ./net/if_atmsubr.c Sun Mar 7 12:58:11 1999 @@ -35,6 +35,9 @@ /* * if_atmsubr.c */ +#ifdef ALTQ +#include "opt_altq.h" +#endif #include "opt_inet.h" #include "opt_natm.h" @@ -64,6 +67,10 @@ #include #endif +#if defined(ALTQ) && defined(AFMAP) +#include +#endif + #ifndef ETHERTYPE_IPV6 #define ETHERTYPE_IPV6 0x86dd #endif @@ -100,10 +107,25 @@ struct atmllc *atmllc; struct atmllc *llc_hdr = NULL; u_int32_t atm_flags; +#ifdef ALTQ + struct pr_hdr pr_hdr; +#endif if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) senderr(ENETDOWN); +#ifdef ALTQ + /* + * save a pointer to the protocol level header before adding + * link headers. + */ + if (dst) + pr_hdr.ph_family = dst->sa_family; + else + pr_hdr.ph_family = AF_UNSPEC; + pr_hdr.ph_hdr = mtod(m, caddr_t); +#endif /* ALTQ */ + /* * check route */ @@ -161,6 +183,17 @@ */ bcopy(dst->sa_data, &atmdst, sizeof(atmdst)); llc_hdr = (struct atmllc *)(dst->sa_data + sizeof(atmdst)); +#ifdef ALTQ + /* modify pr_hdr to have a correct family */ + switch (ATM_LLC_TYPE(llc_hdr)) { + case ETHERTYPE_IP: + pr_hdr.ph_family = AF_INET; + break; + case ETHERTYPE_IPV6: + pr_hdr.ph_family = AF_INET6; + break; + } +#endif break; default: @@ -174,6 +207,29 @@ senderr(EAFNOSUPPORT); } +#if defined(ALTQ) && defined(AFMAP) + if (ifp->if_altqflags & ALTQF_DRIVER1) { + /* try to map flow to vpi/vci. */ + struct flowinfo flow; + struct afm *afm; + + altq_extractflow(m, &pr_hdr, &flow, FIMB_ALL); + if ((afm = afm_match(ifp, &flow)) != NULL) { + /* matching entry found. overwrite vpi:vci. */ +#if 0 + printf("%s%d: atm_output:afmap vci %d -> %d\n", + ifp->if_name, ifp->if_unit, + ATM_PH_VCI(&atmdst), afm->afm_vci); +#endif + ATM_PH_VPI(&atmdst) = afm->afm_vpi; + ATM_PH_SETVCI(&atmdst, afm->afm_vci); + + afm->afms_packets++; + afm->afms_bytes = m->m_pkthdr.len; + } + } +#endif /* ALTQ && AFMAP */ + /* * must add atm_pseudohdr to data */ @@ -202,14 +258,37 @@ * Queue message on interface, and start output if interface * not yet active. */ +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + s = splimp(); + error = (*ifp->if_altqenqueue)(ifp, m, &pr_hdr, ALTEQ_NORMAL); + splx(s); + if (error) { + IF_DROP(&ifp->if_snd); + } + else { + ifp->if_obytes += m->m_pkthdr.len; + if (m->m_flags & M_MCAST) + ifp->if_omcasts++; + } + return (error); + } +#endif /* ALTQ */ + s = splimp(); if (IF_QFULL(&ifp->if_snd)) { IF_DROP(&ifp->if_snd); +#ifdef ALTQ_ACCOUNT + ALTQ_ACCOUNTING(ifp, m, &pr_hdr, ALTEQ_ACCDROP); +#endif splx(s); senderr(ENOBUFS); } ifp->if_obytes += m->m_pkthdr.len; IF_ENQUEUE(&ifp->if_snd, m); +#ifdef ALTQ_ACCOUNT + ALTQ_ACCOUNTING(ifp, m, &pr_hdr, ALTEQ_ACCOK); +#endif if ((ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); splx(s); --- ./net/if_ethersubr.c.orig Tue Jan 12 13:07:00 1999 +++ ./net/if_ethersubr.c Sun Mar 7 13:17:40 1999 @@ -33,6 +33,9 @@ * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93 * $Id: if_ethersubr.c,v 1.54 1999/01/12 12:07:00 eivind Exp $ */ +#ifdef ALTQ +#include "opt_altq.h" +#endif #include "opt_atalk.h" #include "opt_inet.h" @@ -139,6 +142,9 @@ int off, len = m->m_pkthdr.len, loop_copy = 0; int hlen; /* link layer header lenght */ struct arpcom *ac = (struct arpcom *)ifp; +#ifdef ALTQ + struct pr_hdr pr_hdr; +#endif if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) senderr(ENETDOWN); @@ -167,6 +173,15 @@ time_second < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } +#ifdef ALTQ + /* + * save a pointer to the protocol level header before adding + * link headers. + */ + pr_hdr.ph_family = dst->sa_family; + pr_hdr.ph_hdr = mtod(m, caddr_t); +#endif /* ALTQ */ + hlen = ETHER_HDR_LEN; switch (dst->sa_family) { #ifdef INET @@ -397,10 +412,16 @@ */ if (IF_QFULL(&ifp->if_snd)) { IF_DROP(&ifp->if_snd); +#ifdef ALTQ_ACCOUNT + ALTQ_ACCOUNTING(ifp, m, &pr_hdr, ALTEQ_ACCDROP); +#endif splx(s); senderr(ENOBUFS); } IF_ENQUEUE(&ifp->if_snd, m); +#ifdef ALTQ_ACCOUNT + ALTQ_ACCOUNTING(ifp, m, &pr_hdr, ALTEQ_ACCOK); +#endif if ((ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); splx(s); @@ -643,6 +664,22 @@ #endif /* ISO || LLC || NETATALK */ } +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + s = splimp(); + error = (*ifp->if_altqenqueue)(ifp, m, &pr_hdr, ALTEQ_NORMAL); + splx(s); + if (error) { + IF_DROP(&ifp->if_snd); + } + else { + ifp->if_obytes += len + sizeof (struct ether_header); + if (m->m_flags & M_MCAST) + ifp->if_omcasts++; + } + return (error); + } +#endif /* ALTQ */ s = splimp(); if (IF_QFULL(inq)) { IF_DROP(inq); --- ./net/if_loop.c.orig Sun Jul 12 18:46:52 1998 +++ ./net/if_loop.c Sun Mar 7 12:58:11 1999 @@ -91,6 +91,9 @@ static void lortrequest __P((int, struct rtentry *, struct sockaddr *)); static void loopattach __P((void *)); +#ifdef ALTQ +static void lo_altqstart __P((struct ifnet *)); +#endif PSEUDO_SET(loopattach, if_loop); static int looutput __P((struct ifnet *ifp, @@ -120,6 +123,10 @@ ifp->if_ioctl = loioctl; ifp->if_output = looutput; ifp->if_type = IFT_LOOP; +#ifdef ALTQ + ifp->if_start = lo_altqstart; + ifp->if_altqflags |= ALTQF_READY; +#endif if_attach(ifp); #if NBPFILTER > 0 bpfattach(ifp, DLT_NULL, sizeof(u_int)); @@ -230,6 +237,36 @@ m_adj(m, hlen); } +#ifdef ALTQ + /* + * altq for loop is just for debugging. + * only used when called for loop interface (not for + * a simplex interface). + */ + if (ALTQ_IS_ON(ifp) && ifp->if_start == lo_altqstart) { + struct pr_hdr pr_hdr; + int32_t *afp; + int error; + + pr_hdr.ph_family = dst->sa_family; + pr_hdr.ph_hdr = mtod(m, caddr_t); + + M_PREPEND(m, sizeof(int32_t), M_DONTWAIT); + if (m == 0) + return(ENOBUFS); + afp = mtod(m, int32_t *); + *afp = (int32_t)dst->sa_family; + + s = splimp(); + error = (*ifp->if_altqenqueue)(ifp, m, &pr_hdr, ALTEQ_NORMAL); + splx(s); + if (error) { + IF_DROP(&ifp->if_snd); + } + return (error); + } +#endif /* ALTQ */ + switch (dst->sa_family) { #ifdef INET case AF_INET: @@ -280,6 +317,84 @@ splx(s); return (0); } + +#ifdef ALTQ +static void +lo_altqstart(ifp) + struct ifnet *ifp; +{ + struct ifqueue *ifq; + struct mbuf *m; + int32_t af, *afp; + int s, isr; + + if (!ALTQ_IS_ON(ifp)) + return; + + while (1) { + s = splimp(); + m = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + splx(s); + + if (m == NULL) + return; + + afp = mtod(m, int32_t *); + af = *afp; + m_adj(m, sizeof(int32_t)); + + switch (af) { +#ifdef INET + case AF_INET: + ifq = &ipintrq; + isr = NETISR_IP; + break; +#endif +#ifdef IPX + case AF_IPX: + ifq = &ipxintrq; + isr = NETISR_IPX; + break; +#endif +#ifdef NS + case AF_NS: + ifq = &nsintrq; + isr = NETISR_NS; + break; +#endif +#ifdef ISO + case AF_ISO: + ifq = &clnlintrq; + isr = NETISR_ISO; + break; +#endif +#ifdef NETATALK + case AF_APPLETALK: + ifq = &atintrq2; + isr = NETISR_ATALK; + break; +#endif NETATALK + default: + printf("lo_altqstart: can't handle af%d\n", af); + m_freem(m); + return; + } + + s = splimp(); + if (IF_QFULL(ifq)) { + IF_DROP(ifq); + m_freem(m); + splx(s); + return; + } + IF_ENQUEUE(ifq, m); + schednetisr(isr); + ifp->if_ipackets++; + ifp->if_ibytes += m->m_pkthdr.len; + splx(s); + } +} +#endif /* ALTQ */ /* ARGSUSED */ static void --- ./net/if_sl.c.orig Wed Jul 15 04:32:23 1998 +++ ./net/if_sl.c Sun Mar 7 12:58:11 1999 @@ -68,6 +68,10 @@ #include "sl.h" #if NSL > 0 +#ifdef ALTQ +#include "opt_altq.h" +#endif + #include "bpfilter.h" #include "opt_inet.h" @@ -225,6 +229,7 @@ sc->sc_fastq.ifq_maxlen = 32; sc->sc_if.if_linkmib = sc; sc->sc_if.if_linkmiblen = sizeof *sc; + sc->sc_if.if_altqflags |= ALTQF_READY; if_attach(&sc->sc_if); #if NBPFILTER > 0 bpfattach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN); @@ -473,6 +478,12 @@ register struct ip *ip; register struct ifqueue *ifq; int s; +#ifdef ALTQ + struct pr_hdr pr_hdr; + + pr_hdr.ph_family = dst->sa_family; + pr_hdr.ph_hdr = mtod(m, caddr_t); +#endif /* * `Cannot happen' (see slioctl). Someday we will extend @@ -503,14 +514,37 @@ if (ip->ip_tos & IPTOS_LOWDELAY) ifq = &sc->sc_fastq; s = splimp(); +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + int error; + + error = (*ifp->if_altqenqueue)(ifp, m, &pr_hdr, ALTEQ_NORMAL); + if (error) { + splx(s); + IF_DROP(&sc->sc_if.if_snd); + sc->sc_if.if_oerrors++; + return (error); + } + } + else { +#endif /* ALTQ */ if (IF_QFULL(ifq)) { IF_DROP(ifq); +#ifdef ALTQ_ACCOUNT + ALTQ_ACCOUNTING(ifp, m, &pr_hdr, ALTEQ_ACCDROP); +#endif m_freem(m); splx(s); sc->sc_if.if_oerrors++; return (ENOBUFS); } IF_ENQUEUE(ifq, m); +#ifdef ALTQ_ACCOUNT + ALTQ_ACCOUNTING(ifp, m, &pr_hdr, ALTEQ_ACCOK); +#endif +#ifdef ALTQ + } +#endif if (sc->sc_ttyp->t_outq.c_cc == 0) slstart(sc->sc_ttyp); splx(s); @@ -562,11 +596,20 @@ * Get a packet and send it to the interface. */ s = splimp(); +#ifdef ALTQ + if (ALTQ_IS_ON(&sc->sc_if)) + m = (*sc->sc_if.if_altqdequeue)(&sc->sc_if, + ALTDQ_DEQUEUE); + else { +#endif IF_DEQUEUE(&sc->sc_fastq, m); if (m) sc->sc_if.if_omcasts++; /* XXX */ else IF_DEQUEUE(&sc->sc_if.if_snd, m); +#ifdef ALTQ + } +#endif splx(s); if (m == NULL) return 0; --- ./net/if_spppsubr.c.orig Sun Dec 27 22:30:44 1998 +++ ./net/if_spppsubr.c Sun Mar 7 12:58:11 1999 @@ -20,6 +20,10 @@ * $Id: if_spppsubr.c,v 1.52 1998/12/27 21:30:44 phk Exp $ */ +#ifdef ALTQ +#include "opt_altq.h" +#endif + #include #if defined(__FreeBSD__) && __FreeBSD__ >= 3 @@ -619,6 +623,9 @@ */ static int sppp_output(struct ifnet *ifp, struct mbuf *m, +#ifdef ALTQ + struct pr_hdr pr_hdr; +#endif struct sockaddr *dst, struct rtentry *rt) { struct sppp *sp = (struct sppp*) ifp; @@ -647,6 +654,18 @@ s = splimp(); } +#ifdef ALTQ + /* + * save a pointer to the protocol level header before adding + * link headers. + */ + pr_hdr.ph_family = dst->sa_family; + pr_hdr.ph_hdr = mtod(m, caddr_t); +#endif /* ALTQ */ + +#ifdef ALTQ + if (!ALTQ_IS_ON(ifp)) { +#endif ifq = &ifp->if_snd; #ifdef INET if (dst->sa_family == AF_INET) { @@ -693,6 +712,9 @@ ifq = &sp->pp_fastq; } #endif +#ifdef ALTQ + } +#endif /* * Prepend general data packet PPP header. For now, IP only. @@ -767,18 +789,39 @@ return (EAFNOSUPPORT); } +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + int error, len; + len = m->m_pkthdr.len; + error = (*ifp->if_altqenqueue)(ifp, m, &pr_hdr, ALTEQ_NORMAL); + if (error) { + IF_DROP (&ifp->if_snd); + } + else + ifp->if_obytes += len + 3; + splx(s); + return (error); + } +#endif /* ALTQ */ + /* * Queue message on interface, and start output if interface * not yet active. */ if (IF_QFULL (ifq)) { IF_DROP (&ifp->if_snd); +#ifdef ALTQ_ACCOUNT + ALTQ_ACCOUNTING(ifp, m, &pr_hdr, ALTEQ_ACCDROP); +#endif m_freem (m); ++ifp->if_oerrors; splx (s); return (rv? rv: ENOBUFS); } IF_ENQUEUE (ifq, m); +#ifdef ALTQ_ACCOUNT + ALTQ_ACCOUNTING(ifp, m, &pr_hdr, ALTEQ_ACCOK); +#endif if (! (ifp->if_flags & IFF_OACTIVE)) (*ifp->if_start) (ifp); @@ -858,6 +901,12 @@ { struct sppp *sp = (struct sppp*) ifp; +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + (void)(*ifp->if_altqdequeue)(ifp, ALTDQ_FLUSH); + return; + } +#endif sppp_qflush (&sp->pp_if.if_snd); sppp_qflush (&sp->pp_fastq); sppp_qflush (&sp->pp_cpq); @@ -873,6 +922,11 @@ int empty, s; s = splimp(); +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) + empty = ((*ifp->if_altqdequeue)(ifp, ALTDQ_PEEK) == NULL); + else +#endif empty = !sp->pp_fastq.ifq_head && !sp->pp_cpq.ifq_head && !sp->pp_if.if_snd.ifq_head; splx(s); @@ -890,6 +944,13 @@ int s; s = splimp(); +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + m = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + splx(s); + return (m); + } +#endif /* ALTQ */ /* * Process only the control protocol queue until we have at * least one NCP open. @@ -1071,6 +1132,11 @@ if (ifp->if_flags & IFF_UP) { if_down (ifp); sppp_qflush (&sp->pp_cpq); +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) + (void)(*ifp->if_altqdequeue) + (ifp, ALTDQ_FLUSH); +#endif } } ++sp->pp_loopcnt; @@ -1206,6 +1272,22 @@ sppp_print_bytes ((u_char*) (lh+1), len); addlog(">\n"); } +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + struct pr_hdr pr_hdr; + int error, len; + + len = m->m_pkthdr.len; + altq_mkctlhdr(&pr_hdr); /* fake a control type header */ + error = (*ifp->if_altqenqueue)(ifp, m, &pr_hdr, ALTEQ_NORMAL); + if (error) { + IF_DROP (&ifp->if_snd); + } + else + ifp->if_obytes += len + 3; + return; + } +#endif /* ALTQ */ if (IF_QFULL (&sp->pp_cpq)) { IF_DROP (&sp->pp_fastq); IF_DROP (&ifp->if_snd); @@ -1514,6 +1596,10 @@ if_down (ifp); sppp_qflush (&sp->pp_cpq); +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) + (void)(*ifp->if_altqdequeue) (ifp, ALTDQ_FLUSH); +#endif /* Shut down the PPP link. */ /* XXX */ lcp.Down(sp); @@ -2027,6 +2113,11 @@ if_down(ifp); sppp_qflush(&sp->pp_cpq); /* XXX ? */ +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) + (void)(*ifp->if_altqdequeue) + (ifp, ALTDQ_FLUSH); +#endif lcp.Down(sp); lcp.Up(sp); } @@ -3764,6 +3855,22 @@ sppp_print_bytes((u_char*) (lh+1), len); addlog(">\n"); } +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + struct pr_hdr pr_hdr; + int error, len; + + len = m->m_pkthdr.len; + altq_mkctlhdr(&pr_hdr); /* fake a control type header */ + error = (*ifp->if_altqenqueue)(ifp, m, &pr_hdr, ALTEQ_NORMAL); + if (error) { + IF_DROP (&ifp->if_snd); + } + else + ifp->if_obytes += len + 3; + return; + } +#endif /* ALTQ */ if (IF_QFULL (&sp->pp_cpq)) { IF_DROP (&sp->pp_fastq); IF_DROP (&ifp->if_snd); @@ -3822,6 +3929,10 @@ printf (SPP_FMT "down\n", SPP_ARGS(ifp)); if_down (ifp); sppp_qflush (&sp->pp_cpq); +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) + (void)(*ifp->if_altqdequeue)(ifp, ALTDQ_FLUSH); +#endif if (! (sp->pp_flags & PP_CISCO)) { /* XXX */ /* Shut down the PPP link. */ --- ./net/if_var.h.orig Wed Dec 16 19:30:43 1998 +++ ./net/if_var.h Sun Mar 7 12:58:11 1999 @@ -138,6 +138,16 @@ __P((struct ifnet *, struct sockaddr **, struct sockaddr *)); struct ifqueue if_snd; /* output queue */ struct ifqueue *if_poll_slowq; /* input queue for slow devices */ +#if 1 /* ALTQ */ + /* alternate queueing related stuff */ + int if_altqtype; /* queueing scheme id */ + int if_altqflags; /* altq flags (e.g. ready, in-use) */ + void *if_altqp; /* queue state */ + int (*if_altqenqueue) + __P((struct ifnet *, struct mbuf *, struct pr_hdr *, int)); + struct mbuf *(*if_altqdequeue) + __P((struct ifnet *, int)); +#endif /* ALTQ */ }; typedef void if_init_f_t __P((void *)); --- ./netinet/in.h.orig Mon Dec 14 19:09:13 1998 +++ ./netinet/in.h Sun Mar 7 12:58:11 1999 @@ -424,6 +424,9 @@ { "fastforwarding", CTLTYPE_INT }, \ } +#if 1 /* ALTQ */ +#include +#endif #ifdef KERNEL struct ifnet; struct mbuf; /* forward declarations for Standard C */ --- ./netinet/ip.h.orig Sun Jun 7 14:00:13 1998 +++ ./netinet/ip.h Sun Mar 7 12:58:11 1999 @@ -89,6 +89,11 @@ #define IPTOS_THROUGHPUT 0x08 #define IPTOS_RELIABILITY 0x04 #define IPTOS_MINCOST 0x02 +#if 1 /* ALTQ_ECN */ +/* ECN bits proposed by Sally Floyd */ +#define IPTOS_CE 0x01 /* congestion experienced */ +#define IPTOS_ECT 0x02 /* ECN-capable transport */ +#endif /* * Definitions for IP precedence (also in ip_tos) (hopefully unused) --- ./netinet/ip_input.c.orig Tue Jan 12 13:25:00 1999 +++ ./netinet/ip_input.c Sun Mar 7 12:58:11 1999 @@ -1513,9 +1513,19 @@ break; case ENOBUFS: +#ifdef ALTQ + /* + * don't generate ICMP_SOURCEQUENCH + * (RFC1812 Requirements for IP Version 4 Routers) + */ + if (mcopy) + m_freem(mcopy); + return; +#else type = ICMP_SOURCEQUENCH; code = 0; break; +#endif } icmp_error(mcopy, type, code, dest, destifp); } --- ./netinet/ip_mroute.c.orig Mon Jan 18 03:06:57 1999 +++ ./netinet/ip_mroute.c Sun Mar 7 12:58:11 1999 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -2128,6 +2129,12 @@ static struct sockaddr_in rsvp_src = { sizeof rsvp_src, AF_INET }; register int s; struct ifnet *ifp; +#ifdef ALTQ + /* support IP_RECVIF used by rsvpd rel4.2a1 */ + struct inpcb *inp; + struct socket *so; + struct mbuf *opts; +#endif if (rsvpdebug) printf("rsvp_input: rsvp_on %d\n",rsvp_on); @@ -2180,7 +2187,11 @@ if (rsvpdebug) printf("rsvp_input: check socket\n"); +#ifdef ALTQ + if ((so = viftable[vifi].v_rsvpd) == NULL) { +#else if (viftable[vifi].v_rsvpd == NULL) { +#endif /* drop packet, since there is no specific socket for this * interface */ if (rsvpdebug) @@ -2195,12 +2206,33 @@ printf("rsvp_input: m->m_len = %d, sbspace() = %ld\n", m->m_len,sbspace(&(viftable[vifi].v_rsvpd->so_rcv))); +#ifdef ALTQ + opts = NULL; + inp = (struct inpcb *)so->so_pcb; + if (inp->inp_flags & INP_CONTROLOPTS || + inp->inp_socket->so_options & SO_TIMESTAMP) + ip_savecontrol(inp, &opts, ip, m); + if (sbappendaddr(&so->so_rcv, + (struct sockaddr *)&rsvp_src,m, opts) == 0) { + m_freem(m); + if (opts) + m_freem(opts); + if (rsvpdebug) + printf("rsvp_input: Failed to append to socket\n"); + } + else { + sorwakeup(so); + if (rsvpdebug) + printf("rsvp_input: send packet up\n"); + } +#else /* !ALTQ */ if (socket_send(viftable[vifi].v_rsvpd, m, &rsvp_src) < 0) if (rsvpdebug) printf("rsvp_input: Failed to append to socket\n"); else if (rsvpdebug) printf("rsvp_input: send packet up\n"); +#endif /* !ALTQ */ splx(s); } --- ./netinet/ip_output.c.orig Fri Feb 19 19:56:58 1999 +++ ./netinet/ip_output.c Sun Mar 7 12:58:11 1999 @@ -372,6 +372,12 @@ #endif /* IPFIREWALL_FORWARD */ } #endif /* notdef */ +#ifdef ALTQ + /* + * disable packet drop hack. + * packetdrop should be done by queueing. + */ +#else /* !ALTQ */ /* * Verify that we have any chance at all of being able to queue * the packet or packet fragments @@ -381,6 +387,7 @@ error = ENOBUFS; goto bad; } +#endif /* !ALTQ */ /* * Look for broadcast address and --- ./netinet/tcp.h.orig Mon Jul 13 13:09:51 1998 +++ ./netinet/tcp.h Sun Mar 7 12:58:11 1999 @@ -64,7 +64,13 @@ #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 +#if 1 /* ALTQ_ECN */ +#define TH_ECNECHO 0x40 /* ecn echo */ +#define TH_CWR 0x80 /* congestion window reduced */ +#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECNECHO|TH_CWR) +#else #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) +#endif u_short th_win; /* window */ u_short th_sum; /* checksum */ --- ./netinet/tcp_input.c.orig Thu Dec 3 21:23:20 1998 +++ ./netinet/tcp_input.c Sun Mar 7 12:58:11 1999 @@ -88,6 +88,19 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_RW, &tcp_delack_enabled, 0, ""); +#ifdef ALTQ_ECN +/* + * experimental ECN support based on + * draft-kksjf-ecn-03.txt and http://www-nrg.ee.lbl.gov/floyd/ECN-IP.txt + * + * NOTE: this is an experimental implementation. + * + */ +int tcp_ecn = 1; +SYSCTL_INT(_net_inet_tcp, TCPCTL_ECN, ecn, + CTLFLAG_RW, &tcp_ecn , 0, ""); +#endif /* ALTQ_ECN */ + u_long tcp_now; struct inpcbhead tcb; struct inpcbinfo tcbinfo; @@ -275,6 +288,9 @@ struct tcpopt to; /* options in this segment */ struct rmxp_tao *taop; /* pointer to our TAO cache entry */ struct rmxp_tao tao_noncached; /* in case there's no cached entry */ +#ifdef ALTQ_ECN + u_char ip_tos; +#endif #ifdef TCPDEBUG short ostate = 0; #endif @@ -297,6 +313,10 @@ ti = mtod(m, struct tcpiphdr *); } +#ifdef ALTQ_ECN + /* save ip_tos before clearing it for checksum */ + ip_tos = ((struct ip *)ti)->ip_tos; +#endif /* * Checksum extended TCP header and data. */ @@ -502,6 +522,11 @@ if (tp->t_state != TCPS_LISTEN) tcp_dooptions(tp, optp, optlen, ti, &to); +#ifdef ALTQ_ECN + /* if congestion experienced, set ECN bit in the next output. */ + if ((ip_tos & (IPTOS_ECT|IPTOS_CE)) == (IPTOS_ECT|IPTOS_CE)) + tp->t_flags |= TF_RCVD_CE; +#endif /* * Header prediction: check for the two common cases * of a uni-directional data xfer. If the packet has @@ -520,7 +545,11 @@ * be TH_NEEDSYN. */ if (tp->t_state == TCPS_ESTABLISHED && +#ifdef ALTQ_ECN + (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ECNECHO|TH_CWR|TH_ACK)) == TH_ACK && +#else (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK && +#endif ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) && ((to.to_flag & TOF_TS) == 0 || TSTMP_GEQ(to.to_tsval, tp->ts_recent)) && @@ -567,6 +596,11 @@ tcpstat.tcps_rcvackbyte += acked; sbdrop(&so->so_snd, acked); tp->snd_una = ti->ti_ack; +#ifdef ALTQ_ECN + /* sync snc_rcvr with snd_una */ + if (SEQ_GT(tp->snd_una, tp->snd_rcvr)) + tp->snd_rcvr = tp->snd_una; +#endif m_freem(m); /* @@ -702,6 +736,18 @@ tp->irs = ti->ti_seq; tcp_sendseqinit(tp); tcp_rcvseqinit(tp); +#ifdef ALTQ_ECN + tp->snd_rcvr = tp->snd_una; + /* + * if both ECNECHO and CWR flag bits are set, + * peer is ECN capable + */ + if (tcp_ecn && + (tiflags & (TH_ECNECHO|TH_CWR)) == (TH_ECNECHO|TH_CWR)) { + tp->t_flags |= TF_REQ_ECN; + tiflags &= ~(TH_ECNECHO|TH_CWR); + } +#endif /* * Initialization of the tcpcb for transaction; * set SND.WND = SEG.WND, @@ -833,6 +879,23 @@ tp->irs = ti->ti_seq; tcp_rcvseqinit(tp); +#ifdef ALTQ_ECN + tp->snd_rcvr = tp->snd_una; + /* + * peer is ECN capable + * - if ECNECHO is set but CWR is not set for SYN-ACK + * - if both ECNECHO and CWR are set for simultaneous open + */ + if (tcp_ecn) { + if ((tiflags & (TH_ACK|TH_ECNECHO|TH_CWR)) + == (TH_ACK|TH_ECNECHO) || + (tiflags & (TH_ACK|TH_ECNECHO|TH_CWR)) + == (TH_ECNECHO|TH_CWR)) { + tp->t_flags |= TF_REQ_ECN; + tiflags &= ~(TH_ECNECHO|TH_CWR); + } + } +#endif if (tiflags & TH_ACK) { /* * Our SYN was acked. If segment contains CC.ECHO @@ -1320,6 +1383,37 @@ case TCPS_LAST_ACK: case TCPS_TIME_WAIT: +#ifdef ALTQ_ECN + /* + * if we receive ECN notify and we are not already in + * receovery phase, reduce cwnd by half but don't slow- + * start. + */ + if (tcp_ecn && (tiflags & TH_ECNECHO)) { + if (SEQ_GEQ(tp->snd_una, tp->snd_rcvr)) { + u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / + tp->t_maxseg; + if (win < 2) + win = 2; + tp->snd_ssthresh = win * tp->t_maxseg; + tp->snd_cwnd = tp->snd_ssthresh; + tp->t_flags |= TF_SENDCWR; + /* + * advance snd_rcvr to snd_max not to + * reduce cwnd again until all outstanding + * packets are acked. + */ + tp->snd_rcvr = tp->snd_max; + } + } + /* + * if we receive CWR, we know that the peer has reduced + * its congestion window. stop sending ecn-echo. + */ + if (tiflags & TH_CWR) + tp->t_flags &= ~TF_RCVD_CE; +#endif /* ALTQ_ECN */ + if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { tcpstat.tcps_rcvdupack++; @@ -1352,6 +1446,17 @@ tp->t_dupacks = 0; else if (++tp->t_dupacks == tcprexmtthresh) { tcp_seq onxt = tp->snd_nxt; +#ifdef ALTQ_ECN + if (SEQ_LT(tp->snd_una, tp->snd_rcvr)) { + /* + * we are in recovery phase + * and have already halved + * cwnd within a roundtrip. + * don't reduce cwnd again. + */ + } + else { +#endif /* ALTQ_ECN */ u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg; @@ -1359,6 +1464,12 @@ if (win < 2) win = 2; tp->snd_ssthresh = win * tp->t_maxseg; +#ifdef ALTQ_ECN + tp->t_flags |= TF_SENDCWR; + /* mark we are in recovery phase */ + tp->snd_rcvr = tp->snd_max; + } +#endif tp->t_timer[TCPT_REXMT] = 0; tp->t_rtt = 0; tp->snd_nxt = ti->ti_ack; @@ -1476,6 +1587,11 @@ } sowwakeup(so); tp->snd_una = ti->ti_ack; +#ifdef ALTQ_ECN + /* sync snc_rcvr with snd_una */ + if (SEQ_GT(tp->snd_una, tp->snd_rcvr)) + tp->snd_rcvr = tp->snd_una; +#endif if (SEQ_LT(tp->snd_nxt, tp->snd_una)) tp->snd_nxt = tp->snd_una; --- ./netinet/tcp_output.c.orig Wed Jan 20 18:31:59 1999 +++ ./netinet/tcp_output.c Sun Mar 7 12:58:11 1999 @@ -542,6 +542,30 @@ panic("tcp_output"); (void)memcpy(ti, tp->t_template, sizeof (struct tcpiphdr)); +#ifdef ALTQ_ECN + if (tcp_ecn) { + /* + * if we have received congestion experienced segs, + * set ECNECHO bit. + * if this is a SYN seg, set ECNECHO and CWR for a pure SYN, + * set only ECNECHO for SYN-ACK. + */ + if (tp->t_flags & TF_RCVD_CE) + flags |= TH_ECNECHO; + if ((flags & (TH_SYN|TH_ACK)) == TH_SYN) + flags |= (TH_ECNECHO|TH_CWR); + else if ((flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) + flags |= TH_ECNECHO; + /* + * if we have reduced the congestion window, notify + * the peer by setting CWR bit. + */ + if (tp->t_flags & TF_SENDCWR) { + flags |= TH_CWR; + tp->t_flags &= ~TF_SENDCWR; + } + } +#endif /* * Fill in fields, remembering maximum advertised * window for use in delaying messages about window sizes. @@ -679,6 +703,14 @@ ((struct ip *)ti)->ip_len = m->m_pkthdr.len; ((struct ip *)ti)->ip_ttl = tp->t_inpcb->inp_ip_ttl; /* XXX */ ((struct ip *)ti)->ip_tos = tp->t_inpcb->inp_ip_tos; /* XXX */ +#ifdef ALTQ_ECN + /* + * if peer is ECN capable and this is not a pure ack seg, + * set ECN capable bit in IP header. + */ + if ((tp->t_flags & TF_REQ_ECN) && len > 0) + ((struct ip *)ti)->ip_tos |= IPTOS_ECT; +#endif #if 1 /* * See if we should do MTU discovery. We do it only if the following --- ./netinet/tcp_timer.c.orig Fri Apr 24 11:25:35 1998 +++ ./netinet/tcp_timer.c Sun Mar 7 12:58:11 1999 @@ -291,6 +291,10 @@ tp->snd_cwnd = tp->t_maxseg; tp->snd_ssthresh = win * tp->t_maxseg; tp->t_dupacks = 0; +#ifdef ALTQ_ECN + tp->t_flags |= TF_SENDCWR; + tp->snd_rcvr = tp->snd_max; +#endif } (void) tcp_output(tp); break; --- ./netinet/tcp_var.h.orig Wed Jan 20 18:32:00 1999 +++ ./netinet/tcp_var.h Sun Mar 7 12:58:11 1999 @@ -70,6 +70,11 @@ #define TF_REQ_CC 0x02000 /* have/will request CC */ #define TF_RCVD_CC 0x04000 /* a CC was received in SYN */ #define TF_SENDCCNEW 0x08000 /* send CCnew instead of CC in SYN */ +#ifdef ALTQ_ECN +#define TF_REQ_ECN 0x10000 /* peer is ECN capable */ +#define TF_RCVD_CE 0x20000 /* send ECN in next seg */ +#define TF_SENDCWR 0x40000 /* send CWR in next seg */ +#endif #define TF_MORETOCOME 0x10000 /* More data to be appended to sock */ int t_force; /* 1 if forcing out a byte */ @@ -85,6 +90,9 @@ tcp_seq iss; /* initial send sequence number */ tcp_seq irs; /* initial receive sequence number */ +#ifdef ALTQ_ECN + tcp_seq snd_rcvr; /* outstanding seg at fastrecovery */ +#endif tcp_seq rcv_nxt; /* receive next */ tcp_seq rcv_adv; /* advertised window */ u_long rcv_wnd; /* receive window */ @@ -305,7 +313,12 @@ #define TCPCTL_RECVSPACE 9 /* receive buffer space */ #define TCPCTL_KEEPINIT 10 /* receive buffer space */ #define TCPCTL_PCBLIST 11 /* list of all outstanding PCBs */ -#define TCPCTL_MAXID 12 +#ifdef ALTQ_ECN +#define TCPCTL_ECN 12 /* explicit congestion notification */ +#define TCPCTL_MAXID 13 +#else +#define TCPCTL_MAXID 13 +#endif #define TCPCTL_NAMES { \ { 0, 0 }, \ @@ -365,7 +378,9 @@ extern struct pr_usrreqs tcp_usrreqs; extern u_long tcp_sendspace; extern u_long tcp_recvspace; - +#ifdef ALTQ_ECN +extern int tcp_ecn; +#endif #endif /* KERNEL */ #endif /* _NETINET_TCP_VAR_H_ */ --- ./pci/if_de.c.orig Mon Mar 1 18:03:24 1999 +++ ./pci/if_de.c Sun Mar 7 12:58:12 1999 @@ -4243,6 +4243,11 @@ #else struct mbuf *m0; #endif +#ifdef ALTQ + struct ifnet *ifp = &sc->tulip_if; + struct mbuf *ombuf = m; + int compressed = 0; +#endif #if defined(TULIP_DEBUG) if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) { @@ -4393,6 +4398,28 @@ * entries that we can use for one packet, so we have * recopy it into one mbuf and then try again. */ +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + struct mbuf *tmp; + /* + * tulip_mbuf_compress() frees the original mbuf. + * thus, we have to remove the mbuf from the queue + * before calling it. + * we don't have to worry about space shortage + * after compressing the mbuf since the compressed + * mbuf will take only two segs. + */ + if (compressed) { + /* should not happen */ + printf("tulip_txput: compress called twice!\n"); + goto finish; + } + tmp = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + if (tmp != ombuf) + panic("tulip_txput: different mbuf dequeued!"); + compressed = 1; + } +#endif m = tulip_mbuf_compress(m); if (m == NULL) goto finish; @@ -4448,6 +4475,18 @@ * The descriptors have been filled in. Now get ready * to transmit. */ +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + if (!compressed && (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0) { + /* remove the mbuf from the queue */ + struct mbuf *tmp; + tmp = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + if (tmp != ombuf) + panic("tulip_txput: different mbuf dequeued!"); + } + } +#endif + IF_ENQUEUE(&sc->tulip_txq, m); m = NULL; @@ -4516,6 +4555,16 @@ /* * switch back to the single queueing ifstart. */ +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + /* + * de driver is too clever that it doesn't call if_start + * when it thinks it doesn't need to, but altq needs it! + */ + sc->tulip_flags |= TULIP_WANTTXSTART; + } + else +#endif sc->tulip_flags &= ~TULIP_WANTTXSTART; if (sc->tulip_txtimer == 0) sc->tulip_txtimer = TULIP_TXTIMER; @@ -4841,6 +4890,14 @@ return error; } +#ifdef ALTQ +/* + * the original dequeueing policy is dequeue-and-prepend if something + * goes wrong. when altq is used, it is changed to peek-and-dequeue. + * the modification becomes a bit complicated since tulip_txput() might + * copy and modify the mbuf passed. + */ +#endif /* * These routines gets called at device spl (from ether_output). This might * pose a problem for TULIP_USE_SOFTINTR if ether_output is called at @@ -4859,6 +4916,21 @@ if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP) tulip_txput_setup(sc); +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + struct mbuf *m, *m0; + while ((m = (*ifp->if_altqdequeue)(ifp, ALTDQ_PEEK)) != NULL) { + if ((m0 = tulip_txput(sc, m)) != NULL) { + /* txput failed */ + if (m0 != m) + /* should not happen */ + printf("tulip_if_start: bad mbuf dequeued!\n"); + break; + } + } + } + else +#endif /* ALTQ */ while (sc->tulip_if.if_snd.ifq_head != NULL) { struct mbuf *m; IF_DEQUEUE(&sc->tulip_if.if_snd, m); @@ -4881,6 +4953,21 @@ TULIP_PERFSTART(ifstart_one) tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp); +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + struct mbuf *m, *m0; + if ((sc->tulip_if.if_flags & IFF_RUNNING) + && ((m = (*ifp->if_altqdequeue)(ifp, ALTDQ_PEEK)) != NULL)) { + if ((m0 = tulip_txput(sc, m)) != NULL) { + /* txput tailed! */ + if (m0 != m) + /* should not happen */ + printf("tulip_if_start: bad mbuf dequeued!\n"); + } + } + } + else +#endif /* !ALTQ */ if ((sc->tulip_if.if_flags & IFF_RUNNING) && sc->tulip_if.if_snd.ifq_head != NULL) { struct mbuf *m; @@ -5080,6 +5167,9 @@ tulip_reset(sc); +#ifdef ALTQ + ifp->if_altqflags |= ALTQF_READY; +#endif #if defined(__bsdi__) && _BSDI_VERSION >= 199510 sc->tulip_pf = printf; TULIP_ETHER_IFATTACH(sc); --- ./pci/if_fxp.c.orig Mon Feb 15 09:47:10 1999 +++ ./pci/if_fxp.c Sun Mar 7 12:58:19 1999 @@ -570,6 +570,9 @@ ifp->if_ioctl = fxp_ioctl; ifp->if_start = fxp_start; ifp->if_watchdog = fxp_watchdog; +#ifdef ALTQ + ifp->if_altqflags |= ALTQF_READY; +#endif /* * Attach the interface. @@ -812,14 +815,28 @@ * NOTE: One TxCB is reserved to guarantee that fxp_mc_setup() can add * a NOP command when needed. */ +#ifdef ALTQ + while (sc->tx_queued < FXP_NTXCB - 1) { +#else while (ifp->if_snd.ifq_head != NULL && sc->tx_queued < FXP_NTXCB - 1) { +#endif struct mbuf *m, *mb_head; int segment; /* * Grab a packet to transmit. */ +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + mb_head = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + } + else + IF_DEQUEUE(&ifp->if_snd, mb_head); + if (mb_head == NULL) + break; +#else IF_DEQUEUE(&ifp->if_snd, mb_head); +#endif /* * Get pointer to next available tx desc. @@ -969,6 +986,11 @@ /* * Try to start more packets transmitting. */ +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) + fxp_start(ifp); + else +#endif if (ifp->if_snd.ifq_head != NULL) fxp_start(ifp); } --- ./pci/if_tl.c.orig Mon Feb 1 22:32:52 1999 +++ ./pci/if_tl.c Sun Mar 7 12:58:19 1999 @@ -1718,6 +1718,9 @@ ifp->if_watchdog = tl_watchdog; ifp->if_init = tl_init; ifp->if_mtu = ETHERMTU; +#ifdef ALTQ + ifp->if_altqflags |= ALTQF_READY; +#endif ifp->if_snd.ifq_maxlen = TL_TX_LIST_CNT - 1; callout_handle_init(&sc->tl_stat_ch); @@ -2241,6 +2244,12 @@ CMD_PUT(sc, TL_CMD_ACK | r | type); } +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + tl_start(ifp); + } + else +#endif if (ifp->if_snd.ifq_head != NULL) tl_start(ifp); @@ -2410,6 +2419,12 @@ start_tx = sc->tl_cdata.tl_tx_free; while(sc->tl_cdata.tl_tx_free != NULL) { +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + m_head = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + } + else +#endif IF_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -2439,6 +2454,13 @@ bpf_mtap(ifp, cur_tx->tl_mbuf); #endif } +#ifdef ALTQ /* fix imported from 1.16.2.5 1998/12/05 */ + /* + * If there are no packets queued, bail. + */ + if (cur_tx == NULL) + return; +#endif /* * If there are no packets queued, bail. --- ./pci/if_tx.c.orig Mon Dec 14 07:32:56 1998 +++ ./pci/if_tx.c Sun Mar 7 12:58:20 1999 @@ -227,6 +227,12 @@ epic_softc_t *sc = (epic_softc_t*)self; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + m0 = (*ifp->if_altqdequeue)(ifp, ALTDQ_FLUSH); + return; + } +#endif pci_intr_handle_t ih; const char *intrstr = NULL; struct ifnet *ifp; @@ -242,6 +248,11 @@ printf(": can't find i/o space\n"); return; } +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) + m0 = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + else +#endif if( bus_space_map(iot, iobase, iosize, 0, &sc->sc_sh)) { printf(": can't map i/o space\n"); return; @@ -492,6 +503,13 @@ #else ifp->if_flags |= IFF_LINK2; #endif +#ifdef ALTQ + if (ALTQ_IS_ON(&sc->epic_if)) { + epic_ifstart( &sc->epic_if ); + } + else + +#endif } else { printf(", 10Mbps "); #if !defined(EPIC_NOIFMEDIA) @@ -613,6 +631,12 @@ break; } #endif +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + epic_ifstart(&sc->epic_if); + } + else +#endif default: epic_stop(sc); epic_init(sc); @@ -688,6 +712,9 @@ */ static int epic_common_attach( +#ifdef ALTQ + ifp->if_altqflags |= ALTQF_READY; +#endif epic_softc_t *sc) { int i; --- ./pci/if_xl.c.orig Fri Feb 26 09:40:39 1999 +++ ./pci/if_xl.c Sun Mar 7 12:58:20 1999 @@ -1462,6 +1462,9 @@ ifp->if_init = xl_init; ifp->if_baudrate = 10000000; ifp->if_snd.ifq_maxlen = XL_TX_LIST_CNT - 1; +#ifdef ALTQ + ifp->if_altqflags |= ALTQF_READY; +#endif /* * Figure out the card type. 3c905B adapters have the @@ -2058,6 +2061,12 @@ XL_SEL_WIN(7); +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + xl_start(ifp); + } + else +#endif if (ifp->if_snd.ifq_head != NULL) { xl_start(ifp); } @@ -2228,6 +2237,12 @@ start_tx = sc->xl_cdata.xl_tx_free; while(sc->xl_cdata.xl_tx_free != NULL) { +#ifdef ALTQ + if (ALTQ_IS_ON(ifp)) { + m_head = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE); + } + else +#endif IF_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -2257,6 +2272,13 @@ bpf_mtap(ifp, cur_tx->xl_mbuf); #endif } +#ifdef ALTQ /* fix imported from 1.5.2.14 1998/12/05 */ + /* + * If there are no packets queued, bail. + */ + if (cur_tx == NULL) + return; +#endif /* * If there are no packets queued, bail. --lrZ03NoBR/3+SXJZ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=mkdiff /usr/src/sys-altq find . -name "*.orig" | awk '{ print "diff -u ",$1,$1 }' | sed -e 's/.orig$//' | awk '{ print $0, ">> xxx/FreeBSD-3.1-990306.diff" }' | sh -x --lrZ03NoBR/3+SXJZ-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message