Commit eb3c0d83cc78361a28e52e514a7095fdbf771e7e
Committed by
David S. Miller
1 parent
d949d826c0
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
net: unify skb_udp_tunnel_segment() and skb_udp6_tunnel_segment()
As suggested by Pravin, we can unify the code in case of duplicated code. Cc: Pravin Shelar <pshelar@nicira.com> Signed-off-by: Cong Wang <amwang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 2 changed files with 13 additions and 56 deletions Side-by-side Diff
net/ipv4/udp.c
... | ... | @@ -2337,7 +2337,7 @@ |
2337 | 2337 | uh->len = htons(skb->len - udp_offset); |
2338 | 2338 | |
2339 | 2339 | /* csum segment if tunnel sets skb with csum. */ |
2340 | - if (unlikely(uh->check)) { | |
2340 | + if (protocol == htons(ETH_P_IP) && unlikely(uh->check)) { | |
2341 | 2341 | struct iphdr *iph = ip_hdr(skb); |
2342 | 2342 | |
2343 | 2343 | uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, |
2344 | 2344 | |
... | ... | @@ -2348,7 +2348,18 @@ |
2348 | 2348 | if (uh->check == 0) |
2349 | 2349 | uh->check = CSUM_MANGLED_0; |
2350 | 2350 | |
2351 | + } else if (protocol == htons(ETH_P_IPV6)) { | |
2352 | + struct ipv6hdr *ipv6h = ipv6_hdr(skb); | |
2353 | + u32 len = skb->len - udp_offset; | |
2354 | + | |
2355 | + uh->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, | |
2356 | + len, IPPROTO_UDP, 0); | |
2357 | + uh->check = csum_fold(skb_checksum(skb, udp_offset, len, 0)); | |
2358 | + if (uh->check == 0) | |
2359 | + uh->check = CSUM_MANGLED_0; | |
2360 | + skb->ip_summed = CHECKSUM_NONE; | |
2351 | 2361 | } |
2362 | + | |
2352 | 2363 | skb->protocol = protocol; |
2353 | 2364 | } while ((skb = skb->next)); |
2354 | 2365 | out: |
net/ipv6/udp_offload.c
... | ... | @@ -38,60 +38,6 @@ |
38 | 38 | return 0; |
39 | 39 | } |
40 | 40 | |
41 | -static struct sk_buff *skb_udp6_tunnel_segment(struct sk_buff *skb, | |
42 | - netdev_features_t features) | |
43 | -{ | |
44 | - struct sk_buff *segs = ERR_PTR(-EINVAL); | |
45 | - int mac_len = skb->mac_len; | |
46 | - int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb); | |
47 | - int outer_hlen; | |
48 | - netdev_features_t enc_features; | |
49 | - | |
50 | - if (unlikely(!pskb_may_pull(skb, tnl_hlen))) | |
51 | - goto out; | |
52 | - | |
53 | - skb->encapsulation = 0; | |
54 | - __skb_pull(skb, tnl_hlen); | |
55 | - skb_reset_mac_header(skb); | |
56 | - skb_set_network_header(skb, skb_inner_network_offset(skb)); | |
57 | - skb->mac_len = skb_inner_network_offset(skb); | |
58 | - | |
59 | - /* segment inner packet. */ | |
60 | - enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); | |
61 | - segs = skb_mac_gso_segment(skb, enc_features); | |
62 | - if (!segs || IS_ERR(segs)) | |
63 | - goto out; | |
64 | - | |
65 | - outer_hlen = skb_tnl_header_len(skb); | |
66 | - skb = segs; | |
67 | - do { | |
68 | - struct udphdr *uh; | |
69 | - struct ipv6hdr *ipv6h; | |
70 | - int udp_offset = outer_hlen - tnl_hlen; | |
71 | - u32 len; | |
72 | - | |
73 | - skb->mac_len = mac_len; | |
74 | - | |
75 | - skb_push(skb, outer_hlen); | |
76 | - skb_reset_mac_header(skb); | |
77 | - skb_set_network_header(skb, mac_len); | |
78 | - skb_set_transport_header(skb, udp_offset); | |
79 | - uh = udp_hdr(skb); | |
80 | - uh->len = htons(skb->len - udp_offset); | |
81 | - ipv6h = ipv6_hdr(skb); | |
82 | - len = skb->len - udp_offset; | |
83 | - | |
84 | - uh->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, | |
85 | - len, IPPROTO_UDP, 0); | |
86 | - uh->check = csum_fold(skb_checksum(skb, udp_offset, len, 0)); | |
87 | - if (uh->check == 0) | |
88 | - uh->check = CSUM_MANGLED_0; | |
89 | - skb->ip_summed = CHECKSUM_NONE; | |
90 | - } while ((skb = skb->next)); | |
91 | -out: | |
92 | - return segs; | |
93 | -} | |
94 | - | |
95 | 41 | static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, |
96 | 42 | netdev_features_t features) |
97 | 43 | { |
... | ... | @@ -129,7 +75,7 @@ |
129 | 75 | } |
130 | 76 | |
131 | 77 | if (skb->encapsulation && skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) |
132 | - segs = skb_udp6_tunnel_segment(skb, features); | |
78 | + segs = skb_udp_tunnel_segment(skb, features); | |
133 | 79 | else { |
134 | 80 | /* Do software UFO. Complete and fill in the UDP checksum as HW cannot |
135 | 81 | * do checksum of UDP packets sent as multiple IP fragments. |