P4语法(3)Table,Action

Table

table是p4的匹配——动作表,定义了匹配字段(key)、动作(action)和一些其他相关属性。

其处理数据包的流程:

  1. Key construction.建立其匹配字段
  2. Key lookup in a lookup table.The result of key lookup is an "action". 数据包中去匹配table中的key中的字段,并获得要执行的"action"。
  3. 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。

posted @ 2019-03-02 16:33  水喵桑  阅读(3666)  评论(0编辑  收藏  举报