| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * llc_c_ev.c - Connection component state transition event qualifiers | 
 | 3 |  * | 
 | 4 |  * A 'state' consists of a number of possible event matching functions, | 
 | 5 |  * the actions associated with each being executed when that event is | 
 | 6 |  * matched; a 'state machine' accepts events in a serial fashion from an | 
 | 7 |  * event queue. Each event is passed to each successive event matching | 
 | 8 |  * function until a match is made (the event matching function returns | 
 | 9 |  * success, or '0') or the list of event matching functions is exhausted. | 
 | 10 |  * If a match is made, the actions associated with the event are executed | 
 | 11 |  * and the state is changed to that event's transition state. Before some | 
 | 12 |  * events are recognized, even after a match has been made, a certain | 
 | 13 |  * number of 'event qualifier' functions must also be executed. If these | 
 | 14 |  * all execute successfully, then the event is finally executed. | 
 | 15 |  * | 
 | 16 |  * These event functions must return 0 for success, to show a matched | 
 | 17 |  * event, of 1 if the event does not match. Event qualifier functions | 
 | 18 |  * must return a 0 for success or a non-zero for failure. Each function | 
 | 19 |  * is simply responsible for verifying one single thing and returning | 
 | 20 |  * either a success or failure. | 
 | 21 |  * | 
 | 22 |  * All of followed event functions are described in 802.2 LLC Protocol | 
 | 23 |  * standard document except two functions that we added that will explain | 
 | 24 |  * in their comments, at below. | 
 | 25 |  * | 
 | 26 |  * Copyright (c) 1997 by Procom Technology, Inc. | 
 | 27 |  * 		 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 
 | 28 |  * | 
 | 29 |  * This program can be redistributed or modified under the terms of the | 
 | 30 |  * GNU General Public License as published by the Free Software Foundation. | 
 | 31 |  * This program is distributed without any warranty or implied warranty | 
 | 32 |  * of merchantability or fitness for a particular purpose. | 
 | 33 |  * | 
 | 34 |  * See the GNU General Public License for more details. | 
 | 35 |  */ | 
 | 36 | #include <linux/netdevice.h> | 
 | 37 | #include <net/llc_conn.h> | 
 | 38 | #include <net/llc_sap.h> | 
 | 39 | #include <net/sock.h> | 
| Arnaldo Carvalho de Melo | 72b1ad4 | 2005-09-22 04:19:52 -0300 | [diff] [blame] | 40 | #include <net/llc_c_ac.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 41 | #include <net/llc_c_ev.h> | 
 | 42 | #include <net/llc_pdu.h> | 
 | 43 |  | 
 | 44 | #if 1 | 
 | 45 | #define dprintk(args...) printk(KERN_DEBUG args) | 
 | 46 | #else | 
 | 47 | #define dprintk(args...) | 
 | 48 | #endif | 
 | 49 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 50 | /** | 
 | 51 |  *	llc_util_ns_inside_rx_window - check if sequence number is in rx window | 
 | 52 |  *	@ns: sequence number of received pdu. | 
 | 53 |  *	@vr: sequence number which receiver expects to receive. | 
 | 54 |  *	@rw: receive window size of receiver. | 
 | 55 |  * | 
 | 56 |  *	Checks if sequence number of received PDU is in range of receive | 
 | 57 |  *	window. Returns 0 for success, 1 otherwise | 
 | 58 |  */ | 
 | 59 | static u16 llc_util_ns_inside_rx_window(u8 ns, u8 vr, u8 rw) | 
 | 60 | { | 
 | 61 | 	return !llc_circular_between(vr, ns, | 
 | 62 | 				     (vr + rw - 1) % LLC_2_SEQ_NBR_MODULO); | 
 | 63 | } | 
 | 64 |  | 
 | 65 | /** | 
 | 66 |  *	llc_util_nr_inside_tx_window - check if sequence number is in tx window | 
 | 67 |  *	@sk: current connection. | 
 | 68 |  *	@nr: N(R) of received PDU. | 
 | 69 |  * | 
 | 70 |  *	This routine checks if N(R) of received PDU is in range of transmit | 
 | 71 |  *	window; on the other hand checks if received PDU acknowledges some | 
 | 72 |  *	outstanding PDUs that are in transmit window. Returns 0 for success, 1 | 
 | 73 |  *	otherwise. | 
 | 74 |  */ | 
 | 75 | static u16 llc_util_nr_inside_tx_window(struct sock *sk, u8 nr) | 
 | 76 | { | 
 | 77 | 	u8 nr1, nr2; | 
 | 78 | 	struct sk_buff *skb; | 
 | 79 | 	struct llc_pdu_sn *pdu; | 
 | 80 | 	struct llc_sock *llc = llc_sk(sk); | 
 | 81 | 	int rc = 0; | 
 | 82 |  | 
 | 83 | 	if (llc->dev->flags & IFF_LOOPBACK) | 
 | 84 | 		goto out; | 
 | 85 | 	rc = 1; | 
| David S. Miller | b03efcf | 2005-07-08 14:57:23 -0700 | [diff] [blame] | 86 | 	if (skb_queue_empty(&llc->pdu_unack_q)) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 87 | 		goto out; | 
 | 88 | 	skb = skb_peek(&llc->pdu_unack_q); | 
 | 89 | 	pdu = llc_pdu_sn_hdr(skb); | 
 | 90 | 	nr1 = LLC_I_GET_NS(pdu); | 
 | 91 | 	skb = skb_peek_tail(&llc->pdu_unack_q); | 
 | 92 | 	pdu = llc_pdu_sn_hdr(skb); | 
 | 93 | 	nr2 = LLC_I_GET_NS(pdu); | 
 | 94 | 	rc = !llc_circular_between(nr1, nr, (nr2 + 1) % LLC_2_SEQ_NBR_MODULO); | 
 | 95 | out: | 
 | 96 | 	return rc; | 
 | 97 | } | 
 | 98 |  | 
 | 99 | int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb) | 
 | 100 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 101 | 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 102 |  | 
 | 103 | 	return ev->prim == LLC_CONN_PRIM && | 
 | 104 | 	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; | 
 | 105 | } | 
 | 106 |  | 
 | 107 | int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb) | 
 | 108 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 109 | 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 110 |  | 
 | 111 | 	return ev->prim == LLC_DATA_PRIM && | 
 | 112 | 	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; | 
 | 113 | } | 
 | 114 |  | 
 | 115 | int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb) | 
 | 116 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 117 | 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 118 |  | 
 | 119 | 	return ev->prim == LLC_DISC_PRIM && | 
 | 120 | 	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; | 
 | 121 | } | 
 | 122 |  | 
 | 123 | int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb) | 
 | 124 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 125 | 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 126 |  | 
 | 127 | 	return ev->prim == LLC_RESET_PRIM && | 
 | 128 | 	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; | 
 | 129 | } | 
 | 130 |  | 
 | 131 | int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb) | 
 | 132 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 133 | 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 134 |  | 
 | 135 | 	return ev->type == LLC_CONN_EV_TYPE_SIMPLE && | 
 | 136 | 	       ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1; | 
 | 137 | } | 
 | 138 |  | 
 | 139 | int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb) | 
 | 140 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 141 | 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 142 |  | 
 | 143 | 	return ev->type == LLC_CONN_EV_TYPE_SIMPLE && | 
 | 144 | 	       ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1; | 
 | 145 | } | 
 | 146 |  | 
 | 147 | int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb) | 
 | 148 | { | 
 | 149 | 	return 1; | 
 | 150 | } | 
 | 151 |  | 
 | 152 | int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb) | 
 | 153 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 154 | 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 155 |  | 
 | 156 | 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) && | 
 | 157 | 	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1; | 
 | 158 | } | 
 | 159 |  | 
 | 160 | int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | 
 | 161 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 162 | 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 163 |  | 
 | 164 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) && | 
 | 165 | 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1; | 
 | 166 | } | 
 | 167 |  | 
 | 168 | int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | 
 | 169 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 170 | 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 171 |  | 
 | 172 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) && | 
 | 173 | 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1; | 
 | 174 | } | 
 | 175 |  | 
 | 176 | int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | 
 | 177 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 178 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 179 |  | 
 | 180 | 	return llc_conn_space(sk, skb) && | 
 | 181 | 	       LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 
 | 182 | 	       LLC_I_PF_IS_0(pdu) && | 
 | 183 | 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; | 
 | 184 | } | 
 | 185 |  | 
 | 186 | int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | 
 | 187 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 188 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 189 |  | 
 | 190 | 	return llc_conn_space(sk, skb) && | 
 | 191 | 	       LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 
 | 192 | 	       LLC_I_PF_IS_1(pdu) && | 
 | 193 | 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; | 
 | 194 | } | 
 | 195 |  | 
 | 196 | int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk, | 
 | 197 | 					      struct sk_buff *skb) | 
 | 198 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 199 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
 | 200 | 	const u8 vr = llc_sk(sk)->vR; | 
 | 201 | 	const u8 ns = LLC_I_GET_NS(pdu); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 202 |  | 
 | 203 | 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 
 | 204 | 	       LLC_I_PF_IS_0(pdu) && ns != vr && | 
 | 205 | 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; | 
 | 206 | } | 
 | 207 |  | 
 | 208 | int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk, | 
 | 209 | 					      struct sk_buff *skb) | 
 | 210 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 211 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
 | 212 | 	const u8 vr = llc_sk(sk)->vR; | 
 | 213 | 	const u8 ns = LLC_I_GET_NS(pdu); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 214 |  | 
 | 215 | 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 
 | 216 | 	       LLC_I_PF_IS_1(pdu) && ns != vr && | 
 | 217 | 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; | 
 | 218 | } | 
 | 219 |  | 
 | 220 | int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk, | 
 | 221 | 					     struct sk_buff *skb) | 
 | 222 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 223 | 	const struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb); | 
 | 224 | 	const u8 vr = llc_sk(sk)->vR; | 
 | 225 | 	const u8 ns = LLC_I_GET_NS(pdu); | 
 | 226 | 	const u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 
 | 227 | 		ns != vr && | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 228 | 		 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; | 
 | 229 | 	if (!rc) | 
 | 230 | 		dprintk("%s: matched, state=%d, ns=%d, vr=%d\n", | 
| Harvey Harrison | 0dc4787 | 2008-03-05 20:47:47 -0800 | [diff] [blame] | 231 | 			__func__, llc_sk(sk)->state, ns, vr); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 232 | 	return rc; | 
 | 233 | } | 
 | 234 |  | 
 | 235 | int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | 
 | 236 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 237 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 238 |  | 
 | 239 | 	return llc_conn_space(sk, skb) && | 
 | 240 | 	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 
 | 241 | 	       LLC_I_PF_IS_0(pdu) && | 
 | 242 | 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; | 
 | 243 | } | 
 | 244 |  | 
 | 245 | int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | 
 | 246 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 247 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 248 |  | 
 | 249 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 
 | 250 | 	       LLC_I_PF_IS_1(pdu) && | 
 | 251 | 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; | 
 | 252 | } | 
 | 253 |  | 
 | 254 | int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | 
 | 255 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 256 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 257 |  | 
 | 258 | 	return llc_conn_space(sk, skb) && | 
 | 259 | 	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 
 | 260 | 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1; | 
 | 261 | } | 
 | 262 |  | 
 | 263 | int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk, | 
 | 264 | 					      struct sk_buff *skb) | 
 | 265 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 266 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
 | 267 | 	const u8 vr = llc_sk(sk)->vR; | 
 | 268 | 	const u8 ns = LLC_I_GET_NS(pdu); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 269 |  | 
 | 270 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 
 | 271 | 	       LLC_I_PF_IS_0(pdu) && ns != vr && | 
 | 272 | 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; | 
 | 273 | } | 
 | 274 |  | 
 | 275 | int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk, | 
 | 276 | 					      struct sk_buff *skb) | 
 | 277 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 278 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
 | 279 | 	const u8 vr = llc_sk(sk)->vR; | 
 | 280 | 	const u8 ns = LLC_I_GET_NS(pdu); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 281 |  | 
 | 282 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 
 | 283 | 	       LLC_I_PF_IS_1(pdu) && ns != vr && | 
 | 284 | 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; | 
 | 285 | } | 
 | 286 |  | 
 | 287 | int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk, | 
 | 288 | 					      struct sk_buff *skb) | 
 | 289 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 290 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
 | 291 | 	const u8 vr = llc_sk(sk)->vR; | 
 | 292 | 	const u8 ns = LLC_I_GET_NS(pdu); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 293 |  | 
 | 294 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr && | 
 | 295 | 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; | 
 | 296 | } | 
 | 297 |  | 
 | 298 | int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk, | 
 | 299 | 					     struct sk_buff *skb) | 
 | 300 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 301 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
 | 302 | 	const u8 vr = llc_sk(sk)->vR; | 
 | 303 | 	const u8 ns = LLC_I_GET_NS(pdu); | 
 | 304 | 	const u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 
 | 305 | 		ns != vr && | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 306 | 		 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; | 
 | 307 | 	if (!rc) | 
 | 308 | 		dprintk("%s: matched, state=%d, ns=%d, vr=%d\n", | 
| Harvey Harrison | 0dc4787 | 2008-03-05 20:47:47 -0800 | [diff] [blame] | 309 | 			__func__, llc_sk(sk)->state, ns, vr); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 310 | 	return rc; | 
 | 311 | } | 
 | 312 |  | 
 | 313 | int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | 
 | 314 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 315 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 316 |  | 
 | 317 | 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 318 | 	       LLC_S_PF_IS_0(pdu) && | 
 | 319 | 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1; | 
 | 320 | } | 
 | 321 |  | 
 | 322 | int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | 
 | 323 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 324 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 325 |  | 
 | 326 | 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 327 | 	       LLC_S_PF_IS_1(pdu) && | 
 | 328 | 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1; | 
 | 329 | } | 
 | 330 |  | 
 | 331 | int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | 
 | 332 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 333 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 334 |  | 
 | 335 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 336 | 	       LLC_S_PF_IS_0(pdu) && | 
 | 337 | 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1; | 
 | 338 | } | 
 | 339 |  | 
 | 340 | int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | 
 | 341 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 342 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 343 |  | 
 | 344 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 345 | 	       LLC_S_PF_IS_1(pdu) && | 
 | 346 | 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1; | 
 | 347 | } | 
 | 348 |  | 
 | 349 | int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | 
 | 350 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 351 | 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 352 |  | 
 | 353 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 354 | 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1; | 
 | 355 | } | 
 | 356 |  | 
 | 357 | int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | 
 | 358 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 359 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 360 |  | 
 | 361 | 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 362 | 	       LLC_S_PF_IS_0(pdu) && | 
 | 363 | 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1; | 
 | 364 | } | 
 | 365 |  | 
 | 366 | int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | 
 | 367 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 368 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 369 |  | 
 | 370 | 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 371 | 	       LLC_S_PF_IS_1(pdu) && | 
 | 372 | 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1; | 
 | 373 | } | 
 | 374 |  | 
 | 375 | int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | 
 | 376 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 377 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 378 |  | 
 | 379 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 380 | 	       LLC_S_PF_IS_0(pdu) && | 
 | 381 | 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1; | 
 | 382 | } | 
 | 383 |  | 
 | 384 | int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | 
 | 385 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 386 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 387 |  | 
 | 388 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 389 | 	       LLC_S_PF_IS_1(pdu) && | 
 | 390 | 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1; | 
 | 391 | } | 
 | 392 |  | 
 | 393 | int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | 
 | 394 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 395 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 396 |  | 
 | 397 | 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 398 | 	       LLC_S_PF_IS_0(pdu) && | 
 | 399 | 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1; | 
 | 400 | } | 
 | 401 |  | 
 | 402 | int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | 
 | 403 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 404 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 405 |  | 
 | 406 | 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 407 | 	       LLC_S_PF_IS_1(pdu) && | 
 | 408 | 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1; | 
 | 409 | } | 
 | 410 |  | 
 | 411 | int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | 
 | 412 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 413 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 414 |  | 
 | 415 | 	return llc_conn_space(sk, skb) && | 
 | 416 | 	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 417 | 	       LLC_S_PF_IS_0(pdu) && | 
 | 418 | 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1; | 
 | 419 | } | 
 | 420 |  | 
 | 421 | int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | 
 | 422 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 423 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 424 |  | 
 | 425 | 	return llc_conn_space(sk, skb) && | 
 | 426 | 	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 
 | 427 | 	       LLC_S_PF_IS_1(pdu) && | 
 | 428 | 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1; | 
 | 429 | } | 
 | 430 |  | 
 | 431 | int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb) | 
 | 432 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 433 | 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 434 |  | 
 | 435 | 	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) && | 
 | 436 | 	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1; | 
 | 437 | } | 
 | 438 |  | 
 | 439 | int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | 
 | 440 | { | 
 | 441 | 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 
 | 442 |  | 
 | 443 | 	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) && | 
 | 444 | 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1; | 
 | 445 | } | 
 | 446 |  | 
 | 447 | int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | 
 | 448 | { | 
 | 449 | 	u16 rc = 1; | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 450 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 451 |  | 
 | 452 | 	if (LLC_PDU_IS_CMD(pdu)) { | 
 | 453 | 		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) { | 
 | 454 | 			if (LLC_I_PF_IS_1(pdu)) | 
 | 455 | 				rc = 0; | 
 | 456 | 		} else if (LLC_PDU_TYPE_IS_U(pdu) && LLC_U_PF_IS_1(pdu)) | 
 | 457 | 			rc = 0; | 
 | 458 | 	} | 
 | 459 | 	return rc; | 
 | 460 | } | 
 | 461 |  | 
 | 462 | int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb) | 
 | 463 | { | 
 | 464 | 	u16 rc = 1; | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 465 | 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 466 |  | 
 | 467 | 	if (LLC_PDU_IS_CMD(pdu)) { | 
 | 468 | 		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) | 
 | 469 | 			rc = 0; | 
 | 470 | 		else if (LLC_PDU_TYPE_IS_U(pdu)) | 
 | 471 | 			switch (LLC_U_PDU_CMD(pdu)) { | 
 | 472 | 			case LLC_2_PDU_CMD_SABME: | 
 | 473 | 			case LLC_2_PDU_CMD_DISC: | 
 | 474 | 				rc = 0; | 
 | 475 | 				break; | 
 | 476 | 			} | 
 | 477 | 	} | 
 | 478 | 	return rc; | 
 | 479 | } | 
 | 480 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 481 | int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | 
 | 482 | { | 
 | 483 | 	u16 rc = 1; | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 484 | 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 485 |  | 
 | 486 | 	if (LLC_PDU_IS_RSP(pdu)) { | 
 | 487 | 		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) | 
 | 488 | 			rc = 0; | 
 | 489 | 		else if (LLC_PDU_TYPE_IS_U(pdu)) | 
 | 490 | 			switch (LLC_U_PDU_RSP(pdu)) { | 
 | 491 | 			case LLC_2_PDU_RSP_UA: | 
 | 492 | 			case LLC_2_PDU_RSP_DM: | 
 | 493 | 			case LLC_2_PDU_RSP_FRMR: | 
 | 494 | 				rc = 0; | 
 | 495 | 				break; | 
 | 496 | 			} | 
 | 497 | 	} | 
 | 498 |  | 
 | 499 | 	return rc; | 
 | 500 | } | 
 | 501 |  | 
 | 502 | int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk, | 
 | 503 | 					       struct sk_buff *skb) | 
 | 504 | { | 
 | 505 | 	u16 rc = 1; | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 506 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
 | 507 | 	const u8 vs = llc_sk(sk)->vS; | 
 | 508 | 	const u8 nr = LLC_I_GET_NR(pdu); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 509 |  | 
 | 510 | 	if (LLC_PDU_IS_CMD(pdu) && | 
 | 511 | 	    (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) && | 
 | 512 | 	    nr != vs && llc_util_nr_inside_tx_window(sk, nr)) { | 
 | 513 | 		dprintk("%s: matched, state=%d, vs=%d, nr=%d\n", | 
| Harvey Harrison | 0dc4787 | 2008-03-05 20:47:47 -0800 | [diff] [blame] | 514 | 			__func__, llc_sk(sk)->state, vs, nr); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 515 | 		rc = 0; | 
 | 516 | 	} | 
 | 517 | 	return rc; | 
 | 518 | } | 
 | 519 |  | 
 | 520 | int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk, | 
 | 521 | 					       struct sk_buff *skb) | 
 | 522 | { | 
 | 523 | 	u16 rc = 1; | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 524 | 	const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 
 | 525 | 	const u8 vs = llc_sk(sk)->vS; | 
 | 526 | 	const u8 nr = LLC_I_GET_NR(pdu); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 527 |  | 
 | 528 | 	if (LLC_PDU_IS_RSP(pdu) && | 
 | 529 | 	    (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) && | 
 | 530 | 	    nr != vs && llc_util_nr_inside_tx_window(sk, nr)) { | 
 | 531 | 		rc = 0; | 
 | 532 | 		dprintk("%s: matched, state=%d, vs=%d, nr=%d\n", | 
| Harvey Harrison | 0dc4787 | 2008-03-05 20:47:47 -0800 | [diff] [blame] | 533 | 			__func__, llc_sk(sk)->state, vs, nr); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 534 | 	} | 
 | 535 | 	return rc; | 
 | 536 | } | 
 | 537 |  | 
 | 538 | int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb) | 
 | 539 | { | 
 | 540 | 	return 0; | 
 | 541 | } | 
 | 542 |  | 
 | 543 | int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb) | 
 | 544 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 545 | 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 546 |  | 
 | 547 | 	return ev->type != LLC_CONN_EV_TYPE_P_TMR; | 
 | 548 | } | 
 | 549 |  | 
 | 550 | int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb) | 
 | 551 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 552 | 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 553 |  | 
 | 554 | 	return ev->type != LLC_CONN_EV_TYPE_ACK_TMR; | 
 | 555 | } | 
 | 556 |  | 
 | 557 | int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb) | 
 | 558 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 559 | 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 560 |  | 
 | 561 | 	return ev->type != LLC_CONN_EV_TYPE_REJ_TMR; | 
 | 562 | } | 
 | 563 |  | 
 | 564 | int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb) | 
 | 565 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 566 | 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 567 |  | 
 | 568 | 	return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR; | 
 | 569 | } | 
 | 570 |  | 
 | 571 | int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb) | 
 | 572 | { | 
 | 573 | 	return 1; | 
 | 574 | } | 
 | 575 |  | 
 | 576 | int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb) | 
 | 577 | { | 
| Arnaldo Carvalho de Melo | b9441fc | 2005-09-22 04:09:45 -0300 | [diff] [blame] | 578 | 	const struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 579 |  | 
 | 580 | 	return ev->type == LLC_CONN_EV_TYPE_SIMPLE && | 
 | 581 | 	       ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1; | 
 | 582 | } | 
 | 583 |  | 
 | 584 | /* Event qualifier functions | 
 | 585 |  * | 
 | 586 |  * these functions simply verify the value of a state flag associated with | 
 | 587 |  * the connection and return either a 0 for success or a non-zero value | 
 | 588 |  * for not-success; verify the event is the type we expect | 
 | 589 |  */ | 
 | 590 | int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, struct sk_buff *skb) | 
 | 591 | { | 
 | 592 | 	return llc_sk(sk)->data_flag != 1; | 
 | 593 | } | 
 | 594 |  | 
 | 595 | int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, struct sk_buff *skb) | 
 | 596 | { | 
 | 597 | 	return llc_sk(sk)->data_flag; | 
 | 598 | } | 
 | 599 |  | 
 | 600 | int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, struct sk_buff *skb) | 
 | 601 | { | 
 | 602 | 	return llc_sk(sk)->data_flag != 2; | 
 | 603 | } | 
 | 604 |  | 
 | 605 | int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb) | 
 | 606 | { | 
 | 607 | 	return llc_sk(sk)->p_flag != 1; | 
 | 608 | } | 
 | 609 |  | 
 | 610 | /** | 
 | 611 |  *	conn_ev_qlfy_last_frame_eq_1 - checks if frame is last in tx window | 
 | 612 |  *	@sk: current connection structure. | 
 | 613 |  *	@skb: current event. | 
 | 614 |  * | 
 | 615 |  *	This function determines when frame which is sent, is last frame of | 
 | 616 |  *	transmit window, if it is then this function return zero else return | 
 | 617 |  *	one.  This function is used for sending last frame of transmit window | 
 | 618 |  *	as I-format command with p-bit set to one. Returns 0 if frame is last | 
 | 619 |  *	frame, 1 otherwise. | 
 | 620 |  */ | 
 | 621 | int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, struct sk_buff *skb) | 
 | 622 | { | 
 | 623 | 	return !(skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k); | 
 | 624 | } | 
 | 625 |  | 
 | 626 | /** | 
 | 627 |  *	conn_ev_qlfy_last_frame_eq_0 - checks if frame isn't last in tx window | 
 | 628 |  *	@sk: current connection structure. | 
 | 629 |  *	@skb: current event. | 
 | 630 |  * | 
 | 631 |  *	This function determines when frame which is sent, isn't last frame of | 
 | 632 |  *	transmit window, if it isn't then this function return zero else return | 
 | 633 |  *	one. Returns 0 if frame isn't last frame, 1 otherwise. | 
 | 634 |  */ | 
 | 635 | int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, struct sk_buff *skb) | 
 | 636 | { | 
 | 637 | 	return skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k; | 
 | 638 | } | 
 | 639 |  | 
 | 640 | int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb) | 
 | 641 | { | 
 | 642 | 	return llc_sk(sk)->p_flag; | 
 | 643 | } | 
 | 644 |  | 
 | 645 | int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb) | 
 | 646 | { | 
 | 647 | 	u8 f_bit; | 
 | 648 |  | 
 | 649 | 	llc_pdu_decode_pf_bit(skb, &f_bit); | 
 | 650 | 	return llc_sk(sk)->p_flag == f_bit ? 0 : 1; | 
 | 651 | } | 
 | 652 |  | 
 | 653 | int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, struct sk_buff *skb) | 
 | 654 | { | 
 | 655 | 	return llc_sk(sk)->remote_busy_flag; | 
 | 656 | } | 
 | 657 |  | 
 | 658 | int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, struct sk_buff *skb) | 
 | 659 | { | 
 | 660 | 	return !llc_sk(sk)->remote_busy_flag; | 
 | 661 | } | 
 | 662 |  | 
 | 663 | int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, struct sk_buff *skb) | 
 | 664 | { | 
 | 665 | 	return !(llc_sk(sk)->retry_count < llc_sk(sk)->n2); | 
 | 666 | } | 
 | 667 |  | 
 | 668 | int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, struct sk_buff *skb) | 
 | 669 | { | 
 | 670 | 	return !(llc_sk(sk)->retry_count >= llc_sk(sk)->n2); | 
 | 671 | } | 
 | 672 |  | 
 | 673 | int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb) | 
 | 674 | { | 
 | 675 | 	return !llc_sk(sk)->s_flag; | 
 | 676 | } | 
 | 677 |  | 
 | 678 | int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb) | 
 | 679 | { | 
 | 680 | 	return llc_sk(sk)->s_flag; | 
 | 681 | } | 
 | 682 |  | 
 | 683 | int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, struct sk_buff *skb) | 
 | 684 | { | 
 | 685 | 	return !llc_sk(sk)->cause_flag; | 
 | 686 | } | 
 | 687 |  | 
 | 688 | int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, struct sk_buff *skb) | 
 | 689 | { | 
 | 690 | 	return llc_sk(sk)->cause_flag; | 
 | 691 | } | 
 | 692 |  | 
 | 693 | int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb) | 
 | 694 | { | 
 | 695 | 	struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
 | 696 |  | 
 | 697 | 	ev->status = LLC_STATUS_CONN; | 
 | 698 | 	return 0; | 
 | 699 | } | 
 | 700 |  | 
 | 701 | int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, struct sk_buff *skb) | 
 | 702 | { | 
 | 703 | 	struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
 | 704 |  | 
 | 705 | 	ev->status = LLC_STATUS_DISC; | 
 | 706 | 	return 0; | 
 | 707 | } | 
 | 708 |  | 
 | 709 | int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb) | 
 | 710 | { | 
 | 711 | 	struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
 | 712 |  | 
 | 713 | 	ev->status = LLC_STATUS_FAILED; | 
 | 714 | 	return 0; | 
 | 715 | } | 
 | 716 |  | 
 | 717 | int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk, | 
 | 718 | 					    struct sk_buff *skb) | 
 | 719 | { | 
 | 720 | 	struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
 | 721 |  | 
 | 722 | 	ev->status = LLC_STATUS_REMOTE_BUSY; | 
 | 723 | 	return 0; | 
 | 724 | } | 
 | 725 |  | 
 | 726 | int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, struct sk_buff *skb) | 
 | 727 | { | 
 | 728 | 	struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
 | 729 |  | 
 | 730 | 	ev->status = LLC_STATUS_REFUSE; | 
 | 731 | 	return 0; | 
 | 732 | } | 
 | 733 |  | 
 | 734 | int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb) | 
 | 735 | { | 
 | 736 | 	struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
 | 737 |  | 
 | 738 | 	ev->status = LLC_STATUS_CONFLICT; | 
 | 739 | 	return 0; | 
 | 740 | } | 
 | 741 |  | 
 | 742 | int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb) | 
 | 743 | { | 
 | 744 | 	struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 
 | 745 |  | 
 | 746 | 	ev->status = LLC_STATUS_RESET_DONE; | 
 | 747 | 	return 0; | 
 | 748 | } |