diff options
author | Joonwoo Park <joonwpark81@gmail.com> | 2008-04-01 00:02:47 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-01 00:02:47 -0400 |
commit | f83f1768f833cb45bc93429fdc552252a4f55ac3 (patch) | |
tree | 15de7d2df2fc3a35e0a6b933bb37aefcba2cc3ef /net/llc | |
parent | b50660f1fe4ebd6129064e4fba0bd882b60c2425 (diff) |
[LLC]: skb allocation size for responses
Allocate the skb for llc responses with the received packet size by
using the size adjustable llc_frame_alloc.
Don't allocate useless extra payload.
Cleanup magic numbers.
So, this fixes oops.
Reported by Jim Westfall:
kernel: skb_over_panic: text:c0541fc7 len:1000 put:997 head:c166ac00 data:c166ac2f tail:0xc166b017 end:0xc166ac80 dev:eth0
kernel: ------------[ cut here ]------------
kernel: kernel BUG at net/core/skbuff.c:95!
Signed-off-by: Joonwoo Park <joonwpark81@gmail.com>
Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/llc')
-rw-r--r-- | net/llc/llc_c_ac.c | 47 | ||||
-rw-r--r-- | net/llc/llc_pdu.c | 2 | ||||
-rw-r--r-- | net/llc/llc_s_ac.c | 9 | ||||
-rw-r--r-- | net/llc/llc_sap.c | 27 | ||||
-rw-r--r-- | net/llc/llc_station.c | 13 |
5 files changed, 67 insertions, 31 deletions
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index 860140caa6e..71a00225bdb 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c | |||
@@ -198,7 +198,7 @@ int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) | |||
198 | { | 198 | { |
199 | int rc = -ENOBUFS; | 199 | int rc = -ENOBUFS; |
200 | struct llc_sock *llc = llc_sk(sk); | 200 | struct llc_sock *llc = llc_sk(sk); |
201 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 201 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); |
202 | 202 | ||
203 | if (nskb) { | 203 | if (nskb) { |
204 | struct llc_sap *sap = llc->sap; | 204 | struct llc_sap *sap = llc->sap; |
@@ -223,7 +223,7 @@ int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) | |||
223 | { | 223 | { |
224 | int rc = -ENOBUFS; | 224 | int rc = -ENOBUFS; |
225 | struct llc_sock *llc = llc_sk(sk); | 225 | struct llc_sock *llc = llc_sk(sk); |
226 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 226 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); |
227 | 227 | ||
228 | if (nskb) { | 228 | if (nskb) { |
229 | struct llc_sap *sap = llc->sap; | 229 | struct llc_sap *sap = llc->sap; |
@@ -249,7 +249,7 @@ int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) | |||
249 | { | 249 | { |
250 | int rc = -ENOBUFS; | 250 | int rc = -ENOBUFS; |
251 | struct llc_sock *llc = llc_sk(sk); | 251 | struct llc_sock *llc = llc_sk(sk); |
252 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 252 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); |
253 | 253 | ||
254 | if (nskb) { | 254 | if (nskb) { |
255 | struct llc_sap *sap = llc->sap; | 255 | struct llc_sap *sap = llc->sap; |
@@ -282,7 +282,8 @@ int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb) | |||
282 | llc_pdu_decode_pf_bit(skb, &f_bit); | 282 | llc_pdu_decode_pf_bit(skb, &f_bit); |
283 | else | 283 | else |
284 | f_bit = 0; | 284 | f_bit = 0; |
285 | nskb = llc_alloc_frame(sk, llc->dev); | 285 | nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, |
286 | sizeof(struct llc_frmr_info)); | ||
286 | if (nskb) { | 287 | if (nskb) { |
287 | struct llc_sap *sap = llc->sap; | 288 | struct llc_sap *sap = llc->sap; |
288 | 289 | ||
@@ -306,7 +307,8 @@ int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb) | |||
306 | { | 307 | { |
307 | int rc = -ENOBUFS; | 308 | int rc = -ENOBUFS; |
308 | struct llc_sock *llc = llc_sk(sk); | 309 | struct llc_sock *llc = llc_sk(sk); |
309 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 310 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, |
311 | sizeof(struct llc_frmr_info)); | ||
310 | 312 | ||
311 | if (nskb) { | 313 | if (nskb) { |
312 | struct llc_sap *sap = llc->sap; | 314 | struct llc_sap *sap = llc->sap; |
@@ -336,7 +338,8 @@ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) | |||
336 | struct llc_sock *llc = llc_sk(sk); | 338 | struct llc_sock *llc = llc_sk(sk); |
337 | 339 | ||
338 | llc_pdu_decode_pf_bit(skb, &f_bit); | 340 | llc_pdu_decode_pf_bit(skb, &f_bit); |
339 | nskb = llc_alloc_frame(sk, llc->dev); | 341 | nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, |
342 | sizeof(struct llc_frmr_info)); | ||
340 | if (nskb) { | 343 | if (nskb) { |
341 | struct llc_sap *sap = llc->sap; | 344 | struct llc_sap *sap = llc->sap; |
342 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 345 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
@@ -424,7 +427,7 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk, | |||
424 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 427 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
425 | int rc = -ENOBUFS; | 428 | int rc = -ENOBUFS; |
426 | struct llc_sock *llc = llc_sk(sk); | 429 | struct llc_sock *llc = llc_sk(sk); |
427 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 430 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); |
428 | 431 | ||
429 | if (nskb) { | 432 | if (nskb) { |
430 | struct llc_sap *sap = llc->sap; | 433 | struct llc_sap *sap = llc->sap; |
@@ -459,7 +462,7 @@ int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) | |||
459 | { | 462 | { |
460 | int rc = -ENOBUFS; | 463 | int rc = -ENOBUFS; |
461 | struct llc_sock *llc = llc_sk(sk); | 464 | struct llc_sock *llc = llc_sk(sk); |
462 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 465 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
463 | 466 | ||
464 | if (nskb) { | 467 | if (nskb) { |
465 | struct llc_sap *sap = llc->sap; | 468 | struct llc_sap *sap = llc->sap; |
@@ -483,7 +486,7 @@ int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) | |||
483 | { | 486 | { |
484 | int rc = -ENOBUFS; | 487 | int rc = -ENOBUFS; |
485 | struct llc_sock *llc = llc_sk(sk); | 488 | struct llc_sock *llc = llc_sk(sk); |
486 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 489 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
487 | 490 | ||
488 | if (nskb) { | 491 | if (nskb) { |
489 | struct llc_sap *sap = llc->sap; | 492 | struct llc_sap *sap = llc->sap; |
@@ -507,7 +510,7 @@ int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) | |||
507 | { | 510 | { |
508 | int rc = -ENOBUFS; | 511 | int rc = -ENOBUFS; |
509 | struct llc_sock *llc = llc_sk(sk); | 512 | struct llc_sock *llc = llc_sk(sk); |
510 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 513 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
511 | 514 | ||
512 | if (nskb) { | 515 | if (nskb) { |
513 | struct llc_sap *sap = llc->sap; | 516 | struct llc_sap *sap = llc->sap; |
@@ -531,7 +534,7 @@ int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) | |||
531 | { | 534 | { |
532 | int rc = -ENOBUFS; | 535 | int rc = -ENOBUFS; |
533 | struct llc_sock *llc = llc_sk(sk); | 536 | struct llc_sock *llc = llc_sk(sk); |
534 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 537 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
535 | 538 | ||
536 | if (nskb) { | 539 | if (nskb) { |
537 | struct llc_sap *sap = llc->sap; | 540 | struct llc_sap *sap = llc->sap; |
@@ -555,7 +558,7 @@ int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) | |||
555 | { | 558 | { |
556 | int rc = -ENOBUFS; | 559 | int rc = -ENOBUFS; |
557 | struct llc_sock *llc = llc_sk(sk); | 560 | struct llc_sock *llc = llc_sk(sk); |
558 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 561 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
559 | 562 | ||
560 | if (nskb) { | 563 | if (nskb) { |
561 | struct llc_sap *sap = llc->sap; | 564 | struct llc_sap *sap = llc->sap; |
@@ -579,7 +582,7 @@ int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) | |||
579 | { | 582 | { |
580 | int rc = -ENOBUFS; | 583 | int rc = -ENOBUFS; |
581 | struct llc_sock *llc = llc_sk(sk); | 584 | struct llc_sock *llc = llc_sk(sk); |
582 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 585 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
583 | 586 | ||
584 | if (nskb) { | 587 | if (nskb) { |
585 | struct llc_sap *sap = llc->sap; | 588 | struct llc_sap *sap = llc->sap; |
@@ -615,7 +618,7 @@ int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) | |||
615 | { | 618 | { |
616 | int rc = -ENOBUFS; | 619 | int rc = -ENOBUFS; |
617 | struct llc_sock *llc = llc_sk(sk); | 620 | struct llc_sock *llc = llc_sk(sk); |
618 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 621 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
619 | 622 | ||
620 | if (nskb) { | 623 | if (nskb) { |
621 | struct llc_sap *sap = llc->sap; | 624 | struct llc_sap *sap = llc->sap; |
@@ -639,7 +642,7 @@ int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) | |||
639 | { | 642 | { |
640 | int rc = -ENOBUFS; | 643 | int rc = -ENOBUFS; |
641 | struct llc_sock *llc = llc_sk(sk); | 644 | struct llc_sock *llc = llc_sk(sk); |
642 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 645 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
643 | 646 | ||
644 | if (nskb) { | 647 | if (nskb) { |
645 | struct llc_sap *sap = llc->sap; | 648 | struct llc_sap *sap = llc->sap; |
@@ -663,7 +666,7 @@ int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) | |||
663 | { | 666 | { |
664 | int rc = -ENOBUFS; | 667 | int rc = -ENOBUFS; |
665 | struct llc_sock *llc = llc_sk(sk); | 668 | struct llc_sock *llc = llc_sk(sk); |
666 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 669 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
667 | 670 | ||
668 | if (nskb) { | 671 | if (nskb) { |
669 | struct llc_sap *sap = llc->sap; | 672 | struct llc_sap *sap = llc->sap; |
@@ -688,7 +691,7 @@ int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) | |||
688 | { | 691 | { |
689 | int rc = -ENOBUFS; | 692 | int rc = -ENOBUFS; |
690 | struct llc_sock *llc = llc_sk(sk); | 693 | struct llc_sock *llc = llc_sk(sk); |
691 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 694 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
692 | 695 | ||
693 | if (nskb) { | 696 | if (nskb) { |
694 | struct llc_sap *sap = llc->sap; | 697 | struct llc_sap *sap = llc->sap; |
@@ -712,7 +715,7 @@ int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) | |||
712 | { | 715 | { |
713 | int rc = -ENOBUFS; | 716 | int rc = -ENOBUFS; |
714 | struct llc_sock *llc = llc_sk(sk); | 717 | struct llc_sock *llc = llc_sk(sk); |
715 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 718 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
716 | 719 | ||
717 | if (nskb) { | 720 | if (nskb) { |
718 | struct llc_sap *sap = llc->sap; | 721 | struct llc_sap *sap = llc->sap; |
@@ -736,7 +739,7 @@ int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) | |||
736 | { | 739 | { |
737 | int rc = -ENOBUFS; | 740 | int rc = -ENOBUFS; |
738 | struct llc_sock *llc = llc_sk(sk); | 741 | struct llc_sock *llc = llc_sk(sk); |
739 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 742 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
740 | 743 | ||
741 | if (nskb) { | 744 | if (nskb) { |
742 | struct llc_sap *sap = llc->sap; | 745 | struct llc_sap *sap = llc->sap; |
@@ -770,7 +773,7 @@ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) | |||
770 | { | 773 | { |
771 | int rc = -ENOBUFS; | 774 | int rc = -ENOBUFS; |
772 | struct llc_sock *llc = llc_sk(sk); | 775 | struct llc_sock *llc = llc_sk(sk); |
773 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 776 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); |
774 | 777 | ||
775 | if (nskb) { | 778 | if (nskb) { |
776 | struct llc_sap *sap = llc->sap; | 779 | struct llc_sap *sap = llc->sap; |
@@ -799,7 +802,7 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) | |||
799 | u8 f_bit; | 802 | u8 f_bit; |
800 | int rc = -ENOBUFS; | 803 | int rc = -ENOBUFS; |
801 | struct llc_sock *llc = llc_sk(sk); | 804 | struct llc_sock *llc = llc_sk(sk); |
802 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 805 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); |
803 | 806 | ||
804 | llc_pdu_decode_pf_bit(skb, &f_bit); | 807 | llc_pdu_decode_pf_bit(skb, &f_bit); |
805 | if (nskb) { | 808 | if (nskb) { |
@@ -956,7 +959,7 @@ static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, | |||
956 | { | 959 | { |
957 | int rc = -ENOBUFS; | 960 | int rc = -ENOBUFS; |
958 | struct llc_sock *llc = llc_sk(sk); | 961 | struct llc_sock *llc = llc_sk(sk); |
959 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | 962 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); |
960 | 963 | ||
961 | if (nskb) { | 964 | if (nskb) { |
962 | struct llc_sap *sap = llc->sap; | 965 | struct llc_sap *sap = llc->sap; |
diff --git a/net/llc/llc_pdu.c b/net/llc/llc_pdu.c index fa8324396db..2e6cb79196b 100644 --- a/net/llc/llc_pdu.c +++ b/net/llc/llc_pdu.c | |||
@@ -241,7 +241,7 @@ void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu, | |||
241 | FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw); | 241 | FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw); |
242 | FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw); | 242 | FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw); |
243 | FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw); | 243 | FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw); |
244 | skb_put(skb, 5); | 244 | skb_put(skb, sizeof(struct llc_frmr_info)); |
245 | } | 245 | } |
246 | 246 | ||
247 | /** | 247 | /** |
diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c index ac3d93b210d..a94bd56bcac 100644 --- a/net/llc/llc_s_ac.c +++ b/net/llc/llc_s_ac.c | |||
@@ -103,7 +103,8 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb) | |||
103 | llc_pdu_decode_sa(skb, mac_da); | 103 | llc_pdu_decode_sa(skb, mac_da); |
104 | llc_pdu_decode_da(skb, mac_sa); | 104 | llc_pdu_decode_da(skb, mac_sa); |
105 | llc_pdu_decode_ssap(skb, &dsap); | 105 | llc_pdu_decode_ssap(skb, &dsap); |
106 | nskb = llc_alloc_frame(NULL, skb->dev); | 106 | nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, |
107 | sizeof(struct llc_xid_info)); | ||
107 | if (!nskb) | 108 | if (!nskb) |
108 | goto out; | 109 | goto out; |
109 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, | 110 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, |
@@ -144,11 +145,15 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb) | |||
144 | u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap; | 145 | u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap; |
145 | struct sk_buff *nskb; | 146 | struct sk_buff *nskb; |
146 | int rc = 1; | 147 | int rc = 1; |
148 | u32 data_size; | ||
147 | 149 | ||
148 | llc_pdu_decode_sa(skb, mac_da); | 150 | llc_pdu_decode_sa(skb, mac_da); |
149 | llc_pdu_decode_da(skb, mac_sa); | 151 | llc_pdu_decode_da(skb, mac_sa); |
150 | llc_pdu_decode_ssap(skb, &dsap); | 152 | llc_pdu_decode_ssap(skb, &dsap); |
151 | nskb = llc_alloc_frame(NULL, skb->dev); | 153 | |
154 | /* The test request command is type U (llc_len = 3) */ | ||
155 | data_size = ntohs(eth_hdr(skb)->h_proto) - 3; | ||
156 | nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size); | ||
152 | if (!nskb) | 157 | if (!nskb) |
153 | goto out; | 158 | goto out; |
154 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, | 159 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, |
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index 2525165e2e8..e2ddde75501 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c | |||
@@ -24,20 +24,41 @@ | |||
24 | #include <net/tcp_states.h> | 24 | #include <net/tcp_states.h> |
25 | #include <linux/llc.h> | 25 | #include <linux/llc.h> |
26 | 26 | ||
27 | static int llc_mac_header_len(unsigned short devtype) | ||
28 | { | ||
29 | switch (devtype) { | ||
30 | case ARPHRD_ETHER: | ||
31 | case ARPHRD_LOOPBACK: | ||
32 | return sizeof(struct ethhdr); | ||
33 | #ifdef CONFIG_TR | ||
34 | case ARPHRD_IEEE802_TR: | ||
35 | return sizeof(struct trh_hdr); | ||
36 | #endif | ||
37 | } | ||
38 | return 0; | ||
39 | } | ||
40 | |||
27 | /** | 41 | /** |
28 | * llc_alloc_frame - allocates sk_buff for frame | 42 | * llc_alloc_frame - allocates sk_buff for frame |
29 | * @dev: network device this skb will be sent over | 43 | * @dev: network device this skb will be sent over |
44 | * @type: pdu type to allocate | ||
45 | * @data_size: data size to allocate | ||
30 | * | 46 | * |
31 | * Allocates an sk_buff for frame and initializes sk_buff fields. | 47 | * Allocates an sk_buff for frame and initializes sk_buff fields. |
32 | * Returns allocated skb or %NULL when out of memory. | 48 | * Returns allocated skb or %NULL when out of memory. |
33 | */ | 49 | */ |
34 | struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev) | 50 | struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev, |
51 | u8 type, u32 data_size) | ||
35 | { | 52 | { |
36 | struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); | 53 | int hlen = type == LLC_PDU_TYPE_U ? 3 : 4; |
54 | struct sk_buff *skb; | ||
55 | |||
56 | hlen += llc_mac_header_len(dev->type); | ||
57 | skb = alloc_skb(hlen + data_size, GFP_ATOMIC); | ||
37 | 58 | ||
38 | if (skb) { | 59 | if (skb) { |
39 | skb_reset_mac_header(skb); | 60 | skb_reset_mac_header(skb); |
40 | skb_reserve(skb, 50); | 61 | skb_reserve(skb, hlen); |
41 | skb_reset_network_header(skb); | 62 | skb_reset_network_header(skb); |
42 | skb_reset_transport_header(skb); | 63 | skb_reset_transport_header(skb); |
43 | skb->protocol = htons(ETH_P_802_2); | 64 | skb->protocol = htons(ETH_P_802_2); |
diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c index 959e7f31833..83da1333949 100644 --- a/net/llc/llc_station.c +++ b/net/llc/llc_station.c | |||
@@ -253,7 +253,8 @@ static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb) | |||
253 | static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb) | 253 | static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb) |
254 | { | 254 | { |
255 | int rc = 1; | 255 | int rc = 1; |
256 | struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev); | 256 | struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, |
257 | sizeof(struct llc_xid_info)); | ||
257 | 258 | ||
258 | if (!nskb) | 259 | if (!nskb) |
259 | goto out; | 260 | goto out; |
@@ -274,7 +275,8 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb) | |||
274 | { | 275 | { |
275 | u8 mac_da[ETH_ALEN], dsap; | 276 | u8 mac_da[ETH_ALEN], dsap; |
276 | int rc = 1; | 277 | int rc = 1; |
277 | struct sk_buff* nskb = llc_alloc_frame(NULL, skb->dev); | 278 | struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, |
279 | sizeof(struct llc_xid_info)); | ||
278 | 280 | ||
279 | if (!nskb) | 281 | if (!nskb) |
280 | goto out; | 282 | goto out; |
@@ -298,7 +300,12 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb) | |||
298 | { | 300 | { |
299 | u8 mac_da[ETH_ALEN], dsap; | 301 | u8 mac_da[ETH_ALEN], dsap; |
300 | int rc = 1; | 302 | int rc = 1; |
301 | struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev); | 303 | u32 data_size; |
304 | struct sk_buff *nskb; | ||
305 | |||
306 | /* The test request command is type U (llc_len = 3) */ | ||
307 | data_size = ntohs(eth_hdr(skb)->h_proto) - 3; | ||
308 | nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size); | ||
302 | 309 | ||
303 | if (!nskb) | 310 | if (!nskb) |
304 | goto out; | 311 | goto out; |