diff --git a/.gitmodules b/.gitmodules index 14461012..9337c3e1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -818,3 +818,6 @@ [submodule "vendor/grammars/language-regexp"] path = vendor/grammars/language-regexp url = https://github.com/Alhadis/language-regexp +[submodule "vendor/grammars/atom-language-p4"] + path = vendor/grammars/atom-language-p4 + url = https://github.com/TakeshiTseng/atom-language-p4 diff --git a/grammars.yml b/grammars.yml index 217eefad..c1619668 100755 --- a/grammars.yml +++ b/grammars.yml @@ -180,6 +180,8 @@ vendor/grammars/atom-language-1c-bsl: - source.sdbl vendor/grammars/atom-language-clean: - source.clean +vendor/grammars/atom-language-p4: +- source.p4 vendor/grammars/atom-language-perl6: - source.meta-info - source.perl6fe diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index a86c8a31..b5f6d819 100755 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -2952,6 +2952,14 @@ Oz: codemirror_mode: oz codemirror_mime_type: text/x-oz language_id: 270 +P4: + type: programming + color: "#7055b5" + extensions: + - ".p4" + tm_scope: source.p4 + ace_mode: text + language_id: 348895984 PAWN: type: programming color: "#dbb284" diff --git a/samples/P4/l2.p4 b/samples/P4/l2.p4 new file mode 100644 index 00000000..b24ca974 --- /dev/null +++ b/samples/P4/l2.p4 @@ -0,0 +1,329 @@ +/* +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. +*/ + +/* + * Layer-2 processing + */ + +header_type l2_metadata_t { + fields { + lkp_pkt_type : 3; + lkp_mac_sa : 48; + lkp_mac_da : 48; + lkp_mac_type : 16; + + l2_nexthop : 16; /* next hop from l2 */ + l2_nexthop_type : 1; /* ecmp or nexthop */ + l2_redirect : 1; /* l2 redirect action */ + l2_src_miss : 1; /* l2 source miss */ + l2_src_move : IFINDEX_BIT_WIDTH; /* l2 source interface mis-match */ + stp_group: 10; /* spanning tree group id */ + stp_state : 3; /* spanning tree port state */ + bd_stats_idx : 16; /* ingress BD stats index */ + learning_enabled : 1; /* is learning enabled */ + port_vlan_mapping_miss : 1; /* port vlan mapping miss */ + same_if_check : IFINDEX_BIT_WIDTH; /* same interface check */ + } +} + +metadata l2_metadata_t l2_metadata; + +#ifndef L2_DISABLE +/*****************************************************************************/ +/* Spanning tree lookup */ +/*****************************************************************************/ +action set_stp_state(stp_state) { + modify_field(l2_metadata.stp_state, stp_state); +} + +table spanning_tree { + reads { + ingress_metadata.ifindex : exact; + l2_metadata.stp_group: exact; + } + actions { + set_stp_state; + } + size : SPANNING_TREE_TABLE_SIZE; +} +#endif /* L2_DISABLE */ + +control process_spanning_tree { +#ifndef L2_DISABLE + if (l2_metadata.stp_group != STP_GROUP_NONE) { + apply(spanning_tree); + } +#endif /* L2_DISABLE */ +} + +#ifndef L2_DISABLE +/*****************************************************************************/ +/* Source MAC lookup */ +/*****************************************************************************/ +action smac_miss() { + modify_field(l2_metadata.l2_src_miss, TRUE); +} + +action smac_hit(ifindex) { + bit_xor(l2_metadata.l2_src_move, ingress_metadata.ifindex, ifindex); +} + +table smac { + reads { + ingress_metadata.bd : exact; + l2_metadata.lkp_mac_sa : exact; + } + actions { + nop; + smac_miss; + smac_hit; + } + size : MAC_TABLE_SIZE; +} + +/*****************************************************************************/ +/* Destination MAC lookup */ +/*****************************************************************************/ +action dmac_hit(ifindex) { + modify_field(ingress_metadata.egress_ifindex, ifindex); + bit_xor(l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex); +} + +action dmac_multicast_hit(mc_index) { + modify_field(intrinsic_metadata.mcast_grp, mc_index); +#ifdef FABRIC_ENABLE + modify_field(fabric_metadata.dst_device, FABRIC_DEVICE_MULTICAST); +#endif /* FABRIC_ENABLE */ +} + +action dmac_miss() { + modify_field(ingress_metadata.egress_ifindex, IFINDEX_FLOOD); +#ifdef FABRIC_ENABLE + modify_field(fabric_metadata.dst_device, FABRIC_DEVICE_MULTICAST); +#endif /* FABRIC_ENABLE */ +} + +action dmac_redirect_nexthop(nexthop_index) { + modify_field(l2_metadata.l2_redirect, TRUE); + modify_field(l2_metadata.l2_nexthop, nexthop_index); + modify_field(l2_metadata.l2_nexthop_type, NEXTHOP_TYPE_SIMPLE); +} + +action dmac_redirect_ecmp(ecmp_index) { + modify_field(l2_metadata.l2_redirect, TRUE); + modify_field(l2_metadata.l2_nexthop, ecmp_index); + modify_field(l2_metadata.l2_nexthop_type, NEXTHOP_TYPE_ECMP); +} + +action dmac_drop() { + drop(); +} + +table dmac { + reads { + ingress_metadata.bd : exact; + l2_metadata.lkp_mac_da : exact; + } + actions { +#ifdef OPENFLOW_ENABLE + openflow_apply; + openflow_miss; +#endif /* OPENFLOW_ENABLE */ + nop; + dmac_hit; + dmac_multicast_hit; + dmac_miss; + dmac_redirect_nexthop; + dmac_redirect_ecmp; + dmac_drop; + } + size : MAC_TABLE_SIZE; + support_timeout: true; +} +#endif /* L2_DISABLE */ + +control process_mac { +#ifndef L2_DISABLE + apply(smac); + apply(dmac); +#endif /* L2_DISABLE */ +} + +#ifndef L2_DISABLE +/*****************************************************************************/ +/* MAC learn notification */ +/*****************************************************************************/ +field_list mac_learn_digest { + ingress_metadata.bd; + l2_metadata.lkp_mac_sa; + ingress_metadata.ifindex; +} + +action generate_learn_notify() { + generate_digest(MAC_LEARN_RECEIVER, mac_learn_digest); +} + +table learn_notify { + reads { + l2_metadata.l2_src_miss : ternary; + l2_metadata.l2_src_move : ternary; + l2_metadata.stp_state : ternary; + } + actions { + nop; + generate_learn_notify; + } + size : LEARN_NOTIFY_TABLE_SIZE; +} +#endif /* L2_DISABLE */ + +control process_mac_learning { +#ifndef L2_DISABLE + if (l2_metadata.learning_enabled == TRUE) { + apply(learn_notify); + } +#endif /* L2_DISABLE */ +} + + +/*****************************************************************************/ +/* Validate packet */ +/*****************************************************************************/ +action set_unicast() { + modify_field(l2_metadata.lkp_pkt_type, L2_UNICAST); +} + +action set_unicast_and_ipv6_src_is_link_local() { + modify_field(l2_metadata.lkp_pkt_type, L2_UNICAST); + modify_field(ipv6_metadata.ipv6_src_is_link_local, TRUE); +} + +action set_multicast() { + modify_field(l2_metadata.lkp_pkt_type, L2_MULTICAST); + add_to_field(l2_metadata.bd_stats_idx, 1); +} + +action set_multicast_and_ipv6_src_is_link_local() { + modify_field(l2_metadata.lkp_pkt_type, L2_MULTICAST); + modify_field(ipv6_metadata.ipv6_src_is_link_local, TRUE); + add_to_field(l2_metadata.bd_stats_idx, 1); +} + +action set_broadcast() { + modify_field(l2_metadata.lkp_pkt_type, L2_BROADCAST); + add_to_field(l2_metadata.bd_stats_idx, 2); +} + +action set_malformed_packet(drop_reason) { + modify_field(ingress_metadata.drop_flag, TRUE); + modify_field(ingress_metadata.drop_reason, drop_reason); +} + +table validate_packet { + reads { +#ifndef __TARGET_BMV2__ + l2_metadata.lkp_mac_sa mask 0x010000000000 : ternary; +#else + l2_metadata.lkp_mac_sa : ternary; +#endif + l2_metadata.lkp_mac_da : ternary; + l3_metadata.lkp_ip_type : ternary; + l3_metadata.lkp_ip_ttl : ternary; + l3_metadata.lkp_ip_version : ternary; +#ifndef __TARGET_BMV2__ + ipv4_metadata.lkp_ipv4_sa mask 0xFF000000 : ternary; +#else + ipv4_metadata.lkp_ipv4_sa : ternary; +#endif +#ifndef IPV6_DISABLE +#ifndef __TARGET_BMV2__ + ipv6_metadata.lkp_ipv6_sa mask 0xFFFF0000000000000000000000000000 : ternary; +#else + ipv6_metadata.lkp_ipv6_sa : ternary; +#endif +#endif /* IPV6_DISABLE */ + } + actions { + nop; + set_unicast; + set_unicast_and_ipv6_src_is_link_local; + set_multicast; + set_multicast_and_ipv6_src_is_link_local; + set_broadcast; + set_malformed_packet; + } + size : VALIDATE_PACKET_TABLE_SIZE; +} + +control process_validate_packet { + if (ingress_metadata.drop_flag == FALSE) { + apply(validate_packet); + } +} + + +/*****************************************************************************/ +/* Egress BD lookup */ +/*****************************************************************************/ +action set_egress_bd_properties() { +} + +table egress_bd_map { + reads { + egress_metadata.bd : exact; + } + actions { + nop; + set_egress_bd_properties; + } + size : EGRESS_BD_MAPPING_TABLE_SIZE; +} + +control process_egress_bd { + apply(egress_bd_map); +} + + +/*****************************************************************************/ +/* Egress VLAN decap */ +/*****************************************************************************/ +action remove_vlan_single_tagged() { + modify_field(ethernet.etherType, vlan_tag_[0].etherType); + remove_header(vlan_tag_[0]); +} + +action remove_vlan_double_tagged() { + modify_field(ethernet.etherType, vlan_tag_[1].etherType); + remove_header(vlan_tag_[0]); + remove_header(vlan_tag_[1]); +} + +table vlan_decap { + reads { + vlan_tag_[0] : valid; + vlan_tag_[1] : valid; + } + actions { + nop; + remove_vlan_single_tagged; + remove_vlan_double_tagged; + } + size: VLAN_DECAP_TABLE_SIZE; +} + +control process_vlan_decap { + apply(vlan_decap); +} diff --git a/samples/P4/mirror_acl.p4 b/samples/P4/mirror_acl.p4 new file mode 100644 index 00000000..f5db1f29 --- /dev/null +++ b/samples/P4/mirror_acl.p4 @@ -0,0 +1,39 @@ +// Copyright 2015, 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. + +action set_mirror_id(session_id) { + clone_ingress_pkt_to_egress(session_id); +} + +table mirror_acl { + reads { + ingress_metadata.if_label : ternary; + ingress_metadata.bd_label : ternary; + + /* ip acl */ + ingress_metadata.lkp_ipv4_sa : ternary; + ingress_metadata.lkp_ipv4_da : ternary; + ingress_metadata.lkp_ip_proto : ternary; + + /* mac acl */ + ingress_metadata.lkp_mac_sa : ternary; + ingress_metadata.lkp_mac_da : ternary; + ingress_metadata.lkp_mac_type : ternary; + } + actions { + nop; + set_mirror_id; + } + size : INGRESS_MIRROR_ACL_TABLE_SIZE; +} diff --git a/vendor/README.md b/vendor/README.md index 359a9b14..2c0911dd 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -240,6 +240,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting - **OpenType Feature File:** [Alhadis/language-fontforge](https://github.com/Alhadis/language-fontforge) - **Ox:** [andreashetland/sublime-text-ox](https://github.com/andreashetland/sublime-text-ox) - **Oz:** [eregon/oz-tmbundle](https://github.com/eregon/oz-tmbundle) +- **P4:** [TakeshiTseng/atom-language-p4](https://github.com/TakeshiTseng/atom-language-p4) - **Papyrus:** [Kapiainen/SublimePapyrus](https://github.com/Kapiainen/SublimePapyrus) - **Parrot Internal Representation:** [textmate/parrot.tmbundle](https://github.com/textmate/parrot.tmbundle) - **Pascal:** [textmate/pascal.tmbundle](https://github.com/textmate/pascal.tmbundle) diff --git a/vendor/grammars/atom-language-p4 b/vendor/grammars/atom-language-p4 new file mode 160000 index 00000000..9086e387 --- /dev/null +++ b/vendor/grammars/atom-language-p4 @@ -0,0 +1 @@ +Subproject commit 9086e387fc96932666b7a3b1ffe6345e61264fd8 diff --git a/vendor/licenses/grammar/atom-language-p4.txt b/vendor/licenses/grammar/atom-language-p4.txt new file mode 100644 index 00000000..bc0d3bef --- /dev/null +++ b/vendor/licenses/grammar/atom-language-p4.txt @@ -0,0 +1,12 @@ +--- +type: grammar +name: atom-language-p4 +license: mit +--- +Copyright (c) 2016 Yi Tseng + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.