3. Flow Library
3.1. Introduction
The Flow Library provides interfaces to configure hardware for identifying the traffic and executing actions based on rules defined by the user. The library defines APIs for constructing flow rules that include match criteria and a set of actions. Once a continuous stream of packets matching the flow is received, the flow is offloaded to the hardware.
The flows can be cascaded, allowing a packet to proceed to another flow after a flow-defined action is executed
There are some challenges which flow library can meet:
Optimal performance is achieved when flow rules are offloaded to hardware, however, the capacity of TCAM entries, which store these flow rules, is finite. Consequently, once the TCAM entries reach their maximum limit, a precipitous decline in performance is inevitable.
This TCAM limit can be mitigated via Flow library that manages these flows, making decisions on when to install and age out a flow from the hardware.
This flow library could be instrumental in fulfilling the requirement of managing up to 1 million flows through software ACL tables.
3.2. Flow Rule
A flow rule is the combination of attributes with a matching pattern and a list of actions.
Refer DPDK Flow Rule Description for more details.
3.3. Programming Model
The Flow Library is designed to provide a generic means for applications to offload flows to hardware (HW) or perform ACL lookups in case of HW flow miss for packet classification. Applications such as ovs-offload or virtio-l2fwd can subscribe to this library.
3.3.1. Initialization
As part of the application initialization sequence, dao_flow_init()
is invoked.
This function takes struct dao_flow_offload_config
as input, providing details of
whether the ACL table should be backed by TCAM and the KEX profile to be used for ACL
lookup.
This function should be invoked for each port, taking into account that an application
can have two types of ports: RPM ports, which require hardware flow offloading, and
virtio ports, which do not have hardware TCAM backing
User flow offloading configuration structure
struct dao_flow_offload_config {
/* Different features supported */
uint32_t feature;
/* Key exchange profiles supported */
char parse_profile[DAO_FLOW_PROFILE_NAME_MAX];
/* Flow aging timeout */
uint32_t aging_tmo_sec;
};
Flow initialization API
int dao_flow_init(uint16_t port_id, struct dao_flow_offload_config *config);
- Arguments:
config
: User provided flow offloading configuration
Sample initialization code:
struct dao_flow_offload_config config = {0};
uint16_t port_id = 0;
config.feature |= hw_offload_enable ? DAO_FLOW_HW_OFFLOAD_ENABLE : 0;
rte_strscpy(config.parse_profile, prfl, DAO_FLOW_PROFILE_NAME_MAX);
config.aging_tmo = 10;
rc = dao_flow_init(port_id, &config);
if (rc) {
dao_err("Error: DAO flow init failed, err %d", rc);
return;
}
3.3.2. Flow Creation
dao_flow_create()
is used to add a new flow to the ACL table, which is maintained
per port. At this stage, the flow is added only to the ACL table and nothing goes to
TCAM.
struct dao_flow *dao_flow_create(uint16_t port_id, const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
struct rte_flow_error *error);
- Arguments:
port_id
: Port identifier of Ethernet deviceattr
: Flow rule attributespattern
: Pattern specification (list terminated by the END pattern item)actions
: Associated actions (list terminated by the END action)error
: Perform verbose error reporting if not NULL- Return value:
A valid handle in case of success, NULL otherwise and errno is set
3.3.3. Flow Lookup
On the arrival of the first packet, the ACL table is looked up via dao_flow_lookup()
.
If no rule is found, the packet takes the exception path (i.e., port representor to OVS
path in the case of OVS). If a rule is hit, the flow is installed to the HW TCAM
(provided port has requested for HW offload capability while dao_flow_init()). One hit is
enough to decide to push the rule to HW.
int dao_flow_lookup(uint16_t port_id, struct rte_mbuf **objs, uint16_t nb_objs);
- Arguments:
port_id
: Port identifier of Ethernet deviceobjs
: Array of packet buffersnb_objs
: No of packet buffers- Return value:
0 on success, a negative errno value
3.3.4. Flow Destruction
Applications can call dao_flow_destroy()
. This function removes the rule from HW TCAM
(if installed) and ACL.
int dao_flow_destroy(uint16_t port_id, struct dao_flow *flow, struct rte_flow_error *error);
- Arguments:
port_id
: Port identifier of Ethernet deviceflow
: Flow rule handle to destroyerror
: Perform verbose error reporting if not NULL- Return value:
0 on success, a negative errno value
3.3.5. Flow Query
This function enables the extraction of flow-specific data, such as counters, which is accumulated through special actions that are integral to the flow rule definition.
int dao_flow_query(uint16_t port_id, struct dao_flow *flow, const struct rte_flow_action *action, void *data, struct rte_flow_error *error);
- Arguments:
port_id
: Port identifier of Ethernet deviceflow
: Flow rule handle to queryaction
: Action definition as defined in original flow ruledata
: Pointer to storage for the associated query data typeerror
: Perform verbose error reporting if not NULL- Return value:
0 on success, a negative errno value otherwise and rte_errno is set
3.3.6. Flow Flush
In the unlikely event of failure, there may be a requirement to destroy all flow rule handles associated with a port.
int dao_flow_flush(uint16_t port_id, struct rte_flow_error *error);
- Arguments:
port_id
: Port identifier of Ethernet deviceerror
: Perform verbose error reporting if not NULL- Return value:
0 on success, a negative value otherwise.
3.3.7. Flow Information
Dumping internal information about a flow.
int dao_flow_dev_dump(uint16_t port_id, struct dao_flow *flow, FILE *file, struct rte_flow_error *error);
- Arguments:
port_id
: The port identifier of the Ethernet deviceflow
: The pointer of flow rule to dump. Dump all rules if NULLfile
: A pointer to a file for outputerror
: Perform verbose error reporting if not NULL- Return value:
0 on success, a negative value otherwise.
3.3.8. Installing flow directly into hardware
Install a flow rule on a given port which gets offloaded directly into the HW.
struct dao_flow *dao_flow_hw_install(uint16_t port_id, const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
struct rte_flow_error *error);
- Arguments:
port_id
: Port identifier of Ethernet deviceattr
: Flow rule attributespattern
: Pattern specification (list terminated by the END pattern item)actions
: Associated actions (list terminated by the END action)error
: Perform verbose error reporting if not NULL- Return value:
A valid handle in case of success, NULL otherwise and errno is set
3.3.9. Removing a flow from hardware
Removing a flow rule on a given port which was directly offloaded to hardware.
int dao_flow_hw_uninstall(uint16_t port_id, struct dao_flow *flow,
struct rte_flow_error *error);
- Arguments:
port_id
: Port identifier of Ethernet deviceflow
: Pointer to flow which is to be removed.error
: Perform verbose error reporting if not NULL- Return value:
0 on success, a negative value otherwise.