DOCA Documentation v3.0.0

Entropy in Hash-Based Load Balancing Example

Most load-balancing systems use hash functions to map traffic flows to specific paths. A typical example of a hash input includes packet header fields of IP source/destination addresses, L4 source/destination port, and IP protocol. The effectiveness of load balancing depends on the entropy (randomness) of these fields. A high entropy is obtained when the input values are varied (e.g. diverse source ports) lead to even traffic distribution.

This example demonstrates how DPL can be used to set the entropy for the UDP source port, based on a hash of the 5-tuple. Then for load balancing devices further downstream of the DPU, the UDP source port is consumed as a part of the load balancer's algorithm.

A user metadata struct is defined to hold the temporary result of the entropy calculation:

Copy
Copied!
            

struct usermeta_t { bit<32> entropy; };

In this sample, the control needs to

  • define the hash object

  • match and select the VxLAN packets which to apply the entropy calculation

  • calculate the hash over the inner 5-tuple

  • set the outer UDP destination port with the hash value

Since the underlay header 5-tuple is often the same for different inner 5 tuple flows, setting the outer UDP destination port in this manner allows external network devices to load balance based solely on the underlay packet fields.

Copy
Copied!
            

control c( inout nv_headers_t headers, in nv_standard_metadata_t std_meta, inout usermeta_t user_meta, inout nv_empty_metadata_t pkt_out_meta ) { // Create a hash object with the selected algorithm NvHash(NvHashAlgorithm.CRC32) hash;   action drop() { nv_drop(); }   action transmit(nv_logical_port_t port) { nv_send_to_port(port); }   table balancer { key = { headers.ipv4.dst_addr: lpm; } actions = { drop; set_entropy; } default_action = drop; size = 1024; }

The apply logic glues the tables details above by filtering out VxLAN packets with a valid inner TCP/UDP.

Copy
Copied!
            

apply { if (headers.vxlan.isValid() && std_meta.is_inner_l4_ok != 0) { user_meta.entropy = hash.get_hash( 65536, { headers.inner_ipv4.src_addr, headers.inner_ipv4.dst_addr, headers.inner_ipv4.protocol, std_meta.inner_l4_src_port, std_meta.inner_l4_dst_port } ); nv_set_l4_src_port(headers, (bit<16>)user_meta.entropy); balancer.apply(); } }

See below for the complete DPL example.

Copy
Copied!
            

/* * 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>   struct usermeta_t { bit<32> entropy; };   control c( inout nv_headers_t headers, in nv_standard_metadata_t std_meta, inout usermeta_t user_meta, inout nv_empty_metadata_t pkt_out_meta ) { // Create a hash object with the selected algorithm NvHash(NvHashAlgorithm.CRC32) hash;   action drop() { nv_drop(); }   action transmit(nv_logical_port_t port) { nv_send_to_port(port); }   table balancer { key = { headers.ipv4.dst_addr: lpm; } actions = { drop; transmit; } default_action = drop; size = 1024; }   apply { if (headers.vxlan.isValid() && std_meta.is_inner_l4_ok != 0) { user_meta.entropy = hash.get_hash( 65536, { headers.inner_ipv4.src_addr, headers.inner_ipv4.dst_addr, headers.inner_ipv4.protocol, std_meta.inner_l4_src_port, std_meta.inner_l4_dst_port } ); nv_set_l4_src_port(headers, (bit<16>)user_meta.entropy); balancer.apply(); } } }   NvDocaPipeline( nv_fixed_parser(), c() ) main;

© Copyright 2025, NVIDIA. Last updated on Jul 10, 2025.