feat: 流量统计支持 --iface 指定网卡,隧道与叠加设备按内核事实识别 - #6
Merged
Merged
Conversation
- 名单补 fwln(PVE 防火墙 veth 的另一端)、ifb、gretap、erspan;pppoe- 归入叠加设备 - 新增 counted_elsewhere():有 lower_* 链接的是叠加设备,无 device 且为三层隧道类型或 DEVTYPE=vxlan/geneve 的是隧道,改过名也认得出 - --iface / MONITOR_IFACE:列出的网卡是唯一答案,内置规则不再生效;-name 从本来会计入的里 去掉;末尾 * 匹配前缀 - 设了 --iface 时拼进 boot_id,改设置后 hub 重新对基线,不把两组读数之差记成流量 - 启动打印计入的网卡;修正 --help 续行缩进
This was referenced Sep 18, 2026
- boot_id 后接所计网卡集合的摘要(原为 --iface 文本):LXD 网桥失去最后一个端口、网卡改名 进出名单时,hub 不再把它的整机读数记成流量 - 网桥、bond 按 uevent 的 DEVTYPE 判定,与有无端口无关 - 新增 Metrics.iface,供面板显示当前设置,不再从 boot_id 里解析 - --iface 的前缀只在默认会计入的网卡里挑,不带上 VLAN 子接口;拒绝单独的 *、-* 与 -- 开头 - 名单补 lxc、cilium(Cilium 的 pod veth 与宿主设备);测试的临时目录开跑前先清理
- 没有硬件、又挂在网桥(或其它 master)下的设备不计:libvirt 的 vnetN 等虚拟机 tap、自定义名字的 容器 veth。虚拟机发出的流量在物理口上已经记过一次。只凭 tun_flags 判 tap 不可取:rootless 容器的 pasta 网络里,唯一的网卡就是一块不挂网桥的 tap。 - 集合变化时 net_rx / net_tx 按新旧两组读数之差计算,会把新加入网卡的全部历史读数当成一秒内的流量, 写进历史图。现在纪元不同就不算速率,与 hub 重新对基线一致。 - epoch 的 ponytail 标注:集合每变一次,hub 丢一个间隔的流量,以及消除它的办法。
- 上一版按 master 判定,范围比说明宽:VRF、Open vSwitch 下的设备也有 master,可能正是这台机器的 上联。改按 brport/ 判定,只认网桥端口,与 README 的「挂在网桥上」一致。 - 所计网卡集合变化那一次不再整体把速率记成 0:速率只存在内存里,逐网卡与自己的上一次读数相减, 只算两次采样里都在的网卡。新加入的网卡下一次采样才计入,计数器重新开始的网卡这一次记 0, 其余网卡照常。总流量仍按 boot_id 由 hub 重新对基线,不变。
前缀规则是这套语法里最绕的一条(只在默认会计入的网卡里挑),也让 agent、install.sh、面板三处的 校验最复杂,而有了 `-` 排除之后,基本没有非它不可的场景。现在只有两种写法:列出要统计的网卡, 或在名字前加 `-` 排除。写了 `*` 直接报错退出,不会静默地什么都匹配不到。
通配匹配已经去掉,`*` 没有理由比写错的网卡名多一条规则:两者都匹配不到网卡,启动日志的 `counting traffic on:` 和面板的「当前」都能看出来。install.sh 与面板的字符白名单照样不收 `*`。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
#3:PVE、iStoreOS 这类有转发或虚拟网卡的机器,流量被重复统计。原因有两类:
fwbr/fwpr/fwln三个设备,名单只有前两个,guest 的流量在物理网卡和fwln上各记一次。OpenWrt 的pppoe-wan叠在 WAN 口上,SQM 的ifb*是入向镜像,也各多记一次。改动
默认规则:按内核事实识别,改过名也认得出
fwln、ifb、gretap、erspan、lxc与cilium(Cilium 的 pod veth 与宿主设备);is_stacked补pppoe-(只影响流量,pppoe-wan上的公网地址照常上报)。counted_elsewhere(),读/sys/class/net/<name>/:DEVTYPE=bridge|bond→ 叠加设备,不管有没有端口lower_*链接 → 叠加设备:VLAN、macvlan、DSA 交换机端口device,且链路类型为三层隧道(none / ipip / ip6tnl / sit / gre / ip6gre)或DEVTYPE=vxlan|geneve→ 隧道device)、OpenVZ 的venet0(type void)、移进容器的 macvlan(lower_*链接只在同一 netns 内存在)device,且是网桥的端口(brport/)→ 虚拟机的 tap(如 libvirt 的vnet0)、容器的 veth,名字随意。虚拟机发出的流量在物理口上已经记过一次;物理口挂在网桥下时有device,照计。VRF、Open vSwitch 下的设备有 master 但不是网桥端口,照计,它们可能就是这台机器的上联device就排除」:LXC 里 guest 唯一的 veth 也没有device,排除它会让整台机器的流量归零。也不按tun_flags排除所有 tap:rootless 容器的 pasta 网络里,唯一的网卡就是一块以宿主网卡命名、不挂网桥的 tap。GRE tap 与不挂网桥的 tap、veth 继续靠名单,已在SKIP_IFACES的ponytail:标记里写明上限。boot_id:所计网卡集合一变就重新对基线boot_id改为「内核 boot_id +/+ 所计网卡集合的摘要」(名字排序后做 FNV-1a)。hub 只比较是否相等,所以同一次开机里集合的任何变化都会让 hub 重新对基线,包括改--iface、网卡被重新归类、网卡改名进出名单。代价是每次变化丢一个采样间隔,新建的网卡(计数从 0 开始,原本能算对)也一样。计入的网卡频繁增减的机器(名字不在名单上的 pod、VPN 服务器上的 pppN)每次都丢一个间隔,已在epoch的ponytail:标记里写明;根治办法是逐网卡上报、由 hub 逐个累加。不在 agent 里记偏移量:偏移量随进程消失,agent 停机期间的流量也会跟着丢。hub 不用改代码。速率改为逐网卡与自己的上一次读数相减,只算两次采样里都在的网卡:按总和相减,新加入网卡的全部历史读数会被当成一秒内的流量写进历史图。新加入的网卡下一次采样才计入,其余网卡照常。速率只存在内存里,不涉及无状态的约定。
升级到这个版本时
boot_id的格式会变,每个节点会重新对一次基线。--iface/MONITOR_IFACE--iface eth1,pppoe-wan):只统计列出的网卡,内置规则全部不再生效,因此能选vmbr0、pppoe-wan。-name:从本来会计入的网卡里去掉,排除优先于列出。网卡名各不相同的一组机器可以共用一条命令。-、--开头。*不单独拒绝:它和写错的名字一样匹配不到网卡,启动日志的counting traffic on:能看出来;install.sh 与面板的字符白名单本来就不收*。Metrics.iface,原样回报当前的--iface,供面板显示和预填。hub 的公开页用白名单输出指标,这个字段不会外泄。counting traffic on: ...,列出此刻计入的网卡。--iface影响。另外修正了
--help里多行说明的续行缩进:原先被 Rust 字符串续行吞掉了,--insecure一直是错位的。验证
cargo test26 个全部通过(新增 3 个),clippy 无告警。lower_判定及其与device的先后、device豁免、隧道 DEVTYPE、隧道类型集合--iface:全名覆盖内置规则、排除优先、各项参数校验lan下的 tapvm1与 vethct1不计;不挂网桥的 vetheth0、以宿主网卡命名的 tapenp1s0、VRF 成员up1照计;网桥、VRF 设备与 tun 不计。nebula1)、sit(he-ipv6)、gre、vxlan、geneve、tun/tap、PVE 防火墙 veth 对、自命名网桥lan、VLAN、macvlan、pppoe-wan、ifb。默认规则下只计入以太网口。lxdbr0失去最后一个端口(容器停掉)--iface的校验:同一批 18 种写法,本 PR 的 agent 与 install.sh(dash 与 busybox)逐一对照。-、eth0,-、--eth0、eth0 eth1两边都拒绝;eth*、*、-*、e*h0与 shell 元字符只有 install.sh 拒绝,它的字符白名单只会更严。面板的正则由它的单元测试覆盖。安装脚本与面板的
--iface见 monitor-probe/monitor#27。发版顺序:本 PR 先于含 monitor#27 的 hub,hub 转发的是 agent 的最新发布,早于本 PR 的 agent 会静默忽略MONITOR_IFACE。Closes #3