l2tp-rs
High-level async L2TPv3 control API for Linux Generic Netlink.
This crate focuses on L2TP tunnel/session lifecycle and query operations only.
It does not configure interfaces/bridges/routes (rtnetlink tasks belong in a separate crate).
Requirements
- Linux kernel with L2TP Generic Netlink support (
l2tpfamily). - Tokio runtime.
CAP_NET_ADMIN(or root) for most create/modify/delete operations.
Installation
[]
= "0.2.1"
= { = "1", = ["rt-multi-thread", "macros"] }
Quick Start
Managed UDP tunnel + Ethernet session
use ;
use ;
async
Managed IP-backed tunnel (IPv4 or IPv6)
use ;
use Ipv4Addr;
async
Binding Managed Sockets to an Interface
Use IfName with managed sockets:
- At creation:
TunnelSocket::udp(..., Some(&ifname))TunnelSocket::ip(..., Some(&ifname), ...)
- After creation:
tunnel.socket().unwrap().bind_to_device(&ifname)?
SO_BINDTODEVICE typically requires CAP_NET_ADMIN.
Kernel Semantics Notes
L2TP_ATTR_IFNAMEapplies to sessions (SESSION_CREATE/session lookups), not tunnels. Tunnels do not create a netdevice.- Managed tunnels are fd-backed. When the managed tunnel socket is closed, the kernel tears down that tunnel and its sessions.
Unmanaged Tunnels
For kernel-managed tunnels without L2TP_ATTR_FD:
let cfg = new?;
let tunnel = handle.create_unmanaged_tunnel.await?;
Common Operations
let tunnels = handle.list_tunnels.await?;
let sessions = handle.list_all_sessions.await?;
let tstats = handle.tunnel_stats.await?;
let sstats = handle.session_stats.await?;
Handle Lifetime
TunnelHandleandSessionHandledefault toauto_delete = true.- On drop, they spawn best-effort async delete calls.
- Use
set_auto_delete(false)if you want to avoid those best-effort netlink delete calls. - For managed tunnels, dropping the handle still closes the owned tunnel socket fd, which causes the kernel to remove the tunnel/session datapath.
Running Tests
Standard tests:
Privileged tests (require root/CAP_NET_ADMIN and matching kernel modules):