/*
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.
*/ /*
* Openflow Processing
*/ // Openflow features
//#define OPENFLOW_ENABLE_MPLS
//#define OPENFLOW_ENABLE_VLAN
//#define OPENFLOW_ENABLE_L3 // adds some handy stuff from switch.p4 for packet in/out
#define OPENFLOW_PACKET_IN_OUT #define ingress_input_port standard_metadata.ingress_port
#define ingress_egress_port standard_metadata.egress_spec
#define egress_egress_port standard_metadata.egress_port
#define intrinsic_mcast_grp intrinsic_metadata.mcast_grp header_type openflow_metadata_t {
fields {
index : 32;
bmap : 32;
group_id : 32;
ofvalid : 1;
}
} metadata openflow_metadata_t openflow_metadata; #ifndef CPU_PORT_ID
#define CPU_PORT_ID 64
#endif #define TRUE 1 #ifdef OPENFLOW_PACKET_IN_OUT
#define ETHERTYPE_BF_FABRIC 0x9000 #define FABRIC_HEADER_TYPE_MULTICAST 2
#define FABRIC_HEADER_TYPE_CPU 5 header_type fabric_header_t {
fields {
packetType : 3;
headerVersion : 2;
packetVersion : 2;
pad1 : 1; fabricColor : 3;
fabricQos : 5; dstDevice : 8;
dstPortOrGroup : 16;
}
} header_type fabric_header_multicast_t {
fields {
routed : 1;
outerRouted : 1;
tunnelTerminate : 1;
ingressTunnelType : 5; ingressIfindex : 16;
ingressBd : 16; mcastGrp : 16;
}
} header_type fabric_header_cpu_t {
fields {
egressQueue : 5;
txBypass : 1;
reserved : 2; ingressPort: 16;
ingressIfindex : 16;
ingressBd : 16; reasonCode : 16;
}
} header_type fabric_payload_header_t {
fields {
etherType : 16;
}
} header fabric_header_t fabric_header;
header fabric_header_cpu_t fabric_header_cpu;
header fabric_header_multicast_t fabric_header_multicast;
header fabric_payload_header_t fabric_payload_header; parser parse_fabric_header {
extract(fabric_header);
return select(latest.packetType) {
FABRIC_HEADER_TYPE_MULTICAST : parse_fabric_header_multicast;
FABRIC_HEADER_TYPE_CPU : parse_fabric_header_cpu;
default : ingress;
}
} parser parse_fabric_header_multicast {
extract(fabric_header_multicast);
return parse_fabric_payload_header;
} parser parse_fabric_header_cpu {
extract(fabric_header_cpu);
return parse_fabric_payload_header;
} parser parse_fabric_payload_header {
extract(fabric_payload_header);
return select(latest.etherType) {
// add more ethertypes here if you want
default: ingress;
}
} action nop () {
} // remove the comments in "terminate_cpu_packet" and "terminate_fabric_multicast_packet"
// as necessary. I'm just assuming these features aren't used (Except copying the
// ethertype from the fabric payload header, that's necessary but I don't want to
// assume you've named your ethernet header "ethernet" :) ) action terminate_cpu_packet() {
modify_field(ingress_egress_port,
fabric_header.dstPortOrGroup);
// modify_field(egress_metadata.bypass, fabric_header_cpu.txBypass); modify_field(ethernet.etherType, fabric_payload_header.etherType);
remove_header(fabric_header);
remove_header(fabric_header_cpu);
remove_header(fabric_payload_header);
} action terminate_fabric_multicast_packet() {
// modify_field(tunnel_metadata.tunnel_terminate,
// fabric_header_multicast.tunnelTerminate);
// modify_field(tunnel_metadata.ingress_tunnel_type,
// fabric_header_multicast.ingressTunnelType);
// modify_field(l3_metadata.nexthop_index, 0);
// modify_field(l3_metadata.routed, fabric_header_multicast.routed);
// modify_field(l3_metadata.outer_routed,
// fabric_header_multicast.outerRouted); modify_field(intrinsic_mcast_grp,
fabric_header_multicast.mcastGrp); modify_field(ethernet.etherType, fabric_payload_header.etherType);
remove_header(fabric_header);
remove_header(fabric_header_multicast);
remove_header(fabric_payload_header);
} table packet_out {
reads {
fabric_header.packetType : exact;
}
actions {
nop;
terminate_cpu_packet;
terminate_fabric_multicast_packet;
}
} #endif /* OPENFLOW_PACKET_IN_OUT */ /****************************************************************
* Actions common to all openflow tables, sets a bitmap indicating
* which OFPAT to be applied to packets in flow flow_id.
****************************************************************/ action openflow_apply(bmap, index, group_id) {
modify_field(openflow_metadata.bmap, bmap);
modify_field(openflow_metadata.index, index);
modify_field(openflow_metadata.group_id, group_id);
modify_field(openflow_metadata.ofvalid, TRUE);
// modify_field(egress_metadata.bypass, TRUE);
} action openflow_miss(reason, table_id) {
#ifdef OPENFLOW_PACKET_IN_OUT
add_header(fabric_header);
add_header(fabric_header_cpu);
add_header(fabric_payload_header); modify_field(fabric_payload_header.etherType, ethernet.etherType); modify_field(fabric_header_cpu.ingressPort, ingress_input_port);
#endif modify_field(fabric_header_cpu.reasonCode, reason); shift_left(fabric_header_cpu.reasonCode, fabric_header_cpu.reasonCode, 8);
bit_or(fabric_header_cpu.reasonCode, fabric_header_cpu.reasonCode, table_id); modify_field(ingress_egress_port, CPU_PORT_ID);
} /****************************************************************
* Egress openflow bitmap translation
****************************************************************/ action ofpat_group_egress_update(bmap) {
bit_or (openflow_metadata.bmap, openflow_metadata.bmap, bmap);
} table ofpat_group_egress {
reads {
openflow_metadata.group_id : exact;
egress_egress_port : exact;
} actions {
ofpat_group_egress_update;
nop;
}
} /****************************************************************
* GROUPS
****************************************************************/ action ofpat_group_ingress_uc(ifindex) {
modify_field(ingress_egress_port, ifindex);
} action ofpat_group_ingress_mc(mcindex) {
modify_field(intrinsic_mcast_grp, mcindex);
} table ofpat_group_ingress {
reads {
openflow_metadata.group_id : exact;
} actions {
ofpat_group_ingress_uc;
ofpat_group_ingress_mc;
nop;
}
} /****************************************************************
* OFPAT_OUTPUT
****************************************************************/ action ofpat_output(egress_port) {
modify_field(ingress_egress_port, egress_port);
// for switch.p4
// modify_field(ingress_metadata.egress_ifindex, 0);
} table ofpat_output {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
ingress_egress_port : ternary;
} actions {
ofpat_output;
nop;
}
} #ifdef OPENFLOW_ENABLE_MPLS
/***************************************************************
* OFPAT_SET_MPLS_TTL
***************************************************************/ action ofpat_set_mpls_ttl(ttl) {
modify_field(mpls[0].ttl, ttl);
} table ofpat_set_mpls_ttl {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
egress_egress_port : ternary;
} actions {
ofpat_set_mpls_ttl;
nop;
}
} /***************************************************************
* OFPAT_DEC_MPLS_TTL
***************************************************************/ action ofpat_dec_mpls_ttl() {
add_to_field(mpls[0].ttl, -1);
} table ofpat_dec_mpls_ttl {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
egress_egress_port : ternary;
} actions {
ofpat_dec_mpls_ttl;
nop;
}
} /****************************************************************
* OFPAT_PUSH_MPLS
****************************************************************/ action ofpat_push_mpls() {
modify_field(ethernet.etherType, 0x8847);
add_header(mpls[0]);
} table ofpat_push_mpls {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
egress_egress_port : ternary;
} actions {
ofpat_push_mpls;
nop;
}
} /***************************************************************
* OFPAT_POP_MPLS
***************************************************************/ action ofpat_pop_mpls() {
remove_header(mpls[0]);
} table ofpat_pop_mpls {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
egress_egress_port : ternary;
} actions {
ofpat_pop_mpls;
nop;
}
}
#endif /* OPENFLOW_ENABLE_MPLS */
#ifdef OPENFLOW_ENABLE_VLAN
/***************************************************************
* OFPAT_PUSH_VLAN
***************************************************************/ action ofpat_push_vlan() {
modify_field(ethernet.etherType, 0x8100);
add_header(vlan_tag_[0]);
modify_field(vlan_tag_[0].etherType, 0x0800);
} table ofpat_push_vlan {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
egress_egress_port : ternary;
} actions {
ofpat_push_vlan;
nop;
}
} /***************************************************************
* OFPAT_POP_VLAN
***************************************************************/ action ofpat_pop_vlan() {
modify_field(ethernet.etherType, vlan_tag_[0].etherType);
remove_header(vlan_tag_[0]);
} table ofpat_pop_vlan {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
egress_egress_port : ternary;
} actions {
ofpat_pop_vlan;
nop;
}
} /***************************************************************
* OFPAT_SET_FIELD
***************************************************************/ action ofpat_set_vlan_vid(vid) {
modify_field(vlan_tag_[0].vid, vid);
} table ofpat_set_field {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
egress_egress_port : ternary;
} actions {
ofpat_set_vlan_vid;
nop;
}
} #endif /* OPENFLOW_ENABLE_VLAN */ /****************************************************************
* OFPAT_SET_QUEUE
****************************************************************/ //TODO #ifdef OPENFLOW_ENABLE_L3
/***************************************************************
* OFPAT_SET_NW_TTL IPV4
***************************************************************/ action ofpat_set_nw_ttl_ipv4(ttl) {
modify_field(ipv4.ttl, ttl);
} table ofpat_set_nw_ttl_ipv4 {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
egress_egress_port : ternary;
} actions {
ofpat_set_nw_ttl_ipv4;
nop;
}
} /***************************************************************
* OFPAT_SET_NW_TTL IPV6
***************************************************************/ action ofpat_set_nw_ttl_ipv6(ttl) {
modify_field(ipv6.hopLimit, ttl);
} table ofpat_set_nw_ttl_ipv6 {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
egress_egress_port : ternary;
} actions {
ofpat_set_nw_ttl_ipv6;
nop;
}
} /***************************************************************
* OFPAT_DEC_NW_TTL IPV4
***************************************************************/ action ofpat_dec_nw_ttl_ipv4() {
add_to_field(ipv4.ttl, -1);
} table ofpat_dec_nw_ttl_ipv4 {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
egress_egress_port : ternary;
} actions {
ofpat_dec_nw_ttl_ipv4;
nop;
}
} /***************************************************************
* OFPAT_DEC_NW_TTL IPV6
***************************************************************/ action ofpat_dec_nw_ttl_ipv6(ttl) {
add_to_field(ipv6.hopLimit, -1);
} table ofpat_dec_nw_ttl_ipv6 {
reads {
openflow_metadata.index : ternary;
openflow_metadata.group_id : ternary;
egress_egress_port : ternary;
} actions {
ofpat_dec_nw_ttl_ipv6;
nop;
}
}
#endif /* OPENFLOW_ENABLE_L3 */ /***************************************************************
* Main control block
***************************************************************/ control process_ofpat_ingress {
if (openflow_metadata.bmap & 0x400000 == 0x400000) {
apply(ofpat_group_ingress);
} if (openflow_metadata.bmap & 0x1 == 1) {
apply(ofpat_output);
}
} control process_ofpat_egress {
apply(ofpat_group_egress); #ifdef OPENFLOW_ENABLE_MPLS
if (openflow_metadata.bmap & 0x100000 == 0x100000) {
apply(ofpat_pop_mpls);
} if (openflow_metadata.bmap & 0x80000 == 0x80000) {
apply(ofpat_push_mpls);
} if (openflow_metadata.bmap & 0x10000 == 0x10000) {
apply(ofpat_dec_mpls_ttl);
} if (openflow_metadata.bmap & 0x8000 == 0x8000) {
apply(ofpat_set_mpls_ttl);
}
#endif /* OPENFLOW_ENABLE_MPLS */
#ifdef OPENFLOW_ENABLE_VLAN
if (openflow_metadata.bmap & 0x40000 == 0x40000) {
apply(ofpat_pop_vlan);
} if (openflow_metadata.bmap & 0x20000 == 0x20000) {
apply(ofpat_push_vlan);
} if (openflow_metadata.bmap & 0x2000000 == 0x2000000) {
apply(ofpat_set_field);
}
#endif /* OPENFLOW_ENABLE_VLAN */
#ifdef OPENFLOW_ENABLE_L3
if (openflow_metadata.bmap & 0x1000000 == 0x1000000) {
if ((valid(ipv4))) {
apply(ofpat_dec_nw_ttl_ipv4);
} else {
if ((valid(ipv6))) {
apply(ofpat_dec_nw_ttl_ipv6);
}
}
} if (openflow_metadata.bmap & 0x800000 == 0x800000) {
if (valid(ipv4)) {
apply(ofpat_set_nw_ttl_ipv4);
} else {
if (valid(ipv6)) {
apply(ofpat_set_nw_ttl_ipv6);
}
}
}
#endif /* OPENFLOW_ENABLE_L3 */ // oq (set queue)
}

2016/10/16

OpenFlow.p4 源码的更多相关文章

  1. switch parser.p4源码

    /* Copyright 2013-present Barefoot Networks, Inc. Licensed under the Apache License, Version 2.0 (th ...

  2. maven 下载 源码和javadoc 命令

    摘要:我们在写代码时候,往往是想查看一下源码,看看源码的一些细节内容.一般情况下,在IDE(如eclipse)中近仅仅只需按住ctrl+ 点击对应的方法即可进入对应的源码部分.但是有些时候很多依赖项并 ...

  3. android源码的目录结构

    android源码的目录结构 [以下网络摘抄] |-- Makefile ! l/ a5 n% S% @- `0 d# z# a$ P4 V3 o7 R|-- bionic              ...

  4. JS魔法堂:剖析源码理解Promises/A规范

    一.前言 Promises/A是由CommonJS组织制定的异步模式编程规范,有不少库已根据该规范及后来经改进的Promises/A+规范提供了实现 如Q, Bluebird, when, rsvp. ...

  5. AndFix热修复 —— 实战与源码解析

    当你的应用发布后第二天却发现一个重要的bug要修复,头疼的同时你可能想着赶紧修复重新打个包发布出去,让用户收到自动更新重新下载.但是万事皆有可能,万一隔一天又发现一个急需修复的bug呢?难道再次发布打 ...

  6. socket_server源码剖析、python作用域、IO多路复用

    本节内容: 课前准备知识: 函数嵌套函数的使用方法: 我们在使用函数嵌套函数的时候,是学习装饰器的时候,出现过,由一个函数返回值是一个函数体情况. 我们在使用函数嵌套函数的时候,最好也这么写. def ...

  7. JQuery源码分析(七)

    了解jQuery对DOM进行遍历背后的工作机制,这样可以在编写代码时有意识地避免一些不必要的重复操作,从而提升代码的性能. 关于jQuery对象的包装 var $aaron = $("aar ...

  8. Hadoop源码的编译过程详细解读(各版本)

    说在前面的话   重新试多几次.编译过程中会出现下载某个包的时间太久,这是由于连接网站的过程中会出现假死,按ctrl+c,重新运行编译命令. 如果出现缺少了某个文件的情况,则要先清理maven(使用命 ...

  9. Android中Canvas绘图基础详解(附源码下载) (转)

    Android中Canvas绘图基础详解(附源码下载) 原文链接  http://blog.csdn.net/iispring/article/details/49770651   AndroidCa ...

随机推荐

  1. 组合数(codevs 1631)

    1631 组合数  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description 组合数C(N, K)表示 ...

  2. ajax(ajax开发与入门)

    AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术.AJAX是一种进行页面局部异步刷新的技术,局 ...

  3. [hihoCoder] 博弈游戏·Nim游戏

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 今天我们要认识一对新朋友,Alice与Bob.Alice与Bob总是在进行各种各样的比试,今天他们在玩一个取石子的游戏.在 ...

  4. oracle 卸载步骤(图解)

    1.卸载第一步:点击开始菜单: 步骤阅读 2 2.点击Universal Installer来实现下面 步骤阅读 3 3.点击卸载产品后出现的内容: 步骤阅读 4 4.点击打开Oracle主目录下的O ...

  5. 递推DP URAL 1017 Staircases

    题目传送门 /* 题意:给n块砖头,问能组成多少个楼梯,楼梯至少两层,且每层至少一块砖头,层与层之间数目不能相等! 递推DP:dp[i][j] 表示总共i块砖头,最后一列的砖头数是j块的方案数 状态转 ...

  6. LightOJ1033 Generating Palindromes(区间DP/LCS)

    题目要计算一个字符串最少添加几个字符使其成为回文串. 一年多前,我LCS这道经典DP例题看得还一知半解时遇到一样的问题,http://acm.fafu.edu.cn/problem.php?id=10 ...

  7. android 进程什么时候被销毁

    http://wear.techbrood.com/guide/components/processes-and-threads.html 每一个 android 应用默认会起一个进程,除非你用 an ...

  8. BZOJ2739 : 最远点

    把环倍长,设$w(i,j)$表示对于$i$,决策$j$的价值,如果$j$在$[i,i+n]$,那么$w(i,j)=dis(i,j)$,否则$w(i,j)=-dis(i,j)$. 则$w$满足四边形不等 ...

  9. 解决ibus图标为红圈(图标丢失)

    修正IBUS图标丢失gconftool –type boolean -s /desktop/ibus/panel/show_icon_on_systray truegconftool –type bo ...

  10. 【POJ】2828 Buy Tickets(线段树+特殊的技巧/splay)

    http://poj.org/problem?id=2828 一开始敲了个splay,直接模拟. tle了.. 常数太大.. 好吧,说是用线段树.. 而且思想很拽.. (貌似很久以前写过貌似的,,) ...