# Mininet p4 1
[TOC]
## Openflow
Openflow 是一種protocol -> Controller switch 互動協議
Controller ---> 透過 openflows protocol 來下放flow 到 switch 上
switch 就會透過這些flows 來 forward, modify or drop packets
示意圖
>
Control Function
North Bound
SDN controller
Sound Bound
switch
Control Function -> control plane (能去Control 整個Network)
switch -> data plane (forward Data stream)
openflow 相比 p4 還算太簡單了
---
## Top-down Design
由上往下

## Programming Protocol Independent Packet Processor
p4 主要是讓 Data plane 可以用 program 去處理 packet Action
---
## p4 Component

### Parsers -> Analysis packet header info
e.g Ether Type
= 0800(ARP)
= 0806(ICMP)
### Controls
table
Actions
control flow statements
## Architectures and Target

Target -> switch
V1 mode -> simple switch
---
Framework(框架)
https://github.com/nsg-ethz/p4-Utils
---
### Programming p4 Target

Source Image

p4 Program Structure
#### include
```
#include <core.p4>
#include <v1model.p4>
```
#### Header
```
header ethernet_t {
bit<48> dstAddr;
bit<48> srcAddr;
bit<16> etherType;
}
struct metadata {
/* empty */
}
struct headers {
ethernet_t ethernet;
}
```
Define: Ethernet Header
dst 8 byte
src 8 byte
ethertype 4 bite
e.g. 0800 ARP 0806 ICMP
#### Parser packet header
```
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;
}
}
```
packet.extract(hdr.ethernet);
把 header value 取出
#### checksum
```
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
apply { }
}
```
#### Ingress processing
Packets 進入switch 入口
類似 firewall input
```
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();
}
}
```
Packets Forwarding
```
action forward(bit<9> port) {
standard_metadata.egress_spec = port;
}
```
Rule Match
```
table mac_forward {
key = {
hdr.ethernet.dstAddr: exact;
}
```
action -> 封包行為
```
actions = {
forward;
drop;
}
size = 1024;
default_action = drop();
```
size -> flows 的數量
沒在 flow 規則下 (default drop 掉)(policy)
#### Engress processing
```
control MyEgress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
apply { }
}
```
#### Checksum Computation
```
control MyComputeChecksum(inout headers hdr, inout metadata meta) {
apply {
}
}
```
當封包進入 switch TTL 會 -1
就要重計 Checksum
#### Deparser
把剛 parser 部分組回來
```
control MyDeparser(packet_out packet, in headers hdr) {
apply {
packet.emit(hdr.ethernet);
}
}
```
#### Switch
```
V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;
```
v1Switch 使用 V1model
Ingress -> 流程控制 (去看 table 裡的flows -> 執行相對應的Action)
### JSON file -> 把 p4 寫進switch 裡面
```
{
"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"
}
}
}
}
```

## Reference
https://docs.google.com/presentation/d/1zliBqsS8IOD4nQUboRRmF_19poeLLDLadD5zLzrTkVc/edit#slide=id.g37fca2850e_6_2115