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。 |
@flexda @main action flexda_inner_rss(bit<8> rss) |
支持用户自定义指定报文层级的Inner RSS。 |
|
@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_set_ttl(bit<8> ttl) |
修改IP报文的TTL值。 |
不涉及 |
@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的actionsList中,用户不可手动加入。 |
@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):表示来自数据面的参数。不应使用无方向的header或包含header的其他数据类型作为action的参数。
数据面参数需在table的actionsList中进行绑定,如上述control示例中的ovs_action_mod_tos(hdr);。
- action参数列表中的无方向参数:表示来自控制面的参数。
- 自定义action应定义在top-level,不应定义在control内。
- 自定义action仅支持一个数据面参数,且该参数仅可为所在control的第一个入参,参数方向只能是in。
- 自定义action可使用框架提供的extern接口实现用户自定义的报文编辑功能,报文编辑能力由extern接口规格说明统一限制。
- 自定义action的数量不可超过128个。
- 单个自定义action的action data的数据大小不可超过128Byte,若超过128Byte,action data中超出128Byte的部分会不符合预期。
用户自定义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);
}