diff options
| author | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 2002-09-30 06:46:43 -0300 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 2002-09-30 06:46:43 -0300 |
| commit | af19bc3ddb6de0c1a3b33ef0ce61377ea5075447 (patch) | |
| tree | 6fa189adeb89a6c1bbe1ed2c826e529e7eb2f725 | |
| parent | 92e153dbaa302c69877d8daa48fb7d373b546048 (diff) | |
o LLC: grab the skb in llc_conn_state_event, use llc_pdu_sn_hdr
| -rw-r--r-- | net/llc/llc_conn.c | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 161cff1c450b..aedb5ce61150 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -71,6 +71,12 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) struct llc_opt *llc = llc_sk(sk); struct llc_conn_state_ev *ev = llc_conn_ev(skb); + /* + * We have to hold the skb, because llc_conn_service will kfree it in + * the sending path and we need to look at the skb->cb, where we encode + * llc_conn_state_ev. + */ + skb_get(skb); ev->ind_prim = ev->cfm_prim = 0; rc = llc_conn_service(sk, skb); /* sending event to state machine */ if (rc) { @@ -81,10 +87,10 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) if (!ev->ind_prim && !ev->cfm_prim) { /* indicate or confirm not required */ if (!skb->list) goto out_kfree_skb; - goto out; + goto out_skb_put; } - if (ev->ind_prim && ev->cfm_prim) + if (ev->ind_prim && ev->cfm_prim) /* Paranoia */ skb_get(skb); switch (ev->ind_prim) { @@ -180,11 +186,12 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) __FUNCTION__, ev->cfm_prim); break; } - goto out; /* No confirmation */ + goto out_skb_put; /* No confirmation */ } out_kfree_skb: kfree_skb(skb); -out: +out_skb_put: + kfree_skb(skb); return rc; } @@ -226,25 +233,29 @@ void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit) struct sk_buff *skb; struct llc_pdu_sn *pdu; u16 nbr_unack_pdus; + struct llc_opt *llc; u8 howmany_resend = 0; llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus); if (!nbr_unack_pdus) goto out; - /* process unack PDUs only if unack queue is not empty; remove + /* + * Process unack PDUs only if unack queue is not empty; remove * appropriate PDUs, fix them up, and put them on mac_pdu_q. */ - while ((skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q)) != NULL) { - pdu = (struct llc_pdu_sn *)skb->nh.raw; + llc = llc_sk(sk); + + while ((skb = skb_dequeue(&llc->pdu_unack_q)) != NULL) { + pdu = llc_pdu_sn_hdr(skb); llc_pdu_set_cmd_rsp(skb, LLC_PDU_CMD); llc_pdu_set_pf_bit(skb, first_p_bit); skb_queue_tail(&sk->write_queue, skb); first_p_bit = 0; - llc_sk(sk)->vS = LLC_I_GET_NS(pdu); + llc->vS = LLC_I_GET_NS(pdu); howmany_resend++; } if (howmany_resend > 0) - llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO; + llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO; /* any PDUs to re-send are queued up; start sending to MAC */ llc_conn_send_pdus(sk); out:; @@ -263,27 +274,29 @@ out:; void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit) { struct sk_buff *skb; - struct llc_pdu_sn *pdu; u16 nbr_unack_pdus; + struct llc_opt *llc = llc_sk(sk); u8 howmany_resend = 0; llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus); if (!nbr_unack_pdus) goto out; - /* process unack PDUs only if unack queue is not empty; remove + /* + * Process unack PDUs only if unack queue is not empty; remove * appropriate PDUs, fix them up, and put them on mac_pdu_q */ - while ((skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q)) != NULL) { - pdu = (struct llc_pdu_sn *)skb->nh.raw; + while ((skb = skb_dequeue(&llc->pdu_unack_q)) != NULL) { + struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); + llc_pdu_set_cmd_rsp(skb, LLC_PDU_RSP); llc_pdu_set_pf_bit(skb, first_f_bit); skb_queue_tail(&sk->write_queue, skb); first_f_bit = 0; - llc_sk(sk)->vS = LLC_I_GET_NS(pdu); + llc->vS = LLC_I_GET_NS(pdu); howmany_resend++; } if (howmany_resend > 0) - llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO; + llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO; /* any PDUs to re-send are queued up; start sending to MAC */ llc_conn_send_pdus(sk); out:; @@ -304,25 +317,26 @@ int llc_conn_remove_acked_pdus(struct sock *sk, u8 nr, u16 *how_many_unacked) struct sk_buff *skb; struct llc_pdu_sn *pdu; int nbr_acked = 0; - int q_len = skb_queue_len(&llc_sk(sk)->pdu_unack_q); + struct llc_opt *llc = llc_sk(sk); + int q_len = skb_queue_len(&llc->pdu_unack_q); if (!q_len) goto out; - skb = skb_peek(&llc_sk(sk)->pdu_unack_q); - pdu = (struct llc_pdu_sn *)skb->nh.raw; + skb = skb_peek(&llc->pdu_unack_q); + pdu = llc_pdu_sn_hdr(skb); /* finding position of last acked pdu in queue */ pdu_pos = ((int)LLC_2_SEQ_NBR_MODULO + (int)nr - (int)LLC_I_GET_NS(pdu)) % LLC_2_SEQ_NBR_MODULO; for (i = 0; i < pdu_pos && i < q_len; i++) { - skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q); + skb = skb_dequeue(&llc->pdu_unack_q); if (skb) kfree_skb(skb); nbr_acked++; } out: - *how_many_unacked = skb_queue_len(&llc_sk(sk)->pdu_unack_q); + *how_many_unacked = skb_queue_len(&llc->pdu_unack_q); return nbr_acked; } @@ -337,7 +351,7 @@ static void llc_conn_send_pdus(struct sock *sk) struct sk_buff *skb; while ((skb = skb_dequeue(&sk->write_queue)) != NULL) { - struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw; + struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); if (!LLC_PDU_TYPE_IS_I(pdu) && !(skb->dev->flags & IFF_LOOPBACK)) { |
