您的位置:首页 > 理论基础 > 计算机网络

TCP/IP协议栈之四---------链路层

2016-10-22 16:03 232 查看

4.1接收帧

由硬件驱动在中断处理程序中直接调用netif_rx

netif_rx(skb)★ (dev.c/core)----将接收到的消息挂在每CPU的输入队列中

if(netpoll_rx函数与把数据拿走)

return

__skb_queue_tail(把所有收到的数据保存起来)

netif_rx_schedule

__raise_softirq_irqoff(NET_RX_SOFTIRQ);

重要:在netif_rx的上层函数中利用dev_alloc_skb创建skb结构,并设置skb->dev。在netif_rx中把skb加入每CPU的输入队列。然后在process_backlog 函数中,从每CPU输入队列中取出skb(从队列中循环读取skb,直到读完),调用netif_receive_skb对每一个skb进行处理。

在net_dev_init函数中初始化了软中断:
(dev.c/core)

open_softirq(NET_TX_SOFTIRQ, net_tx_action,NULL);

open_softirq(NET_RX_SOFTIRQ, net_rx_action,NULL);

所以NET_RX_SOFTIRQ中断的处理函数是net_rx_action,NET_TX_SOFTIRQ中断的处理函数是net_tx_action。需要让上层接收数据时,只要触发相应的软中断,如__raise_softirq_irqoff(NET_RX_SOFTIRQ)。内核就会在适当时机执行do_softirq来处理pending的软中断。

net_rx_action★
(dev.c/core)

n->poll = process_backlog ((structnet_device *)

netif_receive_skb (skb)

pt_prev->func(skb,skb->dev)=
ip_rcv★(在这里完成了交接)

__raise_softirq_irqoff(NET_RX_SOFTIRQ)



4.2发送帧

dev_queue_xmit(sk_buff *skb..)★
(dev.c/core, P182)

------分支细节见书籍P101

dev->hard_start_xmit=
el_start_xmit
(struct sk_buff*, struct net_device *)★ –

调用outw汇编指令发送数据,够底层了

重要:这里的net_device是从skb->dev得到的,而skb->dev是在函数ip_finish_output中得到的,有skb->dev
=skb->dst->dev; 而skb->dst是路由选择后被赋值的


rcu_read_unlock_bh

lookback的发送函数见下面(P183):



net_tx_action(struct softirq_action *)★
(dev.c/core)

__kfree_skb(释放已发送的,此时中断由dev_kfree_skb_irq函数发起)

qdisc_run(struct net_device *)---发送包函数

---
qdisc_restart

-----
dev->hard_start_xmit(skb, dev)(在网卡上实际的发送包)

netif_schedule(struct net_device *★ (netdevice.h)

__netif_schedule (调度设备发包,netdevice.h)

raise_softirq_irqoff(NET_TX_SOFTIRQ)

net_tx­_action
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息