Commit eb3c0d83cc78361a28e52e514a7095fdbf771e7e

Authored by Cong Wang
Committed by David S. Miller
1 parent d949d826c0

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

... ... @@ -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.