P4语言——basic_tunnel
练习二:自定义头部
定义一种新的header,实现ipv4转发和自定义头部协议转发的优先级
控制平面代码
下发给交换机table。除了定义ipv4转发的地址与行为匹配,还定义了自定义header的转发行为匹配。
{"target": "bmv2","p4info": "build/basic_tunnel.p4info","bmv2_json": "build/basic_tunnel.json","table_entries": [{"table": "MyIngress.ipv4_lpm","match": {"hdr.ipv4.dstAddr": ["10.0.1.1", 32]},"action_name": "MyIngress.ipv4_forward","action_params": {"dstAddr": "00:00:00:00:01:01","port": 1}},{"table": "MyIngress.ipv4_lpm","match": {"hdr.ipv4.dstAddr": ["10.0.2.2", 32]},"action_name": "MyIngress.ipv4_forward","action_params": {"dstAddr": "00:00:00:02:02:00","port": 2}},{"table": "MyIngress.ipv4_lpm","match": {"hdr.ipv4.dstAddr": ["10.0.3.3", 32]},"action_name": "MyIngress.ipv4_forward","action_params": {"dstAddr": "00:00:00:03:03:00","port": 3}},{"table": "MyIngress.myTunnel_exact","match": {"hdr.myTunnel.dst_id": [1]},"action_name": "MyIngress.myTunnel_forward","action_params": {"port": 1}},{"table": "MyIngress.myTunnel_exact","match": {"hdr.myTunnel.dst_id": [2]},"action_name": "MyIngress.myTunnel_forward","action_params": {"port": 2}},{"table": "MyIngress.myTunnel_exact","match": {"hdr.myTunnel.dst_id": [3]},"action_name": "MyIngress.myTunnel_forward","action_params": {"port": 3}}]
}
拓扑平面代码
{"hosts": ["h1","h2","h3"],"switches": {"s1": { "runtime_json" : "s1-runtime.json" },"s2": { "runtime_json" : "s2-runtime.json" },"s3": { "runtime_json" : "s3-runtime.json" }},"links": [["h1", "s1"], ["s1", "s2"], ["s1", "s3"], ["s3", "s2"], ["s2", "h2"], ["s3", "h3"]]
}
P4文件
/* -*- P4_16 -*- */
#include <core.p4>
#include <v1model.p4>const bit<16> TYPE_MYTUNNEL = 0x1212;
const bit<16> TYPE_IPV4 = 0x800;/*************************************************************************
*********************** H E A D E R S ***********************************
*************************************************************************/typedef bit<9> egressSpec_t;
typedef bit<48> macAddr_t;
typedef bit<32> ip4Addr_t;header ethernet_t {macAddr_t dstAddr;macAddr_t srcAddr;bit<16> etherType;
}header myTunnel_t {bit<16> proto_id;bit<16> dst_id;
}header ipv4_t {bit<4> version;bit<4> ihl;bit<8> diffserv;bit<16> totalLen;bit<16> identification;bit<3> flags;bit<13> fragOffset;bit<8> ttl;bit<8> protocol;bit<16> hdrChecksum;ip4Addr_t srcAddr;ip4Addr_t dstAddr;
}struct metadata {/* empty */
}struct headers {ethernet_t ethernet;myTunnel_t myTunnel;ipv4_t ipv4;
}/*************************************************************************
*********************** P A R S E R ***********************************
*************************************************************************/parser MyParser(packet_in packet,out headers hdr,inout metadata meta,inout standard_metadata_t standard_metadata) {state start {transition parse_ethernet;}state parse_ethernet {packet.extract(hdr.ethernet);transition select(hdr.ethernet.etherType) {TYPE_MYTUNNEL: parse_myTunnel;//mac层后跟着自定义头部和ipv4头TYPE_IPV4: parse_ipv4;default: accept;}}state parse_myTunnel {packet.extract(hdr.myTunnel);transition select(hdr.myTunnel.proto_id) {TYPE_IPV4: parse_ipv4;//一层层的解析default: accept;}}state parse_ipv4 {packet.extract(hdr.ipv4);transition accept;}}/*************************************************************************
************ C H E C K S U M V E R I F I C A T I O N *************
*************************************************************************/control MyVerifyChecksum(inout headers hdr, inout metadata meta) { apply { }
}/*************************************************************************
************** I N G R E S S P R O C E S S I N G *******************
*************************************************************************/control MyIngress(inout headers hdr,inout metadata meta,inout standard_metadata_t standard_metadata) {action drop() {mark_to_drop();}action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {standard_metadata.egress_spec = port;hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;hdr.ethernet.dstAddr = dstAddr;hdr.ipv4.ttl = hdr.ipv4.ttl - 1;}table ipv4_lpm {key = {hdr.ipv4.dstAddr: lpm;}actions = {ipv4_forward;drop;NoAction;}size = 1024;default_action = drop();}action myTunnel_forward(egressSpec_t port) {standard_metadata.egress_spec = port;//根据传入的参数决定端口发送}table myTunnel_exact {key = {hdr.myTunnel.dst_id: exact;}actions = {myTunnel_forward;drop;}size = 1024;default_action = drop();}apply {//如果只有ipv4,根据ipv4转发if (hdr.ipv4.isValid() && !hdr.myTunnel.isValid()) {// Process only non-tunneled IPv4 packetsipv4_lpm.apply();}//如果有自定义头部,根据自定义头部的行为参数转发if (hdr.myTunnel.isValid()) {// process tunneled packetsmyTunnel_exact.apply();}}
}/*************************************************************************
**************** E G R E S S P R O C E S S I N G *******************
*************************************************************************/control MyEgress(inout headers hdr,inout metadata meta,inout standard_metadata_t standard_metadata) {apply { }
}/*************************************************************************
************* C H E C K S U M C O M P U T A T I O N **************
*************************************************************************/control MyComputeChecksum(inout headers hdr, inout metadata meta) {apply {update_checksum(hdr.ipv4.isValid(),{ hdr.ipv4.version,hdr.ipv4.ihl,hdr.ipv4.diffserv,hdr.ipv4.totalLen,hdr.ipv4.identification,hdr.ipv4.flags,hdr.ipv4.fragOffset,hdr.ipv4.ttl,hdr.ipv4.protocol,hdr.ipv4.srcAddr,hdr.ipv4.dstAddr },hdr.ipv4.hdrChecksum,HashAlgorithm.csum16);}
}/*************************************************************************
*********************** D E P A R S E R *******************************
*************************************************************************/control MyDeparser(packet_out packet, in headers hdr) {apply {packet.emit(hdr.ethernet);packet.emit(hdr.myTunnel);packet.emit(hdr.ipv4);//重新打包所有header}
}/*************************************************************************
*********************** S W I T C H *******************************
*************************************************************************/V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;
扩展
如何实现在网络入口增加自定义头部并在网络出口删除自定义头部
增加:对于入口交换机,根据ipv4地址设置自定义header的内容,并设置自定义header为isValid()。
删除:在出口交换机,根据自定义header设置出口port,并设置自定义header为notValid()。
P4语言——basic_tunnel相关推荐
- P4语言编程快速开始 实践二
参考:P4语言编程快速开始 上一篇系列博客:P4语言编程快速开始 实践二 Demo 2 本Demo所做的修改及实现的功能: 为simple_router添加一个计数器(counter),该计数器附加( ...
- P4语言的特性、P4语言和P4交换机的工作原理和流程简介
现有的SDN解决方案将控制平面与转发平面分离,并为我们提供了控制平面的可编程能力.而事实上,目前通过软件编程实现的控制平面的功能,在传统的高级交换机和路由器上也都能实现,差别是厂商把这些功能固化在了系 ...
- Ubuntu16.04安装P4语言以及遇到的问题
前言 P4语言是一种用于SDN数据平面可编程语言,主要内容是一种协议无关的包转发控制高级语言,最早在2014年的<ACM SIGCOMM Communication Review>中的&l ...
- P4语言——p4runtime
练习三:使用p4runtime 使用p4runtime而不是json文件控制交换机的table. 控制平面代码 #!/usr/bin/env python2 import argparse impor ...
- Run P4 without P4factory - A Simple Example In Tutorials. -2
Reference:Github-Tutorial Exercise 2: Implementing TCP flowlet switching 实验准备: 参考之前的博客:Run P4 withou ...
- A Simple Note on P4FPGA: A Rapid Prototyping Framework for P4
论文:P4FPGA: A Rapid Prototyping Framework for P4 Github:https://github.com/p4fpga Reference: Han Wang ...
- P4: Programming Protocol-Independent Packet Processors
P4: Programming Protocol-Independent Packet Processors 摘要 P4是一门高级语言,用于编程与协议无关的数据包处理器.P4与SDN控制协议相关联,类 ...
- linux+下c语言编程项目,精通UNIX下C语言编程与项目实践
cc -I //include 目录 -L //静态库目录?动态也可以 -l //小写L,接静态库名称?动态也可以 -DXXX='"XXFF"' //-D直接定义宏 -c 只编译 ...
- Programming Protocol-independent Packet Processors (P4)
P4语言:数据面可编程 OpenFlow:控制面可编程 类比C语言 C语言源代码-GCC编译-可执行文件-运行在CPU: P4语言源代码-P4编译器-硬件或其他形式输出-运行在CPU,FPGA,ASI ...
最新文章
- 【HeadFirst 设计模式总结】1.策略模式
- Linux shell 编程入门 - 使用ubuntu-14.10
- 金士顿sd卡恢复软件_手机上使用SD内存卡会让手机性能变差?
- JDK,JRE和JVM三者的关系以及java的运行机制,环境变量,三大版本,特点
- java学习(93):线程的创建方法二
- 【JS】教你如何在对象内任意位置插入任意属性
- node ajax配置文件,如何存储Node.js部署设置/配置文件?
- 西瓜书+实战+吴恩达机器学习(二)机器学习基础(偏差、方差、调试模型技巧)
- 运用Links方法安装插件
- 一键配置以太网IP脚本
- java模拟器野人岛2,生存战争野人岛2最终版
- android 火车购票功能,12306 火车票订票
- CSS笔记(菜鸟教程)
- LightOJ	 1224 DNA Prefix(字典树)
- 北京工商专修学校计算机学院院长,北京工商大学计算机学院
- 影院在线选座购票API接口
- 「Premiere教程」为视频添加文字字幕
- CSS3|大数据热点图案例(带图+代码)
- 一个有趣的时钟flash
- 创业股权以及企业治理体系图鉴