内核版本:kernel-2.6.18
网卡驱动通过调用netif_rx函数,把数据送入到协议栈中。
代码中用到一个数据结构 softnet_data ,在网卡收发数据的时候,需要维护一个缓冲区队列,来缓存数据,在协议栈中用一个队列层来表示该缓冲区,队列层位于数据链路层和网络层之间。softnet_data 就是数据链路层中的数据结构,它是一个Per-CPU变量,每个CPU都有一个.
点击(此处)折叠或打开
-
int netif_rx(struct sk_buff *skb)
-
{
-
………………………………
-
local_irq_save(flags);
-
/* 获取当前CPU的 softnet_data 数据 */
-
queue = &__get_cpu_var(softnet_data);
-
__get_cpu_var(netdev_rx_stat).total++;
-
/* netdev_max_backlog 允许送到队列的数据包的最大数目。
-
监测是否还有空间来存储帧,若大于netdev_max_backlog
-
表示空间已满,网络阻塞严重,cpu将丢弃。
-
*/
-
if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
-
/* 空间已有存储的数据帧 */
-
if (queue->input_pkt_queue.qlen) {
-
enqueue:
-
dev_hold(skb->dev);
-
/* 挂softnet_data输入队列 */
-
__skb_queue_tail(&queue->input_pkt_queue, skb);
-
local_irq_restore(flags);
-
return NET_RX_SUCCESS;
-
}
- /* queue->input_pkt_queue.qlen 为0表示队列是空,
- 表明此队列并没有被软中断所处理,
-
因此我们需要将此队列加入到软中断的处理链表中。
-
*/
-
netif_rx_schedule(&queue->backlog_dev);
-
goto enqueue;
-
}
-
__get_cpu_var(netdev_rx_stat).dropped++;
-
local_irq_restore(flags);
-
kfree_skb(skb);
-
return NET_RX_DROP;
- }