#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
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;
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))