diff options
| author | David S. Miller <davem@nuts.ninka.net> | 2002-09-18 22:14:48 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.ninka.net> | 2002-09-18 22:14:48 -0700 |
| commit | b5fbb36cb06821439b5932c1b56620c0db580237 (patch) | |
| tree | 19835bfe98169e5194af0e7d6944ec0fd8cdadb0 | |
| parent | 8188258ccab58a99b9e4bf16e9cbfe0b704b628c (diff) | |
| parent | 2ecd16f0147c6e8cd2299882a5dfb367e06e188b (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_actn.h | 1 | ||||
| -rw-r--r-- | include/net/llc_c_ac.h | 5 | ||||
| -rw-r--r-- | include/net/llc_c_ev.h | 9 | ||||
| -rw-r--r-- | include/net/llc_main.h | 2 | ||||
| -rw-r--r-- | net/llc/llc_actn.c | 10 | ||||
| -rw-r--r-- | net/llc/llc_c_ac.c | 57 | ||||
| -rw-r--r-- | net/llc/llc_c_ev.c | 18 | ||||
| -rw-r--r-- | net/llc/llc_main.c | 84 | ||||
| -rw-r--r-- | net/llc/llc_sock.c | 6 |
9 files changed, 114 insertions, 78 deletions
diff --git a/include/net/llc_actn.h b/include/net/llc_actn.h index 28d2873f5065..3619601c4c81 100644 --- a/include/net/llc_actn.h +++ b/include/net/llc_actn.h @@ -45,4 +45,5 @@ extern int llc_station_ac_report_status(struct llc_station *station, struct sk_buff *skb); extern int llc_station_ac_report_status(struct llc_station *station, struct sk_buff *skb); +extern void llc_station_ack_tmr_cb(unsigned long timeout_data); #endif /* LLC_ACTN_H */ diff --git a/include/net/llc_c_ac.h b/include/net/llc_c_ac.h index 1d2facdf212b..221899a24530 100644 --- a/include/net/llc_c_ac.h +++ b/include/net/llc_c_ac.h @@ -211,4 +211,9 @@ extern int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock* sk, struct sk_buff *skb); extern int llc_conn_ac_send_i_rsp_as_ack(struct sock* sk, struct sk_buff *skb); extern int llc_conn_ac_send_i_as_ack(struct sock* sk, struct sk_buff *skb); + +extern void llc_conn_busy_tmr_cb(unsigned long timeout_data); +extern void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data); +extern void llc_conn_ack_tmr_cb(unsigned long timeout_data); +extern void llc_conn_rej_tmr_cb(unsigned long timeout_data); #endif /* LLC_C_AC_H */ diff --git a/include/net/llc_c_ev.h b/include/net/llc_c_ev.h index 5fe315ebcc7c..795cb74166a5 100644 --- a/include/net/llc_c_ev.h +++ b/include/net/llc_c_ev.h @@ -11,6 +11,9 @@ * * See the GNU General Public License for more details. */ + +#include <net/sock.h> + /* Connection component state transition event qualifiers */ /* Types of events (possible values in 'ev->type') */ #define LLC_CONN_EV_TYPE_SIMPLE 1 @@ -293,4 +296,10 @@ extern int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb); extern int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb); + +static __inline__ int llc_conn_space(struct sock *sk, struct sk_buff *skb) +{ + return atomic_read(&sk->rmem_alloc) + skb->truesize < + (unsigned)sk->rcvbuf; +} #endif /* LLC_C_EV_H */ diff --git a/include/net/llc_main.h b/include/net/llc_main.h index e3b0c7a09caa..25d486278da4 100644 --- a/include/net/llc_main.h +++ b/include/net/llc_main.h @@ -16,7 +16,7 @@ #define LLC_TYPE_1 1 #define LLC_TYPE_2 2 #define LLC_P_TIME 2 -#define LLC_ACK_TIME 3 +#define LLC_ACK_TIME 1 #define LLC_REJ_TIME 3 #define LLC_BUSY_TIME 3 #define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */ diff --git a/net/llc/llc_actn.c b/net/llc/llc_actn.c index 0577ea70eba4..07f144745113 100644 --- a/net/llc/llc_actn.c +++ b/net/llc/llc_actn.c @@ -24,16 +24,10 @@ #include <net/llc_pdu.h> #include <net/llc_mac.h> -static void llc_station_ack_tmr_callback(unsigned long timeout_data); - int llc_station_ac_start_ack_timer(struct llc_station *station, struct sk_buff *skb) { - del_timer(&station->ack_timer); - station->ack_timer.expires = jiffies + LLC_ACK_TIME * HZ; - station->ack_timer.data = (unsigned long)station; - station->ack_timer.function = llc_station_ack_tmr_callback; - add_timer(&station->ack_timer); + mod_timer(&station->ack_timer, jiffies + LLC_ACK_TIME * HZ); return 0; } @@ -130,7 +124,7 @@ int llc_station_ac_report_status(struct llc_station *station, return 0; } -static void llc_station_ack_tmr_callback(unsigned long timeout_data) +void llc_station_ack_tmr_cb(unsigned long timeout_data) { struct llc_station *station = (struct llc_station *)timeout_data; struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index c0d872652363..b53e5ec3de5f 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -28,10 +28,6 @@ #include <net/llc_pdu.h> #include <net/llc_mac.h> -static void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data); -static void llc_conn_ack_tmr_cb(unsigned long timeout_data); -static void llc_conn_rej_tmr_cb(unsigned long timeout_data); -static void llc_conn_busy_tmr_cb(unsigned long timeout_data); static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb); static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb); static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *ev); @@ -664,11 +660,8 @@ int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb) if (!llc->remote_busy_flag) { llc->remote_busy_flag = 1; - llc->busy_state_timer.timer.expires = jiffies + - llc->busy_state_timer.expire * HZ; - llc->busy_state_timer.timer.data = (unsigned long)sk; - llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb; - add_timer(&llc->busy_state_timer.timer); + mod_timer(&llc->busy_state_timer.timer, + jiffies + llc->busy_state_timer.expire * HZ); } return 0; } @@ -905,12 +898,8 @@ int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb) struct llc_opt *llc = llc_sk(sk); llc->p_flag = 1; - del_timer(&llc->pf_cycle_timer.timer); - llc->pf_cycle_timer.timer.expires = jiffies + - llc->pf_cycle_timer.expire * HZ; - llc->pf_cycle_timer.timer.data = (unsigned long)sk; - llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb; - add_timer(&llc->pf_cycle_timer.timer); + mod_timer(&llc->pf_cycle_timer.timer, + jiffies + llc->pf_cycle_timer.expire * HZ); return 0; } @@ -1181,11 +1170,7 @@ int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb) { struct llc_opt *llc = llc_sk(sk); - del_timer(&llc->ack_timer.timer); - llc->ack_timer.timer.expires = jiffies + llc->ack_timer.expire * HZ; - llc->ack_timer.timer.data = (unsigned long)sk; - llc->ack_timer.timer.function = llc_conn_ack_tmr_cb; - add_timer(&llc->ack_timer.timer); + mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire * HZ); return 0; } @@ -1193,12 +1178,8 @@ int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb) { struct llc_opt *llc = llc_sk(sk); - del_timer(&llc->rej_sent_timer.timer); - llc->rej_sent_timer.timer.expires = jiffies + - llc->rej_sent_timer.expire * HZ; - llc->rej_sent_timer.timer.data = (unsigned long)sk; - llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb; - add_timer(&llc->rej_sent_timer.timer); + mod_timer(&llc->rej_sent_timer.timer, + jiffies + llc->rej_sent_timer.expire * HZ); return 0; } @@ -1207,13 +1188,9 @@ int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk, { struct llc_opt *llc = llc_sk(sk); - if (!timer_pending(&llc->ack_timer.timer)) { - llc->ack_timer.timer.expires = jiffies + - llc->ack_timer.expire * HZ; - llc->ack_timer.timer.data = (unsigned long)sk; - llc->ack_timer.timer.function = llc_conn_ack_tmr_cb; - add_timer(&llc->ack_timer.timer); - } + if (!timer_pending(&llc->ack_timer.timer)) + mod_timer(&llc->ack_timer.timer, + jiffies + llc->ack_timer.expire * HZ); return 0; } @@ -1260,13 +1237,9 @@ int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb) llc->failed_data_req = 0; llc_conn_ac_data_confirm(sk, skb); } - if (unacked) { - llc->ack_timer.timer.expires = jiffies + - llc->ack_timer.expire * HZ; - llc->ack_timer.timer.data = (unsigned long)sk; - llc->ack_timer.timer.function = llc_conn_ack_tmr_cb; - add_timer(&llc->ack_timer.timer); - } + if (unacked) + mod_timer(&llc->ack_timer.timer, + jiffies + llc->ack_timer.expire * HZ); } else if (llc->failed_data_req) { llc_pdu_decode_pf_bit(skb, &fbit); if (fbit == 1) { @@ -1413,7 +1386,7 @@ void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data) bh_unlock_sock(sk); } -static void llc_conn_busy_tmr_cb(unsigned long timeout_data) +void llc_conn_busy_tmr_cb(unsigned long timeout_data) { struct sock *sk = (struct sock *)timeout_data; struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); @@ -1445,7 +1418,7 @@ void llc_conn_ack_tmr_cb(unsigned long timeout_data) bh_unlock_sock(sk); } -static void llc_conn_rej_tmr_cb(unsigned long timeout_data) +void llc_conn_rej_tmr_cb(unsigned long timeout_data) { struct sock *sk = (struct sock *)timeout_data; struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); diff --git a/net/llc/llc_c_ev.c b/net/llc/llc_c_ev.c index 9b455714143a..9c699fb6b815 100644 --- a/net/llc/llc_c_ev.c +++ b/net/llc/llc_c_ev.c @@ -194,7 +194,8 @@ int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); - return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + return llc_conn_space(sk, skb) && + !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && !LLC_I_PF_IS_0(pdu) && LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; } @@ -203,7 +204,8 @@ int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); - return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + return llc_conn_space(sk, skb) && + !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && !LLC_I_PF_IS_1(pdu) && LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; } @@ -250,7 +252,8 @@ int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); - return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + return llc_conn_space(sk, skb) && + !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && !LLC_I_PF_IS_0(pdu) && LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; } @@ -268,7 +271,8 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); - return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && + return llc_conn_space(sk, skb) && + !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; } @@ -423,7 +427,8 @@ int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); - return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + return llc_conn_space(sk, skb) && + !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && !LLC_S_PF_IS_0(pdu) && LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1; } @@ -432,7 +437,8 @@ int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); - return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && + return llc_conn_space(sk, skb) && + !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) && !LLC_S_PF_IS_1(pdu) && LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1; } diff --git a/net/llc/llc_main.c b/net/llc/llc_main.c index cdb0b6e6020b..ecc52456fff6 100644 --- a/net/llc/llc_main.c +++ b/net/llc/llc_main.c @@ -184,19 +184,32 @@ int llc_sk_init(struct sock* sk) goto out; memset(llc, 0, sizeof(*llc)); rc = 0; - llc->sk = sk; - llc->state = LLC_CONN_STATE_ADM; - llc->inc_cntr = llc->dec_cntr = 2; - llc->dec_step = llc->connect_step = 1; - llc->ack_timer.expire = LLC_ACK_TIME; - llc->pf_cycle_timer.expire = LLC_P_TIME; - llc->rej_sent_timer.expire = LLC_REJ_TIME; - llc->busy_state_timer.expire = LLC_BUSY_TIME; - llc->n2 = 2; /* max retransmit */ - llc->k = 2; /* tx win size, will adjust dynam */ - llc->rw = 128; /* rx win size (opt and equal to - * tx_win of remote LLC) - */ + + llc->sk = sk; + llc->state = LLC_CONN_STATE_ADM; + llc->inc_cntr = llc->dec_cntr = 2; + llc->dec_step = llc->connect_step = 1; + + llc->ack_timer.expire = LLC_ACK_TIME; + llc->ack_timer.timer.data = (unsigned long)sk; + llc->ack_timer.timer.function = llc_conn_ack_tmr_cb; + + llc->pf_cycle_timer.expire = LLC_P_TIME; + llc->pf_cycle_timer.timer.data = (unsigned long)sk; + llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb; + + llc->rej_sent_timer.expire = LLC_REJ_TIME; + llc->rej_sent_timer.timer.data = (unsigned long)sk; + llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb; + + llc->busy_state_timer.expire = LLC_BUSY_TIME; + llc->busy_state_timer.timer.data = (unsigned long)sk; + llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb; + + llc->n2 = 2; /* max retransmit */ + llc->k = 2; /* tx win size, will adjust dynam */ + llc->rw = 128; /* rx win size (opt and equal to + * tx_win of remote LLC) */ skb_queue_head_init(&llc->pdu_unack_q); sk->backlog_rcv = llc_backlog_rcv; llc_sk(sk) = llc; @@ -534,6 +547,21 @@ struct sk_buff *llc_alloc_frame(void) return skb; } +static char *llc_conn_state_names[] = { + [LLC_CONN_STATE_ADM] = "adm", + [LLC_CONN_STATE_SETUP] = "setup", + [LLC_CONN_STATE_NORMAL] = "normal", + [LLC_CONN_STATE_BUSY] = "busy", + [LLC_CONN_STATE_REJ] = "rej", + [LLC_CONN_STATE_AWAIT] = "await", + [LLC_CONN_STATE_AWAIT_BUSY] = "await_busy", + [LLC_CONN_STATE_AWAIT_REJ] = "await_rej", + [LLC_CONN_STATE_D_CONN] = "d_conn", + [LLC_CONN_STATE_RESET] = "reset", + [LLC_CONN_STATE_ERROR] = "error", + [LLC_CONN_STATE_TEMP] = "temp", +}; + static int llc_proc_get_info(char *bf, char **start, off_t offset, int length) { struct llc_opt *llc; @@ -546,19 +574,34 @@ static int llc_proc_get_info(char *bf, char **start, off_t offset, int length) struct llc_sap *sap = list_entry(sap_entry, struct llc_sap, node); - len += sprintf(bf + len, "lsap=%d\n", sap->laddr.lsap); + len += sprintf(bf + len, "lsap=%02X\n", sap->laddr.lsap); spin_lock_bh(&sap->sk_list.lock); if (list_empty(&sap->sk_list.list)) { len += sprintf(bf + len, "no connections\n"); goto unlock; } - len += sprintf(bf + len, - "connection list:\nstate retr txwin rxwin\n"); + len += sprintf(bf + len, "connection list:\n" + "dsap state retr txw rxw " + "pf ff sf df rs cs " + "tack tpfc trs tbs blog busr\n"); list_for_each(llc_entry, &sap->sk_list.list) { llc = list_entry(llc_entry, struct llc_opt, node); - len += sprintf(bf + len, " %-5d%-5d%-6d%-5d\n", - llc->state, llc->retry_count, llc->k, - llc->rw); + len += sprintf(bf + len, " %02X %-10s %3d %3d %3d " + "%2d %2d %2d " + "%2d %2d %2d " + "%4d %4d %3d %3d %4d %4d\n", + llc->daddr.lsap, + llc_conn_state_names[llc->state], + llc->retry_count, llc->k, llc->rw, + llc->p_flag, llc->f_flag, llc->s_flag, + llc->data_flag, llc->remote_busy_flag, + llc->cause_flag, + timer_pending(&llc->ack_timer.timer), + timer_pending(&llc->pf_cycle_timer.timer), + timer_pending(&llc->rej_sent_timer.timer), + timer_pending(&llc->busy_state_timer.timer), + !!llc->sk->backlog.tail, + llc->sk->lock.users); } unlock: spin_unlock_bh(&sap->sk_list.lock); @@ -608,6 +651,9 @@ static int __init llc_init(void) skb_queue_head_init(&llc_main_station.mac_pdu_q); skb_queue_head_init(&llc_main_station.ev_q.list); spin_lock_init(&llc_main_station.ev_q.lock); + llc_main_station.ack_timer.data = (unsigned long)&llc_main_station; + llc_main_station.ack_timer.function = llc_station_ack_tmr_cb; + skb = alloc_skb(0, GFP_ATOMIC); if (!skb) goto err; diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c index 12e6546f643e..81d975278085 100644 --- a/net/llc/llc_sock.c +++ b/net/llc/llc_sock.c @@ -360,11 +360,11 @@ static int llc_ui_release(struct socket *sock) llc->laddr.lsap, llc->daddr.lsap); if (!llc_send_disc(sk)) llc_ui_wait_for_disc(sk, sk->rcvtimeo); - release_sock(sk); if (!sk->zapped) { llc_sap_unassign_sock(llc->sap, sk); llc_ui_remove_socket(sk); } + release_sock(sk); if (llc->sap && list_empty(&llc->sap->sk_list.list)) llc_sap_close(llc->sap); sock_put(sk); @@ -484,10 +484,10 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) llc->daddr.lsap = addr->sllc_dsap; memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN); memcpy(&llc->addr, addr, sizeof(llc->addr)); - rc = sk->zapped = 0; llc_ui_insert_socket(sk); /* assign new connection to it's SAP */ llc_sap_assign_sock(sap, sk); + rc = sk->zapped = 0; out: return rc; } @@ -952,7 +952,9 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, if (size > dev->mtu) size = dev->mtu; copied = size - hdrlen; + release_sock(sk); skb = sock_alloc_send_skb(sk, size, noblock, &rc); + lock_sock(sk); if (!skb) goto release; skb->sk = sk; |
