#! /bin/sh /usr/share/dpatch/dpatch-run ## sfq-hash.dpatch by dean gaudet ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: No description. @DPATCH@ diff -urNad iproute-20061002~/include/linux/pkt_sched.h iproute-20061002/include/linux/pkt_sched.h --- iproute-20061002~/include/linux/pkt_sched.h 2006-11-18 18:06:06.000000000 -0800 +++ iproute-20061002/include/linux/pkt_sched.h 2006-11-18 18:06:56.000000000 -0800 @@ -165,6 +165,9 @@ __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 */ }; /* @@ -543,6 +546,9 @@ __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 -urNad iproute-20061002~/man/man8/tc-sfq.8 iproute-20061002/man/man8/tc-sfq.8 --- iproute-20061002~/man/man8/tc-sfq.8 2006-11-18 18:05:20.000000000 -0800 +++ iproute-20061002/man/man8/tc-sfq.8 2006-11-18 18:06:07.000000000 -0800 @@ -6,6 +6,11 @@ seconds .B quantum bytes +.B [ limit +packets +.B ] +.B [ noports ] +.B [ nosrcip ] .SH DESCRIPTION @@ -22,21 +27,13 @@ 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 @@ 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 -urNad iproute-20061002~/tc/q_sfq.c iproute-20061002/tc/q_sfq.c --- iproute-20061002~/tc/q_sfq.c 2006-11-18 18:05:20.000000000 -0800 +++ iproute-20061002/tc/q_sfq.c 2006-11-18 18:06:07.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 @@ 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 @@ } 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; }