Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/llc/llc_c_ac.c
26282 views
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 <[email protected]>
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
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
timer_delete(&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
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
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
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
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
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
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
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
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
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
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
timer_delete(&llc->rej_sent_timer.timer);
195
return 0;
196
}
197
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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
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
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
timer_delete(&llc->rej_sent_timer.timer);
1115
timer_delete(&llc->pf_cycle_timer.timer);
1116
timer_delete(&llc->busy_state_timer.timer);
1117
llc->ack_must_be_send = 0;
1118
llc->ack_pf = 0;
1119
return 0;
1120
}
1121
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
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
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
1150
int llc_conn_ac_stop_ack_timer(struct sock *sk, struct sk_buff *skb)
1151
{
1152
timer_delete(&llc_sk(sk)->ack_timer.timer);
1153
return 0;
1154
}
1155
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
timer_delete(&llc->pf_cycle_timer.timer);
1161
llc_conn_set_p_flag(sk, 0);
1162
return 0;
1163
}
1164
1165
int llc_conn_ac_stop_rej_timer(struct sock *sk, struct sk_buff *skb)
1166
{
1167
timer_delete(&llc_sk(sk)->rej_sent_timer.timer);
1168
return 0;
1169
}
1170
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
timer_delete(&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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
1336
void llc_conn_pf_cycle_tmr_cb(struct timer_list *t)
1337
{
1338
struct llc_sock *llc = timer_container_of(llc, t,
1339
pf_cycle_timer.timer);
1340
1341
llc_conn_tmr_common_cb(&llc->sk, LLC_CONN_EV_TYPE_P_TMR);
1342
}
1343
1344
void llc_conn_busy_tmr_cb(struct timer_list *t)
1345
{
1346
struct llc_sock *llc = timer_container_of(llc, t,
1347
busy_state_timer.timer);
1348
1349
llc_conn_tmr_common_cb(&llc->sk, LLC_CONN_EV_TYPE_BUSY_TMR);
1350
}
1351
1352
void llc_conn_ack_tmr_cb(struct timer_list *t)
1353
{
1354
struct llc_sock *llc = timer_container_of(llc, t, ack_timer.timer);
1355
1356
llc_conn_tmr_common_cb(&llc->sk, LLC_CONN_EV_TYPE_ACK_TMR);
1357
}
1358
1359
void llc_conn_rej_tmr_cb(struct timer_list *t)
1360
{
1361
struct llc_sock *llc = timer_container_of(llc, t,
1362
rej_sent_timer.timer);
1363
1364
llc_conn_tmr_common_cb(&llc->sk, LLC_CONN_EV_TYPE_REJ_TMR);
1365
}
1366
1367
int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb)
1368
{
1369
llc_sk(sk)->X = llc_sk(sk)->vS;
1370
llc_conn_ac_set_vs_nr(sk, skb);
1371
return 0;
1372
}
1373
1374
int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb)
1375
{
1376
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1377
u8 nr = PDU_SUPV_GET_Nr(pdu);
1378
1379
if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X))
1380
llc_conn_ac_set_vs_nr(sk, skb);
1381
return 0;
1382
}
1383
1384
/*
1385
* Non-standard actions; these not contained in IEEE specification; for
1386
* our own usage
1387
*/
1388
/**
1389
* llc_conn_disc - removes connection from SAP list and frees it
1390
* @sk: closed connection
1391
* @skb: occurred event
1392
*/
1393
int llc_conn_disc(struct sock *sk, struct sk_buff *skb)
1394
{
1395
/* FIXME: this thing seems to want to die */
1396
return 0;
1397
}
1398
1399
/**
1400
* llc_conn_reset - resets connection
1401
* @sk : reseting connection.
1402
* @skb: occurred event.
1403
*
1404
* Stop all timers, empty all queues and reset all flags.
1405
*/
1406
int llc_conn_reset(struct sock *sk, struct sk_buff *skb)
1407
{
1408
llc_sk_reset(sk);
1409
return 0;
1410
}
1411
1412
/**
1413
* llc_circular_between - designates that b is between a and c or not
1414
* @a: lower bound
1415
* @b: element to see if is between a and b
1416
* @c: upper bound
1417
*
1418
* This function designates that b is between a and c or not (for example,
1419
* 0 is between 127 and 1). Returns 1 if b is between a and c, 0
1420
* otherwise.
1421
*/
1422
u8 llc_circular_between(u8 a, u8 b, u8 c)
1423
{
1424
b = b - a;
1425
c = c - a;
1426
return b <= c;
1427
}
1428
1429
/**
1430
* llc_process_tmr_ev - timer backend
1431
* @sk: active connection
1432
* @skb: occurred event
1433
*
1434
* This function is called from timer callback functions. When connection
1435
* is busy (during sending a data frame) timer expiration event must be
1436
* queued. Otherwise this event can be sent to connection state machine.
1437
* Queued events will process by llc_backlog_rcv function after sending
1438
* data frame.
1439
*/
1440
static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
1441
{
1442
if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) {
1443
printk(KERN_WARNING "%s: timer called on closed connection\n",
1444
__func__);
1445
kfree_skb(skb);
1446
} else {
1447
if (!sock_owned_by_user(sk))
1448
llc_conn_state_process(sk, skb);
1449
else {
1450
llc_set_backlog_type(skb, LLC_EVENT);
1451
__sk_add_backlog(sk, skb);
1452
}
1453
}
1454
}
1455
1456