- 呼叫 netpoll_rx() 來支援 Netpoll API。netpoll 在 kernel 裡實作 UDP clients 及 servers,應用在 netdump, remote syslog, netlog/netconsole, kgdb 等,即使 kernel crash 也可以送收封包。
- 如果有 VLAN tag,則做標記,並做 untag 動作,更新 sk_buff 相關欄位。
- 呼叫接收任何 Ether Type 的封包處理函數 (ptype_all 部份,用在 tcpdump 等)
- 呼叫 handle_ing() 作為 ingress queueing
- 如果原本有 VLAN tag,封包的 net_device 換成此 VLAN ,從 2 再開始。
- 呼叫 net_device 的 rx_handler (用於 bridged 的界面),結果可能是
- RX_HANDLER_CONSUMED:已經完成處理,結束。
- RX_HANDLER_ANOTHER:從 2 再開始下一回合。
- RX_HANDLER_EXACT:接下來需符合 sk_buff 指定的 net_device
- RX_HANDLER_PASS:接下來可以符合不指定 net_device
- 呼叫特定 Ether Type 的封包處理函數:例如 VLAN 的 vlan_skb_recv()、ARP 的 arp_rcv()、IPv4 的 ip_rcv()、IPv6 的 ipv6_rcv()、PPPoE 的 pppoe_rcv() 跟 pppoe_disc_rcv() 等。
註:
- 針對 Ether Type 的封包處理函數紀錄在 ptype_all 跟 ptype_ base[],透過 dev_add_pack() 登記 ether type 及處理的函數 (struct packet_type)。相反動作是呼叫 dev_remove_pack() 來移除。
- L2 socket 如果要收的 Ether Type 是 VLAN,應該會收不到
- pfmemalloc 只用在 ARP, IP, VLAN 等 Ether Type,不做 任何 Ether Type 的封包處理
- vlan_skb_recv() 移除 VLAN header 後,透過 netif_rx() 放到 input_pkt_queue,再 poll 取出呼叫 netif_receive_skb()。
參考來源:
- net/core/dev.c 及相關 source code
- http://www.linuxfoundation.org/collaborate/workgroups/networking/kernel_flow#Receive_flow
- http://www.cs.columbia.edu/~nahum/w6998/lectures/device-layer.ppt
- Sending UDP packets from the Linux Kernel
- vlan_skb_recv(), packet_rcv(), /proc/net/dev, /proc/net/dev_mcast
沒有留言:
張貼留言