- 定義:include/linux/skbuff.h
- 取得:alloc_skb() 或 dev_alloc_skb()
- 釋出:kfree_skb() 或 dev_kfree_skb()
- struct sk_buff *next, *prev
- head、data、tail、end:head 和 end 分別指到整個資料區塊的開頭和結束,其中有一段是封包的部份,用 data 和 tail 分別指到封包的開頭和結束。skb_pull(len) 將開頭後移 len。
- len
- transport_header (h)、network_header (nh)、mac_header (mac):三個 union 經過這些層時分別指到不同協定層的信頭,分別用 skb_transport_header(skb)、skb_network_header(skb) 及 skb_mac_header(skb) 取得這些指標。
- pkt_type 封包類型:PACKET_BROADCAST、PACKET_MULTICAST、PACKET_OTHERHOST、PACKET_LOOPBCK (針對位址決定?什麼位址?)
- prev、next、list
- sk
- ktime_t tstamp:收到封包的時間。net_enable_timestamp() must be called in order to get values
- struct net_device *dev, *rx_dev
- struct dst_entry *dst:系統決定的路由,有兩個重要的函數指標:
- int (*input)(struct sk_buff*):可指定為 ip_local_deliver, ip_forward, ip_mr_input, ip_error 或 dst_discard_in
- int (*output)(struct sk_buff*):可指定為 ip_output, ip_mc_output, ip_rt_bug, 或 dst_discard_out.
- data_len
- mac_len
- __be16 protocol:1536 以上的 EtherType、或 ETH_P_802_3、ETH_P_802_2 等其它 ETH_P_xxx 協定。
- 檢查 sk_buff 是毋是共有,就是看伊 reference count (users) 不是 1。
- kfree_skb() 會將 reference count 減 1,在 reference count 是 0 時才會真正釋出。
- 通常一個封包使用者用 skb_shared() 檢查是否 shared,如果是的話用 skb_clone() 複製一份,並用 kfree_skb() 將原本的 reference count 減 1。這些動作可用 skb_share_check() 完成。
- 什麼情況需要 skb_shared() 檢查?
- skb_clone() 是複製資料結構,封包資料仍是共用的。如果封包資料也要複製一份,則用 skb_copy();如果只是部份封包資料要複製一份,則用 pskb_copy()。
- 大部分 reference count 是 1,什麼時候會大於 1 呢?
參考來源
- Linux Kernel Networking by Rami Rosen at Haifux, August 2007
- Linux Kernel Source Codes