最熟悉的还是IP协议。 找到入手点。再去延伸。
src/main:系统的入口
- modules_init(); 这里用来加载模块,这里不能忽略。 各种模块的初始化。
- dpdk的主从启动?
- 模块之一:inet (初始化和管理 IP 协议栈,处理 IPv4 和 IPv6 数据包的路由和转发)
//初始化各种协议,对应inet_term 释放资源
int inet_init(void)
{
int err;
///初始化邻居表(neighbor table),用于管理和维护网络邻居(如 ARP 缓存)。
if ((err = neigh_init()) != 0)
return err;
///初始化 IPv4 路由表,管理 IPv4 路由信息。
if ((err = route_init()) != 0)
return err;
///初始化 IPv6 路由表,管理 IPv6 路由信息。
if ((err = route6_init()) != 0)
return err;
///初始化网络钩子,用于在数据包处理过程中插入自定义处理逻辑。
if ((err = inet_hook_init()) != 0)
return err;
///初始化 IPv4 协议栈,设置 IPv4 相关的数据结构和资源。
if ((err = ipv4_init()) != 0)
return err;
///初始化 IPv6 协议栈,设置 IPv6 相关的数据结构和资源。
if ((err = ipv6_init()) != 0)
return err;
///初始化 ICMP 协议栈,处理 ICMP 消息。
if ((err = icmp_init()) != 0)
return err;
///初始化 ICMPv6 协议栈,处理 ICMPv6 消息。
if ((err = icmpv6_init()) != 0)
return err;
///初始化网络地址管理模块,管理 IP 地址的分配和配置。
if ((err = inet_addr_init()) != 0)
return err;
return EDPVS_OK;
}
- neigh_init函数(arp相关)
ARP(Address Resolution Protocol)
+------------------+ +------------------+
| 主机 A | | 主机 B |
| IP: 192.168.1.1 | | IP: 192.168.1.2 |
| MAC: AA:AA:AA | | MAC: BB:BB:BB |
+--------+---------+ +--------+---------+
| |
| ARP 请求 (广播) |
|------------------------->|
| |
| |
|<-------------------------|
| ARP 响应 (单播) |
| |
| |
+--------+---------+ +--------+---------+
| 更新 ARP 缓存 | | 发送 ARP 响应 |
+------------------+ +------------------+
- ARP 请求:主机 A 需要知道主机 B 的 MAC 地址,于是发送一个 ARP 请求广播包,包含主机 B 的 IP 地址。
- ARP 响应:主机 B 收到 ARP 请求后,发送一个 ARP 响应包,包含自己的 MAC 地址,直接发给主机 A(单播)。
- 更新 ARP 缓存:主机 A 收到 ARP 响应后,更新其 ARP 缓存,将主机 B 的 IP 地址和 MAC 地址对应起来。
邻居发现协议(Neighbor Discovery Protocol,NDP)
NDP 是用于 IPv6 网络中的协议,提供类似 ARP 的功能,还包括一些其他功能如地址自动配置、邻居无效检测等。
+------------------+ +------------------+
| 主机 A | | 主机 B |
| IP: fe80::1 | | IP: fe80::2 |
| MAC: AA:AA:AA | | MAC: BB:BB:BB |
+--------+---------+ +--------+---------+
| |
| 邻居请求 (多播) |
|------------------------->|
| |
| |
|<-------------------------|
| 邻居响应 (单播) |
| |
| |
+--------+---------+ +--------+---------+
| 更新邻居缓存 | | 发送邻居响应 |
+------------------+ +------------------+
- 邻居请求:主机 A 需要知道主机 B 的 MAC 地址,于是发送一个邻居请求多播包,包含主机 B 的 IP 地址。
- 邻居响应:主机 B 收到邻居请求后,发送一个邻居响应包,包含自己的 MAC 地址,直接发给主机 A(单播)。
- 更新邻居缓存:主机 A 收到邻居响应后,更新其邻居缓存,将主机 B 的 IP 地址和 MAC 地址对应起来。
- IP隧道模块:(未完)
IPIP 隧道将一个 IP 数据包封装在另一个 IP 数据包内进行传输。以下是详细的封装结构:
+-------------------+-------------------+-------------------+
| 外层 IP 头 | 内层 IP 头 | 数据 |
+-------------------+-------------------+-------------------+
外层 IP 头用于在隧道端点之间传输数据包。以下是外层 IP 头的详细字段:
+-----------------------+-----------------------+-----------------------+-----------------------+
| 版本 (4 bits) | 首部长度 (4 bits) | 服务类型 (8 bits) | 总长度 (16 bits) |
+-----------------------+-----------------------+-----------------------+-----------------------+
| 标识 (16 bits) | 标志 (3 bits) | 片偏移 (13 bits) | 生存时间 (8 bits) |
+-----------------------+-----------------------+-----------------------+-----------------------+
| 协议 (8 bits) | 首部校验和 (16 bits) | 源地址 (32 bits) | 目的地址 (32 bits) |
+-----------------------+-----------------------+-----------------------+-----------------------+
GRE 隧道在外层 IP 头和内层 IP 头之间增加了 GRE 头。
+-------------------+-------------------+-------------------+-------------------+
| 外层 IP 头 | GRE 头 | 内层 IP 头 | 数据 |
+-------------------+-------------------+-------------------+-------------------+
GRE 头用于封装内层 IP 数据包
+-----------------------+-----------------------+-----------------------+-----------------------+
| C (1 bit) | R (1 bit) | K (1 bit) | S (1 bit) |
+-----------------------+-----------------------+-----------------------+-----------------------+
| 版本 (3 bits) | 协议类型 (13 bits) | 校验和 (16 bits) | 保留 (16 bits) |
+-----------------------+-----------------------+-----------------------+-----------------------+
| 键 (32 bits, 可选) | 序列号 (32 bits, 可选)| 路由 (32 bits, 可选) | |
+-----------------------+-----------------------+-----------------------+-----------------------+
VXLAN 隧道在外层 IP 头和内层 IP 头之间增加了 UDP 头和 VXLAN 头。
+-------------------+-------------------+-------------------+-------------------+-------------------+
| 外层 IP 头 | UDP 头 | VXLAN 头 | 内层 IP 头 | 数据 |
+-------------------+-------------------+-------------------+-------------------+-------------------+
UDP 头用于封装 VXLAN 数据包
+-----------------------+-----------------------+-----------------------+-----------------------+
| 源端口 (16 bits) | 目的端口 (16 bits) | 长度 (16 bits) | 校验和 (16 bits) |
+-----------------------+-----------------------+-----------------------+-----------------------+
VXLAN 头用于封装内层 IP 数据包。以下是 VXLAN 头的详细字段:
+-----------------------+-----------------------+-----------------------+-----------------------+
| 标志 (8 bits) | VXLAN 网络标识符 (24 bits) | 保留 (24 bits) |
+-----------------------+-----------------------+-----------------------+-----------------------+
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。