TCP/IP协议栈之四---------链路层
2016-10-22 16:03
232 查看
4.1接收帧
由硬件驱动在中断处理程序中直接调用netif_rxnetif_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
相关文章推荐
- TCP/IP协议栈 -----链路层
- tcp/ip协议栈之数据链路协议slip,ppp,802.3
- PPP链路工作过程
- lwIP――TCP/IP协议栈的一种实现(3)
- TCP/IP详解(二)链路层
- 网络冗余链路管理的实现
- 配置点到点链路OSPF及认证
- 三地跨区域链路 汇聚统一监控平台——国际化综合性顾问咨询公司阿特金斯
- 学习数据链路层和传输层时的超级困惑!谁能解惑?
- 物理链路备份的重要性
- OSPF链路状态通告
- 【转】几种开放源码的TCP/IP协议栈比较
- OSPF虚拟链路的简单应用
- TCP/IP协议栈与数据包封装
- 企业网络高级技术 第6章 PPP 协议 PAP CHAP双向认证 多链路
- 通过隧道与虚链路解决区域分割 推荐
- 几种开源的TCP/IP协议栈分析
- 详解VLAN链路数据包的转发过程