zoukankan      html  css  js  c++  java
  • 【p4tutorials】P4 v1.1 Simple Router

    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 {
         32;
        static: drop_expired;
        instance_count: 16;
    }
    
    register drops_register_enabled {
         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);
    }
    
    
  • 相关阅读:
    0317复利计算的回顾与总结
    0518 Scrum 项目 5.0
    0517 Scrum 项目4.0
    0512 Scrum 项目3.0
    实验三 进程调度模拟程序
    0505 Scrum 项目1.0
    0502团队项目 SCRUM团队成立
    0428 团队项目2.0
    0422团队项目
    实验二 作业调度模拟程序
  • 原文地址:https://www.cnblogs.com/qq952693358/p/5912834.html
Copyright © 2011-2022 走看看