mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 06:12:08 +00:00
[NET]: Treat CHECKSUM_PARTIAL as CHECKSUM_UNNECESSARY
When a transmitted packet is looped back directly, CHECKSUM_PARTIAL maps to the semantics of CHECKSUM_UNNECESSARY. Therefore we should treat it as such in the stack. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
628592ccdb
commit
604763722c
@ -32,10 +32,11 @@
|
||||
#define HAVE_ALLOC_SKB /* For the drivers to know */
|
||||
#define HAVE_ALIGNABLE_SKB /* Ditto 8) */
|
||||
|
||||
/* Don't change this without changing skb_csum_unnecessary! */
|
||||
#define CHECKSUM_NONE 0
|
||||
#define CHECKSUM_PARTIAL 1
|
||||
#define CHECKSUM_UNNECESSARY 2
|
||||
#define CHECKSUM_COMPLETE 3
|
||||
#define CHECKSUM_UNNECESSARY 1
|
||||
#define CHECKSUM_COMPLETE 2
|
||||
#define CHECKSUM_PARTIAL 3
|
||||
|
||||
#define SKB_DATA_ALIGN(X) (((X) + (SMP_CACHE_BYTES - 1)) & \
|
||||
~(SMP_CACHE_BYTES - 1))
|
||||
@ -1572,6 +1573,11 @@ static inline void __net_timestamp(struct sk_buff *skb)
|
||||
extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len);
|
||||
extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
|
||||
|
||||
static inline int skb_csum_unnecessary(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->ip_summed & CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
|
||||
/**
|
||||
* skb_checksum_complete - Calculate checksum of an entire packet
|
||||
* @skb: packet to process
|
||||
@ -1590,8 +1596,8 @@ extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
|
||||
*/
|
||||
static inline unsigned int skb_checksum_complete(struct sk_buff *skb)
|
||||
{
|
||||
return skb->ip_summed != CHECKSUM_UNNECESSARY &&
|
||||
__skb_checksum_complete(skb);
|
||||
return skb_csum_unnecessary(skb) ?
|
||||
0 : __skb_checksum_complete(skb);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||
|
@ -818,7 +818,7 @@ static inline __sum16 __tcp_checksum_complete(struct sk_buff *skb)
|
||||
|
||||
static inline int tcp_checksum_complete(struct sk_buff *skb)
|
||||
{
|
||||
return skb->ip_summed != CHECKSUM_UNNECESSARY &&
|
||||
return !skb_csum_unnecessary(skb) &&
|
||||
__tcp_checksum_complete(skb);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ static inline __sum16 __udp_lib_checksum_complete(struct sk_buff *skb)
|
||||
|
||||
static inline int udp_lib_checksum_complete(struct sk_buff *skb)
|
||||
{
|
||||
return skb->ip_summed != CHECKSUM_UNNECESSARY &&
|
||||
return !skb_csum_unnecessary(skb) &&
|
||||
__udp_lib_checksum_complete(skb);
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ static __sum16 checksum_udp(struct sk_buff *skb, struct udphdr *uh,
|
||||
{
|
||||
__wsum psum;
|
||||
|
||||
if (uh->check == 0 || skb->ip_summed == CHECKSUM_UNNECESSARY)
|
||||
if (uh->check == 0 || skb_csum_unnecessary(skb))
|
||||
return 0;
|
||||
|
||||
psum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
|
||||
|
@ -681,8 +681,7 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
|
||||
}
|
||||
|
||||
/* Ensure the checksum is correct */
|
||||
if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
|
||||
ip_vs_checksum_complete(skb, ihl)) {
|
||||
if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
|
||||
/* Failed checksum! */
|
||||
IP_VS_DBG(1, "Forward ICMP: failed checksum from %d.%d.%d.%d!\n",
|
||||
NIPQUAD(iph->saddr));
|
||||
@ -921,8 +920,7 @@ ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
|
||||
verdict = NF_DROP;
|
||||
|
||||
/* Ensure the checksum is correct */
|
||||
if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
|
||||
ip_vs_checksum_complete(skb, ihl)) {
|
||||
if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
|
||||
/* Failed checksum! */
|
||||
IP_VS_DBG(1, "Incoming ICMP: failed checksum from %d.%d.%d.%d!\n",
|
||||
NIPQUAD(iph->saddr));
|
||||
|
@ -4009,7 +4009,7 @@ static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen)
|
||||
int err;
|
||||
|
||||
local_bh_enable();
|
||||
if (skb->ip_summed==CHECKSUM_UNNECESSARY)
|
||||
if (skb_csum_unnecessary(skb))
|
||||
err = skb_copy_datagram_iovec(skb, hlen, tp->ucopy.iov, chunk);
|
||||
else
|
||||
err = skb_copy_and_csum_datagram_iovec(skb, hlen,
|
||||
@ -4041,7 +4041,7 @@ static __sum16 __tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb
|
||||
|
||||
static inline int tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return skb->ip_summed != CHECKSUM_UNNECESSARY &&
|
||||
return !skb_csum_unnecessary(skb) &&
|
||||
__tcp_checksum_complete_user(sk, skb);
|
||||
}
|
||||
|
||||
@ -4059,7 +4059,7 @@ static int tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, int hlen
|
||||
if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
|
||||
tp->ucopy.dma_chan = get_softnet_dma();
|
||||
|
||||
if (tp->ucopy.dma_chan && skb->ip_summed == CHECKSUM_UNNECESSARY) {
|
||||
if (tp->ucopy.dma_chan && skb_csum_unnecessary(skb)) {
|
||||
|
||||
dma_cookie = dma_skb_copy_datagram_iovec(tp->ucopy.dma_chan,
|
||||
skb, hlen, tp->ucopy.iov, chunk, tp->ucopy.pinned_list);
|
||||
|
@ -1638,8 +1638,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
|
||||
* Packet length and doff are validated by header prediction,
|
||||
* provided case of th->doff==0 is eliminated.
|
||||
* So, we defer the checks. */
|
||||
if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
|
||||
tcp_v4_checksum_init(skb)))
|
||||
if (!skb_csum_unnecessary(skb) && tcp_v4_checksum_init(skb))
|
||||
goto bad_packet;
|
||||
|
||||
th = tcp_hdr(skb);
|
||||
|
@ -848,7 +848,7 @@ try_again:
|
||||
goto csum_copy_err;
|
||||
}
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_UNNECESSARY)
|
||||
if (skb_csum_unnecessary(skb))
|
||||
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
|
||||
msg->msg_iov, copied );
|
||||
else {
|
||||
@ -1190,7 +1190,7 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
|
||||
proto, skb->csum))
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
|
||||
if (!skb_csum_unnecessary(skb))
|
||||
skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
|
||||
skb->len, proto, 0);
|
||||
/* Probably, we should checksum udp header (it should be in cache
|
||||
|
@ -368,7 +368,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
|
||||
skb->len, inet->num, skb->csum))
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
|
||||
if (!skb_csum_unnecessary(skb))
|
||||
skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr,
|
||||
skb->len,
|
||||
@ -421,7 +421,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
|
||||
msg->msg_flags |= MSG_TRUNC;
|
||||
}
|
||||
|
||||
if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
|
||||
if (skb_csum_unnecessary(skb)) {
|
||||
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
|
||||
} else if (msg->msg_flags&MSG_TRUNC) {
|
||||
if (__skb_checksum_complete(skb))
|
||||
|
@ -1707,8 +1707,7 @@ static int tcp_v6_rcv(struct sk_buff **pskb)
|
||||
if (!pskb_may_pull(skb, th->doff*4))
|
||||
goto discard_it;
|
||||
|
||||
if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
|
||||
tcp_v6_checksum_init(skb)))
|
||||
if (!skb_csum_unnecessary(skb) && tcp_v6_checksum_init(skb))
|
||||
goto bad_packet;
|
||||
|
||||
th = tcp_hdr(skb);
|
||||
|
@ -153,7 +153,7 @@ try_again:
|
||||
goto csum_copy_err;
|
||||
}
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_UNNECESSARY)
|
||||
if (skb_csum_unnecessary(skb))
|
||||
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
|
||||
msg->msg_iov, copied );
|
||||
else {
|
||||
@ -397,7 +397,7 @@ static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh,
|
||||
skb->len, proto, skb->csum))
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
|
||||
if (!skb_csum_unnecessary(skb))
|
||||
skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr,
|
||||
skb->len, proto, 0));
|
||||
|
@ -140,8 +140,7 @@ int sctp_rcv(struct sk_buff *skb)
|
||||
__skb_pull(skb, skb_transport_offset(skb));
|
||||
if (skb->len < sizeof(struct sctphdr))
|
||||
goto discard_it;
|
||||
if ((skb->ip_summed != CHECKSUM_UNNECESSARY) &&
|
||||
(sctp_rcv_checksum(skb) < 0))
|
||||
if (!skb_csum_unnecessary(skb) && sctp_rcv_checksum(skb) < 0)
|
||||
goto discard_it;
|
||||
|
||||
skb_pull(skb, sizeof(struct sctphdr));
|
||||
|
@ -154,7 +154,7 @@ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
|
||||
desc.offset = sizeof(struct udphdr);
|
||||
desc.count = skb->len - desc.offset;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_UNNECESSARY)
|
||||
if (skb_csum_unnecessary(skb))
|
||||
goto no_checksum;
|
||||
|
||||
desc.csum = csum_partial(skb->data, desc.offset, skb->csum);
|
||||
|
Loading…
Reference in New Issue
Block a user