參考: https://csie1.nqu.edu.tw/smallko/sdn/sdn.htm
Parsers : 分析標頭資訊
Controls : 控制data flow的行為(從哪個port出發)
Expressions : 支援+ - *
不支援/
Data Types : Bistrings, headers, structures, arrays
編譯:
p4c --target bmv2 --arch v1model --std p4-16 "basic.p4" -o.
bmv2 (behavioral model version 2)
輸出 basic.json
範例程式1:
12:35 ~ 19:10
19:10 ~ 21:00
簡化框架
22:25 ~ 25:12
在開發專案之前 複製並修改p4app.json的topology部分 (通常只會修改紅色部分)
cmd.txt: s1預先設定的規則
basic.p4: 要執行的p4程式
測試:
25:13 ~ 31:55
p4run
動態 調整 規則
從執行p4run
的終端機(a)中 可以看到thrift-port 9090 (s1 透過9090 port 進行通訊)
(a): h1 ping h2 -c 3 會通
再從另一個終端機(b) 執行 simple_switch_CLI –thrift-port 9090
(b): help
查看cmd
help table_down
查看table_down指令
table_down mac_forward(這個表格名稱是自己取的) 可以看到cmd.txt對應的規則
table_clear mac_forward: 清除表格內容
table_down mac_forward 會發現 規則不見了
(a): h1 ping h2 -c 3 不會通
只要有封包傳送就會記錄到./pcap
30:30 ~ 31:48
log資料夾(debug) 解析
p4app.json 的 cli_input(下圖)若沒設定 會導致ping 失敗
0:00 ~ 5:00
這時 也可以在runtime透過table_add設定規則(下圖)
加入的規則:
priority的設定 05:00 ~ 05:35
log解析 ping(重要) 06:38 ~ 13:55
在runtime時 動態替換P4程式
p4-util 原生不支持 動態替換P4程式
you need to modify the file p4_mininet.py, which is located p4-utils/p4utils/mininetlib. 具體內容請參考上方連結
程式碼講解 5:30 ~ 9:30
實驗 9:30 ~
load_new_config_file mac_forward.json(要替換的p4 file)
swap_configs
可以用table_dump檢查是否生效,會發現 新的table是空的 所以要記得設定規則(table_add)
規則:
範例1 Repeater
程式碼講解 02:00 ~ 07:35
執行範例 07:35 ~ 24:14
mx命令、腳本執行
第3層 轉發
code講解(包含.json中的topology設定) 03:30 ~ 12:57
拓樸中,若需要手動指定IP、default gateway要修改下圖圈選處
執行 12:57 ~ 15:45
L3-routing (web)、 L3-routing1 code、 L3-routing2 code
路由轉發時,有兩種不同的策略:
(1) 用 單一表格 進行轉發 (只根據IP addr)
(2) 用 2個不同表格 進行轉發 (根據 處理方式編號)
two-tables 的優缺點 22:00~25:24
當鏈路出現問題時 two-tables只要修改特定 處理方式 的內容,不需單獨修該所有設定(one-table需要)
實驗(包含程式碼講解、metadata使用32:23) 25:24~34:45
Simple Controller to populate routing tables for any topology (web)、 code
使用controller生成、下放規則
程式碼講解 02:55~06:20
實驗 06:20~08:15
P4-controller撰寫 08:15(code 10:50)(執行 15:20) ~ 31:53
controller 透過 topology.db 取得全局拓樸資訊
topology.db 包含節點(s1 s2)相關資訊 IP設定 連接狀態 delay…
量測switch 或 host 間的 bandwidth utilization
元件 counter(11:00~18:20)
紀錄 每個port累計的封包數、byte數 以及 吞吐量計算
程式碼講解 02:30 ~ 10:30
(3:20~10:30)Q: P4程式完成後 如何在程式執行時再加上規則
Monitor Queue Length (交換機中的queue)
元件 register 04:35~07:25
暫時存放資訊 類似buffer
可以記錄15個port(0~14) 並且每個port的柱列長度為32 bit
注意:
link 是使用TCLink (本身就存在一個 (放在link中) queue)
程式碼講解 03:50~08:40
實驗 08:44~14:40
量測佇列長度、時間(腳本) 11:20~14:40
封包複製
程式碼講解 03:55~10:30
實驗 10:30~12:00
source routing
example1 程式碼講解 12:15~31:10
example2 程式碼講解 31:10~49:00
執行 49:00~56:20
Broadcast
程式碼講解 04:25~11:10
執行 11:10~14:50
ECMP
存在多條等價路徑可供選擇時,隨機選取可以達到負載均衡,提高鏈路使用率
(相同flow(5-tuple)還是走同一路徑)
程式碼講解 04:30~27:35 (包含部分執行12:34)
hash() 23:27~24:55
執行 27:35~31:14
在P4中 實現PacketIn
程式碼講解 04:00~35:42 (執行 09:30~)
在.json需要加上 "cpu_port": true
注意ping是雙向的所以會經過2次 controller
recirculate example
程式碼講解 2:55~7:45
hdr.ipv4.diffserv 就是傳統的tos field
range
1..10
1到10之間
_
default
執行 07:45~
h1 ping -c 3 h2 -Q 11
-Q 可以設定 tos field
分析log 13:15~17:42
Anti TCP SYN Port Scan web
法1: 由P4檢測
原理: 統計SYN、SYN-ACK的個數或比例,正常情況下是1:1或是SYN略多 若SYN超過3個就有可能是SYN port scan
程式碼講解 7:40~23:40
主要邏輯 14:05~22:40
分別設置 標號0~99 容量10bit(0~1023) 的 register(conter)
flowlet_map_index 暫存src_ip的hash (節省儲存空間)
syn_count 暫存某個來源syn pkt數
syn_ack_count 暫存某個來源syn-ack pkt數
執行 23:40~
nv -vnz -w [IP] 80-85
-v: verbose
-n: numeric-only (不解析)
-z: zero-I/O mode (scan用)
nc -vnz 命令的作用是以 verbose(詳細)模式、禁用 DNS 解析、並使用 zero-I/O(零輸入/輸出)模式來測試網絡連接
-w: wait time
80-85 port scan的範圍
結果: syn - syn-ack > 3時 就不forwarding而是直接drop
法2: 由controller檢測
程式碼講解 28:15~41:00
執行 41:00~43:20
Meter
是用於測量和監控網絡流量的工具或機制
two-rate three-color meters 演算法
用處: 差異式服務
定義了2種傳送速度
Committed Information Rate,CIR
Peak Information Rate,PIR
ChatGPT:
CIR < PIR
若流量 < CIR : GREEN (tag)
CIR < 流量 < PIR : YELLOW
流量 > PIR : RED
程式碼講解 3:30~11:50
10 (綠色底線)代表 meter的數量 (可以根據port的數量設定)
執行 11:50~14:00
multipath transmission 多重路徑傳輸
多路徑傳輸可能會失序
程式碼講解 3:15~19:40
P4不支援浮點數
原理: 設置30%的封包走A路徑、70%封包走B路徑
圖中 是 50% 50% 的範例
在P4程式碼中,action區塊不能使用if-else語句,apply區塊才可以用if-else
random(meta.result, (bit<8>)最小值,(bit<8>)最大值);
random(meta.result, (bit<8>)0,(bit<8>)100);
執行 19:40~22:00
結果:
單路徑:約 0.5 Mbps
多路徑:約 1.0 Mbps,但是會出現失序的問題,所以需要在applicatoin layer額外處理
影像視訊串流
multiple queue
P4中 預設有8個queue(0~7),queue7是priority最高的
把影片傳輸的流量放在queue7便能優先維護傳輸品質(避免競爭)
程式碼講解 02:40~03:49
執行 03:49~09:30
設定output queue的深度,只允許50個封包
每秒傳輸速度 100 個封包
接收端
ffplay -i udp://10.0.3.1:1234
傳送端
ffmpeg -stream_loop -1 -re -i 1.mp4 -c copy -f mpegts udp://10.0.3.1:1234
-stream_loop -1 : 原本的影片只有300個畫片,每秒撥30個,只有10秒鐘,這個設定可以讓影片播完後繼續重新撥放
深度封包檢測(Deep Packet Inspection,DPI)
h1-s1-h2 | h3
情境: h1與h2通訊過程中,s1把封包複製(10:30~11:20)一份到h3,h3檢查是否為HTTP協定(不是透過80port判斷,透過解析應用層資料),若是,則block h1與h2之間的通訊
DPI需要使用go語言、go-dpi庫 安裝go-dpi
go語言、go-dpi 安裝 4:30~8:50
程式碼講解 08:50~14:00
執行(跳過DPI程式講解) 14:0016:23、19:0022:40
服務端
在h2中,python -m SimpleHTTPServer 800
客戶端 curl 10.0.2.1:800
在p4app.json中,若設定"cpu_port": true
ifconfig 會看到多出了s1-cpu-eth1
s1-cpu-eth0: 在s1使用
s1-cpu-eth1: 在目前網路中,接收封包(所以go程式會在這個interface監聽)
DPI程式講解(go語言) 16:23~18:50
程式碼講解 05:00~09:50
執行 09:5011:50、22:5529:32(最後面有留一個小問題)
local controller程式碼講解 11:50~22:55
查看連線狀態
load balancer for http service
P4-14 轉 P4-16
p4c-bm2-ss –p4v 14 –pp basic.p4 connection-hash14.p4
其中 basic.p4 是 輸出的P4-16程式碼,connection-hash14.p4是輸入的P4-14程式碼
程式碼講解 5:10~14:45
執行 14:45~17:55
match
exact: 完全比對
lpm(longest prefix match): 遮罩、1多的優先(255.255.255.255)
(少見)ternary: 比較dst_mac時 使用and與自訂的遮罩運算(實例 3:55~8:55) 可以設置priority(0最大)
(少見)range: 比較UDP port number 將特定區間的封包送往特定port(實例 8:55~16:50)
Random Load Balancer
程式碼講解 6:18~31:50
執行 31:50~32:51
register
random
hash
source routing
程式碼講解 5:55~14:55
執行 14:55~18:47
讓不同交換機執行不同P4程式
程式碼講解 4:05~8:12
執行 8:12~9:00
使用SVM對ICMP flow分類
hping3 惡意流量
influxdb 資料庫
logstash 資料收集
sklearn 實作svm
軟體安裝、設置 05:00~12:00
程式碼講解 15:2019:45、27:5030:15
實驗 19:4527:50、30:1535:10
round robin load balancer
web1、web2(考慮了server發生錯誤時的應對機制)
code-lb-rrlb4、code-lb-rrlb4-fd
程式碼講解 03:20~19:00
執行 19:00~21:10
fd程式碼講解 21:10~26:15
fd執行 26:15~29:50
Port Knocking
執行 1:30~5:15
程式碼講解 5:15~18:30
使用curl去敲10號port 執行一次命令可能傳送多次封包
所以 第1次敲10號port時 設定成狀態1
上次port knocking時"也"是10號port 則執行drop()而不重設狀態,避免重複傳送導致機制失效
Weighted Round Robin (WRR)
包含fault detection
程式碼講解 3:45~19:00
執行 19:00~20:40
P4-utils : assignment strategy
l2 全部都屬於同一個區域網路
code
程式碼講解 06:23~09:10
執行 09:10~10:30
l3 每條link都是獨立的網路
code
程式碼講解 10:30~14:25
執行 14:25~15:05
mixed
主機相連:同個區域網路
switch相連:不同區域網路
code
程式碼講解 15:05~17:05
執行 17:05~17:35
manual
類似l3,但IP、gateway可以手動配置
code
程式碼講解 17:35~18:15
執行 18:15~18:45
code
包含用scapy實現的 封包傳送/接收程式
Heavy Hitter Detector
可以當作一種DoS攻擊的防禦機制
用來源IP或應用程式埠號或application session(5-tuple)來作為攻擊單位
用hash來減少儲存空間 搭配counting bloom filter來減緩collision的發生
Bloom Filter 資料結構 05:10~10:40
基本上就是透過多個hash function搭配降低碰撞率
程式碼講解 10:40~20:48
執行 20:48~22:10
實作 High-Speed Data-Plane Packet Aggregation and Disaggregation by P4 Switches
程式碼講解 06:15~25:30
當buffer滿了 又有封包進來時 執行Aggregation(聚合)
Aggregation具體內容
執行 25:30~31:10
Generic Routing Encapsulation (GRE)
在兩個網路之間透過GRE Tunnel來協助溝通
傳統網路 與 P4網路 的整合
P4-utils 只能模擬全部都是P4-switch的情境
web
實驗1、2(全部都是 傳統/P4 設備)
程式碼講解 07:40~29:10
先把原有的部分IP欄位(src、dst…)copy到 inner_ip 再 把外層IP改為GRE Tunnel的
inner_ip:TTL+24
外層IP:TTL=255、Protocol=0x2f
封裝
傳達後要解析封包時,先把inner_ip的欄位複製到外層IP,再把GRE、inner_ip標頭設成Invalid
inner_ip:TTL-24
解封裝
執行 29:10~30:15
實驗3 (傳統+P4, 不使用P4-utils)
程式碼講解 30:40~39:45
執行 39:45~41:10
basic.p4 to basic.json
p4c-bm2-ss --p4v 16 basic.p4 -o basic.json
將P4程式運行在實體機器上
h1 – s1 – h2
s1:
ifconfig ens37 192.168.1.254/24 這種設定有時候會失效(失效時重設就好) 要注意
h1:
h2:
可以互相ping後 把路由功能關閉
s1:
程式碼講解 09:50~11:40
編譯: p4c-bm2-ss --p4v 16 ip_forward.p4 -o ip_forward.json
執行 11:40~19:45
把目前機器變成P4 software switch
simple_switch -i 1@ens37 -i 2@ens38 --thrift-port 9090 --nanolog ipc:///tmp/bm-1-log.ipc --device-id 1 ip_forward.json --log-console
1@ens37: 第1個port
2@ens38: 第2個port
thrift-port 可以自己指定
在docker中跑P4
法1: 01:43~02:23
法2: 02:23~05:51 (dockerhub)
環境設置 05:51~09:30
程式碼講解 09:30~11:25
執行 11:25~16:40
切換回mininet-wifi環境 16:40~17:24