P4 advantages:
Program protocol (P4 programs specify how a switch processes packets.)Target independent (P4 is suitable for describing everything from high- performance forwarding ASICs to software switches.)Field Reconfigurable (P4 allows network engineers to change the way their switches process packets after they are deployed.)Environment on ubuntu 18.04 (password:ubuntu)
sudo apt-get install git curl wget gedit -ygit clone https://github.com/mininet/mininet.gitcd mininetutil/install.sh -a //install all the packets
you need to try to install :
https://github.com/p4lang/behavioral-model (behavioral-model is a software platform to run the p4)https://github.com/p4lang/p4c (Compile the p4 program)https://github.com/nsg-ethz/p4-utilssome example and tutorials:
https://github.com/nsg-ethz/p4-learning
Review the basic topology of mininet:
h1----h2
#!/usr/bin/pythonfrom mininet.net import Mininetfrom mininet.node import Hostfrom mininet.cli import CLIfrom mininet.link import TCLink, Intffrom mininet.log import setLogLevel, infofrom subprocess import calldef myNetwork(): net = Mininet() //Step3. h2 = net.addHost('h2') //Step4. h1 = net.addHost('h1') //Step5. info( '*** Add links\n') net.addLink(h1, h2) //Step6. info( '*** Starting network\n') net.build() //Step7. CLI(net) //Step8. CLI means command line interface. net.stop()if __name__ == '__main__': // Step1.Start from here!!! setLogLevel( 'info' ) myNetwork() // Step2.
Let's write the first p4 program
H1----H2 let h1 can ping h2
Parser-->Ingress-->Egress-->Deparser
you need three files: basic.p4 cmd.txt p4app.json
1.basic.p4
/* -*- P4_16 -*- */#include <core.p4>#include <v1model.p4>/************************************************************************************************ H E A D E R S ************************************************************************************************************/ struct metadata { /* empty */} struct headers {} /************************************************************************************************ 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 accept; //---->Analysis of the end }} /************************************************************************************* 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(standard_metadata); } action forward(bit<9> port) { standard_metadata.egress_spec = port; } table phy_forward { //phy_forward is table name key = { standard_metadata.ingress_port: exact; //The system itself has a variable that stores which packets come in from which packets. } actions = { forward; drop; } size = 1024; //1024 means this table can store 1024 rules default_action = drop(); //If the packet does not find a matching rule, throw it away apply { phy_forward.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 { }}/************************************************************************************************ D E P A R S E R ********************************************************************************************************/control MyDeparser(packet_out packet, in headers hdr) { apply { }}/************************************************************************************************ S W I T C H ********************************************************************************************************/V1Switch(MyParser(),MyVerifyChecksum(),MyIngress(),MyEgress(),MyComputeChecksum(),MyDeparser()) main;
2.cmd.txt
table_add phy_forward forward 1 => 2table_add phy_forward forward 2 => 1
3.p4app.json
{ "program": "basic.p4", "switch": "simple_switch", "compiler": "p4c", "options": "--target bmv2 --arch v1model --std p4-16", "switch_cli": "simple_switch_CLI", "cli": true, "pcap_dump": true, "enable_log": true, "topo_module": { "file_path": "", "module_name": "p4utils.mininetlib.apptopo", "object_name": "AppTopoStrategies" }, "controller_module": null, "topodb_module": { "file_path": "", "module_name": "p4utils.utils.topology", "object_name": "Topology" }, "mininet_module": { "file_path": "", "module_name": "p4utils.mininetlib.p4net", "object_name": "P4Mininet" }, "topology": { //You can start here!!! "links": [["h1", "s1"], ["h2", "s1"]], "hosts": { "h1": { }, "h2": { } }, "switches": { "s1": { "cli_input": "cmd.txt", "program": "basic.p4" } } }}
you can use p4run
to run the program, also you can use this command simple_switch_CLI --thrift-port 9090
to dynamically change packet forwarding rules.