This repository demonstrates flow-stable equal-cost multipath forwarding with P4_16, BMv2, P4Runtime, and Mininet.
s2
/ \
h1 --- s1 s4 --- h2
\ /
s3
The forward paths are h1-s1-s2-s4-h2 and h1-s1-s3-s4-h2. The same two paths are available in reverse. Hosts use static routes and permanent neighbor entries, so ARP does not affect the demonstration.
p4/ecmp.p4 parses Ethernet, IPv4, and TCP or UDP ports. The ingress pipeline performs an IPv4 LPM lookup, hashes the IPv4 five-tuple into an ECMP member, then resolves that member to an egress port and next-hop MAC addresses. Other IPv4 protocols use zero transport ports in the hash. IPv4 options, fragments, bad checksums, expired TTLs, and table misses are dropped.
The controller installs the BMv2 pipeline and static entries through P4Runtime. It uses p4runtime-go-controller v1.1.1 and verifies the entry count in each table after programming.
| Host | Address | MAC |
|---|---|---|
| h1 | 10.0.1.1/24 |
02:00:00:00:01:01 |
| h2 | 10.0.4.2/24 |
02:00:00:00:04:02 |
p4c-bm2-sswith the v1model backendsimple_switch_grpc- Mininet and
ethtool - Go 1.25 or Go automatic toolchain selection
- Python 3 with Scapy
sudoaccess for Mininet
No container image or separate P4 toolchain is required.
Build the P4 artifacts and controller:
make buildStart the topology and open the Mininet CLI:
make runThe command uses sudo for Mininet and may prompt for your password.
For example:
mininet> pingall
mininet> h1 ping -c 3 10.0.4.2
mininet> h2 ping -c 3 10.0.1.1
Run the complete test suite:
make testThe integration test starts all four switches, installs and reads back the P4Runtime state, checks ping in both directions, and traces deterministic UDP flows at each hop. It verifies same-flow stability, use of both paths, lack of duplication, the expected TTL at every hop, invalid-packet drops, and complete cleanup. The build runs as the current user; only the Mininet topology and integration test run through sudo.
Remove generated files with:
make clean