Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers/net/wan/hdlc_fr: Move the skb_headroom check out of fr_hard_header

Move the skb_headroom check out of fr_hard_header and into pvc_xmit.
This has two benefits:

1. Originally we only do this check for skbs sent by users on Ethernet-
emulating PVC devices. After the change we do this check for skbs sent on
normal PVC devices, too.
(Also add a comment to make it clear that this is only a protection
against upper layers that don't take dev->needed_headroom into account.
Such upper layers should be rare and I believe they should be fixed.)

2. After the change we can simplify the parameter list of fr_hard_header.
We no longer need to use a pointer to pointers (skb_p) because we no
longer need to replace the skb inside fr_hard_header.

Cc: Krzysztof Halasa <khc@pm.waw.pl>
Signed-off-by: Xie He <xie.he.0141@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Xie He and committed by
Jakub Kicinski
df41c19a e0b2e0d8

+17 -13
+17 -13
drivers/net/wan/hdlc_fr.c
··· 271 271 } 272 272 273 273 274 - static int fr_hard_header(struct sk_buff **skb_p, u16 dlci) 274 + static int fr_hard_header(struct sk_buff *skb, u16 dlci) 275 275 { 276 - struct sk_buff *skb = *skb_p; 277 - 278 276 if (!skb->dev) { /* Control packets */ 279 277 switch (dlci) { 280 278 case LMI_CCITT_ANSI_DLCI: ··· 314 316 } 315 317 316 318 } else if (skb->dev->type == ARPHRD_ETHER) { 317 - if (skb_headroom(skb) < 10) { 318 - struct sk_buff *skb2 = skb_realloc_headroom(skb, 10); 319 - if (!skb2) 320 - return -ENOBUFS; 321 - dev_kfree_skb(skb); 322 - skb = *skb_p = skb2; 323 - } 324 319 skb_push(skb, 10); 325 320 skb->data[3] = FR_PAD; 326 321 skb->data[4] = NLPID_SNAP; ··· 420 429 } 421 430 } 422 431 432 + /* We already requested the header space with dev->needed_headroom. 433 + * So this is just a protection in case the upper layer didn't take 434 + * dev->needed_headroom into consideration. 435 + */ 436 + if (skb_headroom(skb) < 10) { 437 + struct sk_buff *skb2 = skb_realloc_headroom(skb, 10); 438 + 439 + if (!skb2) 440 + goto drop; 441 + dev_kfree_skb(skb); 442 + skb = skb2; 443 + } 444 + 423 445 skb->dev = dev; 424 - if (fr_hard_header(&skb, pvc->dlci)) 446 + if (fr_hard_header(skb, pvc->dlci)) 425 447 goto drop; 426 448 427 449 dev->stats.tx_bytes += skb->len; ··· 502 498 memset(skb->data, 0, len); 503 499 skb_reserve(skb, 4); 504 500 if (lmi == LMI_CISCO) { 505 - fr_hard_header(&skb, LMI_CISCO_DLCI); 501 + fr_hard_header(skb, LMI_CISCO_DLCI); 506 502 } else { 507 - fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI); 503 + fr_hard_header(skb, LMI_CCITT_ANSI_DLCI); 508 504 } 509 505 data = skb_tail_pointer(skb); 510 506 data[i++] = LMI_CALLREF;