Date: Sun, 7 Mar 1999 14:26:18 +0100 From: Andreas Klemm <andreas@klemm.gtn.com> 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>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
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 <net/if_sppp.h>
#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''
[-- Attachment #2 --]
--- ./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 <netnatm/natm.h>
#endif
+#if defined(ALTQ) && defined(AFMAP)
+#include <netinet/altq_afmap.h>
+#endif
+
#if !defined(sparc) && !defined(__FreeBSD__)
#include <machine/bus.h>
#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
+# <URL:http://www.FreeBSD.ORG/>
+#
+# 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 <sys/time.h>
#endif
+#if 1 /* ALTQ */
+#include <net/if_altq.h>
+#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 <netnatm/natm.h>
#endif
+#if defined(ALTQ) && defined(AFMAP)
+#include <netinet/altq_afmap.h>
+#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 <sys/param.h>
#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 <netinet/in_altq.h>
+#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 <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#include <netinet/in_pcb.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/in_var.h>
@@ -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.
[-- Attachment #3 --]
/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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990307142618.A4807>
