User Tools

Site Tools


unix:gateway

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Last revision Both sides next revision
unix:gateway [2013/10/13 12:32]
robm [IP Forwarding and NAT]
unix:gateway [2013/10/13 12:38]
robm [Traffic Shaping] Updating wondershaper script, linking to github
Line 293: Line 293:
 I used to use Ubuntu's stock ''wondershaper'' package, but now use my own adaptation of it that does *not* shape or police LAN traffic. This allows my gateway PC to double as a file server: internet traffic is shaped and policed to match my ADSL line speeds, while file-server (local) traffic runs at gigabit speeds. I used to use Ubuntu's stock ''wondershaper'' package, but now use my own adaptation of it that does *not* shape or police LAN traffic. This allows my gateway PC to double as a file server: internet traffic is shaped and policed to match my ADSL line speeds, while file-server (local) traffic runs at gigabit speeds.
  
-<code sh+See my ADSL project on GitHub: https://github.com/meermanr/adsl 
-#!/bin/sh+ 
 +<code bash wondershaper
 +#!/bin/bash -e
  
 # Adapted from http://lartc.org/wondershaper/ # Adapted from http://lartc.org/wondershaper/
  
 +DEV=$1
 DOWNLINK=$2 DOWNLINK=$2
 UPLINK=$3 UPLINK=$3
-DEV=$1+ 
 +# The following fudge factors allow you to express the usable % of your link.   
 +
 +# Experimentation has shown that ~75% of the author's ADSL downlink can be used  
 +# before upstream congestion starts to affect round-trip times. In other words,  
 +# by throttling our download speeds we can ensure that our ISP does not queue  
 +# any packs on our behalf, giving us full control over congestion. 
 +DOWNFACTOR='74/100' 
 +UPFACTOR='75/100'
  
 if [ "x$DEV" = "x" ] if [ "x$DEV" = "x" ]
 then then
-    echo "Usage: $0 (DEV) [ 'clear' | (DOWNLINK UPLINK) ]"+    echo "Usage: $0 (DEV) [ 'clear' | (DOWNLINK kbit/s) (UPLINK kbit/s) ]"
     exit 0     exit 0
 fi fi
Line 311: Line 322:
 if [ "x$DOWNLINK" = "x" ] if [ "x$DOWNLINK" = "x" ]
 then then
-    tc -s qdisc ls dev $DEV+    #echo "--------------------------------------------------------------------------------" 
 +    #iptables -nvL -t mangle 
 +    #echo "--------------------------------------------------------------------------------" 
 +    tc -s filter ls dev $DEV 
 +    echo "--------------------------------------------------------------------------------" 
 +    #tc -s qdisc ls dev $DEV 
 +    #echo "--------------------------------------------------------------------------------"
     tc -s class ls dev $DEV     tc -s class ls dev $DEV
     exit 0     exit 0
Line 319: Line 336:
 tc qdisc del dev $DEV root    2> /dev/null > /dev/null || true tc qdisc del dev $DEV root    2> /dev/null > /dev/null || true
 tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null || true tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null || true
 +
 +# Flush and delete all mangle rules
 +iptables -F 
 +iptables -X 
 +iptables -t mangle -F 
 +iptables -t mangle -X 
  
 if [ "x$DOWNLINK" = "xclear" ] if [ "x$DOWNLINK" = "xclear" ]
Line 326: Line 349:
 fi fi
  
-############################################################################### +trap "$0 $1 clear" ERR
-# UPLINK+
  
-Set root Queuing Discipline (qdisc) to Class Based Queuing (cbq) +Calculations 
-tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 1000mbit +
 +# Target latency is < 50ms. This means max burst length should be limited to  
 +1/20th the queue's rate.
  
-# Traffic is either headed to the gateway (i.e. internet traffic) or not.   
-# Internet uplink is scarse, so aggresively shape it. LAN uplink is plentiful,  
-# do not restrict it. 
  
 +LOCALIP=$(ifconfig eth0 | sed -ne 's/^.*inet addr:\([0-9.]\+\).*/\1/p')
 +
 +# =============================================================================
 +# Queues and Classes
 # ============================================================================= # =============================================================================
-INTERNET GATEWAYShape to $UPLINK speed, this prevents huge queues in the  +1ROOT 
-DSL modem that cause massive latency +# |-- 1:ff LOCAL_TRAFFIC (to/from this host itself) 
-tc class add dev $DEV parent 1: classid 1:1 cbq rate ${UPLINK}kbit \ +| `-- ff: (sfq) 
-    allot 1500 prio 5 bounded isolated+# |-- 1:1 INTERNET->LAN (downlink) 
 +# | `-- 10(red) Drop traffic as link approaches congestion 
 +# `-- 1:2 LAN->INTERNET (uplink) 
 +#   |-- 1:21: High priority 
 +#   | `-- 21: (sfq) 
 +#   |-- 1:22: Medium priority 
 +#   | `-- 22: (sfq) 
 +#   `-- 1:23: Low priority 
 +#     `-- 23: (sfq) Low priority
  
-High priority internet traffic +ROOT 
-tc class add dev $DEV parent 1:1 classid 1:10 cbq rate ${UPLINK}kbit \ +tc qdisc add dev $DEV root handle 1: htb
-   allot 1600 prio 1 avpkt 1000 +
-# .. and its actual queue that holds the packets +
-tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10+
  
 +    # LOCAL TRAFFIC
 +    tc class add dev $DEV parent 1: classid 1:ff htb \
 +        rate 100mbit \
 +        burst $((100/20))mbit \
 +        cburst $((100/20))mbit \
 +        prio 1
  
-# Default priority internet traffic, bulk transfers. +        # .. and its actual queue that holds the packets 
-tc class add dev $DEV parent 1:1 classid 1:20 cbq rate $((9*$UPLINK/10))kbit \ + tc qdisc add dev $DEV parent 1:ff handle ff: sfq perturb 10
-   allot 1600 prio 2 avpkt 1000 +
-# .. and its actual queue that holds the packets +
-tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10+
  
-Low priority traffic. +    INTERNET->LAN (downlink) 
-tc class add dev $DEV parent 1:classid 1:30 cbq rate $((8*$UPLINK/10))kbit \ +    tc class add dev $DEV parent 1: classid 1:1 htb \ 
-   allot 1600 prio 2 avpkt 1000 +        rate $(($DOWNLINK*$DOWNFACTOR))kbit \ 
-# .. and its actual queue that holds the packets +        ceil $(($DOWNLINK*$DOWNFACTOR))kbit \ 
-tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10+        burst $(($DOWNLINK*$DOWNFACTOR/20))kbit \ 
 +        cburst $(($DOWNLINK*$DOWNFACTOR/20))kbit \ 
 +        prio 10
  
-============================================================================= +        .. and its actual queue that holds the packets 
-LAN +        Note: All values are in BYTES. It doesn't seem to accept "kbit" 
-tc class add dev $DEV parent 1: classid 1:40 cbq rate 1000mbit +        # 
-    allot 1500 prio 5 borrow sharing +        # The burst calculation needs to be increased by one so as to avoid an  
-tc qdisc add dev $DEV parent 1:40 handle 40: sfq perturb 10+        # internal assert in the qdisc (seems our target and their min  
 +        # acceptable burst are one and the same) 
 +        tc qdisc add dev $DEV parent 1:1 handle 10red 
 +            limit $(($DOWNLINK*$DOWNFACTOR*1000/8)) \ 
 +            avpkt 1500 \ 
 +            burst $((($DOWNLINK*1000/8/20/1500)+1)) \ 
 +            min   $(($DOWNLINK*1000/8/20)) \ 
 +            max   $(($DOWNLINK*$DOWNFACTOR*1000/8)) \ 
 +            ecn \ 
 +            probability 1
  
-============================================================================= +    LAN->INTERNET (uplink) 
-# Filters+    tc class add dev $DEV parent 1: classid 1:2 htb \ 
 +        rate $(($UPLINK*$UPFACTOR))kbit \ 
 +        ceil $(($UPLINK*$UPFACTOR))kbit \ 
 +        burst $(($UPLINK/20))kbit \ 
 +        cburst $(($UPLINK/20))kbit \ 
 +        prio 20
  
-LAN traffic ----------------------------------------------------------------- +        High priority 
-tc filter add dev $DEV parent 1:0 protocol ip prio u32 +        tc class add dev $DEV parent 1:2 classid 1:21 htb 
-    match ip dst 192.168.0.0/16 flowid 1:40 +            rate $(($UPLINK*$UPFACTOR*4/6))kbit \ 
-tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 +            ceil $(($UPLINK*$UPFACTOR))kbit 
-    match ip dst 10.0.0.0/8 flowid 1:40 +            prio 0
-tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ +
-    match ip dst 172.16.0.0/12 flowid 1:40+
  
-Internet traffic ------------------------------------------------------------+        Medium priority 
 +        tc class add dev $DEV parent 1:2 classid 1:22 htb \ 
 +            rate $(($UPLINK*$UPFACTOR*2/6))kbit \ 
 +            ceil $(($UPLINK*$UPFACTOR))kbit \ 
 +            prio 1
  
-TOS Minimum Delay (ssh, NOT scp) in 1:10: +        Low priority 
-tc filter add dev $DEV parent 1:0 protocol ip prio 10 u32 +        tc class add dev $DEV parent 1:2 classid 1:23 htb 
-      match ip tos 0x10 0xff  flowid 1:10+            rate $(($UPLINK*$UPFACTOR*1/6))kbit \ 
 +            prio 2
  
-ICMP (ip protocol 1) in the interactive class 1:10 so we  +        .. and their actual queues that hold the packets 
-# can do measurements & impress our friends+        for ID in 21 22 23 
-tc filter add dev $DEV parent 1:0 protocol ip prio 11 u32 +        do 
-        match ip protocol 0xff flowid 1:10+            tc qdisc add dev $DEV parent 1:$ID handle $ID: sfq 
 +            ## tc qdisc add dev $DEV parent 1:$ID handle $ID: red 
 +            ##     limit $(($UPLINK*$UPFACTOR*1000/8)) \ 
 +            ##     avpkt 1500 \ 
 +            ##     burst $((($UPLINK*1000/8/20/1500)+1)) \ 
 +            ##     min   $(($UPLINK*1000/8/20)) \ 
 +            ##     max   $(($UPLINK*$UPFACTOR*1000/8)) \ 
 +            ##     ecn \ 
 +            ##     probability 1 
 +        done
  
-# pablo.iranzo@uv.es provided a patch for the MLDonkey system 
-# The MLDonkey uses small UDP packets for source propogation 
-# which floods the wondershaper out. 
-tc filter add dev $DEV parent 1:0 protocol ip prio 10 u32 \ 
-   match ip protocol 17 0xff \ 
-   match ip sport 4666 0xffff \ 
-   flowid 1:30  
  
-prioritize small packets (<64 bytes)+============================================================================= 
 +# Filters 
 +# =============================================================================
  
-tc filter add dev $DEV parent 1: protocol ip prio 12 u32 \ +# ----------------------------------------------------------------------------- 
-   match ip protocol 6 0xff \ +# LOCAL TRAFFIC 
-   match u8 0x05 0x0f at 0 \ +# Mark traffic generated by this host itself (INPUT + OUTPUT, but not FORWARD) 
-   match u16 0x0000 0xffc0 at 2 \ +iptables -t mangle -A INPUT  -p all -i $DEV -j MARK --set-mark 0xff 
-   flowid 1:10+iptables -t mangle -A OUTPUT -p all -o $DEV -j MARK --set-mark 0xff
  
 +# ("fw" means the handle refers to a MARK, rather than a qdisc)
 +tc filter add dev $DEV parent 1: protocol ip prio 1 handle 0xff fw classid 1:ff
  
-#for a in $NOPRIOPORTDST +----------------------------------------------------------------------------- 
-#do +INTERNET->LAN (downlink)
-# tc filter add dev $DEV parent 1: protocol ip prio 14 u32 \ +
-#    match ip dport $a 0xffff flowid 1:30 +
-#done+
 # #
-#for a in $NOPRIOPORTSRC +Note: We assume that LAN->LAN traffic is *not* forwarded through this host,  
-#do +and so we need only check the destination of a given packet. We've already  
- tc filter add dev $DEV parent 1: protocol ip prio 15 u32 \ +taken care of this host's own traffic above. 
-#    match ip sport $a 0xffff flowid 1:30 + 
-#done+iptables -t mangle -N DOWNLINK 
 +iptables -t mangle -A DOWNLINK -p all -j MARK --set-mark 0x1 
 +tc filter add dev $DEV parent 1: protocol ip prio 2 handle 0x1 fw classid 1:1 
 + 
 +for SUBNET in 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12  
 +do 
 +    iptables -t mangle -A PREROUTING -p all -i $DEV ! -s $SUBNET -d $SUBNET -j DOWNLINK 
 +done 
 + 
 + 
 +# ----------------------------------------------------------------------------- 
 +# LAN->INTERNET (uplink)
 # #
-#for a in $NOPRIOHOSTSRC +Note: Assumes that all downlink and private traffic have already been  
-#do +classified, so no source checks are performed. 
-# tc filter add dev $DEV parent 1: protocol ip prio 16 u32 \ + 
-#    match ip src $a flowid 1:30 +iptables -t mangle -N UPLINK 
-#done +iptables -t mangle -A UPLINK -p all -j MARK --set-mark 0x22     Default to medium priority 
-+#for CHAIN in PREROUTING INPUT FORWARD OUTPUT POSTROUTING DOWNLINK UPLINK
-#for in $NOPRIOHOSTDST+
 #do #do
- tc filter add dev $DEV parent 1: protocol ip prio 17 u32 \ +   iptables -t mangle -I $CHAIN -p tcp --sport 12345 -j MARK --set-mark 0/0 
-#    match ip dst $a flowid 1:30+#    iptables -t mangle -I $CHAIN -p tcp --dport 12345 -j MARK --set-mark 0/0
 #done #done
  
-# Internet traffic catch-all: bulk. +for SUBNET in 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12  
-tc filter add dev $DEV parent 1: protocol ip prio 18 u32 \ +do 
-   match ip dst 0.0.0.0/flowid 1:20+    iptables -t mangle -A PREROUTING -p all -i $DEV -s $SUBNET ! -d $SUBNET -j UPLINK 
 +done
  
 +##
 +## HIGH PRIORITY ##
 +##
  
-############################################################################### +TOS Minimum Delay (ssh, NOT scp) 
-# DOWNLINK +tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ 
-+    match ip tos 0x10 0xff \ 
-# Limit downloads to slightly less than the maximum achievable speed. This  +    flowid 1:21
-# prevents a queues building up in the ISP (which is typically a huge FIFO),  +
-# and so reduces round-trip time; effectively reducing latency.+
  
-Ingress policer +ICMP (ip protocol 1) in the interactive class so we can do measurements &  
-(FYI: The term "shaping" only applied to egress traffic, "policing" is the  +impress our friends: 
-ingress equivalent)+tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ 
 +    match ip protocol 1 0xff \ 
 +    flowid 1:21
  
-tc qdisc add dev $DEV handle ffffingress+# Prioritize small packets (<64 bytes) 
 +tc filter add dev $DEV parent 1protocol ip prio 20 u32 \ 
 +    match ip protocol 6 0xff \ 
 +    match u8 0x05 0x0f at 0 \ 
 +    match u16 0x0000 0xffc0 at 2 \ 
 +    flowid 1:21
  
-LAN traffic is exempt from policing +Prioritise ACK packets (but only if they are small) 
-tc filter add dev $DEV parent ffff: protocol ip prio 40 u32 \ +# IP protocol 6, 
-    match ip src 192.168.0.0/16 \ +# IP header length 0x5(32 bit words), 
-    police pass \ +# IP Total length 0x34 (ACK + 12 bytes of TCP options) 
-    flowid :1 +# TCP ack set (bit 5, offset 33) 
-tc filter add dev $DEV parent ffff: protocol ip prio 40 u32 \ +tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ 
-    match ip src 10.0.0.0/+    match ip protocol 6 0xff 
-    police pass +    match u8 0x05 0x0f at 0 
-    flowid :1 +    match u16 0x0000 0xffc0 at 2 
-tc filter add dev $DEV parent ffff: protocol ip prio 40 u32 +    match u8 0x10 0xff at 33 
-    match ip src 172.16.0.0/12 \ +    flowid 1:21
-    police pass +
-    flowid :1+
  
-Internet traffic that arrives too fast should be discarded +Traffic headed to robmeerman.co.uk (typically SSH proxying to else where) 
-tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 \ +tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ 
-    match ip src 0.0.0.0/0 \ +    match ip dst 85.119.82.218/32 
-    police rate ${DOWNLINK}kbit burst 10k drop +    flowid 1:21
-    flowid :+
-</code>+
  
 +# Traffic originating from the Xbox should be treated as urgent
 +tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \
 +    match ip src 192.168.1.2/32 \
 +    flowid 1:21
 +
 +
 +##
 +## LOW PRIORITY ##
 +##
 +
 +# # WiiU, while it's downloading purchases
 +# tc filter add dev $DEV parent 1: protocol ip prio 30 u32 \
 +#     match ip src 192.168.1.5/32 \
 +#     flowid 1:23
 +
 +# TOS High Throughput
 +tc filter add dev $DEV parent 1: protocol ip prio 30 u32 \
 +    match ip tos 0x8 0xff \
 +    flowid 1:23
 +
 +# If no other filter has classified the packet, then use FW markers (set by 
 +# iptables -j MARK). All UPLINK packets are marked as 0x22 by default (see 
 +# iptables command earlier)
 +tc filter add dev $DEV parent 1: protocol ip prio 40 handle 0x21 fw classid 1:21 # High priority
 +tc filter add dev $DEV parent 1: protocol ip prio 40 handle 0x22 fw classid 1:22 # Medium priority
 +tc filter add dev $DEV parent 1: protocol ip prio 40 handle 0x23 fw classid 1:23 # Low priority
 +
 +
 +# Reset counters, so that packet counts are in sync (it takes time to add 
 +# rules, and during that time the first rule added may be hit, leading to 
 +# confusing packet counts: "But these rules should always apply to the same 
 +# packets! How can their hit count be different?"
 +iptables -t mangle -Z
 +</code>
 ==== Transparent Web Proxy ==== ==== Transparent Web Proxy ====
  
unix/gateway.txt · Last modified: 2018/10/04 14:37 by robm