diff -ruNp linux-2.6.11/Makefile 2611-maxnet-router-v1.0/Makefile
--- linux-2.6.11/Makefile	2005-03-01 23:38:13.000000000 -0800
+++ 2611-maxnet-router-v1.0/Makefile	2006-07-29 20:40:29.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 11
-EXTRAVERSION =
+EXTRAVERSION =-maxnet-router
 NAME=Woozy Numbat
 
 # *DOCUMENTATION*
diff -ruNp linux-2.6.11/alternate_install_maxnet_module 2611-maxnet-router-v1.0/alternate_install_maxnet_module
--- linux-2.6.11/alternate_install_maxnet_module	1969-12-31 16:00:00.000000000 -0800
+++ 2611-maxnet-router-v1.0/alternate_install_maxnet_module	2006-07-29 20:40:29.000000000 -0700
@@ -0,0 +1,23 @@
+#! /bin/bash
+
+cd /home/2611-maxnet
+echo "Remove the current qdisc..."
+tc qdisc del dev eth0 parent 1: 
+tc qdisc del dev eth0 root  
+tc qdisc del dev eth1 parent 2:  
+tc qdisc del dev eth1 root   
+tc qdisc del dev eth2 parent 3:  
+tc qdisc del dev eth2 root   
+sleep .1s
+echo "Now the kernel module..."
+rmmod sch_maxnet
+
+install net/sched/sch_maxnet.ko /lib/modules/2.6.11/kernel/net/sched/sch_maxnet.ko
+
+tc qdisc add dev eth0 root handle 1: maxnet limit 1000000 capacity 1250000 util 1024 gamma 1250000 dt 10000 id 1 fix_p 0 msg_dt 200000
+tc qdisc add dev eth0 parent 1: tbf rate 10Mbit buffer 30000 limit 1000000
+tc qdisc add dev eth1 root handle 2: maxnet limit 1000000 capacity 1250000 util 1024 gamma 1250000 dt 10000 id 2 fix_p 0 msg_dt 200000
+tc qdisc add dev eth1 parent 2: tbf rate 10Mbit buffer 30000 limit 1000000
+tc qdisc add dev eth2 root handle 3: maxnet limit 1000000 capacity 2500000 util 1500 gamma 25000000 dt 100000 id 3 fix_p 0 msg_dt 20000
+tc qdisc add dev eth2 parent 3: tbf rate 20Mbit buffer 30000 limit 1000000
+
diff -ruNp linux-2.6.11/include/linux/pkt_sched.h 2611-maxnet-router-v1.0/include/linux/pkt_sched.h
--- linux-2.6.11/include/linux/pkt_sched.h	2005-03-01 23:38:13.000000000 -0800
+++ 2611-maxnet-router-v1.0/include/linux/pkt_sched.h	2006-07-29 20:41:09.000000000 -0700
@@ -179,6 +179,35 @@ struct tc_red_xstats
 	__u32           marked;         /* Marked packets */
 };
 
+
+/* 
+ * MAXNET section
+ * Ryan Witt <witt@caltech.edu>
+ */
+
+enum
+{
+	TCA_MAXNET_UNSPEC,
+	TCA_MAXNET_PARMS,
+	    __TCA_MAXNET_MAX,
+};
+#define TCA_MAXNET_MAX (__TCA_MAXNET_MAX - 1)
+
+struct tc_maxnet_qopt
+{
+	__u32	limit;        /* HARD maximal queue length (bytes) */
+	__u32	c;           
+	__u32	u;
+	__u32   g;
+	__u32   beta;	
+	__u32	update_dt;
+	__u32	id;
+	__u32	fix_p;
+	__u32	p_min;
+	__u32	msg_dt;
+	__u32	queue_term_delta;
+};
+
 /* GRED section */
 
 #define MAX_DPs 16
diff -ruNp linux-2.6.11/install_fixp 2611-maxnet-router-v1.0/install_fixp
--- linux-2.6.11/install_fixp	1969-12-31 16:00:00.000000000 -0800
+++ 2611-maxnet-router-v1.0/install_fixp	2006-07-29 20:40:29.000000000 -0700
@@ -0,0 +1,15 @@
+#! /bin/bash
+
+cd /home/2611-maxnet
+echo "Removing the current qdisc..."
+tc qdisc del dev eth2 parent 3:  
+tc qdisc del dev eth2 root   
+sleep .1s
+echo "Now the kernel module..."
+rmmod sch_maxnet
+
+install net/sched/sch_maxnet.ko /lib/modules/2.6.11/kernel/net/sched/sch_maxnet.ko
+
+tc qdisc add dev eth2 root handle 3: maxnet limit 1000000 capacity 2500000 util 960 gamma 12500000 dt 100000 id 3 fix_p $1 msg_dt 200000
+tc qdisc add dev eth2 parent 3: tbf rate 20Mbit buffer 30000 limit 1000000
+
diff -ruNp linux-2.6.11/install_maxnet_module 2611-maxnet-router-v1.0/install_maxnet_module
--- linux-2.6.11/install_maxnet_module	1969-12-31 16:00:00.000000000 -0800
+++ 2611-maxnet-router-v1.0/install_maxnet_module	2006-07-29 20:40:29.000000000 -0700
@@ -0,0 +1,15 @@
+#! /bin/bash
+
+cd /home/bartek/2611-maxnet-router
+echo "Remove the current qdisc..."
+tc qdisc del dev eth2 parent 3:  
+tc qdisc del dev eth2 root   
+sleep .1s
+echo "Now the kernel module..."
+rmmod sch_maxnet
+
+install net/sched/sch_maxnet.ko /lib/modules/2.6.11/kernel/net/sched/sch_maxnet.ko
+
+tc qdisc add dev eth2 root handle 3: maxnet limit 10000000 capacity 12500000 util 500 gamma 12500000 dt 1000 id 3 fix_p 0 msg_dt 200000 p_min 4400000 
+tc qdisc add dev eth2 parent 3: tbf rate 100Mbit buffer 10000000 limit 1000000
+
diff -ruNp linux-2.6.11/net/sched/Kconfig 2611-maxnet-router-v1.0/net/sched/Kconfig
--- linux-2.6.11/net/sched/Kconfig	2005-03-01 23:38:25.000000000 -0800
+++ 2611-maxnet-router-v1.0/net/sched/Kconfig	2006-07-29 20:41:24.000000000 -0700
@@ -141,6 +141,12 @@ config NET_SCH_RED
 	  To compile this code as a module, choose M here: the
 	  module will be called sch_red.
 
+config NET_SCH_MAXNET
+	tristate "MAXNET queue"
+	depends on NET_SCHED
+	help
+	  Help yourself, sucker.
+
 config NET_SCH_SFQ
 	tristate "SFQ queue"
 	depends on NET_SCHED
diff -ruNp linux-2.6.11/net/sched/Makefile 2611-maxnet-router-v1.0/net/sched/Makefile
--- linux-2.6.11/net/sched/Makefile	2005-03-01 23:38:09.000000000 -0800
+++ 2611-maxnet-router-v1.0/net/sched/Makefile	2006-07-29 20:41:24.000000000 -0700
@@ -18,6 +18,7 @@ obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o
 obj-$(CONFIG_NET_SCH_HPFQ)	+= sch_hpfq.o
 obj-$(CONFIG_NET_SCH_HFSC)	+= sch_hfsc.o
 obj-$(CONFIG_NET_SCH_RED)	+= sch_red.o
+obj-$(CONFIG_NET_SCH_MAXNET)	+= sch_maxnet.o
 obj-$(CONFIG_NET_SCH_GRED)	+= sch_gred.o
 obj-$(CONFIG_NET_SCH_INGRESS)	+= sch_ingress.o 
 obj-$(CONFIG_NET_SCH_DSMARK)	+= sch_dsmark.o
diff -ruNp linux-2.6.11/net/sched/sch_maxnet.c 2611-maxnet-router-v1.0/net/sched/sch_maxnet.c
--- linux-2.6.11/net/sched/sch_maxnet.c	1969-12-31 16:00:00.000000000 -0800
+++ 2611-maxnet-router-v1.0/net/sched/sch_maxnet.c	2006-07-29 20:41:24.000000000 -0700
@@ -0,0 +1,650 @@
+/*
+   MaxNet TCP code V1.0 29-Jul-06
+   Router code.
+
+   Copyright (C) 2006 Martin Suchara, Ryan Witt, Lachlan Andrew, Bartek Wydrowski.
+
+   All Rights Reserved.
+
+   Redistribution and use in source and binary forms, with or without modification,
+   are permitted provided that the following conditions are met:
+        -Redistributions of source code must retain the above copyright notice,
+         this list of conditions and the following disclaimer.
+        -Redistributions in binary form must reproduce the above copyright notice,
+         this list of conditions and the following disclaimer in the documentation
+         and/or other materials provided with the distribution.
+        -The name of the author may not be used to endorse or promote products
+         derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <linux/bitops.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/in.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/notifier.h>
+#include <net/ip.h>
+#include <net/route.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <net/pkt_sched.h>
+#include <net/tcp.h>		/* Needed to access tcphdr structure. */
+#include <linux/time.h>		/* Needed for dt calculation. */
+
+struct maxnet_sched_data
+{
+/* Parameters from user */
+	__u32    limit;		/* HARD maximal queue length (bytes). */
+	__u32    c;		/* Link capacity (bytes/sec). */
+	__u32	 u;		/* Target utilization, 1024 = 100%. */
+	__u32	 g;		/* Gamma (unitless, but ~= c). */
+	__u32	 beta;		/* Factor multiplying buffer occupation component of price. */
+	__u32    update_dt;	/* Price update period (usec). */
+	__u32	 id;		/* Module instance ID. */
+	__u32	 fix_p;		/* Fixed price (0: price not fixed). */
+	__u32    p_min;		/* Minimum price. */
+	__u32	 msg_dt;	/* Message print period (usec, if 0, no messages are printed). */
+	__u64	 queue_term;		// experimental, not in use
+	__u32	 queue_term_delta;	// experimental, not in use
+
+/* Variables */
+	__s64	 p_t;		/* Current price. */
+	__u64	 y;		/* Bytes received in current update interval. */
+	__u64	 y_avg;		/**/
+	__u64	 y_avg_sample;	/**/
+	__u32	 y_avg_dt;	/**/
+	__u64 	 t_avg_prev;	/**/
+	__u64	 t_avg;		/**/
+	__s64    t_prev;	/* Time of previous price update. */
+	__u64    t_msg;		/**/
+	__u64	 t_msg_prev;	/* Time of previous message print. */
+
+/* Variables/constants for price calculation */
+	__u64	 part2_1;	/* This need not be recalculated every update_dt... */
+
+/* Variables for some statistics */
+	long int ingress;
+	__u32    drops;
+
+/* Child qdisc */
+	struct   Qdisc *qdisc;
+};
+
+/* Incremental checksum subroutine. */
+static inline __u16 incr_check_16(__u16 old_check, __u16 old, __u16 new) {
+	__u32 	r1,r2,r3;
+	r1 = (__u32)(~old_check & 0xffff) + (~old & 0xffff) + new;
+	r2 = (r1&0xffff) + (r1>>16);
+	r2 = (r2&0xffff) + (r2>>16);
+	r3 = ~r2;
+	return r3;
+}
+
+/* Calculates incremental checksum given old checksum, old and new word. */
+static inline __u16 incr_check_32(__u16 old_check, __u32 old, __u32 new) {
+	old_check = ntohs(old_check);
+	old_check = incr_check_16(old_check,(__u16)(old&0xffff),(__u16)(new&0xffff));
+	old_check = incr_check_16(old_check,(__u16)(old>>16),(__u16)(new>>16));
+	return htons(old_check);
+}
+	
+static int maxnet_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+{
+	struct 	maxnet_sched_data *q = qdisc_priv(sch);
+	int	proto = ntohs(skb->protocol);
+	struct 	iphdr *iph=0;
+	struct 	tcphdr *th;
+	int 	ret;
+	__s32 	rate,rate_p;
+	__u64 	t_now, dt = 0;
+	__s32 	p_t_prev;
+	__u64 	part1_1, part2_2, part2_3;
+	struct 	timeval tsval_now;
+	int 	length, saw_maxnet_option;
+	__u32	iph_tot_len;
+	unsigned char *ptr;
+
+	/* Let's make sure the traffic we see is IP traffic */
+	if( proto == ETH_P_IP ) {
+	iph = (struct iphdr*)skb->nh.iph;
+		
+	/* Check this is IPv4 TCP traffic. */
+	if( iph->version == 4 && iph->protocol == 6 ) {
+	th = (struct tcphdr*)((char*)iph + iph->ihl*4);  /* skb->h.th is not reliable, so we calculates it ourselves. */
+
+	/* Obtain current time (later used to calculate dt). */
+	do_gettimeofday(&(tsval_now));
+	t_now = 1000000 * ((__u64)tsval_now.tv_sec)+(__u64)tsval_now.tv_usec;
+
+	/* Traffic monitoring for QuickStart. */
+	if ( q->t_avg < t_now ) {
+		q->y_avg_sample = q->y_avg;
+		q->y_avg = 0;
+		q->y_avg_dt = t_now - q->t_avg_prev;
+		q->t_avg_prev = t_now;
+		q->t_avg = t_now + q->update_dt * 500;
+	}
+	
+        /*----------------------------------------------------------*/
+        /*     A: Price calculation                                 */
+        /*----------------------------------------------------------*/	
+	if ( q->t_prev < t_now )
+		dt = t_now - q->t_prev;
+	else {
+		dt = 0;
+		q->t_prev = t_now;
+	}
+	/* Only do this if it is the right time to update the price. */
+	if( dt > q->update_dt ) {
+		/* We want to do this: p_t(t+1) = p_t(t) + 1/g*(y(t) + dt*backlog*beta - u*c*dt). */
+		/* Recall that beta has 16 bits integer and 16 bits fractional part. */
+		/* 16 >> for beta & 20 >> for dt in uS & 18 << for price format      */
+		__u64 queue_term = dt * (__u64)sch->qstats.backlog * (__u64)q->beta >> 18;
+		do_div(queue_term,q->c);
+		
+		/* Recall that price has 6 bits integer and 18 bits fractional part. */
+		part1_1 = (((__u64)q->y) << 18);
+		do_div(part1_1,q->g);
+			
+		part2_2 = dt * q->part2_1;
+		part2_3 = part2_2;
+		do_div(part2_3, 1000000);
+		p_t_prev = q->p_t;
+		q->p_t = q->p_t + ((__s64)part1_1 - (__s64)part2_3) + queue_term;
+				 
+		/* Constrain price 0xffffff >= p(t) >= p_min. */	
+		q->p_t = (q->p_t < q->p_min) ? q->p_min	: q->p_t;
+		q->p_t = (q->p_t > 0xffffff) ? 0xffffff : q->p_t;
+				
+		/* Here we are using a fixed value of price saved in fix_p. */
+		if (q->fix_p) q->p_t = q->fix_p;
+				
+		/* Print message with statistics here. This should be done infrequently. */
+		if (q->msg_dt) {
+			if (t_now > q->t_msg) {
+				__u64 msgdt;
+				q->t_msg = t_now + q->msg_dt;
+				if (q->t_msg_prev < t_now)
+					msgdt = t_now - q->t_msg_prev;
+				else
+					msgdt = 10000000;
+				q->t_msg_prev = t_now;
+					
+				printk(	"sch_maxnet id %u pLO %u pHI %u pLO_p %u pHI_p %u y %u dt %u q %Ld "
+				        "p11 %u beta %u p21 %u p22 %u p23 %u "
+					"nowLO %u nowHI %u c %u u %u g %u udt %u fix_p %u p_min %u "
+					"drops %u ingress %u msgdt %u tot_len %u q.qlen %u queue %Ld skblen %u "
+					"queue_term %Lu\n",
+					(__u32)q->id, (__u32)q->p_t, (__u32)(q->p_t>>32), (__u32)p_t_prev, p_t_prev,
+					(__u32)q->y, (__u32)dt, (__s64)sch->qstats.backlog, (__u32)part1_1,q->beta,
+					(__u32)q->part2_1, (__u32)part2_2, (__u32)part2_3, (__u32)t_now,
+					(__u32)(t_now>>32), (__u32)q->c, (__u32)q->u, (__u32)q->g, (__u32)q->update_dt,
+					(__u32)q->fix_p, (__u32)q->p_min, (__u32)q->drops, (__u32)q->ingress, (__u32)msgdt,
+				       	(__u32)ntohs(iph->tot_len), (__u32)sch->q.qlen, 
+					(__s64)sch->qstats.backlog, (__u32)skb->len,queue_term);
+				q->drops = 0;
+				q->ingress = 0;
+			}
+			else if ( q->t_msg > t_now + (q->msg_dt<<1))
+				q->t_msg = t_now;
+		}
+			
+		/* Reset variables. */
+		q->y = 0;
+		q->t_prev = t_now;
+	}
+
+        /*----------------------------------------------------------*/
+	/*     B: Packet price update                               */
+	/*----------------------------------------------------------*/
+	length = (th->doff*4) - sizeof(struct tcphdr);
+	saw_maxnet_option = 0;
+	ptr = (unsigned char *)(th + 1);
+
+	while(length > 0) {
+		int opcode=*ptr++;
+		int opsize;
+
+		switch (opcode) {
+		case TCPOPT_EOL:        /* We have nothing to do in this case. */
+			break;
+		case TCPOPT_NOP:	/* Reference: RFC 793 section 3.1. */
+			length--;
+			continue;
+		default:
+			opsize=*ptr++;
+			if (opsize < 2) { /* "Silly options." */
+				goto enqueue;
+			}
+			if (opsize > length) {	
+				break;
+			}
+				
+			switch(opcode) {
+			#define TCPOPT_MAXNET_PRICE 42
+			case TCPOPT_MAXNET_PRICE: {
+				__u32 old_value,new_value;
+//				static __u32 pkt_cnt=0;
+//				struct iphdr *iph=skb->nh.iph;
+				
+				/* Only touch the second value. */
+				ptr += 2;	
+				old_value = ntohl(*(__u32 *)(ptr)); 
+						
+			        /*----------------------------------------------------------*/
+			        /*     B.1: QuickStart algorithm                            */
+			        /*----------------------------------------------------------*/	
+				if ( old_value & 0x00800000 ) {
+					__u64 traffic;
+					__u32 target_rate;
+					__u32 e;
+					rate_p = old_value & 0x007fffff;
+					traffic=((__u64)q->y_avg_sample)*1000000;
+					if (!q->y_avg_dt)
+						q->y_avg_dt=1;
+					do_div(traffic,q->y_avg_dt);
+					e = q->u + (1024 - q->u)/4;
+					target_rate = e*(q->c>>10);
+					if (target_rate > traffic)
+						rate = ((__s32)target_rate-(__s32)traffic);
+					else
+						rate = 0;
+					if ( rate < (__s32)(q->c>>7) )
+						rate=q->c>>7;
+					/* Rate is in words/sec. */
+					rate>>=8;
+					if (rate > 0x007fffff)
+						rate=0x007fffff;
+					if (rate_p<rate)
+						rate=rate_p;
+					rate |= 1<<23; 
+				
+					printk("sch_maxnet_quickstart id %u c %u y_avg_dt %u y_avg_sample %u traffic %u target_rate %u rate %u rate_p %u\n", (__u32)q->id, (__u32)q->c, (__u32)q->y_avg_dt, (__u32)q->y_avg_sample, (__u32)traffic, (__u32)target_rate, (__u32)rate,(__u32)rate_p);
+							
+					/* Put rate in the packet. */
+					new_value = (old_value & 0xff000000) | (0x00ffffff & rate);
+					*(__u32 *)(ptr) = htonl(new_value);	
+					/* Recalculate the checksum. */
+					th->check=incr_check_32(th->check, old_value, new_value);
+				}
+				/*----------------------------------------------------------*/
+				/*     B.2: Insert price in the packet                      */
+				/*----------------------------------------------------------*/
+				else { 
+					__u32 link_price = q->p_t + q->queue_term;
+					if ( link_price > 0x00ffffff )
+						link_price = 0x00ffffff;
+					if ( link_price > (old_value & 0x00ffffff) ) {
+						new_value = (old_value & 0xff000000) | (0x00ffffff & (link_price));
+						*(__u32 *)(ptr) = htonl(new_value);	
+						/* Recalculate the checksum. */
+						th->check = incr_check_32(th->check, old_value, new_value);
+					}
+				}
+				saw_maxnet_option = 1;
+				break;
+			}
+			default:
+				break;
+			};
+			ptr += opsize - 2;
+			length -= opsize;
+		};
+
+	}
+	} /* end if IPv4 TCP traffic. */	
+	} /* end if IP protocol traffic. */
+	
+/*----------------------------------------------------------*/
+/*     C: Enqueue packet                                    */
+/*----------------------------------------------------------*/
+enqueue:
+	/* No actual maxnet queue, just enqueue things in our child. */
+	if ((ret = q->qdisc->enqueue(skb, q->qdisc)) == NET_XMIT_SUCCESS) {
+
+		sch->qstats.backlog += skb->len;
+		sch->bstats.bytes += skb->len;
+		sch->bstats.packets++;
+	
+		if(iph) {
+			if (!q->t_avg_prev) {			
+				do_gettimeofday(&(tsval_now));
+				q->t_avg_prev = 1000000 * ((__u64)tsval_now.tv_sec)+(__u64)tsval_now.tv_usec;
+			}
+			/* Update our count of bytes enqueued. */
+			iph_tot_len = (__u32) ntohs(iph->tot_len);
+			q->y       += iph_tot_len; 
+			q->y_avg   += iph_tot_len;
+			q->ingress += iph_tot_len;
+		}
+
+		return NET_XMIT_SUCCESS;
+	}
+
+	sch->qstats.drops++;
+	q->drops++;
+	return ret;
+}
+
+static int maxnet_requeue (struct sk_buff *skb, struct Qdisc* sch)
+{
+	struct maxnet_sched_data *q = qdisc_priv(sch);
+	int ret;
+//	struct iphdr *iph=0;
+	
+	if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == NET_XMIT_SUCCESS) {
+		sch->qstats.backlog += skb->len;
+		sch->qstats.requeues++;
+		
+		return 0;
+	}
+	sch->qstats.drops++;
+	q->drops++;
+	return NET_XMIT_DROP;
+}
+
+static struct sk_buff * maxnet_dequeue(struct Qdisc* sch)
+{
+	struct sk_buff *skb;
+//	struct iphdr *iph=0;
+	struct maxnet_sched_data *q = qdisc_priv(sch);
+
+	/* Dequeue. */
+	skb = q->qdisc->dequeue(q->qdisc);
+		
+	/* Statistics. */
+	if (skb) {
+		sch->qstats.backlog -= skb->len;
+		
+	}
+
+	return skb;
+}
+
+static unsigned int maxnet_drop(struct Qdisc* sch)
+{
+	struct maxnet_sched_data *q = qdisc_priv(sch);
+	unsigned int len;
+
+	len = q->qdisc->ops->drop(q->qdisc);
+	if (len) {
+		sch->qstats.backlog -= len;
+		sch->qstats.drops++;
+		q->drops++;
+		return len;
+	}
+	return 0;
+}
+
+static void maxnet_reset(struct Qdisc* sch)
+{
+	struct maxnet_sched_data *q = qdisc_priv(sch);
+
+	q->y 		= 0;
+	q->y_avg 	= 0;
+	q->y_avg_sample	= 0;
+	q->y_avg_dt	= 0;
+	q->t_avg	= 0;
+	q->p_t		= 0;
+	sch->qstats.backlog = 0;
+	q->t_msg_prev	= 0;
+	q->ingress	= 0;
+	q->queue_term	= 0;
+
+	qdisc_reset(q->qdisc);
+}
+
+static int maxnet_change(struct Qdisc *sch, struct rtattr *opt)
+{
+	struct maxnet_sched_data *q = qdisc_priv(sch);
+	struct rtattr *tb[TCA_MAXNET_PARMS]; /* Has to be large enough to hold all rtattrs in the message */
+	struct tc_maxnet_qopt *qopt;
+
+	/* Parse our options from the rtnetlink packet */
+	if(rtattr_parse(tb, TCA_MAXNET_PARMS, RTA_DATA(opt), RTA_PAYLOAD(opt))	/* Parse into tb array. */
+	   || tb[TCA_MAXNET_PARMS-1] == NULL		           	/* Make sure we parsed out SOMETHING. */
+	   || RTA_PAYLOAD(tb[TCA_MAXNET_PARMS-1]) < sizeof(*qopt)) 	/* Is data same length as our control structure? */
+		return -EINVAL;
+	
+	qopt = RTA_DATA(tb[TCA_MAXNET_PARMS-1]);   /* Lay the old data onto the new structure. */
+
+	/* Get parameters && perform conversion from human readable format to what we need! */
+	q->p_min	= qopt->p_min;
+	q->limit	= qopt->limit;
+	q->c		= qopt->c;
+       	q->u		= qopt->u;
+	q->g		= qopt->g;	
+	q->beta		= qopt->beta;
+	q->update_dt	= qopt->update_dt;
+	q->id		= qopt->id;
+	q->fix_p	= qopt->fix_p;
+	q->msg_dt	= qopt->msg_dt;
+	q->queue_term_delta = qopt->queue_term_delta;
+
+	/* Initialize Variables */
+	q->y 		= 0;
+	q->y_avg 	= 0;
+	q->y_avg_sample	= 0;
+	q->y_avg_dt 	= 0;
+	q->t_avg	= 0;
+	q->p_t		= 0;
+	q->ingress	= 0;
+	q->queue_term	= 0;
+
+	/* Initialize part2_1*/
+	q->part2_1 = ((__u64)q->c)<<18;		
+	do_div(q->part2_1,q->g);			
+	q->part2_1 = (q->part2_1*q->u)>>10;	
+	
+	/* Print information about the qdisc when it is loaded. */
+	printk("MAXNET: qdisc was loaded with limit %u c %u u %u g %u beta %u update_dt %u fix_p %u p_min %u queue_term_delta %u\n",
+		   q->limit, q->c, q->u, q->g, q->beta, q->update_dt, q->fix_p, q->p_min, q->queue_term_delta );
+
+	return 0;
+}
+
+static int maxnet_init(struct Qdisc *sch, struct rtattr *opt)
+{
+	struct maxnet_sched_data *q = qdisc_priv(sch);
+	struct Qdisc *child;
+	
+	if (opt == NULL)
+		return -EINVAL;
+
+	/* Start us out with a normal pfifo qdisc. */
+	sch_tree_lock(sch);	/* Needed here? */
+	if((child = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)) == NULL) {
+		q->qdisc = &noop_qdisc;
+		printk("MAXNET: could not create default child qdisc! No qdisc loaded!\n");
+	}	
+	else 
+		q->qdisc = child;
+	sch_tree_unlock(sch);
+
+	return maxnet_change(sch, opt);
+}
+
+static void maxnet_destroy(struct Qdisc *sch)
+{
+	struct maxnet_sched_data *q = qdisc_priv(sch);
+	qdisc_destroy(q->qdisc);
+}
+
+static int maxnet_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+	struct maxnet_sched_data *q = qdisc_priv(sch);
+	unsigned char *b = skb->tail;
+	struct rtattr *rta;
+	struct tc_maxnet_qopt opt;
+
+	printk("MAXNET: maxnet_dump was called.\n");
+
+	rta = (struct rtattr*)b;
+	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	opt.limit      = q->limit;
+	opt.u	       = q->u;
+	opt.c	       = q->c;
+	opt.g	       = q->g;
+	opt.beta       = q->beta;
+	opt.update_dt  = q->update_dt;
+	opt.id	       = q->id;
+	opt.fix_p      = q->fix_p;
+	opt.msg_dt     = q->msg_dt;
+	opt.p_min      = q->p_min;
+	opt.queue_term_delta = q->queue_term_delta;
+	
+	RTA_PUT(skb, TCA_MAXNET_PARMS, sizeof(opt), &opt);
+	rta->rta_len = skb->tail - b;
+
+	return skb->len;
+
+rtattr_failure:
+	skb_trim(skb, b - skb->data);
+	return -1;
+}
+
+static int maxnet_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm)
+{
+	struct maxnet_sched_data *q = qdisc_priv(sch);
+
+	if (cl != 1) 	/* only one class */
+		return -ENOENT;
+
+	tcm->tcm_handle |= TC_H_MIN(1);
+	tcm->tcm_info = q->qdisc->handle;
+
+	return 0;
+}
+
+static int maxnet_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old)
+{
+	struct maxnet_sched_data *q = qdisc_priv(sch);
+
+	/* For blank qdisc we want to create a pfifo. */
+	if (new == NULL) {
+		if ((new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)) == NULL)
+			return -ENOBUFS;
+		else {
+			new = &noop_qdisc;
+			printk("MAXNET: no qdisc created!\n");
+		}
+	}
+
+	sch_tree_lock(sch);
+	*old = xchg(&q->qdisc, new);
+	qdisc_reset(*old);
+	sch_tree_unlock(sch);
+
+	return 0;
+}
+
+static struct Qdisc *maxnet_leaf(struct Qdisc *sch, unsigned long arg)
+{
+	struct maxnet_sched_data *q = qdisc_priv(sch);
+	return q->qdisc;
+}
+
+static unsigned long maxnet_get(struct Qdisc *sch, u32 classid)
+{
+	return 1;
+}
+
+static void maxnet_put(struct Qdisc *sch, unsigned long arg)
+{
+    return;
+}
+
+static int maxnet_change_class(struct Qdisc *sch, u32 classid, u32 parentid, 
+			    struct rtattr **tca, unsigned long *arg)
+{
+	return -ENOSYS;
+}
+
+static int maxnet_delete(struct Qdisc *sch, unsigned long arg)
+{
+	return -ENOSYS;
+}
+
+static void maxnet_walk(struct Qdisc *sch, struct qdisc_walker *walker)
+{
+	if (!walker->stop) {
+		if (walker->count >= walker->skip)
+			if (walker->fn(sch, 1, walker) < 0) {
+				walker->stop = 1;
+				return;
+			}
+		walker->count++;
+	}
+    return;
+}
+
+static struct tcf_proto **maxnet_find_tcf(struct Qdisc *sch, unsigned long cl)
+{
+	return NULL;
+}
+
+static struct Qdisc_class_ops maxnet_class_ops = {
+	.graft		=	maxnet_graft,
+	.leaf		=	maxnet_leaf,
+	.get		=	maxnet_get,
+	.put		=	maxnet_put,
+	.change		=	maxnet_change_class,
+	.delete		=	maxnet_delete,
+	.walk		=	maxnet_walk,
+	.tcf_chain	=	maxnet_find_tcf,
+	.dump		=	maxnet_dump_class,
+};
+
+struct Qdisc_ops maxnet_qdisc_ops = {
+	.next		=	NULL,
+	.id		=	"maxnet",
+	.cl_ops		=	&maxnet_class_ops,
+	.priv_size	=	sizeof(struct maxnet_sched_data),
+	.enqueue	=	maxnet_enqueue,
+	.dequeue	=	maxnet_dequeue,
+	.requeue	=	maxnet_requeue,
+	.drop		=	maxnet_drop,
+	.init		=	maxnet_init,
+	.reset		=	maxnet_reset,
+	.destroy	=	maxnet_destroy,
+	.change		= 	maxnet_change,
+	.dump		= 	maxnet_dump,
+	.owner		= 	THIS_MODULE,
+};
+
+
+static int __init maxnet_module_init(void)
+{
+	return register_qdisc(&maxnet_qdisc_ops);
+}
+static void __exit maxnet_module_exit(void)
+{
+	unregister_qdisc(&maxnet_qdisc_ops);
+}
+module_init(maxnet_module_init)
+module_exit(maxnet_module_exit)
+EXPORT_SYMBOL(maxnet_qdisc_ops);
diff -ruNp linux-2.6.11/rebuild_and_install_maxnet_module 2611-maxnet-router-v1.0/rebuild_and_install_maxnet_module
--- linux-2.6.11/rebuild_and_install_maxnet_module	1969-12-31 16:00:00.000000000 -0800
+++ 2611-maxnet-router-v1.0/rebuild_and_install_maxnet_module	2006-07-29 20:40:29.000000000 -0700
@@ -0,0 +1,11 @@
+#! /bin/bash
+
+source /etc/bashrc
+source ~/.bashrc
+
+echo "Rebuild the module..."
+make modules
+
+RV=$?
+ZR=0
+if [ "$RV" -eq "$ZR" ]; then ./install_maxnet_module; fi

