此筆記出自於The Linux Networking Architecture: Design and Implementation of Network Protocols in the Linux Kernel
首先linux的網路架構(Stack)大概如下,細節部分之後再補上(Linux&FreeBSD接承襲自BSD 4.2,但之後的BSD從4.4後便開始與linux有較大差異):
Userspace function call(From C library)
--------------------Socket layer---------------------------
BSD socket API(Userlevel)
Socket system call(syscall)
-------------------Kernel space----------------------------
Syscall implementation
---------------Kernel TCP/IP layer-------------------
在kernel的Network Packet是使用"sk_buff"這個資料結構來做管理的(放在socket buffer queue裡的也是這個),其結構如下:
"sk_buff_head"其實就是目前"sk_buff"所在的socket buffer queue head。
"list"會指向所屬queue的head,因此除非不屬於任何queue的socket buffer(例如使用"skb_deque()"?),不然list都會指向"sk_buff_head"
2024/01/05:
"next"、"prev"指向buffer queue的前後element
"sk"(圖上沒有)指向對應的socket(通常是創造這個packet的socket)
"datarefp"表示有多少skb指向(reference)這個packet,但這個不屬於"skb_buff"的元素
head跟data之間的空間稱為"headroom",tail跟end之間的空間稱為"tailroom"。
socket buffer(skb)在記憶體分配時就會拿到足夠的大小,因此在每個layer加上header時不需再做copy payload的動作(實際上skb正常只會在user space to kernel space與丟給NIC時會做copy)
skb在記憶體的配置上的機制,個人覺得很像是kernel memory management的slab layer(都是CPU independent,但好像沒有partial、full、empty的分別)。在free的時候都不會真的release而是送到一個cache,之後需要時直接從那裏拿出來。