summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@conectiva.com.br>2002-09-19 09:38:37 -0300
committerDavid S. Miller <davem@nuts.ninka.net>2002-09-19 09:38:37 -0300
commit2ecd16f0147c6e8cd2299882a5dfb367e06e188b (patch)
treea770abd2d30a14a992793f402a49c179d50901e3
parent7e17bc3e4edf9df86be1df69043b976d2baa9609 (diff)
[LLC] check if we have space in the socket to receive the packet
Now we have llc_conn_space and use it to see if we can accept the packet in the core llc state machine. Transfers of 80 megabytes now are safe 8)
-rw-r--r--include/net/llc_c_ev.h9
-rw-r--r--net/llc/llc_c_ev.c18
2 files changed, 21 insertions, 6 deletions
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/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;
}