20210510 Programming Protocol-independent Packet Processors ( P4 ) - 1
Previous20210503 Containernet / Mininet-Wifi ( Miniedit )Next20210517 Programming Protocol-independent Packet Processors ( P4 ) - 2
Last updated
Was this helpful?
Last updated
Was this helpful?
P4 是用於編程與協議無關的包處理器的高級語言,其與SDN控制協議
(如 OpenFlow)結合使用,在當前形式下,OpenFlow 顯式指定其所操作的協議標頭
幾年來,這個集合已經從 12個字段 增加到 41個字段,這增加了規範的複雜性,同時仍然沒有提供添加新標頭的靈活性
我們有三個目標:
現場可重配置性
:程序員應該能夠在交換機部署數據包後改變交換機處理數據包的方式
協議獨立性
:交換機不應綁定到任何特定的網絡協議
目標獨立性
:程序員應該能夠獨立於底層硬件的細節來描述數據包處理功能
cd p4-test/1
gedit p4app.json basic.p4 cmd.txt
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": false,
"enable_log": false,
"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": {
"links": [["h1", "s1"], ["h2", "s1"]],
"hosts": {
"h1": {
},
"h2": {
}
},
"switches": {
"s1": {
"cli_input": "cmd.txt",
"program": "basic.p4"
}
}
}
}
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;
}
}
/*************************************************************************
************ 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 {
key = {
standard_metadata.ingress_port: exact;
}
actions = {
forward;
drop;
}
size = 1024;
default_action = drop();
}
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;
cmd.txt
table_add phy_forward forward 1 => 2
table_add phy_forward forward 2 => 1
cd 1
sed -i '/^$/d' p4app.json
sed -i '/^$/d' basic.p4
sed -i '/^$/d' cmd.txt
p4run
net
h1 ping h2 -c 5
table_clear phy_forward
後
h1 ping h2 -c 5
table_add phy_forward
後
h1 ping h2 -c 5
simple_switch_CLI --thrift-port 9090
table_info phy_forward
table_dump phy_forward
table_clear phy_forward
table_dump phy_forward
table_add phy_forward forward 1 => 2
table_add phy_forward forward 2 => 1
table_dump phy_forward
cd ..
cd 1-1
gedit p4app.json basic.p4
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": {
"assignment_strategy": "l2",
"links": [["h1", "s1"], ["h2", "s2"], ["s1", "s2"]],
"hosts": {
"h1": {
},
"h2": {
}
},
"switches": {
"s1": {
"cli_input":"cmd1.txt",
"program": "basic.p4"
},
"s2": {
"cli_input":"cmd2.txt",
"program": "basic.p4"
}
}
}
}
cd 1-1
p4run
h1 ping h2 -c 5
cd p4-test
cd 2
誤關
gedit basic.p4 cmd.txt p4app.json
p4run
h1 ping h2 -c 5
變更
mac_forward
後
h1 ping h2 -c 5
basic.p4
/* -*- P4_16 -*- */
#include <core.p4>
#include <v1model.p4>
/*************************************************************************
*********************** H E A D E R S ***********************************
*************************************************************************/
header ethernet_t {
bit<48> dstAddr;
bit<48> srcAddr;
bit<16> etherType;
}
struct metadata {
/* empty */
}
struct headers {
ethernet_t ethernet;
}
/*************************************************************************
*********************** 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 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(standard_metadata);
}
action forward(bit<9> port) {
standard_metadata.egress_spec = port;
}
table mac_forward {
key = {
hdr.ethernet.dstAddr: exact;
}
actions = {
forward;
drop;
}
size = 1024;
default_action = drop();
}
apply {
mac_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 {
packet.emit(hdr.ethernet);
}
}
/*************************************************************************
*********************** S W I T C H *******************************
*************************************************************************/
V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;
cmd.txt
table_add mac_forward forward 00:00:0a:00:01:01 => 1
table_add mac_forward forward 00:00:0a:00:01:02 => 2
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": {
"links": [["h1", "s1"], ["h2", "s1"]],
"hosts": {
"h1": {
},
"h2": {
}
},
"switches": {
"s1": {
"cli_input": "cmd.txt",
"program": "basic.p4"
}
}
}
}
simple_switch_CLI --thrift-port 9090
help
table_dump mac_forward
table_clear mac_forward
table_dump mac_forward
ls
rm basic.p4i basic.json topology.db
rm -rf log pcap
ls
p4run
h1 ping h2 -c 5
變更
mac_forward => 1
後
h1 ping h2 -c 5
變更
mac_forward => 2
後
h1 ping h2 -c 5
exit
p4run
查看完log之後
h1 ping h2 -c 5
simple_switch_CLI --thrift-port 9090
table_add mac_forward forward 00:00:0a:00:01:01 => 1
table_add mac_forward forward 00:00:0a:00:01:02 => 2
table_dump mac_forward
p4run 後
cd p4-test
cd 2
cd log
gedit s1.log