P4语法(2) Parser
这里参考学习了:
Parser
关于parser
在P4程序中,有着大量的首部(header)和首部实例,但每次只有部分首部实例会对数据包进行操作,而parser会用于生成描述数据包进行哪些匹配动作操作的中间表示(Intermediate Representation),这些解析后表示规定了对数据包生效的实例,可以认为是一组对数据包生效的实例的集合。
p416中的parser
不同于p414,不需要定义多个parser,并在多个parser间切换,只需要定义一个parser,并在parser中写不同的状态(state),通过accept(接受)和reject(拒绝)决定parser是否成功解析一个包。
类型声明
参数中至少有一个参数packet_in,表示处理的接受数据包。输出内容可以是struct或者一般的封包参照。
1 parser parsername(packet_in pkt,out ...)
其起始方式依然以start开始:
1 parser parsername(packet_in pkt,out ...){ 2 3 state start{ 4 ... 5 } 6 7 state state_name{ 8 ... 9 } 10 }
对于其中常用的关键字语法:
- extract:将目前的packet以特定的header取出来,取出来的各部分长度以header定义的为主。
- select:类似于c中的switch case语法,取决于参数通过transition关键字决定接下来的跳转方向,另一个parser state 或 control function。
- transition:在不同的state之间切换。
这里给出一个以太网ipv4的parser例子:
1 parser parser_ipv4(packet_in pkt,out eth,out ipv4){ 2 3 state start{ 4 transition eth;//先转至以太网部分处理。 5 } 6 7 state eth{ 8 pkt.extract(eth); 9 //根据以太网首部类型判断,除了ipv4以外的都抛出。 10 transition select(eth.ethType){ 11 0x0800:i4; 12 _:reject;//其余情况拒绝抛出。 13 } 14 } 15 16 state i4{ 17 pkt.extract(ipv4); 18 transition accept;//接受 19 } 20 }
对于ipv6也是一个类似的逻辑:
1 parser parser_ipv6(packet_in pkt,out eth,out ipv4){ 2 3 state start{ 4 transition eth; 5 } 6 7 state eth{ 8 pkt.extract(eth); 9 transition select(eth.ethType){ 10 0x86DD:i6; 11 _:reject;//其余情况拒绝抛出。 12 } 13 } 14 15 state i6{ 16 pkt.extract(ipv6); 17 transition accept;//接受 18 } 19 }