eBPF Talk: 善用 TCP option 來支持網關 ping
這裏的網關 ping 指的是對虛擬網絡網關發包,確認網關的數據面能夠符合預期地轉發網絡包。
在部署、升級網關的時候,需要對網關進行 ping 測試,以確認網關的數據面符合預期地轉發網絡包。目前,發的 ping 包是 tcp SYN 包。
然而,存在一個網關跟業務節點混部的場景,導致網關的數據面不知道該將 SYN 包轉發出去,還是放行到內核協議棧。
近來,研究了一下解決辦法:
-
將 MAGIC 存放在 SYN 包的 payload 中;
-
將 MAGIC 存放在 TCP option 中;
網關判斷 magic number 是不是網關 ping 包:
-
如果是 MAGIC,則將 MAGIC 減一,然後轉發出去;
-
如果是 MAGIC-1,則放行到內核協議棧。
經過 POC 驗證,方法 1 不可行;因爲取決於內核協議棧的行爲,可能直接丟包,也有可能回包。
經過 POC 驗證,方法 2 可行。
選擇 TCP option
因爲需要存放 MAGIC,所以需要選擇能支持值爲 4 個字節長度的 option。
快速瞭解了一下 TCP options,看到 TCP timestamps option[1] 符合需求,就它了。
使用 gopacket[2] 發包時,將 MAGIC 寫入該 TCP option 即可:
const MAGIC = 0xdeadbeef
optData := make([]byte, 8)
binary.BigEndian.PutUint32(optData[:4], MAGIC)
tcpLayer := layers.TCP{
// ...
Options: []layers.TCPOption{
{OptionType: layers.TCPOptionKindTimestamps, OptionLength: 10, OptionData: optData},
},
}
網關對該 TCP option 的支持
因爲是 tcp SYN 包,所以在判斷協議、SYN 等之後,就需要做如下處理:
#define MAGIC 0xdeadbeef
#define MAGIC_PASS 0xddadbeef
struct tcp_option_timestamps {
u8 type;
u8 len;
u32 magic;
u32 pad;
} __packed;
static __always_inline bool
pass_to_kernel(struct iphdr *iph) {
// ...
struct tcphdr *tcph = (typeof(tcph)) ((void *) iph + (iph->ihl << 2));
// ...
struct tcp_option_timestamps *topt = (typeof(topt)) (tcph + 1);
if (topt->magic == MAGIC_PASS)
return true;
if (topt->magic != MAGIC)
return false;
// Update tcp checksum.
u32 check = (u32) tcph->check;
check += (u32) bpf_htons(0x0100);
tcp->check = (u16) (check + (check>=0xFFFF));
topt->magic--;
return false;
}
-
MAGIC_PASS 是 MAGIC 以大端存放在 option 裏而後在小端服務器上減一的結果。
-
判斷 magic 是 MAGIC_PASS,則放行到內核協議棧。
-
判斷 magic 不是 MAGIC,則跳過對 magic 的處理。
-
參考 IP 頭部 TTL 減一時的校驗和更新方法,更新 TCP 頭部的校驗和。
-
magic 減一。
如此,網關便可判斷出一個 ping 包該放行到內核協議棧還是該轉發走了。
小結
通過將 MAGIC 保存到 TCP timestamps option 的方式,巧妙地讓網關正確地判斷出 ping 包、並正確地處理 ping 包。
以此,更好地支持網關跟業務節點混部的場景。畢竟,得降本增效嘛。
參考資料
[1]
TCP timestamps option: https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_timestamps
[2]
gopacket: https://pkg.go.dev/github.com/google/gopacket@v1.1.19/layers#TCP
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/BKo2lAOoh_6BAsKoC5SjdA