问题背景

最近在调试一个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上配网络,别忘了策略路由表!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐