openwrt多wan限上下行速脚本,基于qosv4,imq模块替换成ifb模块

由于树莓派2装openwrt官方没有imq模块, 好像说ifb比较有优势,优势对于普通玩家来说,没用~.
百度翻遍各种文档,总算凑合起来可以用.有问题再提出来讨论,欢迎测试.
有些参数是写死在脚本里面,因为暂时设了htb的带宽不可借用的,所以大小好像没关系.
all_wan_down_speed=1500
all_wan_up_speed=50

脚本如下:
#!/bin/sh
#copyright by zhoutao0712 modify lynatgz  @2015.07.12

. /lib/functions.sh

#装载核心模块
load_modules(){
    #insmod imq numdevs=2
    #ifb模块 代替 imq模块
    insmod ifb
    insmod cls_fw 
    insmod sch_hfsc 
    insmod sch_sfq 
    insmod sch_red 
    insmod sch_htb 
    insmod sch_prio 
    insmod xt_multiport 
    insmod xt_CONNMARK
    insmod xt_length 
    insmod xt_hashlimit
    insmod cls_u32
    insmod xt_connlimit
    insmod xt_connbytes
    echo "" > ${qosv4_tmp_pach}/insmod
}

bak(){
<<!
#必需在函数里面才能多行注释!
        ##sfq 随机公平队列,参数perturb 12秒后重新配置一次散列算法(默认为10). quantum 每轮当前的class能发送的字节数
        #队列 hadnle 编号为 $RULE_ID$IP4 (后面没有用到这条队列!)
        #tc qdisc add dev ifb0 parent 1RULE_ID$IP4 handle $RULE_ID$IP4 sfq perturb 12 quantum 2000 
!
}

qos_stop(){
    #for iface in $(tc qdisc show | grep htb | awk '{print $5}'); do
    for iface in $(tc qdisc show | awk '{print $5}'); do
        #ifconfig的所有网卡
        tc qdisc del dev "$iface" root
    done

    #删链重建.NEW meaning that the packet has started a new connection, or otherwise associated with a connection which has not seen packets in both directions
    iptables -t mangle -D PREROUTING -m state --state NEW -j NEWLMT

    #删除旧规则
    iptables -t mangle -D NEWLMT -i pppoe+ -j RETURN
    iptables -D FORWARD -o pppoe+ -p udp -j UDPLMT
    iptables -t mangle -D FORWARD -i pppoe+ -j QOSDOWN
    iptables -t mangle -D POSTROUTING -o pppoe+ -j QOSUP

    #清空链规则
    iptables -t mangle -F QOSDOWN
    iptables -t mangle -F QOSUP
    iptables -t mangle -F NEWLMT
    iptables -F UDPLMT
    #iptables -t mangle -F PUNISH0

    #-X --delete-chain 删除链
    iptables -t mangle -X QOSDOWN
    iptables -t mangle -X QOSUP
    iptables -t mangle -X NEWLMT
    iptables -X UDPLMT
    #iptables -t mangle -X PUNISH0

    [ -f ${qosv4_tmp_pach}/connlimit ] && {
        sh ${qosv4_tmp_pach}/connlimit
        echo "" > ${qosv4_tmp_pach}/connlimit
    }
    echo "QOS DELETE DONE";echo ""
}

#创建QOS专用链
qos_start(){
    #删除各种链
    qos_stop

    #新建链NEWLMT, 用于新建连接控制  -N --new-chain 
    iptables -t mangle -N NEWLMT

    #PREROUTING下一规则NEWLMT, 当匹配到新建链接全部入NEWLMT链规则
    iptables -t mangle -I PREROUTING -m state --state NEW -j NEWLMT

    #放行本地地址访问局域网
    iptables -t mangle -A NEWLMT -s $(uci get network.lan.ipaddr)/24 -d $(uci get network.lan.ipaddr)/24 -j RETURN
    #放行upd端口53,67,68,1900 53端口为DNS端口,67和68是DHCP端口,
    iptables -t mangle -A NEWLMT -p udp -m multiport --dports 53,67,68,1900 -j RETURN
    #udp链接数超过100的包丢弃
    iptables -t mangle -A NEWLMT -p udp -m connlimit --connlimit-above 120 -j DROP
    #点对点的tcp握手包链接数超过200的包丢弃, 握手包SYN、ACK、FIN.connlimit: Allows you to restrict the number of parallel connections  to  a  server  per  client  IP address
    iptables -t mangle -A NEWLMT -p tcp --syn -m connlimit --connlimit-above 200 -j DROP
    #为每个源IP(收与发)建立匹配项, 产生速度25/s, 放行匹配的数据包, 超过速率的就可能丢弃了
    iptables -t mangle -A NEWLMT -m hashlimit --hashlimit-name newlmt --hashlimit-mode srcip --hashlimit 40 -j RETURN
    #限制tcp 80端口的请求包低于25/秒
    iptables -t mangle -A NEWLMT -p tcp --dport 80 -m limit --limit 40 -j RETURN
    #其他全部丢弃
    iptables -t mangle -A NEWLMT -j DROP
    #NEWLMT -I 插入首规则: 当网卡N收到数据, 回原路PREROUTING. 对端发起连接时,放行
    iptables -t mangle -I NEWLMT -i pppoe+ -j RETURN

    #新建链 UDPLMT, 用于控制udp, 不指定则入filter表
    iptables -N UDPLMT
    #为每个源IP(收与发)建立匹配项, 产生速度120/s, 放行匹配的数据包, 超过速率的就可能丢弃了
    iptables -A UDPLMT -m hashlimit --hashlimit-name udplmt --hashlimit-mode srcip --hashlimit 120 -j RETURN
    #限制udp 30, 8000端口的请求包低于30/秒
    iptables -A UDPLMT -p udp -m multiport --dports 53,8000 -m limit --limit 30 -j RETURN
    #其他全部丢弃
    iptables -A UDPLMT -j DROP
    #FORWARD -I 插入首规则:当网卡N发送数据udp, 入UDPLMT,
    iptables -I FORWARD -o pppoe+ -p udp -j UDPLMT

    iptables -t mangle -N QOSDOWN
    iptables -t mangle -N QOSUP
    #FORWARD -I 插入首规则:当网卡N收到数据, 入QOSDOWN    #INPUT 可能是访问路由的, 不限制路由自身下行
    iptables -t mangle -I FORWARD -i pppoe+ -j QOSDOWN
    #FORWARD -I 插入首规则:当网卡N发送数据, 入QOSUP
    iptables -t mangle -I POSTROUTING -o pppoe+ -j QOSUP

<<!
    #小包不进入后面的打标记,小包不进入tc限速
!
    #放下行upd外部端口为53的, 53端口为DNS端口
    iptables -t mangle -A QOSDOWN -p udp --sport 53 -j RETURN
    #放上行upd外部端口为53的,53端口为DNS端口
    iptables -t mangle -A QOSUP -p udp --dport 53 -j RETURN
    #放下行tcp 不是初始包, 长度0:100字节的
    iptables -t mangle -A QOSDOWN -p tcp ! --syn -m length --length :100 -j RETURN
    #放上行tcp 不是初始包, 长度0:80字节的
    iptables -t mangle -A QOSUP -p tcp ! --syn -m length --length :80 -j RETURN

    #以下3条规则是一起生效的
    # iptables -t mangle -A PREROUTING -p tcp -m connmark ! --mark 80 -m web --path ".exe$ .rar$ .iso$ .zip$ .rm$ .rmvb$ .wma$ .avi$" -j CONNMARK --set-mark 80
    #connmark连接打标记, mask为80的, 设置连接mark为80
    #iptables -t mangle -A QOSDOWN -m connmark --mark 80 -j MARK --set-mark 80
    #iptables -t mangle -A QOSUP -m connmark --mark 80 -j MARK --set-mark 80

<<!
    #大包作特殊标记
!
    #QOSDOWN tcp包长度0:768字节的,下一规则为MARK,标记为255(配合TC做QOS流量限制或应用策略路由)
    #iptables -t mangle -A QOSDOWN -p tcp -m length --length :768 -j MARK --set-mark 255
    #QOSUP tcp包长度0:512字节的,下一规则为MARK,标记为255(配合TC做QOS流量限制或应用策略路由)
    #iptables -t mangle -A QOSUP -p tcp -m length --length :512 -j MARK --set-mark 255

    ##CONNBYTES模块
    ##tcp 80,443,25,110 QOSDOWN下一规则为CONNBYTES, 可能这一写法是错误的
    #iptables -t mangle -A QOSDOWN -p tcp -m multiport --sports 80,443,25,110 -j CONNBYTES
    #iptables -t mangle -A QOSUP -p tcp -m multiport --dports 80,443,25,110 -j CONNBYTES

    ##--connbytes 1:200 match packets from a connection whose packets/bytes/average packet size is more than FROM and less than TO bytes/packets
    ##QOSUP tcp 80,443,25,110 端口 双向的数据达到 0:51200字节, 下一规则为MARK,标记为254
    #iptables -t mangle -A QOSUP -p tcp -m multiport --sports 80,443,25,110  -m connbytes  --connbytes :51200 --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 254
    ##QOSDOWN tcp 80,443,25,110 端口 双向的数据达到 0:102400字节, 下一规则为MARK,标记为254
    #iptables -t mangle -A QOSDOWN -p tcp -m multiport --sports 80,443,25,110 -m connbytes  --connbytes :102400 --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 254

    #http://segmentfault.com/a/1190000000666869
    #http://blog.chinaunix.net/uid-7396260-id-3294466.html
    #http://it.chinawin.net/internet/article-24b44.html
    #http://www.cnblogs.com/endsock/archive/2011/12/09/2281519.html
    #tc cl ad dev ifb0 缩写写法.

    #ifb0-下行控制,  ifb1-上行控制
    ifconfig ifb1 up

    #下载速度控制,限制内网网卡发送给用户的数据包速度

    #1. htb可以很容易地保证每个类别的带宽, 虽然它也允许特定的类可以突破带宽上限, 占用别的类的带宽
    #根队列规则, 把htb队列绑定到 ifb0 , 并指定了一个 handle 句柄 1: (效果1:0) 用于标识它下面的子类, 没标识的分配默认子类 9999 (默认值只是设置而已, 可以不用)
    tc qdisc add dev eth0 root handle 1: htb default 999
    tc qdisc add dev ifb1 root handle 1: htb default 999 

    #2. 为队列建一个主干类, htb的主干类不能互相借用带宽, 但是一个父类的所有子类之间可以借用带宽, parent 1: 是刚才建立的 handle 1: , 父类为1:0 , 分类号 1:1
    #ceil 不配则值与rate一样, prio 0 burst 1599b cburst 1599b 
    tc class add dev eth0 parent 1: classid 1:1 htb rate $((all_wan_down_speed))kbps
    tc class add dev ifb1 parent 1: classid 1:1 htb rate $((all_wan_up_speed))kbps

    #每个IP限速, 下行 & 上行
    config_foreach   get_qos_ip_limit   qos_ip

    #tc class add dev ifb0 parent 1:1 classid 1:a254 htb rate $((GLOBAL_DOWN/10))kbps ceil $((GLOBAL_DOWN*7/10))kbps quantum 8000 prio 3
    ##sfq 随机公平队列,参数perturb 12秒后重新配置一次散列算法(默认为10). quantum 每轮当前的class能发送的字节数
    #tc qdisc add dev ifb0 parent 1:a254 handle a254 sfq perturb 12 quantum 1500
    #tc filter add dev ifb0 parent 1: protocol ip prio 10 handle 254 fw flowid 1:a254
}

wan_list=$(ifconfig | grep "oint-to-Point Protocol" | cut -d" " -f1) 
#所有普通IP单独限速 (暂不调用)
qos_ip_limit() {
    #传入参数: 1-limit_ip   2-DOWNLOADR 保证    3-DOWNLOADC 最大  
    #               4-UPLOADR 保证   5-UPLOADC 最大    6-ip_prio        7-tcplimit  8-udplimit
    #保存IP第4个数字
    start=$(echo $1|cut -d '-' -f1|cut -d '.' -f4)
    end=$(echo $1|cut -d '-' -f2|cut -d '.' -f4)
    #NET 保存前3个数字 192.168.1
    NET=$(echo $1|cut -d '.' -f1-3)
    #记录在处理第几条规则
    RULE_ID=$((RULE_ID+1))
    echo "QOS_IP_LIMIT  limit_ip=$1  DOWNLOADR=$2   DOWNLOADC=$3  UPLOADR=$4 UPLOADC=$5 ip_prio=$6  tcplimit=$7  udplimit=$8"
    while [ $start -le $end ]
    do
        #不足2位前面补0
        IP4=$(printf "%02x" $start)
        echo "$NET.start  end=$end  RULE_ID=$RULE_ID IP4=$IP4"

        #QOSDOWN 标记tc需要限速的包, 标记为255
        iptables -t mangle -A QOSDOWN -d $NET.$start -j MARK --set-mark $start 
        #QOSUP 标记tc需要限速的包, 标记为 1255
        iptables -t mangle -A QOSUP -s $NET.$start -j MARK --set-mark $((start+1000))
        ##u32过滤器匹配ip目标地址, u32 match ip dst 10.0.0.229/32  ##防火墙标记过滤器 handle 254 fw 
        #eth0 叶分类,parent 1:1能借用带宽, 不想借用,写成parent 1:, 改用主干类, 主干ceil不启作用
        tc class add dev eth0 parent 1: classid 1RULE_ID$IP4 htb rate $2kbps ceil $3kbps prio $6
        #3. 设过滤器, handle 255 fw-根据防火墙标识控制标记为 255 的包,(与 iptables, set-mark对应), 父类1:, 送到子类1RULE_ID$IP4处理
        tc filter add dev eth0 parent 1: protocol ip prio 1 handle $start fw flowid 1RULE_ID$IP4

        #ifb1 叶分类,parent 1:1能借用带宽, 不想借用,写成parent 1:, 改用主干类
        tc class add dev ifb1 parent 1: classid 1RULE_ID$IP4 htb rate $4kbps ceil $5kbps prio $6
        tc filter add dev ifb1 parent 1: protocol ip prio 1 handle $((start+1000)) fw flowid 1RULE_ID$IP4

        for pppoe_ifconfig in $wan_list; 
        do
            #pppoe 重定向到 ifb0    #redirect 会进入blackhole
            [ -z $init ] && {
                tc qdisc add dev $pppoe_ifconfig root handle 1: htb default 999
            }
            tc class add dev $pppoe_ifconfig parent 1: classid 1RULE_ID$IP4 htb rate $4kbps ceil $5kbps prio $6
            tc filter add dev $pppoe_ifconfig parent 1: protocol ip prio 1 handle $((start+1000)) fw flowid 1RULE_ID$IP4 action mirred egress mirror dev ifb1
        done
        init=1

        #tc class add dev ifb1 parent 1: classid 1RULE_ID$IP4 htb rate $4kbps ceil $5kbps prio $6
        #tc filter add dev ifb1 parent 1: protocol ip prio 1 u32 match ip src $NET.$start flowid 1RULE_ID$IP4

<<!
        #TCP UDP 连接数限制
        [ "$7" != "0" ] && {
            echo "iptables -t mangle -D FORWARD -p tcp -d $NET.$start -m connlimit --connlimit-above $7 -j DROP" >> $qosv4_tmp_pach/connlimit
            iptables -t mangle -A FORWARD -p tcp -d $NET.$start -m connlimit --connlimit-above $7 -j DROP
        }
        [ "$8" != "0" ] && {
            echo "iptables -t mangle -D FORWARD -p udp -d $NET.$start -m connlimit --connlimit-above $8 -j DROP" >> $qosv4_tmp_pach/connlimit
            iptables -t mangle -A FORWARD -p udp -d $NET.$start -m connlimit --connlimit-above $8 -j DROP
        }
!
        start=$((start+1))
    done
}

#没有配置限速的IP, 设置默认规则
qos_default_limit(){
    tc class add dev ifb1 parent 1:1 classid 1:999 htb rate 8kbps ceil 12kbps prio 7
    tc class add dev ifb0 parent 1:1 classid 1:999 htb rate 250kbps ceil 300kbps prio 7
}

#QOS白名单
qos_white(){
    #192.168.1.8,192.168.1.80-192.168.1.90有zhoutao0712发放的免死金牌
    #iptables -t mangle -I PUNISH0 -m iprange --src-range 192.168.1.80-192.168.1.90 -j RETURN
    iptables -t mangle -I PUNISH0 -s $nolimit_ip -j RETURN
}

<<!
    config qos_settings
        option UP '100'
        option UPLOADR2 '1'
        option UPLOADC2 '5'
        option DOWNLOADR2 '1'
        option DOWNLOADC2 '2'
        option DOWNLOADR '50'
        option UPLOADR '20'
        option qos_scheduler '0'
        option DOWN '2600'
        option enable '0'
!
#读取总网速配置
get_qos_config(){
    config_get GLOBAL_ENABLE $1 enable
    config_get GLOBAL_UP $1 UP
    config_get GLOBAL_DOWN $1 DOWN
    #config_get GLOBAL_UPLOADR2 $1 UPLOADR2
    #config_get GLOBAL_UPLOADC2 $1 UPLOADC2
    #config_get GLOBAL_DOWNLOADR2 $1 DOWNLOADR2
    #config_get GLOBAL_DOWNLOADC2 $1 DOWNLOADC2
    #config_get qos_scheduler $1 qos_scheduler
    echo "get_qos_config: GLOBAL_ENABLE=$GLOBAL_ENABLE GLOBAL_UP=$GLOBAL_UP  GLOBAL_DOWN=$GLOBAL_DOWN"
}


<<!
    config qos_ip
        option enable '1'
        option limit_ips '192.168.1.12'
        option limit_ipe '192.168.1.19'
        option UPLOADR '10'  保证
        option UPLOADC '16'  最大
        option DOWNLOADR '150'  保证
        option DOWNLOADC '2200'  最大
        option tcplimit '0'
        option udplimit '0'
        option ip_prio '5'
!
#循环读取每条IP限速规则, 并调用限速
get_qos_ip_limit(){
    config_get qos_limit_enable $1 enable
    config_get limit_ips $1 limit_ips
    config_get limit_ipe $1 limit_ipe
    config_get ip_prio $1 ip_prio
    config_get UPLOADC $1 UPLOADC
    config_get DOWNLOADC $1 DOWNLOADC
    config_get UPLOADR $1 UPLOADR
    config_get DOWNLOADR $1 DOWNLOADR
    config_get tcplimit $1 tcplimit
    config_get udplimit $1 udplimit
    limit_ip=$limit_ips-$limit_ipe

    #echo "get_qos_ip_limit: enable=$qos_limit_enable limit_ips=$limit_ips  limit_ipe=$limit_ipe ip_prio=$ip_prio UPLOADC=$UPLOADC DOWNLOADC=$DOWNLOADC"
    #放在这里调用是因为foreach循环调用
    [ "$qos_limit_enable" == "1" ] && qos_ip_limit $limit_ip $DOWNLOADR $DOWNLOADC $UPLOADR $UPLOADC $ip_prio $tcplimit $udplimit
}

<<!
    config 'qos_nolimit_ip'
        option 'nolimit_ip' '192.168.1.1'
        option 'nolimit_mac' '00:00:00:00:00'
        option 'enable' '0'
!
#读取不限制ip和mac
get_qos_nolimit_ip(){
    config_get enable $1 enable
    config_get nolimit_ip $1 nolimit_ip
    config_get nolimit_mac $1 nolimit_mac
    [ "$enable" == "1" ]&&printf "|grep -v  $nolimit_mac " >>${qosv4_tmp_pach}/qosv4_nolimit_mac
}

usage() {
cat << EOF
    Usage: $0 [start|stop]
EOF
    exit 1
}

#lan_net
#单位: kbps--千字节/s
all_wan_down_speed=1500
all_wan_up_speed=50
#each_wan_up_speed=30
qosv4_tmp_pach="/tmp/qosv4"
[ -d $qosv4_tmp_pach ] || mkdir -p ${qosv4_tmp_pach}
case $1 in
    start)
        config_load qosv4
        echo "start qosv4........"
        rm -rf ${qosv4_tmp_pach}/qosv4_nolimit_mac
        config_foreach   get_qos_config   qos_settings
        #GLOBAL_ENABLE=1
        echo "qosv4 enable=$GLOBAL_ENABLE " 
        if [ "$GLOBAL_ENABLE" == "1" ];then
            #存在insmod文件表示已经加载过了
            [ -f ${qosv4_tmp_pach}/insmod ] || load_modules >/dev/null 2>&1
            qos_start
            #qos_default_limit
            #QOS白名单
            #config_foreach   get_qos_nolimit_ip   qos_nolimit_ip
            #qos_white
        else
            echo "ENABLE = 0.";echo ""
            qos_stop
        fi
        ;;
    stop)
        qos_stop
        #qos_stop >/dev/null 2>&1 
        ;;
    *) usage;;
esac




// ifb 例子 qos-htb-sfq.sh

#! /bin/sh
# QoS setup


#egress


ip link set dev eth0.1999 txqueuelen 128


tc qdisc del dev eth0.1999 root
tc qdisc add dev eth0.1999 root handle 1: htb
tc class add dev eth0.1999 parent 1: classid 1:1 htb rate 19Mbit burst 25k


tc class add dev eth0.1999 parent 1:1 classid 1:2128 htb ceil 19Mbit rate 100kbit burst 25k
tc class add dev eth0.1999 parent 1:1 classid 1:2129 htb ceil 19Mbit rate 100kbit burst 25k
tc class add dev eth0.1999 parent 1:1 classid 1:2130 htb ceil 19Mbit rate 100kbit burst 25k
tc class add dev eth0.1999 parent 1:1 classid 1:2131 htb ceil 19Mbit rate 100kbit burst 25k
tc class add dev eth0.1999 parent 1:1 classid 1:2132 htb ceil 19Mbit rate 100kbit burst 25k
tc class add dev eth0.1999 parent 1:1 classid 1:2133 htb ceil 19Mbit rate 100kbit burst 25k


tc qdisc add dev eth0.1999 parent 1:2128 handle 2128: sfq 
tc qdisc add dev eth0.1999 parent 1:2129 handle 2129: sfq 
tc qdisc add dev eth0.1999 parent 1:2130 handle 2130: sfq 
tc qdisc add dev eth0.1999 parent 1:2131 handle 2131: sfq 
tc qdisc add dev eth0.1999 parent 1:2132 handle 2132: sfq 
tc qdisc add dev eth0.1999 parent 1:2133 handle 2133: sfq 


# Egress classification is handled through iptables (MARKing in
# PREROUTING/CLASSIFY in POSTROUTING), as tc filter doesn't have access to the
# pre-NAT IP address.


# ingress


# ensure that the ifb module is loaded 
tc qdisc del dev ifb0 root
tc qdisc add dev ifb0 root handle 1: htb
tc class add dev ifb0 parent 1: classid 1:1 htb rate 19Mbit burst 25k


tc class add dev ifb0 parent 1:1 classid 1:2128 htb ceil 19Mbit rate 100kbit burst 25k
tc class add dev ifb0 parent 1:1 classid 1:2129 htb ceil 19Mbit rate 100kbit burst 25k
tc class add dev ifb0 parent 1:1 classid 1:2130 htb ceil 19Mbit rate 100kbit burst 25k
tc class add dev ifb0 parent 1:1 classid 1:2131 htb ceil 19Mbit rate 100kbit burst 25k
tc class add dev ifb0 parent 1:1 classid 1:2132 htb ceil 19Mbit rate 100kbit burst 25k
tc class add dev ifb0 parent 1:1 classid 1:2133 htb ceil 19Mbit rate 100kbit burst 25k


tc qdisc add dev ifb0 parent 1:2128 handle 2128: sfq 
tc qdisc add dev ifb0 parent 1:2129 handle 2129: sfq 
tc qdisc add dev ifb0 parent 1:2130 handle 2130: sfq 
tc qdisc add dev ifb0 parent 1:2131 handle 2131: sfq 
tc qdisc add dev ifb0 parent 1:2132 handle 2132: sfq 
tc qdisc add dev ifb0 parent 1:2133 handle 2133: sfq 
tc qdisc add dev ifb0 parent 1:2134 handle 2134: sfq 


ip link set dev ifb0 up
ip link set dev ifb0 txqueuelen 128


# ingress redirection and classification


tc qdisc del dev eth0.2128 root
ip link set dev eth0.2128 txqueuelen 32
tc qdisc add dev eth0.2128 root handle 1: prio priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
tc filter add dev eth0.2128 parent 1:0 protocol ip priority 10 u32 match u32 0 \
0 flowid 1: action mirred egress redirect dev ifb0
tc filter add dev ifb0 parent 1:0 protocol ip u32 match ip dst 172.19.128.0/24 \
flowid 1:2128


tc qdisc del dev eth0.2129 root
ip link set dev eth0.2129 txqueuelen 32
tc qdisc add dev eth0.2129 root handle 1: prio priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
tc filter add dev eth0.2129 parent 1:0 protocol ip priority 10 u32 match u32 0 \
0 flowid 1: action mirred egress redirect dev ifb0
tc filter add dev ifb0 parent 1:0 protocol ip u32 match ip dst 172.19.129.0/24 \
flowid 1:2129


tc qdisc del dev eth0.2130 root
ip link set dev eth0.2130 txqueuelen 32
tc qdisc add dev eth0.2130 root handle 1: prio priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
tc filter add dev eth0.2130 parent 1:0 protocol ip priority 10 u32 match u32 0 \
0 flowid 1: action mirred egress redirect dev ifb0
tc filter add dev ifb0 parent 1:0 protocol ip u32 match ip dst 172.19.130.0/24 \
flowid 1:2130


tc qdisc del dev eth0.2131 root
ip link set dev eth0.2131 txqueuelen 32
tc qdisc add dev eth0.2131 root handle 1:  prio priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
tc filter add dev eth0.2131 parent 1:0 protocol ip priority 10 u32 match u32 0 \
0 flowid 1: action mirred egress redirect dev ifb0
tc filter add dev ifb0 parent 1:0 protocol ip u32 match ip dst 172.19.131.0/24 \
flowid 1:2131


tc qdisc del dev eth0.2132 root
ip link set dev eth0.2132 txqueuelen 32
tc qdisc add dev eth0.2132 root handle 1: prio priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
tc filter add dev eth0.2132 parent 1:0 protocol ip priority 10 u32 match u32 0 \
0 flowid 1: action mirred egress redirect dev ifb0
tc filter add dev ifb0 parent 1:0 protocol ip u32 match ip dst 172.19.132.0/24 \
flowid 1:2132


tc qdisc del dev eth0.2133 root
ip link set dev eth0.2133 txqueuelen 32
tc qdisc add dev eth0.2133 root handle 1: prio priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
tc filter add dev eth0.2133 parent 1:0 protocol ip priority 10 u32 match u32 0 \
0 flowid 1: action mirred egress redirect dev ifb0
tc filter add dev ifb0 parent 1:0 protocol ip u32 match ip dst 172.19.133.0/24 \
flowid 1:2133
 
 
2#
  发表于 2015-7-13 11:30  |  只看该作者
学习qos,还是参考tomato系统的/etc/qos,简单高效。

ifb跟imq的最大差别是,ifb不支持netfilter hook。虽然openwrt下的版本打过补丁能识别conntrack状态,但是pppoe ingress 依然在DNAT之前无法抓到lan的ip地址。
  1. On 7/19/06, Andy Furniss <lists at andyfurniss.entadsl.com> wrote:
  2. > Rajesh Mahajan wrote:
  3. > > Is IFB realy replacement of IMQ
  4. >
  5. > Mostly - it hooks before/after netfilter though, so if you really need
  6. > IMQ to hook "in" netfilter (eg. to get denatted addresses on ingress so
  7. > you can seperate INPUT and FORWARD traffic), you still need IMQ.
  8. >
  9. > Andy.
复制代码
虽然ifb支持多interface接口统一用一个ifb0做流控
tc filter add dev $pppoe_ifconfig parent 1: protocol ip prio 1 handle $((start+1000)) fw flowid 1RULE_ID$IP4 action mirred egress mirror dev ifb1
无法确定你上面是否有效,网上的标准语法都是下面这种吧。
$TC filter add dev pppoe-wan parent ffff: protocol all prio 1 u32 match u32 0 0 flowid 1:1 action connmark action mirred egress redirect dev ifb0


从测试的情况iptables limit比connlimit要好N多,limit基本属于匹配限流,而connlimit基本属于直接丢包。两种用户体验完全不一样。

至于   
#限制tcp 80端口的请求包低于25/秒
iptables -t mangle -A NEWLMT -p tcp --dport 80 -m limit --limit 40 -j RETURN完整语法是
iptables  -A INPUT -p tcp --dport 80 -m limit --limit 40/s --limit-burst 5 -j RETURN


先不归结于多少包的问题,你既然有多wan,怎么会做这种匹配,这种匹配一台电脑都受不了,更别说在大量ip的环境使用,无条件放过5个包,然后每250毫秒新生成一个新令牌。


看着头疼,还是去学习 tomato /etc/qos 吧,简单高效。这种qos在生产环境限速丢包,在玩游戏时要命,那是在飘移。最近被fq_codel折腾得够呛,虽然想法是好的随机丢弃高延迟的包清空队列获得低延迟,可是偏偏丢的是重要的包,玩游戏简直是坑队友。

点评

#限制tcp 80端口的请求包低于25/秒 iptables -t mangle -A NEWLMT -p tcp --dport 80 -m limit --limit 40 -j RETURN完整语法是 iptables -A INPUT -p tcp --dport 80 -m limit --limit 40/s --limit-burst 5 -j   详情  回复  发表于 2015-7-13 11:55
 
 
   
3#
  楼主 |  发表于 2015-7-13 11:55  |  只看该作者
dato 发表于 2015-7-13 11:30
学习qos,还是参考tomato系统的/etc/qos,简单高效。

ifb跟imq的最大差别是,ifb不支持netfilter hook。 ...

#限制tcp 80端口的请求包低于25/秒
iptables -t mangle -A NEWLMT -p tcp --dport 80 -m limit --limit 40 -j RETURN完整语法是
iptables  -A INPUT -p tcp --dport 80 -m limit --limit 40/s --limit-burst 5 -j RETURN

这些都是之前qosv4的东西,我放宽了一点速度,高压环境下不知道表现如何.只在宽带空闲的时限速过自己.

ifb的用法网上有mirror和redirect两种,实测过redirect不通,看到有句用了这个redirect会进入blackhole之类的,文档比较少,无法理解透ifb.

tomato /etc/qos 这个是配置吧?
对tomato没了解过,适用于openwrt吗?
 
 
   
4#
  发表于 2015-7-13 12:34  |  只看该作者
平时都是先设计高效的htb结构,然后再对特殊ip进行限制。比如像通过iptables limit对特定ip来限流来防止迅雷导致的高并发而导致局端开始对用户端进行丢包。
下面的语句完全就是两种结果,第一种所有的ip都受到限制,而下面的只限制迅雷用户192.168.1.1的并发,其它ip不受并发限制。
iptables -t mangle -A NEWLMT -p tcp --dport 80 -m limit --limit 40 -j RETURN
iptables -t mangle -A NEWLMT -p tcp -s 192.168.1.1--dport 80 -m limit --limit 40 -j RETURN
通过丢包方式进行降速,drop跟reject完全是两种性能,drop时导致发送端收不到回应,会持续到设定的conntrack timeout 时间才在conntrack表里消除该链接,而reject则是让该链接快速消失。这在大型网络是很致命的,特别对于lan用户,没必要drop而是应该用reject快速丢弃。丢包并不是个好的处理方式。

ifb的多接口重定可以看下面的例子,ifb还是蛮神奇的。这个例子解决了以前1lan+3vlan高达13个ip网段的接口流量识别问题,用一个统一的ifb就搞定了。论坛上那SQM我一直回答不了它为什么可以导致低延迟,一个大的作用就是ifb。还有fq_codel。但是做pppoe ffff这种重定向,依然会有不大不小的丢包问题,在ifb接口下面,会发现流量远不如不设ifb时,但是换来的是延迟的稳定。
https://github.com/westnetz/qos-script/blob/master/qos-htb-sfq.sh   // 例子在下面
ifb
By Linux Foundatio... - November 19, 2009 - 10:23am
http://www.linuxfoundation.org/collaborate/workgroups/networking/ifb



至于tomato的qos,其实真正要参考的是 CONNMARK --restore-mark结构,包标记应用到链接的过程。让routeros都相见汗颜,原生linux有着多种多样的工具可以实现QOS,效果当然非常NB。只能给链接自己参考去实现了。这个结构是可以同时实现根据上行优先级的标记准确的对下行的流量进行区分,所以它直接的效果就是在540kb线路上实现500-520kb流量波动时,高优先级的通过无线网卡的流量都能获得非常低的延迟。具体自己去整合吧。。。。别问我代码。。。。

Netfilter CONNMARK用法及分析(二)-- 内核代码分析
http://blog.chinaunix.net/uid-30005765-id-5057386.html

点评

我还以为drop丢掉不处理,对路由的效率会高点呢, 又理解了一个优化点. 我改下reject试下效果先,哈哈   详情  回复  发表于 2015-7-13 22:01
 
 
   
5#
  发表于 2015-7-13 12:44  |  只看该作者
这个要支持一下
 
 
   
6#
  发表于 2015-7-13 20:02  |  只看该作者
这种牛13帖要顶啊
 
 
   
7#
  楼主 |  发表于 2015-7-13 22:01  |  只看该作者
dato 发表于 2015-7-13 12:34
平时都是先设计高效的htb结构,然后再对特殊ip进行限制。比如像通过iptables limit对特定ip来限流来防止迅 ...

我还以为drop丢掉不处理,对路由的效率会高点呢, 又理解了一个优化点. 我改下reject试下效果先,哈哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值