Android 7系统网络(四)Native层(下)—netd Controller详解
系列目录第一篇全景图与调用链路概览 | 第二篇内核层—netfilter/iptables与路由策略 | 第三篇Native层(上)—netd守护进程与CommandListener |第四篇Native层(下)—netd Controller详解| 第五篇Framework层(上)—ConnectivityService核心机制 | 第六篇Framework层(下)—NMS/NPMS/NSS三大服务 | 第七篇连接建立—WiFi/移动数据/以太网完整流程 | 第八篇应用API层—ConnectivityManager使用与实战调试一、Controller 层概述如果说 CommandListener 是 netd 的耳朵Controller 层就是 netd 的手——所有实际的网络操作都在 Controller 中执行。netd 内部有八类主要的 ControllerCommandListener命令接收 │ ├── NetworkController ← 网络接口管理 ├── RouteController ← 路由策略管理 ├── FirewallController ← 防火墙UID过滤 ├── BandwidthController ← 带宽控制流量限制 ├── TetherController ← 网络共享 ├── SoftapController ← WiFi热点管理 ├── IdletimerController ← 接口空闲检测 └── ResolverController ← DNS解析器管理每个 Controller 对应一类网络操作由 CommandListener 的对应 Cmd 类转发调用。二、NetworkController — 网络接口管理源码路径system/netd/server/NetworkController.cppNetworkController管理网络接口的生命周期创建/销毁物理网络和虚拟网络、将接口绑定到指定网络、设置默认网络、管理网络权限。核心方法intcreatePhysicalNetwork(unsignednetId,Permission permission);intcreateVirtualNetwork(unsignednetId,boolhasDns,boolsecure);intdestroyNetwork(unsignednetId);intaddInterfaceToNetwork(unsignednetId,constchar*interface);intremoveInterfaceFromNetwork(unsignednetId,constchar*interface);intsetDefaultNetwork(unsignednetId);关键设计每个网络由netId标识接口通过addInterfaceToNetwork绑定到网络而非直接操作接口属性。IP 地址配置由上层通过netd的interface命令间接完成。以 WiFi 连接获取 IP 为例的调用过程NetworkController.createPhysicalNetwork(100, PERMISSION_SYSTEM) → 创建 netId100 的物理网络 NetworkController.addInterfaceToNetwork(100, wlan0) → 将 wlan0 接口绑定到 netId100 NetworkController.setDefaultNetwork(100) → 设置 netId100 为默认网络后续路由走此网络关键netId范围是 100-65535与ConnectivityService保持同步物理网络和虚拟网络使用不同的创建方法。三、RouteController — 路由策略管理源码路径system/netd/server/RouteController.cppRouteController是 Android 多网络并存的关键。它为每个网络netId创建独立的路由表配置 fwmark 策略路由规则管理 VPN 路由优先级保护直连路由避免被默认路由覆盖。核心方法staticintaddInterfaceToPhysicalNetwork(unsignednetId,constchar*interface,Permission permission);staticintremoveInterfaceFromPhysicalNetwork(unsignednetId,constchar*interface,Permission permission);staticintaddInterfaceToVirtualNetwork(unsignednetId,constchar*interface,boolsecure,constUidRangesuidRanges);staticintremoveInterfaceFromVirtualNetwork(unsignednetId,constchar*interface,boolsecure,constUidRangesuidRanges);staticintaddRoute(constchar*interface,constchar*destination,constchar*nexthop,TableType tableType);staticintremoveRoute(constchar*interface,constchar*destination,constchar*nexthop,TableType tableType);关键设计RouteController的所有方法都是static不维护实例状态直接操作内核路由表和策略规则。fwmark 优先级表定义constuint32_tRULE_PRIORITY_VPN_OVERRIDE_SYSTEM10000;constuint32_tRULE_PRIORITY_VPN_OVERRIDE_OIF10500;constuint32_tRULE_PRIORITY_VPN_OUTPUT_TO_LOCAL11000;constuint32_tRULE_PRIORITY_SECURE_VPN12000;constuint32_tRULE_PRIORITY_PROHIBIT_NON_VPN12500;constuint32_tRULE_PRIORITY_EXPLICIT_NETWORK13000;constuint32_tRULE_PRIORITY_OUTPUT_INTERFACE14000;constuint32_tRULE_PRIORITY_LEGACY_SYSTEM15000;constuint32_tRULE_PRIORITY_LEGACY_NETWORK16000;constuint32_tRULE_PRIORITY_LOCAL_NETWORK17000;constuint32_tRULE_PRIORITY_TETHERING18000;constuint32_tRULE_PRIORITY_IMPLICIT_NETWORK19000;constuint32_tRULE_PRIORITY_BYPASSABLE_VPN20000;constuint32_tRULE_PRIORITY_VPN_FALLTHROUGH21000;constuint32_tRULE_PRIORITY_DEFAULT_NETWORK22000;constuint32_tRULE_PRIORITY_DIRECTLY_CONNECTED23000;constuint32_tRULE_PRIORITY_UNREACHABLE32000;关键设计优先级数值越小越优先从 VPN10000到不可达32000共 16 级覆盖了 VPN 覆盖、显式网络、传统网络、网络共享、直连路由等全部场景。优先级常量数值用途VPN_OVERRIDE_SYSTEM10000VPN 覆盖系统网络VPN_OVERRIDE_OIF10500VPN 覆盖出口接口VPN_OUTPUT_TO_LOCAL11000VPN 发往本地的流量SECURE_VPN12000安全 VPN不允许绕过PROHIBIT_NON_VPN12500禁止非 VPN 流量EXPLICIT_NETWORK13000应用显式绑定的网络DEFAULT_NETWORK22000默认网络较低优先级关键应用通过bindProcessToNetwork()显式绑定的网络走EXPLICIT_NETWORK13000未绑定的 Socket 走DEFAULT_NETWORK22000确保显式绑定优先于默认路由。典型设备上的 ip rule 输出iprule show# 0: from all lookup local# 10000: from all fwmark 0x3e8/0xc0000 lookup 1000 ← VPN 优先# 13000: from all fwmark 0x64/0x1ffff lookup 100 ← netId100 (WiFi)# 13000: from all fwmark 0x65/0x1ffff lookup 101 ← netId101 (移动数据)# 22000: from all fwmark 0x0/0x0 lookup 99 ← 默认关键每个网络拥有独立的fwmark标记和路由表内核根据fwmark值选择对应的路由表进行查找实现多网络流量隔离。四、FirewallController — 防火墙源码路径system/netd/server/FirewallController.cppFirewallController基于 UID 控制应用的网络访问权限通过 iptables 的-m owner --uid-owner匹配实现。防火墙链定义constchar*LOCAL_INPUTfw_INPUT;constchar*LOCAL_OUTPUTfw_OUTPUT;constchar*LOCAL_FORWARDfw_FORWARD;constchar*LOCAL_DOZABLEfw_dozable;constchar*LOCAL_STANDBYfw_standby;constchar*LOCAL_POWERSAVEfw_powersave;关键设计fw_INPUT、fw_OUTPUT、fw_FORWARD是框架链fw_dozable、fw_standby、fw_powersave是子链子链通过setupIptablesHooks()按需挂载到框架链上。链触发条件限制规则fw_standby待机状态限制后台应用的网络fw_powersave省电模式限制所有应用使用移动数据fw_dozableDoze 深度睡眠严格限制网络访问核心方法intsetFirewallUidRule(intchain,intuid,intrule);关键防火墙支持 BLACKLIST 和 WHITELIST 两种模式默认为黑名单模式。对应的 iptables 操作# 禁止 UID 10086 使用 WiFiiptables-Ifw_standby-owlan0-mowner --uid-owner10086-jREJECT# 省电模式下禁止 UID 10086 使用移动数据iptables-Ifw_powersave-ormnet_data0-mowner --uid-owner10086-jREJECT关键fw_dozable链同时作用于 INPUT 和 OUTPUT同时拦截接收和发送的 IPv6 邻居发现报文也会被放行避免 Doze 模式导致 IPv6 完全不可用。省电模式切换时的规则变化流程用户关闭屏幕 → Doze 模式 ↓ NetworkPolicyManagerService 判断是否进入省电 ↓ NetworkManagementService.setFirewallUidRule(FIREWALL_CHAIN_DOZABLE, uid, DENY) ↓ 通过 NativeDaemonConnector 向 netd 发送命令 ↓ firewall set_uid_rule dozable uid deny ↓ FirewallController 执行 iptables -I fw_dozable -m owner --uid-owner uid -j REJECT ↓ 该 UID 的应用发出的所有网络请求被拒绝关键FIREWALL_CHAIN_DOZABLE是 Java 层的枚举常量对应 netd 侧的fw_dozable链两层命名有差异但通过getFirewallChainName()映射。五、BandwidthController — 带宽控制源码路径system/netd/server/BandwidthController.cppBandwidthController依赖内核的xt_qtaguid模块控制网络的带宽使用限制设置接口的配额限制每天/每月流量上限、设置全局警告阈值、限制特定 UID 的带宽。xt_qtaguid的工作原理应用 (UID10086) Socket.send() ↓ 内核 xt_qtaguid 模块 ├── 检查接口配额 → 未超 → 放行 │ → 已超 → DROP └── 更新统计计数 ↓ 统计数据写入 /proc/net/xt_qtaguid/stats ↓ NetworkStatsService 定期读取统计文件关键xt_qtaguid在内核协议栈中拦截每个数据包统计和限额检查都在内核态完成不存在用户态代理的性能开销。核心命令# 启用带宽控制bandwidthenable# 设置接口配额字节bandwidth setiquota rmnet_data01073741824# 1GB# 设置全局警告阈值bandwidth setglobalalert943718400# 900MB 警告# 移除接口配额bandwidth removeiquota rmnet_data0# 设置接口告警到达指定流量后告警bandwidth setinterfacealert rmnet_data0524288000# 500MB 告警关键配额和告警是独立的——配额超限会直接丢弃数据包告警只产生通知事件两者可以组合使用。六、TetherController — 网络共享源码路径system/netd/server/TetherController.cppTetherController实现 USB 和 WiFi 网络共享功能依赖三种技术技术作用IP 转发允许数据包从内网转发到外网iptables NAT (MASQUERADE)将内网 IP 替换为外网接口 IPDHCP 服务器dnsmasq为连接的设备分配 IP 和 DNS启动网络共享的完整流程用户开启 WiFi 热点 ↓ ConnectivityManager.startTethering() ↓ NetworkManagementService.tetherInterface(wlan0) ↓ 向 netd 发送tether interface add wlan0 ↓ TetherController::tetherInterface(wlan0) ├── 1. 启用 IP 转发echo 1 /proc/sys/net/ipv4/ip_forward ├── 2. 添加 NAT 规则iptables -t nat -A POSTROUTING -o rmnet_data0 -j MASQUERADE ├── 3. 添加 FORWARD 规则 │ iptables -A FORWARD -i wlan0 -o rmnet_data0 -j ACCEPT │ iptables -A FORWARD -i rmnet_data0 -o wlan0 -m state --state ESTABLISHED,RELATED -j ACCEPT ├── 4. 配置 wlan0 的 IPifconfig wlan0 192.168.43.1 netmask 255.255.255.0 up └── 5. 启动 dnsmasq DHCP 服务器关键FORWARD 链的ESTABLISHED,RELATED规则只放行已建立连接的回包确保外网设备无法主动向内网发起连接。TetherController支持同时共享多个下游接口通过mInterfaces列表管理。七、SoftapController — WiFi 热点源码路径system/netd/server/SoftapController.cppSoftapController管理 WiFi 热点的软件配置。它不直接操作 WiFi 硬件由hostapd负责而是管理 AP 接口的创建与删除、SSID/密码/加密方式的配置、信道选择等。与TetherController的协作关系SoftapController::startSoftap() ↓ 启动 hostapd创建 AP Interface ↓ NetworkManagementService ↓ setIpForwardingEnabled(true) ↓ startTethering([wlan0]) → 调用 TetherController ↓ TetherController 配置 NAT FORWARD 规则启动 dnsmasq DHCP ↓ 网络共享可用关键SoftapController负责 WiFi 硬件的 AP 模式配置TetherController负责 IP 层的 NAT 和 DHCP两者职责分离通过NetworkManagementService协调。八、IdletimerController — 空闲检测源码路径system/netd/server/IdletimerController.cppIdletimerController监控网络接口的空闲状态。当接口在指定时间内没有流量时触发告警。基于内核的xt_IDLETIMER模块实现。典型使用场景是运营商要求数据连接在空闲一段时间后断开IdletimerController 监控 rmnet_data0timeout 600 秒 ├── 有流量 → 重置计时器 └── 10分钟无流量 → 触发告警 ↓ NetworkManagementService 收到空闲通知 ↓ ConnectivityService 断开移动数据连接关键xt_IDLETIMER通过/sys/class/net/iface/idletimer接口与用户态通信计时器在内核中维护没有用户态定时器的精度问题。九、ndc 命令实战ndcNative Daemon Connector是一个命令行工具可以直接向netd发送命令# 列出所有网络接口ndc interface list# 查看防火墙状态ndc firewall is_enabled# 添加带宽控制接口ndc bandwidth setiquota rmnet_data01073741824# 查看 tether 状态ndc tether status# 添加路由ndc network routeadd100wlan00.0.0.0/0192.168.1.1关键ndc的命令格式与NativeDaemonConnector发送的协议完全一致输出直接反映netd的内部状态是调试网络问题的首选工具。十、本篇总结八大 Controller 各司其职共同构成了netd的执行层Controller操作内核对象上层调用方NetworkController网络接口ioctl netlinkConnectivityServiceRouteController路由表 ip ruleConnectivityServiceFirewallControlleriptables (filter表)NetworkPolicyManagerServiceBandwidthControllerxt_qtaguidNetworkPolicyManagerServiceTetherControlleriptables (nat表) dnsmasqConnectivityServiceSoftapControllerhostapd 配置WifiStateMachineIdletimerControllerxt_IDLETIMERConnectivityServiceResolverControllerDNS 服务器配置ConnectivityService每个 Controller 都是对特定内核机制的一层封装。下一篇将上升到 Framework 层深入ConnectivityService的网络评分与切换机制。