性能·网络 / 命令文档

Linux内核网络栈研究

$ network 17 个章节 Linux 命令详解

概述

从数据包接收到发送深入其中

学习目标

通过本课程,你将深入理解Linux内核如何处理网络数据包,掌握从硬件中断到用户空间的完整数据流程,并了解网络栈各层的核心机制。

7用户空间应用层

应用程序通过Socket API与内核通信

6Socket层

提供统一的网络编程接口,管理socket描述符

5传输层 (TCP/UDP)

处理端到端的可靠传输和不可靠传输

4网络层 (IP)

处理路由、分片、重组等网络层功能

3Netfilter框架

提供包过滤、NAT、连接跟踪等功能

2数据链路层

处理以太网帧、ARP协议等

1网络设备驱动层

与网卡硬件直接交互,处理中断和DMA

从网卡到应用程序的数据包旅程

网卡接收数据包

硬件中断

DMA传输

软中断(NET_RX)

协议栈处理

Socket缓冲

用户空间读取

关键概念:NAPI (New API) 现代Linux使用NAPI机制来优化网络性能,在高负载时切换到轮询模式,避免中断风暴。

// 简化的数据包接收流程
网卡:通过DMA方式,将网络包放到收包队列中,然后硬中断
网卡中断处理程序:
static int netif_rx(struct sk_buff *skb)
{
    // 1. 获取当前CPU的接收队列
    struct softnet_data *sd = this_cpu_ptr(&softnet_data);
    
    // 2. 将数据包加入队列
    enqueue_to_backlog(skb, get_cpu(), &qtail);
    
    // 3. 触发软中断处理
    __raise_softirq_irqoff(NET_RX_SOFTIRQ);
    
    return NET_RX_SUCCESS;
}
// 软中断处理函数
static void net_rx_action(struct softirq_action *h)
{
    // 处理接收队列中的所有数据包
    process_backlog(&sd->process_queue, "a, jiffies + 2);
}
内核协议栈:从缓冲区取出网络帧
网络协议栈:从下到上处理网络帧
    - 链路层:解析以太网帧,去掉帧头帧尾,交给网络层
    - 网络层:对IP头进行处理,确认需要本机处理,去掉IP头,交给传输层
    - 传输层:对TCP/UDP报文处理,根据(源IP,源端口,目标IP,目标端口)找出对应的socket,将数据包copy到对应Socket的接收缓存中
用户空间应用程序:通过Socket调用读取应用数据

从应用程序到网卡的数据包旅程

应用程序发送

Socket层处理

协议栈封装

队列规程(Qdisc)

网卡驱动

DMA传输

物理发送

性能优化:TX队列管理 现代网卡支持多队列发送,可以并行处理多个数据流,显著提高发送性能。

sk_buff - 网络数据包的抽象

struct sk_buff {
    struct sk_buff *next, *prev;    // 链表指针
    struct net_device *dev;         // 关联的网络设备
    
    unsigned int len;               // 数据长度
    unsigned int data_len;          // 分片数据长度
    
    __u16 protocol;                 // 协议类型
    __u16 transport_header;         // 传输层头偏移
    __u16 network_header;           // 网络层头偏移
    __u16 mac_header;              // MAC层头偏移
    
    unsigned char *data;            // 数据指针
    unsigned char *tail;            // 尾部指针
    unsigned char *end;             // 缓冲区结束
    unsigned char *head;            // 缓冲区开始
    
    struct sock *sk;                // 关联的socket
};

sk_buff是Linux网络栈的核心数据结构,它抽象了网络数据包,支持零拷贝操作和高效的头部操作。

net_device - 网络设备抽象

struct net_device {
    char name[IFNAMSIZ];            // 设备名称 (eth0, wlan0等)
    
    struct net_device_ops *netdev_ops;  // 设备操作函数集
    
    unsigned int mtu;               // 最大传输单元
    unsigned char addr_len;         // 硬件地址长度
    unsigned char dev_addr[MAX_ADDR_LEN]; // MAC地址
    
    struct netdev_queue *_tx;       // 发送队列
    unsigned int real_num_tx_queues; // 实际TX队列数
    
    struct Qdisc *qdisc;           // 队列规程
    
    const struct net_device_stats *(*get_stats)(struct net_device *dev);
};

socket - 套接字抽象

struct socket {
    socket_state state;             // socket状态
    short type;                     // socket类型 (SOCK_STREAM/DGRAM)
    
    unsigned long flags;            // 标志位
    struct file *file;              // 关联的文件描述符
    struct sock *sk;                // 协议相关的sock结构
    
    const struct proto_ops *ops;    // 协议操作函数集
    
    struct socket_wq __rcu *wq;     // 等待队列
};

网络性能优化技术

技术作用适用场景性能提升
NAPI中断与轮询混合模式高负载网络环境减少CPU中断开销
多队列网卡并行处理多个数据流多核CPU系统提高并发处理能力
CPU亲和性绑定中断到特定CPU延迟敏感应用减少缓存miss
零拷贝避免数据在内核和用户空间拷贝大量数据传输显著减少CPU使用
TSO/GSO大包分段卸载高带宽应用减少协议栈开销

实战调试技巧

常用调试工具和命令
# 查看网络接口统计信息
cat /proc/net/dev

# 查看socket连接状态
ss -tuln

# 监控网络中断
watch -n 1 'cat /proc/interrupts | grep eth'

# 查看网络队列状态
tc -s qdisc show dev eth0

# 使用perf分析网络性能
perf record -g -e cycles:k -- stress-network
perf report

性能调优参数: • net.core.rmem_max: 增加接收缓冲区大小 • net.core.wmem_max: 增加发送缓冲区大小 • net.core.netdev_max_backlog: 调整网卡队列长度 • net.ipv4.tcp_rmem/tcp_wmem: TCP专用缓冲区设置

总结与要点

记住这些核心概念: 1. 网络栈是分层架构,每层都有特定的职责 2. sk_buff是数据包在内核中的统一表示 3. NAPI机制是现代网络性能优化的基础 4. 理解中断和软中断的处理机制 5. 零拷贝和卸载技术是性能优化的关键

深入学习建议:
                1. 阅读内核源码,特别是net/core目录
                2. 实际配置和调优网络参数
                3. 使用工具分析网络性能瓶颈
                4. 理解不同应用场景的优化策略

同分类 · 其他命令文档