Linux???????????·????????IPЭ??
???????????? ???????[ 2013/1/6 10:08:12 ] ????????
???????????????????????豸??????????????????·?????????dev_queue_xmit()
?????ú???????ù?????£?
	
	/*
	 * Send (or queue for sending) a packet.
	 *
	 * IMPORTANT: When this is called to resend frames. The caller MUST
	 * already have locked the sk_buff. Apart from that we do the
	 * rest of the magic.
	 */
	void dev_queue_xmit(struct sk_buff *skb?? struct device *dev?? int pri)
	{
	 unsigned long flags;
	 int nitcount;
	 struct packet_type *ptype;
	 int where = 0;  /* used to say if the packet should go */
	    /* at the front or the back of the */
	    /* queue - front is a retransmit try */
	    /* where=0 ??????????????????????where=1 ????????????????????????*/
	 if (dev == NULL)
	 {
	  printk("dev.c: dev_queue_xmit: dev = NULL
");
	  return;
	 }
	 
	 if(pri>=0 && !skb_device_locked(skb))//??????skb????в???????????????????????
	  skb_device_lock(skb); /* Shove a lock on the frame */
	#ifdef CONFIG_SLAVE_BALANCING
	 save_flags(flags);
	 cli();
	 if(dev->slave!=NULL && dev->slave->pkt_queue < dev->pkt_queue &&
	    (dev->slave->flags & IFF_UP))
	  dev=dev->slave;
	 restore_flags(flags);
	#endif 
	#ifdef CONFIG_SKB_CHECK
	 IS_SKB(skb);
	#endif   
	 skb->dev = dev;
	 /*
	  * This just eliminates some race conditions?? but not all...
	  */
	 if (skb->next != NULL) //?????????????????????????????????????????????????????????
	 {//???????????BUG
	  /*
	   * Make sure we haven't missed an interrupt.
	   */
	  printk("dev_queue_xmit: worked around a missed interrupt
");
	  start_bh_atomic();
	  dev->hard_start_xmit(NULL?? dev);
	  end_bh_atomic();
	  return;
	   }
	 /*
	  * Negative priority is used to flag a frame that is being pulled from the
	  * queue front as a retransmit attempt. It therefore goes back on the queue
	  * start on a failure.
	  */
	 
	   if (pri < 0) //?????С??0?????????????????????????
	   {
	  pri = -pri-1;
	  where = 1;
	   }
	 if (pri >= DEV_NUMBUFFS)
	 {
	  printk("bad priority in dev_queue_xmit.
");
	  pri = 1;
	 }
	 /*
	  * If the address has not been resolved. Call the device header rebuilder.
	  * This can cover all protocols and technically not just ARP either.
	  */
	 
	 if (!skb->arp && dev->rebuild_header(skb->data?? dev?? skb->raddr?? skb)) {//????ARPЭ?飬?????MAC????
	  return;
	 }
	 save_flags(flags);
	 cli();
	 if (!where) {//?????????????????????????豸??????
	#ifdef CONFIG_SLAVE_BALANCING
	  skb->in_dev_queue=1;//??????????豸????
	#endif 
	  skb_queue_tail(dev->buffs + pri??skb);//??????????????????????
	  skb_device_unlock(skb);  /* Buffer is on the device queue and can be freed safely */
	  skb = skb_dequeue(dev->buffs + pri);//??????????????????????
	  skb_device_lock(skb);  /* New buffer needs locking down */
	#ifdef CONFIG_SLAVE_BALANCING 
	  skb->in_dev_queue=0;
	#endif 
	 }
	 restore_flags(flags);
	 /* copy outgoing packets to any sniffer packet handlers */
	 if(!where)//?????μ??????????????????Э????У????????????
	 {
	  for (nitcount= dev_nit?? ptype = ptype_base; nitcount > 0 && ptype != NULL; ptype = ptype->next)
	  {
	   /* Never send packets back to the socket
	    * they originated from - MvS (miquels@drinkel.ow.org)
	    */
	   if (ptype->type == htons(ETH_P_ALL) &&
	      (ptype->dev == dev || !ptype->dev) &&
	      ((struct sock *)ptype->data != skb->sk))
	   {
	    struct sk_buff *skb2;
	    if ((skb2 = skb_clone(skb?? GFP_ATOMIC)) == NULL)
	     break;
	    /*
	     * The protocol knows this has (for other paths) been taken off
	     * and adds it back.
	     */
	    skb2->len-=skb->dev->hard_header_len;
	    ptype->func(skb2?? skb->dev?? ptype);//IP???????func?ip_rcv()??????????????????????????????Э??
	    nitcount--;//????????????
	   }
	  }
	 }
	 start_bh_atomic();//?????????
	 if (dev->hard_start_xmit(skb?? dev) == 0) {//???????????????????????
	  end_bh_atomic();//??????????
	  /*
	   * Packet is now solely the responsibility of the driver
	   */
	  return;//?????????????????????
	 }
	 //???????г??????????д?????????????????????????
	 end_bh_atomic();
	 /*
	  * Transmission failed?? put skb back into a list. Once on the list it's safe and
	  * no longer device locked (it can be freed safely from the device queue)
	  */
	 cli();
	#ifdef CONFIG_SLAVE_BALANCING
	 skb->in_dev_queue=1;
	 dev->pkt_queue++;
	#endif 
	 skb_device_unlock(skb);//??SKB????
	 skb_queue_head(dev->buffs + pri??skb);//??β?????巨??????????????
	 restore_flags(flags);
	}
	 
	
	???????????????????dev->hard_start_xmit????????????????з?????
????????????http://blog.csdn.net/yming0221/article/details/7492423
??????
					
					???·???
App??С????H5?????????????????Щ??
2024/9/11 15:34:34?????????????????????????
2024/9/10 11:13:49P-One ???????????????????????????????????????
2024/9/10 10:14:12???????????????????????????
2024/9/9 18:04:26??????????????????
2023/3/23 14:23:39???д?ò??????????
2023/3/22 16:17:39????????????????????Щ??
2022/6/14 16:14:27??????????????????????????
2021/10/18 15:37:44
					
			
								
								
								
								
								
								
								
								
								
								
				
sales@spasvo.com