Linux???????????·????????IPЭ??
???????????? ???????[ 2013/1/6 10:08:12 ] ????????
????????????????????????ú???ip_queue_xmit()???????????????????????????????????????ú?????
?????ú???????????????ù??????£?
/*
* Queues a packet to be sent?? and starts the transmitter
* if necessary. if free = 1 then we free the block after
* transmit?? otherwise we don't. If free==2 we not only
* free the block but also don't assign a new ip seq number.
* This routine also needs to put in the total length??
* and compute the checksum
*/
void ip_queue_xmit(struct sock *sk?? //???????????????????sock??
struct device *dev??//?????????????????豸
struct sk_buff *skb??//??????sk_buff????????????????y???
int free)//??????TCPЭ??????????????????????UDP??Э???????free=1
{
struct iphdr *iph;//IP???????????
unsigned char *ptr;
/* Sanity check */
if (dev == NULL)
{
printk("IP: ip_queue_xmit dev = NULL
");
return;
}
IS_SKB(skb);
/*
* Do some book-keeping in the packet for later
*/
skb->dev = dev;//?????????sk_buff????????
skb->when = jiffies;//????TCPЭ????????
/*
* Find the IP header and set the length. This is bad
* but once we get the skb data handling code in the
* hardware will push its header sensibly and we will
* set skb->ip_hdr to avoid this mess and the fixed
* header length problem
*/
ptr = skb->data;//??????sk_buff?е????????
ptr += dev->hard_header_len;//hard_header_len??????????????net_init.c?????eth_setup()????????????dev->hard_header_len = ETH_HLEN; ?????????????14
iph = (struct iphdr *)ptr;//prt??????IP??????????
skb->ip_hdr = iph;
iph->tot_len = ntohs(skb->len-dev->hard_header_len);//????IP????????????
#ifdef CONFIG_IP_FIREWALL
if(ip_fw_chk(iph?? dev?? ip_fw_blk_chain?? ip_fw_blk_policy?? 0) != 1)
/* just don't send this packet */
return;
#endif
/*
* No reassigning numbers to fragments...
*/
if(free!=2)
iph->id = htons(ip_id_count++);
else
free=1;
/* All buffers without an owner socket get freed */
if (sk == NULL)
free = 1;
skb->free = free;//????skb??free???free=1???????????????free=2???????????棬??????????μ????к?
/*
* Do we need to fragment. Again this is inefficient.
* We need to somehow lock the original buffer and use
* bits of it.
*/
//??????е???????????С?????MTU
if(skb->len > dev->mtu + dev->hard_header_len)//??????????????????????????????????????????????
{
ip_fragment(sk??skb??dev??0);//???????????????????ip _queue_xmit()????????????
IS_SKB(skb);
kfree_skb(skb??FREE_WRITE);
return;
}
/*
* Add an IP checksum
*/
ip_send_check(iph);//IP???????????
/*
* Print the frame when debugging
*/
/*
* More debugging. You cannot queue a packet already on a list
* Spot this and moan loudly.
*/
if (skb->next != NULL)//?????????????????????????????
{
printk("ip_queue_xmit: next != NULL
");
skb_unlink(skb);//???????????????????????????????????
}
/*
* If a sender wishes the packet to remain unfreed
* we add it to his send queue. This arguably belongs
* in the TCP level since nobody else uses it. BUT
* remember IPng might change all the rules.
*/
if (!free)//free=0
{
unsigned long flags;
/* The socket now has more outstanding blocks */
sk->packets_out++;
/* Protect the list for a moment */
save_flags(flags);
cli();
if (skb->link3 != NULL)//link3???????????????????
{
printk("ip.c: link3 != NULL
");
skb->link3 = NULL;
}
//sk??send_tail??send_head??????????????????β????
if (sk->send_head == NULL)
{
sk->send_tail = skb;
sk->send_head = skb;
}
else
{
sk->send_tail->link3 = skb;//link3??????????????????
sk->send_tail = skb;
}
/* skb->link3 is NULL */
/* Interrupt restore */
restore_flags(flags);
}
else
/* Remember who owns the buffer */
skb->sk = sk;
/*
* If the indicated interface is up and running?? send the packet.
*/
ip_statistics.IpOutRequests++;
#ifdef CONFIG_IP_ACCT
ip_acct_cnt(iph??dev?? ip_acct_chain);
#endif
#ifdef CONFIG_IP_MULTICAST //??????IP????????????
/*
* Multicasts are looped back for other local users
*/
.......................................
#endif
if((dev->flags&IFF_BROADCAST) && iph->daddr==dev->pa_brdaddr && !(dev->flags&IFF_LOOPBACK))//????????????
ip_loopback(dev??skb);
if (dev->flags & IFF_UP)//?豸??????
{
/*
* If we have an owner use its priority setting??
* otherwise use NORMAL
*/
//?????豸??????????????: dev_queue_xmit()????
if (sk != NULL)
{
dev_queue_xmit(skb?? dev?? sk->priority);
}
else
{
dev_queue_xmit(skb?? dev?? SOPRI_NORMAL);
}
}
else//?豸????????
{
ip_statistics.IpOutDiscards++;
if (free)
kfree_skb(skb?? FREE_WRITE);
}
}
??????
???·???
??????????????????
2023/3/23 14:23:39???д?ò??????????
2023/3/22 16:17:39????????????????????Щ??
2022/6/14 16:14:27??????????????????????????
2021/10/18 15:37:44???????????????
2021/9/17 15:19:29???·???????·
2021/9/14 15:42:25?????????????
2021/5/28 17:25:47??????APP??????????
2021/5/8 17:01:11