summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@conectiva.com.br>2002-09-30 10:17:07 -0300
committerArnaldo Carvalho de Melo <acme@conectiva.com.br>2002-09-30 10:17:07 -0300
commitc96542edd5bf18453a433ffb149c3cb8977f8a28 (patch)
tree11134b08183f7a29644c2f28c8cd5cc44fdad999
parentaf19bc3ddb6de0c1a3b33ef0ce61377ea5075447 (diff)
o LLC: kill llc_conn_free_ev, use plain kfree_skb instead
Also flush the backlog in llc_ui_wait_for_data before going to sleep. Also fix a bug in llc_backlog_rcv where I was double freeing a skb.
-rw-r--r--include/net/llc_conn.h1
-rw-r--r--net/llc/af_llc.c7
-rw-r--r--net/llc/llc_c_ac.c2
-rw-r--r--net/llc/llc_conn.c25
-rw-r--r--net/llc/llc_main.c12
5 files changed, 15 insertions, 32 deletions
diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h
index b27ee7332c3b..3dd6d0b19f6b 100644
--- a/include/net/llc_conn.h
+++ b/include/net/llc_conn.h
@@ -79,7 +79,6 @@ extern int llc_sk_init(struct sock *sk);
extern int llc_conn_state_process(struct sock *sk, struct sk_buff *skb);
extern void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
extern void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb);
-extern void llc_conn_free_ev(struct sk_buff *skb);
extern void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr,
u8 first_p_bit);
extern void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr,
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index e55b54574499..2144915eee5b 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -569,6 +569,13 @@ static int llc_ui_wait_for_data(struct sock *sk, int timeout)
rc = -EAGAIN;
if (!timeout)
break;
+ /*
+ * Well, if we have backlog, try to process it now.
+ */
+ if (sk->backlog.tail) {
+ release_sock(sk);
+ lock_sock(sk);
+ }
rc = 0;
if (skb_queue_empty(&sk->receive_queue)) {
release_sock(sk);
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index 856f39efae9a..2a96a6a6178d 100644
--- a/net/llc/llc_c_ac.c
+++ b/net/llc/llc_c_ac.c
@@ -1487,7 +1487,7 @@ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) {
printk(KERN_WARNING "%s: timer called on closed connection\n",
__FUNCTION__);
- llc_conn_free_ev(skb);
+ kfree_skb(skb);
} else {
if (!sk->lock.users)
llc_conn_state_process(sk, skb);
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index aedb5ce61150..e20cec698566 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -367,31 +367,6 @@ static void llc_conn_send_pdus(struct sock *sk)
}
/**
- * llc_conn_free_ev - free event
- * @skb: event to free
- *
- * Free allocated event.
- */
-void llc_conn_free_ev(struct sk_buff *skb)
-{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-
- if (ev->type == LLC_CONN_EV_TYPE_PDU) {
- /* free the frame that is bound to this event */
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
-
- if (LLC_PDU_TYPE_IS_I(pdu) || !ev->ind_prim)
- kfree_skb(skb);
- } else if (ev->type == LLC_CONN_EV_TYPE_PRIM &&
- ev->prim != LLC_DATA_PRIM)
- kfree_skb(skb);
- else if (ev->type == LLC_CONN_EV_TYPE_P_TMR ||
- ev->type == LLC_CONN_EV_TYPE_BUSY_TMR ||
- ev->type == LLC_CONN_EV_TYPE_REJ_TMR)
- kfree_skb(skb);
-}
-
-/**
* llc_conn_service - finds transition and changes state of connection
* @sk: connection
* @skb: happened event
diff --git a/net/llc/llc_main.c b/net/llc/llc_main.c
index 044fce7207e7..f7b54e15882d 100644
--- a/net/llc/llc_main.c
+++ b/net/llc/llc_main.c
@@ -147,20 +147,22 @@ static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
if (llc->state > 1) /* not closed */
rc = llc_conn_rcv(sk, skb);
else
- kfree_skb(skb);
+ goto out_kfree_skb;
} else if (llc_backlog_type(skb) == LLC_EVENT) {
/* timer expiration event */
if (llc->state > 1) /* not closed */
rc = llc_conn_state_process(sk, skb);
else
- llc_conn_free_ev(skb);
- kfree_skb(skb);
+ goto out_kfree_skb;
} else {
printk(KERN_ERR "%s: invalid skb in backlog\n", __FUNCTION__);
- kfree_skb(skb);
+ goto out_kfree_skb;
}
-
+out:
return rc;
+out_kfree_skb:
+ kfree_skb(skb);
+ goto out;
}
/**