P4 学习笔记(1)-- P4程序的构成、基本组件


我们在所有的P4程序中(.p4文件),都可以发现其拥有5个基本组件:

  • 首部(Headers):定义报文头部格式
  • 解析器(Parsers):定义数据包解析流程的有限状态机
  • 表(Tables):定义匹配域以及对应的执行动作
  • 动作(Action):动作指令集,包括构造查找键(Construct lookup keys)、根据查找键查表、执行动作等
  • 流控制程序(Controller):控制程序,决定了数据包处理的流程,比如如何在不同表之间跳转等

接下来将就这5个方面进行简要介绍。

首部(Headers)

       首部分为两种,一种是包头(Packet Header),一种是元数据(Metadata)。在首部区域除了定义这些结构,还需要进行实例化操作。

  • 包头
           以ipv4的包头为例,根据下图所示的ipv4结构,
       可定义其包头的基本格式如下:
header ethernet_t {
    macAddr_t dstAddr;
    macAddr_t srcAddr;
    bit<16>   etherType;
}
header ipv4_t
{
	bit<4> version;
	bit<4> ihl;
	bit<8> diffserv;
	bit<16> totallen;
	bit<16> identification;
	bit<3> flags;
	bit<13> fragoffset;
	bit<8> ttl;
	bit<8> protocol;
	bit<16> hdrchecksum;
	bit<32> srcaddr;
	bit<32> dstaddr;
} 
  • 元数据
           元数据用来携带数据和配置信息,元数据的声明与包头类似,但在实例化时不同,而且包头和元数据在字段值的约束上存在一定的差别。
           元数据分为两种,一种是用来携带P4程序运行过程中产生的数据的用户自定义元数据(User-Defined Metadata),如首部字段的运算结果等。另一种是固有元数据(Intrinsic Metadata),用于携带交换机自身的配置信息,如数据包进入交换机时的端口号等。
           关于V1Modeld的元数据如下图所示,其中常见的:ingress_port表示数据包的入端口;egress_spec表示指定数据包的出端口(在入口流水线中设置);egress_port表示数据包离开的端口(在出口流水线中设置)。在使用时,可以直接使用,无需提前自定义。
  • 实例化
    具体的实例化例子如下所示:
struct headers {
    ethernet_t   ethernet;  //ethernet_t 和 ipv4_t 都是之前定义的包头
    ipv4_t       ipv4;
}

 

解析器(Parsers)

       一个P4程序中往往定义了大量的首部和首部实例,但并不是所有的首部实例都会对数据包进行操作。解析器工作时会生成描述数据包进行哪些匹配+动作操作的中间表示,在P4中称之为解析后表示,这些解析后表示规定了对数据包生效的实例,是一组对数据包生效的实例的集合。
       P4语言中解析器采用有限状态机的设计思路,每个解析器方法视为一种状态。当解析器工作时,会将当前处理的数据包头字节的偏移量记录在首部实例中,并在状态迁移(调用另一个解析器)时指向包头中下一个待处理的有效字节。
       针对上述的以太网和ipv4的头部定义,对应解析过程如下,其中transition即表示状态转移过程。

parser MyParser(packet_in packet,
                out headers hdr,
                inout metadata meta,
                inout standard_metadata_t standard_metadata) {

    state start {
        transition parse_ethernet;
    }

    state parse_ethernet {
        packet.extract(hdr.ethernet);
        transition select(hdr.ethernet.etherType) {
            TYPE_IPV4: parse_ipv4;
            default: accept;
        }
    }

    state parse_ipv4 {
        packet.extract(hdr.ipv4);
        transition accept;
    }

}

表(Tables)

       定义了匹配字段(key)、可选的动作(action)和一些其他相关属性。

    table ipv4_lpm {
        key = {
            hdr.ipv4.dstAddr: lpm;
        }
        actions = {
            ipv4_forward;
            drop;
            NoAction;
        }
        size = 1024;
        default_action = drop();
    }

       在上述例子中,对于匹配字段的匹配方式,有如下几种:

  • lpm:最长前缀匹配
  • exact:精确匹配
  • ternary:三元匹配
           除了匹配字段和对应可选动作以外,表中还可以定义了一些其他属性,例如上述例子中的default_action等,相关属性与功能如下表。
其他属性功能
default_action当table miss的时候执行的动作
counters计数器
implementation指定表实际运作方式,这部分通常取决于架构,例如v1model中action profile提供了通过hash的方式随机选择一个action profile member去执行。
size表的大小
const entries预设的table entry,在编译阶段会写到编译好的档案中

动作(Action)

       动作会在表中被引用,可以读取控制平面提供的数据,指导数据平面的工作。

action ipv4_forward(macAddr_t dstAddr, egressSpec_t port)
{
standard_metadata.egress_spec = port;
hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
hdr.ethernet.dstAddr = dstAddr;
hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
}

流控制程序(Controller)

       可以把control block认为是流水线操作的一个模板,v1model中就是ingress和egress,其主要的功能就是知道每一个封包经过的table顺序以及采用的规则(触发条件等)。还能放置一些其他的功能部件,例如计数器counter等。

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值