> 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