The following note explains how to deploy a high-performance VPN using WireGuard on VPP with DPDK. This lets lab members connect to computation servers from anywhere on the campus network with minimal overhead.
While SoftEther VPN with a local-bridge to the NIC offers ~90 MB/s for a single user on a 1 Gbps network, but drop quickly to 1MB/s with increasing clients, it cannot leverage DPDK or SR-IOV. To scale beyond a few clients, we upgrade to an Intel E810 NIC and running VPP in user space. DPDK bypasses the kernel’s network stack, enabling zero-copy packet forwarding:
eth0 (out) <--> VPP (WireGuard + DPDK) <--> eth1 (in)
Network topology:
VPN Client (10.100.1.x)
│
│ WireGuard tunnel
│
VPN Server
wg0: 10.100.1.1/24 ← VPN subnet
dpdk1: 10.10.2.10/24 ← Internal servers
dpdk0: <Internet IP> ← Public internet
│
├── Servers (10.10.2.0/24)
└── Internet
Clients on 10.100.1.0/24 connect through wg0. Internal servers on 10.10.2.0/24 connect via dpdk1. The VPN server also acts as the NAT gateway for both subnets.
Example VPP configuration:
# 1) Interface configuration
set interface ip address dpdk0 dhcp client # Public internet
set interface ip address dpdk1 10.10.2.10/24 # Internal server subnet
set interface state dpdk0 up
set interface state dpdk1 up
# 2) WireGuard setup
wireguard create listen-port 51820 private-key <server-private-key>
set interface ip address wg0 10.100.1.1/24
set interface state wg0 up
# 3) Peer configuration
wireguard peer add wg0 \
public-key <client-public-key> \
allowed-ip 10.100.1.2/32 \
persistent-keepalive 25
# 4) Routing
ip route add 0.0.0.0/0 via <internet-gw> dpdk0
ip route add 10.100.1.0/24 via wg0
# 5) Enable NAT (NAT44) for internet access
nat44 plugin enable sessions 65535
nat44 add interface address dpdk0 # SNAT on public interface
set interface nat44 out dpdk0
set interface nat44 in dpdk1 # DNAT/MASQUERADE for internal
set interface nat44 in wg0 # DNAT/MASQUERADE for VPN
Of course, on the servers of 10.10.2.0/24, # ip route add 10.100.1.0/24 via 10.10.2.10
should be added for “seeing” the vpn clients, 10.10.100.0/24.
And the client side:
[Interface]
PrivateKey = Client-Private-Key
Address = 10.100.1.2/24
DNS = 8.8.8.8
[Peer]
PublicKey = Server-public-key
Endpoint = [Server IPV4/6]:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
Here’s the results of the configuration:
Traffic Path | NAT Applied? | Explanation | Meets Requirements? |
---|---|---|---|
VPN Clients ↔ Internal Servers | ❌ No | Traffic between two “inside” interfaces has no NAT. | ✅ Yes |
VPN Clients → Internet (External Network) | ✅ Yes | Traffic from an “inside” to an “outside” interface undergoes NAT. | ✅ Yes |
Internal Servers → Internet (External Network) | ✅ Yes | Traffic from an “inside” to an “outside” interface undergoes NAT. | ✅ Yes |
Optimization
If desktop CPUs are used, here are some optimization principles:
- Maximize Single-Core Performance: Assign dedicated CPU cores explicitly to DPDK/VPP tasks to minimize context switching overhead.
- NUMA Node Optimization: Desktop CPUs typically have a single NUMA node; ensure DPDK memory allocation is configured accordingly.
- CPU Isolation and Affinity: Explicitly isolate and bind VPP and DPDK threads to specific CPU cores.
- Disable Power-Saving Features: Ensure CPU frequency stability by disabling dynamic frequency scaling and CPU power-saving modes.
No Comments.
You can use <pre><code class="language-xxx">...<code><pre> to post codes and $...$, $$...$$ to post LaTeX inline/standalone equations.