P4模型
这是P4中提供的最简单最易理解的编程结构,V1Model。可以看到它由5个模块组成,他们的名字分别是(从左到右):
• Parser: 解析器, 解析并且提取数据包头的各个字段。
• Ingress: Ingress处理,在这里定义Ingress流水线。
• TM: Traffic manager,有一些队列,用于流量控制(一些队列相关的metadata在此更新)。
• Egress: Egress, 在这里定义Egress流水线。
• Deparser:用于重组数据包,因为数据包在处理过程中经历了分解和处理。所以最后转发的时候需要重组一下。
P4语言代码结构
/*导入库部分*/
#include<core.p4>
#include<v1model.p4>
/*数据格式定义部分*/
header ethernet_t{
bit<48> dst_addr; //根据各个字段的长度等信息,定义各种数据包头。
bit<48> src_addr;
bit<16> ether_type;
}
//.....其他包头格式和 metadata格式定义
/*Parser部分*/
parser MyParser(packet_in packet,
out headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
state start {
transition parse_ethernet; //转移到 parse_ethernet状态
}
state parse_ethernet {
packet.extract(hdr.ethernet); //提起数据包头
transition select(hdr.ethernet.etherType) {
TYPE_MYTUNNEL: parse_myTunnel;
TYPE_IPV4: parse_ipv4;
default: accept; //根据 etherType, 选择性的转移到其他状态,知道转移到accept;
}
// other state
}
}
/*Checksum计算可以空着*/
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
apply { }
}
/*Ingress 处理*/
control MyIngress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
action some_action() {
//一些动作,如修改包头,或者丢弃等等。
}
table ipv4_lpm {//定义一张表
key = {
hdr.ipv4.dstAddr: lpm;//要匹配的动作和匹配模式(lpm是最长前缀匹配,exact是精准匹配)
}
actions = { //定义控制平面添加流表项时,可选的动作。
ipv4_forward;
drop;
NoAction;
}
size = 1024; //定义大小
default_action = drop(); //定义默认的动作。
}
apply { //上面只是一些定义,真正的数据包处理逻辑在这里。
//不用管这里if中具体的条件
//先主要了解 apply 里面时让我们根据一些逻辑条件,定义数据包再流表之间的处理过程。
if (hdr.ipv4.isValid() && !hdr.myTunnel.isValid()) {
ipv4_lpm.apply();
}
if (hdr.myTunnel.isValid()) {
myTunnel_exact.apply();
}
}
}
/*与Ingress处理过程类似*/
control MyEgress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
apply { }
}
/*输出的校验和检验*/
control MyComputeChecksum(inout headers hdr, inout metadata meta) {
apply {}
}
/*Deparser 数据包重组*/
control MyDeparser(packet_out packet, in headers hdr) {
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.ipv4);
// other emit
}
}
/*将上述代码中定义的各个模块组装起来,有点像C/C++中的main函数*/
V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;
就先这样吧,已经毕业了,毕业快乐