LWIP_Packet_Manager

概述

协议栈的本质: 数据包处理

  1. 链路层: 判断数据包类型 提取数据字段 记录主机物理地址信息
  2. IP层: 根据IP地址实现 数据的 存储 转发 重装 提取传输层信息
  3. TCP: 更新TCP状态机 向应用程序提交数据

所以 : 数据包的管理应该高效,并减少各层间传递时的时间与空间的开销

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
struct pbuf {
/** next pbuf in singly linked pbuf chain */
struct pbuf *next;

/** pointer to the actual data in the buffer */
void *payload;

/**
* total length of this buffer and all next buffers in chain
* belonging to the same packet.
*
* For non-queue packet chains this is the invariant:
* p->tot_len == p->len + (p->next? p->next->tot_len: 0)
*/
u16_t tot_len;

/** length of this buffer */
u16_t len;

/** pbuf_type as u8_t instead of enum to save space */
u8_t /*pbuf_type*/ type;

/** misc flags */
u8_t flags;

/**
* the reference count always equals the number of pointers
* that refer to this pbuf. This can be pointers from an application,
* the stack itself, or pbuf->next pointers from a chain.
*/
u16_t ref;

};

分层特点

特点

  • 各个层独立,负责完成独立任务 [数据链路: 物理线路传输封装 IP层:找到主机 传输层:找到进程 详细见7.1.1 ]
  • 各个层可以单独实现,只要保证实现接口

但是: 如果严格按照分层,导致pkt 在各层传递变得缓慢[memcpy]

解决: 各层协议可以直接对数据包中属于其他层协议的字段进行操作

总结

  • 结构上按照分层模型,每层都在一个单独的模块中实现,上下提供输入/出 接口

  • 协议栈之间:分层思想并非严格,各个层存在数据交叉存取的现象

  • 用户层与协议栈之间: 分层思想并非严格,User 程序可以直接访问协议栈内部数据包,也可以共共同使用一段内存

    从而避免内存拷贝带来的开销

Pbuf

概述

1
2
3
4
5
6
7
8
9
struct pbuf {
struct pbuf *next;
void *payload;
u16_t tot_len;
u16_t len;
u8_t /*pbuf_type*/ type;
u8_t flags;
u16_t ref;
};

图: 见7.2.1

PBUF_RAM

使用者: 协议栈与应用程序 的 待发数据

图例 :7-1

关键点: offset 存储数据包在各个首部字段: TCP报文首部 IP首部 以太网帧首部

PBUF_POOL

使用者 : 网卡接收数据包

图例: 7-2

关键点:数据包很长时,分配多个Pool ,并使用链表将其 链接起来

PBUF_ROM PBUF_REF

图例: 7-3

关键点: 只分配 pbuf结构体,不分配数据区,而数据区可能存在 RAM 或 ROM

混合

对于一个数据包,可能是不同类型的几个pbuf,链接起来的, 共同保存 一个数据包的数据

数据包申请

关键参数

  • pbuf类型: 上一章节的描述
  • pbuf 对应的层: 不同层 要预留出 对应的空间,即pkbuf中 offset 的大小

数据包释放

关键参数

  • ref: ref参数决定了pbuf 是否允许被释放
undefined