summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.ninka.net>2002-09-18 22:14:48 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2002-09-18 22:14:48 -0700
commitb5fbb36cb06821439b5932c1b56620c0db580237 (patch)
tree19835bfe98169e5194af0e7d6944ec0fd8cdadb0
parent8188258ccab58a99b9e4bf16e9cbfe0b704b628c (diff)
parent2ecd16f0147c6e8cd2299882a5dfb367e06e188b (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.h1
-rw-r--r--include/net/llc_c_ac.h5
-rw-r--r--include/net/llc_c_ev.h9
-rw-r--r--include/net/llc_main.h2
-rw-r--r--net/llc/llc_actn.c10
-rw-r--r--net/llc/llc_c_ac.c57
-rw-r--r--net/llc/llc_c_ev.c18
-rw-r--r--net/llc/llc_main.c84
-rw-r--r--net/llc/llc_sock.c6
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;