P4 01-Reflector

P4示例程序-01 数据包反射器

功能:交换机将数据包从入端口重新转发出去,并对数据包中的调源目的MAC地址

原程序

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/* -*- P4_16 -*- */
#include <core.p4>
#include <v1model.p4>

/*************************************************************************
*********************** H E A D E R S ***********************************
*************************************************************************/

typedef bit<48> macAddr_t;
header ethernet_t {
macAddr_t dstAddr;
macAddr_t srcAddr;
bit<16> etherType;
}

struct metadata {
/* empty */
}

struct headers {
ethernet_t ethernet;
}

/*************************************************************************
*********************** P A R S E R ***********************************
*************************************************************************/

parser MyParser(packet_in packet,
out headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {

state start{

/* TODO 1: parse ethernet header */
transition accept;
}

}

/*************************************************************************
************ C H E C K S U M V E R I F I C A T I O N *************
*************************************************************************/

control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
apply { }
}


/*************************************************************************
************** I N G R E S S P R O C E S S I N G *******************
*************************************************************************/

control MyIngress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {

apply {
/* TODO 2: swap mac addresses */
/* TODO 3: set output port */
}
}

/*************************************************************************
**************** E G R E S S P R O C E S S I N G *******************
*************************************************************************/

control MyEgress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
apply { }
}

/*************************************************************************
************* C H E C K S U M C O M P U T A T I O N **************
*************************************************************************/

control MyComputeChecksum(inout headers hdr, inout metadata meta) {
apply { }
}

/*************************************************************************
*********************** D E P A R S E R *******************************
*************************************************************************/

control MyDeparser(packet_out packet, in headers hdr) {
apply {
/* TODO 4: deparse ethernet header */
}
}

/*************************************************************************
*********************** S W I T C H *******************************
*************************************************************************/

V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;

解析

  1. Main
    1
    2
    3
    4
    5
    6
    7
    8
    V1Switch(
    MyParser(), // 解析器
    MyVerifyChecksum(), // 校验和验证
    MyIngress(), // 入端处理
    MyEgress(), // 出端处理
    MyComputeChecksum(), // 校验和计算
    MyDeparser() // 反解析器
    ) main;
  2. Headers
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    typedef 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; // 包含以太网头部
    }
  3. Parser
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    parser 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 状态(默认结束状态)
    }

    }
  4. Checksum Verification
    1
    2
    3
    4
    // 校验和验证控制器(这里没有实际进行校验操作)
    control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
    apply { } // 空操作
    }
  5. 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;
    }
    }
  6. Egress Processing
    1
    2
    3
    4
    5
    6
    // 出队列控制逻辑,这里没有进行任何处理
    control MyEgress(inout headers hdr,
    inout metadata meta,
    inout standard_metadata_t standard_metadata) {
    apply { } // 空操作
    }
  7. Checksum Computation
    1
    2
    3
    4
    // 校验和计算控制器,这里也没有进行处理
    control MyComputeChecksum(inout headers hdr, inout metadata meta) {
    apply { } // 空操作
    }
  8. DE parser
    1
    2
    3
    4
    5
    6
    7
    // 反解析器:将解析后的字段重新写回包中
    control MyDeparser(packet_out packet, in headers hdr) {
    apply {
    // 将以太网头部重新写入数据包中
    packet.emit(hdr.ethernet);
    }
    }

P4仿真

  1. 在拓扑描述文件p4app.json所在的目录执行以下命令,启动网络拓扑
    1
    sudo p4run
启动截图
  1. 使用xterm h1命令登陆host1的shell界面
    1
    xterm h1
启动h1 shell界面
  1. 运行命令执行端侧收发Python脚本,成功实现反射器效果
    1
    python send_receive.py
运行send_receive脚本
成功截图

P4 01-Reflector
http://example.com/2025/07/19/P4 01-Reflector/
作者
Wsdbybyd
发布于
2025年7月19日
许可协议