DMVPN have nothing to do with this.
The technology Peplink and others use are one or both of:
- Sending duplicates over multiple physical links. Receiving router will only forward the first copy that arrives.
Example client sending 1, 2, 3, 4, 5.
Result is (example with two links):
Link1: 1, 2, 3, 4, 5.
Link2: 1, 2, 3, 4, 5.
Receiving router will receive (depending on latency etc): 1, 1, 2, 2, 3, 3, 4, 4, 5, 5.
But it will filter this so only the original packets will be forwarded as in: 1, 2, 3, 4, 5.
- Aggregating multiple physical links for a single TCP/UDP-flow.
Example client sending 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
Result is (example with two links):
Link1: 1, 3, 5, 7, 9.
Link2: 2, 4, 6, 8, 10.
Receiving router will receive (depending on latency etc): 1, 3, 5, 2, 4, 6, 8, 7, 9, 10.
But it will re-order this so the original order will be maintained and forwarded as: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
The exact distribution between the physical paths (links) depends on latency and available bandwidth (which will be contantly measured).
This gives that if you got 4x100Mbps uplinks the client can push a single TCP/UDP-flow at 400Mbps. With regular linkaggregation the client is limited to the speed and throughput of a single link for a specific TCP/UDP-flow.
- A third option which doesnt seem to be too common is virtual re-assembly.
That is the client sends a 1500 byte packet. But since both uplinks through the router is lets say 1400 bytes MTU this 1500 byte packet from the client is splitted into two 1400 + 100 bytes. Nothing fancy here.
The fancy part happens on receiving end where the 1400 + 100 fragments are defragmented or “virtual re-assembled” into the original 1500 bytes packet before being forwarded from the receiving router towards the server. This is normally not properly fixed by a router (unless you have enabled NAT which with nftables seems to automatically enable virtual re-assemble before forward packets) who normally would just forward the fragments to the destination for it to figure out the fragments.
That is you get a flow such as:
client ↔ 1500 bytes ↔ routerA ↔ 1400+100 bytes ↔ routerB ↔ 1500 bytes ↔ server