llc_c_ac.c revision f4ad2b162d653e4a6e57d598119e3820c65fef71
1/*
2 * llc_c_ac.c - actions performed during connection state transition.
3 *
4 * Description:
5 *   Functions in this module are implementation of connection component actions
6 *   Details of actions can be found in IEEE-802.2 standard document.
7 *   All functions have one connection and one event as input argument. All of
8 *   them return 0 On success and 1 otherwise.
9 *
10 * Copyright (c) 1997 by Procom Technology, Inc.
11 * 		 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
12 *
13 * This program can be redistributed or modified under the terms of the
14 * GNU General Public License as published by the Free Software Foundation.
15 * This program is distributed without any warranty or implied warranty
16 * of merchantability or fitness for a particular purpose.
17 *
18 * See the GNU General Public License for more details.
19 */
20#include <linux/netdevice.h>
21#include <net/llc_conn.h>
22#include <net/llc_sap.h>
23#include <net/sock.h>
24#include <net/llc_c_ev.h>
25#include <net/llc_c_ac.h>
26#include <net/llc_c_st.h>
27#include <net/llc_pdu.h>
28#include <net/llc.h>
29
30
31static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb);
32static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb);
33static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *ev);
34
35static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb);
36
37static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
38					       struct sk_buff *skb);
39
40static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb);
41
42#define INCORRECT 0
43
44int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb)
45{
46	struct llc_sock *llc = llc_sk(sk);
47
48	if (llc->remote_busy_flag) {
49		u8 nr;
50		struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
51
52		llc->remote_busy_flag = 0;
53		del_timer(&llc->busy_state_timer.timer);
54		nr = LLC_I_GET_NR(pdu);
55		llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
56	}
57	return 0;
58}
59
60int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
61{
62	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
63
64	ev->ind_prim = LLC_CONN_PRIM;
65	return 0;
66}
67
68int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb)
69{
70	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
71
72	ev->cfm_prim = LLC_CONN_PRIM;
73	return 0;
74}
75
76static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *skb)
77{
78	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
79
80	ev->cfm_prim = LLC_DATA_PRIM;
81	return 0;
82}
83
84int llc_conn_ac_data_ind(struct sock *sk, struct sk_buff *skb)
85{
86	llc_conn_rtn_pdu(sk, skb);
87	return 0;
88}
89
90int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb)
91{
92	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
93	u8 reason = 0;
94	int rc = 0;
95
96	if (ev->type == LLC_CONN_EV_TYPE_PDU) {
97		struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
98
99		if (LLC_PDU_IS_RSP(pdu) &&
100		    LLC_PDU_TYPE_IS_U(pdu) &&
101		    LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM)
102			reason = LLC_DISC_REASON_RX_DM_RSP_PDU;
103		else if (LLC_PDU_IS_CMD(pdu) &&
104			   LLC_PDU_TYPE_IS_U(pdu) &&
105			   LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC)
106			reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
107	} else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR)
108		reason = LLC_DISC_REASON_ACK_TMR_EXP;
109	else
110		rc = -EINVAL;
111	if (!rc) {
112		ev->reason   = reason;
113		ev->ind_prim = LLC_DISC_PRIM;
114	}
115	return rc;
116}
117
118int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb)
119{
120	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
121
122	ev->reason   = ev->status;
123	ev->cfm_prim = LLC_DISC_PRIM;
124	return 0;
125}
126
127int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
128{
129	u8 reason = 0;
130	int rc = 1;
131	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
132	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
133	struct llc_sock *llc = llc_sk(sk);
134
135	switch (ev->type) {
136	case LLC_CONN_EV_TYPE_PDU:
137		if (LLC_PDU_IS_RSP(pdu) &&
138		    LLC_PDU_TYPE_IS_U(pdu) &&
139		    LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR) {
140			reason = LLC_RESET_REASON_LOCAL;
141			rc = 0;
142		} else if (LLC_PDU_IS_CMD(pdu) &&
143			   LLC_PDU_TYPE_IS_U(pdu) &&
144			   LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) {
145			reason = LLC_RESET_REASON_REMOTE;
146			rc = 0;
147		}
148		break;
149	case LLC_CONN_EV_TYPE_ACK_TMR:
150	case LLC_CONN_EV_TYPE_P_TMR:
151	case LLC_CONN_EV_TYPE_REJ_TMR:
152	case LLC_CONN_EV_TYPE_BUSY_TMR:
153		if (llc->retry_count > llc->n2) {
154			reason = LLC_RESET_REASON_LOCAL;
155			rc = 0;
156		}
157		break;
158	}
159	if (!rc) {
160		ev->reason   = reason;
161		ev->ind_prim = LLC_RESET_PRIM;
162	}
163	return rc;
164}
165
166int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *skb)
167{
168	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
169
170	ev->reason   = 0;
171	ev->cfm_prim = LLC_RESET_PRIM;
172	return 0;
173}
174
175int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,
176					    struct sk_buff *skb)
177{
178	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
179
180	if (LLC_PDU_IS_RSP(pdu) &&
181	    LLC_PDU_TYPE_IS_I(pdu) &&
182	    LLC_I_PF_IS_1(pdu) && llc_sk(sk)->ack_pf)
183		llc_conn_ac_clear_remote_busy(sk, skb);
184	return 0;
185}
186
187int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,
188					       struct sk_buff *skb)
189{
190	struct llc_sock *llc = llc_sk(sk);
191
192	if (llc->data_flag == 2)
193		del_timer(&llc->rej_sent_timer.timer);
194	return 0;
195}
196
197int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
198{
199	int rc = -ENOBUFS;
200	struct llc_sock *llc = llc_sk(sk);
201	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
202
203	if (nskb) {
204		struct llc_sap *sap = llc->sap;
205
206		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
207				    llc->daddr.lsap, LLC_PDU_CMD);
208		llc_pdu_init_as_disc_cmd(nskb, 1);
209		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
210		if (unlikely(rc))
211			goto free;
212		llc_conn_send_pdu(sk, nskb);
213		llc_conn_ac_set_p_flag_1(sk, skb);
214	}
215out:
216	return rc;
217free:
218	kfree_skb(nskb);
219	goto out;
220}
221
222int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
223{
224	int rc = -ENOBUFS;
225	struct llc_sock *llc = llc_sk(sk);
226	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
227
228	if (nskb) {
229		struct llc_sap *sap = llc->sap;
230		u8 f_bit;
231
232		llc_pdu_decode_pf_bit(skb, &f_bit);
233		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
234				    llc->daddr.lsap, LLC_PDU_RSP);
235		llc_pdu_init_as_dm_rsp(nskb, f_bit);
236		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
237		if (unlikely(rc))
238			goto free;
239		llc_conn_send_pdu(sk, nskb);
240	}
241out:
242	return rc;
243free:
244	kfree_skb(nskb);
245	goto out;
246}
247
248int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
249{
250	int rc = -ENOBUFS;
251	struct llc_sock *llc = llc_sk(sk);
252	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
253
254	if (nskb) {
255		struct llc_sap *sap = llc->sap;
256
257		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
258				    llc->daddr.lsap, LLC_PDU_RSP);
259		llc_pdu_init_as_dm_rsp(nskb, 1);
260		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
261		if (unlikely(rc))
262			goto free;
263		llc_conn_send_pdu(sk, nskb);
264	}
265out:
266	return rc;
267free:
268	kfree_skb(nskb);
269	goto out;
270}
271
272int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
273{
274	u8 f_bit;
275	int rc = -ENOBUFS;
276	struct sk_buff *nskb;
277	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
278	struct llc_sock *llc = llc_sk(sk);
279
280	llc->rx_pdu_hdr = *((u32 *)pdu);
281	if (LLC_PDU_IS_CMD(pdu))
282		llc_pdu_decode_pf_bit(skb, &f_bit);
283	else
284		f_bit = 0;
285	nskb = llc_alloc_frame(sk, llc->dev);
286	if (nskb) {
287		struct llc_sap *sap = llc->sap;
288
289		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
290				    llc->daddr.lsap, LLC_PDU_RSP);
291		llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
292					 llc->vR, INCORRECT);
293		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
294		if (unlikely(rc))
295			goto free;
296		llc_conn_send_pdu(sk, nskb);
297	}
298out:
299	return rc;
300free:
301	kfree_skb(nskb);
302	goto out;
303}
304
305int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
306{
307	int rc = -ENOBUFS;
308	struct llc_sock *llc = llc_sk(sk);
309	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
310
311	if (nskb) {
312		struct llc_sap *sap = llc->sap;
313		struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr;
314
315		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
316				    llc->daddr.lsap, LLC_PDU_RSP);
317		llc_pdu_init_as_frmr_rsp(nskb, pdu, 0, llc->vS,
318					 llc->vR, INCORRECT);
319		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
320		if (unlikely(rc))
321			goto free;
322		llc_conn_send_pdu(sk, nskb);
323	}
324out:
325	return rc;
326free:
327	kfree_skb(nskb);
328	goto out;
329}
330
331int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
332{
333	u8 f_bit;
334	int rc = -ENOBUFS;
335	struct sk_buff *nskb;
336	struct llc_sock *llc = llc_sk(sk);
337
338	llc_pdu_decode_pf_bit(skb, &f_bit);
339	nskb = llc_alloc_frame(sk, llc->dev);
340	if (nskb) {
341		struct llc_sap *sap = llc->sap;
342		struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
343
344		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
345				    llc->daddr.lsap, LLC_PDU_RSP);
346		llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
347					 llc->vR, INCORRECT);
348		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
349		if (unlikely(rc))
350			goto free;
351		llc_conn_send_pdu(sk, nskb);
352	}
353out:
354	return rc;
355free:
356	kfree_skb(nskb);
357	goto out;
358}
359
360int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
361{
362	int rc;
363	struct llc_sock *llc = llc_sk(sk);
364	struct llc_sap *sap = llc->sap;
365
366	llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
367			    llc->daddr.lsap, LLC_PDU_CMD);
368	llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR);
369	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
370	if (likely(!rc)) {
371		llc_conn_send_pdu(sk, skb);
372		llc_conn_ac_inc_vs_by_1(sk, skb);
373	}
374	return rc;
375}
376
377static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
378{
379	int rc;
380	struct llc_sock *llc = llc_sk(sk);
381	struct llc_sap *sap = llc->sap;
382
383	llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
384			    llc->daddr.lsap, LLC_PDU_CMD);
385	llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
386	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
387	if (likely(!rc)) {
388		llc_conn_send_pdu(sk, skb);
389		llc_conn_ac_inc_vs_by_1(sk, skb);
390	}
391	return rc;
392}
393
394int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
395{
396	int rc;
397	struct llc_sock *llc = llc_sk(sk);
398	struct llc_sap *sap = llc->sap;
399
400	llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
401			    llc->daddr.lsap, LLC_PDU_CMD);
402	llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
403	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
404	if (likely(!rc)) {
405		llc_conn_send_pdu(sk, skb);
406		llc_conn_ac_inc_vs_by_1(sk, skb);
407	}
408	return 0;
409}
410
411int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
412{
413	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
414	u8 nr = LLC_I_GET_NR(pdu);
415
416	llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
417	return 0;
418}
419
420int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
421						struct sk_buff *skb)
422{
423	u8 nr;
424	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
425	int rc = -ENOBUFS;
426	struct llc_sock *llc = llc_sk(sk);
427	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
428
429	if (nskb) {
430		struct llc_sap *sap = llc->sap;
431
432		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
433				    llc->daddr.lsap, LLC_PDU_RSP);
434		llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
435		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
436		if (likely(!rc))
437			llc_conn_send_pdu(sk, nskb);
438		else
439			kfree_skb(skb);
440	}
441	if (rc) {
442		nr = LLC_I_GET_NR(pdu);
443		rc = 0;
444		llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
445	}
446	return rc;
447}
448
449int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
450{
451	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
452	u8 nr = LLC_I_GET_NR(pdu);
453
454	llc_conn_resend_i_pdu_as_rsp(sk, nr, 1);
455	return 0;
456}
457
458int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
459{
460	int rc = -ENOBUFS;
461	struct llc_sock *llc = llc_sk(sk);
462	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
463
464	if (nskb) {
465		struct llc_sap *sap = llc->sap;
466
467		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
468				    llc->daddr.lsap, LLC_PDU_CMD);
469		llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);
470		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
471		if (unlikely(rc))
472			goto free;
473		llc_conn_send_pdu(sk, nskb);
474	}
475out:
476	return rc;
477free:
478	kfree_skb(nskb);
479	goto out;
480}
481
482int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
483{
484	int rc = -ENOBUFS;
485	struct llc_sock *llc = llc_sk(sk);
486	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
487
488	if (nskb) {
489		struct llc_sap *sap = llc->sap;
490
491		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
492				    llc->daddr.lsap, LLC_PDU_RSP);
493		llc_pdu_init_as_rej_rsp(nskb, 1, llc->vR);
494		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
495		if (unlikely(rc))
496			goto free;
497		llc_conn_send_pdu(sk, nskb);
498	}
499out:
500	return rc;
501free:
502	kfree_skb(nskb);
503	goto out;
504}
505
506int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
507{
508	int rc = -ENOBUFS;
509	struct llc_sock *llc = llc_sk(sk);
510	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
511
512	if (nskb) {
513		struct llc_sap *sap = llc->sap;
514
515		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
516				    llc->daddr.lsap, LLC_PDU_RSP);
517		llc_pdu_init_as_rej_rsp(nskb, 0, llc->vR);
518		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
519		if (unlikely(rc))
520			goto free;
521		llc_conn_send_pdu(sk, nskb);
522	}
523out:
524	return rc;
525free:
526	kfree_skb(nskb);
527	goto out;
528}
529
530int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
531{
532	int rc = -ENOBUFS;
533	struct llc_sock *llc = llc_sk(sk);
534	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
535
536	if (nskb) {
537		struct llc_sap *sap = llc->sap;
538
539		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
540				    llc->daddr.lsap, LLC_PDU_CMD);
541		llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR);
542		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
543		if (unlikely(rc))
544			goto free;
545		llc_conn_send_pdu(sk, nskb);
546	}
547out:
548	return rc;
549free:
550	kfree_skb(nskb);
551	goto out;
552}
553
554int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
555{
556	int rc = -ENOBUFS;
557	struct llc_sock *llc = llc_sk(sk);
558	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
559
560	if (nskb) {
561		struct llc_sap *sap = llc->sap;
562
563		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
564				    llc->daddr.lsap, LLC_PDU_RSP);
565		llc_pdu_init_as_rnr_rsp(nskb, 1, llc->vR);
566		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
567		if (unlikely(rc))
568			goto free;
569		llc_conn_send_pdu(sk, nskb);
570	}
571out:
572	return rc;
573free:
574	kfree_skb(nskb);
575	goto out;
576}
577
578int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
579{
580	int rc = -ENOBUFS;
581	struct llc_sock *llc = llc_sk(sk);
582	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
583
584	if (nskb) {
585		struct llc_sap *sap = llc->sap;
586
587		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
588				    llc->daddr.lsap, LLC_PDU_RSP);
589		llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
590		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
591		if (unlikely(rc))
592			goto free;
593		llc_conn_send_pdu(sk, nskb);
594	}
595out:
596	return rc;
597free:
598	kfree_skb(nskb);
599	goto out;
600}
601
602int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
603{
604	struct llc_sock *llc = llc_sk(sk);
605
606	if (!llc->remote_busy_flag) {
607		llc->remote_busy_flag = 1;
608		mod_timer(&llc->busy_state_timer.timer,
609			 jiffies + llc->busy_state_timer.expire);
610	}
611	return 0;
612}
613
614int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
615{
616	int rc = -ENOBUFS;
617	struct llc_sock *llc = llc_sk(sk);
618	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
619
620	if (nskb) {
621		struct llc_sap *sap = llc->sap;
622
623		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
624				    llc->daddr.lsap, LLC_PDU_RSP);
625		llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
626		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
627		if (unlikely(rc))
628			goto free;
629		llc_conn_send_pdu(sk, nskb);
630	}
631out:
632	return rc;
633free:
634	kfree_skb(nskb);
635	goto out;
636}
637
638int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
639{
640	int rc = -ENOBUFS;
641	struct llc_sock *llc = llc_sk(sk);
642	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
643
644	if (nskb) {
645		struct llc_sap *sap = llc->sap;
646
647		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
648				    llc->daddr.lsap, LLC_PDU_CMD);
649		llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
650		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
651		if (unlikely(rc))
652			goto free;
653		llc_conn_send_pdu(sk, nskb);
654	}
655out:
656	return rc;
657free:
658	kfree_skb(nskb);
659	goto out;
660}
661
662int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
663{
664	int rc = -ENOBUFS;
665	struct llc_sock *llc = llc_sk(sk);
666	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
667
668	if (nskb) {
669		struct llc_sap *sap = llc->sap;
670		u8 f_bit = 1;
671
672		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
673				    llc->daddr.lsap, LLC_PDU_RSP);
674		llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
675		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
676		if (unlikely(rc))
677			goto free;
678		llc_conn_send_pdu(sk, nskb);
679	}
680out:
681	return rc;
682free:
683	kfree_skb(nskb);
684	goto out;
685}
686
687int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
688{
689	int rc = -ENOBUFS;
690	struct llc_sock *llc = llc_sk(sk);
691	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
692
693	if (nskb) {
694		struct llc_sap *sap = llc->sap;
695
696		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
697				    llc->daddr.lsap, LLC_PDU_RSP);
698		llc_pdu_init_as_rr_rsp(nskb, 1, llc->vR);
699		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
700		if (unlikely(rc))
701			goto free;
702		llc_conn_send_pdu(sk, nskb);
703	}
704out:
705	return rc;
706free:
707	kfree_skb(nskb);
708	goto out;
709}
710
711int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
712{
713	int rc = -ENOBUFS;
714	struct llc_sock *llc = llc_sk(sk);
715	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
716
717	if (nskb) {
718		struct llc_sap *sap = llc->sap;
719
720		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
721				    llc->daddr.lsap, LLC_PDU_RSP);
722		llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
723		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
724		if (unlikely(rc))
725			goto free;
726		llc_conn_send_pdu(sk, nskb);
727	}
728out:
729	return rc;
730free:
731	kfree_skb(nskb);
732	goto out;
733}
734
735int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
736{
737	int rc = -ENOBUFS;
738	struct llc_sock *llc = llc_sk(sk);
739	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
740
741	if (nskb) {
742		struct llc_sap *sap = llc->sap;
743
744		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
745				    llc->daddr.lsap, LLC_PDU_RSP);
746		llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
747		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
748		if (unlikely(rc))
749			goto free;
750		llc_conn_send_pdu(sk, nskb);
751	}
752out:
753	return rc;
754free:
755	kfree_skb(nskb);
756	goto out;
757}
758
759void llc_conn_set_p_flag(struct sock *sk, u8 value)
760{
761	int state_changed = llc_sk(sk)->p_flag && !value;
762
763	llc_sk(sk)->p_flag = value;
764
765	if (state_changed)
766		sk->sk_state_change(sk);
767}
768
769int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
770{
771	int rc = -ENOBUFS;
772	struct llc_sock *llc = llc_sk(sk);
773	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
774
775	if (nskb) {
776		struct llc_sap *sap = llc->sap;
777		u8 *dmac = llc->daddr.mac;
778
779		if (llc->dev->flags & IFF_LOOPBACK)
780			dmac = llc->dev->dev_addr;
781		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
782				    llc->daddr.lsap, LLC_PDU_CMD);
783		llc_pdu_init_as_sabme_cmd(nskb, 1);
784		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac);
785		if (unlikely(rc))
786			goto free;
787		llc_conn_send_pdu(sk, nskb);
788		llc_conn_set_p_flag(sk, 1);
789	}
790out:
791	return rc;
792free:
793	kfree_skb(nskb);
794	goto out;
795}
796
797int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
798{
799	u8 f_bit;
800	int rc = -ENOBUFS;
801	struct llc_sock *llc = llc_sk(sk);
802	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
803
804	llc_pdu_decode_pf_bit(skb, &f_bit);
805	if (nskb) {
806		struct llc_sap *sap = llc->sap;
807
808		nskb->dev = llc->dev;
809		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
810				    llc->daddr.lsap, LLC_PDU_RSP);
811		llc_pdu_init_as_ua_rsp(nskb, f_bit);
812		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
813		if (unlikely(rc))
814			goto free;
815		llc_conn_send_pdu(sk, nskb);
816	}
817out:
818	return rc;
819free:
820	kfree_skb(nskb);
821	goto out;
822}
823
824int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb)
825{
826	llc_sk(sk)->s_flag = 0;
827	return 0;
828}
829
830int llc_conn_ac_set_s_flag_1(struct sock *sk, struct sk_buff *skb)
831{
832	llc_sk(sk)->s_flag = 1;
833	return 0;
834}
835
836int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb)
837{
838	struct llc_sock *llc = llc_sk(sk);
839
840	llc_conn_set_p_flag(sk, 1);
841	mod_timer(&llc->pf_cycle_timer.timer,
842		  jiffies + llc->pf_cycle_timer.expire);
843	return 0;
844}
845
846/**
847 *	llc_conn_ac_send_ack_if_needed - check if ack is needed
848 *	@sk: current connection structure
849 *	@skb: current event
850 *
851 *	Checks number of received PDUs which have not been acknowledged, yet,
852 *	If number of them reaches to "npta"(Number of PDUs To Acknowledge) then
853 *	sends an RR response as acknowledgement for them.  Returns 0 for
854 *	success, 1 otherwise.
855 */
856int llc_conn_ac_send_ack_if_needed(struct sock *sk, struct sk_buff *skb)
857{
858	u8 pf_bit;
859	struct llc_sock *llc = llc_sk(sk);
860
861	llc_pdu_decode_pf_bit(skb, &pf_bit);
862	llc->ack_pf |= pf_bit & 1;
863	if (!llc->ack_must_be_send) {
864		llc->first_pdu_Ns = llc->vR;
865		llc->ack_must_be_send = 1;
866		llc->ack_pf = pf_bit & 1;
867	}
868	if (((llc->vR - llc->first_pdu_Ns + 1 + LLC_2_SEQ_NBR_MODULO)
869			% LLC_2_SEQ_NBR_MODULO) >= llc->npta) {
870		llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, skb);
871		llc->ack_must_be_send	= 0;
872		llc->ack_pf		= 0;
873		llc_conn_ac_inc_npta_value(sk, skb);
874	}
875	return 0;
876}
877
878/**
879 *	llc_conn_ac_rst_sendack_flag - resets ack_must_be_send flag
880 *	@sk: current connection structure
881 *	@skb: current event
882 *
883 *	This action resets ack_must_be_send flag of given connection, this flag
884 *	indicates if there is any PDU which has not been acknowledged yet.
885 *	Returns 0 for success, 1 otherwise.
886 */
887int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb)
888{
889	llc_sk(sk)->ack_must_be_send = llc_sk(sk)->ack_pf = 0;
890	return 0;
891}
892
893/**
894 *	llc_conn_ac_send_i_rsp_f_set_ackpf - acknowledge received PDUs
895 *	@sk: current connection structure
896 *	@skb: current event
897 *
898 *	Sends an I response PDU with f-bit set to ack_pf flag as acknowledge to
899 *	all received PDUs which have not been acknowledged, yet. ack_pf flag is
900 *	set to one if one PDU with p-bit set to one is received.  Returns 0 for
901 *	success, 1 otherwise.
902 */
903static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
904					      struct sk_buff *skb)
905{
906	int rc;
907	struct llc_sock *llc = llc_sk(sk);
908	struct llc_sap *sap = llc->sap;
909
910	llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
911			    llc->daddr.lsap, LLC_PDU_RSP);
912	llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
913	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
914	if (likely(!rc)) {
915		llc_conn_send_pdu(sk, skb);
916		llc_conn_ac_inc_vs_by_1(sk, skb);
917	}
918	return rc;
919}
920
921/**
922 *	llc_conn_ac_send_i_as_ack - sends an I-format PDU to acknowledge rx PDUs
923 *	@sk: current connection structure.
924 *	@skb: current event.
925 *
926 *	This action sends an I-format PDU as acknowledge to received PDUs which
927 *	have not been acknowledged, yet, if there is any. By using of this
928 *	action number of acknowledgements decreases, this technic is called
929 *	piggy backing. Returns 0 for success, 1 otherwise.
930 */
931int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb)
932{
933	struct llc_sock *llc = llc_sk(sk);
934
935	if (llc->ack_must_be_send) {
936		llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
937		llc->ack_must_be_send = 0 ;
938		llc->ack_pf = 0;
939	} else
940		llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
941	return 0;
942}
943
944/**
945 *	llc_conn_ac_send_rr_rsp_f_set_ackpf - ack all rx PDUs not yet acked
946 *	@sk: current connection structure.
947 *	@skb: current event.
948 *
949 *	This action sends an RR response with f-bit set to ack_pf flag as
950 *	acknowledge to all received PDUs which have not been acknowledged, yet,
951 *	if there is any. ack_pf flag indicates if a PDU has been received with
952 *	p-bit set to one. Returns 0 for success, 1 otherwise.
953 */
954static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
955					       struct sk_buff *skb)
956{
957	int rc = -ENOBUFS;
958	struct llc_sock *llc = llc_sk(sk);
959	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
960
961	if (nskb) {
962		struct llc_sap *sap = llc->sap;
963
964		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
965				    llc->daddr.lsap, LLC_PDU_RSP);
966		llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR);
967		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
968		if (unlikely(rc))
969			goto free;
970		llc_conn_send_pdu(sk, nskb);
971	}
972out:
973	return rc;
974free:
975	kfree_skb(nskb);
976	goto out;
977}
978
979/**
980 *	llc_conn_ac_inc_npta_value - tries to make value of npta greater
981 *	@sk: current connection structure.
982 *	@skb: current event.
983 *
984 *	After "inc_cntr" times calling of this action, "npta" increase by one.
985 *	this action tries to make vale of "npta" greater as possible; number of
986 *	acknowledgements decreases by increasing of "npta". Returns 0 for
987 *	success, 1 otherwise.
988 */
989static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb)
990{
991	struct llc_sock *llc = llc_sk(sk);
992
993	if (!llc->inc_cntr) {
994		llc->dec_step = 0;
995		llc->dec_cntr = llc->inc_cntr = 2;
996		++llc->npta;
997		if (llc->npta > (u8) ~LLC_2_SEQ_NBR_MODULO)
998			llc->npta = (u8) ~LLC_2_SEQ_NBR_MODULO;
999	} else
1000		--llc->inc_cntr;
1001	return 0;
1002}
1003
1004/**
1005 *	llc_conn_ac_adjust_npta_by_rr - decreases "npta" by one
1006 *	@sk: current connection structure.
1007 *	@skb: current event.
1008 *
1009 *	After receiving "dec_cntr" times RR command, this action decreases
1010 *	"npta" by one. Returns 0 for success, 1 otherwise.
1011 */
1012int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct sk_buff *skb)
1013{
1014	struct llc_sock *llc = llc_sk(sk);
1015
1016	if (!llc->connect_step && !llc->remote_busy_flag) {
1017		if (!llc->dec_step) {
1018			if (!llc->dec_cntr) {
1019				llc->inc_cntr = llc->dec_cntr = 2;
1020				if (llc->npta > 0)
1021					llc->npta = llc->npta - 1;
1022			} else
1023				llc->dec_cntr -=1;
1024		}
1025	} else
1026		llc->connect_step = 0 ;
1027	return 0;
1028}
1029
1030/**
1031 *	llc_conn_ac_adjust_npta_by_rnr - decreases "npta" by one
1032 *	@sk: current connection structure.
1033 *	@skb: current event.
1034 *
1035 *	After receiving "dec_cntr" times RNR command, this action decreases
1036 *	"npta" by one. Returns 0 for success, 1 otherwise.
1037 */
1038int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, struct sk_buff *skb)
1039{
1040	struct llc_sock *llc = llc_sk(sk);
1041
1042	if (llc->remote_busy_flag)
1043		if (!llc->dec_step) {
1044			if (!llc->dec_cntr) {
1045				llc->inc_cntr = llc->dec_cntr = 2;
1046				if (llc->npta > 0)
1047					--llc->npta;
1048			} else
1049				--llc->dec_cntr;
1050		}
1051	return 0;
1052}
1053
1054/**
1055 *	llc_conn_ac_dec_tx_win_size - decreases tx window size
1056 *	@sk: current connection structure.
1057 *	@skb: current event.
1058 *
1059 *	After receiving of a REJ command or response, transmit window size is
1060 *	decreased by number of PDUs which are outstanding yet. Returns 0 for
1061 *	success, 1 otherwise.
1062 */
1063int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct sk_buff *skb)
1064{
1065	struct llc_sock *llc = llc_sk(sk);
1066	u8 unacked_pdu = skb_queue_len(&llc->pdu_unack_q);
1067
1068	if (llc->k - unacked_pdu < 1)
1069		llc->k = 1;
1070	else
1071		llc->k -= unacked_pdu;
1072	return 0;
1073}
1074
1075/**
1076 *	llc_conn_ac_inc_tx_win_size - tx window size is inc by 1
1077 *	@sk: current connection structure.
1078 *	@skb: current event.
1079 *
1080 *	After receiving an RR response with f-bit set to one, transmit window
1081 *	size is increased by one. Returns 0 for success, 1 otherwise.
1082 */
1083int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb)
1084{
1085	struct llc_sock *llc = llc_sk(sk);
1086
1087	llc->k += 1;
1088	if (llc->k > (u8) ~LLC_2_SEQ_NBR_MODULO)
1089		llc->k = (u8) ~LLC_2_SEQ_NBR_MODULO;
1090	return 0;
1091}
1092
1093int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb)
1094{
1095	struct llc_sock *llc = llc_sk(sk);
1096
1097	del_timer(&llc->pf_cycle_timer.timer);
1098	del_timer(&llc->ack_timer.timer);
1099	del_timer(&llc->rej_sent_timer.timer);
1100	del_timer(&llc->busy_state_timer.timer);
1101	llc->ack_must_be_send = 0;
1102	llc->ack_pf = 0;
1103	return 0;
1104}
1105
1106int llc_conn_ac_stop_other_timers(struct sock *sk, struct sk_buff *skb)
1107{
1108	struct llc_sock *llc = llc_sk(sk);
1109
1110	del_timer(&llc->rej_sent_timer.timer);
1111	del_timer(&llc->pf_cycle_timer.timer);
1112	del_timer(&llc->busy_state_timer.timer);
1113	llc->ack_must_be_send = 0;
1114	llc->ack_pf = 0;
1115	return 0;
1116}
1117
1118int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb)
1119{
1120	struct llc_sock *llc = llc_sk(sk);
1121
1122	mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire);
1123	return 0;
1124}
1125
1126int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb)
1127{
1128	struct llc_sock *llc = llc_sk(sk);
1129
1130	mod_timer(&llc->rej_sent_timer.timer,
1131		  jiffies + llc->rej_sent_timer.expire);
1132	return 0;
1133}
1134
1135int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
1136					     struct sk_buff *skb)
1137{
1138	struct llc_sock *llc = llc_sk(sk);
1139
1140	if (!timer_pending(&llc->ack_timer.timer))
1141		mod_timer(&llc->ack_timer.timer,
1142			  jiffies + llc->ack_timer.expire);
1143	return 0;
1144}
1145
1146int llc_conn_ac_stop_ack_timer(struct sock *sk, struct sk_buff *skb)
1147{
1148	del_timer(&llc_sk(sk)->ack_timer.timer);
1149	return 0;
1150}
1151
1152int llc_conn_ac_stop_p_timer(struct sock *sk, struct sk_buff *skb)
1153{
1154	struct llc_sock *llc = llc_sk(sk);
1155
1156	del_timer(&llc->pf_cycle_timer.timer);
1157	llc_conn_set_p_flag(sk, 0);
1158	return 0;
1159}
1160
1161int llc_conn_ac_stop_rej_timer(struct sock *sk, struct sk_buff *skb)
1162{
1163	del_timer(&llc_sk(sk)->rej_sent_timer.timer);
1164	return 0;
1165}
1166
1167int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb)
1168{
1169	int acked;
1170	u16 unacked = 0;
1171	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1172	struct llc_sock *llc = llc_sk(sk);
1173
1174	llc->last_nr = PDU_SUPV_GET_Nr(pdu);
1175	acked = llc_conn_remove_acked_pdus(sk, llc->last_nr, &unacked);
1176	/* On loopback we don't queue I frames in unack_pdu_q queue. */
1177	if (acked > 0 || (llc->dev->flags & IFF_LOOPBACK)) {
1178		llc->retry_count = 0;
1179		del_timer(&llc->ack_timer.timer);
1180		if (llc->failed_data_req) {
1181			/* already, we did not accept data from upper layer
1182			 * (tx_window full or unacceptable state). Now, we
1183			 * can send data and must inform to upper layer.
1184			 */
1185			llc->failed_data_req = 0;
1186			llc_conn_ac_data_confirm(sk, skb);
1187		}
1188		if (unacked)
1189			mod_timer(&llc->ack_timer.timer,
1190				  jiffies + llc->ack_timer.expire);
1191	} else if (llc->failed_data_req) {
1192		u8 f_bit;
1193
1194		llc_pdu_decode_pf_bit(skb, &f_bit);
1195		if (f_bit == 1) {
1196			llc->failed_data_req = 0;
1197			llc_conn_ac_data_confirm(sk, skb);
1198		}
1199	}
1200	return 0;
1201}
1202
1203int llc_conn_ac_upd_p_flag(struct sock *sk, struct sk_buff *skb)
1204{
1205	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1206
1207	if (LLC_PDU_IS_RSP(pdu)) {
1208		u8 f_bit;
1209
1210		llc_pdu_decode_pf_bit(skb, &f_bit);
1211		if (f_bit) {
1212			llc_conn_set_p_flag(sk, 0);
1213			llc_conn_ac_stop_p_timer(sk, skb);
1214		}
1215	}
1216	return 0;
1217}
1218
1219int llc_conn_ac_set_data_flag_2(struct sock *sk, struct sk_buff *skb)
1220{
1221	llc_sk(sk)->data_flag = 2;
1222	return 0;
1223}
1224
1225int llc_conn_ac_set_data_flag_0(struct sock *sk, struct sk_buff *skb)
1226{
1227	llc_sk(sk)->data_flag = 0;
1228	return 0;
1229}
1230
1231int llc_conn_ac_set_data_flag_1(struct sock *sk, struct sk_buff *skb)
1232{
1233	llc_sk(sk)->data_flag = 1;
1234	return 0;
1235}
1236
1237int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk,
1238						  struct sk_buff *skb)
1239{
1240	if (!llc_sk(sk)->data_flag)
1241		llc_sk(sk)->data_flag = 1;
1242	return 0;
1243}
1244
1245int llc_conn_ac_set_p_flag_0(struct sock *sk, struct sk_buff *skb)
1246{
1247	llc_conn_set_p_flag(sk, 0);
1248	return 0;
1249}
1250
1251static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb)
1252{
1253	llc_conn_set_p_flag(sk, 1);
1254	return 0;
1255}
1256
1257int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct sk_buff *skb)
1258{
1259	llc_sk(sk)->remote_busy_flag = 0;
1260	return 0;
1261}
1262
1263int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct sk_buff *skb)
1264{
1265	llc_sk(sk)->cause_flag = 0;
1266	return 0;
1267}
1268
1269int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct sk_buff *skb)
1270{
1271	llc_sk(sk)->cause_flag = 1;
1272	return 0;
1273}
1274
1275int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct sk_buff *skb)
1276{
1277	llc_sk(sk)->retry_count = 0;
1278	return 0;
1279}
1280
1281int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk, struct sk_buff *skb)
1282{
1283	llc_sk(sk)->retry_count++;
1284	return 0;
1285}
1286
1287int llc_conn_ac_set_vr_0(struct sock *sk, struct sk_buff *skb)
1288{
1289	llc_sk(sk)->vR = 0;
1290	return 0;
1291}
1292
1293int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct sk_buff *skb)
1294{
1295	llc_sk(sk)->vR = PDU_GET_NEXT_Vr(llc_sk(sk)->vR);
1296	return 0;
1297}
1298
1299int llc_conn_ac_set_vs_0(struct sock *sk, struct sk_buff *skb)
1300{
1301	llc_sk(sk)->vS = 0;
1302	return 0;
1303}
1304
1305int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb)
1306{
1307	llc_sk(sk)->vS = llc_sk(sk)->last_nr;
1308	return 0;
1309}
1310
1311static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb)
1312{
1313	llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO;
1314	return 0;
1315}
1316
1317static void llc_conn_tmr_common_cb(unsigned long timeout_data, u8 type)
1318{
1319	struct sock *sk = (struct sock *)timeout_data;
1320	struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
1321
1322	bh_lock_sock(sk);
1323	if (skb) {
1324		struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1325
1326		skb_set_owner_r(skb, sk);
1327		ev->type = type;
1328		llc_process_tmr_ev(sk, skb);
1329	}
1330	bh_unlock_sock(sk);
1331}
1332
1333void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
1334{
1335	llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_P_TMR);
1336}
1337
1338void llc_conn_busy_tmr_cb(unsigned long timeout_data)
1339{
1340	llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_BUSY_TMR);
1341}
1342
1343void llc_conn_ack_tmr_cb(unsigned long timeout_data)
1344{
1345	llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_ACK_TMR);
1346}
1347
1348void llc_conn_rej_tmr_cb(unsigned long timeout_data)
1349{
1350	llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_REJ_TMR);
1351}
1352
1353int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb)
1354{
1355	llc_sk(sk)->X = llc_sk(sk)->vS;
1356	llc_conn_ac_set_vs_nr(sk, skb);
1357	return 0;
1358}
1359
1360int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb)
1361{
1362	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1363	u8 nr = PDU_SUPV_GET_Nr(pdu);
1364
1365	if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X))
1366		llc_conn_ac_set_vs_nr(sk, skb);
1367	return 0;
1368}
1369
1370/*
1371 * Non-standard actions; these not contained in IEEE specification; for
1372 * our own usage
1373 */
1374/**
1375 *	llc_conn_disc - removes connection from SAP list and frees it
1376 *	@sk: closed connection
1377 *	@skb: occurred event
1378 */
1379int llc_conn_disc(struct sock *sk, struct sk_buff *skb)
1380{
1381	/* FIXME: this thing seems to want to die */
1382	return 0;
1383}
1384
1385/**
1386 *	llc_conn_reset - resets connection
1387 *	@sk : reseting connection.
1388 *	@skb: occurred event.
1389 *
1390 *	Stop all timers, empty all queues and reset all flags.
1391 */
1392int llc_conn_reset(struct sock *sk, struct sk_buff *skb)
1393{
1394	llc_sk_reset(sk);
1395	return 0;
1396}
1397
1398/**
1399 *	llc_circular_between - designates that b is between a and c or not
1400 *	@a: lower bound
1401 *	@b: element to see if is between a and b
1402 *	@c: upper bound
1403 *
1404 *	This function designates that b is between a and c or not (for example,
1405 *	0 is between 127 and 1). Returns 1 if b is between a and c, 0
1406 *	otherwise.
1407 */
1408u8 llc_circular_between(u8 a, u8 b, u8 c)
1409{
1410	b = b - a;
1411	c = c - a;
1412	return b <= c;
1413}
1414
1415/**
1416 *	llc_process_tmr_ev - timer backend
1417 *	@sk: active connection
1418 *	@skb: occurred event
1419 *
1420 *	This function is called from timer callback functions. When connection
1421 *	is busy (during sending a data frame) timer expiration event must be
1422 *	queued. Otherwise this event can be sent to connection state machine.
1423 *	Queued events will process by llc_backlog_rcv function after sending
1424 *	data frame.
1425 */
1426static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
1427{
1428	if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) {
1429		printk(KERN_WARNING "%s: timer called on closed connection\n",
1430		       __FUNCTION__);
1431		kfree_skb(skb);
1432	} else {
1433		if (!sock_owned_by_user(sk))
1434			llc_conn_state_process(sk, skb);
1435		else {
1436			llc_set_backlog_type(skb, LLC_EVENT);
1437			sk_add_backlog(sk, skb);
1438		}
1439	}
1440}
1441