aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/pppoe.c2
-rw-r--r--include/linux/skbuff.h40
-rw-r--r--net/bridge/br_netfilter.c2
3 files changed, 33 insertions, 11 deletions
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index bac36546e0bf..0d7f570b9a54 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -860,7 +860,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
860 /* Copy the data if there is no space for the header or if it's 860 /* Copy the data if there is no space for the header or if it's
861 * read-only. 861 * read-only.
862 */ 862 */
863 if (skb_cow(skb, sizeof(*ph) + dev->hard_header_len)) 863 if (skb_cow_head(skb, sizeof(*ph) + dev->hard_header_len))
864 goto abort; 864 goto abort;
865 865
866 __skb_push(skb, sizeof(*ph)); 866 __skb_push(skb, sizeof(*ph));
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 93c27f71122a..a656cecd373c 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1352,6 +1352,22 @@ static inline int skb_clone_writable(struct sk_buff *skb, int len)
1352 skb_headroom(skb) + len <= skb->hdr_len; 1352 skb_headroom(skb) + len <= skb->hdr_len;
1353} 1353}
1354 1354
1355static inline int __skb_cow(struct sk_buff *skb, unsigned int headroom,
1356 int cloned)
1357{
1358 int delta = 0;
1359
1360 if (headroom < NET_SKB_PAD)
1361 headroom = NET_SKB_PAD;
1362 if (headroom > skb_headroom(skb))
1363 delta = headroom - skb_headroom(skb);
1364
1365 if (delta || cloned)
1366 return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD), 0,
1367 GFP_ATOMIC);
1368 return 0;
1369}
1370
1355/** 1371/**
1356 * skb_cow - copy header of skb when it is required 1372 * skb_cow - copy header of skb when it is required
1357 * @skb: buffer to cow 1373 * @skb: buffer to cow
@@ -1366,16 +1382,22 @@ static inline int skb_clone_writable(struct sk_buff *skb, int len)
1366 */ 1382 */
1367static inline int skb_cow(struct sk_buff *skb, unsigned int headroom) 1383static inline int skb_cow(struct sk_buff *skb, unsigned int headroom)
1368{ 1384{
1369 int delta = (headroom > NET_SKB_PAD ? headroom : NET_SKB_PAD) - 1385 return __skb_cow(skb, headroom, skb_cloned(skb));
1370 skb_headroom(skb); 1386}
1371
1372 if (delta < 0)
1373 delta = 0;
1374 1387
1375 if (delta || skb_cloned(skb)) 1388/**
1376 return pskb_expand_head(skb, (delta + (NET_SKB_PAD-1)) & 1389 * skb_cow_head - skb_cow but only making the head writable
1377 ~(NET_SKB_PAD-1), 0, GFP_ATOMIC); 1390 * @skb: buffer to cow
1378 return 0; 1391 * @headroom: needed headroom
1392 *
1393 * This function is identical to skb_cow except that we replace the
1394 * skb_cloned check by skb_header_cloned. It should be used when
1395 * you only need to push on some header and do not need to modify
1396 * the data.
1397 */
1398static inline int skb_cow_head(struct sk_buff *skb, unsigned int headroom)
1399{
1400 return __skb_cow(skb, headroom, skb_header_cloned(skb));
1379} 1401}
1380 1402
1381/** 1403/**
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 3ee2022928e3..fc13130035e7 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -183,7 +183,7 @@ int nf_bridge_copy_header(struct sk_buff *skb)
183 int err; 183 int err;
184 int header_size = ETH_HLEN + nf_bridge_encap_header_len(skb); 184 int header_size = ETH_HLEN + nf_bridge_encap_header_len(skb);
185 185
186 err = skb_cow(skb, header_size); 186 err = skb_cow_head(skb, header_size);
187 if (err) 187 if (err)
188 return err; 188 return err;
189 189