aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTom Herbert <therbert@google.com>2015-02-10 19:30:29 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-11 18:12:10 -0500
commit6db93ea13b7937c0523ea1f977b322f1347a5633 (patch)
tree05964d4c4fda83679ac32139dbf3859bbd24c8c1 /net
parent6edec0e61b1e52f9144935d28c9088f5b202e61c (diff)
udp: Set SKB_GSO_UDP_TUNNEL* in UDP GRO path
Properly set GSO types and skb->encapsulation in the UDP tunnel GRO complete so that packets are properly represented for GSO. This sets SKB_GSO_UDP_TUNNEL or SKB_GSO_UDP_TUNNEL_CSUM depending on whether non-zero checksums were received, and sets SKB_GSO_TUNNEL_REMCSUM if the remote checksum option was processed. Signed-off-by: Tom Herbert <therbert@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/udp_offload.c13
-rw-r--r--net/ipv6/udp_offload.c6
2 files changed, 17 insertions, 2 deletions
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index d10f6f4ead27..4915d8284a86 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -402,6 +402,13 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff)
402 } 402 }
403 403
404 rcu_read_unlock(); 404 rcu_read_unlock();
405
406 if (skb->remcsum_offload)
407 skb_shinfo(skb)->gso_type |= SKB_GSO_TUNNEL_REMCSUM;
408
409 skb->encapsulation = 1;
410 skb_set_inner_mac_header(skb, nhoff + sizeof(struct udphdr));
411
405 return err; 412 return err;
406} 413}
407 414
@@ -410,9 +417,13 @@ static int udp4_gro_complete(struct sk_buff *skb, int nhoff)
410 const struct iphdr *iph = ip_hdr(skb); 417 const struct iphdr *iph = ip_hdr(skb);
411 struct udphdr *uh = (struct udphdr *)(skb->data + nhoff); 418 struct udphdr *uh = (struct udphdr *)(skb->data + nhoff);
412 419
413 if (uh->check) 420 if (uh->check) {
421 skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL_CSUM;
414 uh->check = ~udp_v4_check(skb->len - nhoff, iph->saddr, 422 uh->check = ~udp_v4_check(skb->len - nhoff, iph->saddr,
415 iph->daddr, 0); 423 iph->daddr, 0);
424 } else {
425 skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL;
426 }
416 427
417 return udp_gro_complete(skb, nhoff); 428 return udp_gro_complete(skb, nhoff);
418} 429}
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index a56276996b72..ab889bb16b3c 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -161,9 +161,13 @@ static int udp6_gro_complete(struct sk_buff *skb, int nhoff)
161 const struct ipv6hdr *ipv6h = ipv6_hdr(skb); 161 const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
162 struct udphdr *uh = (struct udphdr *)(skb->data + nhoff); 162 struct udphdr *uh = (struct udphdr *)(skb->data + nhoff);
163 163
164 if (uh->check) 164 if (uh->check) {
165 skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL_CSUM;
165 uh->check = ~udp_v6_check(skb->len - nhoff, &ipv6h->saddr, 166 uh->check = ~udp_v6_check(skb->len - nhoff, &ipv6h->saddr,
166 &ipv6h->daddr, 0); 167 &ipv6h->daddr, 0);
168 } else {
169 skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL;
170 }
167 171
168 return udp_gro_complete(skb, nhoff); 172 return udp_gro_complete(skb, nhoff);
169} 173}