Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/llc/llc_c_ac.c
15109 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
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
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
del_timer(&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
llc_conn_send_pdu(sk, skb);
376
llc_conn_ac_inc_vs_by_1(sk, skb);
377
}
378
return rc;
379
}
380
381
static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
382
{
383
int rc;
384
struct llc_sock *llc = llc_sk(sk);
385
struct llc_sap *sap = llc->sap;
386
387
llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
388
llc->daddr.lsap, LLC_PDU_CMD);
389
llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
390
rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
391
if (likely(!rc)) {
392
llc_conn_send_pdu(sk, skb);
393
llc_conn_ac_inc_vs_by_1(sk, skb);
394
}
395
return rc;
396
}
397
398
int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
399
{
400
int rc;
401
struct llc_sock *llc = llc_sk(sk);
402
struct llc_sap *sap = llc->sap;
403
404
llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
405
llc->daddr.lsap, LLC_PDU_CMD);
406
llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
407
rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
408
if (likely(!rc)) {
409
llc_conn_send_pdu(sk, skb);
410
llc_conn_ac_inc_vs_by_1(sk, skb);
411
}
412
return 0;
413
}
414
415
int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
416
{
417
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
418
u8 nr = LLC_I_GET_NR(pdu);
419
420
llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
421
return 0;
422
}
423
424
int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
425
struct sk_buff *skb)
426
{
427
u8 nr;
428
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
429
int rc = -ENOBUFS;
430
struct llc_sock *llc = llc_sk(sk);
431
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
432
433
if (nskb) {
434
struct llc_sap *sap = llc->sap;
435
436
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
437
llc->daddr.lsap, LLC_PDU_RSP);
438
llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
439
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
440
if (likely(!rc))
441
llc_conn_send_pdu(sk, nskb);
442
else
443
kfree_skb(skb);
444
}
445
if (rc) {
446
nr = LLC_I_GET_NR(pdu);
447
rc = 0;
448
llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
449
}
450
return rc;
451
}
452
453
int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
454
{
455
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
456
u8 nr = LLC_I_GET_NR(pdu);
457
458
llc_conn_resend_i_pdu_as_rsp(sk, nr, 1);
459
return 0;
460
}
461
462
int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
463
{
464
int rc = -ENOBUFS;
465
struct llc_sock *llc = llc_sk(sk);
466
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
467
468
if (nskb) {
469
struct llc_sap *sap = llc->sap;
470
471
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
472
llc->daddr.lsap, LLC_PDU_CMD);
473
llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);
474
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
475
if (unlikely(rc))
476
goto free;
477
llc_conn_send_pdu(sk, nskb);
478
}
479
out:
480
return rc;
481
free:
482
kfree_skb(nskb);
483
goto out;
484
}
485
486
int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
487
{
488
int rc = -ENOBUFS;
489
struct llc_sock *llc = llc_sk(sk);
490
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
491
492
if (nskb) {
493
struct llc_sap *sap = llc->sap;
494
495
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
496
llc->daddr.lsap, LLC_PDU_RSP);
497
llc_pdu_init_as_rej_rsp(nskb, 1, llc->vR);
498
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
499
if (unlikely(rc))
500
goto free;
501
llc_conn_send_pdu(sk, nskb);
502
}
503
out:
504
return rc;
505
free:
506
kfree_skb(nskb);
507
goto out;
508
}
509
510
int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
511
{
512
int rc = -ENOBUFS;
513
struct llc_sock *llc = llc_sk(sk);
514
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
515
516
if (nskb) {
517
struct llc_sap *sap = llc->sap;
518
519
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
520
llc->daddr.lsap, LLC_PDU_RSP);
521
llc_pdu_init_as_rej_rsp(nskb, 0, llc->vR);
522
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
523
if (unlikely(rc))
524
goto free;
525
llc_conn_send_pdu(sk, nskb);
526
}
527
out:
528
return rc;
529
free:
530
kfree_skb(nskb);
531
goto out;
532
}
533
534
int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
535
{
536
int rc = -ENOBUFS;
537
struct llc_sock *llc = llc_sk(sk);
538
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
539
540
if (nskb) {
541
struct llc_sap *sap = llc->sap;
542
543
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
544
llc->daddr.lsap, LLC_PDU_CMD);
545
llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR);
546
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
547
if (unlikely(rc))
548
goto free;
549
llc_conn_send_pdu(sk, nskb);
550
}
551
out:
552
return rc;
553
free:
554
kfree_skb(nskb);
555
goto out;
556
}
557
558
int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
559
{
560
int rc = -ENOBUFS;
561
struct llc_sock *llc = llc_sk(sk);
562
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
563
564
if (nskb) {
565
struct llc_sap *sap = llc->sap;
566
567
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
568
llc->daddr.lsap, LLC_PDU_RSP);
569
llc_pdu_init_as_rnr_rsp(nskb, 1, llc->vR);
570
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
571
if (unlikely(rc))
572
goto free;
573
llc_conn_send_pdu(sk, nskb);
574
}
575
out:
576
return rc;
577
free:
578
kfree_skb(nskb);
579
goto out;
580
}
581
582
int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
583
{
584
int rc = -ENOBUFS;
585
struct llc_sock *llc = llc_sk(sk);
586
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
587
588
if (nskb) {
589
struct llc_sap *sap = llc->sap;
590
591
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
592
llc->daddr.lsap, LLC_PDU_RSP);
593
llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
594
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
595
if (unlikely(rc))
596
goto free;
597
llc_conn_send_pdu(sk, nskb);
598
}
599
out:
600
return rc;
601
free:
602
kfree_skb(nskb);
603
goto out;
604
}
605
606
int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
607
{
608
struct llc_sock *llc = llc_sk(sk);
609
610
if (!llc->remote_busy_flag) {
611
llc->remote_busy_flag = 1;
612
mod_timer(&llc->busy_state_timer.timer,
613
jiffies + llc->busy_state_timer.expire);
614
}
615
return 0;
616
}
617
618
int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
619
{
620
int rc = -ENOBUFS;
621
struct llc_sock *llc = llc_sk(sk);
622
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
623
624
if (nskb) {
625
struct llc_sap *sap = llc->sap;
626
627
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
628
llc->daddr.lsap, LLC_PDU_RSP);
629
llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
630
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
631
if (unlikely(rc))
632
goto free;
633
llc_conn_send_pdu(sk, nskb);
634
}
635
out:
636
return rc;
637
free:
638
kfree_skb(nskb);
639
goto out;
640
}
641
642
int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
643
{
644
int rc = -ENOBUFS;
645
struct llc_sock *llc = llc_sk(sk);
646
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
647
648
if (nskb) {
649
struct llc_sap *sap = llc->sap;
650
651
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
652
llc->daddr.lsap, LLC_PDU_CMD);
653
llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
654
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
655
if (unlikely(rc))
656
goto free;
657
llc_conn_send_pdu(sk, nskb);
658
}
659
out:
660
return rc;
661
free:
662
kfree_skb(nskb);
663
goto out;
664
}
665
666
int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
667
{
668
int rc = -ENOBUFS;
669
struct llc_sock *llc = llc_sk(sk);
670
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
671
672
if (nskb) {
673
struct llc_sap *sap = llc->sap;
674
u8 f_bit = 1;
675
676
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
677
llc->daddr.lsap, LLC_PDU_RSP);
678
llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
679
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
680
if (unlikely(rc))
681
goto free;
682
llc_conn_send_pdu(sk, nskb);
683
}
684
out:
685
return rc;
686
free:
687
kfree_skb(nskb);
688
goto out;
689
}
690
691
int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
692
{
693
int rc = -ENOBUFS;
694
struct llc_sock *llc = llc_sk(sk);
695
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
696
697
if (nskb) {
698
struct llc_sap *sap = llc->sap;
699
700
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
701
llc->daddr.lsap, LLC_PDU_RSP);
702
llc_pdu_init_as_rr_rsp(nskb, 1, llc->vR);
703
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
704
if (unlikely(rc))
705
goto free;
706
llc_conn_send_pdu(sk, nskb);
707
}
708
out:
709
return rc;
710
free:
711
kfree_skb(nskb);
712
goto out;
713
}
714
715
int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
716
{
717
int rc = -ENOBUFS;
718
struct llc_sock *llc = llc_sk(sk);
719
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
720
721
if (nskb) {
722
struct llc_sap *sap = llc->sap;
723
724
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
725
llc->daddr.lsap, LLC_PDU_RSP);
726
llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
727
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
728
if (unlikely(rc))
729
goto free;
730
llc_conn_send_pdu(sk, nskb);
731
}
732
out:
733
return rc;
734
free:
735
kfree_skb(nskb);
736
goto out;
737
}
738
739
int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
740
{
741
int rc = -ENOBUFS;
742
struct llc_sock *llc = llc_sk(sk);
743
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
744
745
if (nskb) {
746
struct llc_sap *sap = llc->sap;
747
748
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
749
llc->daddr.lsap, LLC_PDU_RSP);
750
llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
751
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
752
if (unlikely(rc))
753
goto free;
754
llc_conn_send_pdu(sk, nskb);
755
}
756
out:
757
return rc;
758
free:
759
kfree_skb(nskb);
760
goto out;
761
}
762
763
void llc_conn_set_p_flag(struct sock *sk, u8 value)
764
{
765
int state_changed = llc_sk(sk)->p_flag && !value;
766
767
llc_sk(sk)->p_flag = value;
768
769
if (state_changed)
770
sk->sk_state_change(sk);
771
}
772
773
int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
774
{
775
int rc = -ENOBUFS;
776
struct llc_sock *llc = llc_sk(sk);
777
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
778
779
if (nskb) {
780
struct llc_sap *sap = llc->sap;
781
u8 *dmac = llc->daddr.mac;
782
783
if (llc->dev->flags & IFF_LOOPBACK)
784
dmac = llc->dev->dev_addr;
785
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
786
llc->daddr.lsap, LLC_PDU_CMD);
787
llc_pdu_init_as_sabme_cmd(nskb, 1);
788
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac);
789
if (unlikely(rc))
790
goto free;
791
llc_conn_send_pdu(sk, nskb);
792
llc_conn_set_p_flag(sk, 1);
793
}
794
out:
795
return rc;
796
free:
797
kfree_skb(nskb);
798
goto out;
799
}
800
801
int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
802
{
803
u8 f_bit;
804
int rc = -ENOBUFS;
805
struct llc_sock *llc = llc_sk(sk);
806
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
807
808
llc_pdu_decode_pf_bit(skb, &f_bit);
809
if (nskb) {
810
struct llc_sap *sap = llc->sap;
811
812
nskb->dev = llc->dev;
813
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
814
llc->daddr.lsap, LLC_PDU_RSP);
815
llc_pdu_init_as_ua_rsp(nskb, f_bit);
816
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
817
if (unlikely(rc))
818
goto free;
819
llc_conn_send_pdu(sk, nskb);
820
}
821
out:
822
return rc;
823
free:
824
kfree_skb(nskb);
825
goto out;
826
}
827
828
int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb)
829
{
830
llc_sk(sk)->s_flag = 0;
831
return 0;
832
}
833
834
int llc_conn_ac_set_s_flag_1(struct sock *sk, struct sk_buff *skb)
835
{
836
llc_sk(sk)->s_flag = 1;
837
return 0;
838
}
839
840
int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb)
841
{
842
struct llc_sock *llc = llc_sk(sk);
843
844
llc_conn_set_p_flag(sk, 1);
845
mod_timer(&llc->pf_cycle_timer.timer,
846
jiffies + llc->pf_cycle_timer.expire);
847
return 0;
848
}
849
850
/**
851
* llc_conn_ac_send_ack_if_needed - check if ack is needed
852
* @sk: current connection structure
853
* @skb: current event
854
*
855
* Checks number of received PDUs which have not been acknowledged, yet,
856
* If number of them reaches to "npta"(Number of PDUs To Acknowledge) then
857
* sends an RR response as acknowledgement for them. Returns 0 for
858
* success, 1 otherwise.
859
*/
860
int llc_conn_ac_send_ack_if_needed(struct sock *sk, struct sk_buff *skb)
861
{
862
u8 pf_bit;
863
struct llc_sock *llc = llc_sk(sk);
864
865
llc_pdu_decode_pf_bit(skb, &pf_bit);
866
llc->ack_pf |= pf_bit & 1;
867
if (!llc->ack_must_be_send) {
868
llc->first_pdu_Ns = llc->vR;
869
llc->ack_must_be_send = 1;
870
llc->ack_pf = pf_bit & 1;
871
}
872
if (((llc->vR - llc->first_pdu_Ns + 1 + LLC_2_SEQ_NBR_MODULO)
873
% LLC_2_SEQ_NBR_MODULO) >= llc->npta) {
874
llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, skb);
875
llc->ack_must_be_send = 0;
876
llc->ack_pf = 0;
877
llc_conn_ac_inc_npta_value(sk, skb);
878
}
879
return 0;
880
}
881
882
/**
883
* llc_conn_ac_rst_sendack_flag - resets ack_must_be_send flag
884
* @sk: current connection structure
885
* @skb: current event
886
*
887
* This action resets ack_must_be_send flag of given connection, this flag
888
* indicates if there is any PDU which has not been acknowledged yet.
889
* Returns 0 for success, 1 otherwise.
890
*/
891
int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb)
892
{
893
llc_sk(sk)->ack_must_be_send = llc_sk(sk)->ack_pf = 0;
894
return 0;
895
}
896
897
/**
898
* llc_conn_ac_send_i_rsp_f_set_ackpf - acknowledge received PDUs
899
* @sk: current connection structure
900
* @skb: current event
901
*
902
* Sends an I response PDU with f-bit set to ack_pf flag as acknowledge to
903
* all received PDUs which have not been acknowledged, yet. ack_pf flag is
904
* set to one if one PDU with p-bit set to one is received. Returns 0 for
905
* success, 1 otherwise.
906
*/
907
static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
908
struct sk_buff *skb)
909
{
910
int rc;
911
struct llc_sock *llc = llc_sk(sk);
912
struct llc_sap *sap = llc->sap;
913
914
llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
915
llc->daddr.lsap, LLC_PDU_RSP);
916
llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
917
rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
918
if (likely(!rc)) {
919
llc_conn_send_pdu(sk, skb);
920
llc_conn_ac_inc_vs_by_1(sk, skb);
921
}
922
return rc;
923
}
924
925
/**
926
* llc_conn_ac_send_i_as_ack - sends an I-format PDU to acknowledge rx PDUs
927
* @sk: current connection structure.
928
* @skb: current event.
929
*
930
* This action sends an I-format PDU as acknowledge to received PDUs which
931
* have not been acknowledged, yet, if there is any. By using of this
932
* action number of acknowledgements decreases, this technic is called
933
* piggy backing. Returns 0 for success, 1 otherwise.
934
*/
935
int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb)
936
{
937
struct llc_sock *llc = llc_sk(sk);
938
939
if (llc->ack_must_be_send) {
940
llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
941
llc->ack_must_be_send = 0 ;
942
llc->ack_pf = 0;
943
} else
944
llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
945
return 0;
946
}
947
948
/**
949
* llc_conn_ac_send_rr_rsp_f_set_ackpf - ack all rx PDUs not yet acked
950
* @sk: current connection structure.
951
* @skb: current event.
952
*
953
* This action sends an RR response with f-bit set to ack_pf flag as
954
* acknowledge to all received PDUs which have not been acknowledged, yet,
955
* if there is any. ack_pf flag indicates if a PDU has been received with
956
* p-bit set to one. Returns 0 for success, 1 otherwise.
957
*/
958
static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
959
struct sk_buff *skb)
960
{
961
int rc = -ENOBUFS;
962
struct llc_sock *llc = llc_sk(sk);
963
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
964
965
if (nskb) {
966
struct llc_sap *sap = llc->sap;
967
968
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
969
llc->daddr.lsap, LLC_PDU_RSP);
970
llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR);
971
rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
972
if (unlikely(rc))
973
goto free;
974
llc_conn_send_pdu(sk, nskb);
975
}
976
out:
977
return rc;
978
free:
979
kfree_skb(nskb);
980
goto out;
981
}
982
983
/**
984
* llc_conn_ac_inc_npta_value - tries to make value of npta greater
985
* @sk: current connection structure.
986
* @skb: current event.
987
*
988
* After "inc_cntr" times calling of this action, "npta" increase by one.
989
* this action tries to make vale of "npta" greater as possible; number of
990
* acknowledgements decreases by increasing of "npta". Returns 0 for
991
* success, 1 otherwise.
992
*/
993
static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb)
994
{
995
struct llc_sock *llc = llc_sk(sk);
996
997
if (!llc->inc_cntr) {
998
llc->dec_step = 0;
999
llc->dec_cntr = llc->inc_cntr = 2;
1000
++llc->npta;
1001
if (llc->npta > (u8) ~LLC_2_SEQ_NBR_MODULO)
1002
llc->npta = (u8) ~LLC_2_SEQ_NBR_MODULO;
1003
} else
1004
--llc->inc_cntr;
1005
return 0;
1006
}
1007
1008
/**
1009
* llc_conn_ac_adjust_npta_by_rr - decreases "npta" by one
1010
* @sk: current connection structure.
1011
* @skb: current event.
1012
*
1013
* After receiving "dec_cntr" times RR command, this action decreases
1014
* "npta" by one. Returns 0 for success, 1 otherwise.
1015
*/
1016
int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct sk_buff *skb)
1017
{
1018
struct llc_sock *llc = llc_sk(sk);
1019
1020
if (!llc->connect_step && !llc->remote_busy_flag) {
1021
if (!llc->dec_step) {
1022
if (!llc->dec_cntr) {
1023
llc->inc_cntr = llc->dec_cntr = 2;
1024
if (llc->npta > 0)
1025
llc->npta = llc->npta - 1;
1026
} else
1027
llc->dec_cntr -=1;
1028
}
1029
} else
1030
llc->connect_step = 0 ;
1031
return 0;
1032
}
1033
1034
/**
1035
* llc_conn_ac_adjust_npta_by_rnr - decreases "npta" by one
1036
* @sk: current connection structure.
1037
* @skb: current event.
1038
*
1039
* After receiving "dec_cntr" times RNR command, this action decreases
1040
* "npta" by one. Returns 0 for success, 1 otherwise.
1041
*/
1042
int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, struct sk_buff *skb)
1043
{
1044
struct llc_sock *llc = llc_sk(sk);
1045
1046
if (llc->remote_busy_flag)
1047
if (!llc->dec_step) {
1048
if (!llc->dec_cntr) {
1049
llc->inc_cntr = llc->dec_cntr = 2;
1050
if (llc->npta > 0)
1051
--llc->npta;
1052
} else
1053
--llc->dec_cntr;
1054
}
1055
return 0;
1056
}
1057
1058
/**
1059
* llc_conn_ac_dec_tx_win_size - decreases tx window size
1060
* @sk: current connection structure.
1061
* @skb: current event.
1062
*
1063
* After receiving of a REJ command or response, transmit window size is
1064
* decreased by number of PDUs which are outstanding yet. Returns 0 for
1065
* success, 1 otherwise.
1066
*/
1067
int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct sk_buff *skb)
1068
{
1069
struct llc_sock *llc = llc_sk(sk);
1070
u8 unacked_pdu = skb_queue_len(&llc->pdu_unack_q);
1071
1072
if (llc->k - unacked_pdu < 1)
1073
llc->k = 1;
1074
else
1075
llc->k -= unacked_pdu;
1076
return 0;
1077
}
1078
1079
/**
1080
* llc_conn_ac_inc_tx_win_size - tx window size is inc by 1
1081
* @sk: current connection structure.
1082
* @skb: current event.
1083
*
1084
* After receiving an RR response with f-bit set to one, transmit window
1085
* size is increased by one. Returns 0 for success, 1 otherwise.
1086
*/
1087
int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb)
1088
{
1089
struct llc_sock *llc = llc_sk(sk);
1090
1091
llc->k += 1;
1092
if (llc->k > (u8) ~LLC_2_SEQ_NBR_MODULO)
1093
llc->k = (u8) ~LLC_2_SEQ_NBR_MODULO;
1094
return 0;
1095
}
1096
1097
int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb)
1098
{
1099
struct llc_sock *llc = llc_sk(sk);
1100
1101
del_timer(&llc->pf_cycle_timer.timer);
1102
del_timer(&llc->ack_timer.timer);
1103
del_timer(&llc->rej_sent_timer.timer);
1104
del_timer(&llc->busy_state_timer.timer);
1105
llc->ack_must_be_send = 0;
1106
llc->ack_pf = 0;
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
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
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
del_timer(&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
del_timer(&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
del_timer(&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
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
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(unsigned long timeout_data, u8 type)
1322
{
1323
struct sock *sk = (struct sock *)timeout_data;
1324
struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
1325
1326
bh_lock_sock(sk);
1327
if (skb) {
1328
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1329
1330
skb_set_owner_r(skb, sk);
1331
ev->type = type;
1332
llc_process_tmr_ev(sk, skb);
1333
}
1334
bh_unlock_sock(sk);
1335
}
1336
1337
void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
1338
{
1339
llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_P_TMR);
1340
}
1341
1342
void llc_conn_busy_tmr_cb(unsigned long timeout_data)
1343
{
1344
llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_BUSY_TMR);
1345
}
1346
1347
void llc_conn_ack_tmr_cb(unsigned long timeout_data)
1348
{
1349
llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_ACK_TMR);
1350
}
1351
1352
void llc_conn_rej_tmr_cb(unsigned long timeout_data)
1353
{
1354
llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_REJ_TMR);
1355
}
1356
1357
int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb)
1358
{
1359
llc_sk(sk)->X = llc_sk(sk)->vS;
1360
llc_conn_ac_set_vs_nr(sk, skb);
1361
return 0;
1362
}
1363
1364
int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb)
1365
{
1366
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1367
u8 nr = PDU_SUPV_GET_Nr(pdu);
1368
1369
if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X))
1370
llc_conn_ac_set_vs_nr(sk, skb);
1371
return 0;
1372
}
1373
1374
/*
1375
* Non-standard actions; these not contained in IEEE specification; for
1376
* our own usage
1377
*/
1378
/**
1379
* llc_conn_disc - removes connection from SAP list and frees it
1380
* @sk: closed connection
1381
* @skb: occurred event
1382
*/
1383
int llc_conn_disc(struct sock *sk, struct sk_buff *skb)
1384
{
1385
/* FIXME: this thing seems to want to die */
1386
return 0;
1387
}
1388
1389
/**
1390
* llc_conn_reset - resets connection
1391
* @sk : reseting connection.
1392
* @skb: occurred event.
1393
*
1394
* Stop all timers, empty all queues and reset all flags.
1395
*/
1396
int llc_conn_reset(struct sock *sk, struct sk_buff *skb)
1397
{
1398
llc_sk_reset(sk);
1399
return 0;
1400
}
1401
1402
/**
1403
* llc_circular_between - designates that b is between a and c or not
1404
* @a: lower bound
1405
* @b: element to see if is between a and b
1406
* @c: upper bound
1407
*
1408
* This function designates that b is between a and c or not (for example,
1409
* 0 is between 127 and 1). Returns 1 if b is between a and c, 0
1410
* otherwise.
1411
*/
1412
u8 llc_circular_between(u8 a, u8 b, u8 c)
1413
{
1414
b = b - a;
1415
c = c - a;
1416
return b <= c;
1417
}
1418
1419
/**
1420
* llc_process_tmr_ev - timer backend
1421
* @sk: active connection
1422
* @skb: occurred event
1423
*
1424
* This function is called from timer callback functions. When connection
1425
* is busy (during sending a data frame) timer expiration event must be
1426
* queued. Otherwise this event can be sent to connection state machine.
1427
* Queued events will process by llc_backlog_rcv function after sending
1428
* data frame.
1429
*/
1430
static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
1431
{
1432
if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) {
1433
printk(KERN_WARNING "%s: timer called on closed connection\n",
1434
__func__);
1435
kfree_skb(skb);
1436
} else {
1437
if (!sock_owned_by_user(sk))
1438
llc_conn_state_process(sk, skb);
1439
else {
1440
llc_set_backlog_type(skb, LLC_EVENT);
1441
__sk_add_backlog(sk, skb);
1442
}
1443
}
1444
}
1445
1446