Experiment 8: data plane programming practice - P4
1, Experimental purpose
- Master P4 under V1Model framework_ 16 program structure and basic syntax
- Be able to use P4 for simple data plane programming
2, Experimental environment
- Download the virtual machine software Oracle VisualBox or VMware;
- Install Ubuntu 16.04 Desktop amd64 in the virtual machine, and install the complete Mininet and P4 development environment;
- Provide P4 image P4-Suite2018.ova , extraction code: egwf
3, Experimental requirements
Learn the P4 official sample tutorial, link: https://github.com/p4lang/tutorials , understand the basic syntax of P4-16 version and the P4 code structure based on V1Model, and complete the following exercises:
(1) Basic requirements
Be familiar with the basic forwarding principle of switch IPV4 using P4, write P4 program, and realize IPV4 tunnel forwarding in the following topology.
- Write supplementary basic_ And run the code in tunnel.p4
/* -*- 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 input command make run
- Execute pingall to check its connectivity
- XTERM opens h1 and h2 terminals
1. Tunnel not used:
-
In h2, enter:. / receive.py
-
In h1, enter:. / send.py 10.0.2.2 "sdn" to send a message to host h2:! [image-20211102213351886]
-
h2 receive:
The packet is normally delivered according to the destination ipv4 address
2. Test with tunnel
- In h1, enter:. / send.py 10.0.2.2 "goodbye h2" --dst_id 2![image-20211102214745274]
4, Experimental experience
The main content of this experiment is to master P4 under the V1Model framework_ 16 program structure and basic syntax can use P4 for simple data plane programming.
Experimental difficulty: high
Problems and solutions:
1. You need to learn the relevant knowledge of P4 language. The content of the document is relatively long, difficult to understand, and the learning time is very long.
2. Clone the warehouse on the official github and run it locally, but during the running process, it is found that the compilation fails. It's because of the version. The solution is mark_ to_ The parameters in drop (stdmeta) are removed.
Conclusion: the overall content of this experiment is difficult to understand and learn. By learning the basic forwarding principle of P4 switch IPv4, you can use P4 for simple data plane programming. After several experiments, I mastered the use of mininet, enhanced my understanding of linux system and mastered the use of command line.