| BOOTBRIDGE(8) | System Manager's Manual | BOOTBRIDGE(8) |
NAME
bootbridge —
connect a network interface to bootd and emulators over
UDP
SYNOPSIS
bootbridge |
[-c config]
-i interface
[-listen
addr:port]
[-peer
addr:port ...]
[-l2tp
addr:port]
[-l2tp-peer
addr:port ...]
[-session id]
[-cookie hex]
[-counter=bool]
[-stats duration]
[-ctl path]
[-v] [-print]
[-X] [-print-iface
name] |
bootbridge |
-version |
DESCRIPTION
bootbridge bridges an Ethernet interface
to UDP, so that bootd(8), simh, QEMU
and other emulators can exchange frames with the machines on it. It is the
only part of gobootd that needs to capture: it must run as root, with
CAP_NET_RAW on Linux, or with access to
/dev/bpf* on BSD and macOS.
Frames travel over UDP in one of two formats, on separate listeners that can run at once:
- raw
- One Ethernet frame per datagram, with no header, as the HECnet bridge,
simh (
attach xq udp:...) and QEMU (-netdevdgram) send them. There is no authentication, so the raw listener should stay on a loopback address;bootbridgewarns about any other address. - L2TPv3
- Static L2TPv3 over UDP (RFC 3931) carrying Ethernet, without the control
connection, as Linux (
ipl2tp) and QEMU (-netdevl2tpv3) speak it. Datagrams with the wrong session or cookie are dropped, so the cookie keeps out anyone who does not know it. It is sent in clear, which is no protection against anyone who can see the traffic.
Every endpoint is a UDP address. Fixed peers always receive frames. Any other address that sends a valid frame becomes a peer for 180 seconds. Unicast frames go to the peer that last sent from their destination address, as in a learning switch; broadcast, multicast and frames for unknown destinations go to every peer. Frames also pass between peers, never back to the peer they came from. Fixed peers are sent a keepalive every 60 seconds.
The options are:
-cconfig- Read the settings from an HCL configuration file (see CONFIGURATION). Options given on the command line override it.
-iinterface- The network interface to bridge. Required, here or in the configuration file.
-listenaddr:port- The UDP address to exchange raw frames on. The default is 127.0.0.1:4711; an empty string disables the raw listener.
-peeraddr:port- A raw peer that always receives frames. Can be given more than once.
-l2tpaddr:port- The UDP address to exchange L2TPv3 frames on. None by default.
-l2tp-peeraddr:port- An L2TPv3 peer that always receives frames. Can be given more than once.
-sessionid- The L2TPv3 session ID, the same in both directions. The default is 1.
- The L2TPv3 cookie, 8 or 16 hex digits, the same in both directions.
-counter=bool- Whether L2TPv3 frames carry the L2-specific sublayer with a sequence number, as Linux and QEMU do by default. The default is true.
-statsduration- How often to log interface statistics, such as
30s(the default) or5m; 0 disables them. -ctlpath- The Unix socket
bootbridgectl(1) connects
to. The default is /run/bootbridge/bootbridge.sock
(or /var/run/bootbridge/bootbridge.sock where
there is no /run, as on macOS), or a socket in
XDG_RUNTIME_DIRfor a user who cannot write /run; an empty string uses the default and-disables the socket. -v- Log every forwarding error.
-print,-p- Print packets as they pass through the bridge.
-X,-dump- Print packets with a hex and ASCII dump, like
tcpdump-X. -print-ifacename,-print-interfacename- Only print packets on one side:
udp,lan,all(the default), or an interface name. -version- Print the version.
When standard input is a terminal,
bootbridge reads single keys:
The same, and more, works without a terminal: the control socket
answers bootbridgectl(1),
which lists known peers, prints statistics, shows the frames that pass
through, and changes these settings while bootbridge
runs.
CONFIGURATION
The configuration file is HCL, the format
bootd.hcl(5) describes. Only the
listeners it declares are opened: without a raw
block there is no raw listener. Its settings are:
interface= string- The network interface, as
-i. stats= duration- As
-stats. ctl= string- As
-ctl. ctl_mode= string- The socket's permissions as octal digits, e.g. “0600” for
root only; the default is “0660”, so the group of the user
running
bootbridgecan query it. Any local user who can write the socket can see every frame bridged and change what is printed. verbose= bool- As
-v. print= bool- As
-print. dump= bool- As
-X. print_interface= string- As
-print-iface. raw{...}- The raw listener, with
listen(default 127.0.0.1:4711) andpeers, a list of fixed peers. l2tp{...}- The L2TPv3 listener, with
listen(required),peers,session,cookieandcounter.
-peer and
-l2tp-peer replace the file's lists of peers. Errors
are reported with file and line. A file that holds a cookie should be
readable by root only; bootbridge warns if anyone
can read it.
FILES
- /etc/bootbridge.hcl
- The configuration file the Debian and Ubuntu service uses.
- /usr/local/etc/bootbridge.hcl
- The configuration file the macOS launch daemon uses.
- /run/bootbridge/bootbridge.sock
- The control socket, when
bootbridgeruns as root.
EXIT STATUS
bootbridge exits 0 when it is stopped, 1
if it cannot open the interface or a listener, and 2 for invalid usage or
configuration.
EXAMPLES
Connect en0 to a bootd(8) listening on 127.0.0.1:4712:
# bootbridge -i en0 -listen
127.0.0.1:4711 -peer 127.0.0.1:4712Accept L2TPv3 from bootd(8) or QEMU on other machines, which need to know the cookie:
# bootbridge -i en0 -l2tp
0.0.0.0:1701 -cookie 0x0123456789abcdefThe same as a configuration file, with a raw listener for local emulators as well:
interface = "en0"
raw {
listen = "127.0.0.1:4711"
}
l2tp {
listen = "0.0.0.0:1701"
cookie = "0x0123456789abcdef"
}
Connect QEMU on Linux to that L2TPv3 listener on 192.168.1.10:
-netdev l2tpv3,id=n0,udp=on,src=0.0.0.0,srcport=1701,\
dst=192.168.1.10,dstport=1701,txsession=1,rxsession=1,\
cookie64=on,txcookie=0x0123456789abcdef,\
rxcookie=0x0123456789abcdef,counter=on
Watch the frames from another terminal while
bootbridge runs as a service:
$ bootbridgectl dump -t
20SEE ALSO
STANDARDS
Layer Two Tunneling Protocol - Version 3 (L2TPv3), RFC 3931. Transport of Ethernet Frames over Layer 2 Tunneling Protocol Version 3 (L2TPv3), RFC 4719.
AUTHORS
Rico Pajarola <rp@servium.ch>
CAVEATS
Full frames exceed a 1500-byte MTU as UDP datagrams and are fragmented across real networks. There is no loop protection: two bridges joined twice pass frames around forever.
Receive offload (GRO on Linux) merges bursts of TCP segments into
packets larger than any Ethernet frame before
bootbridge captures them.
bootbridge splits them again into segments no larger
than the MSS the receiving peer announced in its SYN, or 536 bytes if it did
not see the SYN. Other oversized frames are dropped and counted as
errors.
# ethtool -K enp2s0 gro
offWi-Fi access points drop frames from Ethernet addresses that have
not associated, so bridging a Wi-Fi interface does not work for
bootd(8) 's own address; use a
pcap network in
bootd.hcl(5) with
mac = "interface"
instead.
| October 14, 2026 | Ubuntu |