参考文章:王垠:谈谈Parser

簡單介紹 P4 語言(一)- Parser

什么是Parser

传统的parser,一般出现在编译器和编译原理课程中,援引《谈谈Parser》的定义:

首先来科普一下。所谓 parser,一般是指把某种格式的文本(字符串)转换成某种数据结构的过程。最常见的 parser,是把程序文本转换成编译器内部的一种叫做“抽象语法树”(AST)的数据结构。也有简单一些的 parser,用于处理 CSV,JSON,XML 之类的格式。

也就是说,parser 是编译器用来 将人们编写的程序代码,转换成编译器读的懂的代码 的工具,parsing 是这个过程。

机器本身能够读懂的代码,往往具有复杂的逻辑数据结构,不能直接读懂程序员写的代码,这个时候就需要parser了。

那么在P4语言中的parser,我认为和编译过程中的parser相类似:数据包到达Switch的时候,并不能马上进行Match-Action匹配,需要 parser解析器 进行处理加工成MA单元能够匹配的程序。那么这个过程,可以通过P4程序代码的Parser模块进行定义。

P4中的Parser

P4中的Parser解析器模块,包括两个方面:

(1)Header,说明底层解析器解析数据报的时候,有哪些格式(字段长度,值限制等等)的Header可以使用,这些格式下Header的处理细节是什么。

(2)Parser,说明处理该格式Header下的解析工具。

Header

Header定义代码:

header_type ethernet_t {        //header类型:以太网类型
fields { //域
dst_addr : 48; //目的地址字段长度:48bit
src_addr : 48; //源地址字段长度:48bit
ether_type : 16; //以太网类型字段长度:16bit
}
}

Header实例化代码:

header ethernet_t ethernet;

Header可以类比为C语言中的Structure,在以太网格式域内,将一些特定属性(字段字节长度)说明清楚。

我们可以写一个独立的说明Header的p4程序,并将它include到比较重要的p4程序中。

也就是说,定义的时候说明一些固有属性;那么我们要使用它的时候,就需要把它实例化出来了。

类比,C语言中的Structure定义如下:

struct Node{
int data;
Node* next;
}

实例化如下:

struct Node n;

类比之后,就发现其实不难理解。Header实例化的过程,也可以叫做 header instance。

Parser

parser也一样,可以在一个p4程序里面(比如命名为parser.p4)定义,方便编程重构。

按照我的理解,parser工具和工具之间有相互调用的关系,可以通过类似if-else的逻辑判断选用何种parser。

在P4程序中,永远有一个起始的parser,和一个结束的节点。

起始parser,我们叫做start:

parser start {
return next_parser; //next_parser 特定协议格式的parser
}

终止节点,一般是:

return ingress;

结束解析器处理阶段,来到Match-Action的Ingress阶段。

援引《简单介绍 P4语言》的这段话:

在每一個 parser 中都會依據目前所分析的內容來決定下一個 parser,直到回傳的內容為 “ingress”(或其他 control function) 為止.

这个目前所分析的内容,我认为是协议类型,当前所要处理的数据报的协议类型(比如IPv4,比如Ethernet等等)决定了要使用的下一个parser工具。

当最后return ingress进入Ingress阶段,或者其他功能模块的时候,结束parsing解析过程。

代码分析(以 处理IPv4数据报 为例):

parser start {                //parsing,开始调用parser工具。
return parse_ethernet; //当前处理的是以太网协议字段,调用处理以太网的parser。
} parser parse_ethernet { //处理以太网协议的parser
extract(ethernet); //extract,parser工具解析 格式为以太网的Header实例ethernet。
return select(latest.ether_type) { //select,类似if-else的逻辑判断,判断条件是以太网字段的长度,根据判断条件决定调用何种工具。
0x0800 : parse_ipv4; //latest.ether_type : 0x0800 ---> 调用处理Ipv4的parser。
default : ingress; //latest.ether_type 属性不为 0x0800 ---> 调用ingress,结束解析。
}
} parser parse_ipv4 { //处理Ipv4协议的parser。
extract(ipv4); //解析Ipv4协议。
return ingress; //调用ingress,结束。
}
這邊有幾個需要補充的東西:

   1) extract : 將目前的 Packet 以特定的 header 取出來,取出來的資料長度以 header 定義的為主
2) return : 透過 return 的方式決定要前往哪個 parser、control function(後面會補充),可以直接 return 或是使用 select。
3) select(select_exp) : 蠻像 C 語言中的 switch case,依據特定的 field 數值去決定要哪一個 parser 或是 control function。
4) select_exp : 依據 spec,他可以是:
* field_ref : 如 ethernet.ether_type
* latest.field_name : 以最後 extract 的 header 為主,取用他的 field
* current (offset, length) : 以目前的 packet offset 位置開始某固定長度所取得的數值。

说明一下 select(select_exp),我们可以根据Header的某些特定属性,来决定调用何种parser。这个属性可以是前面提到的 1)当前parser所处理的协议,所属的Header域属性,也可以是 2)最后解析的Header的域(不一定是当前处理的),还可以是 3)current,参考上文。

类比于C语言中的if-else,就很好理解了。

parser 异常处理 exception

parser 也提供了异常处理exception,格式如下:

parser_error parser_exception_name;

parser_exception_name 有很多种,比如 p4_pe_out_of_packet 等等。

如果我们要执行一个exception,我们需要先定义好 exception handler。

parser_exception p4_pe_out_of_packet {
/* statements */
/* return or parser_drop */
}

处理一个exception的方法有很多,但是最后的结果只会有两个,(1)运行指定的function,(2)将该包drop掉。

Egress阶段

与Ingress之前的解析器处理阶段相对应的是 Match-Action 的动作逻辑阶段,需要把Ingress时做的修改,比如add header、modiffy header等等,重新装到packet里面去。

2016/9/28

【P4语言学习】Parser解析器的更多相关文章

  1. EasyUI基础入门之Parser(解析器)

    前言 JQuery EasyUI提供的组件包含功能强大的DataGrid,TreeGrid.面板.下拉组合等.用户能够组合使用这些组件,也能够单独使用当中一个.(使用的形式是以插件的方式提供的) Ea ...

  2. 1.引入必要的文件 2.加载 UI 组件的方式 4.Parser 解析器

    //引入 jQuery 核心库,这里采用的是 2.0 <scripttype="text/javascript"src="easyui/jquery.min.js& ...

  3. EasyUI Parser 解析器

    Parser(解析器)应用场景 1,自动调用parser 只要我们书写相应的class,easyui就能成功的渲染页面,这是因为解析器在默认情况下,会在dom加载完成的时候($(docunment). ...

  4. 「Django」rest_framework学习系列-解析器

    满足两个要求,request.Post中才有值 1.请求头要求:请求头中的Content-Type为application/x-www-form-urlencoded 2.数据格式要求 name=x& ...

  5. 【P4语言学习】basic_routing.p4

    headers.p4 /* Copyright 2013-present Barefoot Networks, Inc. Licensed under the Apache License, Vers ...

  6. P4语言编程详解

    1.源码目录结构 P4项目源码可以在github上直接获取(https://github.com/p4lang).P4项目由很多个单独的模块组成,每个模块就是一个子项目,下面分别简单介绍一下各模块的功 ...

  7. easyui的解析器Parser

    平时使用easyui做框架开发时,都知道easyui的模块组件能通过属性方法或js方法来渲染,本质上是通过parser解析器来处理实现的,因为多数情况下都是自动触发完成整个页面的解析,所以没有感觉到它 ...

  8. 四、XML语言学习(1)

    XML语言 1.XML是什么?XML是指可扩展标记语言XML是指可扩展标记语言(eXtensible Markup Language),它是一种标记语言,很类似HTML.它被设计的宗旨是传输数据,而非 ...

  9. Python 文本解析器

    Python 文本解析器 一.课程介绍 本课程讲解一个使用 Python 来解析纯文本生成一个 HTML 页面的小程序. 二.相关技术 Python:一种面向对象.解释型计算机程序设计语言,用它可以做 ...

随机推荐

  1. 【BZOJ1176】[Balkan2007]Mokia/【BZOJ2683】简单题 cdq分治

    [BZOJ1176][Balkan2007]Mokia Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=1600 ...

  2. 利用阿里云腾讯云正版KMS服务器端口转发

    注意:以下内容仅供实验,请勿用于任何非法用途我们知道,阿里云和腾讯云在内网部署了KMS服务器,而且是正版的,那么,有没有办法使用公网的计算机直接或间接连接到这些KMS服务器呢,受代理服务器和跳板机配置 ...

  3. 第1章 1.6计算机网络概述--OSI参考模型

    ISO七层模式:国际标准组织对互联网通信规则进行的定义. 7.应用层:所有能产生网络流量的程序,如:QQ. 6.表示层:传输前对数据进行进行处理,是一种数据处理的规则,如:加密.压缩.传输二进制(图片 ...

  4. python控制台输出颜色

    python_控制台输出带颜色的文字方法在开发项目过程中,为了方便调试代码,经常会向stdout中输出一些日志,默认的这些日志就直接显示在了终端中.而一般的应用服务器,第三方库,甚至服务器的一些通告也 ...

  5. (2.4)DDL增强功能-数据汇总grouping、rollup、cube

    参考:https://www.cnblogs.com/nikyxxx/archive/2012/11/27/2791001.html 1.rollup (1)rollup在group by 子句中使用 ...

  6. centos LAMP第三部分php,mysql配置 php配置文件 配置php的error_log 配置php的open_basedir 安装php的扩展模块 phpize mysql配置第二十一节课

    centos   LAMP第三部分php,mysql配置 php配置文件   配置php的error_log  配置php的open_basedir 安装php的扩展模块 phpize  mysql配 ...

  7. JAVA问题定位跟踪技术

    常用的JAVA调试技巧: 线程堆栈解读 性能瓶颈分析 远程调试 内存泄露检测 常用工具集: proc工具集 系统跟踪命令truss/strace Core文件管理coreadm 进程状态监控prsta ...

  8. React package.json详解

    概述: 每个项目的根目录下面,一般都有一个package.json文件,定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称.版本.许可证等元数据).npm install命令根据这个配置文件 ...

  9. 一个很大的文件,存放了10G个整数的乱序数列,如何用程序找出中位数。

    一.梳理审题 一.看清题目: 注意这个题目的量词,这个文件中有10G个整数,而不是这个文件占了10G的内存空间. 二.一些疑问: 在计算机中我们讲的G.M等都是存储容量的概念,但是一般都会在会面加上B ...

  10. Java final finally finalize有什么不同

    ① final 可以用来修饰类.方法.变量, ----final修饰的class代表不可以继承扩展 ----final的变量不可以修改 ----final的方法不可以override ----fina ...