Skip to content

Instantly share code, notes, and snippets.

@carlos-jenkins
Created October 22, 2025 18:15
Show Gist options
  • Save carlos-jenkins/64e2d6bcc19e036e5eecc3fda60828af to your computer and use it in GitHub Desktop.
Save carlos-jenkins/64e2d6bcc19e036e5eecc3fda60828af to your computer and use it in GitHub Desktop.
Linux kernel bonding driver hash algorithm Python equivalent for xmit_hash_policy=layer3+4 unfragmented TCP/UDP and IPv4
import socket
import struct
def _ipv4_to_u32(ip_str: str) -> int:
# network-order (big-endian) to host int
return struct.unpack("!I", socket.inet_aton(ip_str))[0]
def bond_layer3_4_hash_tcp(
src_ip: str,
dst_ip: str,
src_port: int,
dst_port: int,
slave_count: int
) -> int:
"""
Predict the slave index for Linux bonding xmit_hash_policy=layer3+4 for
unfragmented TCP.
:param str src_ip: Source IPv4 address, e.g. "192.168.1.10"
:param str dst_ip: Destination IPv4 address, e.g. "10.0.0.5"
:param int src_port: TCP source port (0..65535)
:param int dst_port: TCP destination port (0..65535)
:param int slave_count: Number of slaves (>0)
:return: Slave index in [0, slave_count-1]
:rtype: int
"""
if not (0 <= src_port <= 0xFFFF and 0 <= dst_port <= 0xFFFF):
raise ValueError("Ports must be 0..65535")
if slave_count <= 0:
raise ValueError("slave_count must be > 0")
sip = _ipv4_to_u32(src_ip)
dip = _ipv4_to_u32(dst_ip)
# Start with ports "as in the header".
# A common interpretation is to pack them as 16|16 bits:
h = ((src_port & 0xFFFF) << 16) | (dst_port & 0xFFFF)
# Then XOR in the IPs (L3)
h ^= sip ^ dip
# Fold/mix as per docs
h ^= (h >> 16)
h ^= (h >> 8)
# Bonding special-case for LAYER34: discard lowest bit
h >>= 1
# Reduce to slave index
return h % slave_count
# Example usage
ip_src = '192.168.1.10'
ip_dst = '10.0.0.5'
slave_count = 2
port_dst = 80
# Show distribution of source ports to slave indices
distribution = [0] * slave_count
for port_src in range(1, 65536):
slave_index = bond_layer3_4_hash_tcp(
ip_src,
ip_dst,
port_src,
port_dst,
slave_count,
)
distribution[slave_index] += 1
print(f'Distribution of source ports to {slave_count} slaves:')
for idx, count in enumerate(distribution):
print(f' Slave {idx}: {count} ports')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment