Guest User

20-qos-htb

a guest
Mar 21st, 2014
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 16.18 KB | None | 0 0
  1. #!/bin/sh
  2.  
  3. # qos-script v1.05
  4.  
  5. ## Please modify user configuration in /etc/qos.conf
  6. ## To start QoS without reboot, use "ifdown wan && ifup wan"
  7.  
  8. # User configuration
  9. [ -f /etc/storage/qos.conf ] && . /etc/storage/qos.conf
  10.  
  11. # If no interface defined, use WAN interface
  12. [ "$QOS_IF" ] || QOS_IF=$(nvram get wan_ifname)
  13.  
  14. # Find out interface of hotplug event
  15. #HOTPLUG_IF=$(nvram get ${INTERFACE}_ifname)
  16.  
  17. # Script can be activated by hotplug event on qos interface or passing "qosstart" in $INTERFACE
  18. #if [ "$ACTION" = "ifup" -a \( "$HOTPLUG_IF" = "$QOS_IF" -o "$INTERFACE" = "qosstart" \) ]
  19. if true ; then
  20.  
  21.  
  22.   # Length of burst buffers in ms (must be larger than kernel jiffy of 10ms)
  23.   DBURST_D=10
  24.   DBURST_U=10
  25.  
  26.   MTU=1600
  27.  
  28.   # Minimum class rate as percentage of full line rate
  29.   MIN_RATE=10
  30.  
  31.   # The following packages are required for the modules:
  32.   # kmod-sched
  33.   # kmod-ipt-conntrack
  34.   # iptables-mod-conntrack
  35.   # kmod-ipt-ipopt
  36.   # iptables-mod-ipopt
  37.   # kmod-ipt-extra
  38.   # iptables-mod-extra
  39.   # ip
  40.   # kmod-imq
  41.   # iptables-mod-imq
  42.   # kmod-ipt-filter
  43.   # iptables-mod-filter
  44.  
  45.   modprobe cls_fw >&- 2>&-
  46.   modprobe sch_htb >&- 2>&-
  47.   modprobe sch_sfq >&- 2>&-
  48. #  modprobe ipt_CONNMARK >&- 2>&-
  49.   modprobe xt_length >&- 2>&-
  50.   modprobe imq numdevs=1 >&- 2>&-
  51.   modprobe xt_IMQ >&- 2>&-
  52.   modprobe ipt_ipp2p >&- 2>&-
  53.   modprobe xt_layer7 >&- 2>&-
  54. #  modprobe ipt_tos >&- 2>&-
  55. #  modprobe ipt_TOS >&- 2>&-
  56.   modprobe xt_dscp >&- 2>&-
  57.   modprobe xt_DSCP >&- 2>&-
  58.   modprobe sch_red >&- 2>&-
  59.  
  60.   # To enable logging (requires iptables-mod-extra package)
  61.   [ "$DEBUG" -eq 1 ] && modprobe ipt_LOG >&- 2>&-
  62.  
  63.   iptables -t mangle -F
  64.   iptables -t mangle -X
  65.  
  66.   # Set up the InterMediate Queuing device (IMQ)
  67.   ip link set imq0 up
  68.  
  69.   # Remove queuing disciplines from all interfaces
  70.   sed -n 's/ *\(.*\):.*/\1/p' /proc/net/dev | while read INTERFACE; do
  71.     tc qdisc del dev $INTERFACE root >&- 2>&-
  72.   done
  73.  
  74.   [ $UPLOAD -ne 0 ] && {
  75.     # Calculate buffer lengths in bytes
  76.     BURST_U=$(($DBURST_U*$UPLOAD/8))
  77.  
  78.     # Make sure burst buffer size is at least MTU
  79.     [ $BURST_U -lt $((1*$MTU)) ] && BURST_U=$((1*$MTU))
  80.  
  81.     # Calculate r2q for htb discipline
  82.     RTOQ_U=$(($MIN_RATE*$UPLOAD*10/(8*$MTU)))
  83.     [ $RTOQ_U -gt 20 ] && RTOQ_U=20
  84.     [ $RTOQ_U -eq 0 ] && RTOQ_U=1
  85.  
  86.     # Attach egress queuing discipline to QoS interface
  87.     tc qdisc add dev $QOS_IF root handle 1: htb default 40 r2q $RTOQ_U
  88.     tc class add dev $QOS_IF parent 1: classid 1:1 htb rate ${UPLOAD}kbit ceil ${UPLOAD}kbit burst $(($BURST_U*3)) cburst $(($BURST_U*3)) mtu $MTU
  89.     tc class add dev $QOS_IF parent 1:1 classid 1:10 htb rate $(($UPLOAD*5/10))kbit ceil ${UPLOAD}kbit burst $(($BURST_U*1)) cburst $(($BURST_U*1)) prio 1 mtu $MTU
  90.     tc class add dev $QOS_IF parent 1:1 classid 1:20 htb rate $(($UPLOAD*2/10))kbit ceil ${UPLOAD}kbit burst $(($BURST_U*1)) cburst $(($BURST_U*1)) prio 2 mtu $MTU
  91.     tc class add dev $QOS_IF parent 1:1 classid 1:30 htb rate $(($UPLOAD*2/10))kbit ceil ${UPLOAD}kbit burst $(($BURST_U*1)) cburst $(($BURST_U*1)) prio 3 mtu $MTU
  92.     tc class add dev $QOS_IF parent 1:1 classid 1:40 htb rate $(($UPLOAD*1/10))kbit ceil ${UPLOAD}kbit burst $(($BURST_U*1)) cburst $(($BURST_U*1)) prio 4 mtu $MTU
  93.  
  94.     tc qdisc add dev $QOS_IF parent 1:10 sfq quantum $MTU perturb 10
  95.     tc qdisc add dev $QOS_IF parent 1:20 sfq quantum $MTU perturb 10
  96.     tc qdisc add dev $QOS_IF parent 1:30 sfq quantum $MTU perturb 10
  97.     tc qdisc add dev $QOS_IF parent 1:40 sfq quantum $MTU perturb 10
  98.  
  99.     tc filter add dev $QOS_IF parent 1: prio 1 protocol ip handle 1 fw flowid 1:10
  100.     tc filter add dev $QOS_IF parent 1: prio 2 protocol ip handle 2 fw flowid 1:20
  101.     tc filter add dev $QOS_IF parent 1: prio 3 protocol ip handle 3 fw flowid 1:30
  102.     tc filter add dev $QOS_IF parent 1: prio 4 protocol ip handle 4 fw flowid 1:40
  103.   }
  104.  
  105.   [ $DOWNLOAD -ne 0 ] && {
  106.     # Calculate buffer lengths in bytes
  107.     BURST_D=$(($DBURST_D*$DOWNLOAD/8))
  108.  
  109.     # Make sure burst buffer size is at least MTU
  110.     [ $BURST_D -lt $((1*$MTU)) ] && BURST_D=$((1*$MTU))
  111.  
  112.     # Calculate r2q for htb discipline
  113.     RTOQ_D=$(($MIN_RATE*$DOWNLOAD*10/(8*$MTU)))
  114.     [ $RTOQ_D -gt 20 ] && RTOQ_D=20
  115.     [ $RTOQ_D -eq 0 ] && RTOQ_D=1
  116.  
  117.     # Attach ingress queuing discipline to IMQ interface
  118.     # htb qdisc without default: all unmarked (mark 0) packages pass unlimited
  119.     # htb with non-existing default: unmarked packages get dropped
  120.     tc qdisc add dev imq0 root handle 1: htb default 40 r2q $RTOQ_D
  121.     tc class add dev imq0 parent 1: classid 1:1 htb rate ${DOWNLOAD}kbit ceil ${DOWNLOAD}kbit burst $((BURST_D*3)) cburst $((BURST_D*3)) mtu $MTU
  122.     tc class add dev imq0 parent 1:1 classid 1:10 htb rate $(($DOWNLOAD*5/10))kbit ceil ${DOWNLOAD}kbit burst $((BURST_D*1)) cburst $((BURST_D*1)) prio 1 mtu $MTU
  123.     tc class add dev imq0 parent 1:1 classid 1:20 htb rate $(($DOWNLOAD*2/10))kbit ceil ${DOWNLOAD}kbit burst $((BURST_D*1)) cburst $((BURST_D*1)) prio 2 mtu $MTU
  124.     tc class add dev imq0 parent 1:1 classid 1:30 htb rate $(($DOWNLOAD*2/10))kbit ceil ${DOWNLOAD}kbit burst $((BURST_D*1)) cburst $((BURST_D*1)) prio 3 mtu $MTU
  125.     tc class add dev imq0 parent 1:1 classid 1:40 htb rate $(($DOWNLOAD*1/10))kbit ceil $(($DOWNLOAD*3/4))kbit burst $((BURST_D*1)) cburst $((BURST_D*1)) prio 4 mtu $MTU
  126.  
  127.     tc qdisc add dev imq0 parent 1:10 red limit $((40*$MTU)) min $((5*$MTU)) max $((20*$MTU)) avpkt $(($MTU*6/10)) burst 16 probability 0.015
  128.     tc qdisc add dev imq0 parent 1:20 red limit $((40*$MTU)) min $((5*$MTU)) max $((20*$MTU)) avpkt $(($MTU*6/10)) burst 16 probability 0.015
  129.     tc qdisc add dev imq0 parent 1:30 red limit $((40*$MTU)) min $((5*$MTU)) max $((20*$MTU)) avpkt $(($MTU*6/10)) burst 16 probability 0.015
  130.     tc qdisc add dev imq0 parent 1:40 red limit $((40*$MTU)) min $((5*$MTU)) max $((20*$MTU)) avpkt $(($MTU*6/10)) burst 16 probability 0.015
  131.  
  132.     tc filter add dev imq0 parent 1: prio 1 protocol ip handle 1 fw flowid 1:10
  133.     tc filter add dev imq0 parent 1: prio 2 protocol ip handle 2 fw flowid 1:20
  134.     tc filter add dev imq0 parent 1: prio 3 protocol ip handle 3 fw flowid 1:30
  135.     tc filter add dev imq0 parent 1: prio 4 protocol ip handle 4 fw flowid 1:40
  136.   }
  137.  
  138.   iptables -t mangle -N mark_chain
  139.   iptables -t mangle -N egress_chain
  140.   iptables -t mangle -N ingress_chain
  141.  
  142.   # Set up egress marking chain
  143.   iptables -t mangle -A POSTROUTING -o $QOS_IF -j egress_chain
  144.  
  145.   # Mark ingress in FORWARD and INPUT chains to make sure any DNAT (virt. server) is taken into account
  146.   # Mark ingress in FORWARD chain for LAN and send through the IMQ device
  147.   iptables -t mangle -A FORWARD -i $QOS_IF -j ingress_chain
  148.   iptables -t mangle -A FORWARD -i $QOS_IF -j IMQ --todev 0
  149.  
  150.   # Mark ingress in INPUT chain for this router and send through the IMQ device
  151.   iptables -t mangle -A INPUT -i $QOS_IF -j ingress_chain
  152.   iptables -t mangle -A INPUT -i $QOS_IF -j IMQ --todev 0
  153.  
  154.   #################################### FUNCTION DEFINITIONS ############################################
  155.   mark_addr_in()
  156.     {
  157.      # Set up ingress rules based on ip_address[:port[:range]]
  158.      # $1 is a list of ip:port elements
  159.      # $2 is the priority
  160.  
  161.      for ADDR in $1; do
  162.        IP_PART=`echo $ADDR | sed -n 's/\([^:]*\):.*/\1/p'`
  163.        if [ "$IP_PART" ]; then
  164.          PORT_PART=`echo $ADDR | sed -n 's/[^:]*:\(.*\)/\1/p'`
  165.          iptables -t mangle -A ingress_chain -d $IP_PART -p tcp --dport $PORT_PART -j MARK --set-mark $2
  166.          iptables -t mangle -A ingress_chain -d $IP_PART -p udp --dport $PORT_PART -j MARK --set-mark $2
  167.        else
  168.          iptables -t mangle -A ingress_chain -d $ADDR -j MARK --set-mark $2
  169.        fi
  170.      done
  171.     }
  172.  
  173.   mark_addr_out()
  174.     {
  175.      # Set up egress rules based on ip_address[:port[:range]]
  176.      # $1 is a list of ip:port elements
  177.      # $2 is the priority
  178.  
  179.      for ADDR in $1; do
  180.        IP_PART=`echo $ADDR | sed -n 's/\([^:]*\):.*/\1/p'`
  181.        if [ "$IP_PART" ]; then
  182.          PORT_PART=`echo $ADDR | sed -n 's/[^:]*:\(.*\)/\1/p'`
  183.          iptables -t mangle -A egress_chain -s $IP_PART -p tcp --dport $PORT_PART -j MARK --set-mark $2
  184.          iptables -t mangle -A egress_chain -s $IP_PART -p udp --dport $PORT_PART -j MARK --set-mark $2
  185.        else
  186.          iptables -t mangle -A egress_chain -s $ADDR -j MARK --set-mark $2
  187.        fi
  188.      done
  189.     }
  190.   ######################################################################################################
  191.  
  192.   ###################################### MARK CHAIN ####################################################
  193.   # Restore any saved connection mark if not already marked
  194.   iptables -t mangle -A mark_chain -m mark --mark 0 -j CONNMARK --restore-mark
  195.  
  196.   # Mark expr packets based on port numbers and protocol
  197.   for PORT in $UDP_EXPR; do
  198.     iptables -t mangle -A mark_chain -m mark --mark 0 -p udp --dport $PORT -j MARK --set-mark 1
  199.   done
  200.   for PORT in $TCP_EXPR; do
  201.     iptables -t mangle -A mark_chain -m mark --mark 0 -p tcp --dport $PORT -j MARK --set-mark 1
  202.   done
  203.  
  204.   # Mark prio packets based on port numbers and protocol
  205.   for PORT in $UDP_PRIO; do
  206.     iptables -t mangle -A mark_chain -m mark --mark 0 -p udp --dport $PORT -j MARK --set-mark 2
  207.   done
  208.   for PORT in $TCP_PRIO; do
  209.     iptables -t mangle -A mark_chain -m mark --mark 0 -p tcp --dport $PORT -j MARK --set-mark 2
  210.   done
  211.  
  212.   # Mark bulk packets based on port numbers and protocol
  213.   for PORT in $UDP_BULK; do
  214.     iptables -t mangle -A mark_chain -m mark --mark 0 -p udp --dport $PORT -j MARK --set-mark 4
  215.   done
  216.   for PORT in $TCP_BULK; do
  217.     iptables -t mangle -A mark_chain -m mark --mark 0 -p tcp --dport $PORT -j MARK --set-mark 4
  218.   done
  219.  
  220. #  # Mark expr packets based on ipp2p match
  221. #  ALL_PROTOS=""
  222. #  for PROTO in $IPP2P_EXPR; do
  223. #    ALL_PROTOS="${ALL_PROTOS}--$PROTO "
  224. #  done
  225. #  [ "$ALL_PROTOS" ] && iptables -t mangle -A mark_chain -m mark --mark 0 -m ipp2p $ALL_PROTOS -j
  226. MARK --set-mark 1
  227.  
  228. #  # Mark prio packets based on ipp2p match
  229. #  ALL_PROTOS=""
  230. #  for PROTO in $IPP2P_PRIO; do
  231. #    ALL_PROTOS="${ALL_PROTOS}--$PROTO "
  232. #  done
  233. #  [ "$ALL_PROTOS" ] && iptables -t mangle -A mark_chain -m mark --mark 0 -m ipp2p $ALL_PROTOS -j
  234. MARK --set-mark 2
  235.  
  236. #  # Mark bulk packets based on ipp2p match
  237. #  ALL_PROTOS=""
  238. #  for PROTO in $IPP2P_BULK; do
  239. #    ALL_PROTOS="${ALL_PROTOS}--$PROTO "
  240. #  done
  241. #  [ "$ALL_PROTOS" ] && iptables -t mangle -A mark_chain -m mark --mark 0 -m ipp2p $ALL_PROTOS -j
  242. MARK --set-mark 4
  243.  
  244.   # Mark expr packets based on layer7 match
  245.   for PROTO in $L7_EXPR; do
  246.     iptables -t mangle -A mark_chain -m mark --mark 0 -m layer7 --l7proto $PROTO -j MARK --set-mark 1
  247.   done
  248.  
  249.   # Mark prio packets based on layer7 match
  250.   for PROTO in $L7_PRIO; do
  251.     iptables -t mangle -A mark_chain -m mark --mark 0 -m layer7 --l7proto $PROTO -j MARK --set-mark 2
  252.   done
  253.  
  254.   # Mark bulk packets based on layer7 match
  255.   for PROTO in $L7_BULK; do
  256.     iptables -t mangle -A mark_chain -m mark --mark 0 -m layer7 --l7proto $PROTO -j MARK --set-mark 4
  257.   done
  258.  
  259.   # Default is normal priority (to make sure every packet on WAN interface gets marked)
  260.   iptables -t mangle -A mark_chain -m mark --mark 0 -j MARK --set-mark 3
  261.  
  262.   # Save mark onto connection
  263.   iptables -t mangle -A mark_chain -j CONNMARK --save-mark
  264.  
  265.   # ICMP gets high priority (impress friends)
  266.   iptables -t mangle -A mark_chain -p icmp -j MARK --set-mark 1
  267.   iptables -t mangle -A mark_chain -p ipv6-icmp -j MARK --set-mark 1
  268.  
  269.   # Small UDP packets (most likely games) get high priority
  270.   [ "$UDP_LENGTH" -gt 0 ] && iptables -t mangle -A mark_chain -p udp -m length --length :$UDP_LENGTH -j MARK --set-mark 1
  271.   ######################################################################################################
  272.  
  273.   ###################################### INGRESS CHAIN #################################################
  274.   # Mark bulk packets based on destination LAN ip address and port number
  275.   mark_addr_in "$IP_BULK" 4
  276.  
  277.   # Mark prio packets based on destination LAN ip address and port number
  278.   mark_addr_in "$IP_PRIO" 2
  279.  
  280.   # Mark expr packets based on destination LAN ip address and port number
  281.   mark_addr_in "$IP_EXPR" 1
  282.  
  283.   # Call mark_chain
  284.   iptables -t mangle -A ingress_chain -j mark_chain
  285.   ######################################################################################################
  286.  
  287.   ######################################## EGRESS CHAIN ################################################
  288.   # Mark bulk packets based on tos match (egress only)
  289.   for PROTO in $TOS_BULK; do
  290.     iptables -t mangle -A egress_chain -m tos --tos $PROTO -j MARK --set-mark 4
  291.   done
  292.  
  293.   # Mark prio packets based on tos match (egress only)
  294.   for PROTO in $TOS_PRIO; do
  295.     iptables -t mangle -A egress_chain -m tos --tos $PROTO -j MARK --set-mark 2
  296.   done
  297.  
  298.   # Mark expr packets based on tos match (egress only)
  299.   for PROTO in $TOS_EXPR; do
  300.     iptables -t mangle -A egress_chain -m tos --tos $PROTO -j MARK --set-mark 1
  301.   done
  302.  
  303.   # Mark bulk packets based on dscp match (egress only)
  304.   for PROTO in $DSCP_BULK; do
  305.     iptables -t mangle -A egress_chain -m dscp --dscp $PROTO -j MARK --set-mark 4
  306.   done
  307.  
  308.   # Mark prio packets based on dscp match (egress only)
  309.   for PROTO in $DSCP_PRIO; do
  310.     iptables -t mangle -A egress_chain -m dscp --dscp $PROTO -j MARK --set-mark 2
  311.   done
  312.  
  313.   # Mark expr packets based on dscp match (egress only)
  314.   for PROTO in $DSCP_EXPR; do
  315.     iptables -t mangle -A egress_chain -m dscp --dscp $PROTO -j MARK --set-mark 1
  316.   done
  317.  
  318.   # Mark bulk packets based on source LAN ip address and port number
  319.   mark_addr_out "$IP_BULK" 4
  320.  
  321.   # Mark prio packets based on source LAN ip address and port number
  322.   mark_addr_out "$IP_PRIO" 2
  323.  
  324.   # Mark expr packets based on source LAN ip address and port number
  325.   mark_addr_out "$IP_EXPR" 1
  326.  
  327.   # Call mark_chain
  328.   iptables -t mangle -A egress_chain -j mark_chain
  329.  
  330.   # Make sure ACK packets get priority (to avoid upload speed limiting our download speed)
  331.   iptables -t mangle -A egress_chain -p tcp -m length --length :128 --tcp-flags SYN,RST,ACK ACK -j MARK --set-mark 1
  332.   ######################################################################################################
  333.  
  334.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A egress_chain -m mark --mark 0 -j LOG --log-prefix egress_0::
  335.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A egress_chain -m mark --mark 0 -j ACCEPT
  336.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A egress_chain -m mark --mark 1 -j LOG --log-prefix egress_1::
  337.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A egress_chain -m mark --mark 1 -j ACCEPT
  338.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A egress_chain -m mark --mark 2 -j LOG --log-prefix egress_2::
  339.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A egress_chain -m mark --mark 2 -j ACCEPT
  340.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A egress_chain -m mark --mark 3 -j LOG --log-prefix egress_3::
  341.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A egress_chain -m mark --mark 3 -j ACCEPT
  342.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A egress_chain -m mark --mark 4 -j LOG --log-prefix egress_4::
  343.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A egress_chain -m mark --mark 4 -j ACCEPT
  344.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A egress_chain -j LOG --log-prefix egress_other::
  345.  
  346.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A ingress_chain -m mark --mark 0 -j LOG --log-prefix ingress_0::
  347.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A ingress_chain -m mark --mark 0 -j ACCEPT
  348.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A ingress_chain -m mark --mark 1 -j LOG --log-prefix ingress_1::
  349.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A ingress_chain -m mark --mark 1 -j ACCEPT
  350.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A ingress_chain -m mark --mark 2 -j LOG --log-prefix ingress_2::
  351.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A ingress_chain -m mark --mark 2 -j ACCEPT
  352.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A ingress_chain -m mark --mark 3 -j LOG --log-prefix ingress_3::
  353.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A ingress_chain -m mark --mark 3 -j ACCEPT
  354.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A ingress_chain -m mark --mark 4 -j LOG --log-prefix ingress_4::
  355.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A ingress_chain -m mark --mark 4 -j ACCEPT
  356.   [ "$DEBUG" -eq 1 ] && iptables -t mangle -A ingress_chain -j LOG --log-prefix ingress_other::
  357.  
  358. fi
  359. exit 0
Advertisement
Add Comment
Please, Sign In to add comment