~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to net/rose/rose_route.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This program is free software; you can redistribute it and/or modify
 
3
 * it under the terms of the GNU General Public License as published by
 
4
 * the Free Software Foundation; either version 2 of the License, or
 
5
 * (at your option) any later version.
 
6
 *
 
7
 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
 
8
 * Copyright (C) Terry Dawson VK2KTJ (terry@animats.net)
 
9
 */
 
10
#include <linux/errno.h>
 
11
#include <linux/types.h>
 
12
#include <linux/socket.h>
 
13
#include <linux/in.h>
 
14
#include <linux/kernel.h>
 
15
#include <linux/timer.h>
 
16
#include <linux/string.h>
 
17
#include <linux/sockios.h>
 
18
#include <linux/net.h>
 
19
#include <linux/slab.h>
 
20
#include <net/ax25.h>
 
21
#include <linux/inet.h>
 
22
#include <linux/netdevice.h>
 
23
#include <net/arp.h>
 
24
#include <linux/if_arp.h>
 
25
#include <linux/skbuff.h>
 
26
#include <net/sock.h>
 
27
#include <net/tcp_states.h>
 
28
#include <asm/system.h>
 
29
#include <asm/uaccess.h>
 
30
#include <linux/fcntl.h>
 
31
#include <linux/termios.h>      /* For TIOCINQ/OUTQ */
 
32
#include <linux/mm.h>
 
33
#include <linux/interrupt.h>
 
34
#include <linux/notifier.h>
 
35
#include <linux/netfilter.h>
 
36
#include <linux/init.h>
 
37
#include <net/rose.h>
 
38
#include <linux/seq_file.h>
 
39
#include <linux/export.h>
 
40
 
 
41
static unsigned int rose_neigh_no = 1;
 
42
 
 
43
static struct rose_node  *rose_node_list;
 
44
static DEFINE_SPINLOCK(rose_node_list_lock);
 
45
static struct rose_neigh *rose_neigh_list;
 
46
static DEFINE_SPINLOCK(rose_neigh_list_lock);
 
47
static struct rose_route *rose_route_list;
 
48
static DEFINE_SPINLOCK(rose_route_list_lock);
 
49
 
 
50
struct rose_neigh *rose_loopback_neigh;
 
51
 
 
52
/*
 
53
 *      Add a new route to a node, and in the process add the node and the
 
54
 *      neighbour if it is new.
 
55
 */
 
56
static int __must_check rose_add_node(struct rose_route_struct *rose_route,
 
57
        struct net_device *dev)
 
58
{
 
59
        struct rose_node  *rose_node, *rose_tmpn, *rose_tmpp;
 
60
        struct rose_neigh *rose_neigh;
 
61
        int i, res = 0;
 
62
 
 
63
        spin_lock_bh(&rose_node_list_lock);
 
64
        spin_lock_bh(&rose_neigh_list_lock);
 
65
 
 
66
        rose_node = rose_node_list;
 
67
        while (rose_node != NULL) {
 
68
                if ((rose_node->mask == rose_route->mask) &&
 
69
                    (rosecmpm(&rose_route->address, &rose_node->address,
 
70
                              rose_route->mask) == 0))
 
71
                        break;
 
72
                rose_node = rose_node->next;
 
73
        }
 
74
 
 
75
        if (rose_node != NULL && rose_node->loopback) {
 
76
                res = -EINVAL;
 
77
                goto out;
 
78
        }
 
79
 
 
80
        rose_neigh = rose_neigh_list;
 
81
        while (rose_neigh != NULL) {
 
82
                if (ax25cmp(&rose_route->neighbour,
 
83
                            &rose_neigh->callsign) == 0 &&
 
84
                    rose_neigh->dev == dev)
 
85
                        break;
 
86
                rose_neigh = rose_neigh->next;
 
87
        }
 
88
 
 
89
        if (rose_neigh == NULL) {
 
90
                rose_neigh = kmalloc(sizeof(*rose_neigh), GFP_ATOMIC);
 
91
                if (rose_neigh == NULL) {
 
92
                        res = -ENOMEM;
 
93
                        goto out;
 
94
                }
 
95
 
 
96
                rose_neigh->callsign  = rose_route->neighbour;
 
97
                rose_neigh->digipeat  = NULL;
 
98
                rose_neigh->ax25      = NULL;
 
99
                rose_neigh->dev       = dev;
 
100
                rose_neigh->count     = 0;
 
101
                rose_neigh->use       = 0;
 
102
                rose_neigh->dce_mode  = 0;
 
103
                rose_neigh->loopback  = 0;
 
104
                rose_neigh->number    = rose_neigh_no++;
 
105
                rose_neigh->restarted = 0;
 
106
 
 
107
                skb_queue_head_init(&rose_neigh->queue);
 
108
 
 
109
                init_timer(&rose_neigh->ftimer);
 
110
                init_timer(&rose_neigh->t0timer);
 
111
 
 
112
                if (rose_route->ndigis != 0) {
 
113
                        rose_neigh->digipeat =
 
114
                                kmalloc(sizeof(ax25_digi), GFP_ATOMIC);
 
115
                        if (rose_neigh->digipeat == NULL) {
 
116
                                kfree(rose_neigh);
 
117
                                res = -ENOMEM;
 
118
                                goto out;
 
119
                        }
 
120
 
 
121
                        rose_neigh->digipeat->ndigi      = rose_route->ndigis;
 
122
                        rose_neigh->digipeat->lastrepeat = -1;
 
123
 
 
124
                        for (i = 0; i < rose_route->ndigis; i++) {
 
125
                                rose_neigh->digipeat->calls[i]    =
 
126
                                        rose_route->digipeaters[i];
 
127
                                rose_neigh->digipeat->repeated[i] = 0;
 
128
                        }
 
129
                }
 
130
 
 
131
                rose_neigh->next = rose_neigh_list;
 
132
                rose_neigh_list  = rose_neigh;
 
133
        }
 
134
 
 
135
        /*
 
136
         * This is a new node to be inserted into the list. Find where it needs
 
137
         * to be inserted into the list, and insert it. We want to be sure
 
138
         * to order the list in descending order of mask size to ensure that
 
139
         * later when we are searching this list the first match will be the
 
140
         * best match.
 
141
         */
 
142
        if (rose_node == NULL) {
 
143
                rose_tmpn = rose_node_list;
 
144
                rose_tmpp = NULL;
 
145
 
 
146
                while (rose_tmpn != NULL) {
 
147
                        if (rose_tmpn->mask > rose_route->mask) {
 
148
                                rose_tmpp = rose_tmpn;
 
149
                                rose_tmpn = rose_tmpn->next;
 
150
                        } else {
 
151
                                break;
 
152
                        }
 
153
                }
 
154
 
 
155
                /* create new node */
 
156
                rose_node = kmalloc(sizeof(*rose_node), GFP_ATOMIC);
 
157
                if (rose_node == NULL) {
 
158
                        res = -ENOMEM;
 
159
                        goto out;
 
160
                }
 
161
 
 
162
                rose_node->address      = rose_route->address;
 
163
                rose_node->mask         = rose_route->mask;
 
164
                rose_node->count        = 1;
 
165
                rose_node->loopback     = 0;
 
166
                rose_node->neighbour[0] = rose_neigh;
 
167
 
 
168
                if (rose_tmpn == NULL) {
 
169
                        if (rose_tmpp == NULL) {        /* Empty list */
 
170
                                rose_node_list  = rose_node;
 
171
                                rose_node->next = NULL;
 
172
                        } else {
 
173
                                rose_tmpp->next = rose_node;
 
174
                                rose_node->next = NULL;
 
175
                        }
 
176
                } else {
 
177
                        if (rose_tmpp == NULL) {        /* 1st node */
 
178
                                rose_node->next = rose_node_list;
 
179
                                rose_node_list  = rose_node;
 
180
                        } else {
 
181
                                rose_tmpp->next = rose_node;
 
182
                                rose_node->next = rose_tmpn;
 
183
                        }
 
184
                }
 
185
                rose_neigh->count++;
 
186
 
 
187
                goto out;
 
188
        }
 
189
 
 
190
        /* We have space, slot it in */
 
191
        if (rose_node->count < 3) {
 
192
                rose_node->neighbour[rose_node->count] = rose_neigh;
 
193
                rose_node->count++;
 
194
                rose_neigh->count++;
 
195
        }
 
196
 
 
197
out:
 
198
        spin_unlock_bh(&rose_neigh_list_lock);
 
199
        spin_unlock_bh(&rose_node_list_lock);
 
200
 
 
201
        return res;
 
202
}
 
203
 
 
204
/*
 
205
 * Caller is holding rose_node_list_lock.
 
206
 */
 
207
static void rose_remove_node(struct rose_node *rose_node)
 
208
{
 
209
        struct rose_node *s;
 
210
 
 
211
        if ((s = rose_node_list) == rose_node) {
 
212
                rose_node_list = rose_node->next;
 
213
                kfree(rose_node);
 
214
                return;
 
215
        }
 
216
 
 
217
        while (s != NULL && s->next != NULL) {
 
218
                if (s->next == rose_node) {
 
219
                        s->next = rose_node->next;
 
220
                        kfree(rose_node);
 
221
                        return;
 
222
                }
 
223
 
 
224
                s = s->next;
 
225
        }
 
226
}
 
227
 
 
228
/*
 
229
 * Caller is holding rose_neigh_list_lock.
 
230
 */
 
231
static void rose_remove_neigh(struct rose_neigh *rose_neigh)
 
232
{
 
233
        struct rose_neigh *s;
 
234
 
 
235
        rose_stop_ftimer(rose_neigh);
 
236
        rose_stop_t0timer(rose_neigh);
 
237
 
 
238
        skb_queue_purge(&rose_neigh->queue);
 
239
 
 
240
        if ((s = rose_neigh_list) == rose_neigh) {
 
241
                rose_neigh_list = rose_neigh->next;
 
242
                if (rose_neigh->ax25)
 
243
                        ax25_cb_put(rose_neigh->ax25);
 
244
                kfree(rose_neigh->digipeat);
 
245
                kfree(rose_neigh);
 
246
                return;
 
247
        }
 
248
 
 
249
        while (s != NULL && s->next != NULL) {
 
250
                if (s->next == rose_neigh) {
 
251
                        s->next = rose_neigh->next;
 
252
                        if (rose_neigh->ax25)
 
253
                                ax25_cb_put(rose_neigh->ax25);
 
254
                        kfree(rose_neigh->digipeat);
 
255
                        kfree(rose_neigh);
 
256
                        return;
 
257
                }
 
258
 
 
259
                s = s->next;
 
260
        }
 
261
}
 
262
 
 
263
/*
 
264
 * Caller is holding rose_route_list_lock.
 
265
 */
 
266
static void rose_remove_route(struct rose_route *rose_route)
 
267
{
 
268
        struct rose_route *s;
 
269
 
 
270
        if (rose_route->neigh1 != NULL)
 
271
                rose_route->neigh1->use--;
 
272
 
 
273
        if (rose_route->neigh2 != NULL)
 
274
                rose_route->neigh2->use--;
 
275
 
 
276
        if ((s = rose_route_list) == rose_route) {
 
277
                rose_route_list = rose_route->next;
 
278
                kfree(rose_route);
 
279
                return;
 
280
        }
 
281
 
 
282
        while (s != NULL && s->next != NULL) {
 
283
                if (s->next == rose_route) {
 
284
                        s->next = rose_route->next;
 
285
                        kfree(rose_route);
 
286
                        return;
 
287
                }
 
288
 
 
289
                s = s->next;
 
290
        }
 
291
}
 
292
 
 
293
/*
 
294
 *      "Delete" a node. Strictly speaking remove a route to a node. The node
 
295
 *      is only deleted if no routes are left to it.
 
296
 */
 
297
static int rose_del_node(struct rose_route_struct *rose_route,
 
298
        struct net_device *dev)
 
299
{
 
300
        struct rose_node  *rose_node;
 
301
        struct rose_neigh *rose_neigh;
 
302
        int i, err = 0;
 
303
 
 
304
        spin_lock_bh(&rose_node_list_lock);
 
305
        spin_lock_bh(&rose_neigh_list_lock);
 
306
 
 
307
        rose_node = rose_node_list;
 
308
        while (rose_node != NULL) {
 
309
                if ((rose_node->mask == rose_route->mask) &&
 
310
                    (rosecmpm(&rose_route->address, &rose_node->address,
 
311
                              rose_route->mask) == 0))
 
312
                        break;
 
313
                rose_node = rose_node->next;
 
314
        }
 
315
 
 
316
        if (rose_node == NULL || rose_node->loopback) {
 
317
                err = -EINVAL;
 
318
                goto out;
 
319
        }
 
320
 
 
321
        rose_neigh = rose_neigh_list;
 
322
        while (rose_neigh != NULL) {
 
323
                if (ax25cmp(&rose_route->neighbour,
 
324
                            &rose_neigh->callsign) == 0 &&
 
325
                    rose_neigh->dev == dev)
 
326
                        break;
 
327
                rose_neigh = rose_neigh->next;
 
328
        }
 
329
 
 
330
        if (rose_neigh == NULL) {
 
331
                err = -EINVAL;
 
332
                goto out;
 
333
        }
 
334
 
 
335
        for (i = 0; i < rose_node->count; i++) {
 
336
                if (rose_node->neighbour[i] == rose_neigh) {
 
337
                        rose_neigh->count--;
 
338
 
 
339
                        if (rose_neigh->count == 0 && rose_neigh->use == 0)
 
340
                                rose_remove_neigh(rose_neigh);
 
341
 
 
342
                        rose_node->count--;
 
343
 
 
344
                        if (rose_node->count == 0) {
 
345
                                rose_remove_node(rose_node);
 
346
                        } else {
 
347
                                switch (i) {
 
348
                                case 0:
 
349
                                        rose_node->neighbour[0] =
 
350
                                                rose_node->neighbour[1];
 
351
                                case 1:
 
352
                                        rose_node->neighbour[1] =
 
353
                                                rose_node->neighbour[2];
 
354
                                case 2:
 
355
                                        break;
 
356
                                }
 
357
                        }
 
358
                        goto out;
 
359
                }
 
360
        }
 
361
        err = -EINVAL;
 
362
 
 
363
out:
 
364
        spin_unlock_bh(&rose_neigh_list_lock);
 
365
        spin_unlock_bh(&rose_node_list_lock);
 
366
 
 
367
        return err;
 
368
}
 
369
 
 
370
/*
 
371
 *      Add the loopback neighbour.
 
372
 */
 
373
void rose_add_loopback_neigh(void)
 
374
{
 
375
        struct rose_neigh *sn;
 
376
 
 
377
        rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_KERNEL);
 
378
        if (!rose_loopback_neigh)
 
379
                return;
 
380
        sn = rose_loopback_neigh;
 
381
 
 
382
        sn->callsign  = null_ax25_address;
 
383
        sn->digipeat  = NULL;
 
384
        sn->ax25      = NULL;
 
385
        sn->dev       = NULL;
 
386
        sn->count     = 0;
 
387
        sn->use       = 0;
 
388
        sn->dce_mode  = 1;
 
389
        sn->loopback  = 1;
 
390
        sn->number    = rose_neigh_no++;
 
391
        sn->restarted = 1;
 
392
 
 
393
        skb_queue_head_init(&sn->queue);
 
394
 
 
395
        init_timer(&sn->ftimer);
 
396
        init_timer(&sn->t0timer);
 
397
 
 
398
        spin_lock_bh(&rose_neigh_list_lock);
 
399
        sn->next = rose_neigh_list;
 
400
        rose_neigh_list           = sn;
 
401
        spin_unlock_bh(&rose_neigh_list_lock);
 
402
}
 
403
 
 
404
/*
 
405
 *      Add a loopback node.
 
406
 */
 
407
int rose_add_loopback_node(rose_address *address)
 
408
{
 
409
        struct rose_node *rose_node;
 
410
        int err = 0;
 
411
 
 
412
        spin_lock_bh(&rose_node_list_lock);
 
413
 
 
414
        rose_node = rose_node_list;
 
415
        while (rose_node != NULL) {
 
416
                if ((rose_node->mask == 10) &&
 
417
                     (rosecmpm(address, &rose_node->address, 10) == 0) &&
 
418
                     rose_node->loopback)
 
419
                        break;
 
420
                rose_node = rose_node->next;
 
421
        }
 
422
 
 
423
        if (rose_node != NULL)
 
424
                goto out;
 
425
 
 
426
        if ((rose_node = kmalloc(sizeof(*rose_node), GFP_ATOMIC)) == NULL) {
 
427
                err = -ENOMEM;
 
428
                goto out;
 
429
        }
 
430
 
 
431
        rose_node->address      = *address;
 
432
        rose_node->mask         = 10;
 
433
        rose_node->count        = 1;
 
434
        rose_node->loopback     = 1;
 
435
        rose_node->neighbour[0] = rose_loopback_neigh;
 
436
 
 
437
        /* Insert at the head of list. Address is always mask=10 */
 
438
        rose_node->next = rose_node_list;
 
439
        rose_node_list  = rose_node;
 
440
 
 
441
        rose_loopback_neigh->count++;
 
442
 
 
443
out:
 
444
        spin_unlock_bh(&rose_node_list_lock);
 
445
 
 
446
        return err;
 
447
}
 
448
 
 
449
/*
 
450
 *      Delete a loopback node.
 
451
 */
 
452
void rose_del_loopback_node(rose_address *address)
 
453
{
 
454
        struct rose_node *rose_node;
 
455
 
 
456
        spin_lock_bh(&rose_node_list_lock);
 
457
 
 
458
        rose_node = rose_node_list;
 
459
        while (rose_node != NULL) {
 
460
                if ((rose_node->mask == 10) &&
 
461
                    (rosecmpm(address, &rose_node->address, 10) == 0) &&
 
462
                    rose_node->loopback)
 
463
                        break;
 
464
                rose_node = rose_node->next;
 
465
        }
 
466
 
 
467
        if (rose_node == NULL)
 
468
                goto out;
 
469
 
 
470
        rose_remove_node(rose_node);
 
471
 
 
472
        rose_loopback_neigh->count--;
 
473
 
 
474
out:
 
475
        spin_unlock_bh(&rose_node_list_lock);
 
476
}
 
477
 
 
478
/*
 
479
 *      A device has been removed. Remove its routes and neighbours.
 
480
 */
 
481
void rose_rt_device_down(struct net_device *dev)
 
482
{
 
483
        struct rose_neigh *s, *rose_neigh;
 
484
        struct rose_node  *t, *rose_node;
 
485
        int i;
 
486
 
 
487
        spin_lock_bh(&rose_node_list_lock);
 
488
        spin_lock_bh(&rose_neigh_list_lock);
 
489
        rose_neigh = rose_neigh_list;
 
490
        while (rose_neigh != NULL) {
 
491
                s          = rose_neigh;
 
492
                rose_neigh = rose_neigh->next;
 
493
 
 
494
                if (s->dev != dev)
 
495
                        continue;
 
496
 
 
497
                rose_node = rose_node_list;
 
498
 
 
499
                while (rose_node != NULL) {
 
500
                        t         = rose_node;
 
501
                        rose_node = rose_node->next;
 
502
 
 
503
                        for (i = 0; i < t->count; i++) {
 
504
                                if (t->neighbour[i] != s)
 
505
                                        continue;
 
506
 
 
507
                                t->count--;
 
508
 
 
509
                                switch (i) {
 
510
                                case 0:
 
511
                                        t->neighbour[0] = t->neighbour[1];
 
512
                                case 1:
 
513
                                        t->neighbour[1] = t->neighbour[2];
 
514
                                case 2:
 
515
                                        break;
 
516
                                }
 
517
                        }
 
518
 
 
519
                        if (t->count <= 0)
 
520
                                rose_remove_node(t);
 
521
                }
 
522
 
 
523
                rose_remove_neigh(s);
 
524
        }
 
525
        spin_unlock_bh(&rose_neigh_list_lock);
 
526
        spin_unlock_bh(&rose_node_list_lock);
 
527
}
 
528
 
 
529
#if 0 /* Currently unused */
 
530
/*
 
531
 *      A device has been removed. Remove its links.
 
532
 */
 
533
void rose_route_device_down(struct net_device *dev)
 
534
{
 
535
        struct rose_route *s, *rose_route;
 
536
 
 
537
        spin_lock_bh(&rose_route_list_lock);
 
538
        rose_route = rose_route_list;
 
539
        while (rose_route != NULL) {
 
540
                s          = rose_route;
 
541
                rose_route = rose_route->next;
 
542
 
 
543
                if (s->neigh1->dev == dev || s->neigh2->dev == dev)
 
544
                        rose_remove_route(s);
 
545
        }
 
546
        spin_unlock_bh(&rose_route_list_lock);
 
547
}
 
548
#endif
 
549
 
 
550
/*
 
551
 *      Clear all nodes and neighbours out, except for neighbours with
 
552
 *      active connections going through them.
 
553
 *  Do not clear loopback neighbour and nodes.
 
554
 */
 
555
static int rose_clear_routes(void)
 
556
{
 
557
        struct rose_neigh *s, *rose_neigh;
 
558
        struct rose_node  *t, *rose_node;
 
559
 
 
560
        spin_lock_bh(&rose_node_list_lock);
 
561
        spin_lock_bh(&rose_neigh_list_lock);
 
562
 
 
563
        rose_neigh = rose_neigh_list;
 
564
        rose_node  = rose_node_list;
 
565
 
 
566
        while (rose_node != NULL) {
 
567
                t         = rose_node;
 
568
                rose_node = rose_node->next;
 
569
                if (!t->loopback)
 
570
                        rose_remove_node(t);
 
571
        }
 
572
 
 
573
        while (rose_neigh != NULL) {
 
574
                s          = rose_neigh;
 
575
                rose_neigh = rose_neigh->next;
 
576
 
 
577
                if (s->use == 0 && !s->loopback) {
 
578
                        s->count = 0;
 
579
                        rose_remove_neigh(s);
 
580
                }
 
581
        }
 
582
 
 
583
        spin_unlock_bh(&rose_neigh_list_lock);
 
584
        spin_unlock_bh(&rose_node_list_lock);
 
585
 
 
586
        return 0;
 
587
}
 
588
 
 
589
/*
 
590
 *      Check that the device given is a valid AX.25 interface that is "up".
 
591
 *      called with RTNL
 
592
 */
 
593
static struct net_device *rose_ax25_dev_find(char *devname)
 
594
{
 
595
        struct net_device *dev;
 
596
 
 
597
        if ((dev = __dev_get_by_name(&init_net, devname)) == NULL)
 
598
                return NULL;
 
599
 
 
600
        if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
 
601
                return dev;
 
602
 
 
603
        return NULL;
 
604
}
 
605
 
 
606
/*
 
607
 *      Find the first active ROSE device, usually "rose0".
 
608
 */
 
609
struct net_device *rose_dev_first(void)
 
610
{
 
611
        struct net_device *dev, *first = NULL;
 
612
 
 
613
        rcu_read_lock();
 
614
        for_each_netdev_rcu(&init_net, dev) {
 
615
                if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE)
 
616
                        if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
 
617
                                first = dev;
 
618
        }
 
619
        rcu_read_unlock();
 
620
 
 
621
        return first;
 
622
}
 
623
 
 
624
/*
 
625
 *      Find the ROSE device for the given address.
 
626
 */
 
627
struct net_device *rose_dev_get(rose_address *addr)
 
628
{
 
629
        struct net_device *dev;
 
630
 
 
631
        rcu_read_lock();
 
632
        for_each_netdev_rcu(&init_net, dev) {
 
633
                if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) {
 
634
                        dev_hold(dev);
 
635
                        goto out;
 
636
                }
 
637
        }
 
638
        dev = NULL;
 
639
out:
 
640
        rcu_read_unlock();
 
641
        return dev;
 
642
}
 
643
 
 
644
static int rose_dev_exists(rose_address *addr)
 
645
{
 
646
        struct net_device *dev;
 
647
 
 
648
        rcu_read_lock();
 
649
        for_each_netdev_rcu(&init_net, dev) {
 
650
                if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0)
 
651
                        goto out;
 
652
        }
 
653
        dev = NULL;
 
654
out:
 
655
        rcu_read_unlock();
 
656
        return dev != NULL;
 
657
}
 
658
 
 
659
 
 
660
 
 
661
 
 
662
struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neigh)
 
663
{
 
664
        struct rose_route *rose_route;
 
665
 
 
666
        for (rose_route = rose_route_list; rose_route != NULL; rose_route = rose_route->next)
 
667
                if ((rose_route->neigh1 == neigh && rose_route->lci1 == lci) ||
 
668
                    (rose_route->neigh2 == neigh && rose_route->lci2 == lci))
 
669
                        return rose_route;
 
670
 
 
671
        return NULL;
 
672
}
 
673
 
 
674
/*
 
675
 *      Find a neighbour or a route given a ROSE address.
 
676
 */
 
677
struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
 
678
        unsigned char *diagnostic, int route_frame)
 
679
{
 
680
        struct rose_neigh *res = NULL;
 
681
        struct rose_node *node;
 
682
        int failed = 0;
 
683
        int i;
 
684
 
 
685
        if (!route_frame) spin_lock_bh(&rose_node_list_lock);
 
686
        for (node = rose_node_list; node != NULL; node = node->next) {
 
687
                if (rosecmpm(addr, &node->address, node->mask) == 0) {
 
688
                        for (i = 0; i < node->count; i++) {
 
689
                                if (node->neighbour[i]->restarted) {
 
690
                                        res = node->neighbour[i];
 
691
                                        goto out;
 
692
                                }
 
693
                        }
 
694
                }
 
695
        }
 
696
        if (!route_frame) { /* connect request */
 
697
                for (node = rose_node_list; node != NULL; node = node->next) {
 
698
                        if (rosecmpm(addr, &node->address, node->mask) == 0) {
 
699
                                for (i = 0; i < node->count; i++) {
 
700
                                        if (!rose_ftimer_running(node->neighbour[i])) {
 
701
                                                res = node->neighbour[i];
 
702
                                                failed = 0;
 
703
                                                goto out;
 
704
                                        }
 
705
                                        failed = 1;
 
706
                                }
 
707
                        }
 
708
                }
 
709
        }
 
710
 
 
711
        if (failed) {
 
712
                *cause      = ROSE_OUT_OF_ORDER;
 
713
                *diagnostic = 0;
 
714
        } else {
 
715
                *cause      = ROSE_NOT_OBTAINABLE;
 
716
                *diagnostic = 0;
 
717
        }
 
718
 
 
719
out:
 
720
        if (!route_frame) spin_unlock_bh(&rose_node_list_lock);
 
721
        return res;
 
722
}
 
723
 
 
724
/*
 
725
 *      Handle the ioctls that control the routing functions.
 
726
 */
 
727
int rose_rt_ioctl(unsigned int cmd, void __user *arg)
 
728
{
 
729
        struct rose_route_struct rose_route;
 
730
        struct net_device *dev;
 
731
        int err;
 
732
 
 
733
        switch (cmd) {
 
734
        case SIOCADDRT:
 
735
                if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
 
736
                        return -EFAULT;
 
737
                if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
 
738
                        return -EINVAL;
 
739
                if (rose_dev_exists(&rose_route.address)) /* Can't add routes to ourself */
 
740
                        return -EINVAL;
 
741
                if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
 
742
                        return -EINVAL;
 
743
                if (rose_route.ndigis > AX25_MAX_DIGIS)
 
744
                        return -EINVAL;
 
745
                err = rose_add_node(&rose_route, dev);
 
746
                return err;
 
747
 
 
748
        case SIOCDELRT:
 
749
                if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
 
750
                        return -EFAULT;
 
751
                if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
 
752
                        return -EINVAL;
 
753
                err = rose_del_node(&rose_route, dev);
 
754
                return err;
 
755
 
 
756
        case SIOCRSCLRRT:
 
757
                return rose_clear_routes();
 
758
 
 
759
        default:
 
760
                return -EINVAL;
 
761
        }
 
762
 
 
763
        return 0;
 
764
}
 
765
 
 
766
static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
 
767
{
 
768
        struct rose_route *rose_route, *s;
 
769
 
 
770
        rose_neigh->restarted = 0;
 
771
 
 
772
        rose_stop_t0timer(rose_neigh);
 
773
        rose_start_ftimer(rose_neigh);
 
774
 
 
775
        skb_queue_purge(&rose_neigh->queue);
 
776
 
 
777
        spin_lock_bh(&rose_route_list_lock);
 
778
 
 
779
        rose_route = rose_route_list;
 
780
 
 
781
        while (rose_route != NULL) {
 
782
                if ((rose_route->neigh1 == rose_neigh && rose_route->neigh2 == rose_neigh) ||
 
783
                    (rose_route->neigh1 == rose_neigh && rose_route->neigh2 == NULL)       ||
 
784
                    (rose_route->neigh2 == rose_neigh && rose_route->neigh1 == NULL)) {
 
785
                        s = rose_route->next;
 
786
                        rose_remove_route(rose_route);
 
787
                        rose_route = s;
 
788
                        continue;
 
789
                }
 
790
 
 
791
                if (rose_route->neigh1 == rose_neigh) {
 
792
                        rose_route->neigh1->use--;
 
793
                        rose_route->neigh1 = NULL;
 
794
                        rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
 
795
                }
 
796
 
 
797
                if (rose_route->neigh2 == rose_neigh) {
 
798
                        rose_route->neigh2->use--;
 
799
                        rose_route->neigh2 = NULL;
 
800
                        rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
 
801
                }
 
802
 
 
803
                rose_route = rose_route->next;
 
804
        }
 
805
        spin_unlock_bh(&rose_route_list_lock);
 
806
}
 
807
 
 
808
/*
 
809
 *      A level 2 link has timed out, therefore it appears to be a poor link,
 
810
 *      then don't use that neighbour until it is reset. Blow away all through
 
811
 *      routes and connections using this route.
 
812
 */
 
813
void rose_link_failed(ax25_cb *ax25, int reason)
 
814
{
 
815
        struct rose_neigh *rose_neigh;
 
816
 
 
817
        spin_lock_bh(&rose_neigh_list_lock);
 
818
        rose_neigh = rose_neigh_list;
 
819
        while (rose_neigh != NULL) {
 
820
                if (rose_neigh->ax25 == ax25)
 
821
                        break;
 
822
                rose_neigh = rose_neigh->next;
 
823
        }
 
824
 
 
825
        if (rose_neigh != NULL) {
 
826
                rose_neigh->ax25 = NULL;
 
827
                ax25_cb_put(ax25);
 
828
 
 
829
                rose_del_route_by_neigh(rose_neigh);
 
830
                rose_kill_by_neigh(rose_neigh);
 
831
        }
 
832
        spin_unlock_bh(&rose_neigh_list_lock);
 
833
}
 
834
 
 
835
/*
 
836
 *      A device has been "downed" remove its link status. Blow away all
 
837
 *      through routes and connections that use this device.
 
838
 */
 
839
void rose_link_device_down(struct net_device *dev)
 
840
{
 
841
        struct rose_neigh *rose_neigh;
 
842
 
 
843
        for (rose_neigh = rose_neigh_list; rose_neigh != NULL; rose_neigh = rose_neigh->next) {
 
844
                if (rose_neigh->dev == dev) {
 
845
                        rose_del_route_by_neigh(rose_neigh);
 
846
                        rose_kill_by_neigh(rose_neigh);
 
847
                }
 
848
        }
 
849
}
 
850
 
 
851
/*
 
852
 *      Route a frame to an appropriate AX.25 connection.
 
853
 */
 
854
int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
 
855
{
 
856
        struct rose_neigh *rose_neigh, *new_neigh;
 
857
        struct rose_route *rose_route;
 
858
        struct rose_facilities_struct facilities;
 
859
        rose_address *src_addr, *dest_addr;
 
860
        struct sock *sk;
 
861
        unsigned short frametype;
 
862
        unsigned int lci, new_lci;
 
863
        unsigned char cause, diagnostic;
 
864
        struct net_device *dev;
 
865
        int res = 0;
 
866
        char buf[11];
 
867
 
 
868
        if (skb->len < ROSE_MIN_LEN)
 
869
                return res;
 
870
        frametype = skb->data[2];
 
871
        lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
 
872
        if (frametype == ROSE_CALL_REQUEST &&
 
873
            (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF ||
 
874
             skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] !=
 
875
             ROSE_CALL_REQ_ADDR_LEN_VAL))
 
876
                return res;
 
877
        src_addr  = (rose_address *)(skb->data + ROSE_CALL_REQ_SRC_ADDR_OFF);
 
878
        dest_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF);
 
879
 
 
880
        spin_lock_bh(&rose_neigh_list_lock);
 
881
        spin_lock_bh(&rose_route_list_lock);
 
882
 
 
883
        rose_neigh = rose_neigh_list;
 
884
        while (rose_neigh != NULL) {
 
885
                if (ax25cmp(&ax25->dest_addr, &rose_neigh->callsign) == 0 &&
 
886
                    ax25->ax25_dev->dev == rose_neigh->dev)
 
887
                        break;
 
888
                rose_neigh = rose_neigh->next;
 
889
        }
 
890
 
 
891
        if (rose_neigh == NULL) {
 
892
                printk("rose_route : unknown neighbour or device %s\n",
 
893
                       ax2asc(buf, &ax25->dest_addr));
 
894
                goto out;
 
895
        }
 
896
 
 
897
        /*
 
898
         *      Obviously the link is working, halt the ftimer.
 
899
         */
 
900
        rose_stop_ftimer(rose_neigh);
 
901
 
 
902
        /*
 
903
         *      LCI of zero is always for us, and its always a restart
 
904
         *      frame.
 
905
         */
 
906
        if (lci == 0) {
 
907
                rose_link_rx_restart(skb, rose_neigh, frametype);
 
908
                goto out;
 
909
        }
 
910
 
 
911
        /*
 
912
         *      Find an existing socket.
 
913
         */
 
914
        if ((sk = rose_find_socket(lci, rose_neigh)) != NULL) {
 
915
                if (frametype == ROSE_CALL_REQUEST) {
 
916
                        struct rose_sock *rose = rose_sk(sk);
 
917
 
 
918
                        /* Remove an existing unused socket */
 
919
                        rose_clear_queues(sk);
 
920
                        rose->cause      = ROSE_NETWORK_CONGESTION;
 
921
                        rose->diagnostic = 0;
 
922
                        rose->neighbour->use--;
 
923
                        rose->neighbour  = NULL;
 
924
                        rose->lci        = 0;
 
925
                        rose->state      = ROSE_STATE_0;
 
926
                        sk->sk_state     = TCP_CLOSE;
 
927
                        sk->sk_err       = 0;
 
928
                        sk->sk_shutdown  |= SEND_SHUTDOWN;
 
929
                        if (!sock_flag(sk, SOCK_DEAD)) {
 
930
                                sk->sk_state_change(sk);
 
931
                                sock_set_flag(sk, SOCK_DEAD);
 
932
                        }
 
933
                }
 
934
                else {
 
935
                        skb_reset_transport_header(skb);
 
936
                        res = rose_process_rx_frame(sk, skb);
 
937
                        goto out;
 
938
                }
 
939
        }
 
940
 
 
941
        /*
 
942
         *      Is is a Call Request and is it for us ?
 
943
         */
 
944
        if (frametype == ROSE_CALL_REQUEST)
 
945
                if ((dev = rose_dev_get(dest_addr)) != NULL) {
 
946
                        res = rose_rx_call_request(skb, dev, rose_neigh, lci);
 
947
                        dev_put(dev);
 
948
                        goto out;
 
949
                }
 
950
 
 
951
        if (!sysctl_rose_routing_control) {
 
952
                rose_transmit_clear_request(rose_neigh, lci, ROSE_NOT_OBTAINABLE, 0);
 
953
                goto out;
 
954
        }
 
955
 
 
956
        /*
 
957
         *      Route it to the next in line if we have an entry for it.
 
958
         */
 
959
        rose_route = rose_route_list;
 
960
        while (rose_route != NULL) {
 
961
                if (rose_route->lci1 == lci &&
 
962
                    rose_route->neigh1 == rose_neigh) {
 
963
                        if (frametype == ROSE_CALL_REQUEST) {
 
964
                                /* F6FBB - Remove an existing unused route */
 
965
                                rose_remove_route(rose_route);
 
966
                                break;
 
967
                        } else if (rose_route->neigh2 != NULL) {
 
968
                                skb->data[0] &= 0xF0;
 
969
                                skb->data[0] |= (rose_route->lci2 >> 8) & 0x0F;
 
970
                                skb->data[1]  = (rose_route->lci2 >> 0) & 0xFF;
 
971
                                rose_transmit_link(skb, rose_route->neigh2);
 
972
                                if (frametype == ROSE_CLEAR_CONFIRMATION)
 
973
                                        rose_remove_route(rose_route);
 
974
                                res = 1;
 
975
                                goto out;
 
976
                        } else {
 
977
                                if (frametype == ROSE_CLEAR_CONFIRMATION)
 
978
                                        rose_remove_route(rose_route);
 
979
                                goto out;
 
980
                        }
 
981
                }
 
982
                if (rose_route->lci2 == lci &&
 
983
                    rose_route->neigh2 == rose_neigh) {
 
984
                        if (frametype == ROSE_CALL_REQUEST) {
 
985
                                /* F6FBB - Remove an existing unused route */
 
986
                                rose_remove_route(rose_route);
 
987
                                break;
 
988
                        } else if (rose_route->neigh1 != NULL) {
 
989
                                skb->data[0] &= 0xF0;
 
990
                                skb->data[0] |= (rose_route->lci1 >> 8) & 0x0F;
 
991
                                skb->data[1]  = (rose_route->lci1 >> 0) & 0xFF;
 
992
                                rose_transmit_link(skb, rose_route->neigh1);
 
993
                                if (frametype == ROSE_CLEAR_CONFIRMATION)
 
994
                                        rose_remove_route(rose_route);
 
995
                                res = 1;
 
996
                                goto out;
 
997
                        } else {
 
998
                                if (frametype == ROSE_CLEAR_CONFIRMATION)
 
999
                                        rose_remove_route(rose_route);
 
1000
                                goto out;
 
1001
                        }
 
1002
                }
 
1003
                rose_route = rose_route->next;
 
1004
        }
 
1005
 
 
1006
        /*
 
1007
         *      We know that:
 
1008
         *      1. The frame isn't for us,
 
1009
         *      2. It isn't "owned" by any existing route.
 
1010
         */
 
1011
        if (frametype != ROSE_CALL_REQUEST) {   /* XXX */
 
1012
                res = 0;
 
1013
                goto out;
 
1014
        }
 
1015
 
 
1016
        memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
 
1017
 
 
1018
        if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
 
1019
                                   skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
 
1020
                                   &facilities)) {
 
1021
                rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76);
 
1022
                goto out;
 
1023
        }
 
1024
 
 
1025
        /*
 
1026
         *      Check for routing loops.
 
1027
         */
 
1028
        rose_route = rose_route_list;
 
1029
        while (rose_route != NULL) {
 
1030
                if (rose_route->rand == facilities.rand &&
 
1031
                    rosecmp(src_addr, &rose_route->src_addr) == 0 &&
 
1032
                    ax25cmp(&facilities.dest_call, &rose_route->src_call) == 0 &&
 
1033
                    ax25cmp(&facilities.source_call, &rose_route->dest_call) == 0) {
 
1034
                        rose_transmit_clear_request(rose_neigh, lci, ROSE_NOT_OBTAINABLE, 120);
 
1035
                        goto out;
 
1036
                }
 
1037
                rose_route = rose_route->next;
 
1038
        }
 
1039
 
 
1040
        if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic, 1)) == NULL) {
 
1041
                rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic);
 
1042
                goto out;
 
1043
        }
 
1044
 
 
1045
        if ((new_lci = rose_new_lci(new_neigh)) == 0) {
 
1046
                rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
 
1047
                goto out;
 
1048
        }
 
1049
 
 
1050
        if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
 
1051
                rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
 
1052
                goto out;
 
1053
        }
 
1054
 
 
1055
        rose_route->lci1      = lci;
 
1056
        rose_route->src_addr  = *src_addr;
 
1057
        rose_route->dest_addr = *dest_addr;
 
1058
        rose_route->src_call  = facilities.dest_call;
 
1059
        rose_route->dest_call = facilities.source_call;
 
1060
        rose_route->rand      = facilities.rand;
 
1061
        rose_route->neigh1    = rose_neigh;
 
1062
        rose_route->lci2      = new_lci;
 
1063
        rose_route->neigh2    = new_neigh;
 
1064
 
 
1065
        rose_route->neigh1->use++;
 
1066
        rose_route->neigh2->use++;
 
1067
 
 
1068
        rose_route->next = rose_route_list;
 
1069
        rose_route_list  = rose_route;
 
1070
 
 
1071
        skb->data[0] &= 0xF0;
 
1072
        skb->data[0] |= (rose_route->lci2 >> 8) & 0x0F;
 
1073
        skb->data[1]  = (rose_route->lci2 >> 0) & 0xFF;
 
1074
 
 
1075
        rose_transmit_link(skb, rose_route->neigh2);
 
1076
        res = 1;
 
1077
 
 
1078
out:
 
1079
        spin_unlock_bh(&rose_route_list_lock);
 
1080
        spin_unlock_bh(&rose_neigh_list_lock);
 
1081
 
 
1082
        return res;
 
1083
}
 
1084
 
 
1085
#ifdef CONFIG_PROC_FS
 
1086
 
 
1087
static void *rose_node_start(struct seq_file *seq, loff_t *pos)
 
1088
        __acquires(rose_node_list_lock)
 
1089
{
 
1090
        struct rose_node *rose_node;
 
1091
        int i = 1;
 
1092
 
 
1093
        spin_lock_bh(&rose_node_list_lock);
 
1094
        if (*pos == 0)
 
1095
                return SEQ_START_TOKEN;
 
1096
 
 
1097
        for (rose_node = rose_node_list; rose_node && i < *pos;
 
1098
             rose_node = rose_node->next, ++i);
 
1099
 
 
1100
        return (i == *pos) ? rose_node : NULL;
 
1101
}
 
1102
 
 
1103
static void *rose_node_next(struct seq_file *seq, void *v, loff_t *pos)
 
1104
{
 
1105
        ++*pos;
 
1106
 
 
1107
        return (v == SEQ_START_TOKEN) ? rose_node_list
 
1108
                : ((struct rose_node *)v)->next;
 
1109
}
 
1110
 
 
1111
static void rose_node_stop(struct seq_file *seq, void *v)
 
1112
        __releases(rose_node_list_lock)
 
1113
{
 
1114
        spin_unlock_bh(&rose_node_list_lock);
 
1115
}
 
1116
 
 
1117
static int rose_node_show(struct seq_file *seq, void *v)
 
1118
{
 
1119
        char rsbuf[11];
 
1120
        int i;
 
1121
 
 
1122
        if (v == SEQ_START_TOKEN)
 
1123
                seq_puts(seq, "address    mask n neigh neigh neigh\n");
 
1124
        else {
 
1125
                const struct rose_node *rose_node = v;
 
1126
                /* if (rose_node->loopback) {
 
1127
                        seq_printf(seq, "%-10s %04d 1 loopback\n",
 
1128
                                   rose2asc(rsbuf, &rose_node->address),
 
1129
                                   rose_node->mask);
 
1130
                } else { */
 
1131
                        seq_printf(seq, "%-10s %04d %d",
 
1132
                                   rose2asc(rsbuf, &rose_node->address),
 
1133
                                   rose_node->mask,
 
1134
                                   rose_node->count);
 
1135
 
 
1136
                        for (i = 0; i < rose_node->count; i++)
 
1137
                                seq_printf(seq, " %05d",
 
1138
                                        rose_node->neighbour[i]->number);
 
1139
 
 
1140
                        seq_puts(seq, "\n");
 
1141
                /* } */
 
1142
        }
 
1143
        return 0;
 
1144
}
 
1145
 
 
1146
static const struct seq_operations rose_node_seqops = {
 
1147
        .start = rose_node_start,
 
1148
        .next = rose_node_next,
 
1149
        .stop = rose_node_stop,
 
1150
        .show = rose_node_show,
 
1151
};
 
1152
 
 
1153
static int rose_nodes_open(struct inode *inode, struct file *file)
 
1154
{
 
1155
        return seq_open(file, &rose_node_seqops);
 
1156
}
 
1157
 
 
1158
const struct file_operations rose_nodes_fops = {
 
1159
        .owner = THIS_MODULE,
 
1160
        .open = rose_nodes_open,
 
1161
        .read = seq_read,
 
1162
        .llseek = seq_lseek,
 
1163
        .release = seq_release,
 
1164
};
 
1165
 
 
1166
static void *rose_neigh_start(struct seq_file *seq, loff_t *pos)
 
1167
        __acquires(rose_neigh_list_lock)
 
1168
{
 
1169
        struct rose_neigh *rose_neigh;
 
1170
        int i = 1;
 
1171
 
 
1172
        spin_lock_bh(&rose_neigh_list_lock);
 
1173
        if (*pos == 0)
 
1174
                return SEQ_START_TOKEN;
 
1175
 
 
1176
        for (rose_neigh = rose_neigh_list; rose_neigh && i < *pos;
 
1177
             rose_neigh = rose_neigh->next, ++i);
 
1178
 
 
1179
        return (i == *pos) ? rose_neigh : NULL;
 
1180
}
 
1181
 
 
1182
static void *rose_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
 
1183
{
 
1184
        ++*pos;
 
1185
 
 
1186
        return (v == SEQ_START_TOKEN) ? rose_neigh_list
 
1187
                : ((struct rose_neigh *)v)->next;
 
1188
}
 
1189
 
 
1190
static void rose_neigh_stop(struct seq_file *seq, void *v)
 
1191
        __releases(rose_neigh_list_lock)
 
1192
{
 
1193
        spin_unlock_bh(&rose_neigh_list_lock);
 
1194
}
 
1195
 
 
1196
static int rose_neigh_show(struct seq_file *seq, void *v)
 
1197
{
 
1198
        char buf[11];
 
1199
        int i;
 
1200
 
 
1201
        if (v == SEQ_START_TOKEN)
 
1202
                seq_puts(seq,
 
1203
                         "addr  callsign  dev  count use mode restart  t0  tf digipeaters\n");
 
1204
        else {
 
1205
                struct rose_neigh *rose_neigh = v;
 
1206
 
 
1207
                /* if (!rose_neigh->loopback) { */
 
1208
                seq_printf(seq, "%05d %-9s %-4s   %3d %3d  %3s     %3s %3lu %3lu",
 
1209
                           rose_neigh->number,
 
1210
                           (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
 
1211
                           rose_neigh->dev ? rose_neigh->dev->name : "???",
 
1212
                           rose_neigh->count,
 
1213
                           rose_neigh->use,
 
1214
                           (rose_neigh->dce_mode) ? "DCE" : "DTE",
 
1215
                           (rose_neigh->restarted) ? "yes" : "no",
 
1216
                           ax25_display_timer(&rose_neigh->t0timer) / HZ,
 
1217
                           ax25_display_timer(&rose_neigh->ftimer)  / HZ);
 
1218
 
 
1219
                if (rose_neigh->digipeat != NULL) {
 
1220
                        for (i = 0; i < rose_neigh->digipeat->ndigi; i++)
 
1221
                                seq_printf(seq, " %s", ax2asc(buf, &rose_neigh->digipeat->calls[i]));
 
1222
                }
 
1223
 
 
1224
                seq_puts(seq, "\n");
 
1225
        }
 
1226
        return 0;
 
1227
}
 
1228
 
 
1229
 
 
1230
static const struct seq_operations rose_neigh_seqops = {
 
1231
        .start = rose_neigh_start,
 
1232
        .next = rose_neigh_next,
 
1233
        .stop = rose_neigh_stop,
 
1234
        .show = rose_neigh_show,
 
1235
};
 
1236
 
 
1237
static int rose_neigh_open(struct inode *inode, struct file *file)
 
1238
{
 
1239
        return seq_open(file, &rose_neigh_seqops);
 
1240
}
 
1241
 
 
1242
const struct file_operations rose_neigh_fops = {
 
1243
        .owner = THIS_MODULE,
 
1244
        .open = rose_neigh_open,
 
1245
        .read = seq_read,
 
1246
        .llseek = seq_lseek,
 
1247
        .release = seq_release,
 
1248
};
 
1249
 
 
1250
 
 
1251
static void *rose_route_start(struct seq_file *seq, loff_t *pos)
 
1252
        __acquires(rose_route_list_lock)
 
1253
{
 
1254
        struct rose_route *rose_route;
 
1255
        int i = 1;
 
1256
 
 
1257
        spin_lock_bh(&rose_route_list_lock);
 
1258
        if (*pos == 0)
 
1259
                return SEQ_START_TOKEN;
 
1260
 
 
1261
        for (rose_route = rose_route_list; rose_route && i < *pos;
 
1262
             rose_route = rose_route->next, ++i);
 
1263
 
 
1264
        return (i == *pos) ? rose_route : NULL;
 
1265
}
 
1266
 
 
1267
static void *rose_route_next(struct seq_file *seq, void *v, loff_t *pos)
 
1268
{
 
1269
        ++*pos;
 
1270
 
 
1271
        return (v == SEQ_START_TOKEN) ? rose_route_list
 
1272
                : ((struct rose_route *)v)->next;
 
1273
}
 
1274
 
 
1275
static void rose_route_stop(struct seq_file *seq, void *v)
 
1276
        __releases(rose_route_list_lock)
 
1277
{
 
1278
        spin_unlock_bh(&rose_route_list_lock);
 
1279
}
 
1280
 
 
1281
static int rose_route_show(struct seq_file *seq, void *v)
 
1282
{
 
1283
        char buf[11], rsbuf[11];
 
1284
 
 
1285
        if (v == SEQ_START_TOKEN)
 
1286
                seq_puts(seq,
 
1287
                         "lci  address     callsign   neigh  <-> lci  address     callsign   neigh\n");
 
1288
        else {
 
1289
                struct rose_route *rose_route = v;
 
1290
 
 
1291
                if (rose_route->neigh1)
 
1292
                        seq_printf(seq,
 
1293
                                   "%3.3X  %-10s  %-9s  %05d      ",
 
1294
                                   rose_route->lci1,
 
1295
                                   rose2asc(rsbuf, &rose_route->src_addr),
 
1296
                                   ax2asc(buf, &rose_route->src_call),
 
1297
                                   rose_route->neigh1->number);
 
1298
                else
 
1299
                        seq_puts(seq,
 
1300
                                 "000  *           *          00000      ");
 
1301
 
 
1302
                if (rose_route->neigh2)
 
1303
                        seq_printf(seq,
 
1304
                                   "%3.3X  %-10s  %-9s  %05d\n",
 
1305
                                   rose_route->lci2,
 
1306
                                   rose2asc(rsbuf, &rose_route->dest_addr),
 
1307
                                   ax2asc(buf, &rose_route->dest_call),
 
1308
                                   rose_route->neigh2->number);
 
1309
                 else
 
1310
                         seq_puts(seq,
 
1311
                                  "000  *           *          00000\n");
 
1312
                }
 
1313
        return 0;
 
1314
}
 
1315
 
 
1316
static const struct seq_operations rose_route_seqops = {
 
1317
        .start = rose_route_start,
 
1318
        .next = rose_route_next,
 
1319
        .stop = rose_route_stop,
 
1320
        .show = rose_route_show,
 
1321
};
 
1322
 
 
1323
static int rose_route_open(struct inode *inode, struct file *file)
 
1324
{
 
1325
        return seq_open(file, &rose_route_seqops);
 
1326
}
 
1327
 
 
1328
const struct file_operations rose_routes_fops = {
 
1329
        .owner = THIS_MODULE,
 
1330
        .open = rose_route_open,
 
1331
        .read = seq_read,
 
1332
        .llseek = seq_lseek,
 
1333
        .release = seq_release,
 
1334
};
 
1335
 
 
1336
#endif /* CONFIG_PROC_FS */
 
1337
 
 
1338
/*
 
1339
 *      Release all memory associated with ROSE routing structures.
 
1340
 */
 
1341
void __exit rose_rt_free(void)
 
1342
{
 
1343
        struct rose_neigh *s, *rose_neigh = rose_neigh_list;
 
1344
        struct rose_node  *t, *rose_node  = rose_node_list;
 
1345
        struct rose_route *u, *rose_route = rose_route_list;
 
1346
 
 
1347
        while (rose_neigh != NULL) {
 
1348
                s          = rose_neigh;
 
1349
                rose_neigh = rose_neigh->next;
 
1350
 
 
1351
                rose_remove_neigh(s);
 
1352
        }
 
1353
 
 
1354
        while (rose_node != NULL) {
 
1355
                t         = rose_node;
 
1356
                rose_node = rose_node->next;
 
1357
 
 
1358
                rose_remove_node(t);
 
1359
        }
 
1360
 
 
1361
        while (rose_route != NULL) {
 
1362
                u          = rose_route;
 
1363
                rose_route = rose_route->next;
 
1364
 
 
1365
                rose_remove_route(u);
 
1366
        }
 
1367
}