[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <47e76779.0f98600a.36ef.ffff9c13@mx.google.com>
Date: Mon, 24 Mar 2008 17:33:57 +0900
From: joonwpark81@...il.com
To: acme@...stprotocols.net
Cc: Joonwoo Park <joonwpark81@...il.com>, netdev@...r.kernel.org,
jwestfall@...realistic.net
Subject: [PATCH 1/3] [LLC]: skb allocation size for responses
From: Joonwoo Park <joonwpark81@...il.com>
allocate the skb for llc responses with the received packet size by
using the size adjustable llc_frame_alloc.
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@...il.com>
---
diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h
index 2c56dbe..a5c9f5b 100644
--- a/include/net/llc_sap.h
+++ b/include/net/llc_sap.h
@@ -1,5 +1,8 @@
#ifndef LLC_SAP_H
#define LLC_SAP_H
+
+#include <asm/types.h>
+
/*
* Copyright (c) 1997 by Procom Technology,Inc.
* 2001-2003 by Arnaldo Carvalho de Melo <acme@...ectiva.com.br>
@@ -20,7 +23,7 @@ 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,
unsigned char prim);
extern struct sk_buff *llc_alloc_frame(struct sock *sk,
- struct net_device *dev);
+ struct net_device *dev, u32 size);
extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
struct sk_buff *skb,
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index 860140c..a9db49d 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)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
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)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
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)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -282,7 +282,7 @@ 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);
else
f_bit = 0;
- nskb = llc_alloc_frame(sk, llc->dev);
+ nskb = llc_alloc_frame(sk, llc->dev, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -306,7 +306,7 @@ int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -336,7 +336,7 @@ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
struct llc_sock *llc = llc_sk(sk);
llc_pdu_decode_pf_bit(skb, &f_bit);
- nskb = llc_alloc_frame(sk, llc->dev);
+ nskb = llc_alloc_frame(sk, llc->dev, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
@@ -424,7 +424,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);
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -459,7 +459,7 @@ int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -483,7 +483,7 @@ int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -507,7 +507,7 @@ int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -531,7 +531,7 @@ int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -555,7 +555,7 @@ int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -579,7 +579,7 @@ int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -615,7 +615,7 @@ int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -639,7 +639,7 @@ int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -663,7 +663,7 @@ int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -688,7 +688,7 @@ int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -712,7 +712,7 @@ int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -736,7 +736,7 @@ int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -770,7 +770,7 @@ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
@@ -799,7 +799,7 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
u8 f_bit;
int rc = -ENOBUFS;
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, 78);
llc_pdu_decode_pf_bit(skb, &f_bit);
if (nskb) {
@@ -956,7 +956,7 @@ static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
{
int rc = -ENOBUFS;
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, 78);
if (nskb) {
struct llc_sap *sap = llc->sap;
diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c
index ac3d93b..1cec45c 100644
--- a/net/llc/llc_s_ac.c
+++ b/net/llc/llc_s_ac.c
@@ -103,7 +103,7 @@ 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_da(skb, mac_sa);
llc_pdu_decode_ssap(skb, &dsap);
- nskb = llc_alloc_frame(NULL, skb->dev);
+ nskb = llc_alloc_frame(NULL, skb->dev, 78);
if (!nskb)
goto out;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
@@ -144,11 +144,18 @@ 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;
struct sk_buff *nskb;
int rc = 1;
+ u32 size;
llc_pdu_decode_sa(skb, mac_da);
llc_pdu_decode_da(skb, mac_sa);
llc_pdu_decode_ssap(skb, &dsap);
- nskb = llc_alloc_frame(NULL, skb->dev);
+
+#ifdef NET_SKBUFF_DATA_USES_OFFSET
+ size = skb->end + skb->data_len;
+#else
+ size = skb->end - skb->head;
+#endif
+ nskb = llc_alloc_frame(NULL, skb->dev, size);
if (!nskb)
goto out;
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 2525165..e295549 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -27,13 +27,15 @@
/**
* llc_alloc_frame - allocates sk_buff for frame
* @dev: network device this skb will be sent over
+ * @size: size to allocate
*
* Allocates an sk_buff for frame and initializes sk_buff fields.
* 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,
+ u32 size)
{
- struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
+ struct sk_buff *skb = alloc_skb(size + 50, GFP_ATOMIC);
if (skb) {
skb_reset_mac_header(skb);
diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c
index 6f2ea20..2d7024c 100644
--- a/net/llc/llc_station.c
+++ b/net/llc/llc_station.c
@@ -253,7 +253,7 @@ 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)
{
int rc = 1;
- struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev);
+ struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, 78);
if (!nskb)
goto out;
@@ -274,7 +274,7 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb)
{
u8 mac_da[ETH_ALEN], dsap;
int rc = 1;
- struct sk_buff* nskb = llc_alloc_frame(NULL, skb->dev);
+ struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, 78);
if (!nskb)
goto out;
@@ -298,7 +298,15 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb)
{
u8 mac_da[ETH_ALEN], dsap;
int rc = 1;
- struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev);
+ u32 size;
+ struct sk_buff *nskb;
+
+#ifdef NET_SKBUFF_DATA_USES_OFFSET
+ size = skb->end + skb->data_len;
+#else
+ size = skb->end - skb->head;
+#endif
+ nskb = llc_alloc_frame(NULL, skb->dev, size);
if (!nskb)
goto out;
--
1.5.4.3
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists