diff options
| -rw-r--r-- | include/net/llc_c_ev.h | 9 | ||||
| -rw-r--r-- | net/llc/llc_c_ev.c | 18 |
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; } |
