Experiment 8: data plane programming practice - P4

1, Experimental purpose

1. Master P4 under V1Model framework_ 16 program structure and basic syntax
2. Be able to use P4 for simple data plane programming

2, Experimental environment

1. Download the virtual machine software Oracle VisualBox or VMware;
2. Install Ubuntu 16.04 Desktop amd64 in the virtual machine, and install the complete Mininet and P4 development environment;
3. Provide P4 image P4-Suite2018.ova, extraction code: egwf

3, Experimental requirements

1. Learn P4 official example tutorial, link: https://github.com/p4lang/tutorials
2. Understand the basic syntax of P4-16 and the P4 code structure based on V1Model, and complete the following exercises:
3. Be familiar with the basic forwarding principle of switch IPV4 using P4, write P4 program, and realize IPV4 tunnel forwarding in the following topology.

Experimental steps:

1. Enter home/P4/tutorials/exercises/basic_tunnel folder, write supplementary basic_ And run the code in tunnel.p4. Improved basic_ The code of tunnel.p4 file is as follows

/* -*- P4_16 -*- */
#include <core.p4>
#include <v1model.p4>

const bit<16> TYPE_MYTUNNEL = 0x1212;
const bit<16> TYPE_IPV4 = 0x800;

/*************************************************************************
*********************** H E A D E R S  ***********************************
*************************************************************************/

typedef bit<9>  egressSpec_t;
typedef bit<48> macAddr_t;
typedef bit<32> ip4Addr_t;

header ethernet_t {
    macAddr_t dstAddr;
    macAddr_t srcAddr;
    bit<16>   etherType;
}

header myTunnel_t {
    bit<16> proto_id;
    bit<16> dst_id;
}

header ipv4_t {
    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;
    ip4Addr_t srcAddr;
    ip4Addr_t dstAddr;
}

struct metadata {
    /* empty */
}

struct headers {
    ethernet_t   ethernet;
    myTunnel_t   myTunnel;
    ipv4_t       ipv4;
}

/*************************************************************************
*********************** P A R S E R  ***********************************
*************************************************************************/

parser MyParser(packet_in packet,
                out headers hdr,
                inout metadata meta,
                inout standard_metadata_t standard_metadata) {

    state start {
        transition parse_ethernet;
    }

    state parse_ethernet {
        packet.extract(hdr.ethernet);
        transition select(hdr.ethernet.etherType) {
            TYPE_MYTUNNEL: parse_myTunnel;
            TYPE_IPV4: parse_ipv4;
            default: accept;
        }
    }

    state parse_myTunnel {
        packet.extract(hdr.myTunnel);
        transition select(hdr.myTunnel.proto_id) {
            TYPE_IPV4: parse_ipv4;
            default: accept;
        }
    }

    state parse_ipv4 {
        packet.extract(hdr.ipv4);
        transition accept;
    }

}

/*************************************************************************
************   C H E C K S U M    V E R I F I C A T I O N   *************
*************************************************************************/

control MyVerifyChecksum(inout headers hdr, inout metadata meta) {   
    apply {  }
}


/*************************************************************************
**************  I N G R E S S   P R O C E S S I N G   *******************
*************************************************************************/

control MyIngress(inout headers hdr,
                  inout metadata meta,
                  inout standard_metadata_t standard_metadata) {
    action drop() {
        mark_to_drop();
    }
    
    action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
        standard_metadata.egress_spec = port;
        hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
        hdr.ethernet.dstAddr = dstAddr;
        hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
    }
    
    table ipv4_lpm {
        key = {
            hdr.ipv4.dstAddr: lpm;
        }
        actions = {
            ipv4_forward;
            drop;
            NoAction;
        }
        size = 1024;
        default_action = drop();
    }
    
    action myTunnel_forward(egressSpec_t port) {
        standard_metadata.egress_spec = port;
    }

    table myTunnel_exact {
        key = {
            hdr.myTunnel.dst_id: exact;
        }
        actions = {
            myTunnel_forward;
            drop;
        }
        size = 1024;
        default_action = drop();
    }

    apply {
        if (hdr.ipv4.isValid() && !hdr.myTunnel.isValid()) {
            // Process only non-tunneled IPv4 packets
            ipv4_lpm.apply();
        }

        if (hdr.myTunnel.isValid()) {
            // process tunneled packets
            myTunnel_exact.apply();
        }
    }
}

/*************************************************************************
****************  E G R E S S   P R O C E S S I N G   *******************
*************************************************************************/

control MyEgress(inout headers hdr,
                 inout metadata meta,
                 inout standard_metadata_t standard_metadata) {
    apply {  }
}

/*************************************************************************
*************   C H E C K S U M    C O M P U T A T I O N   **************
*************************************************************************/

control MyComputeChecksum(inout headers  hdr, inout metadata meta) {
     apply {
    update_checksum(
        hdr.ipv4.isValid(),
            { hdr.ipv4.version,
          hdr.ipv4.ihl,
              hdr.ipv4.diffserv,
              hdr.ipv4.totalLen,
              hdr.ipv4.identification,
              hdr.ipv4.flags,
              hdr.ipv4.fragOffset,
              hdr.ipv4.ttl,
              hdr.ipv4.protocol,
              hdr.ipv4.srcAddr,
              hdr.ipv4.dstAddr },
            hdr.ipv4.hdrChecksum,
            HashAlgorithm.csum16);
    }
}

/*************************************************************************
***********************  D E P A R S E R  *******************************
*************************************************************************/

control MyDeparser(packet_out packet, in headers hdr) {
    apply {
        packet.emit(hdr.ethernet);
        packet.emit(hdr.myTunnel);
        packet.emit(hdr.ipv4);
    }
}

/*************************************************************************
***********************  S W I T C H  *******************************
*************************************************************************/

V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;
  • Run the terminal in this folder and enter the command make run. Finally, the mininet command line is displayed.

  • Perform pingall to test connectivity.

2. Enter xterm command to open h1 and h2 terminals. First enter. / receive.py in the interface of host 2 to start the server to receive messages, and then enter. / send.py 10.0.2.2 "102192107" in the interface of h1

3. Test with tunnel. Enter the xterm command to open both terminals h1 and h3. First enter. / receive.py in the interface of host 3 to start the server to receive messages, and then enter. / send.py 10.0.3.3 "123123" -- DST in the interface of h1_ id 3

4, Personal summary

The last experiment of SDN is the most successful experiment I have done this semester. I'm glad to have such a smooth ending. Although I have encountered some small problems, they are not very serious. The installation package of P4 is very large. Fortunately, I started to download it more than a week in advance, that is, I downloaded it from a useful computer, and then I didn't open Baidu Cloud members. Although it is very slow, I finally downloaded it three days in advance because of abundant time. One problem I encountered after the download was that I was not sure how to open the P4 virtual machine. I first opened VMware and then opened P4. Later, I wanted to right-click the P4 virtual machine to open it. The opening of the virtual machine is very smooth. The content of the experiment is very similar to that of a previous experiment. Therefore, it is very smooth. It is always the case when the tunnel is used for testing

I've tried several times, and finally found that it's in. / send.py 10.0.3.3 "123123" -- DST_ The "and" of id 3 -- and the space between id and 3. Fortunately, I finally tried out the correct input code, otherwise I had to upload the imperfect result.

Posted on Tue, 02 Nov 2021 13:40:58 -0400 by Voodoo Jai