diff options
author | Tom Herbert <therbert@google.com> | 2014-07-13 22:49:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-14 19:12:15 -0400 |
commit | 155e010edbc168f43bb332887c43e8579ee3894a (patch) | |
tree | fe501117127ec38d2ef4402681ff3bc53f245379 /net/ipv4 | |
parent | 85644b4d0c6f7be64dad461057d78a484b45bf5b (diff) |
udp: Move udp_tunnel_segment into udp_offload.c
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/udp.c | 76 | ||||
-rw-r--r-- | net/ipv4/udp_offload.c | 76 |
2 files changed, 76 insertions, 76 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index ac30e106a884..f6dfe525584f 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -2522,79 +2522,3 @@ void __init udp_init(void) | |||
2522 | sysctl_udp_rmem_min = SK_MEM_QUANTUM; | 2522 | sysctl_udp_rmem_min = SK_MEM_QUANTUM; |
2523 | sysctl_udp_wmem_min = SK_MEM_QUANTUM; | 2523 | sysctl_udp_wmem_min = SK_MEM_QUANTUM; |
2524 | } | 2524 | } |
2525 | |||
2526 | struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb, | ||
2527 | netdev_features_t features) | ||
2528 | { | ||
2529 | struct sk_buff *segs = ERR_PTR(-EINVAL); | ||
2530 | u16 mac_offset = skb->mac_header; | ||
2531 | int mac_len = skb->mac_len; | ||
2532 | int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb); | ||
2533 | __be16 protocol = skb->protocol; | ||
2534 | netdev_features_t enc_features; | ||
2535 | int udp_offset, outer_hlen; | ||
2536 | unsigned int oldlen; | ||
2537 | bool need_csum; | ||
2538 | |||
2539 | oldlen = (u16)~skb->len; | ||
2540 | |||
2541 | if (unlikely(!pskb_may_pull(skb, tnl_hlen))) | ||
2542 | goto out; | ||
2543 | |||
2544 | skb->encapsulation = 0; | ||
2545 | __skb_pull(skb, tnl_hlen); | ||
2546 | skb_reset_mac_header(skb); | ||
2547 | skb_set_network_header(skb, skb_inner_network_offset(skb)); | ||
2548 | skb->mac_len = skb_inner_network_offset(skb); | ||
2549 | skb->protocol = htons(ETH_P_TEB); | ||
2550 | |||
2551 | need_csum = !!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM); | ||
2552 | if (need_csum) | ||
2553 | skb->encap_hdr_csum = 1; | ||
2554 | |||
2555 | /* segment inner packet. */ | ||
2556 | enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); | ||
2557 | segs = skb_mac_gso_segment(skb, enc_features); | ||
2558 | if (!segs || IS_ERR(segs)) { | ||
2559 | skb_gso_error_unwind(skb, protocol, tnl_hlen, mac_offset, | ||
2560 | mac_len); | ||
2561 | goto out; | ||
2562 | } | ||
2563 | |||
2564 | outer_hlen = skb_tnl_header_len(skb); | ||
2565 | udp_offset = outer_hlen - tnl_hlen; | ||
2566 | skb = segs; | ||
2567 | do { | ||
2568 | struct udphdr *uh; | ||
2569 | int len; | ||
2570 | |||
2571 | skb_reset_inner_headers(skb); | ||
2572 | skb->encapsulation = 1; | ||
2573 | |||
2574 | skb->mac_len = mac_len; | ||
2575 | |||
2576 | skb_push(skb, outer_hlen); | ||
2577 | skb_reset_mac_header(skb); | ||
2578 | skb_set_network_header(skb, mac_len); | ||
2579 | skb_set_transport_header(skb, udp_offset); | ||
2580 | len = skb->len - udp_offset; | ||
2581 | uh = udp_hdr(skb); | ||
2582 | uh->len = htons(len); | ||
2583 | |||
2584 | if (need_csum) { | ||
2585 | __be32 delta = htonl(oldlen + len); | ||
2586 | |||
2587 | uh->check = ~csum_fold((__force __wsum) | ||
2588 | ((__force u32)uh->check + | ||
2589 | (__force u32)delta)); | ||
2590 | uh->check = gso_make_checksum(skb, ~uh->check); | ||
2591 | |||
2592 | if (uh->check == 0) | ||
2593 | uh->check = CSUM_MANGLED_0; | ||
2594 | } | ||
2595 | |||
2596 | skb->protocol = protocol; | ||
2597 | } while ((skb = skb->next)); | ||
2598 | out: | ||
2599 | return segs; | ||
2600 | } | ||
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 546d2d439dda..4807544d018b 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c | |||
@@ -47,6 +47,82 @@ static int udp4_ufo_send_check(struct sk_buff *skb) | |||
47 | return 0; | 47 | return 0; |
48 | } | 48 | } |
49 | 49 | ||
50 | struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb, | ||
51 | netdev_features_t features) | ||
52 | { | ||
53 | struct sk_buff *segs = ERR_PTR(-EINVAL); | ||
54 | u16 mac_offset = skb->mac_header; | ||
55 | int mac_len = skb->mac_len; | ||
56 | int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb); | ||
57 | __be16 protocol = skb->protocol; | ||
58 | netdev_features_t enc_features; | ||
59 | int udp_offset, outer_hlen; | ||
60 | unsigned int oldlen; | ||
61 | bool need_csum; | ||
62 | |||
63 | oldlen = (u16)~skb->len; | ||
64 | |||
65 | if (unlikely(!pskb_may_pull(skb, tnl_hlen))) | ||
66 | goto out; | ||
67 | |||
68 | skb->encapsulation = 0; | ||
69 | __skb_pull(skb, tnl_hlen); | ||
70 | skb_reset_mac_header(skb); | ||
71 | skb_set_network_header(skb, skb_inner_network_offset(skb)); | ||
72 | skb->mac_len = skb_inner_network_offset(skb); | ||
73 | skb->protocol = htons(ETH_P_TEB); | ||
74 | |||
75 | need_csum = !!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM); | ||
76 | if (need_csum) | ||
77 | skb->encap_hdr_csum = 1; | ||
78 | |||
79 | /* segment inner packet. */ | ||
80 | enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); | ||
81 | segs = skb_mac_gso_segment(skb, enc_features); | ||
82 | if (!segs || IS_ERR(segs)) { | ||
83 | skb_gso_error_unwind(skb, protocol, tnl_hlen, mac_offset, | ||
84 | mac_len); | ||
85 | goto out; | ||
86 | } | ||
87 | |||
88 | outer_hlen = skb_tnl_header_len(skb); | ||
89 | udp_offset = outer_hlen - tnl_hlen; | ||
90 | skb = segs; | ||
91 | do { | ||
92 | struct udphdr *uh; | ||
93 | int len; | ||
94 | |||
95 | skb_reset_inner_headers(skb); | ||
96 | skb->encapsulation = 1; | ||
97 | |||
98 | skb->mac_len = mac_len; | ||
99 | |||
100 | skb_push(skb, outer_hlen); | ||
101 | skb_reset_mac_header(skb); | ||
102 | skb_set_network_header(skb, mac_len); | ||
103 | skb_set_transport_header(skb, udp_offset); | ||
104 | len = skb->len - udp_offset; | ||
105 | uh = udp_hdr(skb); | ||
106 | uh->len = htons(len); | ||
107 | |||
108 | if (need_csum) { | ||
109 | __be32 delta = htonl(oldlen + len); | ||
110 | |||
111 | uh->check = ~csum_fold((__force __wsum) | ||
112 | ((__force u32)uh->check + | ||
113 | (__force u32)delta)); | ||
114 | uh->check = gso_make_checksum(skb, ~uh->check); | ||
115 | |||
116 | if (uh->check == 0) | ||
117 | uh->check = CSUM_MANGLED_0; | ||
118 | } | ||
119 | |||
120 | skb->protocol = protocol; | ||
121 | } while ((skb = skb->next)); | ||
122 | out: | ||
123 | return segs; | ||
124 | } | ||
125 | |||
50 | static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, | 126 | static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, |
51 | netdev_features_t features) | 127 | netdev_features_t features) |
52 | { | 128 | { |