diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 63 | ||||
-rw-r--r-- | net/decnet/dn_nsp_in.c | 3 | ||||
-rw-r--r-- | net/decnet/dn_route.c | 3 | ||||
-rw-r--r-- | net/ipv4/ipcomp.c | 11 | ||||
-rw-r--r-- | net/ipv6/ipcomp6.c | 11 |
5 files changed, 10 insertions, 81 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 1b09f1cae46e..91361bc2b682 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1222,64 +1222,6 @@ static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb) | |||
1222 | #define illegal_highdma(dev, skb) (0) | 1222 | #define illegal_highdma(dev, skb) (0) |
1223 | #endif | 1223 | #endif |
1224 | 1224 | ||
1225 | /* Keep head the same: replace data */ | ||
1226 | int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask) | ||
1227 | { | ||
1228 | unsigned int size; | ||
1229 | u8 *data; | ||
1230 | long offset; | ||
1231 | struct skb_shared_info *ninfo; | ||
1232 | int headerlen = skb->data - skb->head; | ||
1233 | int expand = (skb->tail + skb->data_len) - skb->end; | ||
1234 | |||
1235 | if (skb_shared(skb)) | ||
1236 | BUG(); | ||
1237 | |||
1238 | if (expand <= 0) | ||
1239 | expand = 0; | ||
1240 | |||
1241 | size = skb->end - skb->head + expand; | ||
1242 | size = SKB_DATA_ALIGN(size); | ||
1243 | data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); | ||
1244 | if (!data) | ||
1245 | return -ENOMEM; | ||
1246 | |||
1247 | /* Copy entire thing */ | ||
1248 | if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len)) | ||
1249 | BUG(); | ||
1250 | |||
1251 | /* Set up shinfo */ | ||
1252 | ninfo = (struct skb_shared_info*)(data + size); | ||
1253 | atomic_set(&ninfo->dataref, 1); | ||
1254 | ninfo->tso_size = skb_shinfo(skb)->tso_size; | ||
1255 | ninfo->tso_segs = skb_shinfo(skb)->tso_segs; | ||
1256 | ninfo->nr_frags = 0; | ||
1257 | ninfo->frag_list = NULL; | ||
1258 | |||
1259 | /* Offset between the two in bytes */ | ||
1260 | offset = data - skb->head; | ||
1261 | |||
1262 | /* Free old data. */ | ||
1263 | skb_release_data(skb); | ||
1264 | |||
1265 | skb->head = data; | ||
1266 | skb->end = data + size; | ||
1267 | |||
1268 | /* Set up new pointers */ | ||
1269 | skb->h.raw += offset; | ||
1270 | skb->nh.raw += offset; | ||
1271 | skb->mac.raw += offset; | ||
1272 | skb->tail += offset; | ||
1273 | skb->data += offset; | ||
1274 | |||
1275 | /* We are no longer a clone, even if we were. */ | ||
1276 | skb->cloned = 0; | ||
1277 | |||
1278 | skb->tail += skb->data_len; | ||
1279 | skb->data_len = 0; | ||
1280 | return 0; | ||
1281 | } | ||
1282 | |||
1283 | #define HARD_TX_LOCK(dev, cpu) { \ | 1225 | #define HARD_TX_LOCK(dev, cpu) { \ |
1284 | if ((dev->features & NETIF_F_LLTX) == 0) { \ | 1226 | if ((dev->features & NETIF_F_LLTX) == 0) { \ |
1285 | netif_tx_lock(dev); \ | 1227 | netif_tx_lock(dev); \ |
@@ -1326,7 +1268,7 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
1326 | 1268 | ||
1327 | if (skb_shinfo(skb)->frag_list && | 1269 | if (skb_shinfo(skb)->frag_list && |
1328 | !(dev->features & NETIF_F_FRAGLIST) && | 1270 | !(dev->features & NETIF_F_FRAGLIST) && |
1329 | __skb_linearize(skb, GFP_ATOMIC)) | 1271 | __skb_linearize(skb)) |
1330 | goto out_kfree_skb; | 1272 | goto out_kfree_skb; |
1331 | 1273 | ||
1332 | /* Fragmented skb is linearized if device does not support SG, | 1274 | /* Fragmented skb is linearized if device does not support SG, |
@@ -1335,7 +1277,7 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
1335 | */ | 1277 | */ |
1336 | if (skb_shinfo(skb)->nr_frags && | 1278 | if (skb_shinfo(skb)->nr_frags && |
1337 | (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) && | 1279 | (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) && |
1338 | __skb_linearize(skb, GFP_ATOMIC)) | 1280 | __skb_linearize(skb)) |
1339 | goto out_kfree_skb; | 1281 | goto out_kfree_skb; |
1340 | 1282 | ||
1341 | /* If packet is not checksummed and device does not support | 1283 | /* If packet is not checksummed and device does not support |
@@ -3473,7 +3415,6 @@ subsys_initcall(net_dev_init); | |||
3473 | EXPORT_SYMBOL(__dev_get_by_index); | 3415 | EXPORT_SYMBOL(__dev_get_by_index); |
3474 | EXPORT_SYMBOL(__dev_get_by_name); | 3416 | EXPORT_SYMBOL(__dev_get_by_name); |
3475 | EXPORT_SYMBOL(__dev_remove_pack); | 3417 | EXPORT_SYMBOL(__dev_remove_pack); |
3476 | EXPORT_SYMBOL(__skb_linearize); | ||
3477 | EXPORT_SYMBOL(dev_valid_name); | 3418 | EXPORT_SYMBOL(dev_valid_name); |
3478 | EXPORT_SYMBOL(dev_add_pack); | 3419 | EXPORT_SYMBOL(dev_add_pack); |
3479 | EXPORT_SYMBOL(dev_alloc_name); | 3420 | EXPORT_SYMBOL(dev_alloc_name); |
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c index 547523b41c81..a2ba9db1c376 100644 --- a/net/decnet/dn_nsp_in.c +++ b/net/decnet/dn_nsp_in.c | |||
@@ -801,8 +801,7 @@ got_it: | |||
801 | * We linearize everything except data segments here. | 801 | * We linearize everything except data segments here. |
802 | */ | 802 | */ |
803 | if (cb->nsp_flags & ~0x60) { | 803 | if (cb->nsp_flags & ~0x60) { |
804 | if (unlikely(skb_is_nonlinear(skb)) && | 804 | if (unlikely(skb_linearize(skb))) |
805 | skb_linearize(skb, GFP_ATOMIC) != 0) | ||
806 | goto free_out; | 805 | goto free_out; |
807 | } | 806 | } |
808 | 807 | ||
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index e172cf98d7fc..5abf7057af00 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
@@ -629,8 +629,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type | |||
629 | padlen); | 629 | padlen); |
630 | 630 | ||
631 | if (flags & DN_RT_PKT_CNTL) { | 631 | if (flags & DN_RT_PKT_CNTL) { |
632 | if (unlikely(skb_is_nonlinear(skb)) && | 632 | if (unlikely(skb_linearize(skb))) |
633 | skb_linearize(skb, GFP_ATOMIC) != 0) | ||
634 | goto dump_it; | 633 | goto dump_it; |
635 | 634 | ||
636 | switch(flags & DN_RT_CNTL_MSK) { | 635 | switch(flags & DN_RT_CNTL_MSK) { |
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 8e243589045f..3ed8b57a1002 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
@@ -80,15 +80,12 @@ out: | |||
80 | 80 | ||
81 | static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) | 81 | static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) |
82 | { | 82 | { |
83 | int err = 0; | 83 | int err = -ENOMEM; |
84 | struct iphdr *iph; | 84 | struct iphdr *iph; |
85 | struct ip_comp_hdr *ipch; | 85 | struct ip_comp_hdr *ipch; |
86 | 86 | ||
87 | if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && | 87 | if (skb_linearize_cow(skb)) |
88 | skb_linearize(skb, GFP_ATOMIC) != 0) { | ||
89 | err = -ENOMEM; | ||
90 | goto out; | 88 | goto out; |
91 | } | ||
92 | 89 | ||
93 | skb->ip_summed = CHECKSUM_NONE; | 90 | skb->ip_summed = CHECKSUM_NONE; |
94 | 91 | ||
@@ -158,10 +155,8 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
158 | goto out_ok; | 155 | goto out_ok; |
159 | } | 156 | } |
160 | 157 | ||
161 | if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && | 158 | if (skb_linearize_cow(skb)) |
162 | skb_linearize(skb, GFP_ATOMIC) != 0) { | ||
163 | goto out_ok; | 159 | goto out_ok; |
164 | } | ||
165 | 160 | ||
166 | err = ipcomp_compress(x, skb); | 161 | err = ipcomp_compress(x, skb); |
167 | iph = skb->nh.iph; | 162 | iph = skb->nh.iph; |
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index cec3be544b69..f28cd37feed3 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c | |||
@@ -65,7 +65,7 @@ static LIST_HEAD(ipcomp6_tfms_list); | |||
65 | 65 | ||
66 | static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) | 66 | static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) |
67 | { | 67 | { |
68 | int err = 0; | 68 | int err = -ENOMEM; |
69 | struct ipv6hdr *iph; | 69 | struct ipv6hdr *iph; |
70 | struct ipv6_comp_hdr *ipch; | 70 | struct ipv6_comp_hdr *ipch; |
71 | int plen, dlen; | 71 | int plen, dlen; |
@@ -74,11 +74,8 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
74 | struct crypto_tfm *tfm; | 74 | struct crypto_tfm *tfm; |
75 | int cpu; | 75 | int cpu; |
76 | 76 | ||
77 | if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && | 77 | if (skb_linearize_cow(skb)) |
78 | skb_linearize(skb, GFP_ATOMIC) != 0) { | ||
79 | err = -ENOMEM; | ||
80 | goto out; | 78 | goto out; |
81 | } | ||
82 | 79 | ||
83 | skb->ip_summed = CHECKSUM_NONE; | 80 | skb->ip_summed = CHECKSUM_NONE; |
84 | 81 | ||
@@ -142,10 +139,8 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
142 | goto out_ok; | 139 | goto out_ok; |
143 | } | 140 | } |
144 | 141 | ||
145 | if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && | 142 | if (skb_linearize_cow(skb)) |
146 | skb_linearize(skb, GFP_ATOMIC) != 0) { | ||
147 | goto out_ok; | 143 | goto out_ok; |
148 | } | ||
149 | 144 | ||
150 | /* compression */ | 145 | /* compression */ |
151 | plen = skb->len - hdr_len; | 146 | plen = skb->len - hdr_len; |