Domains, connection tracking, aging, meters
S4·E3 Two in the morning, and nothing expires · Bridge call with the customer NOC, 02:10
Builds on: The DOCA Flow model
Before you read: what do you already know?
Wrong answers are fine and expected; trying first makes the lesson stick.
After this lesson you can
- Place a pipe in the right domain (DEFAULT, SECURE_INGRESS, EGRESS, SECURE_EGRESS) and explain the unidirectional ingress-to-egress rule.
- Implement aging with monitor.aging_sec, doca_flow_aging_handle and the AGED callback path, and explain why the application removes entries.
- Choose between RFC 2697, RFC 2698 and RFC 4115 meters and configure a non-shared meter at pipe and entry level.
- Trace a connection-tracking entry through doca_flow_ct_entry_prepare, doca_flow_ct_add_entry and doca_flow_ct_entries_process with the flags the sample uses.
- Explain how NAT is expressed in DOCA Flow (NAT64 element, CT origin/reply actions) and what OVS-DOCA does not offload.
Episode 3 — Two in the morning, and nothing expires
The night-shift operator joins from the cage, label maker still in his hand, and reads out what the NOC sees: the tenant edge is clean for the first few thousand connections, then latency climbs and never comes back down. Their DOCA Flow application on the Arm installs a connection-tracking entry per flow; nothing ever removes one. Acceptance is Friday. You ask two questions on the call: what timeout_s do they pass to doca_flow_ct_add_entry, and does anything call doca_flow_aging_handle? The answers are zero, and no.
It is worth saying out loud why the offload is built this way. The e-switch keeps the timers, but the library never deletes an entry behind the application’s back: an aged entry arrives in the entry callback with op == DOCA_FLOW_ENTRY_OP_AGED, and the application frees it there with doca_flow_pipe_remove_entry.4 Software owns the lifetime because software owns the session state the flow belongs to. The same division of labour runs through the rest of this layer — the monitor struct carries counters, meters and aging per entry, and doca_flow_pipe_cfg_set_domain decides where a pipe lives, with the pipeline strictly one-way: no egress-to-ingress transitions are allowed.1
Hardware measures idleness; only your code frees the entry. Before you can tell them where the aging loop goes, you both need to agree on where their pipes actually live.
1Domains: where a pipe lives and the one-way rule
Every pipe belongs to a domain, set with doca_flow_pipe_cfg_set_domain. enum doca_flow_pipe_domain has four values: DOCA_FLOW_PIPE_DOMAIN_DEFAULT (ingress, non-secure), DOCA_FLOW_PIPE_DOMAIN_SECURE_INGRESS (decrypt only), DOCA_FLOW_PIPE_DOMAIN_EGRESS (encap), DOCA_FLOW_PIPE_DOMAIN_SECURE_EGRESS (encrypt only).1 The guide then states four constraints: DEFAULT and SECURE_INGRESS share one ingress root slot; EGRESS and SECURE_EGRESS share one egress root slot; ingress-to-egress forwarding requires a root pipe target; and no egress-to-ingress transitions are allowed.1 That last pair is the unidirectional rule: a packet travels ingress, then egress, then wire, and a pipe graph that tries to loop back is rejected.
simple_fwd_vnf shows the egress side. Its VXLAN_ENCAP_PIPE is created with doca_flow_pipe_cfg_set_domain(pipe_cfg, DOCA_FLOW_PIPE_DOMAIN_EGRESS) and doca_flow_pipe_cfg_set_is_root(pipe_cfg, true), carries an encap action (actions.encap_cfg.encap.tun.type = DOCA_FLOW_TUN_VXLAN, vxlan_tun_id = 0xffffffff, is_l2 = true, encap_type = DOCA_FLOW_RESOURCE_TYPE_NON_SHARED), and forwards with fwd.type = DOCA_FLOW_FWD_PORT to the wire port.8 The CT UDP sample does the same for its encap pipe.3
flow_acl shows the ingress side and a subtle port rule. It keeps a static domain variable defaulting to DOCA_FLOW_PIPE_DOMAIN_DEFAULT with the comment that egress uses DOCA_FLOW_PIPE_DOMAIN_EGRESS; in DEFAULT the ACL pipe is created on ports[port_id] and allowed traffic goes to port_id ^ 1, whereas in EGRESS the pipe is created on ports[port_id ^ 1] and allowed traffic goes to port_id itself, and the sample then drains both ports’ queues because the entries were enqueued on different ports.7 Read that as: an ingress pipe belongs to the port the packet arrived on; an egress pipe belongs to the port the packet will leave from.
The no_wire_to_wire devargs hint from flow_common.c explains the cost of the boundary: without it, ingress-to-egress forwarding must check the direction bit and loop Rx traffic through an internal pre-egress table before entering the egress domain; with the hint it goes directly to egress.10
Why does the e-switch forbid an egress pipe from forwarding back to an ingress pipe?
2Aging: hardware timers, software removal
Aging is a monitor property. monitor.aging_sec = N on an entry asks the e-switch to flag the entry after N idle seconds; at pipe level 0xffffffff marks the field changeable, which is what simple_fwd_vnf does so each flow can carry its own timeout.18 The aging sample sets monitor.aging_sec = 5 per entry, adds N-1 entries with DOCA_FLOW_ENTRY_FLAGS_WAIT_FOR_BATCH and the last with DOCA_FLOW_ENTRY_FLAGS_NO_WAIT, then doca_flow_pipe_queue_drain(port, 0, NULL).4
Collecting aged entries is an explicit loop:
uint64_t quota_time = 20; /* max handling aging time in ms */
int n = doca_flow_aging_handle(port, 0, quota_time, 0);
while (n != -1) { /* -1 = full cycle complete */
if (n > 0) total += n;
n = doca_flow_aging_handle(port, 0, quota_time, 0);
}Each aged entry arrives in the entry callback with op == DOCA_FLOW_ENTRY_OP_AGED, and the application frees it there with doca_flow_pipe_remove_entry(pipe_queue, DOCA_FLOW_ENTRY_FLAGS_NO_WAIT, entry).4 The sample stores a per-entry user_data struct (entry number, port id, status pointer) as the user_ctx so the callback knows which entry aged.4 simple_fwd_vnf runs the same handle call from an optional aging thread (-g/--age-thread).8
The aging sample also demonstrates the pipe miss counter: doca_flow_pipe_cfg_set_miss_counter(pipe_cfg, true) at creation, then doca_flow_resource_query_pipe_miss(pipe, &query_stats) to read query_stats.counter.total_pkts, which tells you how many packets fell through to fwd_miss.4 3.5.0 adds an API to disable the reset logic in DOCA-CT aging flows, for connections whose timer should not restart on every packet.9
Why must the application remove aged entries itself instead of the library deleting them?
3Meters: three RFCs, one struct
Meters are also monitor properties. enum doca_flow_meter_algorithm offers DOCA_FLOW_METER_RFC2697 (srTCM), DOCA_FLOW_METER_RFC2698 (trTCM) and DOCA_FLOW_METER_RFC4115 (trTCM without peak-rate dependency); enum doca_flow_meter_limit_type selects DOCA_FLOW_METER_LIMIT_TYPE_BYTES or _PACKETS.1 The meter sample uses the changeable pattern once more: at pipe level monitor.meter_type = DOCA_FLOW_RESOURCE_TYPE_NON_SHARED; monitor.non_shared_meter.cir = 0xffffffffffffffff; monitor.non_shared_meter.cbs = 0xffffffffffffffff;, and at entry level cir = 1024; cbs = 1024;, passed as the &monitor argument of doca_flow_pipe_basic_add_entry.5 The port must have been started with meter resources; the sample sets resource.nr_meters and the port helper translates that into doca_flow_port_cfg_set_nr_resources(port_cfg, DOCA_FLOW_RESOURCE_METER, n).510
Shared meters and counters exist for the case where many entries must be policed as one aggregate: reserve them with doca_flow_cfg_set_nr_shared_resource (system level) or doca_flow_port_cfg_set_nr_resources, obtain an id with doca_flow_port_shared_resource_get(port, DOCA_FLOW_RESOURCE_METER, &id), configure with doca_flow_port_shared_resource_set_cfg, and read with doca_flow_port_shared_resources_query.1 The ordered-list sample references a shared meter through meter.shared_meter.shared_meter_id and shared counters through counter.shared_counter.shared_counter_id, mixing them with non-shared counters in different list entries.6
Choosing an RFC: srTCM (2697) has one rate and two burst sizes, which suits a single committed rate with tolerance; trTCM (2698) adds a peak rate, so packets are yellow between committed and peak; RFC 4115 keeps two rates but colors excess traffic independently of the peak-rate dependency of 2698, the guide’s own description of the difference.1
When would you pick RFC 4115 over RFC 2698 for a tenant rate limit?
4Connection tracking: prepare, add, process
The CT pipe (DOCA_FLOW_PIPE_CT) tracks a connection in both directions inside the e-switch.1 Initialization differs in three places. First, CT queues are declared at init: the samples call init_doca_flow_with_ct(nb_queues, "switch,hws", &resource, nr_shared_resources, &ct_cfg) with ct_cfg = { .ct_queues = 1, .ct_ctrl_queues = 1 }, which flow_common.c turns into doca_flow_cfg_set_ct_queues and doca_flow_cfg_set_ct_ctrl_queues; the CT queue id the sample then uses is nb_queues, one past the ordinary pipe queues.310 Second, the device must support CT: doca_flow_ct_cap_is_dev_supported(dev_info).2 Third, each port gets a struct ct_port_cfg with ct_flags = DOCA_FLOW_CT_FLAG_NO_AGING | DOCA_FLOW_CT_FLAG_NO_COUNTER and zone-match and modify masks for origin and reply, applied through doca_flow_port_cfg_set_ct_flags, doca_flow_port_cfg_set_ct_direction(port_cfg, is_reply, match_inner, zone_match_mask, modify_mask) once per direction, and optionally doca_flow_port_cfg_set_ct_actions_mem_size and doca_flow_port_cfg_set_ct_aging_core.310 Resources add resource.nr_ct_counters = nb_ipv4_sessions + nb_ipv6_sessions.3
solid = fwd · dashed = fwd_miss · dotted = per-entry fwd · green bar = is_root
Exact match on the changeable fields; one entry per flow. The workhorse pipe.
Changeable = all-ones (0xffffffff) in the pipe match, value per entry. Constant = fixed value, mask NULL. l3_type / l4_type_ext / tun.type selectors can never be changeable.
- 1.
The pipe itself is configured with doca_flow_pipe_cfg_set_ct_connections(cfg, nb_ipv4_sessions, nb_ipv6_sessions, 0), doca_flow_pipe_cfg_set_ct_max_connections_per_zone, doca_flow_pipe_cfg_set_ct_dup_filter_size, and an explicit doca_flow_pipe_cfg_set_match(cfg, &match, &mask); hits forward to one pipe, misses to another (fwd.type = fwd_miss.type = DOCA_FLOW_FWD_PIPE).3 The guide summarizes CT configuration as session pools, zone limits and a duplication filter.1
A connection is installed in three calls, all on the CT queue:
doca_flow_ct_entry_prepare(ct_queue, pipe, prepare_flags, match_origin, hash_origin,
match_reply, hash_reply, entry, &conn_found);
if (!conn_found)
doca_flow_ct_add_entry(ct_queue, pipe, entry_flags, match_origin, match_reply,
actions_origin, actions_reply, fwd_origin, fwd_reply,
timeout_s, ct_status, *entry);
doca_flow_ct_entries_process(port, ct_queue, room, room, NULL);prepare_flags are DOCA_FLOW_CT_ENTRY_FLAGS_ALLOC_ON_MISS | DOCA_FLOW_CT_ENTRY_FLAGS_DUP_FILTER_ORIGIN | DOCA_FLOW_CT_ENTRY_FLAGS_DUP_FILTER_REPLY; entry_flags are DOCA_FLOW_CT_ENTRY_FLAGS_NO_WAIT | DOCA_FLOW_CT_ENTRY_FLAGS_DIR_ORIGIN | DOCA_FLOW_CT_ENTRY_FLAGS_DIR_REPLY; if add fails after an ALLOC_ON_MISS prepare the sample calls doca_flow_ct_entry_prepare_rollback(ct_queue, pipe, *entry).23 The hashes come from the sample’s flow_ct_hash_6tuple over struct doca_flow_ct_match (5-tuple plus zone).2 The 3.5.0 tree ships thirteen CT samples, from flow_ct_udp and flow_ct_tcp to flow_ct_aging, flow_ct_tcp_ipv4_ipv6 and flow_ct_udp_tunnel_asymmetric.13
Why does CT need a match_origin and a match_reply instead of one 5-tuple?
5NAT and what OVS-DOCA does with all this
DOCA Flow expresses NAT in two places. NAT64 is an ordered-list element, DOCA_FLOW_ORDERED_LIST_ELEMENT_NAT64, alongside _ACTIONS and _MONITOR.6 Four-tuple NAT for tracked connections goes through the CT entry’s actions_origin and actions_reply (struct doca_flow_ct_actions), which rewrite headers per direction; the exact field names inside that struct are not on the pages fetched for this lesson, so consult doca_flow_ct.h before quoting them to a customer.21
The same machinery is what OVS-DOCA uses when you type an OpenFlow ct() action, and its knobs are the operational face of this lesson: other_config:hw-offload-ct-size (default 250000, maximum 2M, best performance up to 1M), hw-offload-ct-ipv6-enabled (default false; IPv6 CT is new in 3.5.0), hw-offload-ct-unidir-udp-enabled (default false), and the stated limitation that ct-ct-nat, connection tracking with NAT, is unsupported.119 Meters map the same way: OVS-DOCA offloads OpenFlow meters, including chained meters, with a slow-path options:sw-meter=pps:10k:6k fallback.11
Every step is worked for you. Read it once, then try the faded version.The same method with steps blanked out (____). Fill them in from memory.A fresh case with no steps shown. Solve it on your own.
Goal: track UDP connections in hardware; first packets go to software, subsequent packets in either direction hit the CT entry, are counted and encapsulated.
Step 1, init with CT queues and resources (from flow_ct_udp).
struct flow_resources resource = {0};
resource.mode = DOCA_FLOW_RESOURCE_MODE_PORT;
resource.nr_counters = 1;
resource.nr_ct_counters = nb_ipv4_sessions + nb_ipv6_sessions; /* 1024 + 0 */
resource.nr_rss = 1;
resource.nr_encap = 1;
struct ct_init_cfg ct_cfg = { .ct_queues = 1, .ct_ctrl_queues = 1 };
init_doca_flow_with_ct(nb_queues, "switch,hws", &resource, nr_shared_resources, &ct_cfg);
uint16_t ct_queue = nb_queues;Step 2, ports with CT direction masks (zone masking off).
struct doca_flow_meta o_zone_mask = {0}, r_zone_mask = {0};
struct doca_flow_ct_meta o_modify_mask = {0}, r_modify_mask = {0};
struct ct_port_cfg ct_port_cfg = {
.ct_flags = DOCA_FLOW_CT_FLAG_NO_AGING | DOCA_FLOW_CT_FLAG_NO_COUNTER,
.zone_match_mask = { &o_zone_mask, &r_zone_mask },
.modify_mask = { &o_modify_mask, &r_modify_mask } };
init_doca_flow_switch_ports_with_ct(devs_manager, nb_devs, ports, 1, actions_mem_size, &resource, &ct_port_cfg);Step 3, leaves first: an RSS pipe for first packets, a counter pipe and the egress VXLAN encap pipe (lesson 4.2 shapes), then the CT pipe with hit to the counter pipe and miss to RSS.
doca_flow_pipe_cfg_create(&cfg, ports[0]);
set_flow_pipe_cfg(cfg, "CT_PIPE", DOCA_FLOW_PIPE_CT, false);
doca_flow_pipe_cfg_set_ct_connections(cfg, 1024, 0, 0);
doca_flow_pipe_cfg_set_ct_max_connections_per_zone(cfg, CT_DEFAULT_MAX_ZONE_SESSIONS);
doca_flow_pipe_cfg_set_ct_dup_filter_size(cfg, DUP_FILTER_CONN_NUM);
doca_flow_pipe_cfg_set_match(cfg, &match, &mask); /* both zeroed: library-defined 5-tuple */
fwd.type = DOCA_FLOW_FWD_PIPE; fwd.next_pipe = count_pipe;
fwd_miss.type = DOCA_FLOW_FWD_PIPE; fwd_miss.next_pipe = rss_pipe;
doca_flow_pipe_create(cfg, &fwd, &fwd_miss, &ct_pipe);
doca_flow_pipe_cfg_destroy(cfg);Step 4, the root control pipe steers UDP into the CT pipe (create_ct_root_pipe in flow_ct_common.c) and processes its entries with doca_flow_entries_process.
Step 5, on each first packet delivered to software: fill struct doca_flow_ct_match for origin and the swapped reply, hash both with flow_ct_hash_6tuple, then
doca_flow_ct_entry_prepare(ct_queue, ct_pipe,
DOCA_FLOW_CT_ENTRY_FLAGS_ALLOC_ON_MISS | DOCA_FLOW_CT_ENTRY_FLAGS_DUP_FILTER_ORIGIN | DOCA_FLOW_CT_ENTRY_FLAGS_DUP_FILTER_REPLY,
&match_o, hash_o, &match_r, hash_r, &entry, &conn_found);
doca_flow_ct_add_entry(ct_queue, ct_pipe,
DOCA_FLOW_CT_ENTRY_FLAGS_NO_WAIT | DOCA_FLOW_CT_ENTRY_FLAGS_DIR_ORIGIN | DOCA_FLOW_CT_ENTRY_FLAGS_DIR_REPLY,
&match_o, &match_r, &actions_o, &actions_r, NULL, NULL, 0 /* timeout_s */, &ct_status, entry);
doca_flow_ct_entries_process(ports[0], ct_queue, CT_DEFAULT_QUEUE_DEPTH, CT_DEFAULT_QUEUE_DEPTH, NULL);Every call and flag above is taken from flow_ct_common.c and flow_ct_udp_sample.c.23
Step 6, teardown: doca_flow_pipe_destroy(ct_pipe), stop_doca_flow_ports, doca_flow_destroy() (the sample’s cleanup_procedure).2
init_doca_flow_with_ct(nb_queues, "____", &resource, nr_shared_resources, &ct_cfg);ct_cfg = { .ct_queues = ____, .ct_ctrl_queues = ____ };ct_queue = ____.ct_port_cfg.ct_flags = DOCA_FLOW_CT_FLAG_____ | DOCA_FLOW_CT_FLAG_____; masks for ____ and ____ directions.- CT pipe:
set_flow_pipe_cfg(cfg, "CT_PIPE", ____, false);doca_flow_pipe_cfg_set_ct_connections(cfg, ____, 0, 0); hit → ____ pipe, miss → ____ pipe. - prepare flags:
ALLOC_ON_MISS | ____ | ____; add flags:____ | DIR_ORIGIN | ____. - Completion:
doca_flow_ct_entries_process(port, ____, room, room, NULL); on add failure after ALLOC_ON_MISS call____.
Add idle aging to the pipeline: connections must expire after 30 s of silence and be removed by software.
Acceptance: (a) you removed one flag from ct_port_cfg.ct_flags and can say which; (b) timeout_s in doca_flow_ct_add_entry is no longer 0; (c) you describe the aging loop (doca_flow_aging_handle until -1) and the callback op that triggers removal; (d) you name the 3.5.0 API change relevant to connections whose timer must not reset on every packet; (e) you state which OVS-DOCA knob would be the equivalent if the customer used OVS instead of a custom app.
Why does OVS-DOCA expose hw-offload-ct-size as a restart-time knob rather than growing the table on demand?
After the maintenance window
The fix is three small changes: drop DOCA_FLOW_CT_FLAG_NO_AGING from ct_port_cfg.ct_flags, pass a real timeout_s to doca_flow_ct_add_entry, and loop doca_flow_aging_handle until it returns -1, removing each aged entry in the callback.24 Connections expire, latency flattens, and the pipe miss counter stops climbing.4 What you say at handover: “The card will tell you an entry has gone idle. It will never take it away for you.” By breakfast the network lead has forwarded a competitor’s slide arguing that a software datapath is fast enough for the tenant bridges — the half of the fabric that runs stock OVS, not their C. He wants it disproved on his bridge, tonight.
Lab
Changes the system0 of 5 steps doneMutating steps ahead. Needs a maintenance window, out-of-band access (BMC/iDRAC/rshim console) and a rollback path. Record the pre-flight inventory before changing anything. Never on a production host.
Pre-flight (read-only): on the Arm, sudo mst start && sudo mst status -v; cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages; ip -br link | grep -E '^(p0|pf0hpf|pf0vf)'; confirm no OVS bridge currently owns p0 and pf0hpf (ovs-vsctl show). The CT sample programs the live e-switch, so run it in a maintenance window.
-
Mutating: hugepages as in lesson 4.2 (
echo '2048' | sudo tee -a /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages). Rollback: write the recorded value back. -
Build
flow_ct_udpas in the no-hardware lab. Run:sudo /tmp/build-ct/samples/doca_flow_ct_udp -a <device-address> -l 60using the device address form the README gives, for examplepci/03:00.0.12Expected: port start and pipe creation logs, then the sample waits for traffic.
-
From the host, send UDP packets through the PF for about ten seconds.
Expected on the Arm: log lines of the form
Entry N matches on the 5-tuple of the incoming packet. Reply direction matches on the inversed origin direction. If instead you seeSample didn't receive packets within 15 seconds timeout, the traffic did not reach the device you passed with-a; re-check the device address and the host’s VF or PF binding.3 -
Mutating check of aging: repeat with
flow_agingon a two-device vnf setup only if you have two SFs from lesson 4.2; expected logEntry number N from port P aged out and removedabout 5 s after the entries are installed, andNum of aged entries: ….4 -
Rollback: Ctrl-C the sample (its
cleanup_proceduredestroys the CT pipe, stops the ports in reverse order and callsdoca_flow_destroy), then restore hugepages.2 Confirm withovs-vsctl showthat nothing changed in OVS.
-
In the devel-host container from lesson m3-01, build the two samples:
cd /opt/mellanox/doca/samples/doca_flow/flow_ct_udp && meson /tmp/build-ct && ninja -C /tmp/build-ctandcd ../flow_aging && meson /tmp/build-aging && ninja -C /tmp/build-aging.Expected:
/tmp/build-ct/samples/doca_flow_ct_udpand/tmp/build-aging/samples/doca_flow_aging.12 If not:find /opt/mellanox/doca -name flow_ct_udp_sample.c. -
Extract the CT flags:
grep -n "DOCA_FLOW_CT_ENTRY_FLAGS_\|DOCA_FLOW_CT_FLAG_" /opt/mellanox/doca/samples/doca_flow/flow_ct_common.c /opt/mellanox/doca/samples/doca_flow/flow_ct_udp/flow_ct_udp_sample.c.Expected:
ALLOC_ON_MISS,DUP_FILTER_ORIGIN,DUP_FILTER_REPLYneardoca_flow_ct_entry_prepare;NO_WAIT,DIR_ORIGIN,DIR_REPLYneardoca_flow_ct_add_entry;NO_AGING | NO_COUNTERin the port config.23 If a flag is missing from the grep, you are reading a different sample:ALLOC_ON_MISSand the twoDUP_FILTER_*flags only appear on thedoca_flow_ct_entry_preparepath, so a sample that adds entries without a prepare step will not show them.3 -
Extract the aging loop:
grep -n -A8 "doca_flow_aging_handle" /opt/mellanox/doca/samples/doca_flow/flow_aging/flow_aging_sample.c.Expected: a 20 ms quota and a loop until -1;
grep -n "DOCA_FLOW_ENTRY_OP_AGED"shows the removal branch.4 If the grep returns nothing, the aged entries reach the application through the same entry-process callback as any other entry, so search the callback instead:grep -n -B4 "DOCA_FLOW_ENTRY_OP_AGED" flow_aging_sample.cand read theopargument the sample switches on.4 -
In the FlowPipeBuilder, rebuild the Worked CT chain and then move the encap pipe into the DEFAULT domain.
Expected: the builder flags the domain error (encap belongs in EGRESS) and the graph stays a DAG with no egress-to-ingress edge.1 If the builder accepts the move without complaint, you moved the pipe but left its actions empty: a DEFAULT-domain pipe with no encap action is legal, so re-add the encap action and repeat.1
-
Write down which of the five OVS-DOCA CT and meter knobs from Segment 5 correspond to which DOCA Flow calls you saw in steps 2 and 3.
Expected: the three
hw-offload-ct-*knobs map onto the CT pipe configuration you grepped in step 2, andoptions:sw-metermaps onto the monitor/meter path, not onto anything in the aging loop.11 If you tried to mapct-ct-natto a call: there is none, it is listed as unsupported in 3.5.0.11
Retrieval check
Answer from memory before looking anything up; misses become flashcards.
Explain it to a Dell SE
Explain to a Dell SE, in five sentences, why a firewall on BlueField needs connection tracking in hardware and what the application still has to do.
Sources
13 sourcesFacts in this lesson were checked against DOCA 3.5.0 docs + doca-samples tag 3.5.0, 2026-09-06. Dates are when each page was fetched. Sources fetched 2026-09-06, checked 16 days ago.
- DOCA Flow (programming guide)
- doca-samples 3.5.0: flow_ct_common.c
- doca-samples 3.5.0: flow_ct_udp_sample.c
- doca-samples 3.5.0: flow_aging_sample.c
- doca-samples 3.5.0: flow_monitor_meter_sample.c
- doca-samples 3.5.0: flow_ordered_list_sample.c
- doca-samples 3.5.0: flow_acl_sample.c
- doca-samples 3.5.0: applications/simple_fwd_vnf/simple_fwd.c
- Changes and New Features (DOCA 3.5.0)
- doca-samples 3.5.0: flow_common.c
- OVS-DOCA Hardware Acceleration
- doca-samples 3.5.0: samples/doca_flow/README.md
- doca-samples 3.5.0 full git tree (CT sample inventory)