Wireguard, but compatible with mpls, no MTU overhead.
- Decapsulate MPLS header (
decap_mpls
) before sending traffic out of WG interface - Encapsulate MPLS header (
encap_mpls
) after receiving traffic from WG interface - Nearly all magical stuff is in
magic.h
- Use back progagation of TTL from inner IP header to restore MPLS TTL
- Add
MESSAGE_DATA_MPLS = 5
to avoid conflicts with some providers (e.g., cloudflare)- Also add
MESSAGE_DATA_MPLS_MC = 6
as multicast MPLS
- Also add
- select
0.0.0.0
and::
as peer for non-IP(mpls) traffic
(IP) ==[encap]==> (MPLS|IP) ==[wg-decap]==> (WG|IP) ==[wg-encap]==> (MPLS|IP) ==[decap]==> (IP)
╔═══════════════════════════════════════════════════════════════════════════════════╗
║ WireGuard Header ║
╠════════════════════════════════════════════════════════════════╦══════════════════╣
║ type ║ others ║
║ 32 bit ║ (we don't care) ║
╠══════════════════════════════════════════╦═════════════════════╬══════════════════╣
║ reserved zero 24 bit ║ type 8 bit ║ ║
║ Used for MPLS Label/Exp/BoS ║ new type for MPLS ║ ║
╚══════════════════════════════════════════╩═════════════════════╩══════════════════╝
╔═══════════════════════════════════════════════════════════════════════════════════╗
║ MPLS Header ║
╠══════════════════════════════╦═══════╦═══════╦════════════════════════════════════╣
║ Label ║ Exp ║ BoS ║ TTL ║
║ 20 bit ║ 3 bit ║ 1 bit ║ 8 bit ║
╠══════════════════════════════╩═══════╩═══════╬════════════════════════════════════╣
║ Put in Wireguard reserved zeros (24 bit) ║ Extracted from inner IP header TTL ║
╚══════════════════════════════════════════════╩════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════════════════════════════╗
║ sk_buff reserved room ║
╠══════════════════════╦════════════════════════════════════════════════════════════╣
║ type ║ MPLS Data (label + exp + bos) ║
║ 8 bit ║ 24 bit ║
╠══════════════════════╬════════════════════════════════════════════════════════════╣
║ 0 for MPLS_UC ║ used in wg pkt processing ║
║ 1 for MPLS_MC ║ (clear before finish post-receive processing) ║
╚══════════════════════╩════════════════════════════════════════════════════════════╝
The origin code is copied from wireguard kernel module from linux-6.10.x.
make
- use
wireguard.ko
Setup wireguard tunnels as usual, route MPLS traffic into wg interfaces, and enjoy.
- MTU is reduced to 1416, may fix it soon.
Only IPv4/IPv6 packets are allowed to be MPLS payload, may add fallback option to accept more protocols.(Now supported)- However, TTL would be propagated from inner IP headers to MPLS headers, inner protocols without TTL would cause MPLS TTL to always be 64.
- Can not disable MPLS function. Use sysctl for temporary solution.
- Non-IP traffic would be sent to peers with allowed-ips 0.0.0.0/0 and/or ::/0.
- There will be MTU issues. For 2 stacked labels, working MTU is reduced to 1408.
- Multicast MPLS is never tested!
- MPLS type encoding (send)
- MPLS type decoding (receive)
- MPLS packet to IP (send)
- IP packet to MPLS (receive)
- TTL back propagation (receive)
- MPLS handing (receive)
- Multi-layer MPLS headers handling
- non-IP inner protocol handling
- Adjust MPLS to use MTU 1420
- BUG: encap ip packet from wg1, decap mpls and send to wg2
make test-install
: replace current wireguard with wireguard-mpls.make test-tunnel
: set up a tunnel from host to netns with MPLS routing.make test-router
: set up 6 netns and 5 tunnels with MPLS routing, run traceroutes.make test-stack
: set up a tunnel from host to netns with MPLS routing with stacked labels.
WIP
(From the results of known tests, there is little difference in performance)