diff options
author | Cong Wang <amwang@redhat.com> | 2013-08-31 01:44:38 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-08-31 22:30:01 -0400 |
commit | eb3c0d83cc78361a28e52e514a7095fdbf771e7e (patch) | |
tree | 78cdcc8781c3e040546e72c49f201ba2659353d0 /net/ipv6 | |
parent | d949d826c09fb65e230f55868ff70dc581ec06fa (diff) |
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>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/udp_offload.c | 56 |
1 files changed, 1 insertions, 55 deletions
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index 7e5e5acc9619..60559511bd9c 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c | |||
@@ -38,60 +38,6 @@ static int udp6_ufo_send_check(struct sk_buff *skb) | |||
38 | return 0; | 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 | static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | 41 | static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, |
96 | netdev_features_t features) | 42 | netdev_features_t features) |
97 | { | 43 | { |
@@ -129,7 +75,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |||
129 | } | 75 | } |
130 | 76 | ||
131 | if (skb->encapsulation && skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) | 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 | else { | 79 | else { |
134 | /* Do software UFO. Complete and fill in the UDP checksum as HW cannot | 80 | /* Do software UFO. Complete and fill in the UDP checksum as HW cannot |
135 | * do checksum of UDP packets sent as multiple IP fragments. | 81 | * do checksum of UDP packets sent as multiple IP fragments. |