diff options
author | David S. Miller <davem@davemloft.net> | 2013-10-19 19:37:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-19 19:37:06 -0400 |
commit | 53481da372851a5506deb5247302f75459b472b4 (patch) | |
tree | f56596d0aa56f97a2a54cd18749805ae2c4becc8 /net | |
parent | b917eb155c56bbb766140b406979820e719e3f55 (diff) | |
parent | 117401ee1df6517203454637fbc3e7e660ce45f6 (diff) |
Merge branch 'ipip_gso'
Eric Dumazet says:
====================
net: Implement GSO/TSO support for IPIP
This patch serie implements GSO/TSO support for IPIP
David, please note it applies after "ipv4: gso: send_check() & segment() cleanups"
( http://patchwork.ozlabs.org/patch/284714/ )
Broadcom bnx2x driver is now enabled for TSO support of IPIP traffic
Before patch :
lpq83:~# ./netperf -H 7.7.9.84 -Cc
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.9.84 () port 0 AF_INET
Recv Send Send Utilization Service Demand
Socket Socket Message Elapsed Send Recv Send Recv
Size Size Size Time Throughput local remote local remote
bytes bytes bytes secs. 10^6bits/s % S % S us/KB us/KB
87380 16384 16384 10.00 3357.88 5.09 3.70 2.983 2.167
After patch :
lpq83:~# ./netperf -H 7.7.9.84 -Cc
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.9.84 () port 0 AF_INET
Recv Send Send Utilization Service Demand
Socket Socket Message Elapsed Send Recv Send Recv
Size Size Size Time Throughput local remote local remote
bytes bytes bytes secs. 10^6bits/s % S % S us/KB us/KB
87380 16384 16384 10.00 8532.40 2.55 7.73 0.588 1.781
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 2 | ||||
-rw-r--r-- | net/core/ethtool.c | 1 | ||||
-rw-r--r-- | net/core/skbuff.c | 22 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 34 | ||||
-rw-r--r-- | net/ipv4/gre_demux.c | 29 | ||||
-rw-r--r-- | net/ipv4/gre_offload.c | 3 | ||||
-rw-r--r-- | net/ipv4/ip_tunnel_core.c | 33 | ||||
-rw-r--r-- | net/ipv4/ipip.c | 11 | ||||
-rw-r--r-- | net/ipv4/tcp_offload.c | 1 | ||||
-rw-r--r-- | net/ipv4/udp_offload.c | 1 | ||||
-rw-r--r-- | net/ipv6/ip6_offload.c | 1 | ||||
-rw-r--r-- | net/ipv6/udp_offload.c | 1 | ||||
-rw-r--r-- | net/mpls/mpls_gso.c | 1 |
13 files changed, 81 insertions, 59 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 1b6eadf69289..0918aadc20fd 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2377,6 +2377,8 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb, | |||
2377 | } | 2377 | } |
2378 | 2378 | ||
2379 | SKB_GSO_CB(skb)->mac_offset = skb_headroom(skb); | 2379 | SKB_GSO_CB(skb)->mac_offset = skb_headroom(skb); |
2380 | SKB_GSO_CB(skb)->encap_level = 0; | ||
2381 | |||
2380 | skb_reset_mac_header(skb); | 2382 | skb_reset_mac_header(skb); |
2381 | skb_reset_mac_len(skb); | 2383 | skb_reset_mac_len(skb); |
2382 | 2384 | ||
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 78e9d9223e40..8cab7744790e 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -81,6 +81,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] | |||
81 | [NETIF_F_TSO6_BIT] = "tx-tcp6-segmentation", | 81 | [NETIF_F_TSO6_BIT] = "tx-tcp6-segmentation", |
82 | [NETIF_F_FSO_BIT] = "tx-fcoe-segmentation", | 82 | [NETIF_F_FSO_BIT] = "tx-fcoe-segmentation", |
83 | [NETIF_F_GSO_GRE_BIT] = "tx-gre-segmentation", | 83 | [NETIF_F_GSO_GRE_BIT] = "tx-gre-segmentation", |
84 | [NETIF_F_GSO_IPIP_BIT] = "tx-ipip-segmentation", | ||
84 | [NETIF_F_GSO_UDP_TUNNEL_BIT] = "tx-udp_tnl-segmentation", | 85 | [NETIF_F_GSO_UDP_TUNNEL_BIT] = "tx-udp_tnl-segmentation", |
85 | [NETIF_F_GSO_MPLS_BIT] = "tx-mpls-segmentation", | 86 | [NETIF_F_GSO_MPLS_BIT] = "tx-mpls-segmentation", |
86 | 87 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 8ead744fcc94..0ab32faa520f 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -903,6 +903,9 @@ EXPORT_SYMBOL(skb_clone); | |||
903 | 903 | ||
904 | static void skb_headers_offset_update(struct sk_buff *skb, int off) | 904 | static void skb_headers_offset_update(struct sk_buff *skb, int off) |
905 | { | 905 | { |
906 | /* Only adjust this if it actually is csum_start rather than csum */ | ||
907 | if (skb->ip_summed == CHECKSUM_PARTIAL) | ||
908 | skb->csum_start += off; | ||
906 | /* {transport,network,mac}_header and tail are relative to skb->head */ | 909 | /* {transport,network,mac}_header and tail are relative to skb->head */ |
907 | skb->transport_header += off; | 910 | skb->transport_header += off; |
908 | skb->network_header += off; | 911 | skb->network_header += off; |
@@ -1109,9 +1112,6 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
1109 | #endif | 1112 | #endif |
1110 | skb->tail += off; | 1113 | skb->tail += off; |
1111 | skb_headers_offset_update(skb, nhead); | 1114 | skb_headers_offset_update(skb, nhead); |
1112 | /* Only adjust this if it actually is csum_start rather than csum */ | ||
1113 | if (skb->ip_summed == CHECKSUM_PARTIAL) | ||
1114 | skb->csum_start += nhead; | ||
1115 | skb->cloned = 0; | 1115 | skb->cloned = 0; |
1116 | skb->hdr_len = 0; | 1116 | skb->hdr_len = 0; |
1117 | skb->nohdr = 0; | 1117 | skb->nohdr = 0; |
@@ -1176,7 +1176,6 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, | |||
1176 | NUMA_NO_NODE); | 1176 | NUMA_NO_NODE); |
1177 | int oldheadroom = skb_headroom(skb); | 1177 | int oldheadroom = skb_headroom(skb); |
1178 | int head_copy_len, head_copy_off; | 1178 | int head_copy_len, head_copy_off; |
1179 | int off; | ||
1180 | 1179 | ||
1181 | if (!n) | 1180 | if (!n) |
1182 | return NULL; | 1181 | return NULL; |
@@ -1200,11 +1199,7 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, | |||
1200 | 1199 | ||
1201 | copy_skb_header(n, skb); | 1200 | copy_skb_header(n, skb); |
1202 | 1201 | ||
1203 | off = newheadroom - oldheadroom; | 1202 | skb_headers_offset_update(n, newheadroom - oldheadroom); |
1204 | if (n->ip_summed == CHECKSUM_PARTIAL) | ||
1205 | n->csum_start += off; | ||
1206 | |||
1207 | skb_headers_offset_update(n, off); | ||
1208 | 1203 | ||
1209 | return n; | 1204 | return n; |
1210 | } | 1205 | } |
@@ -2837,14 +2832,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
2837 | __copy_skb_header(nskb, skb); | 2832 | __copy_skb_header(nskb, skb); |
2838 | nskb->mac_len = skb->mac_len; | 2833 | nskb->mac_len = skb->mac_len; |
2839 | 2834 | ||
2840 | /* nskb and skb might have different headroom */ | 2835 | skb_headers_offset_update(nskb, skb_headroom(nskb) - headroom); |
2841 | if (nskb->ip_summed == CHECKSUM_PARTIAL) | ||
2842 | nskb->csum_start += skb_headroom(nskb) - headroom; | ||
2843 | |||
2844 | skb_reset_mac_header(nskb); | ||
2845 | skb_set_network_header(nskb, skb->mac_len); | ||
2846 | nskb->transport_header = (nskb->network_header + | ||
2847 | skb_network_header_len(skb)); | ||
2848 | 2836 | ||
2849 | skb_copy_from_linear_data_offset(skb, -tnl_hlen, | 2837 | skb_copy_from_linear_data_offset(skb, -tnl_hlen, |
2850 | nskb->data - tnl_hlen, | 2838 | nskb->data - tnl_hlen, |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 4f8cd4fc451d..4049906010f7 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1273,16 +1273,17 @@ out: | |||
1273 | } | 1273 | } |
1274 | 1274 | ||
1275 | static struct sk_buff *inet_gso_segment(struct sk_buff *skb, | 1275 | static struct sk_buff *inet_gso_segment(struct sk_buff *skb, |
1276 | netdev_features_t features) | 1276 | netdev_features_t features) |
1277 | { | 1277 | { |
1278 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 1278 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
1279 | const struct net_offload *ops; | 1279 | const struct net_offload *ops; |
1280 | unsigned int offset = 0; | ||
1280 | struct iphdr *iph; | 1281 | struct iphdr *iph; |
1282 | bool tunnel; | ||
1281 | int proto; | 1283 | int proto; |
1284 | int nhoff; | ||
1282 | int ihl; | 1285 | int ihl; |
1283 | int id; | 1286 | int id; |
1284 | unsigned int offset = 0; | ||
1285 | bool tunnel; | ||
1286 | 1287 | ||
1287 | if (unlikely(skb_shinfo(skb)->gso_type & | 1288 | if (unlikely(skb_shinfo(skb)->gso_type & |
1288 | ~(SKB_GSO_TCPV4 | | 1289 | ~(SKB_GSO_TCPV4 | |
@@ -1290,12 +1291,15 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, | |||
1290 | SKB_GSO_DODGY | | 1291 | SKB_GSO_DODGY | |
1291 | SKB_GSO_TCP_ECN | | 1292 | SKB_GSO_TCP_ECN | |
1292 | SKB_GSO_GRE | | 1293 | SKB_GSO_GRE | |
1294 | SKB_GSO_IPIP | | ||
1293 | SKB_GSO_TCPV6 | | 1295 | SKB_GSO_TCPV6 | |
1294 | SKB_GSO_UDP_TUNNEL | | 1296 | SKB_GSO_UDP_TUNNEL | |
1295 | SKB_GSO_MPLS | | 1297 | SKB_GSO_MPLS | |
1296 | 0))) | 1298 | 0))) |
1297 | goto out; | 1299 | goto out; |
1298 | 1300 | ||
1301 | skb_reset_network_header(skb); | ||
1302 | nhoff = skb_network_header(skb) - skb_mac_header(skb); | ||
1299 | if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) | 1303 | if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) |
1300 | goto out; | 1304 | goto out; |
1301 | 1305 | ||
@@ -1312,7 +1316,10 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, | |||
1312 | goto out; | 1316 | goto out; |
1313 | __skb_pull(skb, ihl); | 1317 | __skb_pull(skb, ihl); |
1314 | 1318 | ||
1315 | tunnel = !!skb->encapsulation; | 1319 | tunnel = SKB_GSO_CB(skb)->encap_level > 0; |
1320 | if (tunnel) | ||
1321 | features = skb->dev->hw_enc_features & netif_skb_features(skb); | ||
1322 | SKB_GSO_CB(skb)->encap_level += ihl; | ||
1316 | 1323 | ||
1317 | skb_reset_transport_header(skb); | 1324 | skb_reset_transport_header(skb); |
1318 | 1325 | ||
@@ -1327,18 +1334,23 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, | |||
1327 | 1334 | ||
1328 | skb = segs; | 1335 | skb = segs; |
1329 | do { | 1336 | do { |
1330 | iph = ip_hdr(skb); | 1337 | iph = (struct iphdr *)(skb_mac_header(skb) + nhoff); |
1331 | if (!tunnel && proto == IPPROTO_UDP) { | 1338 | if (!tunnel && proto == IPPROTO_UDP) { |
1332 | iph->id = htons(id); | 1339 | iph->id = htons(id); |
1333 | iph->frag_off = htons(offset >> 3); | 1340 | iph->frag_off = htons(offset >> 3); |
1334 | if (skb->next != NULL) | 1341 | if (skb->next != NULL) |
1335 | iph->frag_off |= htons(IP_MF); | 1342 | iph->frag_off |= htons(IP_MF); |
1336 | offset += (skb->len - skb->mac_len - iph->ihl * 4); | 1343 | offset += skb->len - nhoff - ihl; |
1337 | } else { | 1344 | } else { |
1338 | iph->id = htons(id++); | 1345 | iph->id = htons(id++); |
1339 | } | 1346 | } |
1340 | iph->tot_len = htons(skb->len - skb->mac_len); | 1347 | iph->tot_len = htons(skb->len - nhoff); |
1341 | ip_send_check(iph); | 1348 | ip_send_check(iph); |
1349 | if (tunnel) { | ||
1350 | skb_reset_inner_headers(skb); | ||
1351 | skb->encapsulation = 1; | ||
1352 | } | ||
1353 | skb->network_header = (u8 *)iph - skb->head; | ||
1342 | } while ((skb = skb->next)); | 1354 | } while ((skb = skb->next)); |
1343 | 1355 | ||
1344 | out: | 1356 | out: |
@@ -1645,6 +1657,13 @@ static struct packet_offload ip_packet_offload __read_mostly = { | |||
1645 | }, | 1657 | }, |
1646 | }; | 1658 | }; |
1647 | 1659 | ||
1660 | static const struct net_offload ipip_offload = { | ||
1661 | .callbacks = { | ||
1662 | .gso_send_check = inet_gso_send_check, | ||
1663 | .gso_segment = inet_gso_segment, | ||
1664 | }, | ||
1665 | }; | ||
1666 | |||
1648 | static int __init ipv4_offload_init(void) | 1667 | static int __init ipv4_offload_init(void) |
1649 | { | 1668 | { |
1650 | /* | 1669 | /* |
@@ -1656,6 +1675,7 @@ static int __init ipv4_offload_init(void) | |||
1656 | pr_crit("%s: Cannot add TCP protocol offload\n", __func__); | 1675 | pr_crit("%s: Cannot add TCP protocol offload\n", __func__); |
1657 | 1676 | ||
1658 | dev_add_offload(&ip_packet_offload); | 1677 | dev_add_offload(&ip_packet_offload); |
1678 | inet_add_offload(&ipip_offload, IPPROTO_IPIP); | ||
1659 | return 0; | 1679 | return 0; |
1660 | } | 1680 | } |
1661 | 1681 | ||
diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c index 736c9fc3ef93..5893e99e8299 100644 --- a/net/ipv4/gre_demux.c +++ b/net/ipv4/gre_demux.c | |||
@@ -93,35 +93,6 @@ void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi, | |||
93 | } | 93 | } |
94 | EXPORT_SYMBOL_GPL(gre_build_header); | 94 | EXPORT_SYMBOL_GPL(gre_build_header); |
95 | 95 | ||
96 | struct sk_buff *gre_handle_offloads(struct sk_buff *skb, bool gre_csum) | ||
97 | { | ||
98 | int err; | ||
99 | |||
100 | if (likely(!skb->encapsulation)) { | ||
101 | skb_reset_inner_headers(skb); | ||
102 | skb->encapsulation = 1; | ||
103 | } | ||
104 | |||
105 | if (skb_is_gso(skb)) { | ||
106 | err = skb_unclone(skb, GFP_ATOMIC); | ||
107 | if (unlikely(err)) | ||
108 | goto error; | ||
109 | skb_shinfo(skb)->gso_type |= SKB_GSO_GRE; | ||
110 | return skb; | ||
111 | } else if (skb->ip_summed == CHECKSUM_PARTIAL && gre_csum) { | ||
112 | err = skb_checksum_help(skb); | ||
113 | if (unlikely(err)) | ||
114 | goto error; | ||
115 | } else if (skb->ip_summed != CHECKSUM_PARTIAL) | ||
116 | skb->ip_summed = CHECKSUM_NONE; | ||
117 | |||
118 | return skb; | ||
119 | error: | ||
120 | kfree_skb(skb); | ||
121 | return ERR_PTR(err); | ||
122 | } | ||
123 | EXPORT_SYMBOL_GPL(gre_handle_offloads); | ||
124 | |||
125 | static __sum16 check_checksum(struct sk_buff *skb) | 96 | static __sum16 check_checksum(struct sk_buff *skb) |
126 | { | 97 | { |
127 | __sum16 csum = 0; | 98 | __sum16 csum = 0; |
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c index 55e6bfb3a289..e5d436188464 100644 --- a/net/ipv4/gre_offload.c +++ b/net/ipv4/gre_offload.c | |||
@@ -39,7 +39,8 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, | |||
39 | SKB_GSO_UDP | | 39 | SKB_GSO_UDP | |
40 | SKB_GSO_DODGY | | 40 | SKB_GSO_DODGY | |
41 | SKB_GSO_TCP_ECN | | 41 | SKB_GSO_TCP_ECN | |
42 | SKB_GSO_GRE))) | 42 | SKB_GSO_GRE | |
43 | SKB_GSO_IPIP))) | ||
43 | goto out; | 44 | goto out; |
44 | 45 | ||
45 | if (unlikely(!pskb_may_pull(skb, sizeof(*greh)))) | 46 | if (unlikely(!pskb_may_pull(skb, sizeof(*greh)))) |
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index c31e3ad98ef2..42ffbc8d65c6 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c | |||
@@ -116,3 +116,36 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto) | |||
116 | return 0; | 116 | return 0; |
117 | } | 117 | } |
118 | EXPORT_SYMBOL_GPL(iptunnel_pull_header); | 118 | EXPORT_SYMBOL_GPL(iptunnel_pull_header); |
119 | |||
120 | struct sk_buff *iptunnel_handle_offloads(struct sk_buff *skb, | ||
121 | bool csum_help, | ||
122 | int gso_type_mask) | ||
123 | { | ||
124 | int err; | ||
125 | |||
126 | if (likely(!skb->encapsulation)) { | ||
127 | skb_reset_inner_headers(skb); | ||
128 | skb->encapsulation = 1; | ||
129 | } | ||
130 | |||
131 | if (skb_is_gso(skb)) { | ||
132 | err = skb_unclone(skb, GFP_ATOMIC); | ||
133 | if (unlikely(err)) | ||
134 | goto error; | ||
135 | skb_shinfo(skb)->gso_type |= gso_type_mask; | ||
136 | return skb; | ||
137 | } | ||
138 | |||
139 | if (skb->ip_summed == CHECKSUM_PARTIAL && csum_help) { | ||
140 | err = skb_checksum_help(skb); | ||
141 | if (unlikely(err)) | ||
142 | goto error; | ||
143 | } else if (skb->ip_summed != CHECKSUM_PARTIAL) | ||
144 | skb->ip_summed = CHECKSUM_NONE; | ||
145 | |||
146 | return skb; | ||
147 | error: | ||
148 | kfree_skb(skb); | ||
149 | return ERR_PTR(err); | ||
150 | } | ||
151 | EXPORT_SYMBOL_GPL(iptunnel_handle_offloads); | ||
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 7f80fb4b82d3..fe3e9f7f1f0b 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -220,17 +220,17 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
220 | if (unlikely(skb->protocol != htons(ETH_P_IP))) | 220 | if (unlikely(skb->protocol != htons(ETH_P_IP))) |
221 | goto tx_error; | 221 | goto tx_error; |
222 | 222 | ||
223 | if (likely(!skb->encapsulation)) { | 223 | skb = iptunnel_handle_offloads(skb, false, SKB_GSO_IPIP); |
224 | skb_reset_inner_headers(skb); | 224 | if (IS_ERR(skb)) |
225 | skb->encapsulation = 1; | 225 | goto out; |
226 | } | ||
227 | 226 | ||
228 | ip_tunnel_xmit(skb, dev, tiph, tiph->protocol); | 227 | ip_tunnel_xmit(skb, dev, tiph, tiph->protocol); |
229 | return NETDEV_TX_OK; | 228 | return NETDEV_TX_OK; |
230 | 229 | ||
231 | tx_error: | 230 | tx_error: |
232 | dev->stats.tx_errors++; | ||
233 | dev_kfree_skb(skb); | 231 | dev_kfree_skb(skb); |
232 | out: | ||
233 | dev->stats.tx_errors++; | ||
234 | return NETDEV_TX_OK; | 234 | return NETDEV_TX_OK; |
235 | } | 235 | } |
236 | 236 | ||
@@ -275,6 +275,7 @@ static const struct net_device_ops ipip_netdev_ops = { | |||
275 | #define IPIP_FEATURES (NETIF_F_SG | \ | 275 | #define IPIP_FEATURES (NETIF_F_SG | \ |
276 | NETIF_F_FRAGLIST | \ | 276 | NETIF_F_FRAGLIST | \ |
277 | NETIF_F_HIGHDMA | \ | 277 | NETIF_F_HIGHDMA | \ |
278 | NETIF_F_GSO_SOFTWARE | \ | ||
278 | NETIF_F_HW_CSUM) | 279 | NETIF_F_HW_CSUM) |
279 | 280 | ||
280 | static void ipip_tunnel_setup(struct net_device *dev) | 281 | static void ipip_tunnel_setup(struct net_device *dev) |
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c index 8e3113f46ec1..dfc96b00673e 100644 --- a/net/ipv4/tcp_offload.c +++ b/net/ipv4/tcp_offload.c | |||
@@ -56,6 +56,7 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb, | |||
56 | SKB_GSO_TCP_ECN | | 56 | SKB_GSO_TCP_ECN | |
57 | SKB_GSO_TCPV6 | | 57 | SKB_GSO_TCPV6 | |
58 | SKB_GSO_GRE | | 58 | SKB_GSO_GRE | |
59 | SKB_GSO_IPIP | | ||
59 | SKB_GSO_MPLS | | 60 | SKB_GSO_MPLS | |
60 | SKB_GSO_UDP_TUNNEL | | 61 | SKB_GSO_UDP_TUNNEL | |
61 | 0) || | 62 | 0) || |
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index f35eccaa855e..83206de2bc76 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c | |||
@@ -52,6 +52,7 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, | |||
52 | 52 | ||
53 | if (unlikely(type & ~(SKB_GSO_UDP | SKB_GSO_DODGY | | 53 | if (unlikely(type & ~(SKB_GSO_UDP | SKB_GSO_DODGY | |
54 | SKB_GSO_UDP_TUNNEL | | 54 | SKB_GSO_UDP_TUNNEL | |
55 | SKB_GSO_IPIP | | ||
55 | SKB_GSO_GRE | SKB_GSO_MPLS) || | 56 | SKB_GSO_GRE | SKB_GSO_MPLS) || |
56 | !(type & (SKB_GSO_UDP)))) | 57 | !(type & (SKB_GSO_UDP)))) |
57 | goto out; | 58 | goto out; |
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index b405fba91c72..5c2fc1d04196 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c | |||
@@ -96,6 +96,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
96 | SKB_GSO_DODGY | | 96 | SKB_GSO_DODGY | |
97 | SKB_GSO_TCP_ECN | | 97 | SKB_GSO_TCP_ECN | |
98 | SKB_GSO_GRE | | 98 | SKB_GSO_GRE | |
99 | SKB_GSO_IPIP | | ||
99 | SKB_GSO_UDP_TUNNEL | | 100 | SKB_GSO_UDP_TUNNEL | |
100 | SKB_GSO_MPLS | | 101 | SKB_GSO_MPLS | |
101 | SKB_GSO_TCPV6 | | 102 | SKB_GSO_TCPV6 | |
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index 60559511bd9c..f63780ff3732 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c | |||
@@ -64,6 +64,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |||
64 | SKB_GSO_DODGY | | 64 | SKB_GSO_DODGY | |
65 | SKB_GSO_UDP_TUNNEL | | 65 | SKB_GSO_UDP_TUNNEL | |
66 | SKB_GSO_GRE | | 66 | SKB_GSO_GRE | |
67 | SKB_GSO_IPIP | | ||
67 | SKB_GSO_MPLS) || | 68 | SKB_GSO_MPLS) || |
68 | !(type & (SKB_GSO_UDP)))) | 69 | !(type & (SKB_GSO_UDP)))) |
69 | goto out; | 70 | goto out; |
diff --git a/net/mpls/mpls_gso.c b/net/mpls/mpls_gso.c index 1bec1219ab81..851cd880b0c0 100644 --- a/net/mpls/mpls_gso.c +++ b/net/mpls/mpls_gso.c | |||
@@ -33,6 +33,7 @@ static struct sk_buff *mpls_gso_segment(struct sk_buff *skb, | |||
33 | SKB_GSO_DODGY | | 33 | SKB_GSO_DODGY | |
34 | SKB_GSO_TCP_ECN | | 34 | SKB_GSO_TCP_ECN | |
35 | SKB_GSO_GRE | | 35 | SKB_GSO_GRE | |
36 | SKB_GSO_IPIP | | ||
36 | SKB_GSO_MPLS))) | 37 | SKB_GSO_MPLS))) |
37 | goto out; | 38 | goto out; |
38 | 39 | ||