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.
parent af19bc3d
......@@ -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,
......
......@@ -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);
......
......@@ -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);
......
......@@ -366,31 +366,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
......
......@@ -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;
}
/**
......
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