P4编程理论与实践(2)—快速上手

作者简介:郑浩,东南大学本科生,研究方向:OpenFlow,P4。邮箱: zenhox@163.com

本文内容简介

本文首先向大家简单介绍在学习P4过程中需要用到的工具。本文的主要特色是让对P4感兴趣的大家不费吹灰之力的在工作,学习之余,快速搭建完善的P4实验环境并开始第一个P4实验。本文的更新日期是2018年10月8日,使用相对于大多数教程来说较新的P4环境,本文提供两种搭建环境的方法,它们的特点如下:

  • 虚拟机安装:一个完整的p4教学环境,无需手动搭建环境。

优点: 方便,快捷,对操作系统没什么要求。

缺点:运行较慢。

如果工作环境没有Linux系统,建议使用VM。

  • 真机搭建:

优点:运行速率快,环境较新。

缺点:可能会遇到错误,需要一个ubuntu系统。

不用担心费神的环境搭建,本文将提供一个一键搭建环境的脚本。这个脚本通过了我多次测试。

实验环境介绍

  • 操作系统: Ubuntu 16.04 LTS 64位 桌面版
  • python : 2.7.12
  • 推荐内存: 4G 以上

各个组件简介

主要需要安装5个组件:

  • bmv2
  • p4c
  • mininet
  • p4-tutorial
  • PI

首先要明白他们各自的作用【图片来源于p4.org】:

如图,我们写好xxx.p4代码,通过 p4c 这个 p4 compiler 将p4代码编译成为p4交换机可以理解的各种”机器代码”。如果目标交换机是 bmv2 , 那么p4c将生成 .json文件。

  • p4c是一款 p4编译器。
  • BMv2是支持P4编程的软件交换机。
  • PI是P4 runtime的实现,用于Control Plane对数据平面的控制。
  • mininet的功能是构建一个虚拟的网络拓扑。 它通过linux内核的一些特性(net命名空间),在一个主机上划分出多个虚拟网络空间,各个网络空间之间相互隔离,有自己的端口, ip等等。mininet让一个或者多个vhost(虚拟主机), 软件交换机(如ovs, bmv2)等 以进程的状态分别绑定在这些网络空间之中,共同构成一个进程级别的虚拟网络拓扑。需要注意的是这些进程级别的主机和交换机他们只是网络上的隔离,而文件系统则是共享主机的文件系统。
  • p4 tutorials 提供了用于学习的实例代码,它提供了很多个带有方向性的实际场景,例如负载均衡,简单的隧道机制,源路由等。并且它事先写好了控制面代码,让p4的初学者可以集中注意力在数据面编程的学习之上。
  • scapy是一个python库,提供构建数据包,抓包,解析包等功能。它功能强大,但是效率很低。由于P4编程中经常会引入各种各样的数据包,有些甚至是开发者自定义的数据包格式。所以我们可以利用scapy进行便捷的组包,发包。如果需要高速率的发包和解析包就不能使用scapy了。

搭建环境

搭建环境有两条路可以走:

  • 使用环境健全的虚拟机,如果朋友们手边没有linux环境,或者希望快速上手开发,建议采取这种方式。
  • 在真机中(我这里时Ubuntu16.04)搭建。建议环境与我相同,否则可能会出现各种意想不到的问题。

方法一: 虚拟机套件

  • 官方提供了用于学习的虚拟机,里面有完整的环境。可以尝试访问官网链接。如果不能访问外网,可以尝试访问我这个1Core, 1M带宽的服务器资源
  • 官方的环境似乎比较陈旧,我利用方法二在虚拟机中搭建了一个环境,并且导出供大家使用,下面是下载链接:

1.FTP服务器下载, 这个是一个云主机,如果过期或者服务器崩溃, 联系我去修复。

2.如果FTP服务器崩溃,建议自己装一个Ubuntu16.04的虚拟机,然后调用方法二,其实也很简单。

3.这里还有一个腾讯微云的链接: https://share.weiyun.com/581m3WN

方法二: 真机搭建

真机搭建需要获得各个组件的源码,然后编译安装,可能遇到各个组件之间的版本兼容性,依赖性等问题。

本来打算一步一步写出手动搭建的步骤,但过程比较痛苦,为了防止让大家陷入搭建环境这种苦涩且收益不大的环节,本文按照p4 tutorials中vagrant用于构建虚拟机环境的脚本,进行了适当修改后,最终改成一个搭建真机P4实验环境的脚本。通过这个脚本,可以方便的让大家搭建好P4学习环境,该脚本通过了本人多次测试。

建议在网络环境较好的环境下执行脚本,如果能使用国外的代理就更好了,如果网速较慢,建议晚上睡觉前执行,然后天亮后再瞅瞅,毕竟国内访问github有时真的太慢了。

相关脚本已经上传至p4-quick 。

在搭建之前

为了不破坏原环境的整洁性,我们还是在home目录下创建一个P4的工作目录,并且加入环境变量:

在运行脚本之前,先核实一下必要的环境和依赖:

  • 发行版: Ubuntu 16.04 Desktop LTS , 通过 lsb_release -a查看。
  • Python: 2.7.12, 通过 python --version查看。
  • 内核: 4.15.0-29-generic , 通过 uanme -a查看,差不多即可。

开始搭建

先安装一些依赖:

然后创建一个文件,用于存放搭建环境的脚本:

然后将以下内容,复制到 env_up.sh文件当中:

保存退出脚本,然后执行这个脚本:

脚本开始自动为你搭建环境,如果中途遇到错误,脚本会中断,如果脚本顺利执行,那么脚本结束后,环境便搭建好了。

进行第一个实验

进行实验之前

如果你下载的是本文提供的第二种虚拟机,或者通过脚本安装了P4环境,现在P4目录下面应该是这个样子:

我们主要的工作目录时tutorials,其余的都是被使用的工具组件。细看tutorials:

其中utils里面存放了一些用于调用各个组件(mininet, bmv2, PI, p4c)的脚本,有了这些脚本,我们可以专注于p4代码的开发,控制面的编写,以及拓扑的构建,而不需要费神去了解bmv2的启动命令,p4c的调用选项等等。具体如何使用,也是非常的简单,我们进入一个具体的例子查看:

可以看到,通过Makefile,我们可以调用utils下的脚本,让我们的p4代码跑起来:

调用make run,我们可以运行当前目录下(以basic目录为例)的代码,它将执行以下几个步骤:

  • 编译basic.p4 代码,生成basic.json
  • 解析topology.json, 并且构建相应的mininet仿真拓扑,按照该拓扑启动一台或者多台BMv2交换机,以及一些host
  • 启动BMv2的同时会将p4代码编译产生的json文件导入
  • 启动BMv2后会解析 sN-runtime.json 文件,将其载入 交换机sN流表之中
  • 进入mininet命令行,同时开始记录log以及搜集pcap文件

在新版本的tutorials中,载入静态流表项时采用了runtime方法,而非之前的CLI方法,我们查看一下s1-runtime.json的部分

这是一个json文件,可以看到,其作用是定义一个个具体的流表项,标明了流表项所处的位置,匹配域,匹配模式,动作名,以及动作参数。这些字段都依赖于我们P4代码中所自定义的流表,匹配域和动作。

开始第一个实验basic

查看要实现的功能

查看README,里面这样介绍这个实验:

可以看到这是一个实现转发功能的P4实例,文件剩余部分是进行实验具体的思路和指令,建议大家多多查阅README,以后就可以自己学习啦~

查看网络拓扑结构 topology.json:

清晰明了:这个拓扑中有3个switch,3个host,构成一个三角形的拓扑,注意到定义switches的时候,会定义载入到交换机的流表项文件”sN-runtime.json”。

了解大概之后,我们开始编写basic.p4代码:

回忆代码要实现的功能:ip_v4转发。我们需要完成的是tutorials中的TODO部分。

在代码的开头, 我们得知该代码是P4_16版本,使用的是我们之前谈到的v1_model。

通过查看main回顾v1_model:

我们要需要完成以下几个基本的步骤,其余部分可以暂时省略。

  • 定义相关数据结构:根据需求,我们需要定义 ipv4数据包头以及其下层的以太网包头结构。
  • 解析数据包:我们在此提取ipv4包头。
  • MyIngress:得到了数据包头,我们定义一个用于转发的流表,然后定义匹配域和动作。
  • MyDeparser:逆解析器
  • 写好控制面代码

定义数据结构:

Parser 解析数据包

parser是一个有限状态机。从 start 状态开始,每一个状态便解析一种协议,然后根据低层协议的类型字段,选择解析高一层协议的状态,然后transition到该状态解析上层协议,最后transition到accept。具体如下:

Ingress

  • 在Ingress中,我们要实现一个转发功能,因此需要定义一个用于转发的流表:
  • 我们需要自己实现以下几个动作:

Checksum 和 Deparser

这两个部分都有高度抽象的内置函数直接完成:

写好控制面代码

虽然说官方为了让大家专注于数据面编程,已经给好了控制面指令,但是我们有必要查看一下他们,从而有了更深入的理解, 查看 s[1,2,3]-runtime.json, 里面定义了很多流表项。以s1-runtime.json为例, 具体的一条流表项为:

回想,table name 就是我们在p4代码中自定义的转发表。匹配域也依照了我们自定义的代码。而动作也按照我们编写的动作代码传入了相应的参数。将所有的流表项汇总一下, 我绘制了下面的图片:

看到这一步,我们便了然了。数据面定义了转发表,而控制面下发了具体匹配转发的流表项,使得这三个主机可以互通。而在控制面下发的流表项与我们p4代码中定义的流表结构息息相关。

运行代码

丢包率为0,说明转发功能实现了。这样我们完成了第一个实验。

一点建议

  • 初次接触mininet的朋友,建议先学习mininet官方的walkthrogh。
  • p4 tutorials exercises中的README写的非常详细,大家可以自己完成后面的一些练习。

总结

本文提供给大家最快捷的方式去体验,学习和使用P4。其中有方便的虚拟机直接使用,也有真机搭建的脚本。搭建好环境并且开始第一个实验后,大家可以自己专注于P4的学习啦。

本文分享自微信公众号 - SDNLAB(SDNLAB)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-10-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员的知识天地

程序员年薪30万,嘲讽清华北大教授工资低,网友:你真的太年轻

我国现在经济水平飞速发展,人们的生活条件也越来越好。不过这条件一好起来,就会出现一些意想不到的问题。

22330
来自专栏程序员的知识天地

程序员给心意企业打电话被拒后失声痛哭:为什么不录用我

 每个人都有特别难过的时候,这个时候往往需要别人帮一把。无独有偶,一名网友在上海张江软件园某星巴克店内见到了心酸一幕:看到一个右手有缺陷的程序员,给他的意向企业...

10520
来自专栏大魏分享(微信公众号:david-share)

在微服务中启用分布式跟踪 | 微服务系列第十篇

跟踪是一种用于监视软件的执行路径、以便进行调试或故障排除的专门的方法。您可能熟悉TRACE日志级别,其中包含有关每个方法调用的信息。跟踪微服务的目标类似于此级别...

27930
来自专栏Android群英传

紧急通知:无论你英语多差,只要想学,看了此文必有改变!

夜深了,Benson关了灯正准备上床休息,手机屏幕亮了,他拿起手机一看,是露露发来的短信:

12240
来自专栏达摩兵的技术空间

docker下部署jenkins(一)

本文带你在docker中安装jenkins服务,为入门级别的介绍,建议阅读时间10-15min.

1.5K30
来自专栏不二小段

延禧攻略变微商独播?心疼爱奇艺一秒钟

今年以来最火的剧应该就是《延禧攻略》了,上线33天以来播放量和话题量节节高升,拿下了单日播放6.5亿,累积播放95亿的成绩,目测今天零点之后就要破百亿了,我虽然...

19140
来自专栏程序员的知识天地

博士程序员感慨互联网行业太累,想进事业单位被网友批:浪费人才

一名计算机博士毕业后在互联网行业从事程序员工作,但随着年龄的增长,感觉越发吃不消了:坐标北京,36岁的博士程序员,技术一般,在互联网公司工作的很吃力,且加班多,...

63520
来自专栏二进制文集

学会提问 —— 批判性思维入门

很早之前就要计划读这本书 ——《学会提问》。其中一位作者是尼尔·布朗(Neil Browne),博林格林州立大学(Bowling Green State Uni...

11930
来自专栏程序员的知识天地

程序员月薪12k被老板逼走,换到国企月薪20k,还5点下班!

211,985学校本科毕业5年,UI,上一家创业公司12k,每天被老板嫌弃做得不好,加班不够多。

2.8K20
来自专栏程序员的知识天地

领导周末喊程序员修错误,程序员霸气回应:在下卖艺不是卖身!

现在不少员工都被公司要求各种加班,周一至周五晚上加,周末加,办公室加,回家加,有偿加,无偿加......确实让人看见就怕作为一名码农,程序员加班更是家常便饭。

11910

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励