diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2005-11-10 16:01:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-11-10 16:01:24 -0500 |
commit | fb286bb2990a107009dbf25f6ffebeb7df77f9be (patch) | |
tree | 0eede2c37f1b3831e59601933eebf6b82be75ffc /include/linux | |
parent | 1064e944d03eb7a72c0fa11236d5e69cfd877a71 (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 'include/linux')
-rw-r--r-- | include/linux/netdevice.h | 7 | ||||
-rw-r--r-- | include/linux/skbuff.h | 27 |
2 files changed, 32 insertions, 2 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c6efce4a04a4..936f8b76114e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -927,6 +927,13 @@ extern int netdev_max_backlog; | |||
927 | extern int weight_p; | 927 | extern int weight_p; |
928 | extern int netdev_set_master(struct net_device *dev, struct net_device *master); | 928 | extern int netdev_set_master(struct net_device *dev, struct net_device *master); |
929 | extern int skb_checksum_help(struct sk_buff *skb, int inward); | 929 | extern int skb_checksum_help(struct sk_buff *skb, int inward); |
930 | #ifdef CONFIG_BUG | ||
931 | extern void netdev_rx_csum_fault(struct net_device *dev); | ||
932 | #else | ||
933 | static inline void netdev_rx_csum_fault(struct net_device *dev) | ||
934 | { | ||
935 | } | ||
936 | #endif | ||
930 | /* rx skb timestamps */ | 937 | /* rx skb timestamps */ |
931 | extern void net_enable_timestamp(void); | 938 | extern void net_enable_timestamp(void); |
932 | extern void net_disable_timestamp(void); | 939 | extern void net_disable_timestamp(void); |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 83010231db99..0a8ea8b35816 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -1236,8 +1236,7 @@ extern unsigned int datagram_poll(struct file *file, struct socket *sock, | |||
1236 | extern int skb_copy_datagram_iovec(const struct sk_buff *from, | 1236 | extern int skb_copy_datagram_iovec(const struct sk_buff *from, |
1237 | int offset, struct iovec *to, | 1237 | int offset, struct iovec *to, |
1238 | int size); | 1238 | int size); |
1239 | extern int skb_copy_and_csum_datagram_iovec(const | 1239 | extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, |
1240 | struct sk_buff *skb, | ||
1241 | int hlen, | 1240 | int hlen, |
1242 | struct iovec *iov); | 1241 | struct iovec *iov); |
1243 | extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb); | 1242 | extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb); |
@@ -1305,6 +1304,30 @@ static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval * | |||
1305 | 1304 | ||
1306 | extern void __net_timestamp(struct sk_buff *skb); | 1305 | extern void __net_timestamp(struct sk_buff *skb); |
1307 | 1306 | ||
1307 | extern unsigned int __skb_checksum_complete(struct sk_buff *skb); | ||
1308 | |||
1309 | /** | ||
1310 | * skb_checksum_complete - Calculate checksum of an entire packet | ||
1311 | * @skb: packet to process | ||
1312 | * | ||
1313 | * This function calculates the checksum over the entire packet plus | ||
1314 | * the value of skb->csum. The latter can be used to supply the | ||
1315 | * checksum of a pseudo header as used by TCP/UDP. It returns the | ||
1316 | * checksum. | ||
1317 | * | ||
1318 | * For protocols that contain complete checksums such as ICMP/TCP/UDP, | ||
1319 | * this function can be used to verify that checksum on received | ||
1320 | * packets. In that case the function should return zero if the | ||
1321 | * checksum is correct. In particular, this function will return zero | ||
1322 | * if skb->ip_summed is CHECKSUM_UNNECESSARY which indicates that the | ||
1323 | * hardware has already verified the correctness of the checksum. | ||
1324 | */ | ||
1325 | static inline unsigned int skb_checksum_complete(struct sk_buff *skb) | ||
1326 | { | ||
1327 | return skb->ip_summed != CHECKSUM_UNNECESSARY && | ||
1328 | __skb_checksum_complete(skb); | ||
1329 | } | ||
1330 | |||
1308 | #ifdef CONFIG_NETFILTER | 1331 | #ifdef CONFIG_NETFILTER |
1309 | static inline void nf_conntrack_put(struct nf_conntrack *nfct) | 1332 | static inline void nf_conntrack_put(struct nf_conntrack *nfct) |
1310 | { | 1333 | { |