鲲鹏社区首页
中文
注册
开发者
我要评分
获取效率
正确性
完整性
易理解
在线提单
论坛求助

action

内置action

Hydra的hydra_builtin.hdr架构文件中提供了一系列内置action,供用户使用,用户可在table的actionsList中直接声明需要的内置action。

表1 内置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。

  • 仅可用于主表。
  • 最多支持两层隧道的Inner RSS。合法入参为0、1、2,此外的值会走默认rss流程。
  • 需要在报文解析里写到用于RSS的对应层级的报文的解析流程。
  • 开源ovs场景下需额外编写控制面下发逻辑。
  • 默认rss:

    1. 对于非隧道报文,tcp/udp报文支持sip、dip、sport、dport进行散列,ip报文支持sip、dip进行散列,其他类型报文不散列。

    2. 对于一层隧道报文,vxlan、geneve支持inner rss,具体散列方式参考非隧道报文;其他隧道报文视为非隧道报文进行散列。

    3. 对于多层隧道报文,视为一层隧道报文进行散列。

@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所示。

表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参数列表中的无方向参数:表示来自控制面的参数。

    控制面参数为流表命中后从表项中读取,所以无需在table的actionsList中绑定。

  • 自定义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);
}