引言


  • OpenFlow协议固定的包头域数目,使得南向协议过于死板。
  • P4可以实现自定义包头,增加灵活性。
  • P4是OpenFlow未来发展的方向。

We propose P4 as a strawman proposal for how OpenFlow should evolve in the future.

  • P4的三个目标:

    • 可重新配置。
    • 协议无关性。
    • 目标无关性:强调了P4的通用性。

1. INTRODUCTION


  • 可以看出:随着版本的迭代,OpenFlow协议越来越复杂。
  • 不再像OpenFlow一样重复的扩展包头,交换机应该支持灵活的“匹配-动作”机制,灵活的包解析机制。这样带来的好处是:
    • 网络供应商扩展新功能变得简单。
    • 控制器应用可以通过通用的南向接口(OpenFlow2.0)来利用交换机的这些功能。
    • 简化南向协议。(与OpenFlow1.x相比)

  • P4:用来配置交换机,告诉交换机如何处理包。
  • existing APIs:例如OpenFlow,被设计用来填充固定功能交换机中的转发表。
  • Figure 1展示了P4与existing APIs的关系:P4提高了网络编程的抽象程度,P4也可以称为像OpenFlow一样的南向协议。

That is, we believe that future generations of OpenFlow should allow the controller to tell the switch how to operate, rather than be constrained by a fixed switch design.

  • 全文框架

    • 一个关于P4的实例。
    • P4如何实现自定义包头,包解析,多张“匹配-动作”表以及多张表之间的控制流。
    • P4编译器的功能及实现。
  • Related work
    • Yadav et al:提出了OpenFlow的一个抽象转发模型,但是忽略了编译器。
    • Kangaroo:介绍了可编程包解析的概念。
    • Song:提出了协议无关,但是他的目标交换机更加倾向于网络处理器。
    • ONF:介绍了表达交换机的匹配能力的类型表。
    • NOSIX:“匹配-动作”表的灵活规范,但是没有考虑协议无关,也没有提出一种语言来定义自定义包头,包解析,多张“匹配-动作”表以及多张表之间的控制流。
    • Other recent work:提出了用于数据平面监视、拥塞控制和队列管理的编程接口。
    • The Click modular router:在软件中支持灵活的数据包处理,但无法将程序配置到各种目标交换机。

2. P4 LANGUAGE BY EXAMPLE


背景:网络部署分为核心交换机与边缘交换机。终端主机与边缘交换机直接相连,边缘交换机通过高带宽的核心交换机相连,核心交换机负责包的转发。

例子是这样的
  • 一个L2网络,使用ToR相连的交换机做为边缘设备。边缘设备之间用2层核心交换机相连。

L2网络:

OSI网络模型分为七层:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

L1代表layer 1就是物理层 L2是数据链路层 L3是网络层

ToR连接技术:

TOR(Top of Rack)是一种数据中心的布线方式。其他的布线方式还有EOR(End of Row)和MOR(Middle of Row)。

TOR接入方式就是在标准的42U的服务器机柜的最上面安装接入交换机。服务器的网口都接入到机柜上部的交换机上。这个接入交换机再通过铜缆或光纤接入到网络机柜的汇聚或核心交换机上。这种组网的好处是简化布线,从服务器机柜到列头柜只有很少的电缆。

这种布局要求每个服务器机柜的服务器密度比较高。

从网络设计上看,TOR布局中每台交换机上的VLAN/子网不会太多,在网络规划的时候也尽量避免让一个VLAN跨了多台交换机,所以TOR布局时一个VLAN范围不会太大,所包含的端口不会太多。但对于EOR来说,一个VLAN范围可能会更大,包含的端口更多。

还有一点,TOR布局的交换机数量多,EOR布局的交换机数量少,所以两者的维护管理工作量也不同。

  • 假设终端主机数目增多,二层核心交换的的转发表Overflowing,有以下三种方法来解决这个问题:
方案 做法 不足
MPLS协议 为每个数据包打上一个Tag,转发时只根据这个Tag来转发。 分发标签,多标签难实现
PortLand 重写MAC地址 破坏网络调试工具
增加ARP协议的负担
P4 mTag:结合上面二者。把核心路由的转发路线以及
目的定界符(PortLand's Pseudo MAC)编码为4字节的
Tag,核心交换机在转发时只需检查4字节中的1个字节即可
完成转发。这个标签可以由数据包经过的第一个ToR交换机打
上,也可以由主机上的NIC打上。这个例子采用了前者。
-

2.1 Underlying Hardware Assumptions

  • 为了实现P4的目标无关性,底层的通用硬件必须满足如下要求:
编号 具体细节
1 支持两种执行模式:
1. 配置模式:在这个模式下,把数据包格式、"匹配-动作"表格式,下发给交换机。
2. 人口模式:在这个模式下,可以向交换机添加/删除规则。
2 有可配置的包解析器,用来识别和提取新的字段。
3 硬件中的表,必须支持:与所有已经定义的字段的匹配。
4 硬件必须支持一些独立于协议的原语,比如对旧域、新域、元数据的复制、添加、删除、修改等操作。
  • P4与OpenFlow的一些对比
- P4 OpenFlow
对硬件要求
解析器功能 可编程、可定义新字段 只能识别固化的头部
流表 顺序+并行处理
(超标量流水线)
只能顺序的处理
(普通流水线)
支持的动作 动做均由原语构成,灵活可编程 固化的几个动作

2.2 P4 Overview

  • 为了实现硬件的两个模式(configuration,population),一个P4程序包含了以下几个组件:
名称 含义/功能
头部(Headers) 一系列头部字段的顺序和结构,包括字段的宽度以及一些对字段值的约束。
解析器(Parsers) 从数据包中提取出头部。
表(Tables) "匹配-动作"表,类似于流表。
动作(Actions) "匹配-动作"表中的动作,由独立于协议的原语组成。
控制程序(Control Programs) 描述了数据包匹配、动作的顺序以各张表之间的控制流(control flow)。

2.3 Header Formats

  • 每个头部都由一系列有序的字段组成,字段名称后的数字为可选字段,标注最大长度(约束)。
  • 一些例子:
  1. //以太网头部
  2. header ethernet {
  3. fields {
  4. dst_addr : 48; // width in bits
  5. src_addr : 48;
  6. ethertype : 16;
  7. }
  8. }
  1. //VLAN头部
  2. header vlan {
  3. fields {
  4. pcp : 3;
  5. cfi : 1;
  6. vid : 12;
  7. ethertype : 16;
  8. }
  9. }
  • mTag的头部,每个核心交换机检查头部字段中的一个比特,这个比特取决于交换机的location in the hierarchy和数据包的direction of travel (向上层还是下层)。
  1. //mTag头部
  2. header mTag {
  3. fields {
  4. up1 : 8;
  5. up2 : 8;
  6. down1 : 8;
  7. down2 : 8;
  8. ethertype : 16;
  9. }
  10. }

2.4 The Packet Parser

  • P4的解析器其实是Header之间转换的状态机,根据检测到的值,跳转到下一个解析器。
  • 贴上原文,方便理解:

P4 describes this state machine directly as the set of transitions from one header to the next. Each transition may be triggered by values in the preceding header.

  • P4的解析器都会有一个start状态,从它对应的解析器(状态)开始检测数据包。
  1. parser start{ //start状态
  2. ethernet; //起始先调用名为ethernet的解析器
  3. }
  4. parser ethernet { //刚开始调用的解析器,也是ethernet状态
  5. switch(ethertype) { //检测ethertype字段的值
  6. case 0x8100: vlan; //如果ethertype的值=0x8100,跳转到名为vlan的解析器
  7. case 0x9100: vlan; //如果ethertype的值=0x9100,跳转到名为vlan的解析器
  8. case 0x800: ipv4; //如果ethertype的值=0x0800,跳转到名为ipv4的解析器
  9. // Other cases
  10. }
  11. }
  12. parser vlan { //vlan状态
  13. switch(ethertype) { //检测ethertype字段的值
  14. case 0xaaaa: mTag; //如果ethertype的值=0xaaaa,跳转到名为mTag的解析器
  15. case 0x800: ipv4; //如果ethertype的值=0x0800,跳转到名为ipv4的解析器
  16. // Other cases
  17. }
  18. }
  19. parser mTag { //mTag状态
  20. switch(ethertype) { //检测ethertype字段的值
  21. case 0x800: ipv4; //如果ethertype的值=0x0800,跳转到名为ipv4的解析器
  22. // Other cases
  23. }
  24. }
  • P4的解析器状态机从起始状态start开始,直到stop状态或者在处理过程中出错才停止。
  • 到达一个新状态时,解析器提取某些字段,根据它的值跳转到下一状态。
  • 解析器提取到的头部信息,交给"匹配-动作"表。

2.5 Table Specification

  • 在我们的mTag例子中,边缘交换机根据目的MAC地址和VLAN ID,为数据包加上mTag的头部,其实这就相当于一次"match -action",根据MAC地址和VLAN ID匹配,动作是:打上mTag标签。
  • P4程序员根据上面了例子,定义一张表。用来match on these fields, with the action to add the mTag header
  • 例子说明:
  1. table mTag_table {
  2. reads {
  3. ethernet.dst_addr : exact; //对目的MAC地址的精确匹配
  4. vlan.vid : exact; //对VLAN ID的精确匹配
  5. }
  6. actions {
  7. // At runtime, entries are programmed with params
  8. // for the mTag action. See below.
  9. add_mTag;
  10. }
  11. max_size : 20000;
  12. }
  • 各个字段及其解释
字段名 含义/作用
read 声明要匹配的字段,以及匹配类型(精确、三元等)。
actions 声明可能对数据包进行的操作,下面还会详细介绍。
max_size 声明这张表最多容纳多少条目。
  • 论文中又给出了控制程序中的三张表的伪代码,控制程序会在后面介绍。2.7节
  1. table source_check {
  2. // Verify mtag only on ports to the core
  3. reads {
  4. mtag : defined; // Was mtag parsed?
  5. metadata.ingress_port;
  6. }
  7. actions {
  8. // If inappropriate mTag, send to CPU
  9. fault_to_cpu;
  10. // If mtag found, strip and record in metadata
  11. strip_mtag;
  12. // Otherwise, allow the packet to continue
  13. pass;
  14. }
  15. max_size : 64; // One rule per port
  16. }
  17. table local_switching {
  18. // Reads destination and checks if local
  19. // If miss occurs, goto mtag table.
  20. }
  21. table egress_check {
  22. // Verify egress is resolved
  23. // Do not retag packets received with tag
  24. // Reads egress and whether packet was mTagged
  25. }

2.6 Action Specifications

  • 前面我们提到过,P4语言中,动作是由P4定义的一系列原语组成的。
  • 为了使Table更加简单,P4把Action定义在函数中。每个P4程序都有自己的Action
  • 刚刚我们提到的add_mTag,由以下代码实现。
  1. action add_mTag(up1, up2, down1, down2, egr_spec) { //传入五个参数
  2. add_header(mTag); //原语,在数据包前加上mTag类型的头部
  3. // Copy VLAN ethertype to mTag
  4. copy_field(mTag.ethertype, vlan.ethertype);
  5. // Set VLAN's ethertype to signal mTag
  6. set_field(vlan.ethertype, 0xaaaa);
  7. set_field(mTag.up1, up1);
  8. set_field(mTag.up2, up2);
  9. set_field(mTag.down1, down1);
  10. set_field(mTag.down2, down2);
  11. // Set the destination egress port as well
  12. set_field(metadata.egress_spec, egr_spec);
  13. }
  • 传入的参数,是在match的时候产生的。
  • 我们也可以逆着这个action函数,写出一个去掉mTagaction
  • 介绍一下P4提供的原语。
名称 含义/功能
set_field set某一头部中的某一个域。
copy_field 把某一头部包含的某一个域的值复制到另一个头部上的某一域
add_header 给数据包加上一个新的头部。
remove_header 从数据包中删除一个头部。
increment 修改头部中某一字段的值。
checksum 计算头部的校验和。

2.7 The Control Program

  • 控制程序负责控制表的顺序,它是由一系列函数、条件句和表的引用组成的程序。
  • 这张图演示了用于在边缘交换机中实现mTag的控制流。

  1. 在包解析过后,"source_check"表检差收到的包与如端口是否一致,例如,带有mTag的包只能从与核心交换机相连的端口收到。"source_check"表同时还会剥掉mTag头部,并在metadata中记录这个数据包是否带有mTag头部,防止重复的贴标签。
  2. "local_switching"表开始工作,如果这个表"miss"了,就表明这个数据包不是发给本地主机的,转3。如果是发给本地的,转4。
  3. 不是本地的数据包,交给我们刚刚定义过的"mTag"表,进行匹配,然后交给"egress_check"表,转4。
  4. 不管是不是本地数据包,"egress_check"表会根据匹配的结果或者根据本地主机所在位置,将包转发。对于那些未知目的地址的数据包,"egress_check"表会把它交给SDN控制器。
  • 下面是mTag控制流的源代码,所用到的表在前面已经提过。
  1. control main() {
  2. // Verify mTag state and port are consistent
  3. table(source_check);
  4. // If no error from source_check, continue
  5. if (!defined(metadata.ingress_error)) {
  6. // Attempt to switch to end hosts
  7. table(local_switching);
  8. if (!defined(metadata.egress_spec)) {
  9. // Not a known local host; try mtagging
  10. table(mTag_table);
  11. }
  12. // Check for unknown egress state or
  13. // bad retagging with mTag.
  14. table(egress_check);
  15. }
  16. }

3. COMPILING A P4 PROGRAM


  • 为了在一个网络中使用我们的P4程序,我们需要一个编译器将P4代码配置到目标交换机。
  • 其中涉及到设备资源分配和设备配置的问题。

3.1 Compiling Packet Parsers

  • 对于具有可编程解析器的设备,P4编译器把对解析器的描述翻译成解析状态机(类似有穷自动机)。
  • 对于具有固化的解析器的设备,P4编译器只是去检查它的解析器和P4代码中描述的是否相同
  • 具体细节在这篇论文中:G. Gibb, G. Varghese, M. Horowitz, and N. McKeown, "Design principles for packet parsers," in ANCS, pp. 13-24, 2013.
  • 下面的表格展示了vlanmTag状态机的状态转移表,是不是很像有穷自动机的转移函数呢?

  • 根据当前状态和检测到的字段值,来决定下一状态。

3.2 Compiling Control Programs

Programming Protocol-Independent Packet Processors的更多相关文章

  1. P4: Programming Protocol-Independent Packet Processors

    P4: Programming Protocol-Independent Packet Processors 摘要 P4是一门高级语言,用于编程与协议无关的数据包处理器.P4与SDN控制协议相关联,类 ...

  2. SDN 编程语言 p4(SDN programming language P4)

    行业趋势,SND是未来. P4 是未来. SDN is inevitably, and P4 is inevitably. P4 = Programming Protocol-Independent ...

  3. DC.p4: programming the forwarding plane of a data-center switch

    Name of article:Dc. p4: Programming the forwarding plane of a data-center switch Origin of the artic ...

  4. Fast Packet Processing - A Survey

    笔记是边读边写的旁注,比较乱,没有整理就丢上来了. 可以说不仅要说fast packet process servey,也同时是一篇packet process的综述了.packet processi ...

  5. 浅谈原始套接字 SOCK_RAW 的内幕及其应用(port scan, packet sniffer, syn flood, icmp flood)

    一.SOCK_RAW 内幕 首先在讲SOCK_RAW 之前,先来看创建socket 的函数: int socket(int domain, int type, int protocol); domai ...

  6. Method of Seamless Integration and Independent Evolution of Information-Centric Networking via Software Defined Networking

    A method of transferring data between a software defined network (SDN) and an information-centric ne ...

  7. Npcap:Nmap项目里一个为Windows而生的嗅探库 Npcap: Nmap Project's packet sniffing library for Windows

    如果有人知道Npcap与libpcap对应的头文件列表,请告诉我,非常感谢 Introduction介绍 This Manual describes the programming interface ...

  8. Spanning Tree Protocol (STP) in NetScaler Appliance

    Spanning Tree Protocol (STP) in NetScaler Appliance 来源 https://support.citrix.com/article/CTX112341 ...

  9. Reading Fast Packet Processing A Survey

    COMST 2018 主要内容 这是一篇有关快速包转发的综述,先介绍了包转发的有关基础知识和背景,具体介绍了包转发的主流方法,对这些方法进行了细致详尽的比较,最后介绍了最新的方法和未来的研究方向. 包 ...

随机推荐

  1. jquery里操作json相关的方法和实例

    $.getJSON("/html/aijquery/JSON.js",function(d){     $.each(d,function(i,v){             $( ...

  2. 批处理之 for /f 中的delims和tokens

    0x00 前言 今天在对windows进行提权之前的系统信息收集的时候,需要使用到一条批处理语句把特定部分的内容从一个txt的文本当中提取出来:该条语句是如下: for /f "tokens ...

  3. mysql secure_file_priv 文件读写问题

    secure_file_priv特性 使用 show global variables like '%secure%'; 查询显示 secure_file_priv的值为null,那么secure_f ...

  4. docker 容器 设置网络代理

    以/bin/bash 形式进入容器: [设置http 及https代理],如下: export http_proxy=http://172.16.0.20:3128 export https_prox ...

  5. PAT甲级 1004.Counting Leaves

    参考:https://blog.csdn.net/qq278672818/article/details/54915636 首先贴上我一开始的部分正确代码: #include<bits/stdc ...

  6. Mac配置MySql

    MySql在Mac下的情况如下: 首先,我们进入MySql的官网下载MySql(直接点击即可),打开之后便是这样. 我们点击红色方框标记的内容,之后我等待下载完成. 下载完成之后,我们需要点点,注意一 ...

  7. 20155222 2016-2017-2 《Java程序设计》实验三

    20155222 2016-2017-2 <Java程序设计>实验三 1 在IDEA中使用工具(Code->Reformate Code)把下面代码重新格式化,再研究一下Code菜单 ...

  8. 使用cursor递归遍历sqlserver的相应表

    use rc GO )DECLARE cur1 cursor for select [name] from sys.tables where name LIKE 'index_%' drop tabl ...

  9. tkinter菜单图标,工具栏

    所用的图片: import tkinter as tk from tkinter import messagebox, filedialog, simpledialog, colorchooser f ...

  10. 【转载】C/C++杂记:NULL与0的区别、nullptr的来历

    原文:C/C++杂记:NULL与0的区别.nullptr的来历 某些时候,我们需要将指针赋值为空指针,以防止野指针.   有人喜欢使用NULL作为空指针常量使用,例如:int* p = NULL;. ...