action
内置action
Hydra的hydra_builtin.hdr架构文件中提供了一系列内置action,供用户使用,用户可在table的actionsList中直接声明需要的内置action。
action签名 |
描述 |
约束 |
|---|---|---|
@flexda action flexda_no_action() |
流表miss后不进行任何操作 |
仅可用于default_action,不可用于table的actionsList中。 |
@flexda @pre action flexda_upcall() |
报文上送 |
可用于default_action,也可用于table的actionsList中。 |
@flexda action flexda_drop() |
流表miss后丢包 |
仅可用于default_action,不可用于table的actionsList中。 |
@flexda @pre@main action flexda_ct() |
TCP状态报文上送 |
此action存在时只会对TCP的状态报文进行上送处理,其他报文仍可正常执行其他action。 |
@dpdk @persist action rte_count() |
计数 |
将隐式添加进每个table的actionsList,用户不可手动将其加到table的actionsList中。 |
@dpdk @main action rte_port_id(bit<16> id) |
将报文发送到指定端口 |
仅可用于主表。 |
@dpdk action rte_set_mac_src(macAddr_t src) |
修改ETHERNET报文头的src_mac字段 |
不涉及 |
@dpdk action rte_set_mac_dst(macAddr_t dst) |
修改ETHERNET报文头的dst_mac字段 |
不涉及 |
@dpdk action rte_set_ipv4_src(ip4Addr_t src) |
修改IPv4报文头的src_ip字段 |
不涉及 |
@dpdk action rte_set_ipv4_dst(ip4Addr_t dst) |
修改IPv4报文头的dst_ip字段 |
不涉及 |
@dpdk action rte_set_ipv6_src(ip6Addr_t src) |
修改IPv6报文头的src_ip字段 |
不涉及 |
@dpdk action rte_set_ipv6_dst(ip6Addr_t dst) |
修改IPv6报文头的dst_ip字段 |
不涉及 |
@dpdk action rte_dec_ttl() |
IP报文的TTL值减1 |
不涉及 |
@dpdk action rte_set_tp_src(portAddr_t src) |
修改TCP/UDP报文头的src_port字段 |
不涉及 |
@dpdk action rte_set_tp_dst(portAddr_t dst) |
修改TCP/UDP报文头的dst_port字段 |
不涉及 |
@dpdk action rte_of_pop_vlan() |
删除以太头中的vlan帧 |
不涉及 |
@dpdk action rte_of_push_vlan(bit<16> vlan_id) |
在以太头中插入vlan帧 |
不涉及 |
@dpdk action rte_of_set_vlan_vid(bit<16> vlan_vid) |
修改VLAN帧的vid字段 |
不涉及 |
@dpdk action rte_of_set_vlan_pcp(bit<8> vlan_pcp) |
修改VLAN帧的pcp字段 |
不涉及 |
@dpdk @encap action rte_vxlan_encap(bit<512> item) |
封装VXLAN隧道 |
不涉及 |
@dpdk @decap action rte_vxlan_decap() |
解封装VXLAN隧道 |
不涉及 |
action的注释说明如下表2所示。
注释 |
说明 |
|---|---|
@flexda |
Flexda编程框架提供的内置action。 |
@dpdk |
对应DPDK标准枚举的内置action。 |
@persist |
该action会隐式加到每个table的actions List中,用户不可手动加入。 |
@pre |
前置action,可用于前置辅表 |
@main |
主action,可用于主表。 |
@post |
后置action,可用于后置辅表。 |
@encap |
隧道封装action,用户自定义的隧道封装action也需加上@encap注解。 |
@decap |
隧道解封装action,用户自定义的隧道解封装action也需加上@decap注解。 |
未添加@pre、@main、@post枚举的action仅可用于主表。
自定义action
对于内置action尚未支持的操作,用户可以通过自定义action来完成对应操作。Hydra中的action类似于其他语言中函数的概念,特殊之处在于action没有返回值,action的语法如下所示。
action max(in bit<16> a, action_data data) {
...
}
- action参数列表中有方向参数(in/out/inout):表示来自数据面的参数。
数据面参数需在table的actionsList中进行绑定,如上述control示例中的ovs_action_mod_tos(hdr);。
- action参数列表中的无方向参数:表示来自控制面的参数。
- 自定义action必须定义在代码顶层部分,不可定义在control内。
- 自定义action仅支持一个数据面参数,且该参数仅可为所在control的第一个入参,参数方向只能是in。
- 自定义action可使用框架提供的extern接口实现用户自定义的报文编辑功能,报文编辑能力由extern接口规格说明统一限制。
- 自定义action的数量不可超过128个。
- 单个自定义action的action data的数据大小不可超过128字节,若超过128字节,action data中超出128字节的部分会不符合预期。
用户自定义action可以调用extern func来对报文进行插入、删除、修改等相关操作。以FullNAT为例,用户可以通过自定义action实现修改IPv4的TOS字段和TTL字段。
struct action_data {
bit<8> tos;
}
action ovs_action_mod_tos(in headers hdr, action_data data) {
packet_incr_cs_param incr_checksum_para;
incr_checksum_para.old_val = (bit<32>)hdr.l3.ipv4.diff_serv;
incr_checksum_para.new_val = (bit<32>)data.tos;
incr_checksum_para.old_cs = hdr.l3.ipv4.hdr_checksum;
incr_checksum_para.cs_alg = RFC.RFC_1624;
hdr_packet_modify(hdr.l3.ipv4.diff_serv, data.tos);
hdr_packet_calc_checksum_incr(hdr.l3.ipv4.diff_serv, hdr.l3.ipv4.hdr_checksum, incr_checksum_para);
}
action ovs_action_mod_ttl(in headers hdr) {
packet_incr_cs_param incr_checksum_para;
incr_checksum_para.old_val = (bit<32>)hdr.l3.ipv4.ttl;
incr_checksum_para.new_val = (bit<32>)(hdr.l3.ipv4.ttl - 1);
incr_checksum_para.old_cs = hdr.l3.ipv4.hdr_checksum;
incr_checksum_para.cs_alg = RFC.RFC_1624;
hdr_packet_modify(hdr.l3.ipv4.ttl, hdr.l3.ipv4.ttl - 1);
hdr_packet_calc_checksum_incr(hdr.l3.ipv4.ttl, hdr.l3.ipv4.hdr_checksum, incr_checksum_para);
}