IP报文的发送的入口函数是ip_output,这个函数一般是挂载到dst->output上。 在发送IP报文时,都需要进行路由查找,得到dst,然后通过dst->output来发送数据包。对于IPv4来说,一般情况下,dst->output都是指向ip_output。

1. intip_output(struct sk_buff*skb)
2. {
3. /* 得到出口的dev */
4. struct net_device*dev=skb_dst(skb)->dev;
/* 增加统计信息 */
 
    
1. IP_UPD_PO_STATS(dev_net(dev),IPSTATS_MIB_OUT,skb->len);
 
    
1. skb->dev=dev;
2. skb->protocol=htons(ETH_P_IP);
 
    
/* 进入netfilter的POSTROUTING链 */
 
    
1. return NF_HOOK_COND(NFPROTO_IPV4,NF_INET_POST_ROUTING,skb,NULL,dev,
2. ip_finish_output,
3. !(IPCB(skb)->flags&IPSKB_REROUTED));
4. }
 
   
进入ip_finish_output
 
   
1. staticintip_finish_output(struct sk_buff*skb)
2. {
3. #ifdefined(CONFIG_NETFILTER)&&defined(CONFIG_XFRM)
4. /*Policy lookup after SNAT yielded a new policy*/
5. if(skb_dst(skb)->xfrm!=NULL){
6. IPCB(skb)->flags|=IPSKB_REROUTED;
7. return dst_output(skb);
8. }
9. #endif
10. /* 处理需要IP分片的情况 */
11. if(skb->len>ip_skb_dst_mtu(skb)&&!skb_is_gso(skb))
12. return ip_fragment(skb,ip_finish_output2);
13. /* 不需要IP分片, 我们就看这种一般情况 */
14. else
15. return ip_finish_output2(skb);
16. }
 
   
进入ip_finish_output2
 
   
1. static inlineintip_finish_output2(struct sk_buff*skb)
2. {
3. struct dst_entry*dst=skb_dst(skb);
4. struct rtable*rt=(struct rtable*)dst;
5. struct net_device*dev=dst->dev;
6. unsignedinthh_len=LL_RESERVED_SPACE(dev);
 
    
/* 根据路由的类型,增加统计信息 */
 
    
1. if(rt->rt_type==RTN_MULTICAST){
2. IP_UPD_PO_STATS(dev_net(dev),IPSTATS_MIB_OUTMCAST,skb->len);
3. }elseif(rt->rt_type==RTN_BROADCAST)
4. IP_UPD_PO_STATS(dev_net(dev),IPSTATS_MIB_OUTBCAST,skb->len);
5. 
6. /*Be paranoid,rather than too clever.*/
7. if(unlikely(skb_headroom(skb)<hh_len&&dev->header_ops)){
8. /* 
9. skb的首部空间不足,无法保存l2层的硬件地址。
10. 这时,需要重新分配一个更大bufer。
11. */
12. struct sk_buff*skb2;
13. 
14. skb2=skb_realloc_headroom(skb,LL_RESERVED_SPACE(dev));
15. if(skb2==NULL){
16. kfree_skb(skb);
17. return-ENOMEM;
18. }
19. if(skb->sk)
20. skb_set_owner_w(skb2,skb->sk);
21. kfree_skb(skb);
22. skb=skb2;
23. }
 
    
/* dst有L2层硬件地址的cache*/
 
    
1. if(dst->hh)
2. return neigh_hh_output(dst->hh,skb);
3. /* 
4. dst没有L2层地址的cache,需要调用neighbour子系统的output进行发送。
5. */
6. elseif(dst->neighbour)
7. return dst->neighbour->output(skb);

 
    
/* 
 
    
正常情况下,不会到达此处
 
    
*/
 
    
1. if(net_ratelimit())
2. printk(KERN_DEBUG"ip_finish_output2: No header cache and no neighbour!\n");
3. kfree_skb(skb);
4. return-EINVAL;
5. }
 
   
在IPv4中,neighbour subsystem使用的是arp,所以一般情况下,dst->neighbour->outpu指向的是arp_generic_ops->neigh_resolve_output(这是需要解析L2硬件地址的情况,其他情况本文暂不考虑)。
 
   

 
   
通常,neighbour subsystem使用的operation都是arp_generic_ops(在arp.c中定义,且还有其他的同类型变量,用于不同情况)。
 
   

 
   
下面看neigh_resolve_output
 
   
 
    
1. int neigh_resolve_output(struct sk_buff *skb)
2. {
3. struct dst_entry *dst = skb_dst(skb);
4. struct neighbour *neigh;
5. int rc = 0;
6. 
7. if(!dst ||!(neigh = dst->neighbour))
8. goto discard;
9. __skb_pull(skb, skb_network_offset(skb));
 
     
/* 判断是否发送neigh请求,对于IPv4来说就是arp request */
 
     
1. if(!neigh_event_send(neigh, skb)){
2. /* 无需发送neigh请求, 可以直接从dev中获得 */
3. interr;
4. struct net_device *dev = neigh->dev;
/* 从dev中获得L2硬件地址*/
 
     
1. if(dev->header_ops->cache &&!dst->hh){
2. write_lock_bh(&neigh->lock);
3. if(!dst->hh)
4. neigh_hh_init(neigh, dst, dst->ops->protocol);
5. err= dev_hard_header(skb, dev, ntohs(skb->protocol),
6. neigh->ha,NULL, skb->len);
7. write_unlock_bh(&neigh->lock);
8. }else{
9. read_lock_bh(&neigh->lock);
10. err= dev_hard_header(skb, dev, ntohs(skb->protocol),
11. neigh->ha,NULL, skb->len);
12. read_unlock_bh(&neigh->lock);
13. }
14. if(err>= 0)
15. rc = neigh->ops->queue_xmit(skb); //发送数据包
16. else
17. goto out_kfree_skb;
18. }
19. out:
20. return rc;
21. discard:
22. NEIGH_PRINTK1("neigh_resolve_output: dst=%p neigh=%p\n",
23. dst, dst ? dst->neighbour :NULL);
24. out_kfree_skb:
25. rc =-EINVAL;
26. kfree_skb(skb);
27. goto out;
28. }
 
   
在neigh_event_send中,实际上并不立刻执行发送neigh 请求,而是将这个数据包加到一个队列中__skb_queue_tail(&neigh->arp_queue, skb);,即语句中的arp_queue。
 
   
然后通过neighbour subsystem的定时处理函数neigh_timer_handler来处理这个队列。
 
   

 
   
neigh_timer_handler主要是neighbour状态的处理和变迁,本文并将其列为重点,留作以后分析学习。对于IPv4来说,当没有对应的neighbour信息时,会先调用arp_solicit发送ARP请求,当收到ARP包时,由arp_process进行处理(可参见我前面的博文 
    TCP/IP学习(33)——ARP数据包的处理流程分析,  
    http://blog.chinaunix.net/space.php?uid=23629988&do=blog&id=335262 
    )。当收到ARP reply时,会调用neigh_update,当neighbour的状态为valid且neighbour的arp_queue不为空时,会调用n1->output将之前的skb数据包发送。
 
   

 
   
 
    
1. while(neigh->nud_state & NUD_VALID &&
2. (skb = __skb_dequeue(&neigh->arp_queue))!=NULL){
3. struct neighbour *n1 = neigh;
4. write_unlock_bh(&neigh->lock);
5. /*On shaper/eql skb->dst->neighbour != neigh :(*/
6. if(skb_dst(skb)&& skb_dst(skb)->neighbour)
7. n1 = skb_dst(skb)->neighbour;
8. n1->output(skb);
9. write_lock_bh(&neigh->lock);
10. }
 
   
当解析neighbour信息成功时,这个n1->output是指向neigh_connected_output,并最终调用dev_queue_xmit->__dev_xmit_skb将数据包添加到dev的queue中,并发送数据包。
 
   

 
   
当发送完毕时,引发NET_TX_SOFTIRQ软中断,进行下半部处理,如释放已发送的数据包skb的内存等。
 
   

 
    
   
本文还遗留了不少细节有待完善,如neighbour subsystem和发送软中断等。
 
    
  

 
  
 
 
  
上次学习IP包的发送流程时,学习到了dev_queue_xmit这个函数。
 
  
1. intdev_queue_xmit(struct sk_buff*skb)
2. {
3. struct net_device*dev=skb->dev;
4. struct netdev_queue*txq;
5. struct Qdisc*q;
6. intrc=-ENOMEM;
7. 
8. /*Disable soft irqsforvarious locks below.Also
9. *stops preemptionforRCU.
10. */
11. rcu_read_lock_bh();
/* 得到发送队列 */
 
    
1. txq=dev_pick_tx(dev,skb);
2. q=rcu_dereference_bh(txq->qdisc);
3. 
4. #ifdef CONFIG_NET_CLS_ACT
5. skb->tc_verd=SET_TC_AT(skb->tc_verd,AT_EGRESS);
6. #endif
7. if(q->enqueue){
8. /* 一般的dev都应该进入这里 */
9. rc=__dev_xmit_skb(skb,q,dev,txq);
10. goto out;
11. }

 
    
...... ......
 
    
1. }
 
   进入函数__dev_xmit_skb 
  
 
   
1. static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
2. struct net_device *dev,
3. struct netdev_queue *txq)
4. {
5. spinlock_t *root_lock = qdisc_lock(q);
6. bool contended = qdisc_is_running(q);
7. int rc;
8. 
9. /*
10. * Heuristic to force contended enqueues to serialize on a
11. * separate lock before trying toget qdisc main lock.
12. * This permits __QDISC_STATE_RUNNING owner toget the lock more often
13. *and dequeue packets faster.
14. */
15. if(unlikely(contended))
16. spin_lock(&q->busylock);
17. 
18. spin_lock(root_lock);
19. if(unlikely(test_bit(__QDISC_STATE_DEACTIVATED,&q->state))){
20. /* 该quque的状态为非活动的,drop该数据包 */
21. kfree_skb(skb);
22. rc = NET_XMIT_DROP;
23. }elseif((q->flags & TCQ_F_CAN_BYPASS)&&!qdisc_qlen(q)&&
24. qdisc_run_begin(q)){
/* 
 
    
这部分代码,从注释上看,似乎选中的queue是一个保留的工作queue。
 
    
想来也是非正常路径,暂时保留不看。
 
    
*/
 
    
1. /*
2. * This is a work-conserving queue; there are no old skbs
3. * waiting to be sent out;and the qdisc isnot running -
4. * xmit the skb directly.
5. */
6. if(!(dev->priv_flags & IFF_XMIT_DST_RELEASE))
7. skb_dst_force(skb);
8. __qdisc_update_bstats(q, skb->len);
9. if(sch_direct_xmit(skb, q, dev, txq, root_lock)){
10. if(unlikely(contended)){
11. spin_unlock(&q->busylock);
12. contended =false;
13. }
14. __qdisc_run(q);
15. }else
16. qdisc_run_end(q);
17. 
18. rc = NET_XMIT_SUCCESS;
19. }else{
/* 正常路径 */
 
    

 
    
/* 确保dst被引用,防止被其他模块释放 */
 
    
1. skb_dst_force(skb);
2. /* 将数据包加入到queue中 */
3. rc = qdisc_enqueue_root(skb, q);
/* 如果queue不是运行状态,将其置为运行状态 */
 
    
1. if(qdisc_run_begin(q)){
2. if(unlikely(contended)){
3. spin_unlock(&q->busylock);
4. contended =false;
5. }
6. __qdisc_run(q);
7. }
8. }
9. spin_unlock(root_lock);
10. if(unlikely(contended))
11. spin_unlock(&q->busylock);
12. return rc;
13. }
 
  
将数据包加入队列的函数是通过q->enque的回调实现的,那么这个enque的回调钩子函数是何时注册上的呢?
请看dev_activate,用于激活网卡。
 
   1. void dev_activate(struct net_device *dev)
2. {
3. int need_watchdog;
4. 
5. /* No queueing discipline is attached to device;
6. create default one i.e. pfifo_fast for devices,
7. which need queueing and noqueue_qdisc for
8. virtual interfaces
9. */
/*
当没有指定queueing discipline时,就使用默认的discipline
*/ 
    
1. if(dev->qdisc ==&noop_qdisc)
2. attach_default_qdiscs(dev);
3. 
4. ...... ...... 
5. }
 
   这里不列出attach_default_qdiscs的代码了,一般情况下,网卡只有一个queue时,这个默认的discipline为 
   
1. struct Qdisc_ops pfifo_fast_ops __read_mostly ={
2. .id ="pfifo_fast",
3. .priv_size = sizeof(struct pfifo_fast_priv),
4. .enqueue = pfifo_fast_enqueue,
5. .dequeue = pfifo_fast_dequeue,
6. .peek = pfifo_fast_peek,
7. .init = pfifo_fast_init,
8. .reset = pfifo_fast_reset,
9. .dump = pfifo_fast_dump,
10. .owner = THIS_MODULE,
11. };
 
   那么对于我们来说,就确定了默认的要是一般情况下的enque函数为pfifo_fast_enqueue。 
   
1. static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
2. {
3. if(skb_queue_len(&qdisc->q)< qdisc_dev(qdisc)->tx_queue_len){
4. int band = prio2band[skb->priority & TC_PRIO_MAX];
5. struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
6. struct sk_buff_head *list = band2list(priv, band);
7. 
8. priv->bitmap |=(1 << band);
9. qdisc->q.qlen++;
10. return __qdisc_enqueue_tail(skb, qdisc, list);
11. }
12. 
13. return qdisc_drop(skb, qdisc);
14. }
 
   上面就是 
   __dev_xmit_skb中调用的q->enque的代码,将数据包加入到了dev->_tx所对应的队列中。
然后我还需要回到__dev_xmit_skb中,在加数据包加入到队列中后。要保证qdisc为运行态。
 
   
1. rc = qdisc_enqueue_root(skb, q);
2. if(qdisc_run_begin(q)){
3. if(unlikely(contended)){
4. spin_unlock(&q->busylock);
5. contended =false;
6. }
7. __qdisc_run(q);
8. }
 
   查看__qdisc_run的代码。 
   
1. void __qdisc_run(struct Qdisc *q)
2. {
3. unsigned long start_time = jiffies;

/*
qdisc_restart中发送了数据包。
这里是循环发送,直至qdisc_restart返回0
或者其它进程请求CPU或发送已运行比较长的时间(1jiffie)则也跳出循环体。
*/ 
    
1. while(qdisc_restart(q)){
2. /*
3. * Postpone processing if
4. * 1. another process needs the CPU;
5. * 2. we've been doing it for too long.
6. */
7. if(need_resched()|| jiffies != start_time){
8. /*
9. 需要以后再执行发送动作(利用softirq)
10. */
11. __netif_schedule(q);
12. break;
13. }
14. }
15. 
16. qdisc_run_end(q);
17. }
 
   进入qdisc_restart->sch_direct_xmit,该函数用于发送一个数据包
 
   
1. int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
2. struct net_device *dev, struct netdev_queue *txq,
3. spinlock_t *root_lock)
4. {
5. int ret = NETDEV_TX_BUSY;
6. 
7. /*And release qdisc */
8. spin_unlock(root_lock);
9. 
10. HARD_TX_LOCK(dev, txq, smp_processor_id());
11. //设备没有被停止,且发送队列没有被冻结
12. if(!netif_tx_queue_stopped(txq)&&!netif_tx_queue_frozen(txq))
13. ret = dev_hard_start_xmit(skb, dev, txq); //发送数据包
14. 
15. HARD_TX_UNLOCK(dev, txq);
16. 
17. spin_lock(root_lock);
18. 
19. if(dev_xmit_complete(ret)){
20. /* Driver sent out skb successfully or skb was consumed */
21. //发送成功,返回qdisc新的队列产的
22. ret = qdisc_qlen(q);
23. }elseif(ret == NETDEV_TX_LOCKED){
24. /* Driver try lock failed */
25. //锁冲突
26. ret = handle_dev_cpu_collision(skb, txq, q);
27. }else{
28. /* Driver returned NETDEV_TX_BUSY - requeue skb */
29. if(unlikely (ret != NETDEV_TX_BUSY && net_ratelimit()))
30. printk(KERN_WARNING "BUG %s code %d qlen %d\n",
31. dev->name, ret, q->q.qlen);
//设备繁忙,重新调度发送(利用softirq) 
    
1. ret = dev_requeue_skb(skb, q);
2. }
3. 
4. if(ret &&(netif_tx_queue_stopped(txq)||
5. netif_tx_queue_frozen(txq)))
6. ret = 0;
7. 
8. return ret;
9. }
 
   到此,本文长度已经不短了,先就此结尾。IP包的发送流程比接收流程要复杂得多,估计还需一篇博文才能基本走完。 
  
 
 
  
前文已经学习到了sch_direct_xmit函数,下面进入下一级函数。
 
  
 
   
1. int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
2. struct netdev_queue *txq)
3. {
4. const struct net_device_ops *ops = dev->netdev_ops;
5. int rc = NETDEV_TX_OK;
6. 
7. if(likely(!skb->next)){
/* skb->next为null,即只发送一个skb */
 
    

 
    
1. if(!list_empty(&ptype_all))
2. dev_queue_xmit_nit(skb, dev); //ptype_all上的协议处理,如tcpdump
3. 
4. /*
5. *If device doesnt need skb->dst, release it rightnowwhile
6. * its hot in this cpu cache
7. */
8. /* device 不需要dst */
9. if(dev->priv_flags & IFF_XMIT_DST_RELEASE)
10. skb_dst_drop(skb);

 
    
/* 使该skb不属于任何一个socket */
 
    
1. skb_orphan_try(skb);
2. 
3. if(netif_needs_gso(dev, skb)){
4. /* 需要scatter gather功能 */

 
    
/*
 
    
从注释上看,是进行perform protocol segmentation on skb。
 
    
但是实际工作,目前我不清楚
 
    
*/
 
    
1. if(unlikely(dev_gso_segment(skb)))
2. goto out_kfree_skb;
3. if(skb->next)
4. goto gso;
5. }else{
6. //不需要scatter gather

 
    
/*
 
    
如需要连续内存,则将skb内存线性化,即连续内存 
 
    
*/
 
    
1. if(skb_needs_linearize(skb, dev)&&
2. __skb_linearize(skb))
3. goto out_kfree_skb;
4. 
5. /*If packet isnot checksummed and device does not
6. * support checksumming for this protocol, complete
7. * checksumming here.
8. */
9. if(skb->ip_summed == CHECKSUM_PARTIAL){
10. /* 计算checksum */
11. skb_set_transport_header(skb, skb->csum_start -
12. skb_headroom(skb));
13. if(!dev_can_checksum(dev, skb)&&
14. skb_checksum_help(skb))
15. goto out_kfree_skb;
16. }
17. }

 
    
/* 发送skb数据 */
 
    
1. rc = ops->ndo_start_xmit(skb, dev);
2. if(rc == NETDEV_TX_OK)
3. txq_trans_update(txq);
4. return rc;
5. }
6. 
7. gso:
8. /* 循环发送数据包 */
9. do{
10. struct sk_buff *nskb = skb->next;
11. 
12. skb->next= nskb->next;
13. nskb->next=NULL;
14. 
15. /*
16. *If device doesnt need nskb->dst, release it rightnowwhile
17. * its hot in this cpu cache
18. */
19. if(dev->priv_flags & IFF_XMIT_DST_RELEASE)
20. skb_dst_drop(nskb);
21. 
22. rc = ops->ndo_start_xmit(nskb, dev);
23. if(unlikely(rc != NETDEV_TX_OK)){
24. if(rc &~NETDEV_TX_MASK)
25. goto out_kfree_gso_skb;
26. nskb->next= skb->next;
27. skb->next= nskb;
28. return rc;
29. }
30. txq_trans_update(txq);
31. if(unlikely(netif_tx_queue_stopped(txq)&& skb->next))
32. return NETDEV_TX_BUSY;
33. }while(skb->next);
34. 
35. out_kfree_gso_skb:
36. if(likely(skb->next==NULL))
37. skb->destructor = DEV_GSO_CB(skb)->destructor;
38. out_kfree_skb:
39. kfree_skb(skb);
40. return rc;
41. }
 
  
继续下一个函数,ops->ndo_start_xmit。又是一个回调函数,这个回调函数由驱动所决定。以e1000_main.c为例,
 
  
 
   
1. static const struct net_device_ops e1000_netdev_ops ={
2. .ndo_open = e1000_open,
3. .ndo_stop = e1000_close,
4. .ndo_start_xmit = e1000_xmit_frame,
5. .ndo_get_stats = e1000_get_stats,
6. .ndo_set_rx_mode = e1000_set_rx_mode,
7. .ndo_set_mac_address = e1000_set_mac,
8. .ndo_tx_timeout = e1000_tx_timeout,
9. .ndo_change_mtu = e1000_change_mtu,
10. .ndo_do_ioctl = e1000_ioctl,
11. .ndo_validate_addr = eth_validate_addr,
12. 
13. .ndo_vlan_rx_register = e1000_vlan_rx_register,
14. .ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid,
15. .ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid,
16. #ifdef CONFIG_NET_POLL_CONTROLLER
17. .ndo_poll_controller = e1000_netpoll,
18. #endif
19. };

从这里可以看出,对于e1000_main来说,该回调函数为e1000_xmit_frame。这个涉及到驱动层,一般都与硬件相关,在此就不继续探讨了。


那么现在,一个基本的IP包发送流程,基本上浏览完毕。小小的总结一下,当linux发送IP数据包时,数据包有可能是立刻发送出去,也有可能由下一次的软中断发送。