Table
table是p4的匹配——动作表,定义了匹配字段(key)、动作(action)和一些其他相关属性。
其处理数据包的流程:
- Key construction.建立其匹配字段
- Key lookup in a lookup table.The result of key lookup is an "action". 数据包中去匹配table中的key中的字段,并获得要执行的"action"。
- Action execution.执行动作。
key
key由一个个表单对组成(e:m),其中e是对应数据包中匹配的字段,而m是一个match_kind常数用来表示匹配的算法。
例如:
1 key = { 2 hdr.ipv4.dstAddr:lpm; 3 }
这个就是以ipv4头的目的地址作为匹配字段,采用的是lpm(最长前缀字段)匹配方式。
p416 core现在提供三种默认的match_kind。
1 match_kind{ 2 lpm,//最长前缀字段 3 ternary,//三元匹配 4 exact//完全匹配 5 }
Action
table中的action list是列举了该table支持的action类型。用于action的匹配。
其他属性
p416提供了一些预设的其他属性:
- default_action:当table miss的时候执行的动作。
- counters:计数器
- size:table大小
- implementation:指定table实际运作方式,这部分通常取决于架构,例如v1model中actionprofile提供了通过hash的方式随机选择一个actionprofilemember去执行。
- const entries:预设的table entry,在编译阶段会写到编译好的档案中。
Action
关于action,p4中在table里可以利用action去对封包做出处理,action非常类似于其他高级语言中所示的函数,抽象程度可以很高,并且表现出协议无关的特性。这也能体现一部分p4的扩展性。
action可以读取控制平面(control plane)提供的数据进行操作,然后根据action的代码内容影响数据平面(data plane)的工作。
对于action的定义:
1 action action_name(parameter1,parameter2,……){ 2 //语句块 3 }
而且p4有提供不少基本操作(Primitive Actions),这些action高度抽象,在p416中,大部分的基本操作被移动到了一些函数库中(arch.p4或者vendor.p4),部分操作依然保留在了core.p4中。更多详细的内容在spec中。
例如ipv4转发的code:
1 action ipv4_forward(bit<48> dstAddr,bit<9> port){ 2 standard_metadata.egress_spec = port; 3 hdr.ethernet.srcAddr = hdr.ethernet.dstAddr; 4 hdr.ethernet.dstAddr = dstAddr; 5 hdr.ipv4.ttl = hdr.ipv4.ttl - 1; 6 }
样例
这里用tutorial中的ipv4转发代码做样例。
1 action drop(){ 2 mark_to_drop();//将要丢弃的包标记为丢弃 3 } 4 5 action ipv4_forward(bit<48> dstAddr,bit<9> port){ 6 standard_metadata.egress_spec = port; 7 hdr.ethernet.srcAddr = hdr.ethernet.dstAddr; 8 hdr.ethernet.dstAddr = dstAddr; 9 hdr.ipv4.ttl = hdr.ipv4.ttl - 1; 10 } 11 table ipv4_lpm{ 12 key = { 13 hdr.ipv4.dstAddr: lpm; 14 } 15 16 actions = { 17 ipv6_forward; 18 drop; 19 NoAction; 20 } 21 22 size = 1024; 23 24 default_action = drop(); 25 }
然后给一个switch中定义的流表项:
1 { 2 "table": "MyIngress.ipv4_lpm", 3 "match": { 4 "hdr.ipv4.dstAddr": ["10.0.1.1", 32] 5 }, 6 "action_name": "MyIngress.ipv4_forward", 7 "action_params": { 8 "dstAddr": "00:00:00:00:01:01", 9 "port": 1 10 } 11 }
这个table就是对应ipv4.lpm的,匹配的dstAddr为10.0.1.1,执行的action为ipv4.forward,传入的两个参数为mac地址00:00:00:00:01:01,端口1。