Actions
Built-in Actions
The hydra_builtin.hdr architecture file provides a series of built-in actions. You can declare required built-in actions in the action list of a table.
- Do not modify the statements of built-in actions. Otherwise, unexpected results may occur.
- Built-in actions do not support structures as input parameters. Consequently, in flow table dumps, such data can only be displayed in its raw bitstream format.
Table 2 describes the action annotations.
Annotation |
Description |
|---|---|
@flexda |
Built-in actions provided by the FlexDA programming framework. |
@dpdk |
Built-in actions corresponding to the |
@persist |
This action is implicitly added to the action list of each table. Do not manually add it again. |
@pre |
Pre-actions, which can be used in a pre-auxiliary table. |
@main |
Main actions, which can be used in a main table. |
@post |
Post-actions, which can be used in a post-auxiliary table. |
@encap |
Tunnel encapsulation action. The @encap annotation is also required for custom tunnel encapsulation actions. |
@decap |
Tunnel decapsulation action. The @decap annotation is also required for custom tunnel decapsulation actions. |
Actions that are not marked by @pre, @main, or @post can be used only in a main table.
Custom Actions
You can customize actions for operations that are not covered by built-in actions. Actions in Hydra are similar to functions in other languages. The difference is that actions do not have return values. The action syntax is as follows:
action max(in bit<16> a, action_data data) {
...
}
- Directional parameters (in/out/inout) are parameters from the data plane. Directionless headers or other data types containing headers cannot be used as action parameters.
Data plane parameters must be bound within the action list of the table (for example, ovs_action_mod_tos(hdr); in a control block).
- Directionless parameters are parameters from the control plane.
Control plane parameters are read from the flow entry after a flow table hit; therefore, they do not require binding in the action list.
- Custom actions must be defined at the top level and must not be defined within a control block.
- A custom action supports only one data plane parameter. This parameter must be the first input parameter of the corresponding control block, and its direction must be set to in.
- Custom actions can utilize the extern interfaces provided by the framework to implement custom packet editing. The packet editing capability is subject to the constraints defined in the extern interface specifications.
- The number of custom actions cannot exceed 128.
- The action data for a single custom action must not exceed 128 bytes. Otherwise, the portion beyond 128 bytes will result in unexpected behavior.
You can implement a series of operations, such as packet insertion, deletion, and modification, by invoking extern functions within custom actions. The following uses FullNAT as an example to describe how to utilize custom actions to modify the tos and ttl fields in the IPv4 header.
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);
}