ifconfig
rk3588_s:/ $ ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope: Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:40 errors:0 dropped:0 overruns:0 frame:0
TX packets:40 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3422 TX bytes:3422
dummy0 Link encap:Ethernet HWaddr 82:10:b8:a3:c2:aa
inet6 addr: fe80::8010:b8ff:fea3:c2aa/64 Scope: Link
UP BROADCAST RUNNING NOARP MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 TX bytes:350
eth0 Link encap:Ethernet HWaddr 4e:27:42:9f:ef:90 Driver rk_gmac-dwmac
inet addr:192.168.0.95 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::c753:c959:5a7d:a7e7/64 Scope: Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:70 errors:0 dropped:0 overruns:0 frame:0
TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:4200 TX bytes:1262
Interrupt:74
eth1 Link encap:Ethernet HWaddr 36:e2:71:5a:11:d3 Driver r8168
inet addr:192.168.43.5 Bcast:192.168.255.255 Mask:255.255.0.0
inet6 addr: fe80::d21d:3f3a:bad4:3402/64 Scope: Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:68 errors:0 dropped:0 overruns:0 frame:0
TX packets:65 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:4080 TX bytes:4962
Interrupt:154 Base address:0xf000
usb0 Link encap:Ethernet HWaddr ae:0c:29:a3:9b:6d Driver cdc_ether
inet addr:10.18.216.73 Bcast:10.255.255.255 Mask:255.0.0.0
inet6 addr: 2409:8d80:9000:34b3:ac0c:29ff:fea3:9b6d/64 Scope: Global
inet6 addr: fe80::ac0c:29ff:fea3:9b6d/64 Scope: Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:268 errors:0 dropped:0 overruns:0 frame:0
TX packets:345 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:82071 TX bytes:41386
lo 回环接口
虚拟网络接口: 并非真实存在,并不真实地从外界接收和发送数据包,而是在系统内部接收和发送数据包,因此虚拟网络接口不需要驱动程序。
用于与本地内部通信的网卡
dummy0
dummy网卡 (dummy network interface)用于在断网的环境下,假装网络可以通,仍然可以通过类似 192.168.1.1 这样的IP 访问服务。因为断网环境下只有本地环回地址127.0.0.1能被内核解析, 因此如果想要解析 192.168.1.1 这种IP,就要将其设置为 dummy类型
dummy 接口主要有两个用途:
- 用于主机内的程序通信
- 在拥有多个物理接口的网络上,可以将 service 地址设置为 loopback 接口或 dummy 接口的地址,这样 service 地址不会因为物理接口的状态而受影响。
Android 多网卡
- Android默认只支持一个网卡, Mobile/Ethernet/Wi-Fi不能同时存在
- linux是可以同时支持多网卡存在的
- 去掉Android Framework中只允许一个网卡存在的逻辑
- 可以通过修改网卡的优先级,再加上把AndroidFW中关掉低优先级的网卡的代码注释掉来实现。当前还有其他方法来实现,比如让AndroidFW不监听linux的指定种类的网卡事件,也可以避免AndroidFW关闭该种类的网卡。
- 为AndroidFramework没有支持的另外的网卡,配置路由规则(ip rule/ ip route)
Android 双以太网
rk3588 eth0(内网) log
// 驱动上卡
2023-08-03 14:57:37.740 268-268 <no-tag> pid-268 I rk_gmac-dwmac fe1c0000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
2023-08-03 14:57:37.740 268-268 <no-tag> pid-268 W [dhd] CFG80211-ERROR) wl_cfg80211_netdev_notifier_call : wdev null. Do nothing
// 加载网卡
2023-08-03 14:57:35.788 627-647 EthernetTracker system_process I interfaceLinkStateChanged, iface: eth0, up: true
2023-08-03 14:57:35.788 627-776 EthernetNe...FactoryExt system_process D interfaceLinkStateChanged: iface = eth0, mIface = eth0,up:true,mLinkUp:false
// 设置静态IP
2023-08-03 14:57:36.790 627-2211 EthernetNe...FactoryExt system_process D setStaticIpAddress:android.net.StaticIpConfiguration$Builder@68bbd8b
2023-08-03 14:57:36.790 627-2211 EthernetNe...FactoryExt system_process D IpClient.startProvisioning
2023-08-03 14:57:36.791 431-431 netd pid-431 I interfaceSetEnableIPv6(eth0, false) <0.04ms>
2023-08-03 14:57:36.792 431-431 netd pid-431 I interfaceClearAddrs(eth0) <0.10ms>
2023-08-03 14:57:36.792 627-2212 IpClient.eth0 system_process E Failed to set accept_ra to 2
2023-08-03 14:57:36.794 431-431 netd pid-431 I interfaceSetIPv6PrivacyExtensions(eth0, true) <0.04ms>
2023-08-03 14:57:36.794 431-431 netd pid-431 I setIPv6AddrGenMode(eth0, 2) <0.03ms>
2023-08-03 14:57:36.794 431-431 netd pid-431 I interfaceSetEnableIPv6(eth0, true) <0.11ms>
2023-08-03 14:57:36.795 431-431 netd pid-431 I interfaceSetCfg(InterfaceConfigurationParcel{ifName: eth0, hwAddr: , ipv4Addr: 192.168.0.95, prefixLength: 24, flags: []}) <0.09ms>
2023-08-03 14:57:36.795 627-2212 EthernetNe...FactoryExt system_process D onLinkPropertiesChange
2023-08-03 14:57:36.796 431-431 netd pid-431 I setProcSysNet(4, 2, eth0, retrans_time_ms, 750) <0.03ms>
2023-08-03 14:57:36.796 431-431 netd pid-431 I setProcSysNet(4, 2, eth0, ucast_solicit, 5) <0.02ms>
2023-08-03 14:57:36.796 431-431 netd pid-431 I setProcSysNet(6, 2, eth0, retrans_time_ms, 750) <0.03ms>
2023-08-03 14:57:36.796 431-431 netd pid-431 I setProcSysNet(6, 2, eth0, ucast_solicit, 5) <0.02ms>
2023-08-03 14:57:36.796 431-431 netd pid-431 I setProcSysNet(4, 2, eth0, retrans_time_ms, 750) <0.02ms>
2023-08-03 14:57:36.796 431-431 netd pid-431 I setProcSysNet(4, 2, eth0, ucast_solicit, 10) <0.01ms>
2023-08-03 14:57:36.796 431-431 netd pid-431 I setProcSysNet(6, 2, eth0, retrans_time_ms, 750) <0.02ms>
2023-08-03 14:57:36.797 431-431 netd pid-431 I setProcSysNet(6, 2, eth0, ucast_solicit, 10) <0.01ms>
2023-08-03 14:57:36.798 627-2212 EthernetNe...FactoryExt system_process D onProvisioningSuccess
2023-08-03 14:57:36.798 627-2212 EthernetNe...FactoryExt system_process D addToLocalNetwork: iface = eth0
// 设置路由表
2023-08-03 14:57:36.799 431-431 netd pid-431 I networkAddInterface(99, eth0) <0.81ms>
2023-08-03 14:57:36.799 431-431 netd pid-431 I networkAddRoute(99, eth0, fe80::/64, ) <0.08ms>
2023-08-03 14:57:36.799 431-431 netd pid-431 I networkAddRoute(99, eth0, 192.168.0.0/24, ) <0.04ms>
2023-08-03 14:57:36.799 431-431 netd pid-431 I networkAddRoute(99, eth0, 255.255.0.0/32, ) <0.05ms>
2023-08-03 14:57:36.799 431-431 libnetd_resolv pid-431 E Error adding route fe80::/64 -> (null) eth0 to table 97: File exists
2023-08-03 14:57:36.799 431-431 netd pid-431 I networkAddRoute(99, eth0, fe80::/64, ) <0.05ms>
``
**rk3588 eth1() log**
```txt
// 加载网卡
2023-08-03 16:17:14.297 0-0 [ C6] r8168 pid-0 I eth1: link up
2023-08-03 16:17:14.297 190-190 <no-tag> pid-190 W [dhd] CFG80211-ERROR) wl_cfg80211_netdev_notifier_call : wdev null. Do nothing
2023-08-03 16:17:12.342 617-646 EthernetTracker system_process I interfaceLinkStateChanged, iface: eth1, up: true
2023-08-03 16:17:12.342 617-774 EthernetNetworkFactory system_process D updateInterfaceLinkState, iface: eth1, up: true
2023-08-03 16:17:12.342 617-774 EthernetNetworkFactory system_process D Starting Ethernet IpClient(eth1)
2023-08-03 16:17:12.343 617-774 EthernetNe...FactoryExt system_process D interfaceLinkStateChanged: iface = eth1, mIface = eth0,up:true,mLinkUp:false
2023-08-03 16:17:12.344 617-2329 IpClient.eth1 system_process E Failed to set accept_ra to 2
2023-08-03 16:17:12.350 617-774 ConnectivityService system_process D registerNetworkAgent NetworkAgentInfo{network{104} handle{450082295821} ni{Ethernet CONNECTING extra: fa:41:32:8f:77:bc} Score(70 ; KeepConnected : 0 ; Policies : IS_UNMETERED) lp nc{[ Transports: ETHERNET Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED&NOT_VCN_MANAGED LinkUpBandwidth>=100000Kbps LinkDnBandwidth>=100000Kbps]}}
2023-08-03 16:17:12.351 617-735 ConnectivityService system_process D [104 ETHERNET] EVENT_NETWORK_INFO_CHANGED, going from CONNECTING to CONNECTING
2023-08-03 16:17:12.351 617-735 ConnectivityService system_process D [104 ETHERNET] EVENT_NETWORK_INFO_CHANGED, going from CONNECTING to CONNECTED
2023-08-03 16:17:12.352 617-735 DnsManager system_process W updatePrivateDns(104, PrivateDnsConfig{true:/[]})
2023-08-03 16:17:12.352 617-735 ConnectivityService system_process D Setting DNS servers for network 104 to [/192.168.43.1]
2023-08-03 16:17:12.352 617-735 DnsManager system_process D sendDnsConfigurationForNetwork(104, [192.168.43.1], [], 1800, 25, 8, 64, 0, 0, , [192.168.43.1])
2023-08-03 16:17:12.352 426-2331 resolv pid-426 W Validating DnsTlsServer 192.168.43.1 with mark 0xf0068
2023-08-03 16:17:12.352 617-735 ConnectivityService system_process D Adding iface eth1 to network 104
2023-08-03 16:17:12.352 426-2331 resolv pid-426 W Socket failed to connect: Network is unreachable
2023-08-03 16:17:12.353 426-2331 resolv pid-426 W TCP Handshake failed: 101
2023-08-03 16:17:12.353 426-2331 resolv pid-426 W query failed
2023-08-03 16:17:12.353 426-2331 resolv pid-426 W validateDnsTlsServer returned 0 for 192.168.43.1
2023-08-03 16:17:12.353 426-2331 resolv pid-426 W Validation failed
2023-08-03 16:17:12.354 617-735 ConnectivityService system_process D Setting DNS servers for network 104 to [/192.168.43.1]
2023-08-03 16:17:12.354 617-735 DnsManager system_process D sendDnsConfigurationForNetwork(104, [192.168.43.1], [], 1800, 25, 8, 64, 0, 0, , [192.168.43.1])
2023-08-03 16:17:12.355 426-2332 resolv pid-426 W Validating DnsTlsServer 192.168.43.1 with mark 0xf0068
2023-08-03 16:17:12.388 617-735 ConnectivityService system_process D NetReassign [no changes]
2023-08-03 16:17:14.676 617-2329 IpClient.eth1 system_process W [IpReachabilityMonitor] WARN ALERT neighbor went from: null to: NeighborEvent{@284903,RTM_NEWNEIGH,if=9,192.168.43.1,NUD_FAILED,[null]}
2023-08-03 16:17:14.676 426-2332 resolv pid-426 W SSL_connect ssl error =5, mark 0xf0068: No route to host
2023-08-03 16:17:14.676 426-2332 resolv pid-426 W TLS Handshake failed
2023-08-03 16:17:14.676 617-2329 IpReachabilityMonitor system_process W FAILURE: LOST_PROVISIONING, NeighborEvent{@284903,RTM_NEWNEIGH,if=9,192.168.43.1,NUD_FAILED,[null]}
2023-08-03 16:17:14.676 426-2332 resolv pid-426 W query failed
2023-08-03 16:17:14.676 426-2332 resolv pid-426 W validateDnsTlsServer returned 0 for 192.168.43.1
2023-08-03 16:17:14.676 426-2332 resolv pid-426 W Validation failed
2023-08-03 16:17:16.996 617-2329 IpClient.eth1 system_process W [IpReachabilityMonitor] WARN ALERT neighbor went from: NeighborEvent{@284903,RTM_NEWNEIGH,if=9,192.168.43.1,NUD_FAILED,[null]} to: NeighborEvent{@287223,RTM_NEWNEIGH,if=9,192.168.43.1,NUD_FAILED,[null]}
2023-08-03 16:17:16.996 617-2329 IpReachabilityMonitor system_process W FAILURE: LOST_PROVISIONING, NeighborEvent{@287223,RTM_NEWNEIGH,if=9,192.168.43.1,NUD_FAILED,[null]}
2023-08-03 16:17:17.387 617-735 ConnectivityService system_process D handleLingerComplete for [104 ETHERNET]
2023-08-03 16:17:19.716 617-2329 IpClient.eth1 system_process W [IpReachabilityMonitor] WARN ALERT neighbor went from: NeighborEvent{@287223,RTM_NEWNEIGH,if=9,192.168.43.1,NUD_FAILED,[null]} to: NeighborEvent{@289943,RTM_NEWNEIGH,if=9,192.168.43.1,NUD_FAILED,[null]}
2023-08-03 16:17:19.716 617-2329 IpReachabilityMonitor system_process W FAILURE: LOST_PROVISIONING, NeighborEvent{@289943,RTM_NEWNEIGH,if=9,192.168.43.1,NUD_FAILED,[null]}
2023-08-03 16:17:22.401 617-617 DnsResolver system_process W resNetworkResult:android.system.ErrnoException: resNetworkResult failed: ETIMEDOUT (Connection timed out)
2023-08-03 16:17:22.401 617-2335 NetworkMonitor/104 system_process D PROBE_DNS www.google.cn 10011ms FAIL in type ADDRCONFIG android.net.DnsResolver$DnsException: android.system.ErrnoException: resNetworkResult failed: ETIMEDOUT (Connection timed out)
2023-08-03 16:17:24.894 617-2334 NetworkMonitor/104 system_process D PROBE_DNS www.google.cn 12503ms FAIL in type ADDRCONFIG Timeout
2023-08-03 16:17:25.402 617-2333 NetworkMonitor/104 system_process D PROBE_FALLBACK http://www.googleapis.cn/generate_204 Probe failed with exception java.net.UnknownHostException: Unable to resolve host "www.googleapis.cn": No address associated with hostname
2023-08-03 16:17:32.414 617-2335 NetworkMonitor/104 system_process D PROBE_HTTP http://www.google.cn/generate_204 Probe failed with exception java.net.UnknownHostException: Unable to resolve
2023-08-03 16:17:42.423 617-2334 NetworkMonitor/104 system_process D PROBE_HTTPS https://www.google.cn/generate_204 Probe failed with exception java.net.UnknownHostException: Unable to resolve host "www.google.cn": No address associated with hostname
2023-08-03 16:17:42.423 617-2333 NetworkMonitor/104 system_process D isCaptivePortal: isSuccessful()=false isPortal()=false RedirectUrl=null isPartialConnectivity()=false Time=30034ms
2023-08-03 16:17:42.424 617-735 ConnectivityService system_process D [104 ETHERNET] validation failed
dumpsys ethernet
rk3588_s:/ $ dumpsys ethernet
Current Ethernet state:
EthernetTracker
Ethernet interface name filter: eth1
Default interface: eth1
Default interface mode: 1
Tethered interface requests: 0
Listeners: 0
IP Configurations:
eth1: IP assignment: STATIC
Static configuration: IP address 192.168.43.5/16 Gateway 192.168.43.1 DNS servers: [ 192.168.43.1 0.0.0.0 ] Domains
Proxy settings: NONE
eth0: IP assignment: STATIC
Static configuration: IP address 192.168.0.95/16 Gateway 192.168.0.1 DNS servers: [ 192.168.0.1 0.0.0.0 ] Domains
Proxy settings: NONE
Network Capabilities:
providerId=1, ScoreFilter=Score(70 ; Policies : 0), Filter=[ Transports: ETHERNET Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&NOT_CONGESTED&NOT_SUSPENDED&NOT_VCN_MANAGED], requests=12
{NetworkRequest [ REQUEST id=25, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VCN_MANAGED Uid: 10047 RequestorUid: 10047 RequestorPkg: com.android.systemui] ], requested=false}
{NetworkRequest [ REQUEST id=7, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VCN_MANAGED Uid: 1000 RequestorUid: 1000 RequestorPkg: android] ], requested=false}
{NetworkRequest [ REQUEST id=18, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VCN_MANAGED Uid: 1000 RequestorUid: 1000 RequestorPkg: com.android.networkstack.inprocess] ], requested=false}
{NetworkRequest [ REQUEST id=14, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VCN_MANAGED Uid: 10033 RequestorUid: 1000 RequestorPkg: android] ], requested=false}
{NetworkRequest [ REQUEST id=16, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VCN_MANAGED Uid: 1000 RequestorUid: 1000 RequestorPkg: android] ], requested=false}
{NetworkRequest [ REQUEST id=1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_VCN_MANAGED RequestorUid: 1000 RequestorPkg: android] ], requested=false}
{NetworkRequest [ REQUEST id=23, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VCN_MANAGED Uid: 10047 RequestorUid: 10047 RequestorPkg: com.android.systemui] ], requested=false}
{NetworkRequest [ REQUEST id=29, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VCN_MANAGED Uid: 1001 RequestorUid: 1001 RequestorPkg: com.android.phone] ], requested=false}
{NetworkRequest [ REQUEST id=33, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VCN_MANAGED Uid: 1000 RequestorUid: 1000 RequestorPkg: android] ], requested=true}
{NetworkRequest [ REQUEST id=34, [ Capabilities: NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_VCN_MANAGED Uid: 1000 RequestorUid: 1000 RequestorPkg: com.wif.baseservice] ], requested=true}
{NetworkRequest [ REQUEST id=40, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VCN_MANAGED Uid: 10043 RequestorUid: 1000 RequestorPkg: android] ], requested=true}
{NetworkRequest [ REQUEST id=42, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VCN_MANAGED Uid: 10003 RequestorUid: 1000 RequestorPkg: android] ], requested=true}
EthernetNetworkFactory
Tracking interfaces:
eth1:NetworkInterfaceState{ refCount: 4, iface: eth1, up: true, hwAddress: fa:41:32:8f:77:bc, networkCapabilities: [ Transports: ETHERNET Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&NOT_CONGESTED&NOT_SUSPENDED&NOT_VCN_MANAGED LinkUpBandwidth>=100000Kbps LinkDnBandwidth>=100000Kbps], networkAgent: com.android.server.ethernet.EthernetNetworkFactory$NetworkInterfaceState$1@595c638, score: 70, ipClient: android.net.ip.IIpClient$Stub$Proxy@a7aa611,linkProperties: {InterfaceName: eth1 LinkAddresses: [ fe80::421b:260f:1da:f2dd/64,192.168.43.5/16 ] DnsAddresses: [ /192.168.43.1 ] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,3145728,524288,1048576,2097152 Routes: [ fe80::/64 -> :: eth1 mtu 0,192.168.0.0/16 -> 0.0.0.0 eth1 mtu 0,0.0.0.0/0 -> 192.168.43.1 eth1 mtu 0 ]}}
IpClient logs have moved to dumpsys network_stack
Handler:
EthernetServiceImplHandler (android.os.Handler) {be88fea} @ 971345
EthernetServiceImpl Looper (EthernetServiceThread, tid 127) {6dac2db}
EthernetServiceImpl (Total messages: 0, polling=true, quitting=false)
源码流程区别
EthernetTracker
final class EthernetTracker {
void start() {
mConfigStore.read();
// Default interface is just the first one we want to track.
mIpConfigForDefaultInterface = mConfigStore.getIpConfigurationForDefaultInterface();
final ArrayMap<String, IpConfiguration> configs = mConfigStore.getIpConfigurations();
for (int i = 0; i < configs.size(); i++) {
mIpConfigurations.put(configs.keyAt(i), configs.valueAt(i));
}
try {
mNMService.registerObserver(new InterfaceObserver());
} catch (RemoteException e) {
Log.e(TAG, "Could not register InterfaceObserver " + e);
}
mHandler.post(this::trackAvailableInterfaces);
}
private class InterfaceObserver extends BaseNetworkObserver {
@Override
public void interfaceLinkStateChanged(String iface, boolean up) {
if (DBG) {
Log.i(TAG, "interfaceLinkStateChanged, iface: " + iface + ", up: " + up);
}
if(isEthernetInterfaceActive())
mHandler.post(() -> updateInterfaceState(iface, up));
else{
if (iface.matches(mIfaceMatch)){
mHandler.post(() -> updateInterfaceState(iface, false));
Settings.System.putInt(mContext.getContentResolver(),Settings.System.ETHERNET_ON,0);
}}
mHandler.post(() -> mEthernetNetworkFactoryExt.interfaceLinkStateChanged(iface, up));
}
@Override
public void interfaceAdded(String iface) {
mHandler.post(() -> maybeTrackInterface(iface));
mHandler.post(() -> mEthernetNetworkFactoryExt.interfaceAdded(iface));
}
@Override
public void interfaceRemoved(String iface) {
mHandler.post(() -> stopTrackingInterface(iface));
mHandler.post(() -> mEthernetNetworkFactoryExt.interfaceRemoved(iface));
}
}
}
EthernetNetworkFactoryExt 管理内网
class EthernetNetworkFactoryExt {
public void interfaceLinkStateChanged(String iface, boolean up) {
Log.d(TAG, "interfaceLinkStateChanged: iface = " + iface + ", mIface = " + mIface+",up:"+up+",mLinkUp:"+mLinkUp);
if (!mIface.equals(iface))
return;
if (mLinkUp == up)
return;
mLinkUp = up;
if (up) {
mHandler.removeMessages(EVENT_INTERFACE_LINK_STATE_CHANGED);
mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_INTERFACE_LINK_STATE_CHANGED, 1, 0),
EVENT_INTERFACE_LINK_STATE_CHANGED_DELAY_MS);
} else {
mHandler.removeMessages(EVENT_INTERFACE_LINK_STATE_CHANGED);
mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_INTERFACE_LINK_STATE_CHANGED, 0, 0),
0);
}
}
private class EthernetNetworkFactoryExtHandler extends Handler {
private EthernetNetworkFactoryExt mEthernetNetworkFactoryExt;
public EthernetNetworkFactoryExtHandler(Looper looper, EthernetNetworkFactoryExt factory) {
super(looper);
mEthernetNetworkFactoryExt = factory;
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_INTERFACE_LINK_STATE_CHANGED:
if(msg.arg1 == 1) {
mEthernetNetworkFactoryExt.connect();
} else {
mEthernetNetworkFactoryExt.disconnect();
}
break;
}
}
}
private void connect() {
Thread connectThread = new Thread(new Runnable() {
public void run() {
if (mConnectState == 1) {
Log.d(TAG, "already connected, skip");
return;
}
mConnectState = 2;
mMode = SystemProperties.get("persist.eth.ext.mode", "0");
if (mMode.equals("0")) { // DHCP
mIpConfiguration.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
if (!startDhcp(mIface, mIpConfiguration)) {
Log.e(TAG, "startDhcp failed for " + mIface);
mConnectState = 0;
sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_DISCONNECTED);
return;
}
Log.d(TAG, "startDhcp success for " + mIface);
sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_CONNECTED);
} else { // Static
setStaticIpConfiguration();
if (!setStaticIpAddress(mStaticIpConfiguration)) {
// We've already logged an error.
if (DBG) Log.i(TAG, "setStaticIpAddress error,set again");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!setStaticIpAddress(mStaticIpConfiguration)) {
mConnectState = 0;
sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_DISCONNECTED);
return;
}
}
//add dhcpserver
if (SystemProperties.get("persist.dhcpserver.enable", "0").equals("1")) {
startDhcpServer();
}
sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_CONNECTED);
}
mConnectState = 1;
}
});
connectThread.start();
}
/* For Android 7.x */
private boolean startDhcp(String iface, IpConfiguration ipconfig) {
Log.d(TAG, "IpClient.startProvisioning");
stopDhcp(iface);
sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_CONNECTING);
mIpClientCallback = new IpClientCallbacksImpl();
IpClientUtil.makeIpClient(mContext, mIface, mIpClientCallback);
mIpClientCallback.awaitIpClientStart();
final ProvisioningConfiguration config;
if (ipconfig.getIpAssignment() == IpAssignment.STATIC) {
config = new ProvisioningConfiguration.Builder()
.withStaticConfiguration(ipconfig.getStaticIpConfiguration())
.build();
} else {
config = new ProvisioningConfiguration.Builder()
.withProvisioningTimeoutMs(0)
.build();
}
try {
mIpClient.startProvisioning(config.toStableParcelable());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
return true;
}
}
EthernetNetworkFactory管理外网
APP 指定某个网络上网
APP
NetworkRequest request = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.build();
mNetworkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(final Network network) { // 找到可用网络后的回调
runOnUiThread(new Runnable() {
@Override
public void run() {
// requires android.permission.INTERNET
if (!mConnectivityManager.bindProcessToNetwork(network)) {
} else {
Log.d(TAG, "Network available");
}
}
});
}
connectivityManager.requestNetwork(request, callback);
framework–ConnectivityManager
public class ConnectivityManager {
@SystemApi
@RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
public void requestNetwork(@NonNull NetworkRequest request,
int timeoutMs, int legacyType, @NonNull Handler handler,
@NonNull NetworkCallback networkCallback) {
if (legacyType == TYPE_NONE) {
throw new IllegalArgumentException("TYPE_NONE is meaningless legacy type");
}
CallbackHandler cbHandler = new CallbackHandler(handler);
NetworkCapabilities nc = request.networkCapabilities;
sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, legacyType, cbHandler);
}
private NetworkRequest sendRequestForNetwork(int asUid, NetworkCapabilities need,
NetworkCallback callback, int timeoutMs, NetworkRequest.Type reqType, int legacyType,
CallbackHandler handler) {
printStackTrace();
checkCallbackNotNull(callback);
if (reqType != TRACK_DEFAULT && reqType != TRACK_SYSTEM_DEFAULT && need == null) {
throw new IllegalArgumentException("null NetworkCapabilities");
}
final NetworkRequest request;
final String callingPackageName = mContext.getOpPackageName();
try {
synchronized(sCallbacks) {
if (callback.networkRequest != null
&& callback.networkRequest != ALREADY_UNREGISTERED) {
// TODO: throw exception instead and enforce 1:1 mapping of callbacks
// and requests (http://b/20701525).
Log.e(TAG, "NetworkCallback was already registered");
}
Messenger messenger = new Messenger(handler);
Binder binder = new Binder();
final int callbackFlags = callback.mFlags;
if (reqType == LISTEN) {
request = mService.listenForNetwork(
need, messenger, binder, callbackFlags, callingPackageName,
getAttributionTag());
} else {
request = mService.requestNetwork(
asUid, need, reqType.ordinal(), messenger, timeoutMs, binder,
legacyType, callbackFlags, callingPackageName, getAttributionTag());
}
if (request != null) {
sCallbacks.put(request, callback);
}
callback.networkRequest = request;
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
} catch (ServiceSpecificException e) {
throw convertServiceException(e);
}
return request;
}
private class CallbackHandler extends Handler {
@Override
public void handleMessage(Message message) {
if (message.what == EXPIRE_LEGACY_REQUEST) {
expireRequest((NetworkCapabilities) message.obj, message.arg1);
return;
}
final NetworkRequest request = getObject(message, NetworkRequest.class);
final Network network = getObject(message, Network.class);
final NetworkCallback callback;
synchronized (sCallbacks) {
callback = sCallbacks.get(request);
if (callback == null) {
Log.w(TAG,
"callback not found for " + getCallbackName(message.what) + " message");
return;
}
if (message.what == CALLBACK_UNAVAIL) {
sCallbacks.remove(request);
callback.networkRequest = ALREADY_UNREGISTERED;
}
}
if (DBG) {
Log.d(TAG, getCallbackName(message.what) + " for network " + network);
}
switch (message.what) {
case CALLBACK_PRECHECK: {
callback.onPreCheck(network);
break;
}
case CALLBACK_AVAILABLE: {
NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
LinkProperties lp = getObject(message, LinkProperties.class);
callback.onAvailable(network, cap, lp, message.arg1); // 回调到app里面
break;
}
case CALLBACK_LOSING: {
callback.onLosing(network, message.arg1);
break;
}
case CALLBACK_LOST: {
callback.onLost(network);
break;
}
case CALLBACK_UNAVAIL: {
callback.onUnavailable();
break;
}
case CALLBACK_CAP_CHANGED: {
NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
callback.onCapabilitiesChanged(network, cap);
break;
}
case CALLBACK_IP_CHANGED: {
LinkProperties lp = getObject(message, LinkProperties.class);
callback.onLinkPropertiesChanged(network, lp);
break;
}
case CALLBACK_SUSPENDED: {
callback.onNetworkSuspended(network);
break;
}
case CALLBACK_RESUMED: {
callback.onNetworkResumed(network);
break;
}
case CALLBACK_BLK_CHANGED: {
callback.onBlockedStatusChanged(network, message.arg1);
}
}
}
}
public boolean bindProcessToNetwork(@Nullable Network network) {
// Forcing callers to call through non-static function ensures ConnectivityManager
// instantiated.
return setProcessDefaultNetwork(network);
}
@Deprecated
public static boolean setProcessDefaultNetwork(@Nullable Network network) {
int netId = (network == null) ? NETID_UNSET : network.netId;
boolean isSameNetId = (netId == NetworkUtils.getBoundNetworkForProcess());
if (netId != NETID_UNSET) {
netId = network.getNetIdForResolv();
}
if (!NetworkUtils.bindProcessToNetwork(netId)) {
return false;
}
if (!isSameNetId) {
// Set HTTP proxy system properties to match network.
// TODO: Deprecate this static method and replace it with a non-static version.
try {
Proxy.setHttpProxyConfiguration(getInstance().getDefaultProxy());
} catch (SecurityException e) {
// The process doesn't have ACCESS_NETWORK_STATE, so we can't fetch the proxy.
Log.e(TAG, "Can't set proxy properties", e);
}
// Must flush DNS cache as new network may have different DNS resolutions.
InetAddress.clearDnsCache();
// Must flush socket pool as idle sockets will be bound to previous network and may
// cause subsequent fetches to be performed on old network.
NetworkEventDispatcher.getInstance().dispatchNetworkConfigurationChange();
}
return true;
}
}
NetworkUtils.java
private static native boolean bindProcessToNetworkHandle(long netHandle);
public static boolean bindProcessToNetwork(int netId) {
return bindProcessToNetworkHandle(new Network(netId).getNetworkHandle());
}
dumpsys netd
rk3588_s:/ $ dumpsys netd
ppid:1 -> pid:432 -> tid:432
total running time: 0d0h32m38s213ms (1958213ms)
user: 0s160ms sys: 0s219ms
maxrss: 9728kB
NetworkController
Default network: 102 // netId
Networks:
51 DUMMY dummy0
52 UNREACHABLE
99 LOCAL eth1
102 PHYSICAL usb0
Required permission: NONE
106 PHYSICAL eth0
Required permission: NONE
Interface <-> last network map:
Ifindex: 4 NetId: 106
Ifindex: 12 NetId: 102
Interface addresses:
address: 192.168.0.95/24 ifindices: [9]
address: fe80::c1d0:6f3b:e7c8:56ce/64 ifindices: [9]
address: fe80::c753:c959:5a7d:a7e7/64 ifindices: [4]
address: 192.168.0.95/16 ifindices: [4]
address: 10.200.241.183/8 ifindices: [12]
address: fe80::ac0c:29ff:fea3:9b6d/64 ifindices: [12]
TrafficController
mCookieTagMap status: OK
mUidCounterSetMap status: OK
mAppUidStatsMap status: OK
mStatsMapA status: OK
mStatsMapB status: OK
mIfaceIndexNameMap status: OK
mIfaceStatsMap status: OK
mConfigurationMap status: OK
mUidOwnerMap status: OK
Cgroup ingress program status: OK
Cgroup egress program status: OK
xt_bpf ingress program status: OK
xt_bpf egress program status: OK
xt_bpf bandwidth allowlist program status: OK
xt_bpf bandwidth denylist program status: OK
XfrmController
XFRM-I support: 1
ClatdController
Trackers: iif[iface] nat64Prefix v6Addr -> v4Addr v4iif[v4iface] [fwmark]
BPF ingress map: iif(iface) nat64Prefix v6Addr -> v4Addr oif(iface)
BPF egress map: iif(iface) v4Addr -> v6Addr nat64Prefix oif(iface)
TetherController
Forwarding requests:
Interface pairs:
Log:
08-03 09:41:09.188 netd 1.0 starting
08-03 09:41:09.198 Pid file removed
08-03 09:41:09.198 SIGPIPE is blocked
08-03 09:41:09.198 setCloseOnExec(dnsproxyd)