fork了p4tutorials,想从里面窥探一些门道。

本文相关的原文链接:ReadMe

说明:

下面的这个P4程序,是当下最著名的 simple_router 程序的一个版本,是根据P4的1.1版本描述的。

除了这个程序之外,这个版本的p4可以根据失效的TTL字段跟踪Drop的IPv4报文;这个程序是用来说明P41.1版本的一些潜在功能,具体请移步P4.org。

Look at the P4 program and observe some of the P4 v1.1 additions:

  • strong typing in header type definitions and action declarations
  • assignment with = instead of modify_field (extension to the v1.1 spec)
  • register indexing
  • support for the ternary operator (extension to the v1.1 spec)

跑这个demo

他们提供了一个小的demo来帮助你测试这个程序,在跑这个程序之前,请确保env.sh这个文件(在这篇ReadMe的上层目录)是处在最新状态的。

To run the demo:

  • start the switch in Mininet with ./run_switch.sh
  • in another terminal, populate the table entries with ./add_entries.sh
  • you should now be able to ping h2 from h1 by typing h1 ping h2 in the Mininet CLI

Once you have the basic demo running, you can start sending packets with a TTL of 1, activate packet drop tracking in the switch and observe the count go up. To do this:

  • activate the tracking with ./register_on_off.sh on
  • send ICMP packets with a TTL of 1 from the Mininet CLI: h1 ping h2 -t 1. The packets are now dropped by the switch, so you should not be able to observe a reply

To get the drop count, simply run ./read_register.sh.

P4程序 位于 ../tutorials/p4v1_1/simple_router/p4src 目录下

/* Copyright 2013-present Barefoot Networks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ header_type ethernet_t {
fields {
bit<48> dstAddr;
bit<48> srcAddr;
bit<16> etherType;
}
} header_type ipv4_t {
fields {
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;
bit<32> srcAddr;
bit<32> dstAddr;
}
} parser start {
return parse_ethernet;
} #define ETHERTYPE_IPV4 0x0800 header ethernet_t ethernet; parser parse_ethernet {
extract(ethernet);
return select(latest.etherType) {
ETHERTYPE_IPV4 : parse_ipv4;
default: ingress;
}
} header ipv4_t ipv4; field_list ipv4_checksum_list {
ipv4.version;
ipv4.ihl;
ipv4.diffserv;
ipv4.totalLen;
ipv4.identification;
ipv4.flags;
ipv4.fragOffset;
ipv4.ttl;
ipv4.protocol;
ipv4.srcAddr;
ipv4.dstAddr;
} field_list_calculation ipv4_checksum {
input {
ipv4_checksum_list;
}
algorithm : csum16;
output_width : 16;
} calculated_field ipv4.hdrChecksum {
verify ipv4_checksum;
update ipv4_checksum;
} parser parse_ipv4 {
extract(ipv4);
return ingress;
} action _drop() {
drop();
} header_type routing_metadata_t {
fields {
bit<32> nhop_ipv4;
}
} metadata routing_metadata_t routing_metadata; register drops_register {
width: 32;
static: drop_expired;
instance_count: 16;
} register drops_register_enabled {
width: 1;
static: drop_expired;
instance_count: 16;
} action do_drop_expired() {
drops_register[0] = drops_register[0] + ((drops_register_enabled[0] == 1) ? (bit<32>)1 : 0);
drop();
} table drop_expired {
actions { do_drop_expired; }
size: 0;
} action set_nhop(in bit<32> nhop_ipv4, in bit<9> port) {
routing_metadata.nhop_ipv4 = nhop_ipv4;
standard_metadata.egress_spec = port;
ipv4.ttl = ipv4.ttl - 1;
} table ipv4_lpm {
reads {
ipv4.dstAddr : lpm;
}
actions {
set_nhop;
_drop;
}
size: 1024;
} action set_dmac(in bit<48> dmac) {
ethernet.dstAddr = dmac;
// modify_field still valid
// modify_field(ethernet.dstAddr, dmac);
} table forward {
reads {
routing_metadata.nhop_ipv4 : exact;
}
actions {
set_dmac;
_drop;
}
size: 512;
} action rewrite_mac(in bit<48> smac) {
ethernet.srcAddr = smac;
} table send_frame {
reads {
standard_metadata.egress_port: exact;
}
actions {
rewrite_mac;
_drop;
}
size: 256;
} control ingress {
if(valid(ipv4)) {
if(ipv4.ttl > 1) {
apply(ipv4_lpm);
apply(forward);
} else {
apply(drop_expired);
}
}
} control egress {
apply(send_frame);
}

【p4tutorials】P4 v1.1 Simple Router的更多相关文章

  1. 【设计模式】简单工厂模式 Simple Factory Pattern

    简单工厂模式Simple Factory Pattern[Simple Factory Pattern]是设计模式里最简单的一个模式,又叫静态工厂模式[Static Factory Pattern], ...

  2. 【翻译】Kinect v1和Kinect v2的彻底比较

      本连载主要是比较Kinect for Windows的现行版(v1)和次世代型的开发者预览版(v2),以C++开发者为背景介绍进化的硬件和软件.本文主要是对传感的配置和运行条件进行彻底的比较.   ...

  3. 【php】下载站系统Simple Down v5.5.1 xss跨站漏洞分析

    author:zzzhhh 一.        跨站漏洞 利用方法1,直接在搜索框处搜索<script>alert(/xss/)</script>//',再次刷新,跨站语句将被 ...

  4. 【代码审计】BootCMS v1.1.3 文件上传漏洞分析

      0x00 环境准备 BootCMS官网:http://www.kilofox.net 网站源码版本:BootCMS v1.1.3  发布日期:2016年10月17日 程序源码下载:http://w ...

  5. 【数论】HDU 4143 A Simple Problem

    题目内容 给出一个正整数\(n\),找到最小的正整数\(x\),使之能找到一个整数\(y\),满足\(y^2=n+x^2\). 输入格式 第一行是数据组数\(T\),每组数据有一个整数\(n\). 输 ...

  6. 数据结构【一】:简单队列simple queue

    简单的FIFO队列实现,非线程安全! 1.queue.h : abstract data type queue #ifndef CUR_QUEUE_H #define CUR_QUEUE_H #inc ...

  7. 【HDOJ】1088 Write a simple HTML Browser

    题目其实不难,但是要注意题目的要求,当前字数(>0)+当前单词长度+1若超过80则需要回车后,输出当前word,并且重新计数.这道题目的数据感觉比较水,不过测试的时候,最后使用fprintf输出 ...

  8. 【35】单层卷积网络(simple convolution)

    今天我们要讲的是如何构建卷积神经网络的卷积层,下面来看个例子.   上节课,我们已经讲了如何通过两个过滤器卷积处理一个三维图像,并输出两个不同的4×4矩阵.假设使用第一个过滤器进行卷积,得到第一个4× ...

  9. 【Vulnhub】FristiLeaks v1.3

    靶机信息 下载连接 https://download.vulnhub.com/fristileaks/FristiLeaks_1.3.ova.torrent https://download.vuln ...

随机推荐

  1. Python 中的线程-进程1

    原文:https://www.cnblogs.com/i-honey/p/8042047.html 1. 并行和并发 并行:同时做某些事,可以互不干扰的同一时刻做几件事. 并发:也是同时做某些事,但是 ...

  2. TextureMerger1.6.6 三:Bitmap Font的制作和使用

    BitmapFont主要用于特殊字体在游戏中的使用. 比如我想使用方正剪纸字体,但是没加载方正剪纸.ttf字体时,egret是没法使用这种字体的. 或者美工制作了效果拔群的0123456789数字字体 ...

  3. windowSoftInputMode

    有个问题困扰我一晚上,每次进入Activity后,EditText自动获得焦点弹出软键盘,键盘遮挡listView,使得无法显示最后一条消息.我在edittext点击事件中也设定了,listView. ...

  4. mysql存储过程基础示例

    转自:http://database.51cto.com/art/201608/516661.htm http://www.cnblogs.com/mark-chan/p/5384139.html D ...

  5. 结合Ajax做地区内容切换!(城市切换)

    实现原理:点击,进行异步保存Cookie , 根据保存的Cookie来切换城市内容: 简单HTML示例: <!doctype html> <html> <head> ...

  6. vue 引入通用 css

    1.在入口 js 文件 main.js 中引入,一些公共的样式文件,可以在这里引入. import Vue from 'vue' import App from './App' // 引入App这个组 ...

  7. vue自定义过滤器的创建和使用

    1.简单介绍   过滤器的作用:实现数据的筛选.过滤.格式化.   过滤器的本质是一个有参数,有返回值的方法.   过滤器可以用在两个地方:双花括号插值和v-bind表达式(后者从2.1.0+开始支持 ...

  8. Oracle HA 之 RAC one node实战

    --创建rac one node步骤 安装grid软件,配置grid集群:安装oracle软件:dbca创建rac one node. >试验创建的rac one node数据库信息如下: gl ...

  9. 使用pidstat查看进程资源使用情况

    简介 pidstat主要用于监控全部或指定进程占用系统资源的情况,如CPU,内存.设备IO.任务切换.线程等.pidstat首次运行时显示自系统启动开始的各项统计信息,之后运行pidstat将显示自上 ...

  10. 针对Redis队列的理解,实例操作(转)

    原文:本文出自 “峰云,就她了.”  http://rfyiamcool.blog.51cto.com/1030776/1131271 为什么要使用消息队列 用我的话来说, 队列特点是先进先出,在任务 ...