diff options
author | Tom Herbert <therbert@google.com> | 2014-08-22 16:33:47 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-08-24 21:09:23 -0400 |
commit | 573e8fca255a27e3573b51f9b183d62641c47a3d (patch) | |
tree | 037fa48ffcd2b80e9b861904370ae64a6cba4224 /net/core | |
parent | 8fc54f68919298ff9689d980efb495707ef43f30 (diff) |
net: skb_gro_checksum_* functions
Add skb_gro_checksum_validate, skb_gro_checksum_validate_zero_check,
and skb_gro_checksum_simple_validate, and __skb_gro_checksum_complete.
These are the cognates of the normal checksum functions but are used
in the gro_receive path and operate on GRO related fields in sk_buffs.
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 1421dad4cb29..b6a718ec11c1 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3962,7 +3962,13 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff | |||
3962 | goto normal; | 3962 | goto normal; |
3963 | 3963 | ||
3964 | gro_list_prepare(napi, skb); | 3964 | gro_list_prepare(napi, skb); |
3965 | NAPI_GRO_CB(skb)->csum = skb->csum; /* Needed for CHECKSUM_COMPLETE */ | 3965 | |
3966 | if (skb->ip_summed == CHECKSUM_COMPLETE) { | ||
3967 | NAPI_GRO_CB(skb)->csum = skb->csum; | ||
3968 | NAPI_GRO_CB(skb)->csum_valid = 1; | ||
3969 | } else { | ||
3970 | NAPI_GRO_CB(skb)->csum_valid = 0; | ||
3971 | } | ||
3966 | 3972 | ||
3967 | rcu_read_lock(); | 3973 | rcu_read_lock(); |
3968 | list_for_each_entry_rcu(ptype, head, list) { | 3974 | list_for_each_entry_rcu(ptype, head, list) { |
@@ -3975,6 +3981,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff | |||
3975 | NAPI_GRO_CB(skb)->flush = 0; | 3981 | NAPI_GRO_CB(skb)->flush = 0; |
3976 | NAPI_GRO_CB(skb)->free = 0; | 3982 | NAPI_GRO_CB(skb)->free = 0; |
3977 | NAPI_GRO_CB(skb)->udp_mark = 0; | 3983 | NAPI_GRO_CB(skb)->udp_mark = 0; |
3984 | NAPI_GRO_CB(skb)->encapsulation = 0; | ||
3978 | 3985 | ||
3979 | pp = ptype->callbacks.gro_receive(&napi->gro_list, skb); | 3986 | pp = ptype->callbacks.gro_receive(&napi->gro_list, skb); |
3980 | break; | 3987 | break; |
@@ -4205,6 +4212,31 @@ gro_result_t napi_gro_frags(struct napi_struct *napi) | |||
4205 | } | 4212 | } |
4206 | EXPORT_SYMBOL(napi_gro_frags); | 4213 | EXPORT_SYMBOL(napi_gro_frags); |
4207 | 4214 | ||
4215 | /* Compute the checksum from gro_offset and return the folded value | ||
4216 | * after adding in any pseudo checksum. | ||
4217 | */ | ||
4218 | __sum16 __skb_gro_checksum_complete(struct sk_buff *skb) | ||
4219 | { | ||
4220 | __wsum wsum; | ||
4221 | __sum16 sum; | ||
4222 | |||
4223 | wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb), 0); | ||
4224 | |||
4225 | /* NAPI_GRO_CB(skb)->csum holds pseudo checksum */ | ||
4226 | sum = csum_fold(csum_add(NAPI_GRO_CB(skb)->csum, wsum)); | ||
4227 | if (likely(!sum)) { | ||
4228 | if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) && | ||
4229 | !skb->csum_complete_sw) | ||
4230 | netdev_rx_csum_fault(skb->dev); | ||
4231 | } | ||
4232 | |||
4233 | NAPI_GRO_CB(skb)->csum = wsum; | ||
4234 | NAPI_GRO_CB(skb)->csum_valid = 1; | ||
4235 | |||
4236 | return sum; | ||
4237 | } | ||
4238 | EXPORT_SYMBOL(__skb_gro_checksum_complete); | ||
4239 | |||
4208 | /* | 4240 | /* |
4209 | * net_rps_action_and_irq_enable sends any pending IPI's for rps. | 4241 | * net_rps_action_and_irq_enable sends any pending IPI's for rps. |
4210 | * Note: called with local irq disabled, but exits with local irq enabled. | 4242 | * Note: called with local irq disabled, but exits with local irq enabled. |