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:
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.
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.
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();
}
}
For more information, refer to the full DPL example, entropy.p4.