Skip to content

Commit 6047637

Browse files
herbertxDavid S. Miller
authored andcommitted
[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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 628592c commit 6047637

File tree

13 files changed

+29
-28
lines changed

13 files changed

+29
-28
lines changed

include/linux/skbuff.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@
3232
#define HAVE_ALLOC_SKB /* For the drivers to know */
3333
#define HAVE_ALIGNABLE_SKB /* Ditto 8) */
3434

35+
/* Don't change this without changing skb_csum_unnecessary! */
3536
#define CHECKSUM_NONE 0
36-
#define CHECKSUM_PARTIAL 1
37-
#define CHECKSUM_UNNECESSARY 2
38-
#define CHECKSUM_COMPLETE 3
37+
#define CHECKSUM_UNNECESSARY 1
38+
#define CHECKSUM_COMPLETE 2
39+
#define CHECKSUM_PARTIAL 3
3940

4041
#define SKB_DATA_ALIGN(X) (((X) + (SMP_CACHE_BYTES - 1)) & \
4142
~(SMP_CACHE_BYTES - 1))
@@ -1572,6 +1573,11 @@ static inline void __net_timestamp(struct sk_buff *skb)
15721573
extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len);
15731574
extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
15741575

1576+
static inline int skb_csum_unnecessary(const struct sk_buff *skb)
1577+
{
1578+
return skb->ip_summed & CHECKSUM_UNNECESSARY;
1579+
}
1580+
15751581
/**
15761582
* skb_checksum_complete - Calculate checksum of an entire packet
15771583
* @skb: packet to process
@@ -1590,8 +1596,8 @@ extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
15901596
*/
15911597
static inline unsigned int skb_checksum_complete(struct sk_buff *skb)
15921598
{
1593-
return skb->ip_summed != CHECKSUM_UNNECESSARY &&
1594-
__skb_checksum_complete(skb);
1599+
return skb_csum_unnecessary(skb) ?
1600+
0 : __skb_checksum_complete(skb);
15951601
}
15961602

15971603
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)

include/net/tcp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ static inline __sum16 __tcp_checksum_complete(struct sk_buff *skb)
818818

819819
static inline int tcp_checksum_complete(struct sk_buff *skb)
820820
{
821-
return skb->ip_summed != CHECKSUM_UNNECESSARY &&
821+
return !skb_csum_unnecessary(skb) &&
822822
__tcp_checksum_complete(skb);
823823
}
824824

include/net/udp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static inline __sum16 __udp_lib_checksum_complete(struct sk_buff *skb)
7777

7878
static inline int udp_lib_checksum_complete(struct sk_buff *skb)
7979
{
80-
return skb->ip_summed != CHECKSUM_UNNECESSARY &&
80+
return !skb_csum_unnecessary(skb) &&
8181
__udp_lib_checksum_complete(skb);
8282
}
8383

net/core/netpoll.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static __sum16 checksum_udp(struct sk_buff *skb, struct udphdr *uh,
8686
{
8787
__wsum psum;
8888

89-
if (uh->check == 0 || skb->ip_summed == CHECKSUM_UNNECESSARY)
89+
if (uh->check == 0 || skb_csum_unnecessary(skb))
9090
return 0;
9191

9292
psum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);

net/ipv4/ipvs/ip_vs_core.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -681,8 +681,7 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
681681
}
682682

683683
/* Ensure the checksum is correct */
684-
if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
685-
ip_vs_checksum_complete(skb, ihl)) {
684+
if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
686685
/* Failed checksum! */
687686
IP_VS_DBG(1, "Forward ICMP: failed checksum from %d.%d.%d.%d!\n",
688687
NIPQUAD(iph->saddr));
@@ -921,8 +920,7 @@ ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
921920
verdict = NF_DROP;
922921

923922
/* Ensure the checksum is correct */
924-
if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
925-
ip_vs_checksum_complete(skb, ihl)) {
923+
if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
926924
/* Failed checksum! */
927925
IP_VS_DBG(1, "Incoming ICMP: failed checksum from %d.%d.%d.%d!\n",
928926
NIPQUAD(iph->saddr));

net/ipv4/tcp_input.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4009,7 +4009,7 @@ static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen)
40094009
int err;
40104010

40114011
local_bh_enable();
4012-
if (skb->ip_summed==CHECKSUM_UNNECESSARY)
4012+
if (skb_csum_unnecessary(skb))
40134013
err = skb_copy_datagram_iovec(skb, hlen, tp->ucopy.iov, chunk);
40144014
else
40154015
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
40414041

40424042
static inline int tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
40434043
{
4044-
return skb->ip_summed != CHECKSUM_UNNECESSARY &&
4044+
return !skb_csum_unnecessary(skb) &&
40454045
__tcp_checksum_complete_user(sk, skb);
40464046
}
40474047

@@ -4059,7 +4059,7 @@ static int tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, int hlen
40594059
if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
40604060
tp->ucopy.dma_chan = get_softnet_dma();
40614061

4062-
if (tp->ucopy.dma_chan && skb->ip_summed == CHECKSUM_UNNECESSARY) {
4062+
if (tp->ucopy.dma_chan && skb_csum_unnecessary(skb)) {
40634063

40644064
dma_cookie = dma_skb_copy_datagram_iovec(tp->ucopy.dma_chan,
40654065
skb, hlen, tp->ucopy.iov, chunk, tp->ucopy.pinned_list);

net/ipv4/tcp_ipv4.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,8 +1638,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
16381638
* Packet length and doff are validated by header prediction,
16391639
* provided case of th->doff==0 is eliminated.
16401640
* So, we defer the checks. */
1641-
if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
1642-
tcp_v4_checksum_init(skb)))
1641+
if (!skb_csum_unnecessary(skb) && tcp_v4_checksum_init(skb))
16431642
goto bad_packet;
16441643

16451644
th = tcp_hdr(skb);

net/ipv4/udp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
848848
goto csum_copy_err;
849849
}
850850

851-
if (skb->ip_summed == CHECKSUM_UNNECESSARY)
851+
if (skb_csum_unnecessary(skb))
852852
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
853853
msg->msg_iov, copied );
854854
else {
@@ -1190,7 +1190,7 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
11901190
proto, skb->csum))
11911191
skb->ip_summed = CHECKSUM_UNNECESSARY;
11921192
}
1193-
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
1193+
if (!skb_csum_unnecessary(skb))
11941194
skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
11951195
skb->len, proto, 0);
11961196
/* Probably, we should checksum udp header (it should be in cache

net/ipv6/raw.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
368368
skb->len, inet->num, skb->csum))
369369
skb->ip_summed = CHECKSUM_UNNECESSARY;
370370
}
371-
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
371+
if (!skb_csum_unnecessary(skb))
372372
skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
373373
&ipv6_hdr(skb)->daddr,
374374
skb->len,
@@ -421,7 +421,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
421421
msg->msg_flags |= MSG_TRUNC;
422422
}
423423

424-
if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
424+
if (skb_csum_unnecessary(skb)) {
425425
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
426426
} else if (msg->msg_flags&MSG_TRUNC) {
427427
if (__skb_checksum_complete(skb))

net/ipv6/tcp_ipv6.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,8 +1707,7 @@ static int tcp_v6_rcv(struct sk_buff **pskb)
17071707
if (!pskb_may_pull(skb, th->doff*4))
17081708
goto discard_it;
17091709

1710-
if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
1711-
tcp_v6_checksum_init(skb)))
1710+
if (!skb_csum_unnecessary(skb) && tcp_v6_checksum_init(skb))
17121711
goto bad_packet;
17131712

17141713
th = tcp_hdr(skb);

net/ipv6/udp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
153153
goto csum_copy_err;
154154
}
155155

156-
if (skb->ip_summed == CHECKSUM_UNNECESSARY)
156+
if (skb_csum_unnecessary(skb))
157157
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
158158
msg->msg_iov, copied );
159159
else {
@@ -397,7 +397,7 @@ static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh,
397397
skb->len, proto, skb->csum))
398398
skb->ip_summed = CHECKSUM_UNNECESSARY;
399399

400-
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
400+
if (!skb_csum_unnecessary(skb))
401401
skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
402402
&ipv6_hdr(skb)->daddr,
403403
skb->len, proto, 0));

net/sctp/input.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,7 @@ int sctp_rcv(struct sk_buff *skb)
140140
__skb_pull(skb, skb_transport_offset(skb));
141141
if (skb->len < sizeof(struct sctphdr))
142142
goto discard_it;
143-
if ((skb->ip_summed != CHECKSUM_UNNECESSARY) &&
144-
(sctp_rcv_checksum(skb) < 0))
143+
if (!skb_csum_unnecessary(skb) && sctp_rcv_checksum(skb) < 0)
145144
goto discard_it;
146145

147146
skb_pull(skb, sizeof(struct sctphdr));

net/sunrpc/socklib.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
154154
desc.offset = sizeof(struct udphdr);
155155
desc.count = skb->len - desc.offset;
156156

157-
if (skb->ip_summed == CHECKSUM_UNNECESSARY)
157+
if (skb_csum_unnecessary(skb))
158158
goto no_checksum;
159159

160160
desc.csum = csum_partial(skb->data, desc.offset, skb->csum);

0 commit comments

Comments
 (0)