Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 60476372 authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller
Browse files

[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: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 628592cc
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -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)
+1 −1
Original line number Diff line number Diff line
@@ -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);
}

+1 −1
Original line number Diff line number Diff line
@@ -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);
}

+1 −1
Original line number Diff line number Diff line
@@ -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);
+2 −4
Original line number Diff line number Diff line
@@ -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));
Loading