Re: skb_under_panic

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

 



> 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


[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