diff options
| author | David S. Miller <davem@nuts.ninka.net> | 2002-09-30 00:05:51 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.ninka.net> | 2002-09-30 00:05:51 -0700 |
| commit | 4e87a098903d4de48f6b43f6a5d52c59b3bbeb6e (patch) | |
| tree | 5c363e21ae28f4021cf8f2a48fae815e9bfde987 | |
| parent | f32a9e2a558d518a39f73d56a93529c2df1d4666 (diff) | |
| parent | c96542edd5bf18453a433ffb149c3cb8977f8a28 (diff) | |
Merge master.kernel.org:/home/acme/BK/llc-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
| -rw-r--r-- | include/net/llc_conn.h | 1 | ||||
| -rw-r--r-- | include/net/llc_mac.h | 2 | ||||
| -rw-r--r-- | net/llc/af_llc.c | 7 | ||||
| -rw-r--r-- | net/llc/llc_c_ac.c | 2 | ||||
| -rw-r--r-- | net/llc/llc_conn.c | 81 | ||||
| -rw-r--r-- | net/llc/llc_if.c | 1 | ||||
| -rw-r--r-- | net/llc/llc_mac.c | 24 | ||||
| -rw-r--r-- | net/llc/llc_main.c | 12 | ||||
| -rw-r--r-- | net/llc/llc_pdu.c | 1 | ||||
| -rw-r--r-- | net/llc/llc_sap.c | 154 |
10 files changed, 124 insertions, 161 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/include/net/llc_mac.h b/include/net/llc_mac.h index e87850701db6..ded7c830b8a8 100644 --- a/include/net/llc_mac.h +++ b/include/net/llc_mac.h @@ -13,8 +13,6 @@ */ extern int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt); -extern struct net_device *mac_dev_peer(struct net_device *current_dev, - int type, u8 *mac); extern u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da); extern int llc_conn_rcv(struct sock *sk, struct sk_buff *skb); 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 161cff1c450b..e20cec698566 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)) { @@ -353,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_if.c b/net/llc/llc_if.c index ee1f20a51958..1f1d241732a6 100644 --- a/net/llc/llc_if.c +++ b/net/llc/llc_if.c @@ -26,7 +26,6 @@ #include <net/llc_c_ac.h> #include <net/llc_c_st.h> #include <net/llc_main.h> -#include <net/llc_mac.h> /** * llc_sap_open - open interface to the upper layers. diff --git a/net/llc/llc_mac.c b/net/llc/llc_mac.c index 7015d55ce748..ae97f73a607b 100644 --- a/net/llc/llc_mac.c +++ b/net/llc/llc_mac.c @@ -294,27 +294,3 @@ u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da) } return rc; } - -/** - * mac_dev_peer - search the appropriate dev to send packets to peer - * @current_dev - Current device suggested by upper layer - * @type - hardware type - * @mac - mac address - * - * Check if the we should use loopback to send packets, i.e., if the - * dmac belongs to one of the local interfaces, returning the pointer - * to the loopback &net_device struct or the current_dev if it is not - * local. - */ -struct net_device *mac_dev_peer(struct net_device *current_dev, int type, - u8 *mac) -{ - struct net_device *dev; - - rtnl_lock(); - dev = dev_getbyhwaddr(type, mac); - if (dev) - dev = __dev_get_by_name("lo"); - rtnl_unlock(); - return dev ? : current_dev; -} 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; } /** diff --git a/net/llc/llc_pdu.c b/net/llc/llc_pdu.c index 069ec96c9312..b5d047e9154f 100644 --- a/net/llc/llc_pdu.c +++ b/net/llc/llc_pdu.c @@ -15,7 +15,6 @@ #include <linux/if_tr.h> #include <net/llc_pdu.h> #include <net/llc_if.h> -#include <net/llc_mac.h> #include <net/llc_main.h> static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type); diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index 28ae6a659658..7cd6bb115a8b 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -20,17 +20,9 @@ #include <net/sock.h> #include <linux/tcp.h> #include <net/llc_main.h> -#include <net/llc_mac.h> #include <net/llc_pdu.h> #include <linux/if_tr.h> -static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb); -static int llc_exec_sap_trans_actions(struct llc_sap *sap, - struct llc_sap_state_trans *trans, - struct sk_buff *skb); -static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap, - struct sk_buff *skb); - /** * llc_sap_assign_sock - adds a connection to a SAP * @sap: pointer to SAP. @@ -76,51 +68,15 @@ void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk) } /** - * llc_sap_state_process - sends event to SAP state machine - * @sap: sap to use - * @skb: pointer to occurred event - * - * After executing actions of the event, upper layer will be indicated - * if needed(on receiving an UI frame). sk can be null for the - * datalink_proto case. - */ -void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) -{ - struct llc_sap_state_ev *ev = llc_sap_ev(skb); - - /* - * We have to hold the skb, because llc_sap_next_state - * will kfree it in the sending path and we need to - * look at the skb->cb, where we encode llc_sap_state_ev. - */ - skb_get(skb); - ev->ind_cfm_flag = 0; - llc_sap_next_state(sap, skb); - if (ev->ind_cfm_flag == LLC_IND) { - if (skb->sk->state == TCP_LISTEN) - kfree_skb(skb); - else { - llc_save_primitive(skb, ev->prim); - - /* queue skb to the user. */ - if (sock_queue_rcv_skb(skb->sk, skb)) - kfree_skb(skb); - } - } - kfree_skb(skb); -} - -/** * llc_sap_rtn_pdu - Informs upper layer on rx of an UI, XID or TEST pdu. * @sap: pointer to SAP * @skb: received pdu */ void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb) { - struct llc_pdu_un *pdu; struct llc_sap_state_ev *ev = llc_sap_ev(skb); + struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); - pdu = llc_pdu_un_hdr(skb); switch (LLC_U_PDU_RSP(pdu)) { case LLC_1_PDU_CMD_TEST: ev->prim = LLC_TEST_PRIM; break; @@ -133,38 +89,6 @@ void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb) } /** - * llc_sap_next_state - finds transition, execs actions & change SAP state - * @sap: pointer to SAP - * @skb: happened event - * - * This function finds transition that matches with happened event, then - * executes related actions and finally changes state of SAP. It returns - * 0 on success and 1 for failure. - */ -static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb) -{ - int rc = 1; - struct llc_sap_state_trans *trans; - - if (sap->state <= LLC_NR_SAP_STATES) { - trans = llc_find_sap_trans(sap, skb); - if (trans) { - /* got the state to which we next transition; perform - * the actions associated with this transition before - * actually transitioning to the next state - */ - rc = llc_exec_sap_trans_actions(sap, trans, skb); - if (!rc) - /* transition SAP to next state if all actions - * execute successfully - */ - sap->state = trans->next_state; - } - } - return rc; -} - -/** * llc_find_sap_trans - finds transition for event * @sap: pointer to SAP * @skb: happened event @@ -180,13 +104,13 @@ static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap, struct llc_sap_state_trans *rc = NULL; struct llc_sap_state_trans **next_trans; struct llc_sap_state *curr_state = &llc_sap_state_table[sap->state - 1]; - /* search thru events for this state until list exhausted or until + /* + * Search thru events for this state until list exhausted or until * its obvious the event is not valid for the current state */ for (next_trans = curr_state->transitions; next_trans[i]->ev; i++) if (!next_trans[i]->ev(sap, skb)) { - /* got event match; return it */ - rc = next_trans[i]; + rc = next_trans[i]; /* got event match; return it */ break; } return rc; @@ -213,3 +137,73 @@ static int llc_exec_sap_trans_actions(struct llc_sap *sap, rc = 1; return rc; } + +/** + * llc_sap_next_state - finds transition, execs actions & change SAP state + * @sap: pointer to SAP + * @skb: happened event + * + * This function finds transition that matches with happened event, then + * executes related actions and finally changes state of SAP. It returns + * 0 on success and 1 for failure. + */ +static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb) +{ + int rc = 1; + struct llc_sap_state_trans *trans; + + if (sap->state > LLC_NR_SAP_STATES) + goto out; + trans = llc_find_sap_trans(sap, skb); + if (!trans) + goto out; + /* + * Got the state to which we next transition; perform the actions + * associated with this transition before actually transitioning to the + * next state + */ + rc = llc_exec_sap_trans_actions(sap, trans, skb); + if (rc) + goto out; + /* + * Transition SAP to next state if all actions execute successfully + */ + sap->state = trans->next_state; +out: + return rc; +} + +/** + * llc_sap_state_process - sends event to SAP state machine + * @sap: sap to use + * @skb: pointer to occurred event + * + * After executing actions of the event, upper layer will be indicated + * if needed(on receiving an UI frame). sk can be null for the + * datalink_proto case. + */ +void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) +{ + struct llc_sap_state_ev *ev = llc_sap_ev(skb); + + /* + * We have to hold the skb, because llc_sap_next_state + * will kfree it in the sending path and we need to + * look at the skb->cb, where we encode llc_sap_state_ev. + */ + skb_get(skb); + ev->ind_cfm_flag = 0; + llc_sap_next_state(sap, skb); + if (ev->ind_cfm_flag == LLC_IND) { + if (skb->sk->state == TCP_LISTEN) + kfree_skb(skb); + else { + llc_save_primitive(skb, ev->prim); + + /* queue skb to the user. */ + if (sock_queue_rcv_skb(skb->sk, skb)) + kfree_skb(skb); + } + } + kfree_skb(skb); +} |
