1. Android 内核网络栈概述

Android 网络栈是一个从应用层到物理层的多层软件体系,其核心基于 Linux 内核网络子系统。理解 Android 网络架构的分层模型、与标准 Linux 内核网络栈的关系,以及数据包在内核中的流转路径,是进行网络栈调试与驱动优化的基础。

1.1 Android 网络架构分层

Android 网络架构从上到下可划分为五个主要层次,每一层负责不同的抽象与功能:

层次 组件/示例 主要职责
应用层 App、Browser、Netd 发起网络请求,调用 Java Framework API
Framework 层 ConnectivityService、WifiService、NetworkPolicyManager 网络策略管理、连接状态跟踪、权限控制
系统服务层 netd (Network Daemon)、DNS 解析、防火墙(iptables) 网络配置下发、NAT、防火墙规则、带宽控制
内核网络栈 TCP/IP 协议栈、Netfilter、Traffic Control 协议处理、路由、过滤、QoS
驱动层 Wi-Fi 驱动、BT 驱动、USB 网络驱动、Ethernet 驱动 硬件抽象、中断处理、DMA 传输、NAPI
关键点: Android 的 Framework 层和系统服务层是 Android 特有的扩展,而内核网络栈与驱动层则直接继承自 Linux 主线内核,但 Android 进行了大量移动场景下的优化与定制。

1.2 Linux 内核网络栈与 Android 的关系

Android 内核网络栈基于 Linux 主线内核网络子系统,但并非完全照搬。Android 在以下方面进行了深度定制与增强:

  • Binder 集成: 网络策略、DNS 配置等通过 Binder IPC 从 Framework 下发到 netd,再通过 Netlink 与内核交互。
  • WLAN 架构差异: Android 使用 wpa_supplicant / Wificond 管理 Wi-Fi 连接,内核侧通过 cfg80211 / nl80211 与用户态通信。
  • 网络命名空间: Android 大量使用网络命名空间实现多用户、VPN、热点的网络隔离。
  • eBPF 支持: 从 Android 10 开始,eBPF 被用于网络流量统计、套接字过滤和性能监控。
  • XT 目标扩展: Android 在 Netfilter 中增加了 xt_qtaguid、xt_owner 等模块,用于按 UID 进行流量统计与防火墙控制。
调试提示: 在 Android 内核中,/proc/net/ 和 netstat 命令依然可用,但更推荐使用 adb shell dumpsys connectivity 或 adb shell bpf net 获取 Android 特有的网络状态。

1.3 网络数据包在内核中的流转路径

一个网络数据包从网卡到达应用层,或从应用层发送到网卡,在内核中经历了一条精心设计的路径。以下以接收路径为例,展示核心阶段:

网络数据包接收路径(内核侧) ① 网卡驱动 ② NAPI 轮询 ③ 协议栈入口 ④ Netfilter 钩子 ⑤ 路由查找 ⑥ TCP/UDP 层 ⑦ Socket 队列 ⑧ 用户态读取 关键说明: • 驱动层通过 DMA 将数据写入 sk_buff,触发硬中断。 • NAPI 轮询机制减少中断次数,提升高吞吐场景性能。 • Netfilter 钩子点(NF_INET_PRE_ROUTING)是防火墙和 NAT 的关键介入点。 • 路由查找决定数据包是本地交付还是转发。

1.4 核心数据结构:sk_buff

在整个内核网络栈中,sk_buff(套接字缓冲区)是数据包在内核中流转的核心载体。它贯穿驱动层到协议栈的每一个环节。

// include/linux/skbuff.h (简化结构)
struct sk_buff {
    /* 链表管理 */
    struct sk_buff      *next;
    struct sk_buff      *prev;

    /* 协议信息 */
    __u16               protocol;
    __u16               mac_header;
    __u16               network_header;
    __u16               transport_header;

    /* 数据指针 */
    unsigned char       *head;
    unsigned char       *data;
    unsigned char       *tail;
    unsigned char       *end;

    /* 长度与校验 */
    unsigned int        len;
    __u32               hash;

    /* 设备与路由 */
    struct net_device   *dev;
    struct dst_entry    *dst;

    /* 安全与标记 */
    __u32               secmark;
    __u32               mark;
};
调试陷阱: 在驱动开发中,sk_buff 的 data 指针在协议栈各层会不断调整(如 push/pull 头部),切勿在驱动层直接修改 data 指针偏移,应使用 skb_push / skb_pull / skb_reserve 等 API。

1.5 发送路径与接收路径对比

阶段 接收路径 发送路径
入口 网卡硬中断 → NAPI 轮询 应用层 write() / sendmsg()
协议处理 L2 处理 → L3 路由 → L4 交付 L4 封装 → L3 路由 → L2 封装
过滤点 NF_INET_PRE_ROUTING NF_INET_POST_ROUTING
出口 Socket 接收队列 网卡驱动 xmit()
关键函数 netif_receive_skb() dev_queue_xmit()