# VPP 带宽控制分析 ## 1 Qos 原理介绍 QoS(Quality of Service,服务质量)是有效管理网络资源的技术。在有限的带宽资源下,它允许不同的流量不平等地竞争网络资源,语音、视频和重要的数据应用在网络设备中可以优先得到服务。S系列交换机支持配置基于差分服务模型(DiffServ,Differentiated Services)的QoS业务。DiffServ模型的基本原理是将网络中的流量分成多个类,每个类享受不同的处理,尤其是网络出现拥塞时不同的类会享受不同级别的处理。 ![image-VPP_classify_policer_qos](../../_static/VPP_classify_policer_qos.png) - 分类:将数据分为不同的类别,称为分类(classification),分类并不修改原来的数据包。 - 标记:将数据设置为不同的优先级称为标记(marking),而标记会修改原来的数据包。 - 流量计量:流量计量可以通过漏桶算法(常用于ATM网络)或令牌桶算法(常用于IP网络)实现。计量后的数据包会根据不同的整形类别分别保存在缓冲区中,待满足对应的流量资料后再进行发送。 - 流量管制:丢弃超出带宽,称为管制(Policing)。 - 流量整形:将超出的带宽缓存在内存中,等到下一秒再传递,这种行为称为Shaping。典型作用是限制流出某一网络的某一连接的流量与突发,使这类报文以比较均匀的速度向外发送,以符合种给定的“流量资料”(traffic profile)。 - 队列调度机制:在QoS技术体系中属于拥塞管理的范畴。 - 拥塞管理:当网络发生拥塞后,数据还是要被传递的,正因为接收到的数据远多于自身的传输能力,所以数据被传输时就出现了先后顺序,而依照什么样的方式来传数据,就需要队列的指导,QOS中的队列定义了数据包被传输的先后顺序。如果处理方式为管制,那么数据包就会被丢弃,通常情况下,网络设备默认丢弃后到的数据包而传输先到的数据包,这样的丢弃方式称为尾丢弃。 ## 2 带宽控制命令 概念: table- 依据协议区分的类(目前仅支持 ip4 、 ip6 、 l2 ); policer 限速规则; session 匹配条件。 1、配置限速策略; ```bash configure policer [name] |> # para1: name # para2: color-aware # para3: rate 1.kbps 2.pps # para4: cir belong to kbps # para5: eir belong to kbps # para6: cb belong to kbps # para7: eb belong to kbps # para8: round 1.closest 2.up 3 down # para9: type 1.1r2c 2.1r3c 3.2r3c-2698 4.2r3c-4115 5.2r3c-mef5cf1 # para10: 1.conform-action 2.exceed-action 3.violate-action # para11: 1.drop 2.transmit 3.mark-and-transmit ``` 2、创建匹配规则表; ```bash classify table [miss-next|l2-miss_next|acl-miss-next ] mask buckets [skip ] [match ] [current-data-flag ] [current-data-offset ] [table ] [memory-size [M][G]] [next-table ] [del] [del-chain] # para1: del # para2: del-chain # para3: buckets 该参数被分类器的哈希算法使用。推荐的值是预期条目的近似大小。 # para4: skip 应用掩码之前要跳过的16字节向量的数量。 # para5: match 定义要匹配的实际值,即字节向量,长度是16个字节的倍数 # para6: table 如果指定 n 是修改,不指定 n 是新增 # para7: mask 1.hex # 2.l2 参数: src dst proto tag1 tag2 ignore-tag1 ignore-tag2 cos1 cos2 dot1q dot1ad # 3.l3 参数: ip4 参数: version hdr_length src/%d dst/%d proto (%d 表示掩码长度 ) # l3 参数: ip6 参数: version traffic-class flow-label src dst proto # 4.l4 参数: tcp 参数 src dst # l4 参数: udp 参数: src_port dst_port # l4 参数: src_port # l4 参数: dst_port # para8: memory-size 分类表及其条目的内存大小 # para9: next-table 下一个分类表,当存在多个表链时使用 # para10: miss-next 当数据包无法找到匹配项时被发送的node # para11: l2-input-miss-next # para12: l2-output-miss-next # para13: acl-miss-next # para14: current-data-flag # para15: current-data-offset ``` 查看 table : table 中包含 policer , policer 中包含 session ```bash show classify tables [index ] [verbose ] # index: 0 - ip4-table # 1 - ip6-table # 2 - l2-table ``` 3、往规则表中添加规则; ```bash classify session [hit-next|l2-hit-next|acl-hit-next |policer-hit-next ] table-index match [hex] [l2] [l3 ip4] [opaque-index ] [action set-ip4-fib-id|set-ip6-fib-id|set-sr-policy-index ] [del] # table-index: 必须是已经有的 table index ,如果存在,则会将规则和 ``` 4、将策略应用到接口,该命令将会把 policy 节点添加到接口的节点图中,仅支持 ip4 、 ip6 和 l2 三种类型 classify 节点。 ```bash set policer classify interface [ip4-table ] [ip6-table ] [l2-table ] [del] ``` 查看 classify policer 内容: ```bash show classify policer type [ip4|ip6|l2] ``` ## 3 带宽控制节点分析 vpp 带宽控制相关参数通过 vppctl 进行配置;当数据流经过节点 ip4-policer-classify 时,如果命中控制规则,则带宽控制生效。 节点流程图: ![image-VPP_classify_policer_node](../../_static/VPP_classify_policer_node.png) ip4-policer-classify 处理流程: ```bash # file: vnet/policer/node_funcs.c ip4_policer_classify_node |_ policer_classify_inline |_ sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; # 获取接口 index |_ table_index0 = pcm->classify_table_index_by_sw_if_index[tid][sw_if_index0]; # 获取 table index |_ if (PREDICT_TRUE (table_index0 != ~0)) # 找到了 table index |_ act0 = vnet_policer_police # 查找 policer 获取操作返回值 |_ if (PREDICT_FALSE (act0 == SSE2_QOS_ACTION_DROP)) # 如果时丢弃操作,则相应赋值 |_ hits++; # 统计命中个数 # vnet_policer_police vnet_policer_police |_ vnet_police_packet # struct: policer_read_response_type_st |_ vnet_policer_mark ``` ## 4 相关结构体 1、table、session、policer ![image-VPP_classify_policer_classify_table](../../_static/VPP_classify_policer_classify_table.png) classify_table 表: `interface` - `sw_if_index` : 接口编号。如指代 GigabitEthernet0/5/0 等。 `protocol` : 目前只支持 ip4 、 ip6 、 l2 三项。 `table` : 值为 table_index ,指向 table 链中的某一个 table 作为 table 链的起点,如果所指向的 table 中 next_table 指针指向其他 table ,则 classify_table 中的该单元是一个 table 链;如果 next_table 没有指向,则该单元是一个单独的 table 。 一个 interface 对应一个 sw_if_index ,每个 sw_if_index 在每种 protocol 中只有一个 table_index ,该 index 是一个起始地址,可以通过 next_table 指针链接其他 table ,当数据包经过节点时,根据协议,从 table_start_index 开始依据 next_table 指针依次遍历,如果命中 table 中的 session 规则,则执行 policer 限速规则。 table 链: 类型有 ip4、 ip6、 l2 三种。 `next_table` : table 之间除了 index 值,并没有严格的链表关系,但可以通过 next_table 指针使节点遍历多个 table 。 `session` : 包含命中字段信息(如3层有 ip 地址,4层有端口等),该信息需要和 table 中的掩码字段进行相与操作得到最终命中字段, session 建立时需要关联 policer 。table 中包含多个 session ,指明了命中规则;每个 session 关联一个 policer ,一个 policer 可以被多个 session 关联。 `policer` : 指明了限速规则和操作。 2、filter、session、flow `filter` : 在创建时也会建立一个表,本质上就是一个 classify_table 表,但最终 session 关联的不是 policer 而是 flow ,其运行原理与上述 classify_table 相似,只是不是完成限速功能,而是过滤及操作(保存、丢弃)的功能。