P4tutorial实战

Tutorial样例实战


实验一:SIGCOMM_2015/Sourse_Routing

实验环境:
实验准备:
  • 认真阅读readme文件,按照提示做下去!
  • 修改环境变量脚本env.sh,该脚本记录了bmv2和p4c-bm的位置。
  • 我的脚本信息如下:
THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )

# ---------------- EDIT THIS ------------------
BMV2_PATH=/home/liuhy/behavioral-model
# e.g. BMV2_PATH=$THIS_DIR/../bmv2
P4C_BM_PATH=/home/liuhy/p4c-bm
# e.g P4C_BM_PATH=$THIS_DIR/../p4c-bm
# ---------------- END ------------------
  • 其实就是注明bmv2的路径和p4c-bm的路径,为了保险起见我选择了绝对路径
实验描述
  • 本次实验是为了实现一个名为Sourse_Routing的协议,其协议格式如下:
preamble (8 bytes) | num_valid (4 bytes) | port_1 (1 byte) | port_2 (1 byte) | ... | port_n (1 byte) | payload
  • 其中各字段含义为:
    • preamble:8bytes,恒为0,用于区分Sourse_Routing协议的数据包,为parser的编码提供了思路。
    • num_valid:4bytes,可用端口数,这各字段的值代表头部中端口字段的数目,假定一个Sourse_Routing数据包要通过三个switch,把它的num_valid字段设置为3,意味着端口列表长度为3bytes。每经过一个switch,该字段值减1并移除第一个端口字段,第一个端口字段表明该数据包的出端口。为action提供了编码思路。
    • payload:该字段代表我们要发送的信息,目前不用管。
  • 举个例子,如果想利用Sourse_Routing协议从h1主机发送hello p4到主机h3,根据本次实验拓扑,可以设置数据包格式为:
00000000 00000000 | 00000002 | 03 | 01 | Hello
  • 经过sw1转发后:
00000000 00000000 | 00000001 | 01 | Hello
  • 经过sw3转发后:
00000000 00000000 | 00000000 | Hello
  • 注意:最后一个交换机不能移除Easyroute头部,因为这会导致主机无法解析数据包。而其他交换机可以,因为它会把数据包给交换机而不是主机,交换机会自动丢弃该数据包。
实验要求
  • 非Easyroute数据包直接丢弃,无Easyroute头部或者其他协议数据包。
  • num_vaild字段值为0的数据包直接丢弃。
Tips
  1. in the start parse state, you can use current() to check if the packet is
    an EasyRoute packet. A call to current(0, 64) will examine the first 64 bits
    of the packet, without shifting the packet pointer.
  2. do not forget that a table can match on the validity of a header. Furthermore
    if a header is not valid, our software switch will set all its fields to 0.
  3. a table can "match" on an empty key, which means the default action will
    always be executed - if configured correctly by the runtime. Just omit the
    "reads" attribute to achieve this.
  4. you can remove a header with a call to remove_header()
  5. when parsing the EasyRoute header, you do not have to parse the whole port
    list. Actually P4 is currently missing language constructs needed to parse a
    general Type-Length-Value style header1, and hence
    you’ll need to simply extract the first port of the list and ignore the rest
    (including the payload). Also preamble, num_valid and the port number don't have
    to all be placed in the same header type.
  6. finally, we advise you to put all your logic in the ingress control flow and
    leave the egress empty. You will not need more than 1 or 2 tables to implement
    EasyRoute.
填充流表
  • readme中给出了必要的两个bmv2命令:
    • table_set_default <table_name> <action_name> [action_data]: this is used to
      set the default action of a given table
    • table_add <table_name> <action_name> <match_fields> => [action_data]: this
      is used to add an entry to a table
Run!

1092957-20180930235831474-147318478.jpg

转载于:https://www.cnblogs.com/031602523liu/p/9733819.html

### P4 编程语言入门教程 #### 1. P4 的基本概念和发展背景 P4 (Programming Protocol-independent Packet Processors) 是一种专为网络数据包处理而设计的语言。该语言允许开发者定义如何在网络设备上处理数据包,从而实现灵活的网络功能定制[^1]。 #### 2. 安装环境配置 为了编写和运行 P4 程序,需要安装相应的开发工具链。通常情况下,建议使用 Ubuntu 或其他 Linux 发行版作为操作系统平台。具体步骤如下: - 更新系统软件源并安装依赖库; - 下载最新版本的 P4 软件编译器 p4c 及其配套模拟器 bmv2; - 将上述组件加入 PATH 环境变量以便全局调用。 ```bash sudo apt-get update && sudo apt-get install -y build-essential cmake git libboost-all-dev python3 python3-pip git clone --recursive https://github.com/p4lang/p4c.git cd p4c mkdir -p build && cd build cmake .. make -j$(nproc) sudo make install ``` #### 3. 基础语法介绍 以下是几个重要的 P4 特性概述: - **控制平面与数据平面分离**:P4 主要关注于描述转发行为即数据面逻辑;至于路由计算等功能则交由外部控制器完成。 - **表项管理**:通过 match-action 表来决定匹配条件以及相应动作,支持精确匹配、LPM(最长前缀匹配)、Ternary 匹配等多种模式。 - **解析器构建**:可以自定义报文结构及其字段提取方式,满足不同应用场景需求。 下面给出一段简单的 Hello World 类似程序用于创建一个最基础的数据流管道模型: ```cpp // Define a simple switch pipeline with one table that forwards packets based on destination IP address. #include <core.p4> control MyIngress(inout headers hdr, inout metadata meta) { action drop() { } action forward(port_t port) { standard_metadata.egress_spec = port; } table ipv4_lpm { key = { hdr.ipv4.dstAddr : lpm; } actions = { NoAction; forward; drop; } size = 1024; default_action = drop(); } apply { ipv4_lpm.apply(); } } V1Switch(MyIngress(), Empty()) main; ``` 此代码片段展示了如何设置基于目标 IPv4 地址进行分组传输的基本流程,并提供了三种可能的操作选项——继续执行后续指令(`NoAction`)、指定出口端口(`forward`)或是丢弃当前帧(`drop`)[^1]。 #### 4. 实践案例分析 假设现在有一个小型局域网拓扑图,其中包含三台主机 H1-H3 和两台交换机 S1-S2 。为了让这些节点之间能够正常通信,则可以在每台设备上加载特定规则集以指导流量走向。例如,在 S1 上添加一条记录指向默认下一跳地址为 H2 所属接口所对应的 MAC 地址即可达成目的。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值