P4 01-Reflector
P4示例程序-01 数据包反射器
功能:交换机将数据包从入端口重新转发出去,并对数据包中的调源目的MAC地址
原程序
1 | |
解析
- Main
1
2
3
4
5
6
7
8V1Switch(
MyParser(), // 解析器
MyVerifyChecksum(), // 校验和验证
MyIngress(), // 入端处理
MyEgress(), // 出端处理
MyComputeChecksum(), // 校验和计算
MyDeparser() // 反解析器
) main; - Headers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18typedef bit<48> macAddr_t; // 定义MAC地址类型为48位比特
// 定义以太网帧头
header ethernet_t {
macAddr_t dstAddr; // 目的MAC地址
macAddr_t srcAddr; // 源MAC地址
bit<16> etherType; // 以太网类型字段(表明上层协议类型)
}
// 元数据结构,此处为空
struct metadata {
/* empty */
}
// 所有解析得到的包头的集合结构体
struct headers {
ethernet_t ethernet; // 包含以太网头部
} - Parser
1
2
3
4
5
6
7
8
9
10
11
12
13parser MyParser( // 定义解析器 MyParser
packet_in packet, // 输入的数据包流
out headers hdr, // 输出的包头结构
inout metadata meta, // 输入输出的元数据
inout standard_metadata_t standard_metadata) // 标准元数据,包含端口、包长等信息
{
state start { // 定义初始状态 start
packet.extract(hdr.ethernet); // 从数据包中提取以太网头部,存入 hdr.ethernet
transition accept; // 提取完成后跳转到 accept 状态(默认结束状态)
}
} - Checksum Verification
1
2
3
4// 校验和验证控制器(这里没有实际进行校验操作)
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
apply { } // 空操作
} - Ingress Processing
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// 入队列控制逻辑
control MyIngress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
// 定义一个动作:交换源MAC和目的MAC地址
action swap_mac() {
macAddr_t tmp;
tmp = hdr.ethernet.srcAddr; // 临时保存源地址
hdr.ethernet.srcAddr = hdr.ethernet.dstAddr; // 目的地址赋值给源地址
hdr.ethernet.dstAddr = tmp; // 原源地址赋值给目的地址
}
apply {
// 应用上述交换MAC地址的动作
swap_mac();
// 设置输出端口为输入端口,实现包回送
standard_metadata.egress_spec = standard_metadata.ingress_port;
}
} - Egress Processing
1
2
3
4
5
6// 出队列控制逻辑,这里没有进行任何处理
control MyEgress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
apply { } // 空操作
} - Checksum Computation
1
2
3
4// 校验和计算控制器,这里也没有进行处理
control MyComputeChecksum(inout headers hdr, inout metadata meta) {
apply { } // 空操作
} - DE parser
1
2
3
4
5
6
7// 反解析器:将解析后的字段重新写回包中
control MyDeparser(packet_out packet, in headers hdr) {
apply {
// 将以太网头部重新写入数据包中
packet.emit(hdr.ethernet);
}
}
P4仿真
- 在拓扑描述文件p4app.json所在的目录执行以下命令,启动网络拓扑
1
sudo p4run
- 使用xterm h1命令登陆host1的shell界面
1
xterm h1
- 运行命令执行端侧收发Python脚本,成功实现反射器效果
1
python send_receive.py
P4 01-Reflector
http://example.com/2025/07/19/P4 01-Reflector/