Commit f83f1768 authored by Joonwoo Park's avatar Joonwoo Park Committed by David S. Miller

[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: default avatarJoonwoo Park <joonwpark81@gmail.com>
Acked-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b50660f1
...@@ -381,7 +381,7 @@ static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb, ...@@ -381,7 +381,7 @@ static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb,
xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */ xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */
xid_info->type = svcs_supported; xid_info->type = svcs_supported;
xid_info->rw = rx_window << 1; /* size of receive window */ xid_info->rw = rx_window << 1; /* size of receive window */
skb_put(skb, 3); skb_put(skb, sizeof(struct llc_xid_info));
} }
/** /**
...@@ -406,7 +406,7 @@ static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb, ...@@ -406,7 +406,7 @@ static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb,
xid_info->fmt_id = LLC_XID_FMT_ID; xid_info->fmt_id = LLC_XID_FMT_ID;
xid_info->type = svcs_supported; xid_info->type = svcs_supported;
xid_info->rw = rx_window << 1; xid_info->rw = rx_window << 1;
skb_put(skb, 3); skb_put(skb, sizeof(struct llc_xid_info));
} }
/* LLC Type 2 FRMR response information field format */ /* LLC Type 2 FRMR response information field format */
......
#ifndef LLC_SAP_H #ifndef LLC_SAP_H
#define LLC_SAP_H #define LLC_SAP_H
#include <asm/types.h>
/* /*
* Copyright (c) 1997 by Procom Technology,Inc. * Copyright (c) 1997 by Procom Technology,Inc.
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
...@@ -19,8 +22,8 @@ struct sock; ...@@ -19,8 +22,8 @@ struct sock;
extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb); extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
extern void llc_save_primitive(struct sock *sk, struct sk_buff* skb, extern void llc_save_primitive(struct sock *sk, struct sk_buff* skb,
unsigned char prim); unsigned char prim);
extern struct sk_buff *llc_alloc_frame(struct sock *sk, extern struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev,
struct net_device *dev); u8 type, u32 data_size);
extern void llc_build_and_send_test_pkt(struct llc_sap *sap, extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
struct sk_buff *skb, struct sk_buff *skb,
......
...@@ -198,7 +198,7 @@ int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) ...@@ -198,7 +198,7 @@ int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +223,7 @@ int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +249,7 @@ int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +282,8 @@ int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
llc_pdu_decode_pf_bit(skb, &f_bit); llc_pdu_decode_pf_bit(skb, &f_bit);
else else
f_bit = 0; f_bit = 0;
nskb = llc_alloc_frame(sk, llc->dev); nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U,
sizeof(struct llc_frmr_info));
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; struct llc_sap *sap = llc->sap;
...@@ -306,7 +307,8 @@ int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb) ...@@ -306,7 +307,8 @@ int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U,
sizeof(struct llc_frmr_info));
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +338,8 @@ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
llc_pdu_decode_pf_bit(skb, &f_bit); llc_pdu_decode_pf_bit(skb, &f_bit);
nskb = llc_alloc_frame(sk, llc->dev); nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U,
sizeof(struct llc_frmr_info));
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; struct llc_sap *sap = llc->sap;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); 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,7 +427,7 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +462,7 @@ int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +486,7 @@ int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +510,7 @@ int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +534,7 @@ int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +558,7 @@ int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +582,7 @@ int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +618,7 @@ int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +642,7 @@ int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +666,7 @@ int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +691,7 @@ int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +715,7 @@ int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +739,7 @@ int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +773,7 @@ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; 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,7 +802,7 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
u8 f_bit; u8 f_bit;
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
llc_pdu_decode_pf_bit(skb, &f_bit); llc_pdu_decode_pf_bit(skb, &f_bit);
if (nskb) { if (nskb) {
...@@ -956,7 +959,7 @@ static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, ...@@ -956,7 +959,7 @@ static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
{ {
int rc = -ENOBUFS; int rc = -ENOBUFS;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
if (nskb) { if (nskb) {
struct llc_sap *sap = llc->sap; struct llc_sap *sap = llc->sap;
......
...@@ -241,7 +241,7 @@ void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu, ...@@ -241,7 +241,7 @@ void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu,
FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw); FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw);
FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw); FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw);
FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw); FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw);
skb_put(skb, 5); skb_put(skb, sizeof(struct llc_frmr_info));
} }
/** /**
......
...@@ -103,7 +103,8 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb) ...@@ -103,7 +103,8 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
llc_pdu_decode_sa(skb, mac_da); llc_pdu_decode_sa(skb, mac_da);
llc_pdu_decode_da(skb, mac_sa); llc_pdu_decode_da(skb, mac_sa);
llc_pdu_decode_ssap(skb, &dsap); llc_pdu_decode_ssap(skb, &dsap);
nskb = llc_alloc_frame(NULL, skb->dev); nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
sizeof(struct llc_xid_info));
if (!nskb) if (!nskb)
goto out; goto out;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, 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,11 +145,15 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap; u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
struct sk_buff *nskb; struct sk_buff *nskb;
int rc = 1; int rc = 1;
u32 data_size;
llc_pdu_decode_sa(skb, mac_da); llc_pdu_decode_sa(skb, mac_da);
llc_pdu_decode_da(skb, mac_sa); llc_pdu_decode_da(skb, mac_sa);
llc_pdu_decode_ssap(skb, &dsap); llc_pdu_decode_ssap(skb, &dsap);
nskb = llc_alloc_frame(NULL, skb->dev);
/* The test request command is type U (llc_len = 3) */
data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
if (!nskb) if (!nskb)
goto out; goto out;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
......
...@@ -24,20 +24,41 @@ ...@@ -24,20 +24,41 @@
#include <net/tcp_states.h> #include <net/tcp_states.h>
#include <linux/llc.h> #include <linux/llc.h>
static int llc_mac_header_len(unsigned short devtype)
{
switch (devtype) {
case ARPHRD_ETHER:
case ARPHRD_LOOPBACK:
return sizeof(struct ethhdr);
#ifdef CONFIG_TR
case ARPHRD_IEEE802_TR:
return sizeof(struct trh_hdr);
#endif
}
return 0;
}
/** /**
* llc_alloc_frame - allocates sk_buff for frame * llc_alloc_frame - allocates sk_buff for frame
* @dev: network device this skb will be sent over * @dev: network device this skb will be sent over
* @type: pdu type to allocate
* @data_size: data size to allocate
* *
* Allocates an sk_buff for frame and initializes sk_buff fields. * Allocates an sk_buff for frame and initializes sk_buff fields.
* Returns allocated skb or %NULL when out of memory. * Returns allocated skb or %NULL when out of memory.
*/ */
struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev) struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev,
u8 type, u32 data_size)
{ {
struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); int hlen = type == LLC_PDU_TYPE_U ? 3 : 4;
struct sk_buff *skb;
hlen += llc_mac_header_len(dev->type);
skb = alloc_skb(hlen + data_size, GFP_ATOMIC);
if (skb) { if (skb) {
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
skb_reserve(skb, 50); skb_reserve(skb, hlen);
skb_reset_network_header(skb); skb_reset_network_header(skb);
skb_reset_transport_header(skb); skb_reset_transport_header(skb);
skb->protocol = htons(ETH_P_802_2); skb->protocol = htons(ETH_P_802_2);
......
...@@ -253,7 +253,8 @@ static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb) ...@@ -253,7 +253,8 @@ static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb)
static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb) static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb)
{ {
int rc = 1; int rc = 1;
struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev); struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
sizeof(struct llc_xid_info));
if (!nskb) if (!nskb)
goto out; goto out;
...@@ -274,7 +275,8 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb) ...@@ -274,7 +275,8 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb)
{ {
u8 mac_da[ETH_ALEN], dsap; u8 mac_da[ETH_ALEN], dsap;
int rc = 1; int rc = 1;
struct sk_buff* nskb = llc_alloc_frame(NULL, skb->dev); struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
sizeof(struct llc_xid_info));
if (!nskb) if (!nskb)
goto out; goto out;
...@@ -298,7 +300,12 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb) ...@@ -298,7 +300,12 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb)
{ {
u8 mac_da[ETH_ALEN], dsap; u8 mac_da[ETH_ALEN], dsap;
int rc = 1; int rc = 1;
struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev); u32 data_size;
struct sk_buff *nskb;
/* The test request command is type U (llc_len = 3) */
data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
if (!nskb) if (!nskb)
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment