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