P4 的概念已经了解了,现在动手搭建开发环境,跑通第一个 P4 程序。
一、P4 开发环境概述#
P4 程序需要两个核心组件:
| 组件 |
作用 |
类比 |
| p4c |
P4 编译器,把 .p4 源码编译成 JSON |
类似 gcc 编译 C 语言 |
| BMv2 (Behavioral Model v2) |
P4 软件交换机,运行编译后的程序 |
类似 Mininet 中的交换机 |
1.1 两种安装方式#
| 方式 |
优点 |
缺点 |
| Docker |
省心,一键启动,不污染系统 |
需要 Docker,性能略低 |
| Ubuntu 直装 |
性能好,调试方便 |
步骤多,可能踩坑 |
推荐先用 Docker 跑通流程,后续需要深入调试再考虑直装。
二、Docker 方式安装(推荐)#
2.1 前置条件#
1
2
3
4
5
6
7
8
|
# 确认 Docker 已安装
docker --version
# 如果没装,Ubuntu 下快速安装
sudo apt update
sudo apt install -y docker.io
sudo usermod -aG docker $USER
# 重新登录终端生效
|
2.2 拉取 P4 官方镜像#
1
2
3
4
5
|
# P4 官方提供的 Docker 镜像(包含 p4c + BMv2)
docker pull p4lang/p4c
# 查看镜像
docker images | grep p4
|
2.3 启动容器#
1
2
3
4
5
6
|
# 启动一个交互式容器,挂载当前目录
docker run -it --rm \
-v $(pwd):/workdir \
-w /workdir \
--name p4-dev \
p4lang/p4c bash
|
进入容器后,验证两个核心组件:
1
2
3
4
5
6
7
|
# 验证 p4c 编译器
p4c --version
# 输出类似:p4c from https://github.com/p4lang/p4c.git ...
# 验证 BMv2 软件交换机
simple_switch --version
# 输出类似:BMv2 simple_switch ...
|
两个命令都能正常输出版本号,说明环境搭建成功。
三、Ubuntu 直装方式#
如果不想用 Docker,也可以直接在 Ubuntu 24.04 上安装。
3.1 安装依赖#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
sudo apt update
sudo apt install -y \
build-essential \
cmake \
g++ \
libgmp-dev \
libboost-dev \
libboost-thread-dev \
libboost-filesystem-dev \
libevent-dev \
libtool \
libboost-program-options-dev \
libboost-test-dev \
libboost-all-dev \
automake \
pkg-config \
libelf-dev \
libffi-dev \
python3 \
python3-pip \
python3-dev
|
3.2 安装 BMv2#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# 安装 PI (Protocol Independent) API
git clone https://github.com/p4lang/PI.git
cd PI
git submodule update --init --recursive
./autogen.sh
./configure
make -j$(nproc)
sudo make install
sudo ldconfig
cd ..
# 安装 BMv2
git clone https://github.com/p4lang/behavioral-model.git
cd behavioral-model
./autogen.sh
./configure
make -j$(nproc)
sudo make install
sudo ldconfig
cd ..
|
3.3 安装 p4c#
1
2
3
4
5
6
7
|
git clone --recursive https://github.com/p4lang/p4c.git
cd p4c
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
cd ../..
|
3.4 验证安装#
1
2
|
p4c --version
simple_switch --version
|
四、跑通第一个 P4 程序#
4.1 获取官方示例#
1
2
3
|
# 克隆 P4 官方教程仓库
git clone https://github.com/p4lang/tutorials.git
cd tutorials/exercises/basic
|
4.2 认识 basic.p4#
打开 basic.p4,核心结构分三段:
// 1. Parser(包解析器):定义如何从原始字节中提取字段
parser MyParser(packet_in packet, ...) {
state start {
transition parse_ethernet;
}
state parse_ethernet {
packet.extract(tmp_hdr.ethernet);
transition select(tmp_hdr.ethernet.etherType) {
0x0800: parse_ipv4;
default: accept;
}
}
state parse_ipv4 {
packet.extract(tmp_hdr.ipv4);
transition accept;
}
}
// 2. Control(控制逻辑):定义转发行为
control MyIngress(inout headers hdr, ...) {
action ipv4_forward(macAddr_t dstAddr, ...) {
hdr.ethernet.dstAddr = dstAddr;
standard_metadata.egress_spec = port;
}
table ipv4_lpm {
key = { hdr.ipv4.dstAddr: lpm; }
actions = { ipv4_forward; NoAction; }
}
apply {
ipv4_lpm.apply();
}
}
// 3. Deparser(包组装器):定义输出顺序
control MyDeparser(packet_out packet, ...) {
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.ipv4);
}
}
4.3 编译并运行#
1
2
3
4
5
6
7
8
|
# 编译 P4 程序
make run
# 这个命令会:
# 1. 用 p4c 编译 basic.p4 → basic.json
# 2. 启动 BMv2 软件交换机
# 3. 启动 Mininet 拓扑(2 台主机)
# 4. 配置转发表
|
4.4 验证转发#
在 Mininet 中测试:
1
2
3
4
5
6
7
|
# 测试连通性
mininet> pingall
*** Ping: testing ping reachability
h1 h2
h1 -> h2
h2 -> h1
*** Results: 0% dropped (8/8 received)
|
pingall 成功,说明 P4 程序正确实现了 IP 转发。
4.5 查看流表#
打开另一个终端,查看 BMv2 的转发表:
1
2
3
4
|
# 查看当前流表
simple_switch_CLI --thrift-port 9090 <<EOF
table_dump ipv4_lpm
EOF
|
输出类似:
mafia@2d98f85d5c27:/workdir/tutorials/exercises/basic$ simple_switch_CLI --thrift-port 9090 <<EOF
> table_dump ipv4_lpm
> EOF
Dumping entry ipv4_lpm 0 { 10.0.2.2/32 => port=2 (10 bytes) }
五、Docker 调试技巧#
5.1 容器内网络问题#
如果 Docker 容器内 Mininet 无法创建网络:
1
2
3
4
5
|
# 检查是否需要特权模式
docker run -it --rm --privileged \
-v $(pwd):/workdir \
-w /workdir \
p4lang/p4c bash
|
5.2 端口映射#
BMv2 的 Thrift 控制端口(默认 9090)需要映射出来:
1
2
3
4
5
|
docker run -it --rm \
-p 9090:9090 \
-v $(pwd):/workdir \
-w /workdir \
p4lang/p4c bash
|
5.3 保存容器状态#
如果想保存调试环境:
1
2
3
4
5
|
# 查看容器 ID
docker ps -a
# 提交为新镜像
docker commit <container_id> my-p4-dev
|
六、踩坑记录#
| 问题 |
原因 |
解决方案 |
p4c: command not found |
PATH 未配置 |
Docker 镜像已内置,直装需 sudo make install |
simple_switch: error while loading shared libraries |
动态库未刷新 |
sudo ldconfig |
Mininet pingall 全部丢包 |
转发表未配置 |
检查 make run 是否成功,查看 s1-app.log |
| Docker 容器内无法创建 veth pair |
权限不足 |
加 --privileged 参数 |
make run 报错 sudo: mininet: command not found |
容器内未装 Mininet |
安装:apt install mininet |
七、今日学习总结#
| 项目 |
内容 |
| 环境搭建 |
Docker 方式安装 p4c + BMv2 |
| 验证 |
p4c --version 和 simple_switch --version |
| 首个程序 |
编译并运行 basic.p4,pingall 验证成功 |
| 流表查看 |
使用 simple_switch_CLI 查看转发表 |
| 下一篇预告 |
P4 实验 1:深入理解 basic 程序的 parser / 控制流 / deparser 结构 |