最近在做一个项目,发现修改FIREWALL_CHAIN_POWERSAVE里调用enableFirewallChainUL,却打印iptables信息时完全没有相关信息。
1、NetworkManagementService.java里通过setFirewallUidRules设置防火墙规则,三条现有规则如下:
FIREWALL_CHAIN_POWERSAVE:
mNetdService.firewallReplaceUidChain("fw_powersave", true, uids)
FIREWALL_CHAIN_STANDBY:
mNetdService.firewallReplaceUidChain("fw_standby", false, uids)
FIREWALL_CHAIN_DOZABLE:
mNetdService.firewallReplaceUidChain("fw_dozable", true, uids)
2、在执行iptables -L指令时,却找不到fw_powersave、fw_standby、fw_dozable等信息,只有fw_INPUT、fw_FORWARD、fw_OUTPUT等chain。但Doze对网络的限制却是真实有效的,到底是哪里起作用了?
3、在跟进到netd服务时,发现setupIptablesHooks创建了这三条chain:
res |= createChain(LOCAL_DOZABLE, getFirewallType(DOZABLE));
res |= createChain(LOCAL_STANDBY, getFirewallType(STANDBY));
res |= createChain(LOCAL_POWERSAVE, getFirewallType(POWERSAVE));
4、FirewallController.cpp里enableChildChains发现调用的是bpf,而不是传统的iptables
if (mUseBpfOwnerMatch != BpfLevel::NONE) {
return gCtls->trafficCtrl.toggleUidOwnerMap(chain, enable); //在这里被bpf截胡了
}
std::string command = "*filter\n";
for (const char *parent : { LOCAL_INPUT, LOCAL_OUTPUT }) {
StringAppendF(&command, "%s %s -j %s\n", (enable ? "-A" : "-D"), parent, name); //这里的iptable命令没有被执行
}
StringAppendF(&command, "COMMIT\n");
5、总结:Android前几个 版本就已经上了bpf要逐渐替代iptable了,bpf在这里通过hook android的代码无缝切换,虽然iptable方式仍然有效,但对于海量的规则来说,iptable越来越无力,使用bpf是必然的。
6、附一些关于bpf的学习链接:
https://blog.csdn.net/f2006116/article/details/89058601
https://source.android.google.cn/devices/tech/datausage/ebpf-traffic-monitor