configure policer name policy1 cir 800 cb 9000 rate kbps round closest type 1r2c conform-action transmit exceed-action drop classify table mask l3 ip4 src classify session policer-hit-next policy1 exceed-color table-index 0 match l3 ip4 src 192.168.2.2 set policer classify interface vmxnet3-0/1b/0/0 ip4-table 0
vpp的限速功能由policer模块实现。可以配置不同的限速算法,代码在/src/vnet/policer目录下
vpp的policer有四个node,分别是
l2-policer-classify ip4-policer-classify ip6-policer-classify policer-input
1.将policer应用到某一个worker线程上:
policer_bind Associate/disassociate a policer with a worker thread
2.将policer应用在某一个接口上:
policer_input Apply policer as an input feature
3.配置不同的限速算法和参数,add/del:
policer_add_del
4.显示当前配置的policer:
policer_dump
api配置的参数列表
@param name - policer name 策略名字,全局唯一。后续api传入的参数都是这个名字。vpp会返回一个index
@param cir - CIR 令牌桶参数,
@param eir - EIR 令牌桶参数
@param cb - Committed Burst 令牌桶参数
@param eb - Excess or Peak Burst 令牌桶参数
@param rate_type - rate type kps/bps
@param round_type - rounding type
@param type - policer algorithm 策略算法类型
@param color_aware - 0=color-blind, 1=color-aware
@param conform_action - conform action
@param exceed_action - exceed action type
@param violate_action - violate action type
policer内部结构体
typedef enum { QOS_ACTION_DROP = 0, QOS_ACTION_TRANSMIT, QOS_ACTION_MARK_AND_TRANSMIT, QOS_ACTION_HANDOFF } __clib_packed qos_action_type_en; /* * edt * struct qos_pol_action_params_st * This structure is used to hold user configured police action parameters. * * element: action_type * Action type (see qos_action_type_en). * element: dscp * DSCP value to set when action is QOS_ACTION_MARK_AND_TRANSMIT. */ typedef struct qos_pol_action_params_st_ { qos_action_type_en action_type; ip_dscp_t dscp; } qos_pol_action_params_st; /* * edt: * struct qos_pol_cfg_params_st * * Description: * This structure is used to hold user configured policing parameters. * * element: cir_kbps * CIR in kbps. * element: eir_kbps * EIR or PIR in kbps. * element: cb_bytes * Committed Burst in bytes. * element: eb_bytes * Excess or Peak Burst in bytes. * element: cir_pps * CIR in pps. * element: eir_pps * EIR or PIR in pps. * element: cb_ms * Committed Burst in milliseconds. * element: eb_ms * Excess or Peak Burst in milliseconds. * element: rate_type * Indicates the union if in kbps/bytes or pps/ms. * element: rfc * Policer algorithm - 1R2C, 1R3C (2697), 2R3C (2698) or 2R3C (4115). See * qos_policer_type_en * element: rnd_type * Rounding type (see qos_round_type_en). Needed when policer values * need to be rounded. Caller can decide on type of rounding used */ typedef struct qos_pol_cfg_params_st_ { union { struct { u32 cir_kbps; u32 eir_kbps; u64 cb_bytes; u64 eb_bytes; } kbps; struct { u32 cir_pps; u32 eir_pps; u64 cb_ms; u64 eb_ms; } pps; } rb; /* rate burst config */ qos_rate_type_en rate_type; qos_round_type_en rnd_type; qos_policer_type_en rfc; u8 color_aware; u8 overwrite_bucket; /* for debugging purposes */ u32 current_bucket; /* for debugging purposes */ u32 extended_bucket; /* for debugging purposes */ qos_pol_action_params_st conform_action; qos_pol_action_params_st exceed_action; qos_pol_action_params_st violate_action; } qos_pol_cfg_params_st;
vpp将api传入的参数转为内部结构体,然后加入到vnet_policer_main中。后续调用vnet_policer_policy函数来对报文进行action判断。
将策略应用到某一个接口上。
/** \brief policer input: Apply policer as an input feature. @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param name - policer name @param sw_if_index - interface to apply the policer @param apply - Apply/remove */ autoreply define policer_input { u32 client_index; u32 context; string name[64]; vl_api_interface_index_t sw_if_index; bool apply; };
具体实现就是调用
vnet_feature_enable_disable("device-input", "policer-input", sw_if_index, apply, 0, 0);
来使能policer-input node。
VNET_FEATURE_INIT (policer_input_node, static) = { .arc_name = "device-input", .node_name = "policer-input", .runs_before = VNET_FEATURES ("ethernet-input"), };
policer-input node注册在device-input arc中,运行在ethernet-input node之前
将策略绑定到某一个worker线程上,在vnet_policer_policy函数中会检查策略的thread-index是否和当前thread-index相同,不同则直接返回,不应用策略
代码在/src/vnet/classiy目录
vpp的classifier是性能和容量的调和产物。某种意义上,vpp classifier是一个dumb rebot。输入一个报文,去查找一个(mask,match)的列表。如果发现了一个entry,就执行相应的action。如果没有匹配,则执行最后一个action。
vpp一次使用16个字节去匹配。也就是说匹配的最小单位长度为16个字节。
对源IP地址为30.1.1.100、30.1.1.101、30.1.1.102以及30.1.1.103的数据包进行过滤。(使用mask l3 ip和match l3 ip)
# classify table mask l3 ip4 src buckets 16 # classify session acl-hit-next deny opaque-index 0 table-index 0 match l3 ip4 src 30.1.1.100 # classify session acl-hit-next deny opaque-index 1 table-index 0 match l3 ip4 src 30.1.1.101 # classify session acl-hit-next deny opaque-index 2 table-index 0 match l3 ip4 src 30.1.1.102 # classify session acl-hit-next deny opaque-index 3 table-index 0 match l3 ip4 src 30.1.1.103 # set int input acl intfc GigabitEthernet13/0/0 ip4-table 0
对源IP地址为30.1.1.100以及源UDP端口为200的数据包进行过滤,使用mask hex和match hex
# classify table mask hex 0000000000000000000000000000000000000000000000000000ffffffff00000000FFFF # classify session acl-hit-next permit opaque-index 0 table-index 0 match hex 00000000000000000000000000000000000000000000000000001e0101640000000000c8 # set int input acl intfc GigabitEthernet13/0/0 ip4-table 0
如果需要匹配多个项,可以使用hex方法,如果是匹配单一项,可以直接使用l3 ip4或者l3 ip6等
增加或者删除一个classify table
向table中增加一个entry
{
u32 client_index;
u32 context;
bool is_add;
u32 table_index;
u32 hit_next_index [default=0xffffffff]; policy-index
u32 opaque_index [default=0xffffffff];
i32 advance [default=0];
vl_api_classify_action_t action [default=0];
u32 metadata [default=0];
u32 match_len;
u8 match[match_len];
};
如果是想把这个entry应用在policy上,那么hit_next_index传入policer-index
将policer_classify设置在某个接口上,使能ip4-policer-classify或者ip6-policer-classify节点
{
u32 client_index;
u32 context;
vl_api_interface_index_t sw_if_index;
u32 ip4_table_index; 传入第一个api中返回的classify_table_index
u32 ip6_table_index;
u32 l2_table_index;
bool is_add;
};
对于ip4的policer classify来说,classify和policy操作都是在ip4-policer-classiy node进行处理。这个node会在ip4-lookup之前。如果找到对应的entry,则会将设置classify session时传入的hit-next-index当做policy-index来进行policy操作
将flow_classify设置在某个接口上。使能ip4-flow-classify或者ip6-flow-classify节点.
flow_classify_set_interface
flow_classify_dump
classify_set_interface_ip_table
classify_set_interface_l2_tables
output_acl_set_interface
classify_pcap_lookup_table
classify_pcap_set_table
classify_pcap_get_tables
classify_trace_lookup_table
classify_trace_set_table
classify_trace_get_tables
policer_classify 查找classify entry,然后执行policer,判断
flow_classify
classify应用在不同的场景下
1. policer-hit-next + policy name
2.hit-next ip4-classify node,ip6-classify node
3.l2-input-hit-next l2-input-classify node
4.l2-output-hit-next l2-output-classify node
3.acl-hit-next
对于不同的hit-next,next值和opaque-index代表的含义是不同的。
classify session policer-hit-next policy1 exceed-color table-index 4 match l3 ip4 src 10.86.108.166 l4 dst_port 55001
set policer classify interface eth0 ip4-table 4 只能将一个table应用在接口上,但是table可以级联,table 0中的next table index可以和其他table级联