]> xenbits.xen.org Git - xenclient/kernel.git/commitdiff
imported patch debug-dump-skb-info-when-invalid bonding-no-updelay-on-first-active-slave.patch
authort_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:06:05 +0000 (12:06 +0000)
committert_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:06:05 +0000 (12:06 +0000)
include/linux/skbuff.h
net/core/skbuff.c

index cc82c016acf6526e08f3013ecd110967ffae32d5..bbb681c1b699164cbb575b146836b769c91bc9f3 100644 (file)
@@ -1630,5 +1630,7 @@ static inline int skb_is_gso(const struct sk_buff *skb)
        return skb_shinfo(skb)->gso_size;
 }
 
+extern void skb_dump_info(const struct sk_buff *skb);
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SKBUFF_H */
index 05c69085739e5c8dbda420be38c7aa35bd746d5f..1db8ce883455265a6ba94d92469cdcc925ee193b 100644 (file)
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
+#include <asm/io.h>
 
 static kmem_cache_t *skbuff_head_cache __read_mostly;
 static kmem_cache_t *skbuff_fclone_cache __read_mostly;
 
+void skb_dump_info(const struct sk_buff *skb)
+{
+#ifdef CONFIG_XEN
+       int i, nr = skb_shinfo(skb)->nr_frags;
+#endif
+       struct ethhdr *ethh = eth_hdr(skb);
+
+       printk(KERN_ERR "skb: skb at %p with %d users\n", skb, atomic_read(&skb->users));
+       printk(KERN_ERR "skb: prev %p next %p prev->next %p next->prev %p\n",
+              skb->prev, skb->next,
+              skb->prev ? skb->prev->next : NULL,
+              skb->next ? skb->next->prev : NULL);
+       printk(KERN_ERR "skb: len is %#x (data:%#x mac:%#x) truesize %#x\n",
+              skb->len, skb->data_len, skb->mac_len, skb->truesize);
+
+        printk(KERN_ERR "skb: linear:%s\n", skb_is_nonlinear(skb) ? "No" : "Yes");
+        printk(KERN_ERR "skb: data %p head %p tail %p end %p\n",
+               skb->data, skb->head, skb->tail, skb->end);
+        printk(KERN_ERR "skb: flags are local_df:%d cloned:%d ip_summed:%d nohdr:%d\n",
+               skb->local_df, skb->cloned, skb->ip_summed, skb->nohdr);
+        printk(KERN_ERR "skb:               nfctinfo:%d pkt_type:%d fclone:%d ipvs_property:%d\n",
+               skb->nfctinfo, skb->pkt_type, skb->nohdr, skb->ipvs_property);
+#ifdef CONFIG_XEN
+        printk(KERN_ERR "skb:               proto_data_valid:%d proto_csum_blank:%d\n",
+               skb->proto_data_valid, skb->proto_csum_blank);
+#endif
+        printk(KERN_ERR "skb: shared info %p ref %#x\n", skb_shinfo(skb), atomic_read(&skb_shinfo(skb)->dataref));
+        printk(KERN_ERR "skb: frag_list %p\n", skb_shinfo(skb)->frag_list);
+
+       printk(KERN_ERR "skb: eth: (%p) src:%02x:%02x:%02x:%02x:%02x:%02x dest:%02x:%02x:%02x:%02x:%02x:%02x proto %u\n",
+              ethh,
+              ethh->h_source[0], ethh->h_source[1], ethh->h_source[2], ethh->h_source[3], ethh->h_source[4], ethh->h_source[5],
+              ethh->h_dest[0], ethh->h_dest[1], ethh->h_dest[2], ethh->h_dest[3], ethh->h_dest[4], ethh->h_dest[5],
+              ntohs(ethh->h_proto));
+       if (ethh->h_proto == __constant_htons(ETH_P_IP)) {
+               struct iphdr *iph = ip_hdr(skb);
+               printk(KERN_ERR "skb: ip: (%p) saddr "NIPQUAD_FMT" daddr "NIPQUAD_FMT" protocol %d frag_off %d\n",
+                      iph, NIPQUAD(iph->saddr), NIPQUAD(iph->daddr), iph->protocol, iph->frag_off);
+
+               if (iph->protocol == IPPROTO_TCP) {
+                       struct tcphdr *tcph = tcp_hdr(skb);
+                       printk(KERN_ERR "bnx2: tcp: (%p) source %d dest %d seq %u ack %u\n",
+                              tcph, ntohs(tcph->source), ntohs(tcph->dest), ntohl(tcph->seq), ntohl(tcph->ack_seq));
+               }
+       }
+
+#ifdef CONFIG_XEN
+       for(i=0; i<nr; i++) {
+               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+               unsigned long pfn = page_to_pfn(frag->page);
+               unsigned long mfn = pfn_to_mfn(pfn);
+               printk(KERN_ERR "skb: %d/%d page:%p offset:%#x size:%#x virt:%p pfn:%#lx mfn:%#lx%s flags:%lx%s)\n",
+                      i, nr, frag->page, frag->page_offset, frag->size,
+                      phys_to_virt(page_to_phys(frag->page)), pfn, mfn,
+                      phys_to_machine_mapping_valid(pfn) ? "" : "(BAD)",
+                      frag->page->flags,
+                      PageForeign(frag->page) ? "FOREIGN" : "not-foreign");
+       }
+#endif
+}
+EXPORT_SYMBOL(skb_dump_info);
+
+
 /*
  *     Keep out-of-line to prevent kernel bloat.
  *     __builtin_return_address is not used because it is not always
@@ -1340,13 +1404,20 @@ unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
        int start = skb_headlen(skb);
        int i, copy = start - offset;
        int pos = 0;
+       int src_err = 0;
 
        /* Copy header. */
        if (copy > 0) {
                if (copy > len)
                        copy = len;
-               csum = csum_partial_copy_nocheck(skb->data + offset, to,
-                                                copy, csum);
+               csum = csum_partial_copy_generic(skb->data + offset, to,
+                                                copy, csum, &src_err, NULL);
+               if (src_err) {
+                       skb_dump_info(skb);
+                       printk(KERN_CRIT "checksum: CA-22751 bad skb in head\n");
+                       BUG();
+               }
+
                if ((len -= copy) == 0)
                        return csum;
                offset += copy;
@@ -1368,10 +1439,15 @@ unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
                        if (copy > len)
                                copy = len;
                        vaddr = kmap_skb_frag(frag);
-                       csum2 = csum_partial_copy_nocheck(vaddr +
+                       csum2 = csum_partial_copy_generic(vaddr +
                                                          frag->page_offset +
                                                          offset - start, to,
-                                                         copy, 0);
+                                                         copy, 0, &src_err, NULL);
+                       if (src_err) {
+                               skb_dump_info(skb);
+                               printk(KERN_CRIT "checksum: CA-22751 bad skb in frag %d\n", i);
+                               BUG();
+                       }
                        kunmap_skb_frag(vaddr);
                        csum = csum_block_add(csum, csum2, pos);
                        if (!(len -= copy))