基于交换芯片的五元组过滤功能

来源:互联网 发布:java上下文 编辑:程序博客网 时间:2024/04/29 09:26
基于交换芯片的五元组的PCL规则过滤功能作者: 韩大卫@吉林师范大学2012.12.10Not Approved by Document ControlReview Copy Only基于Marvell 98DX51xx/81xx交换芯片的五元组等的策略规则(PCL)过滤功能.现将部分的功能的底层实现予以简单介绍.Contact author for detailed information: handawei@jusontech.comForward:Marvell对PCL概念的定义是:The Policy engine performs per-flow processing of packets received and  transmitted by the device.A packet can be bound to one or more sets of policy rules, which we call Policy Control Lists (PCL).PCL:策略控制列表.可以理解为在交换芯片上实现的过滤规则列表.有一种类似的概念叫ACL.ACL:Access Control List . 访问控制列表一般来讲,ACL是用户层上下发的规则, 最终通过交换芯片或CPU来实现的,是一种用户层上定义的规则.PCL是底层的概念, 是交换芯片内部对此功能的定义,驱动工程师在操作系统底层软件提取出此交换芯片的PCL过滤功能(比如根据五元组,根据VLAN-ID, 根据是否ARP报文等等),封装成API类库供用户层使用, 用户层就可以综合使用这些API做成一条条过滤规则.PCL是交换芯片较高级的功能,一般普通的二层/三层交换机的使用的低端交换芯片是没有的此功能的.很多网络安全设备(如防火墙,分流器等)的一部分实现也是基于此机制.根据Marvell的datasheet, PCL对报文的处理是在L2/L3/L4之前,即       Ingress EgressPacket   -------------->    PCL     ----->  L2    ------> L3 -------> L4 ...-------------->  报文 首先经过IPCL(Ingress PCL) Engine  处理, 根据报文的类型和PCL-ID生成一张IPCL Table , 此表的数据结构大致为:9bit---0bit  PCL-ID..29bit---18bit   VID..49bit---42bit  Ip Protocol..130bit---99bit  SIP[4]162bit---131bit  DIP[4]...完成此IPCL table后, 拿此表在TCAM中进行查找匹配, 匹配成功的条件是: 首先要PCL-ID相同, 如果规则制定了过滤条件, 那么依次匹配自定义的成员, 例如: 如想过滤出报文中VID为100的,那么只有IPCL table中VID位置为100 的数据结构(即相应的报文)可以被筛选出来, 进而执行TCAM中此表对对应的ACTION.从而完成了一次PCL过滤.根据以上描述, 可以这样定义一个数据结构用来作为函数参数, 传递用户层的PCL指定规则以下是PCL动作部分的定义, 关于IPCL Table等部分的制作略.typedef struct  sw_pcl_action {    BOOL_T                      enable;    uint32_t                index;//规则编号    uint16_t                pclid;//PCL-ID    pcl_rule_key_t      pcl_key;    //过滤依据    pcl_rule_action_t           pcl_action;       //动作描述}sw_pcl_action_t;                                                                                                                 index即为TCAM查表做匹配时要匹配的表的编号.一个index编号为一条PCL规则, 有多少规则就需要执行多少次匹配查找.其中,typedef struct pcl_rule_key {    char                    sip[4];//源ip地址    uint8_t                 smask;//源ip地址掩码    char                   dip[4];    uint8_t                 dmask;    uint16_t               sport;               //源端口号    uint16_t               spmask;//掩码    uint16_t               dport;          uint16_t               dpmask;    uint8_t                protocol;         //协议号    uint8_t                 tag;    uint16_t                vid;//VID....}pcl_rule_key_t; typedef struct  pcl_rule_action {        uint32_t               intf_id;//出接口    pcl_action_cmd_type     intf_cmd;//动作类型    InterFace_Type          intf_type;//接口类型}pcl_rule_action_t;      //动作类型typedef enum {    PCL_ACT_FOR = 0,//默认转发    PCL_ACT_DROP,//丢弃    PCL_ACT_NOT//不做动作}pcl_action_cmd_type; //接口类型typedef enum {    PCL_INTF_PORT = 0,//默认是端口    PCL_INTF_VLAN,//VLAN    PCL_INTF_TRUNK,//trunk    PCL_INTF_DEV,...    PCL_INTF_VIDX,    PCL_INTF_INDEX, ....}InterFace_Type; 常用的过滤有如下:基于五元组, 即基于源IPv4地址,源端口号,目的IPv4地址,目的端口号,协议号.基于报文本身是否有tag.基于报文本身的VLAN-ID.基于报文是否为ARP报文.基于报文是否为IP报文.基于报文是否为IPv4/v6报文.基于报文是否有分片.如果使用VID子作为过滤条件, 此VID为进过PVID处理后, 报文此时携带的tag中的VLAN-ID.将VID装入 pcl_action.pcl_key.vid , 通过msg发送至底层驱动.底层函数解析出此vid,将其赋值给配置寄存器的数据结构.  mask->ruleStdIpv4L4.common.vid                  = 0xffff;pattern->ruleStdIpv4L4.common.vid               = key_info.vid;理论上此VLAN-ID可配合掩码使用,实现过滤指定范围内的VLAN-ID. 但此功能目前尚未提供.可参考后面端口号 + 掩码部分.基于五元组的过滤可以使用掩码.说明如下:如果使用基于源IP地址 + 掩码作为过滤条件, 如192.163.10.10/24需要将192.163.10.10 分成四个uint8_t 类型的数值, 装在 uint8_t key_info.sip[4] 中. 最后, 将此key_info.sip [] 封装到一个数据结构msg中, 通过socket发送到底层驱动,底层函数收到此msg, 解析出key_info.sip [] 的成员, 将4个成员以网络字节序分步填充一个uint32_t类型的成员.   pattern->ruleStdIpv4L4.sip.u32Ip  |= (key_info.sip[0] & 0xff) << 24;    pattern->ruleStdIpv4L4.sip.u32Ip  |= (key_info.sip[1] & 0xff) << 16;                                                           pattern->ruleStdIpv4L4.sip.u32Ip  |= (key_info.sip[2] & 0xff) << 8;   pattern->ruleStdIpv4L4.sip.u32Ip  |= (key_info.sip[3] & 0xff) << 0;             note :key_info.sip[]承载的是此IP地址, 即192.163.10.10pattern->ruleStdIpv4L4.sip.u32Ip  就是底层需要填充的uint32_t成员, 配置交换芯片寄存器时,依赖的即此变量与mask部分中对应变量的按bit相与的结果.同时, 需要将掩码24也传至底层, 填充u32Ip同时配置一个相应的uint32_t mask 的掩码. mask->ruleStdIpv4L4.sip.u32Ip = ~0<<(32 - key_info.smask);    (如果key_info.smask 为24, 得出结果为: 0xffffff00)note : key_info.smask 承载的是此IP地址的掩码, 即24.mask->ruleStdIpv4L4.sip.u32Ip 是需要配置的掩码, 配置交换芯片寄存器时, 需要将pattern部分与此mask的相应部分按bit相与, 其结果为寄存器真正的有效位.最后还要:pattern->ruleStdIpv4L4.sip.u32Ip &= mask->ruleStdIpv4L4.sip.u32Ip;要保证mask为0 的部分 pattern的也为0 .例:如 mask->ruleStdIpv4L4.sip.u32Ip 为 0xffffff00 (mask 为24) ,pattern->ruleStdIpv4L4.sip.u32Ip 为  0xc0a30a0a( IP为 192.163.10.10)那么pattern->ruleStdIpv4L4.sip.u32Ip最后需要变为 0xc0a30a00.使用目的IP地址 + 掩码 作为过滤的判定条件, 如 192.163.10.20/24则将192.163.20.10 分成四个uint8_t 类型的数值, 装在 uint8_t key_info.dip[4]中, 其他原理同上. 使用源端口号作为过滤判定条件, 如 200 .  需要将此数值 传入uint16_t类型的key_info.sport.  通过msg发送出去, 在底层, 将此值拆成两个uint8_t 数值, 按网络字节序传入 pattern->ruleStdIpv4L4.l4Byte1和 pattern->ruleStdIpv4L4.l4Byte0中. 其对应的掩码使用0xff.     mask->ruleStdIpv4L4.l4Byte1          = 0xff;        pattern->ruleStdIpv4L4.l4Byte1       = (GT_U8)(key_info.sport & 0xff);                                                 mask->ruleStdIpv4L4.l4Byte0           = 0xff;        pattern->ruleStdIpv4L4.l4Byte0        = (GT_U8)(key_info.sport >> 8);                                                        使用协议号作为过滤判定条件, 将数值传入 key_info.protocol,底层驱动中填入mask和pattern的如下部分.        mask->ruleStdIpv4L4.commonStdIp.ipProtocol      = 0xff;        pattern->ruleStdIpv4L4.commonStdIp.ipProtocol   = key_info.protocol;使用目的端口号作为过滤的判定条件, 将数值传入key_info.dport, 其他原理同上.************** ************************************以下部分与驱动无关,可以略过.***************** *********************************使用一段范围的源端口号作为过滤的判定条件,  如 80-8080.需要使用一个或多个配合端口号的掩码共同使用.简单的应用例子:源端口号64-65535,即大于源端口号大于等于64的范围内作为过滤判定条件.64 的二进制 为:  0000 0000 0100 0000那么需要的掩码为: 1111 1111 1100 0000 即0xffc0令  key_info.sport= 64;key_info.spmask= 0xffc0;在底层:     mask->ruleStdIpv4L4.l4Byte1          = (GT_U8)(key_info.spmask & 0xff);         pattern->ruleStdIpv4L4.l4Byte1       = (GT_U8)(key_info.sport  & 0xff);                                                 mask->ruleStdIpv4L4.l4Byte0           = (GT_U8)(key_info.spmask >> 8);         pattern->ruleStdIpv4L4.l4Byte0        = (GT_U8)(key_info.sport  >> 8);                                                        如果源端口号的二进制中1的bit为多个, 那么需要多个mask来配合使用. 即多个PCL规则配合使用.如: value = 80   根据特定算法, 可以得出一下几个mask:80:0000 0000 0101 0000mask1:  1111 1111 1000 0000   mask2:  0000 0000 0110 0000mask3:  0000 0000 0101 0000note:文档附录中包含此计算掩码数组的函数pattern1:1000 0000 0000 0000pattern1:0100 0000 0000 0000pattern1:0010 0000 0000 0000pattern1:0001 0000 0000 0000pattern1:0000 1000 0000 0000pattern1:0000 0100 0000 0000pattern1:0000 0010 0000 0000pattern1:0000 0001 0000 0000pattern1:0000 0000 1000 0000pattern2:0000 0000 0110 0000pattern3:0000 0000 0101 0000note: 如果(x & mask )== pattern  ,那么这是一次成功匹配.每个mask均有相同的转发规则, 报文依次匹配mask1,mask2,mask3 , 命中任一个mask,说明报文的源端口号大于或等于80.执行PCL的设定的转发动作, 如果都没有匹配成功, 不在次范围内, 不执行次系列的PCL转发规则.由于通过掩码的方式只能判断出一个数是否在一个值之上,即是否大于或等于一个数,因此,在处理一个范围的上限时, 需要对PCL的动作进行设定, 即, 当判断出一个数大于此范围的最大值时, 需要对其执行丢弃或不执行此系列的PCL转发规则处理.例: 过滤出源端口号为: 80-8000范围内的报文,执行PCL动作1.实现此功能分两步 可以使用比较器, marvell xcat DX3支持8个比较器, 通过设置端口号范围的上,下限即刻过滤出一段范围的端口号
原创粉丝点击