aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2005-11-10 16:01:24 -0500
committerDavid S. Miller <davem@davemloft.net>2005-11-10 16:01:24 -0500
commitfb286bb2990a107009dbf25f6ffebeb7df77f9be (patch)
tree0eede2c37f1b3831e59601933eebf6b82be75ffc /net/ipv4/udp.c
parent1064e944d03eb7a72c0fa11236d5e69cfd877a71 (diff)
[NET]: Detect hardware rx checksum faults correctly
Here is the patch that introduces the generic skb_checksum_complete which also checks for hardware RX checksum faults. If that happens, it'll call netdev_rx_csum_fault which currently prints out a stack trace with the device name. In future it can turn off RX checksum. I've converted every spot under net/ that does RX checksum checks to use skb_checksum_complete or __skb_checksum_complete with the exceptions of: * Those places where checksums are done bit by bit. These will call netdev_rx_csum_fault directly. * The following have not been completely checked/converted: ipmr ip_vs netfilter dccp This patch is based on patches and suggestions from Stephen Hemminger and David S. Miller. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index e0bd1013cb0d..2422a5f7195d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -761,7 +761,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
761 761
762static __inline__ int __udp_checksum_complete(struct sk_buff *skb) 762static __inline__ int __udp_checksum_complete(struct sk_buff *skb)
763{ 763{
764 return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); 764 return __skb_checksum_complete(skb);
765} 765}
766 766
767static __inline__ int udp_checksum_complete(struct sk_buff *skb) 767static __inline__ int udp_checksum_complete(struct sk_buff *skb)
@@ -1100,11 +1100,8 @@ static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
1100 if (uh->check == 0) { 1100 if (uh->check == 0) {
1101 skb->ip_summed = CHECKSUM_UNNECESSARY; 1101 skb->ip_summed = CHECKSUM_UNNECESSARY;
1102 } else if (skb->ip_summed == CHECKSUM_HW) { 1102 } else if (skb->ip_summed == CHECKSUM_HW) {
1103 skb->ip_summed = CHECKSUM_UNNECESSARY;
1104 if (!udp_check(uh, ulen, saddr, daddr, skb->csum)) 1103 if (!udp_check(uh, ulen, saddr, daddr, skb->csum))
1105 return 0; 1104 skb->ip_summed = CHECKSUM_UNNECESSARY;
1106 LIMIT_NETDEBUG(KERN_DEBUG "udp v4 hw csum failure.\n");
1107 skb->ip_summed = CHECKSUM_NONE;
1108 } 1105 }
1109 if (skb->ip_summed != CHECKSUM_UNNECESSARY) 1106 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
1110 skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0); 1107 skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);