Linux流量控制提高网络效率

目前很多企业的内部局域网已经建立,很多还在局域网基础上建立了企业内部的MIS系统和邮件服务器等,甚至在系统中开展了视频点播等数据流量较大的业务。

     企业内部网络有足够的带宽可以使用。但是,一般在企业接入Internet的部分都是一个有限的流量。为了提高网络的使用质量,保证用户按照网络中业务设 计的要求来使用整个网络的带宽,可以从流量控制服务器的角度分析、优化Linux系统,给企业服务带来便利和高效。

    流量控制的基本实现

    Linux 操作系统中的流量控制器(TC)主要是通过在输出端口处建立一个队列来实现流量控制。Linux从2.1.105版内核开始支持流量控制,使用时需要重新 编译内核。Linux流量控制的基本实现可简单地由图1来描述。从图1可以看出,内核是如何处理接收包、如何产生发送包,并送往网络的。


图1 Linux流量控制的基本实现


     接收包进来后,由输入多路分配器(Input De-Multiplexing)进行判断选择:如果接收包的目的是本主机,那么将该包送给上层处理;否则需要进行转发,将接收包交到转发块 (Forwarding Block)处理。转发块同时也接收本主机上层(TCP、UDP等)产生的包。转发块通过查看路由表,决定所处理包的下一跳。然后,对包进行排列以便将它 们传送到输出接口(Output Interface)。Linux流量控制正是在排列时进行处理和实现的。


图2 流量控制基本框架


    如图2所示,Linux流量控制主要由三大部分来实现:
    ◆ 队列规则(Queue Discipline)
    ◆ 分类(Classes)
    ◆ 过滤器(Filters)

    因此,Linux流量控制主要分为建立队列、建立分类和建立过滤器三个方面。其基本实现步骤为:
    (1)针对网络物理设备(如以太网卡eth0)绑定一个队列;
    (2)在该队列上建立分类;
    (3)为每一分类建立一个基于路由的过滤器。

    流量控制的具体使用

    现在对流量控制(TC)的具体使用做个介绍。首先是TC的总用法。
    TC命令,内核支持需设置QoS support、QoS and/or fair queueing = y。用法为:
    #tc [ OPTIONS ] OBJECT { COMMAND | help }

    其中
    OBJECT := { qdisc | class | filter }
    OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] }

    下面分别介绍TC中队列、分类和过滤器的用法。

    1.TC中队列(qdisc)的用法
    队列的使用中,内核支持需设置QoS support、QoS and/or fair queueing = y。用法为:

      
      
       
       #tc qdisc [ add | del | replace | change | get ] dev STRING
       
       
[ handle QHANDLE ] [ root | ingress | parent CLASSID ]
[ estimator INTERVAL TIME_CONSTANT ]
[ [ QDISC_KIND ] [ help | OPTIONS ] ]
#tc qdisc show [ dev STRING ] [ingress]


    其中

      
      
       
       QDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. }
       
       
OPTIONS := ... try tc qdisc add <desired QDISC_KIND> help


    CBQ队列(qdisc cbq)的使用中,内核支持需设置 QoS support、QoS and/or fair queueing、CBQ packet scheduler、Rate estimator = y,用法为:

      
      
       
       ... cbq bandwidth BPS avpkt BYTES [ mpu BYTES ]
       
       
[ cell BYTES ] [ ewma LOG ]


    2.TC中分类(class)的用法

    分类的使用中,内核支持需设置QoS support、QoS and/or fair queueing、Packet classifier API = y。用法为:

      
      
       
       #tc class [ add | del | change | get ] dev STRING
       
       
[ classid CLASSID ] [ root | parent CLASSID ]
[ [ QDISC_KIND ] [ help | OPTIONS ] ]
#tc class show [ dev STRING ] [ root | parent CLASSID ]


    其中

      
      
       
       QDISC_KIND := { prio | cbq | etc. }
       
       
OPTIONS := ... try tc class add <desired QDISC_KIND> help
&nbsp;&nbsp;&nbsp;&nbsp;TC CBQ分类(class cbq)的用法为:
<ccid_nobr>
<table width="400" border="1" cellspacing="0" cellpadding="2"
bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center">
<tr>
<td bgcolor="e6e6e6" class="code" style="font-size:9pt">
<pre><ccid_code> ... cbq bandwidth BPS rate BPS maxburst PKTS [ avpkt BYTES ]
[ minburst PKTS ] [ bounded ] [ isolated ]
[ allot BYTES ] [ mpu BYTES ] [ weight RATE ]
[ prio NUMBER ] [ cell BYTES ] [ ewma LOG ]
[ estimator INTERVAL TIME_CONSTANT ]
[ split CLASSID ] [ defmap MASK/CHANGE ]


    3.TC中过滤器(filter)的用法

    过滤器的使用中,内核支持需设置QoS support、QoS and/or fair queueing、Packet classifier API = y。用法为:

      
      
       
       #tc filter [ add | del | change | get ] dev STRING
       
       
[ pref PRIO ] [ protocol PROTO ]
[ estimator INTERVAL TIME_CONSTANT ]
[ root | classid CLASSID ] [ handle FILTERID ]
[ [ FILTER_TYPE ] [ help | OPTIONS ] ]
#tc filter show [ dev STRING ] [ root | parent CLASSID ]


    其中

      
      
       
       FILTER_TYPE := { rsvp | u32 | fw | route | etc. }
       
       
FILTERID := ... format depends on classifier, see there
OPTIONS := ... try tc filter add <desired FILTER_KIND> help


    TC U32过滤器(filter u32)的用法:

      
      
       
       ... u32 [ match SELECTOR ... ] [ link HTID ] [ classid CLASSID ]
       
       
[ police POLICE_SPEC ] [ offset OFFSET_SPEC ]
[ ht HTID ] [ hashkey HASHKEY_SPEC ]
[ sample SAMPLE ]
或 u32 divisor DIVISOR


    其中

      
      
       
       SELECTOR := SAMPLE SAMPLE ...
       
       
SAMPLE := { ip | ip6 | udp | tcp | icmp | u{32|16|8} } SAMPLE_ARGS
FILTERID := X:Y:Z


    TC FW过滤器(filter fw)的用法:
    ... fw [ classid CLASSID ] [ police POLICE_SPEC ]

    其中

      
      
       
       POLICE_SPEC := ... look at TBF
       
       
CLASSID := X:Y


 流量控制应用实例

    假设目前某企业面临的是一个复杂的网络环境。在该环境中,既包括了100Mb的局域网,也包括了微波或802.11的无线链路网络,其网络拓扑如图3所示。在这样的环境下,保证业务数据的流量,实现流量控制,需要对各局域网的传输及业务服务进行控制。


图3 企业网络拓扑图



    系统采用Linux 2.2.14版内核来支持QoS。首先需要重新编译内核。运行make config,进行如下设置:

     
     
      
      EXPERIMENTAL _OPTIONS = y
      
      
Class Based Queueing (CBQ) = y
QoS and/or fair queueing = y
CBQ packet scheduler = y
Rate estimator= y
Packet classifier API = y


    编译生成新内核:

      
      
       
       #make dep
       
       
#make clean
#make bzImage


    Linux操作系统中,流量控制器(TC)在输出端口处建立一个队列进行流量控制,控制的方式基于目的IP地址、目的子网的网络号及端口号,或者基于源IP地址、源子网的网络号及端口号。

     流量控制器TC的基本功能模块为队列、分类和过滤器。Linux内核中支持的队列有Class Based Queue、Token Bucket Flow、CSZ、First In First Out、Priority、TEQL、SFQ、ATM、RED。这里讨论的队列与分类都是基于CBQ(Class Based Queue),过滤器则是基于U32和FW。

    配置和使用流量控制器TC,除了建立队列、分类、过滤器和路由外,还需要对现有的队列、分类、过滤器和ipchains进行监视。

    基于如图3所示的网络环境,现对中心流量控制服务器进行简单描述,如图4所示。


图4 中心服务器接口图



    eth1的配置
    假设远端无线网卡(eth1)的IP地址为172.16.32.196,在其上建立一个CBQ队列,控制所有从无线网卡发出的数据包。假设包的平均大小为1000字节,包间隔发送单元的大小为8字节,可接收冲突的发送最长包数目为20字节。

    这里采用源地址及源端口号进行控制。假如有三种类型的流量需要控制:
    ◆ 由本主机发出的业务数据包,源端口为7001:7004,流量带宽控制在100Kb;
    ◆由本地局域网发出的数据包,IP地址为192.168.1.26,流量带宽控制在1.1Mb;
◆发往子网1,子网号为192.168.1.0,子网掩码为255.255.255.0,流量带宽控制在1Mb。

    1.建立队列
    一般情况下,针对一个网卡只需建立一个队列。
    将一个CBQ队列绑定到网络物理设备eth1上,其编号为1:0,实际带宽为10Mb,包的平均大小为1500字节,包间隔发送单元的大小为8字节,最小传输包大小为64字节。
    #tc qdisc add dev eth1 root handle 1:0 cbq bandwidth 10Mbit cell 8 avpkt 1500 mpu 64

    2.建立分类
    分类建立在队列之上。一般情况下,针对一个队列需建立一个根分类,然后在其上建立子分类。对于分类,按其分类的编号顺序起作用,编号小的优先。一旦符合某个分类匹配规则,通过该分类发送数据包,则其后的分类不再起作用。

    (1)创建根分类1:1,分配带宽为10Mb。
    #tc class add dev eth1 parent 1:0 classid 1:1 cbq bandwidth 10Mbit rate 10Mbit allot 1514 cell 8 weight 1Mbit maxburst 1 avpkt 1500 bounded

     该队列的最大可用带宽为10Mb,实际分配的带宽为10Mb,可接收冲突的发送最长包数目为1字节,最大传输单元(加MAC头)大小为1514字节,优先 级别为8,包的平均大小为1500字节,包间隔发送单元的大小为8字节,相应于实际带宽的加权速率为10Mb。

    (2)创建分类1:2,其父分类为1:1,分配带宽为8Mb。
    #tc class add dev eth1 parent 1:1 classid 1:2 cbq bandwidth 10Mbit rate 1200Kbit allot 1514 cell 8 weight 120Kbit maxburst 1 avpkt 1500 bounded isolated

    该队列的最大可用带宽为10Mb,实际分配的带宽为 1.2Mb,可接收冲突的发送最长包数目为1字节,最大传输单元(加MAC头)大小为1514字节,优先级别为1,包的平均大小为1500字节,包间隔发 送单元的大小为8字节,相应于实际带宽的加权速率为120Kb,独占带宽且不可借用未使用带宽。

    (3)创建分类1:10,其父分类为1:2,分配带宽为100Kb。
    #tc class add dev eth1 parent 1:2 classid 1:10 cbq bandwidth 10Mbit rate 100Kbit allot 1514 cell 8 weight 10Kbit maxburst 1 avpkt 1500

     该队列的最大可用带宽为10Mb,实际分配的带宽为 1.2Mb,可接收冲突的发送最长包数目为1字节,最大传输单元(加MAC头)大小为1514字节,优先级别为1,包的平均大小为1500字节,包间隔发 送单元的大小为8字节,相应于实际带宽的加权速率为10Kb。

    (4)创建分类1:20,其父分类为1:2,分配带宽为1.1Mb。
    #tc class add dev eth1 parent 1:2 classid 1:20 cbq bandwidth 10Mbit rate 1100Kbit allot 1514 cell 8 weight 110Kbit maxburst 1 avpkt 1500

     该队列的最大可用带宽为10Mb,实际分配的带宽为 1.1Mb,可接收冲突的发送最长包数目为1字节,最大传输单元(加MAC头)大小为1514字节,优先级别为1,包的平均大小为1500字节,包间隔发 送单元的大小为8字节,相应于实际带宽的加权速率为110Kb。

    3.建立过滤器
    过滤器主要服务于分类。一般只需针对根分类提供一个过滤器,然后为每个子分类提供一个ipchains映射。

    (1)应用FW分类器到分类1:10,父分类编号为1:0,过滤协议为IP,标志号(handle)为4,过滤器为基于ipchains。
    #tc filter add dev eth1 protocol ip parent 1:0 prio 1 handle 4 fw classid 1:10

    (2)应用FW分类器到分类1:20,父分类编号为1:0,过滤协议为IP,过滤器为基于ipchains。
    #tc filter add dev eth1 protocol ip parent 1:0 prio 100 handle 5 fw classid 1:20

    4.建立ipchains映射
    该路由与前面所建立的路由映射一一对应。

    (1)由本机发出的电话数据包通过分类1:10转发(分类1:10的速率100Kb)
    #ipchains -A output -p udp -i tun0 -s 202.168.200.188/32 7001:7004 -t 0x01 0x10 -m 4

    (2)由局域网发出的数据包通过分类1:20转发(分类1:20的速率1.1Mb/s)
    #ipchains -A output -i tun0 -s 192.16.188.0/24 -m 5

    注意,一般对于流量控制器所直接连接的网段,建议使用IP主机地址流量控制限制,不要使用子网流量控制限制。如一定需要对直连子网使用子网流量控制限制,则在建立该子网的ipchains映射前,需将原先由系统建立的ipchains删除,才可完成相应步骤。

    5.监视
    主要包括对现有队列、分类、过滤器和路由状况的监视。

    (1)显示队列的状况
    简单显示指定设备(这里为eth1)的队列状况:

     
     
      
      #tc qdisc ls dev eth1
      
      
qdisc cbq 1: rate 10Mbit (bounded,isolated) prio no-transmit



    详细显示指定设备(这里为eth1)的队列状况:

     
     
      
      #tc -s qdisc ls dev eth1
      
      
qdisc cbq 1: rate 10Mbit (bounded,isolated) prio no-transmit
Sent 7646731 bytes 13232 pkts (dropped 0, overlimits 0)
borrowed 0 overactions 0 avgidle 31 undertime 0



    这里主要显示通过该队列发送了13232个数据包,数据流量为7646731个字节,丢弃的包数目为0,超过速率限制的包数目为0。

    (2)显示分类的状况
    简单显示指定设备(这里为eth1)的分类状况:

     
     
      
      #tc class ls dev eth1
      
      
class cbq 1: root rate 10Mbit (bounded,isolated) prio no-transmit
class cbq 1:1 parent 1: rate 10Mbit prio no-transmit #no-transmit表示优先级为8
class cbq 1:2 parent 1:1 rate 1200Kbit prio no-transmit #no-transmit
class cbq 1:10 parent 1:2 rate 100Kbit prio 1
class cbq 1:20 parent 1:2 rate 1100Kbit prio 6



    详细显示指定设备(这里为eth1)的分类状况:

     
     
      
      #tc -s class ls dev eth1
      
      
class cbq 1: root rate 10Mbit (bounded,isolated) prio no-transmit
Sent 17725304 bytes 32088 pkts (dropped 0, overlimits 0)
borrowed 0 overactions 0 avgidle 31 undertime 0
class cbq 1:1 parent 1: rate 10Mbit prio no-transmit
Sent 16627774 bytes 28884 pkts (dropped 0, overlimits 0)
borrowed 16163 overactions 0 avgidle 587 undertime 0
class cbq 1:2 parent 1:1 rate 1200Kbit prio no-transmit
Sent 628829 bytes 3130 pkts (dropped 0, overlimits 0)
borrowed 0 overactions 0 avgidle 4137 undertime 0
class cbq 1:10 parent 1:2 rate 100KMbit prio 1
Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
borrowed 0 overactions 0 avgidle 159654 undertime 0
class cbq 1:20 parent 1:1 rate 1100Kbit prio no-transmit
Sent 5552879 bytes 8076 pkts (dropped 0, overlimits 0)
borrowed 3797 overactions 0 avgidle 159557 undertime 0



    这里主要显示通过不同分类发送的数据包、数据流量、丢弃的包数目、超过速率限制的包数目等。其中根分类(class cbq 1:0)的状况应与队列的状况类似。

    例如,分类class cbq 1:20发送了8076个数据包,数据流量为5552879个字节,丢弃的包数目为0,超过速率限制的包数目为0。

    (3)显示过滤器的状况

     
     
      
      #tc -s filter ls dev eth1
      
      
filter parent 1: protocol ip pref 1 fw
filter parent 1: protocol ip pref 1 fw handle 0x4 classid 1:10
filter parent 1: protocol ip pref 100 fw
filter parent 1: protocol ip pref 100 fw handle 0x5 classid 1:20



    (4)显示现有ipchains的状况

     
     
      
      #ip ipchains -L
      
      
Chain input (policy ACCEPT):
target prot opt source destination ports
- all ------ anywhere anywhere n/a
- all ------ anywhere anywhere n/a
- udp ------ anywhere anywhere any -> 7001:7004
Chain forward (policy ACCEPT):
Chain output (policy ACCEPT):
target prot opt source destination ports
- all ------ anywhere anywhere n/a
- all ------ anywhere anywhere n/a
- udp ------ anywhere anywhere 7001:7004 -> any
- udp ------ anywhere anywhere 7001:7004 -> any



    6. 维护
    主要包括对队列、分类、过滤器和路由的增添、修改和删除。

    增添动作一般依照队列→分类→过滤器→ipchains的顺序进行;修改动作没有什么特殊要求;删除则依照ipchains→过滤器→分类→队列的顺序进行。

    这里采用的方法是全部删除,然后重新设置。删除命令如下:

     
     
      
      #tc qdisc del root dev eth1
      
      
#ipchains -F



    eth0的配置
    eth0的配置与eth1的配置方法一样。配置如下(说明略):

     
     
      
      #tc qdisc del root dev eth0
      
      
#tc qdisc add dev eth0 root handle 1: cbq bandwidth
10Mbit cell 8 avpkt 1500 mpu 64
#tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth
10Mbit rate 10Mbit allot 1514 cell 8 weight 1Mbit prio 8
maxburst 1 avpkt 1500 bounded
#tc class add dev eth0 parent 1:1 classid 1:10 cbq bandwidth
10Mbit rate 1.4Mbit allot 1514 cell 8 weight 140Kbit prio 8
maxburst 1 avpkt 1500 bounded isolated
#tc filter add dev eth0 protocol ip parent 1:0 prio 100 handle 3 fw classid 1:10
#ipchains -A output -i eth0 -d 0.0.0.0/0 -m 3



    通过对企业流量控制服务器的分析,可以对Linux系统进行简单改造,以实现对一些特殊业务的流量预分配和业务保证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值