aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c63
1 files changed, 2 insertions, 61 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);