Re: skb_under_panic

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi, 
Thanks for the help. Actually, I had already realized 
that ip_finsih_output2 might be the cause of the bug -

it tries to put in a cached header and the
skb_push...thats why i had sent the mail regarding
bug in ip_finish_output2.... (the hardware header size
may not be 16...)

what I need to know is the path of the packet after 
dev_queue_xmit is called. The reason is, that ip_send 
(which calls dev_queue_xmit)
returns success, but sometime after this, I get the 
skb under panic. So it seems like the dev_queue_xmit
functions only queues up the packet for transmission, 
and later some function actually fills in the hardware
header (eth_build_header, eth_rebuild_header after the
arp query has been resolved) and sends the packet out.
This might be another potential place for the error...

I couldn't trace the function pointers ahead of
dev_queue_xmit - thats where I am stuck...
dev->qdisc->enqueue ().... ?

thanks, 
akshay




--- Nivedita Singhvi <nivedita@sequent.com> wrote:
> > can someone tell me what the path of an ip packet
> is
> > after
> > you call ip_send (skb)? The problem I am facing
> is: 
> > 
> > When i call ip_send to send out the packet, the
> > function returns sucessfully, but soon after this,
> 
> > i get an skb_under_panic - some function down
> below is
> > probably trying to push back the skb->data to
> attach
> > the hardware header, and goes back beyond
> skb->head.
> > 
> > How does ip_send return successfully, but then I
> get
> > an error?
> 
> 
> [ net/ip.h: 162 ]
> 
> 	#ifdef CONFIG_INET
> 	static inline int ip_send(struct sk_buff *skb)
> 	{
> 		if (skb->len > skb->dst->pmtu)
> 			return ip_fragment(skb, ip_finish_output);
> 		else
> 			return ip_finish_output(skb);
> 	}                                  
> 
> assuming you've taken care of passing down a
> appropriately sized segment, you wont need to
> fragment, in which case you'll move on to
> ip_finish_output().
> [ net/ipv4/ip_output.c:181 ]
> 
> 	__inline__ int ip_finish_output(struct sk_buff
> *skb)
> 	{
> 		struct net_device *dev = skb->dst->dev;
> 
> 		skb->dev = dev;
> 		skb->protocol = __constant_htons(ETH_P_IP);
> 
> 		return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb,
> NULL, dev,
> 			       ip_finish_output2);
> 	}                             
> 
> if you've configured netfilter, it will do some
> netfilter processing first, otherwise will jump to
> this next:
> [ net/ipv4/ip_output.c: 158 ]
> 
> 	inline int ip_finish_output2(struct sk_buff *skb)
> 	{
> 		struct dst_entry *dst = skb->dst;
> 		struct hh_cache *hh = dst->hh;
> 
> 	#ifdef CONFIG_NETFILTER_DEBUG
> 		nf_debug_ip_finish_output2(skb);
> 	#endif /*CONFIG_NETFILTER_DEBUG*/
> 
> 		if (hh) {
> 			read_lock_bh(&hh->hh_lock);
> 			memcpy(skb->data - 16, hh->hh_data, 16);
> 			read_unlock_bh(&hh->hh_lock);
> 			skb_push(skb, hh->hh_len);
> 			return hh->hh_output(skb);
> 		} else if (dst->neighbour)
> 			return dst->neighbour->output(skb);
> 
> 		printk(KERN_DEBUG "khm\n");
> 		kfree_skb(skb);
> 		return -EINVAL;
> 	}                                                  
> 
> if there is a cached hdr already, it will attach it,
> and perhaps thats where your code is blowing up:
> [ linux/skbuff.h:73 ]
> 
> 	/**
> 	 *      skb_push - add data to the start of a
> buffer
> 	 *      @skb: buffer to use
> 	 *      @len: amount of data to add
> 	 *
> 	 *      This function extends the used data area of
> the buffer 
> 	  at the buffer
> 	 *      start. If this would exceed the total
> buffer headroom 
> 	the kernel will
> 	 *      panic. A pointer to the first byte of the
> extra data is 
> 	returned.
> 	 */
> 
> 	static inline unsigned char *skb_push(struct
> sk_buff *skb, 
> 		unsigned int len)
> 	{
> 		skb->data-=len;
> 		skb->len+=len;
> 		if(skb->data<skb->head) {
> 			skb_under_panic(skb, len, current_text_addr());
> 		}
> 		return skb->data;
> 	}                                          
> 
> hope that helps,
> 
> thanks,
> nivedita
> 
> ---
> Nivedita Singhvi                        (503)
> 578-4580
> Linux Technology Center                
> nivedita@us.ibm.com
> IBM Beaverton, OR                      
> nivedita@sequent.com
> -
> : send the line
> "unsubscribe linux-net" in
> the body of a message to majordomo@vger.kernel.org


__________________________________________________
Do You Yahoo!?
Get email at your own domain with Yahoo! Mail. 
http://personal.mail.yahoo.com/
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux