diff -pru -x '*.o' iproute2-2.6.14-051107.orig/include/linux/pkt_sched.h iproute2-2.6.14-051107/include/linux/pkt_sched.h
--- iproute2-2.6.14-051107.orig/include/linux/pkt_sched.h	2005-08-08 13:24:41.000000000 -0700
+++ iproute2-2.6.14-051107/include/linux/pkt_sched.h	2005-12-17 17:33:23.000000000 -0800
@@ -136,6 +136,9 @@ struct tc_sfq_qopt
 	__u32		limit;		/* Maximal packets in queue */
 	unsigned	divisor;	/* Hash divisor  */
 	unsigned	flows;		/* Maximal number of flows  */
+	unsigned	flags;
+#define TC_SFQ_NOPORTS	(1)		/* ignore src/dst ports in hash */
+#define TC_SFQ_NOSRCIP	(2)		/* ignore src ip address in hash */
 };
 
 /*
diff -pru -x '*.o' iproute2-2.6.14-051107.orig/man/man8/tc-sfq.8 iproute2-2.6.14-051107/man/man8/tc-sfq.8
--- iproute2-2.6.14-051107.orig/man/man8/tc-sfq.8	2004-06-08 13:34:17.000000000 -0700
+++ iproute2-2.6.14-051107/man/man8/tc-sfq.8	2005-12-17 17:45:26.000000000 -0800
@@ -6,6 +6,11 @@ sfq \- Stochastic Fairness Queueing
 seconds
 .B quantum
 bytes
+.B [ limit
+packets
+.B ]
+.B [ noports ]
+.B [ nosrcip ]
 
 .SH DESCRIPTION
 
@@ -22,21 +27,13 @@ This may in fact have some effect in mit
 
 SFQ is work-conserving and therefore always delivers a packet if it has one available.
 .SH ALGORITHM
-On enqueueing, each packet is assigned to a hash bucket, based on
-.TP
-(i)
-Source address
-.TP
-(ii)
-Destination address
-.TP
-(iii)
-Source port
-.P
-If these are available. SFQ knows about ipv4 and ipv6 and also UDP, TCP and ESP. 
-Packets with other protocols are hashed based on the 32bits representation of their 
-destination and the socket they belong to. A flow corresponds mostly to a TCP/IP 
-connection.
+On enqueueing, each packet is assigned to a hash bucket, based on a function of
+source address, source port, destination address, and destination port.
+
+SFQ knows about ipv4 and ipv6 and also UDP, TCP and ESP.  Packets with
+other protocols are hashed based on the 32bits representation of their
+destination and the socket they belong to. A flow corresponds mostly to
+a TCP/IP connection.
 
 Each of these buckets should represent a unique flow. Because multiple flows may
 get hashed to the same bucket, the hashing algorithm is perturbed at configurable 
@@ -59,6 +56,25 @@ reordering. Advised value: 10
 quantum
 Amount of bytes a flow is allowed to dequeue during a round of the round robin process.
 Defaults to the MTU of the interface which is also the advised value and the minimum value.
+.TP
+limit
+Number of packets permitted in the SFQ at one time.  Must be at least 1, and at
+most 128.
+.TP
+noports
+If specified then the source/destination ports are not included in the hash
+function.  This will force all flows for a particular source/destination address
+pair to be placed in the same bucket.  It may be useful for defeating so-called
+"download accelerators".  These "accelerators" use HTTP range-requests in order
+to issue multiple simultaneous requests to a webserver in an attempt to get
+an unfair share of available bandwidth.  Note that this option does unfairly
+penalize hosts sharing an IP address, such as hosts behind a shared NAT.
+.TP
+nosrcip
+If specified then the source address is not considered in the hash function.
+This is useful for when you wish all outbound traffic for a particular
+destination to be considered without consideration for which source address
+generated it.
 
 .SH EXAMPLE & USAGE
 
diff -pru -x '*.o' iproute2-2.6.14-051107.orig/tc/q_sfq.c iproute2-2.6.14-051107/tc/q_sfq.c
--- iproute2-2.6.14-051107.orig/tc/q_sfq.c	2004-09-28 11:35:49.000000000 -0700
+++ iproute2-2.6.14-051107/tc/q_sfq.c	2005-12-17 17:26:52.000000000 -0800
@@ -25,7 +25,7 @@
 
 static void explain(void)
 {
-	fprintf(stderr, "Usage: ... sfq [ limit NUMBER ] [ perturb SECS ] [ quantum BYTES ]\n");
+	fprintf(stderr, "Usage: ... sfq [ limit NUMBER ] [ perturb SECS ] [ quantum BYTES ] [ noports ] [ nosrcip ]\n");
 }
 
 #define usage() return(-1)
@@ -63,6 +63,12 @@ static int sfq_parse_opt(struct qdisc_ut
 				return -1;
 			}
 			ok++;
+		} else if (strcmp(*argv, "noports") == 0) {
+			opt.flags |= TC_SFQ_NOPORTS;
+			ok++;
+		} else if (strcmp(*argv, "nosrcip") == 0) {
+			opt.flags |= TC_SFQ_NOSRCIP;
+			ok++;
 		} else if (strcmp(*argv, "help") == 0) {
 			explain();
 			return -1;
@@ -97,6 +103,10 @@ static int sfq_print_opt(struct qdisc_ut
 	}
 	if (qopt->perturb_period)
 		fprintf(f, "perturb %dsec ", qopt->perturb_period);
+	if (qopt->flags & TC_SFQ_NOPORTS)
+		fprintf(f, "noports ");
+	if (qopt->flags & TC_SFQ_NOSRCIP)
+		fprintf(f, "nosrcip ");
 	return 0;
 }
 
