专栏首页SDNLABP4入门教程(2):P4程序的编译、运行验证与分析

P4入门教程(2):P4程序的编译、运行验证与分析

在前面《P4入门教程:搭建开发和实验环境》一文中,梳理了P4实验的大致流程。P4程序只需要经过一次编译过程,生成数据平面的JSON格式描述文件,最后在启动软件交换机时将JSON描述文件导入即可。现在我带领大家来实际操作一下。

本文重点讲述编译P4程序、启动P4交换机的方法,并以这样一个小功能为例展示P4程序的运行:

交换机只处理IPv4包,把收到的包打上三层MPLS标签,再从入端口把包发回去。

1.实验环境

如下图,配置好两台虚拟机VM1、VM2,Ubuntu 16.04 LTS系统。

VM1作为Switch交换机,绑定ens192和ens224两个网口到交换机上,分别作为1、2号网口。

VM2作为Host主机,唯一的网口ens160与VM1的ens192网口直连,即接在交换机1号端口上。

2.P4程序的编译及运行

首先,在笔者的Github下载示例代码mao_push_three_labels_send_back.p4: https://github.com/MaoJianwei/P4-example-code

(1)编译

执行编译命令,由.p4代码文件生成.json描述文件:

$ p4c-bm2-ss --p4v 16 -o output.file ./mao_push_three_labels_send_back.p4

p4c-bm2-ss是p4c项目编译完后的产物之一,专门用于将P4程序编译生成bmv2使用的描述文件。使用不同的编译器将生成适用于不同平台的文件。

--p4v 16指明程序是用P4-16版语言编写的;

-o output.file指明生成文件的位置和名字;

代码文件的位置和名字写在最后。

如果编译成功,命令行不会有任何显示。如果出现warning,可能是实例化的资源没有被使用,函数参数没有被使用等,最好做出修正,但生成的文件仍可以导入交换机运行。

(2)运行

执行运行命令,启动一个交换机并导入JSON文件:

$ sudo simple_switch -L 'trace' --thrift-port 9090 --log-file ~/maoP4/mao.log --log-flush -i 1@ens192 -i 2@ens224 output.file

simple_switch是behavioral-model项目编译完后的产物之一,可用作基本的P4设备。此外还有simple_router等,可在详细了解它们的特点后选用。

-L 'trace',日志相关,设置哪个级别以上的日志应该输出。

--log-file ~/maoP4/mao.log,日志相关,设置将日志记录在文件中及文件的位置和名称。

--log-flush,日志相关,当日志记录在文件中时,每条日志产生后直接写盘,而不需要等到磁盘缓冲区满。

-i 1@ens192,可选项,将系统中某个Interface作为某号端口绑定到交换机上,可以是物理网口,也可以是veth等。这里将虚拟机的ens192网卡作为交换机的1号网口。

--thrift-port 9090,设置RPC服务的监听端口,每个交换机需要设置不同的端口。P4交换机使用Thrift库来实现RPC服务。控制面通过RPC向服务器下发配置、更改转发表、修改寄存器中的值等。目前也有使用gRPC库来实现,其与ONOS等控制器能更好更灵活地交互,有兴趣的朋友可以研究一下。

output.file,由p4c-bm2-ss生成的JSON描述文件。

成功运行后,命令行会打印少量初始化信息。

(3)控制

启动控制程序:

$ simple_switch_CLI --thrift-port 9090

simple_switch_CLI是bmv2自带的一个控制脚本,对应于simple_switch,运行后会进入一个新的命令行。这里不推荐使用官方介绍的runtime_CLI.py脚本,因为它在组播组配置等方面有bug,会导致控制程序崩溃,而且它的功能也不如simple_switch_CLI丰富。

--thrift-port,指明某个交换机的RPC服务监听的端口。默认是9090。

--thrift-ip,指明某个交换机的IP,可以远程控制交换机。默认是本机。

启动后,控制程序会先从交换机获取它的JSON描述信息,用于命令内容的初始化,然后进入事件循环,等待我们输入命令。支持按Tab补全命令,可用命令一览:

简单的操作可以在RuntimeCmd敲入命令完成,我们也可以将多条命令写入一个文本文件,每条命令占一行,然后通过Linux输入重定向的方式,一次性将多条命令导入Runtime执行。假设多条命令保存在command.txt中,示例如下:

show_ports和show_tables两条命令分别查询了交换机的端口信息和匹配表信息。

$ simple_switch_CLI --thrift-port 9090 < command.txt

3.验证展示

编译、运行mao_push_three_labels_send_back.p4,启动控制程序:

$ p4c-bm2-ss --p4v 16 --p4runtime-file maoRuntime.file --p4runtime-format text -o output.file mao_push_three_labels_send_back.p4

$ sudo simple_switch -L 'trace' --thrift-port 9090 --log-file ~/maoP4/mao.log --log-flush -i 1@ens192 -i 2@ens224 output.file

$ simple_switch_CLI --thrift-port 9090

VM2作为主机,Ping同网段的一个未分配的IP,200.0.0.2,目的只是利用ping发ICMP包来产生IPv4流量。

为了让演示过程更加精炼,程序没有让交换机处理二层流量,这将导致ARP不能完成,因此首先在VM2上进行ARP静态设置,然后开始产生IPv4流量:

$ sudo arp –s 200.0.0.2 66:66:66:66:66:66

这时在交换机1号口检测到注入的v4流量,此时因为交换机匹配表中没有内容,因此直接丢包。

在Runtime命令行中添加一条匹配表,让发往200.0.0.2的包先打上三层MPLS标签,标签值由外到内分别是333、666、999,然后从入端口发回去:

RuntimeCmd: table_add ip_map_mpls push_3_labels_and_send_back 200.0.0.2 => 333 666 999

图中可以看到:上方,长度为98字节的Ping-request包后面紧跟着一个长度为110的Ping-request包。下方,这个包在原来的Ethernet和IP之间加入了三层MPLS标签,而且标签值和顺序正确。另外,Exp、bos(S)、TTL值是程序中设定的,其中bos(S)遵循了MPLS标签栈规则。

到此,P4程序的编译、运行和验证就顺利结束了,希望能给朋友们一点启发。下一篇“P4入门教程”系列连载文章中,我们将利用本次演示中的P4程序,进行P4程序结构的简析,敬请期待!

参考资料

[1]示例代码库https://github.com/MaoJianwei/P4-example-code

[2]《MPLS Fundamentals》,Cisco Press

本文分享自微信公众号 - SDNLAB(SDNLAB),作者:毛健炜@北邮

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

原始发表时间:2017-09-30

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • “白牌”来挑战 传统品牌交换机还行吗?

    编者按:“白牌”交换机的呼声甚嚣尘上,“控制器+白牌交换机”似乎已经是黄金组合,其实不然。瘦死的骆驼比马大,传统交换机横行这么多年必然有其可取之处,因此在白牌交...

    SDNLAB
  • 前有围堵后有追兵,白盒化下的交换机市场老大思科

    在交换机领域,思科是绝对的“龙头老大”,一直牢牢占据着交换机市场的第一份额。但前段时间爆发的关于亚马逊AWS考虑以低价将自己的网络交换机出售给企业客户的传闻,造...

    SDNLAB
  • 源码解读ODL与OpenFlow交换机建立过程

    编者按:OpenDaylight两大技术特色:1.采用了OSGi框架;2.引入了SAL,而今天我们主要介绍服务抽象层(SAL)适配的南向协议之一OF协议模块。 ...

    SDNLAB
  • C#后台调用前台javascript的五种方法

    跟着阿笨一起玩NET
  • 肿瘤预后基因筛选神器:Survival_Analysis_Terminator.R

    上一期的教程给大家讲解了批量对TCGA中的基因进行生存分析的第一步。主要内容为:如何通过cBioportal去下载TCGA中的数据和患者的表型数据,然后通过R语...

    用户6317549
  • Map集合遍历的四种方式理解和简单使用

    ~Map集合是键值对形式存储值的,所以遍历Map集合无非就是获取键和值,根据实际需求,进行获取键和值 1:无非就是通过map.keySet()获取到值,然后根据...

    别先生
  • Java 中如何模拟真正的同时并发请求?

    有时需要测试一下某个功能的并发性能,又不要想借助于其他工具,索性就自己的开发语言,来一个并发请求就最方便了。

    芋道源码
  • Map

    mathor
  • jQuery实现一个穿梭框

    需求:点击选中左侧内容,把左侧的内容放到右侧的框里面,可以一次放入一个,也可以一次放入多个或者全部,同样,右侧也一样。

    祈澈菇凉
  • 图片轮播(左右切换)--JS原生和jQuery实现

    左右切换的做法基本步骤跟 上一篇文章  淡入淡出 类似,只不过修改了一些特定的部分

    书童小二

扫码关注云+社区

领取腾讯云代金券