第一部分:网络子系统总体架构

1.1 网络子系统分层结构树

Linux网络子系统
│
├── 【用户空间层】
│   ├── 应用程序 (sockets API)
│   │   ├── socket() / bind() / listen() / accept()
│   │   ├── send() / recv() / sendto() / recvfrom()
│   │   └── setsockopt() / getsockopt()
│   │
│   └── 配置工具
│       ├── iproute2 (ip命令)
│       ├── net-tools (ifconfig, route)
│       ├── ethtool
│       └── ss / netstat
│
├── 【系统调用接口层】net/socket.c
│   ├── SYSCALL_DEFINE3(socket, ...)     # socket()系统调用
│   ├── SYSCALL_DEFINE3(bind, ...)       # bind()系统调用
│   ├── SYSCALL_DEFINE3(connect, ...)    # connect()系统调用
│   ├── SYSCALL_DEFINE4(send, ...)       # send()系统调用
│   ├── SYSCALL_DEFINE4(recv, ...)       # recv()系统调用
│   └── sockfd_lookup_light()            # fd→socket结构转换
│
├── 【协议无关接口层】net/socket.c
│   ├── struct socket                    # BSD socket抽象
│   │   ├── struct file *file            # 关联的文件结构
│   │   ├── struct sock *sk              # INET socket层
│   │   ├── const struct proto_ops *ops  # 协议族操作
│   │   └── short type                   # SOCK_STREAM等
│   │
│   └── struct proto_ops                 # 协议族操作表
│       ├── .bind = inet_bind
│       ├── .connect = inet_stream_connect
│       ├── .accept = inet_accept
│       ├── .sendmsg = inet_sendmsg
│       └── .recvmsg = inet_recvmsg
│
├── 【INET Socket层】net/ipv4/af_inet.c
│   ├── struct sock                      # 传输层socket抽象
│   │   ├── struct sock_common __sk_common
│   │   │   ├── __be32 skc_daddr         # 目标IP
│   │   │   ├── __be32 skc_rcv_saddr     # 源IP
│   │   │   ├── __u16 skc_num            # 本地端口
│   │   │   └── __u16 skc_dport          # 目标端口
│   │   ├── struct sk_buff_head sk_receive_queue  # 接收队列
│   │   ├── struct sk_buff_head sk_write_queue     # 发送队列
│   │   ├── struct sk_buff_head sk_backlog         # 后备队列
│   │   ├── struct proto *sk_prot        # 传输层协议操作
│   │   └── struct socket *sk_socket     # 回指BSD socket
│   │
│   └── struct proto                     # 传输层协议操作表
│       ├── .hash = tcp_v4_hash
│       ├── .connect = tcp_v4_connect
│       ├── .sendmsg = tcp_sendmsg
│       └── .recvmsg = tcp_recvmsg
│
├── 【传输层协议】
│   ├── TCP (net/ipv4/tcp.c, tcp_input.c, tcp_output.c)
│   │   ├── tcp_v4_rcv()                 # TCP接收入口
│   │   ├── tcp_v4_sendmsg()             # TCP发送
│   │   ├── tcp_input.c                  # 输入处理
│   │   │   ├── tcp_rcv_established()    # 已建立连接接收
│   │   │   └── tcp_rcv_state_process()  # 状态机处理
│   │   ├── tcp_output.c                 # 输出处理
│   │   │   ├── tcp_sendmsg()            # 用户数据发送
│   │   │   └── tcp_write_xmit()         # 实际发送
│   │   └── tcp_timer.c                  # 定时器管理
│   │
│   ├── UDP (net/ipv4/udp.c)
│   │   ├── udp_rcv()                    # UDP接收入口
│   │   ├── udp_sendmsg()                # UDP发送
│   │   └── udp_queue_rcv_skb()          # 入队处理
│   │
│   └── RAW (net/ipv4/raw.c)
│       ├── raw_rcv()
│       └── raw_sendmsg()
│
├── 【网络层】net/ipv4/
│   ├── IP输入 (ip_input.c)
│   │   ├── ip_rcv()                     # IP包接收入口
│   │   ├── ip_rcv_finish()              # 接收完成处理
│   │   ├── ip_local_deliver()           # 本地投递
│   │   └── ip_local_deliver_finish()    # 本地投递完成
│   │
│   ├── IP转发 (ip_forward.c)
│   │   ├── ip_forward()                 # 转发处理
│   │   └── ip_forward_finish()
│   │
│   ├── IP输出 (ip_output.c)
│   │   ├── ip_queue_xmit()              # IP层发送
│   │   ├── ip_output()                  # 输出处理
│   │   └── ip_finish_output()           # 完成输出
│   │
│   ├── IP分片 (ip_fragment.c)
│   │   ├── ip_fragment()                # IP分片
│   │   └── ip_defrag()                  # IP重组
│   │
│   └── 路由子系统 (net/ipv4/route.c)
│       ├── ip_route_input()             # 输入路由查找
│       ├── ip_route_output_key()        # 输出路由查找
│       └── struct rtable                # 路由缓存项
│
├── 【邻居子系统】net/core/neighbour.c
│   ├── struct neighbour                 # 邻居项
│   │   ├── u8 nud_state                 # NUD状态
│   │   ├── struct hh_cache hh           # 硬件头缓存
│   │   └── struct net_device *dev
│   ├── ARP协议 (net/ipv4/arp.c)
│   │   ├── arp_rcv()                    # ARP接收
│   │   ├── arp_send()                   # ARP发送
│   │   └── arp_process()                # ARP处理
│   └── neigh_resolve_output()           # 邻居解析输出
│
├── 【设备无关接口层】net/core/dev.c
│   ├── 初始化: net_dev_init()
│   │   ├── 注册网络软中断
│   │   │   ├── open_softirq(NET_TX_SOFTIRQ, net_tx_action)
│   │   │   └── open_softirq(NET_RX_SOFTIRQ, net_rx_action)
│   │   └── 初始化CPU私有数据
│   │
│   ├── 接收路径
│   │   ├── netif_rx()                   # 传统接收(非NAPI)
│   │   ├── netif_receive_skb()          # 接收核心
│   │   └── __netif_receive_skb_core()   # 核心处理
│   │
│   ├── 发送路径
│   │   ├── dev_queue_xmit()             # 发送入口
│   │   ├── __dev_queue_xmit()           # 核心发送
│   │   └── dev_hard_start_xmit()        # 硬件发送
│   │
│   └── 软中断处理
│       ├── net_rx_action()              # 接收软中断
│       └── net_tx_action()              # 发送软中断
│
└── 【网络设备驱动层】drivers/net/
    ├── struct net_device                # 网络设备抽象
    │   ├── netdev_ops                   # 设备操作
    │   │   ├── .ndo_open
    │   │   ├── .ndo_stop
    │   │   ├── .ndo_start_xmit
    │   │   └── .ndo_get_stats
    │   ├── struct device dev
    │   └── void *priv                   # 驱动私有数据
    │
    └── 驱动示例
        ├── e1000 (Intel PRO/1000)
        ├── r8169 (Realtek)
        ├── virtio_net (虚拟化)
        └── veth (虚拟以太网)

第二部分:TCP/IP协议栈逐层分析

2.1 数据包接收完整流程

TCP数据包接收Pipeline
│
├── 【硬件层】网卡接收
│   ├── 1. 数据帧到达网卡PHY
│   ├── 2. 网卡DMA写入内存环形缓冲区
│   ├── 3. 网卡触发硬件中断
│   └── 代码路径: drivers/net/ethernet/intel/e1000/e1000_main.c
│
├── 【中断处理】上半部
│   ├── e1000_intr()                    # 中断处理函数
│   │   ├── 读取中断状态寄存器
│   │   ├── 禁用中断 (或轮询模式)
│   │   ├── 调度NAPI: napi_schedule()
│   │   └── 返回IRQ_HANDLED
│   │
│   └── 关键函数: __napi_schedule()
│       └── 将napi_struct加入CPU的poll_list
│
├── 【软中断处理】下半部
│   ├── net_rx_action()                 # NET_RX_SOFTIRQ处理
│   │   ├── 遍历CPU的poll_list
│   │   ├── 调用napi->poll()函数
│   │   └── 控制轮询时间/包数预算
│   │
│   └── e1000_clean()                   # NAPI poll函数
│       ├── 读取DMA描述符环
│       ├── 分配sk_buff
│       ├── 将数据拷贝/映射到skb
│       ├── napi_gro_receive()          # GRO合并
│       └── netif_receive_skb()
│
├── 【设备无关层】netif_receive_skb()
│   ├── 1. VLAN去标签 (如果存在)
│   ├── 2. 递交给抓包点: ptype_all (tcpdump)
│   ├── 3. 递交给协议处理
│   │   └── __netif_receive_skb_core()
│   │       ├── 桥接处理 (如果启用)
│   │       ├── 根据skb->protocol查找ptype_base
│   │       └── 调用协议handler: ip_rcv()
│   │
│   └── 关键数据结构: ptype_base哈希表
│       └── 协议类型→处理函数映射
│           ├── ETH_P_IP → ip_rcv
│           ├── ETH_P_ARP → arp_rcv
│           └── ETH_P_8021Q → vlan_skb_recv
│
├── 【网络层】IP层处理 (ip_input.c)
│   ├── ip_rcv()
│   │   ├── 1. IP头合法性检查
│   │   ├── 2. 计算校验和
│   │   ├── 3. 设置netfilter钩子 NF_INET_PRE_ROUTING
│   │   └── 4. 调用 ip_rcv_finish()
│   │
│   ├── ip_rcv_finish()
│   │   ├── 路由查找: ip_route_input_noref()
│   │   ├── 确定是本机、转发还是丢弃
│   │   └── 根据路由结果分发
│   │
│   ├── ip_local_deliver()              # 本机投递
│   │   ├── IP分片重组: ip_defrag()
│   │   ├── netfilter: NF_INET_LOCAL_IN
│   │   └── ip_local_deliver_finish()
│   │
│   └── ip_local_deliver_finish()
│       └── 根据L4协议分发
│           ├── IPPROTO_TCP → tcp_v4_rcv
│           ├── IPPROTO_UDP → udp_rcv
│           └── IPPROTO_ICMP → icmp_rcv
│
├── 【传输层】TCP处理 (tcp_input.c)
│   ├── tcp_v4_rcv()
│   │   ├── 1. 查找sock: __inet_lookup()
│   │   ├── 2. 校验和验证
│   │   ├── 3. 锁socket: bh_lock_sock()
│   │   └── 4. 根据socket状态处理
│   │
│   ├── 接收路径分支
│   │   ├── TCP_ESTABLISHED → tcp_rcv_established()
│   │   └── 其他状态 → tcp_rcv_state_process()
│   │
│   ├── tcp_rcv_established()
│   │   ├── 快速路径 (无选项, 无乱序)
│   │   │   ├── 数据放入接收队列
│   │   │   └── 发送ACK
│   │   └── 慢速路径 (有选项或有乱序)
│   │       ├── tcp_data_queue()        # 排队数据
│   │       ├── 处理乱序包
│   │       └── tcp_ofo_queue()         # 重排序队列
│   │
│   ├── tcp_data_queue()
│   │   ├── 顺序数据 → 加入sk_receive_queue
│   │   ├── 乱序数据 → 加入ofo_queue
│   │   └── 唤醒等待进程
│   │
│   └── 最终数据到达用户空间
│       ├── tcp_recvmsg()               # 用户态read/recv
│       └── skb_copy_datagram_msg()     # 拷贝到用户空间
│
└── 关键数据结构流转
    └── struct sk_buff (SKB) 生命周期
        ├── 网卡DMA分配
        ├── netif_receive_skb()
        ├── ip_rcv()
        ├── tcp_v4_rcv()
        ├── tcp_rcv_established()
        └── kfree_skb() (释放)

2.2 数据包发送完整流程

TCP数据包发送Pipeline
│
├── 【用户层】系统调用
│   ├── send() / write()
│   ├── sys_sendto() → net/socket.c
│   └── sock_sendmsg()
│
├── 【INET Socket层】
│   ├── inet_sendmsg()
│   │   └── 调用sk->sk_prot->sendmsg
│   └── tcp_sendmsg() (net/ipv4/tcp.c)
│       ├── 1. 获取用户数据
│       ├── 2. 锁定socket
│       ├── 3. 拷贝数据到skb
│       ├── 4. 加入发送队列: tcp_send_skb()
│       └── 5. 调度发送: tcp_push()
│
├── 【TCP层输出】
│   ├── tcp_write_xmit() (tcp_output.c)
│   │   ├── 拥塞窗口检查
│   │   ├── 发送窗口检查
│   │   ├── tcp_transmit_skb()         # 构建TCP头
│   │   └── 调用IP层发送
│   │
│   └── tcp_transmit_skb()
│       ├── 克隆SKB (可能)
│       ├── 构建TCP头
│       ├── 计算校验和
│       └── 调用 queue_xmit(): ip_queue_xmit()
│
├── 【网络层】IP输出
│   ├── ip_queue_xmit() (ip_output.c)
│   │   ├── 1. 路由查找 (如果未缓存)
│   │   ├── 2. 设置IP头
│   │   ├── 3. netfilter: NF_INET_LOCAL_OUT
│   │   ├── 4. ip_local_out()
│   │   └── ip_output()
│   │
│   └── ip_finish_output()
│       ├── 分片检查: ip_fragment() (如果超过MTU)
│       ├── netfilter: NF_INET_POST_ROUTING
│       └── neigh_output() → dev_queue_xmit()
│
├── 【邻居子系统】
│   ├── neigh_output()
│   │   ├── 邻居状态检查
│   │   │   ├── NUD_CONNECTED → 直接发送
│   │   │   └── NUD_INCOMPLETE → 排队等待ARP
│   │   └── dev_queue_xmit()
│   │
│   └── ARP处理 (arp.c)
│       ├── arp_send()                 # 发送ARP请求
│       └── arp_process()              # 处理ARP响应
│
├── 【设备无关层】发送核心
│   ├── dev_queue_xmit()
│   ├── __dev_queue_xmit()
│   │   ├── 1. 选择发送队列 (QoS)
│   │   ├── 2. 排队规则入队: qdisc_enqueue()
│   │   ├── 3. 调度: qdisc_run()
│   │   └── __qdisc_run()
│   │
│   └── qdisc_restart()               # 从队列取包发送
│       ├── dev_hard_start_xmit()
│       └── 调用 ndo_start_xmit
│
├── 【网卡驱动】实际发送
│   ├── e1000_xmit_frame() (驱动)
│   │   ├── 1. 映射DMA地址
│   │   ├── 2. 填充描述符
│   │   ├── 3. 更新TDT (发送描述符尾寄存器)
│   │   └── 4. 网卡DMA读取并发送
│   │
│   └── 发送完成中断
│       └── 释放SKB (DMA unmap, kfree_skb)
│
└── 关键流程图
    write() → sys_write() → sock_write() → tcp_sendmsg() 
        → tcp_push() → tcp_write_xmit() → tcp_transmit_skb()
        → ip_queue_xmit() → ip_output() → ip_finish_output()
        → dev_queue_xmit() → qdisc_enqueue() → __qdisc_run()
        → dev_hard_start_xmit() → ndo_start_xmit()
        → 硬件发送 → 发送完成中断

第三部分:核心数据结构树形分析

3.1 sk_buff (SKB) 结构详解

struct sk_buff (include/linux/skbuff.h)
│
├── 【网络参数区】
│   ├── struct sock *sk                 # 所属socket
│   ├── struct net_device *dev          # 接收/发送设备
│   ├── struct net_device *input_dev    # 原始输入设备
│   ├── __be32 protocol                 # 协议类型 (ETH_P_IP等)
│   ├── u16 transport_header            # 传输层头偏移
│   ├── u16 network_header              # 网络层头偏移
│   ├── u16 mac_header                  # MAC层头偏移
│   └── u16 inner_*_header              # 隧道内层头
│
├── 【数据指针区】 (关键偏移操作)
│   ├── unsigned char *head             # 缓冲区起始
│   ├── unsigned char *data             # 数据起始
│   ├── unsigned char *tail             # 数据结束
│   └── unsigned char *end              # 缓冲区结束
│
├── 【长度信息】
│   ├── unsigned int len                # 总数据长度
│   ├── unsigned int data_len           # 非线性数据长度
│   ├── unsigned int truesize           # 实际分配大小
│   └── atomic_t users                  # 引用计数
│
├── 【控制标志】
│   ├── __u8 pkt_type                   # 包类型 (PACKET_HOST等)
│   ├── __u8 ip_summed                  # 校验和状态
│   │   ├── CHECKSUM_NONE
│   │   ├── CHECKSUM_UNNECESSARY
│   │   ├── CHECKSUM_COMPLETE
│   │   └── CHECKSUM_PARTIAL
│   ├── __u8 cloned                     # 是否克隆
│   ├── __u8 nofcs                      # 无FCS标志
│   └── __u8 ignore_df                  # 忽略不分片标志
│
├── 【时间戳】
│   ├── union {
│   │   __u32 tstamp
│   │   ktime_t tstamp
│   │ }
│   └── __u32 skb_mstamp_ns
│
├── 【非线性数据区】 (分页支持)
│   └── struct skb_shared_info *shinfo
│       ├── unsigned int nr_frags       # 分页数量
│       ├── skb_frag_t frags[MAX_SKB_FRAGS]  # 分页数组
│       ├── struct sk_buff *frag_list   # 分片链
│       └── __u32 gso_size              # GSO分段大小
│
└── 【私有数据区】 (各层使用)
    ├── cb[48] char                     # 控制块 (48字节)
    │   └── TCP使用: struct tcp_skb_cb
    │       ├── seq, end_seq
    │       ├── tcp_flags
    │       └── 其他控制信息
    └── __u32 *data_priv

3.2 环形缓冲区实现 (网卡DMA)

网卡DMA环形缓冲区架构
│
├── 【基本原理】
│   ├── 生产者-消费者模型
│   ├── 2的幂次大小 (便于位运算)
│   └── 硬件与软件共享
│
├── 【描述符环结构】
│   struct e1000_rx_ring {
│       struct e1000_rx_desc *desc;     # 描述符数组
│       dma_addr_t dma;                 # 物理地址
│       struct sk_buff **skb;           # SKB指针数组
│       unsigned int count;             # 描述符数量
│       unsigned int next_to_use;       # 生产者索引
│       unsigned int next_to_clean;     # 消费者索引
│   };
│
├── 【环形缓冲区操作宏】 (include/linux/circ_buf.h)
│   ├── CIRC_SPACE(head, tail, size)    # 剩余空间
│   ├── CIRC_SPACE_TO_END()             # 连续剩余空间
│   ├── CIRC_CNT(head, tail, size)      # 已用数量
│   └── CIRC_CNT_TO_END()               # 连续已用数量
│
├── 【接收环形缓冲流程】
│   ├── 1. 硬件接收中断
│   ├── 2. 驱动处理clean函数
│   │   ├── 读取last_clean索引
│   │   ├── 遍历描述符直到last_clean == next_to_use
│   │   │   ├── 检查描述符状态位 (DD)
│   │   │   ├── 获取DMA数据
│   │   │   ├── 构建SKB
│   │   │   └── 提交上层: napi_gro_receive()
│   │   ├── 更新next_to_clean
│   │   └── 分配新的SKB填充释放的描述符
│   │
│   └── 3. 硬件继续DMA写入空闲描述符
│
├── 【发送环形缓冲流程】
│   ├── 1. 驱动xmit函数
│   │   ├── 获取next_to_use索引
│   │   ├── 填充描述符 (DMA地址, 长度)
│   │   └── 更新next_to_use (写入TDT寄存器)
│   │
│   ├── 2. 硬件DMA读取描述符发送
│   ├── 3. 发送完成中断
│   │   ├── 读取next_to_clean
│   │   ├── 检查描述符完成标志
│   │   ├── 释放SKB (DMA unmap, kfree)
│   │   └── 更新next_to_clean
│   │
│   └── 4. BQL字节队列限制
│       ├── 动态限流避免缓冲区膨胀
│       └── dev_watchdog监控
│
└── 【内存屏障应用】 (Documentation/core-api/circular-buffers.rst)
    ├── smp_store_release()             # 生产者写入head
    ├── smp_load_acquire()              # 消费者读取head
    └── 确保数据在索引更新前可见

第四部分:特殊协议族处理Pipeline

4.1 CAN总线协议 (SocketCAN)

CAN总线协议栈 (net/can/)
│
├── 【协议层架构】
│   ├── AF_CAN地址族 (PF_CAN = 29)
│   ├── 协议类型
│   │   ├── CAN_RAW (原始CAN帧)
│   │   ├── CAN_BCM (广播管理器)
│   │   ├── CAN_TP (传输协议ISO 15765-2)
│   │   └── CAN_ISOTP (ISO-TP诊断)
│   │
│   └── 协议族初始化: can_init()
│
├── 【CAN帧结构】
│   struct can_frame {
│       canid_t can_id;        # CAN ID (11位或29位)
│       __u8 can_dlc;          # 数据长度 (0-8)
│       __u8 __pad;            # 填充
│       __u8 __res0;           # 保留
│       __u8 len8_dlc;         # 可选DLC
│       __u8 data[8];          # 数据 (最多8字节)
│   };
│
├── 【接收Pipeline】
│   │
│   ├── 硬件层
│   │   └── CAN控制器驱动 (如mcp251x, flexcan)
│   │
│   ├── 驱动接收
│   │   ├── 中断处理读取CAN帧
│   │   ├── 分配skb: alloc_can_skb()
│   │   ├── 填充can_frame结构
│   │   └── netif_rx() / netif_receive_skb()
│   │
│   ├── 协议层接收 (af_can.c)
│   │   ├── can_rcv()
│   │   │   ├── 过滤匹配 (CAN ID过滤)
│   │   │   ├── 查找绑定的socket
│   │   │   └── can_queue_rcv_skb()
│   │   └── 入队到socket接收队列
│   │
│   └── 用户空间
│       └── recvmsg() 读取can_frame
│
├── 【发送Pipeline】
│   ├── 用户空间sendmsg()
│   ├── raw_sendmsg() (can_raw.c)
│   │   ├── 构建can_frame
│   │   ├── 路由到网络设备
│   │   └── can_send()
│   ├── can_send()
│   │   ├── 计算CAN帧时间戳
│   │   ├── 硬件过滤配置
│   │   └── dev_queue_xmit()
│   └── CAN驱动发送
│       └── 写入控制器寄存器
│
├── 【ISO-TP协议】 (can-isotp)
│   ├── 用途: 传输超过8字节的数据 (UDS诊断)
│   ├── 内核模块: can-isotp
│   ├── 分段机制
│   │   ├── 首帧 (FF) - 包含总长度
│   │   ├── 连续帧 (CF) - 后续数据
│   │   └── 流控制 (FC) - 接收方控制
│   │
│   └── ISO-TP Socket示例
│       int s = socket(PF_CAN, SOCK_DGRAM, CAN_ISOTP);
│       struct sockaddr_can addr;
│       addr.can_family = AF_CAN;
│       addr.can_ifindex = if_nametoindex("can0");
│       addr.can_addr.tp.rx_id = 0x123;  # 接收CAN ID
│       addr.can_addr.tp.tx_id = 0x456;  # 发送CAN ID
│
└── 【调试工具】
    ├── candump (查看CAN帧)
    ├── cansend (发送CAN帧)
    ├── isotpdump (ISO-TP调试)
    └── isotpsend (ISO-TP发送)

4.2 Bluetooth协议栈 (BlueZ)

Bluetooth协议栈架构 (net/bluetooth/)
│
├── 【地址族】
│   ├── PF_BLUETOOTH (AF_BLUETOOTH = 31)
│   └── 协议类型
│       ├── BTPROTO_L2CAP
│       ├── BTPROTO_HCI
│       ├── BTPROTO_RFCOMM
│       ├── BTPROTO_BNEP
│       ├── BTPROTO_CMTP
│       └── BTPROTO_SCO
│
├── 【协议栈分层】
│   │
│   ├── 【HCI层】 (hci_sock.c)
│   │   ├── 主机控制器接口
│   │   ├── 处理与蓝牙硬件的通信
│   │   ├── HCI命令: hci_send_cmd()
│   │   ├── HCI事件: hci_event_packet()
│   │   └── 数据包: hci_send_data()
│   │
│   ├── 【L2CAP层】 (l2cap_core.c)
│   │   ├── 逻辑链路控制和适配协议
│   │   ├── 通道复用 (CID)
│   │   ├── 分段和重组 (SAR)
│   │   ├── l2cap_chan_send()          # 发送
│   │   ├── l2cap_recv_frame()         # 接收
│   │   └── 流控和重传
│   │
│   ├── 【RFCOMM层】 (rfcomm/core.c)
│   │   ├── 串口仿真 (9针RS-232)
│   │   ├── rfcomm_dlc_send()          # DLC发送
│   │   ├── rfcomm_recv_frame()        # 接收
│   │   └── TTY仿真: rfcomm_tty
│   │
│   ├── 【BNEP层】 (bnep/core.c)
│   │   └── 蓝牙网络封装 (PAN)
│   │       ├── BNEP桥接以太网
│   │       └── bnep_netdev_ops (虚拟网卡)
│   │
│   └── 【SCO层】 (sco.c)
│       └── 同步连接 (语音)
│
├── 【核心管理】 (mgmt.c)
│   ├── 蓝牙控制器管理
│   ├── 设备发现
│   ├── 配对和绑定
│   └── mgmt_sock_event()
│
├── 【数据流Pipeline】
│   │
│   ├── 接收路径
│   │   ├── 硬件接收 (USB/串口)
│   │   ├── hci_rx_work()              # HCI接收工作
│   │   ├── hci_send_to_sock()         # 发送到HCI socket
│   │   └── 协议分发
│   │       ├── L2CAP帧 → l2cap_recv_acldata()
│   │       ├── SCO帧 → sco_recv_scodata()
│   │       └── 事件 → mgmt_event()
│   │
│   └── 发送路径
│       ├── L2CAP发送: l2cap_chan_send()
│       ├── 分段处理: l2cap_segment_sdu()
│       ├── HCI封装: hci_send_acl()
│       └── 硬件发送: hci_send_frame()
│
├── 【Socket接口】
│   ├── 创建Bluetooth Socket
│   │   int sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
│   │   int sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
│   │   int sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
│   │
│   └── 地址结构
│       struct sockaddr_hci {
│           sa_family_t hci_family;
│           unsigned short hci_dev;
│           unsigned short hci_channel;
│       };
│
└── 【用户空间】BlueZ工具
    ├── bluetoothd (守护进程)
    ├── bluetoothctl (控制工具)
    ├── hcitool (HCI工具)
    ├── hciconfig (配置)
    └── rfcomm (串口绑定)

4.3 自定义协议实现框架

自定义Socket协议实现框架
│
├── 【步骤1:注册协议族】
│   │
│   ├── 定义协议族编号
│   │   #define AF_MYPROTO 46  (需要分配)
│   │   #define PF_MYPROTO AF_MYPROTO
│   │
│   ├── 实现协议族操作表
│   │   static const struct proto_ops myproto_ops = {
│   │       .family = PF_MYPROTO,
│   │       .owner = THIS_MODULE,
│   │       .release = myproto_release,
│   │       .bind = myproto_bind,
│   │       .connect = myproto_connect,
│   │       .socketpair = sock_no_socketpair,
│   │       .accept = sock_no_accept,
│   │       .sendmsg = myproto_sendmsg,
│   │       .recvmsg = myproto_recvmsg,
│   │       .mmap = sock_no_mmap,
│   │   };
│   │
│   └── 注册到net_families[]
│       static int __init myproto_init(void)
│       {
│           int err = sock_register(&myproto_family_ops);
│           if (err) return err;
│           err = proto_register(&myproto_prot, 0);
│           return err;
│       }
│
├── 【步骤2:定义socket结构】
│   │
│   └── 继承struct sock
│       struct myproto_sock {
│           struct sock sk;           # 必须放在第一位
│           spinlock_t lock;
│           struct list_head rx_queue;
│           struct list_head tx_queue;
│           int state;
│           __u32 local_addr;
│           __u32 remote_addr;
│       };
│
├── 【步骤3:实现socket操作】
│   │
│   ├── myproto_create()
│   │   static int myproto_create(struct net *net, struct socket *sock,
│   │                               int protocol, int kern)
│   │   {
│   │       struct myproto_sock *mp;
│   │       struct sock *sk;
│   │
│   │       if (!capable(CAP_NET_RAW))
│   │           return -EPERM;
│   │
│   │       sock->state = SS_UNCONNECTED;
│   │       sock->ops = &myproto_ops;
│   │
│   │       sk = sk_alloc(net, PF_MYPROTO, GFP_KERNEL, &myproto_prot, kern);
│   │       mp = myproto_sk(sk);
│   │
│   │       sock_init_data(sock, sk);
│   │       sk->sk_destruct = myproto_destruct;
│   │
│   │       return 0;
│   │   }
│   │
│   ├── myproto_sendmsg()
│   │   static int myproto_sendmsg(struct socket *sock,
│   │                                struct msghdr *msg, size_t len)
│   │   {
│   │       struct sock *sk = sock->sk;
│   │       struct sk_buff *skb;
│   │       int err;
│   │
│   │       /* 分配SKB */
│   │       skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE,
│   │                                   msg->msg_flags & MSG_DONTWAIT, &err);
│   │
│   │       /* 拷贝用户数据 */
│   │       skb_put(skb, len);
│   │       err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, len);
│   │
│   │       /* 设置协议头 */
│   │       skb_push(skb, MYPROTO_HLEN);
│   │       skb->protocol = htons(ETH_P_MYPROTO);
│   │
│   │       /* 发送处理 (设备无关层) */
│   │       err = dev_queue_xmit(skb);
│   │
│   │       return len;
│   │   }
│   │
│   └── myproto_recvmsg()
│       static int myproto_recvmsg(struct socket *sock,
│                                    struct msghdr *msg, size_t size, int flags)
│       {
│           struct sock *sk = sock->sk;
│           struct sk_buff *skb;
│           int err;
│
│           skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
│
│           /* 拷贝到用户空间 */
│           err = skb_copy_datagram_msg(skb, 0, msg, skb->len);
│
│           skb_free_datagram(sk, skb);
│           return err ?: skb->len;
│       }
│
├── 【步骤4:协议注册】
│   │
│   └── 协议族结构
│       static struct net_proto_family myproto_family_ops = {
│           .family = PF_MYPROTO,
│           .create = myproto_create,
│           .owner = THIS_MODULE,
│       };
│
└── 【步骤5:用户空间使用】
    int sock = socket(AF_MYPROTO, SOCK_RAW, 0);
    struct sockaddr_my addr = { .family = AF_MYPROTO, .dev = 1 };
    bind(sock, (struct sockaddr*)&addr, sizeof(addr));
    send(sock, data, len, 0);
    recv(sock, buf, sizeof(buf), 0);

第五部分:调试工具与性能分析

5.1 调试工具树形图

Linux网络调试工具全景
│
├── 【传统工具集】
│   ├── net-tools (已过时但常用)
│   │   ├── ifconfig           # 接口配置
│   │   ├── route              # 路由表
│   │   ├── netstat            # 网络统计
│   │   └── arp                # ARP缓存
│   │
│   └── iproute2 (现代替代)
│       ├── ip                 # 主命令
│       │   ├── ip link        # 链路层
│       │   ├── ip addr        # IP地址
│       │   ├── ip route       # 路由
│       │   ├── ip neigh       # 邻居
│       │   └── ip netns       # 网络命名空间
│       ├── ss                 # socket统计
│       ├── tc                 # 流量控制
│       └── bridge             # 桥接
│
├── 【抓包分析工具】
│   ├── tcpdump                # 命令行抓包
│   │   tcpdump -i eth0 -w capture.pcap
│   │   tcpdump -i any host 192.168.1.1
│   │   tcpdump -i eth0 'tcp port 80'
│   │
│   ├── wireshark              # GUI分析
│   │   └── 支持协议解析/流跟踪
│   │
│   ├── tshark                 # 命令行Wireshark
│   │
│   └── netsniff-ng            # 高性能抓包
│       └── ifpps              # top类网络统计
│
├── 【eBPF追踪工具】
│   │
│   ├── pwru (Packet Where aRe yoU)
│   │   ├── 追踪网络包在内核中的路径
│   │   ├── 高级过滤 (skb元数据, 函数名)
│   │   └── 示例: pwru --output-tuple 'host 1.1.1.1'
│   │
│   ├── bpftrace                # 动态追踪
│   │   ├── 追踪kprobe/uprobe
│   │   └── 示例: bpftrace -e 'kprobe:ip_rcv { @[comm] = count(); }'
│   │
│   └── libbpf                  # BPF开发库
│
├── 【内核调试接口】
│   ├── /proc/net/              # 网络统计
│   │   ├── /proc/net/dev       # 设备统计
│   │   ├── /proc/net/tcp       # TCP连接
│   │   ├── /proc/net/udp       # UDP连接
│   │   ├── /proc/net/sockstat  # Socket统计
│   │   └── /proc/net/softnet_stat # 软中断统计
│   │
│   ├── /sys/class/net/         # sysfs接口
│   │   └── eth0/statistics/    # 设备统计
│   │
│   ├── netlink                 # 内核-用户通信
│   │   ├── NETLINK_ROUTE       # 路由信息
│   │   ├── NETLINK_SOCK_DIAG   # Socket诊断
│   │   └── NETLINK_NETFILTER   # Netfilter
│   │
│   └── tracepoints             # 静态跟踪点
│       ├── net:netif_rx
│       ├── net:net_dev_queue
│       ├── net:ip_rcv
│       ├── net:tcp_rcv_established
│       └── net:sock_rcvqueue_alloc
│
├── 【性能分析工具】
│   ├── perf                    # Linux性能分析
│   │   perf record -e net:netif_receive_skb
│   │   perf top
│   │
│   ├── ftrace                  # 函数跟踪
│   │   echo 'ip_rcv' > /sys/kernel/debug/tracing/set_ftrace_filter
│   │   echo function > current_tracer
│   │
│   └── sar                     # 系统活动报告
│       sar -n DEV 1
│
├── 【专用测试工具】
│   ├── netperf                 # 网络性能测试
│   ├── iperf3                  # 带宽测试
│   ├── ping                    # 连通性测试
│   ├── traceroute              # 路由跟踪
│   ├── ethtool                 # 网卡配置/统计
│   │   ethtool -S eth0         # 网卡统计
│   │   ethtool -k eth0         # 卸载功能
│   │   ethtool -i eth0         # 驱动信息
│   │
│   └── nstat                   # 网络统计
│
└── 【开发调试工具】
    ├── strace                  # 系统调用跟踪
    │   strace -e network curl example.com
    │
    ├── gdb                     # 内核调试
    │   gdb vmlinux /proc/kcore
    │
    └── kdump                   # 内核崩溃转储

5.2 性能分析树形图

网络性能分析框架
│
├── 【性能指标层次】
│   │
│   ├── 应用层指标
│   │   ├── 吞吐量 (Mbps)
│   │   ├── 延迟 (RTT)
│   │   ├── 并发连接数
│   │   └── 请求响应时间
│   │
│   ├── 传输层指标
│   │   ├── TCP重传率
│   │   ├── TCP窗口大小
│   │   ├── 拥塞窗口(cwnd)
│   │   ├── 接收窗口(rwnd)
│   │   └── 丢包率
│   │
│   ├── 网络层指标
│   │   ├── 路由缓存命中率
│   │   ├── IP分片率
│   │   ├── ICMP错误率
│   │   └── 转发速率 (pps)
│   │
│   ├── 设备层指标
│   │   ├── 网卡丢包计数
│   │   ├── 中断速率
│   │   ├── DMA映射效率
│   │   ├── 描述符环利用率
│   │   └── 硬件队列深度
│   │
│   └── 系统层指标
│       ├── CPU软中断占用
│       ├── 内存使用 (SKB缓存)
│       ├── 锁竞争
│       └── 缓存未命中率
│
├── 【性能瓶颈定位流程】
│   │
│   ├── 1. 识别瓶颈层
│   │   ├── 应用层: ss -ti 查看TCP统计
│   │   ├── 协议栈: netstat -s 查看协议统计
│   │   ├── 设备层: ethtool -S eth0
│   │   └── 系统层: mpstat -P ALL 1
│   │
│   ├── 2. 细粒度分析
│   │   ├── 追踪函数调用: perf top
│   │   ├── 抓包分析: tcpdump -i eth0 -w cap.pcap
│   │   ├── eBPF追踪: pwru --output-tuple
│   │   └── 内核追踪: trace-cmd record -e net
│   │
│   └── 3. 优化建议
│       ├── 调整缓冲区大小
│       ├── 启用GRO/GSO/TSO
│       ├── 调整中断亲和性
│       ├── 使用多队列网卡
│       └── 优化拥塞控制算法
│
├── 【性能调优参数】
│   │
│   ├── 内核参数 (/proc/sys/net/)
│   │   ├── core/
│   │   │   ├── netdev_max_backlog     # 接收队列长度
│   │   │   ├── somaxconn              # 监听队列长度
│   │   │   └── rmem_default/max      # 接收缓冲区
│   │   ├── ipv4/
│   │   │   ├── tcp_rmem/tcp_wmem     # TCP缓冲区
│   │   │   ├── tcp_congestion_control # 拥塞控制
│   │   │   ├── tcp_tw_reuse           # TIME_WAIT复用
│   │   │   └── tcp_fastopen           # TFO
│   │   └── netfilter/
│   │       └── nf_conntrack_max       # 连接跟踪
│   │
│   ├── 网卡卸载功能 (ethtool -k)
│   │   ├── tso (TCP Segmentation Offload)
│   │   ├── gro (Generic Receive Offload)
│   │   ├── gso (Generic Segmentation Offload)
│   │   ├── lro (Large Receive Offload)
│   │   ├── rx/tx checksum
│   │   └── rss (Receive Side Scaling)
│   │
│   └── 中断亲和性 (smp_affinity)
│       └── echo 1 > /proc/irq/xxx/smp_affinity
│
└── 【性能监控命令】
    ├── sar -n DEV 1           # 设备吞吐量
    ├── sar -n TCP 1           # TCP统计
    ├── sar -n EDEV 1          # 错误统计
    ├── ss -tiepm              # Socket详细信息
    ├── nstat -z               # 内核网络统计
    ├── netstat -i             # 接口统计
    ├── ip -s link             # 接口统计(现代)
    └── ifpps eth0             # top类实时统计

第六部分:总结与参考

6.1 关键源码文件索引

模块路径说明
系统调用net/socket.csocket()、bind()等系统调用实现
协议族注册net/socket.cnet_families[]、sock_register()
INET层net/ipv4/af_inet.cAF_INET协议族实现
TCP协议net/ipv4/tcp.c, tcp_input.c, tcp_output.cTCP核心实现
UDP协议net/ipv4/udp.cUDP实现
IP层net/ipv4/ip_input.c, ip_output.cIP输入输出
路由net/ipv4/route.c路由查找
邻居/ARPnet/core/neighbour.c, net/ipv4/arp.cARP和邻居管理
设备层net/core/dev.cnetif_rx、dev_queue_xmit
SKBnet/core/skbuff.csk_buff管理
Socket层net/core/sock.c通用socket操作
CAN总线net/can/SocketCAN实现
Bluetoothnet/bluetooth/BlueZ协议栈
环形缓冲区include/linux/circ_buf.hCIRC_*宏定义
调试工具tools/net/网络工具源码
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐