理解 Linux网络栈(1):Linux 网络协议栈简单总结( 五 )

2.1.2 skb 的主要操作
(1)分配 skb = alloc_skb(len, GFP_KERNEL)
理解 Linux网络栈(1):Linux 网络协议栈简单总结文章插图
(2)添加 payload (skb_put(skb, user_data_len))
理解 Linux网络栈(1):Linux 网络协议栈简单总结文章插图
(3)使用 skb->push 添加 protocol header , 或者 skb->pull 删除 header
理解 Linux网络栈(1):Linux 网络协议栈简单总结文章插图
2.2 Linux 网络栈使用的驱动队列 (driver queue)2.2.1 队列
理解 Linux网络栈(1):Linux 网络协议栈简单总结文章插图
在 IP 栈和 NIC 驱动之间 , 存在一个 driver queue (驱动队列) 。 典型地 , 它被实现为 FIFO ring buffer , 简单地可以认为它是固定大小的 。 这个队列不包含 packet data , 相反 , 它只是保存 socket kernel buffer (skb)的指针 , 而 skb 的使用如上节所述是贯穿内核网络栈处理过程的始终的 。
该队列的输入时 IP 栈处理完毕的 packets 。 这些packets 要么是本机的应用产生的 , 要么是进入本机又要被路由出去的 。 被 IP 栈加入队列的 packets 会被网络设备驱动(hardware driver)取出并且通过一个数据通道(data bus)发到 NIC 硬件设备并传输出去 。
在不使用 TSO/GSO 的情况下 , IP 栈发到该队列的 packets 的长度必须小于 MTU 。
2.2.2 skb 大小 - 默认最大大小为 NIC MTU
绝大多数的网卡都有一个固定的最大传输单元(maximum transmission unit, MTU)属性 , 它是该网络设备能够传输的最大帧(frame)的大小 。 对以太网来说 , 默认值为 1500 bytes , 但是有些以太网络可以支持巨帧(jumbo frame) , 最大能到 9000 bytes 。 在 IP 网络栈内 , MTU 表示能发给 NIC 的最大 packet 的大小 。 比如 , 如果一个应用向一个 TCP socket 写入了 2000 bytes 数据 , 那么 IP 栈需要创建两个 IP packets 来保持每个 packet 的大小等于或者小于 1500 bytes 。 可见 , 对于大数据传输 , 相对较小的 MTU 会导致产生大量的小网络包(small packets)并被传入 driver queue 。 这成为 IP 分片 (IP fragmentation) 。
下图表示 payload 为 1500 bytes 的 IP 包 , 在 MTU 为 1000 和 600 时候的分片情况:
理解 Linux网络栈(1):Linux 网络协议栈简单总结文章插图
【理解 Linux网络栈(1):Linux 网络协议栈简单总结】备注: 以上资料是从网络上获取的各种资料整理而来 这一块本身就比较复杂 , 而且不同的 linux 内核的版本之间也有差异 , 文中的内容还需要进一步加工 , 错误在所难免 。