Add on Miss
This DPL program implements an efficient model for dynamic IPv6 flow tracking and statistics collection within the DPU’s programmable data plane. By leveraging the nv_add_entry extern, the program autonomously inserts new entries into a match-action table based on observed traffic patterns, effectively offloading connection learning and state management from the control plane. Each invocation dynamically creates an entry keyed by programmable fields (e.g., the IPv6/TCP 5‑tuple) assigns an action with parameters, and configures an optional timeout for expiration. This approach enables on‑the‑fly flow learning directly in hardware, optimizing real‑time performance. The program adheres to the run‑to‑completion DPL architecture, ensuring that packets are parsed, matched, processed, and forwarded in a single logical pass through the pipeline.
IPv6 Flow Match Table Definition (fiveTupleTable_v6)
Defines a match-action table keyed on a five-tuple corresponding to IPv6 TCP flows: source address, destination address, protocol (next header), source port, and destination port.
Uses a direct counter (
NvDirectCounter) to measure per-entry packet and byte statistics.Enables dynamic data-plane learning through
nv_support_add_entryand time-based expiration withnv_support_timeout.The
nv_delayed_counter_statsattribute ensures efficient updates to counters.
Table Actions (count_v6_hit)
Implements an action that increments the per-entry counter and forwards the packet to a specified destination port.
Dynamic Entry Insertion (nv_add_entry)
On table miss, the data plane uses
nv_add_entryto dynamically install a new table entry intofiveTupleTable_v6.This entry is created using runtime key values extracted directly from the incoming packet headers (IPv6 and TCP fields).
The entry associates the
count_v6_hitaction with parameters such as the forwarding port and sets a timeout of 1000 ms before aging out.This approach significantly reduces round-trips to the P4Runtime controller for flow installation, achieving fast insertion of new flows.
Apply Logic (Control Flow)
The
applyblock orchestrates the overall packet-processing sequence:Verifies that the packet includes valid IPv6 headers.
Applies the match table to attempt flow lookup.
On a miss, invokes
nv_add_entryto install the flow rule dynamically.Forwards all packets to a predefined logical port (
nv_send_to_port(1)), representing a final egress or next processing stage.
See below for the complete DPL example.
/*
* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
*
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
* property and proprietary rights in and to this material, related
* documentation and any modifications thereto. Any use, reproduction,
* disclosure or distribution of this material and related documentation
* without an express license agreement from NVIDIA CORPORATION or
* its affiliates is strictly prohibited.
*/
#include <doca_model.p4>
#include <doca_headers.p4>
#include <doca_externs.p4>
#include <doca_parser.p4>
// Pipeline section
control c(
inout nv_headers_t headers,
in nv_standard_metadata_t std_meta,
inout nv_empty_metadata_t user_meta,
inout nv_empty_metadata_t pkt_out_meta
) {
NvDirectCounter(NvCounterType.PACKETS_AND_BYTES) v6tableDirectCounter;
action count_v6_hit(nv_logical_port_t port) {
v6tableDirectCounter.count();
nv_send_to_port(port);
}
table fiveTupleTable_v6 {
key = {
headers.ipv6.src_addr : exact;
headers.ipv6.dst_addr : exact;
headers.ipv6.next_header : exact;
headers.tcp.src_port : exact;
headers.tcp.dst_port : exact;
}
actions = {
count_v6_hit;
NoAction;
}
default_action = NoAction;
direct_counter = v6tableDirectCounter;
nv_support_add_entry = true;
nv_support_timeout = true;
nv_delayed_counter_stats = true;
}
apply {
if (headers.ipv6.isValid() && headers.tcp.isValid()) {
if (fiveTupleTable_v6.apply().miss) {
nv_add_entry(
"fiveTupleTable_v6",
{
headers.ipv6.src_addr,
headers.ipv6.dst_addr,
NV_TCP_PROTOCOL,
headers.tcp.src_port,
headers.tcp.dst_port
},
"count_v6_hit",
{
32w1
},
1000
);
}
}
nv_send_to_port(1);
}
}
// Instantiate the top-level DPU pipeline package
NvDocaPipeline(
nv_fixed_parser(),
c()
) main;