Root/
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> |
40 | #include <net/llc_c_ac.h> |
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 | |
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; |
86 | if (skb_queue_empty(&llc->pdu_unack_q)) |
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 | { |
101 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
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 | { |
109 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
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 | { |
117 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
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 | { |
125 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
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 | { |
133 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
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 | { |
141 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
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 | { |
154 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
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 | { |
162 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
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 | { |
170 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
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 | { |
178 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
188 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
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); |
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 | { |
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); |
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 | { |
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 && |
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", |
231 | __func__, llc_sk(sk)->state, ns, vr); |
232 | return rc; |
233 | } |
234 | |
235 | int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) |
236 | { |
237 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
247 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
256 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
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); |
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 | { |
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); |
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 | { |
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); |
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 | { |
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 && |
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", |
309 | __func__, llc_sk(sk)->state, ns, vr); |
310 | return rc; |
311 | } |
312 | |
313 | int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) |
314 | { |
315 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
324 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
333 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
342 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
351 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
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 | { |
359 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
368 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
377 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
386 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
395 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
404 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
413 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
423 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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 | { |
433 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
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; |
450 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
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; |
465 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
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 | |
481 | int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) |
482 | { |
483 | u16 rc = 1; |
484 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
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; |
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); |
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", |
514 | __func__, llc_sk(sk)->state, vs, nr); |
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; |
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); |
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", |
533 | __func__, llc_sk(sk)->state, vs, nr); |
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 | { |
545 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
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 | { |
552 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
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 | { |
559 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
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 | { |
566 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
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 | { |
578 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
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 | } |
749 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9