aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c63
-rw-r--r--net/decnet/dn_nsp_in.c3
-rw-r--r--net/decnet/dn_route.c3
-rw-r--r--net/ipv4/ipcomp.c11
-rw-r--r--net/ipv6/ipcomp6.c11
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 */
1226int __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);
3473EXPORT_SYMBOL(__dev_get_by_index); 3415EXPORT_SYMBOL(__dev_get_by_index);
3474EXPORT_SYMBOL(__dev_get_by_name); 3416EXPORT_SYMBOL(__dev_get_by_name);
3475EXPORT_SYMBOL(__dev_remove_pack); 3417EXPORT_SYMBOL(__dev_remove_pack);
3476EXPORT_SYMBOL(__skb_linearize);
3477EXPORT_SYMBOL(dev_valid_name); 3418EXPORT_SYMBOL(dev_valid_name);
3478EXPORT_SYMBOL(dev_add_pack); 3419EXPORT_SYMBOL(dev_add_pack);
3479EXPORT_SYMBOL(dev_alloc_name); 3420EXPORT_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
81static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) 81static 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
66static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) 66static 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;