跳转至

qre-tool 参考

qre-tool 是 QRE 唯一的用户态操作入口。它负责 profile 生命周期、daemon 模式、配置规范化、内核状态查看、session 安装、CID 控制、eBPF 共享端口调试和 capture 生成。

全局选项

选项 适用命令 说明
--json showshow-cid-map 输出 JSON。其他命令会解析该选项,但通常没有 JSON 输出路径。
--dry-run upreloaddowndaemonhelp 打印操作计划,不执行内核、网络设备或 daemon runtime 修改。
--help-h helpdaemon 打印帮助。daemon --help 会显示 daemon 专属选项。

全局选项会先从参数列表中过滤,因此通常可放在命令前后。为了可读性,建议放在命令前:

qre-tool --json show qre0
qre-tool --dry-run up qre0

常用命令总览

命令 是否通常需要 root 说明
help 打印帮助。
show [device] 查看所有设备或指定设备的内核状态。
refresh <device> 刷新并显示指定设备的 Dest profile 诊断。
showconf <config> 解析全局配置或接口 profile,输出标准化 JSON。
strip <profile> 读取配置目录中的 profile 并输出标准化 JSON。
up <profile> 一次性准备 profile。
reload <profile> 重新同步 profile。
down <profile> 清理 profile。
daemon <profile> 运行持久 server/client 控制面。
syncconf <device> <config> 把接口配置同步到内核。
delete <device> 删除内核中的 QRE 设备状态。
set <device> role ... 从命令行构造最小 server/client 配置并同步。
install-sessionupdate-session 安装或更新内核 session。
adopt-cidrelease-cid 管理内核 CID 分流键。
create-*mapregister-* BPF map 和共享 socket 调试控制。
session-plansession-capture 用户态握手计划和 pcap 生成。
session-demoshared-port-* 多数需要 root 集成、验收或调试命令。

生命周期命令

strip

qre-tool strip <profile>

读取 ${QRE_CONFIG_DIR:-/etc/qre/dev}/<profile>.conf,同时读取全局配置用于状态目录解析,然后输出 profile 的标准化 JSON。profile 名只能包含 ASCII 字母、数字、-_,不能以 . 开头,不能包含 /\

up

qre-tool [--dry-run] up <profile>

执行一次性准备:

  1. 校验 profile。
  2. 加载 qre.ko,除非 QRE_MODULE_LOAD=false
  3. 执行 PreUp hooks。
  4. 通过 netlink 同步配置。
  5. 设置 link up。
  6. 替换设备地址。
  7. 执行 PostUp hooks。
  8. 在 state dir 保存 profile state。

失败时会尝试删除已配置地址、删除内核设备状态并移除 profile state。

reload

qre-tool [--dry-run] reload <profile>

重新读取 profile,同步内核配置并替换地址。如果保存的旧地址和新地址不同,会先删除旧地址。reload 不负责长期 daemon 的重连策略;systemd 场景通常使用:

sudo systemctl reload qred@qre0

down

qre-tool [--dry-run] down <profile>

执行清理:

  1. 执行 PreDown hooks。
  2. 删除保存的或当前配置中的设备地址。
  3. 删除内核设备状态。
  4. 执行 PostDown hooks。
  5. 移除 profile state。

daemon

qre-tool [--dry-run] daemon <profile> [options]

daemon 先执行与 up 相同的准备,然后按 profile 角色运行持久控制面:

  • server:持有监听/fallback UDP socket、共享端口 eBPF loader 生命周期、外部 REALITY/QUIC 握手、session 安装、CID adoption 和退出清理。
  • client:运行重连循环,握手成功后安装 session,写 ready file;会话丢失后用有界指数退避重试。

daemon 选项:

选项 说明
--config-dir <path> 路径 覆盖 profile 目录,同时设置 QRE_CONFIG_DIR
--global-config <path> 路径 覆盖全局配置路径,同时设置 QRE_GLOBAL_CONFIG
--state-dir <path> 路径 覆盖状态目录,同时设置 QRE_STATE_DIR
--bpf-elf <path> 路径 覆盖 BPF ELF,同时设置 QRE_BPF_ELF
--pin-dir <path> 路径 覆盖 BPF pin 目录,同时设置 QRE_BPF_PIN_DIR
--server-underlay <ip:port> socket addr 测试/调试时覆盖服务端 underlay。
--client-underlay <ip:port> socket addr 测试/调试时覆盖客户端 underlay。
--run-for-ms <ms> 非零 u64 运行指定毫秒后退出,主要用于测试。

状态和配置命令

show

qre-tool show
qre-tool show qre0
qre-tool --json show qre0

显示设备角色、计数器、Dest profile、session、CID adoption、BPF map 同步、共享 socket 和共享 loader 状态。具体字段取决于当前 qre.ko ABI。

refresh

qre-tool refresh <device>

刷新指定设备的 Dest profile,并打印探测结果。常用于确认 Dest 是否可达、cache 是否新鲜。

showconf

qre-tool showconf /etc/qre/qre.conf
qre-tool showconf /etc/qre/dev/qre0.conf

解析全局配置或接口 profile,并输出稳定 JSON。适合在 CI 或部署脚本中作为配置校验。

syncconf

sudo qre-tool syncconf <device> <config>

读取接口配置并同步到内核。命令参数中的 <device> 必须与配置里的 Device 一致。

delete

sudo qre-tool delete <device>

删除内核中的 QRE 设备状态。完整 profile 清理更推荐使用 qre-tool down <profile>,因为它还会处理地址、hooks 和 state。

set

sudo qre-tool set <device> role server \
  Address=<cidr> Listen=<ip:port> MTU=<mtu> Dest=<host:port> ServerName=<sni>

sudo qre-tool set <device> role client \
  Address=<cidr> Endpoint=<host:port> MTU=<mtu> ServerName=<sni> \
  [PersistentKeepalive=<seconds>]

set 是低层调试命令。它会构造一个最小配置并同步到内核,REALITY key 和 short id 使用占位值:

  • server 占位:RealityPrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=RealityShortIds = 00
  • client 占位:RealityPublicKey = AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=RealityShortId = 00

生产配置应使用 profile 文件和 daemon/up

set 字段别名:

标准字段 接受的别名
Address address
Listen listen
Endpoint endpoint
MTU mtu
Dest dest
ServerName server-nameserver_namesni
PersistentKeepalive persistent-keepalivepersistent_keepalive

Session 命令

install-sessionupdate-session

sudo qre-tool install-session <device> \
  SessionId=<64hex> ConnectionId=<hex> \
  TxKey=<32hex> RxKey=<32hex> \
  TxHpKey=<32hex> RxHpKey=<32hex> \
  TxIv=<24hex> RxIv=<24hex> \
  KeyEpoch=<u64> PacketNumber=<u64> \
  [NextRxKey=<32hex> NextRxHpKey=<32hex> NextRxIv=<24hex>] \
  [UnderlayLocalIPv4=<ip> UnderlayLocalPort=<port> UnderlayPeerIPv4=<ip> UnderlayPeerPort=<port>]

sudo qre-tool update-session <device> ...

两者使用同一组字段。成功后都会自动采用该 session 的 ConnectionId

字段 必填 格式 说明
SessionId 64 个 hex 字符 32 字节 session id。
ConnectionId 偶数长度 hex QRE routed connection id。
TxKeyRxKey 32 个 hex 字符 QUIC packet protection key。
TxHpKeyRxHpKey 32 个 hex 字符 QUIC header protection key。
TxIvRxIv 24 个 hex 字符 QUIC IV。
KeyEpoch u64 key epoch。
PacketNumber u64 当前 packet number。
NextRxKeyNextRxHpKeyNextRxIv 同对应当前字段 rekey 接收侧下一组 key。
UnderlayLocalIPv4 条件必填 IPv4 underlay 本地 IP。
UnderlayLocalPort 条件必填 非零端口 underlay 本地端口。
UnderlayPeerIPv4 条件必填 IPv4 underlay 对端 IP。
UnderlayPeerPort 条件必填 非零端口 underlay 对端端口。

只要出现任意 underlay 字段,四个 underlay 字段都必须出现。

字段支持 kebab-case 和 snake_case 别名,例如 session-idsession_idtx-hp-keytx_hp_key

adopt-cidrelease-cid

sudo qre-tool adopt-cid qre0 ConnectionId=<hex>
sudo qre-tool release-cid qre0 ConnectionId=<hex>

显式管理内核 CID 控制表。主要用于 rekey、迁移和 demux 控制测试。生产握手路径通常由 session 安装自动完成。

BPF map 和共享 socket 命令

create-cid-map

sudo qre-tool create-cid-map BpfMapPath=/sys/fs/bpf/qre-cid-routes

创建并 pin 一个 QRE_CID_ROUTES BPF hash map。map 形状:

  • key size:21 字节,包含 CID 长度和最多 20 字节 CID。
  • value size:u32
  • max entries:4096。

create-reuseport-socket-map

sudo qre-tool create-reuseport-socket-map BpfMapPath=/sys/fs/bpf/qre-sockets

创建并 pin 一个 QRE_SOCKETS BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,包含两个 slot:

  • index 0:userspace/fallback socket。
  • index 1:kernel socket。

实际填充 socket 由 shared-port-loader 完成。

register-cid-mapunregister-cid-map

sudo qre-tool register-cid-map BpfMapPath=/sys/fs/bpf/qre-cid-routes
sudo qre-tool register-cid-map BpfMapFd=<fd>
sudo qre-tool unregister-cid-map

注册后,内核会把已采用和未来采用的 CID 镜像到该 map。BpfMapFd=<fd> 只对当前进程中的有效 fd 有意义;跨进程调试通常使用 BpfMapPath=<path>

show-cid-map

qre-tool show-cid-map BpfMapPath=/sys/fs/bpf/qre-cid-routes
qre-tool --json show-cid-map BpfMapPath=/sys/fs/bpf/qre-cid-routes

读取 pinned QRE_CID_ROUTES map。文本输出列出 entry 数量以及每个 connection_idsocket_index

register-shared-socketunregister-shared-socket

sudo qre-tool register-shared-socket SocketFd=<fd>
sudo qre-tool unregister-shared-socket

qre.ko 注册共享端口 kernel-slot UDP socket。内核会验证 fd 是调用者 network namespace 中的 IPv4 UDP datagram socket。fd 不能来自无关进程。

共享端口调试命令

这些命令主要用于验收、开发和定位 eBPF 分流问题。生产 server runtime 由 qre-tool daemon <server-profile> 持有。

shared-port-loader

sudo qre-tool shared-port-loader \
  BpfElf=<path> Listen=<ip:port> \
  UserspaceSocketFd=<fd>

sudo qre-tool shared-port-loader \
  BpfElf=<path> Listen=<ip:port> \
  UserspaceBind=true \
  [PinDir=<bpffs-dir>] [RegisterCidMap=true|false] \
  [RoutedCidLen=17..20] [Device=<device>] \
  [ReadyFile=<path>] [RunForMs=<ms>]

作用:加载 BPF ELF,设置 routed CID 长度,绑定或接收 userspace socket,创建 kernel socket,填充 socket map,pin BPF map,注册 CID map 和 shared socket,attach qre_reuseport_demux,直到收到信号或 RunForMs 到期后清理。

shared-port-loader-check

sudo qre-tool shared-port-loader-check \
  BpfElf=<path> Listen=<ip:port> ConnectionId=<hex> \
  [PinDir=<bpffs-dir>] [RegisterCidMap=true|false] \
  [RoutedCidLen=17..20] [Device=<device>]

短生命周期验收命令。它会建立 userspace/kernel SO_REUSEPORT socket 组,填充 QRE_SOCKETSQRE_CID_ROUTES,attach 程序,验证 fallback、kernel slot 和 detach 后行为。若提供 Device,还会检查 qre-tool show Device 中的共享端口计数。

shared-port-session-demo

sudo qre-tool shared-port-session-demo \
  <server-config> <client-config> BpfElf=<path> \
  [PinDir=<bpffs-dir>] [RegisterCidMap=true|false] \
  [RoutedCidLen=17..20] [ReadyFile=<path>] [RunForMs=<ms>] \
  [ServerUnderlay=<ip:port>] [ClientUnderlay=<ip:port>]

在真实 UDP socket 上跑一轮 REALITY/QUIC 握手,并证明 loader 已注册 map/socket 后再安装 session。

shared-port-handshake-daemon

sudo qre-tool shared-port-handshake-daemon \
  <server-config>... BpfElf=<path> \
  [PinDir=<bpffs-dir>] [RegisterCidMap=true|false] \
  [RoutedCidLen=17..20] [ReadyFile=<path>] [RunForMs=<ms>]

加载一个或多个 server config 作为共享 front。所有 config 必须共享 ListenServerNameDestRealityPrivateKeyRealityMaxTimeDiff,且同一 ServerName 下 short id 不能重叠。每个认证成功的握手按 short id 选择目标 device。

shared-port-handshake-client

qre-tool shared-port-handshake-client \
  <client-config> \
  [ServerUnderlay=<ip:port>] [ClientUnderlay=<ip:port>] \
  [InstallSession=true|false]

执行一次真实 UDP REALITY/QUIC client 握手。InstallSession=true 时还会把客户端 session 安装到 qre.ko 并采用 routed CID,因此需要 root。

共享端口字段说明:

字段 适用命令 默认值 说明
BpfElf 所有 shared-port-* loader/daemon/demo 无,必填 release BPF ELF 路径。
Listen shared-port-loadershared-port-loader-check 无,必填 数字 ip:port
ConnectionId shared-port-loader-check 无,必填 hex,长度必须等于 RoutedCidLen
UserspaceSocketFd shared-port-loader 二选一 已绑定 userspace socket fd。
UserspaceBind shared-port-loader 二选一 必须为 true,由命令自己绑定 userspace socket。
PinDir 多数共享端口命令 /sys/fs/bpf bpffs pin 目录。
RegisterCidMap 多数共享端口命令 true 是否向 qre.ko 注册 CID map。
RoutedCidLen 多数共享端口命令 默认 routed CID 长度 允许 17..20
Device loader/check 用于 qre-tool show 观察共享端口计数。
ReadyFile loader/daemon/demo loader 就绪后写入的文件。
RunForMs loader/daemon/demo 非零毫秒数,到期退出。
ServerUnderlay demo/client/session 命令 server config 的 Listen 覆盖服务端 underlay 地址。
ClientUnderlay demo/client/session 命令 测试默认地址 覆盖客户端本地 underlay 地址。
InstallSession shared-port-handshake-client false 是否把握手结果安装到内核。

字段通常也接受 kebab-case 和 snake_case,例如 bpf-elfbpf_elfrun-for-msrun_for_ms

用户态 session 和 capture 命令

session-plan

qre-tool session-plan <server-config> <client-config> \
  [ServerUnderlay=<ip:port> ClientUnderlay=<ip:port>]

在内存中跑 REALITY/QUIC CONNECT-IP 握手,输出 server/client 的 install-session 参数,不触碰 netlink。适合 namespace 测试或人工检查派生结果。

session-demo

sudo qre-tool session-demo <server-config> <client-config> \
  [ServerUnderlay=<ip:port> ClientUnderlay=<ip:port>]

在内存中跑握手,并把 server/client 两端 session 都安装到内核。它是验证命令,不是生产生命周期入口。

session-capture

qre-tool session-capture \
  <valid-client|invalid-short-id|wrong-sni|malformed-initial|random-udp> \
  <server-config> <client-config> <pcap> \
  [ServerUnderlay=<ip:port> ClientUnderlay=<ip:port>]

生成原始 IPv4 UDP pcap,不触碰 netlink,也不加载 qre.ko

场景 说明
valid-clientvalid 有效客户端,应完成握手。
invalid-short-id short id 错误,应被拒绝。
wrong-sni SNI 错误,应被拒绝。
malformed-initial 伪造 malformed QUIC Initial。
random-udp 随机 UDP payload。

命令会在有效客户端被拒绝或无效客户端被接受时失败。

退出码

成功返回 0。配置校验、参数错误、权限不足、netlink 错误、BPF 错误或握手断言失败时返回非零,CLI 主入口通常使用退出码 2