三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Android开发板与Windows网络不通?原来是策略路由在作祟

Android开发板与Windows网络不通?原来是策略路由在作祟

问题背景

最近在调试一个CCU Android开发板与Windows PC的网络连接问题。开发板通过USB网卡与Windows直连,之前使用192.168.103.x网段时一切正常,但切换到192.168.100.x网段后,双方竟然ping不通了!

问题现象

  • Windows ping Android板子:超时

  • Android板子 ping Windows:Network is unreachable

  • 网络配置:Android板子IP为192.168.100.17/24,Windows PC IP为192.168.100.10/24

排查过程

第一层:检查网络配置脚本

首先怀疑是网络配置脚本setup_android_net.sh没有更新到新网段。检查脚本发现:

# 原脚本内容 ip route add 192.168.100.0/24 dev eth0 ip route add default via 192.168.100.1 dev eth0

发现问题:脚本里竟然没有给eth0设置IP地址!只有路由配置,没有ip addr add命令。

修复:在脚本中添加IP地址配置:

ip addr add 192.168.100.17/24 dev eth0

执行后确认eth0有了正确的IP,但ping仍然不通

第二层:确认Windows端配置

让用户在Windows端确认:

  1. USB网卡已配置为192.168.100.10/24

  2. 防火墙已关闭或添加了例外规则

  3. 网络连接状态正常

Windows端配置正确,但问题依旧。

第三层:深入Android网络栈

执行ip rule show查看路由策略,发现了关键线索:

# Android策略路由规则(简化版) 0: from all lookup local 10000: from all fwmark 0xc0000/0xd0000 lookup legacy_system 13000: from all fwmark 0x10063/0x1ffff lookup local_network 15000: from all fwmark 0x0/0x10000 lookup legacy_system 16000: from all fwmark 0x0/0x10000 lookup legacy_network 17000: from all fwmark 0x0/0x10000 lookup local_network 23000: from all fwmark 0x0/0xffff uidrange 0-0 lookup main 32000: from all unreachable # 兜底规则,直接返回不可达!

接着检查各个策略路由表的内容:

# 检查三个关键策略路由表 ip route show table local_network # 空的! ip route show table legacy_network # 空的! ip route show table legacy_system # 空的! # 检查main表(我们配置的路由在这里) ip route show table main # 输出:192.168.100.0/24 dev eth0 scope link src 192.168.100.17

根本原因分析

Android策略路由机制

Android从5.0开始使用复杂的策略路由来支持多网络并发。与传统的Linux系统不同,Android不会直接使用main路由表,而是通过一系列策略路由表来决定数据包的走向。

路由表优先级对比

路由表

表ID

说明

local

255

系统自动维护,存放本地IP和广播地址路由

local_network

-

Android策略路由表,优先级较高

legacy_network

-

Android策略路由表,优先级中等

legacy_system

-

Android策略路由表,优先级较低

main

254

Linux默认路由表,ip route show显示的就是这个

default

253

默认路由表

路由查找流程

Android的数据包路由查找顺序完全由ip rule show的输出决定:

  1. 规则0:先查local表 → 没匹配(因为目标不是本地地址)

  2. 规则10000-17000:查三个策略路由表(local_networklegacy_networklegacy_system)→全部为空,没匹配

  3. 规则23000:查main表 →这里有我们的路由,但优先级太低!

  4. 规则32000from all unreachable直接返回"Network is unreachable"

关键问题:虽然我们在main表中正确配置了192.168.100.0/24 dev eth0,但Android的策略路由机制根本不会查到这个表,因为前面的策略路由表都是空的,数据包在匹配到main表之前就被unreachable规则拦截了。

问题总结

两个问题叠加导致网络不通:

  1. 脚本缺陷:初始脚本缺少ip addr add命令,eth0没有IP地址

  2. Android特性:Android使用策略路由,需要将路由同时写入多个策略路由表

解决方案

修正网络配置脚本,同时解决两个问题:

#!/system/bin/sh # 修正后的setup_android_net.sh # 1. 设置IP地址(之前缺失的关键步骤) ip addr add 192.168.100.17/24 dev eth0 # 2. 在主路由表中添加路由(传统方式) ip route add 192.168.100.0/24 dev eth0 table main # 3. 在Android的三个策略路由表中都添加路由(关键!) ip route add 192.168.100.0/24 dev eth0 table local_network ip route add 192.168.100.0/24 dev eth0 table legacy_network ip route add 192.168.100.0/24 dev eth0 table legacy_system # 4. 添加默认路由(如果需要上网) ip route add default via 192.168.100.1 dev eth0 # 5. 刷新路由缓存 ip route flush cache # 6. 启动接口 ip link set eth0 up

验证命令

执行修正后的脚本后,使用以下命令验证:

# 检查IP地址 ip addr show eth0 # 检查所有路由表 ip route show table main ip route show table local_network ip route show table legacy_network ip route show table legacy_system # 测试连通性 ping -c 4 192.168.100.10 # 查看路由决策过程 ip route get 192.168.100.10

经验总结

  1. Android网络配置的特殊性:Android不是标准的Linux,它的网络栈经过深度定制,特别是策略路由机制。

  2. 路由表要写全:在Android上配置网络时,不能只写main表,还要考虑策略路由表。

  3. 排查思路

    • 先检查基础配置(IP地址、接口状态)

    • 再检查路由表(ip route show

    • 关键步骤:检查路由策略(ip rule show)和各策略路由表

  4. 调试命令组合

    # 快速诊断网络问题 ip addr show # 查看IP配置 ip route show # 查看主路由表 ip rule show # 查看路由策略 ip route show table <表名> # 查看特定路由表 ip route get <目标IP> # 查看具体路由决策
  5. 脚本健壮性:网络配置脚本应该包含完整的配置步骤,特别是容易被忽略的ip addr add

扩展知识

Android策略路由表的作用

  • local_network:处理本地网络流量

  • legacy_network:处理传统网络应用的流量

  • legacy_system:处理系统服务的网络流量

这些表的存在使得Android能够为不同应用、不同UID、不同网络标记(fwmark)的数据包提供不同的路由路径,实现精细化的网络管理。

为什么Android要这样设计?

Android作为移动操作系统,需要同时处理:

  • 蜂窝数据(4G/5G)

  • WiFi

  • 以太网

  • VPN

  • 热点共享

策略路由机制让Android能够根据数据包的来源、目的、标记等因素,智能地选择最佳的网络路径,实现多网络并发和网络切换的无缝体验。

结语

这次排查经历再次证明:了解系统底层机制的重要性。表面上看是简单的网络不通问题,深挖下去却是Android策略路由机制在"作祟"。希望这篇分享能帮助遇到类似问题的开发者少走弯路。

记住:在Android上配网络,别忘了策略路由表!

← 返回列表