zoukankan      html  css  js  c++  java
  • 【P4语言学习】basic_routing.p4

    headers.p4

    /*
    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 {
            dstAddr : 48;
            srcAddr : 48;
            etherType : 16;
        }
    }
    
    header_type ipv4_t {
        fields {
            version : 4;
            ihl : 4;
            diffserv : 8;
            totalLen : 16;
            identification : 16;
            flags : 3;
            fragOffset : 13;
            ttl : 8;
            protocol : 8;
            hdrChecksum : 16;
            srcAddr : 32;
            dstAddr: 32;
        }
    }
    
    

    parser.p4

    /*
    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.
    */
    
    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;
    }
    

    basic_routing.p4

    /*
    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.
    */
    
    #include "headers.p4"
    #include "parser.p4"
    
    #define PORT_VLAN_TABLE_SIZE                   32768
    #define BD_TABLE_SIZE                          65536
    #define IPV4_LPM_TABLE_SIZE                    16384
    #define IPV4_HOST_TABLE_SIZE                   131072
    #define NEXTHOP_TABLE_SIZE                     32768
    #define REWRITE_MAC_TABLE_SIZE                 32768
    
    #define VRF_BIT_WIDTH                          12
    #define BD_BIT_WIDTH                           16
    #define IFINDEX_BIT_WIDTH                      10
    
    /* METADATA */
    header_type ingress_metadata_t {
        fields {
            vrf : VRF_BIT_WIDTH;                   /* VRF */
            bd : BD_BIT_WIDTH;                     /* ingress BD */
            nexthop_index : 16;                    /* final next hop index */
        }
    }
    
    metadata ingress_metadata_t ingress_metadata;
    
    action on_miss() {
    }
    
    action set_bd(bd) {
        modify_field(ingress_metadata.bd, bd);
    }
    
    table port_mapping {
        reads {
            standard_metadata.ingress_port : exact;
        }
        actions {
            set_bd;
        }
        size : PORT_VLAN_TABLE_SIZE;
    }
    
    action set_vrf(vrf) {
        modify_field(ingress_metadata.vrf, vrf);
    }
    
    table bd {
        reads {
            ingress_metadata.bd : exact;
        }
        actions {
            set_vrf;
        }
        size : BD_TABLE_SIZE;
    }
    
    action fib_hit_nexthop(nexthop_index) {
        modify_field(ingress_metadata.nexthop_index, nexthop_index);
        subtract_from_field(ipv4.ttl, 1);
    }
    
    table ipv4_fib {
        reads {
            ingress_metadata.vrf : exact;
            ipv4.dstAddr : exact;
        }
        actions {
            on_miss;
            fib_hit_nexthop;
        }
        size : IPV4_HOST_TABLE_SIZE;
    }
    
    table ipv4_fib_lpm {
        reads {
            ingress_metadata.vrf : exact;
            ipv4.dstAddr : lpm;
        }
        actions {
            on_miss;
            fib_hit_nexthop;
        }
        size : IPV4_LPM_TABLE_SIZE;
    }
    
    action set_egress_details(egress_spec) {
        modify_field(standard_metadata.egress_spec, egress_spec);
    }
    
    table nexthop {
        reads {
            ingress_metadata.nexthop_index : exact;
        }
        actions {
            on_miss;
            set_egress_details;
        }
        size : NEXTHOP_TABLE_SIZE;
    }
    
    control ingress {
        if (valid(ipv4)) {
            /* derive ingress_metadata.bd */
            apply(port_mapping);
    
            /* derive ingress_metadata.vrf */
            apply(bd);
    
            /* fib lookup, set ingress_metadata.nexthop_index */
            apply(ipv4_fib) {
                on_miss {
                    apply(ipv4_fib_lpm);
                }
            }
    
            /* derive standard_metadata.egress_spec from ingress_metadata.nexthop_index */
            apply(nexthop);
        }
    }
    
    action rewrite_src_dst_mac(smac, dmac) {
        modify_field(ethernet.srcAddr, smac);
        modify_field(ethernet.dstAddr, dmac);
    }
    
    table rewrite_mac {
        reads {
            ingress_metadata.nexthop_index : exact;
        }
        actions {
            on_miss;
            rewrite_src_dst_mac;
        }
        size : REWRITE_MAC_TABLE_SIZE;
    }
    
    control egress {
        /* set smac and dmac from ingress_metadata.nexthop_index */
        apply(rewrite_mac);
    }
    
  • 相关阅读:
    数据结构选讲深入理解红黑树(Red Black Tree)
    [CLRS][CH 15.2] 动态规划之矩阵链乘法
    数据结构选讲树的旋转(Rotation)
    数据结构选讲二叉查找树(Binary Search Tree)
    [SICP][CH 2.2] 层次性数据和闭包性质
    [CLRS][CH 15.3] 动态规划基础
    数据结构选讲234树(234 Tree)
    IEnumerable与IEnumerator
    你日常所做的事情,决定你将永远成为什么样的人
    c#中正则表达中特殊字符的转义!
  • 原文地址:https://www.cnblogs.com/qq952693358/p/5915929.html
Copyright © 2011-2022 走看看