Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/netrom/nr_route.c
15109 views
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 Jonathan Naylor G4KLX ([email protected])
8
* Copyright Alan Cox GW4PTS ([email protected])
9
* Copyright Tomi Manninen OH2BNS ([email protected])
10
*/
11
#include <linux/errno.h>
12
#include <linux/types.h>
13
#include <linux/socket.h>
14
#include <linux/in.h>
15
#include <linux/kernel.h>
16
#include <linux/timer.h>
17
#include <linux/string.h>
18
#include <linux/sockios.h>
19
#include <linux/net.h>
20
#include <linux/slab.h>
21
#include <net/ax25.h>
22
#include <linux/inet.h>
23
#include <linux/netdevice.h>
24
#include <net/arp.h>
25
#include <linux/if_arp.h>
26
#include <linux/skbuff.h>
27
#include <net/sock.h>
28
#include <asm/uaccess.h>
29
#include <asm/system.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 <linux/spinlock.h>
38
#include <net/netrom.h>
39
#include <linux/seq_file.h>
40
41
static unsigned int nr_neigh_no = 1;
42
43
static HLIST_HEAD(nr_node_list);
44
static DEFINE_SPINLOCK(nr_node_list_lock);
45
static HLIST_HEAD(nr_neigh_list);
46
static DEFINE_SPINLOCK(nr_neigh_list_lock);
47
48
static struct nr_node *nr_node_get(ax25_address *callsign)
49
{
50
struct nr_node *found = NULL;
51
struct nr_node *nr_node;
52
struct hlist_node *node;
53
54
spin_lock_bh(&nr_node_list_lock);
55
nr_node_for_each(nr_node, node, &nr_node_list)
56
if (ax25cmp(callsign, &nr_node->callsign) == 0) {
57
nr_node_hold(nr_node);
58
found = nr_node;
59
break;
60
}
61
spin_unlock_bh(&nr_node_list_lock);
62
return found;
63
}
64
65
static struct nr_neigh *nr_neigh_get_dev(ax25_address *callsign,
66
struct net_device *dev)
67
{
68
struct nr_neigh *found = NULL;
69
struct nr_neigh *nr_neigh;
70
struct hlist_node *node;
71
72
spin_lock_bh(&nr_neigh_list_lock);
73
nr_neigh_for_each(nr_neigh, node, &nr_neigh_list)
74
if (ax25cmp(callsign, &nr_neigh->callsign) == 0 &&
75
nr_neigh->dev == dev) {
76
nr_neigh_hold(nr_neigh);
77
found = nr_neigh;
78
break;
79
}
80
spin_unlock_bh(&nr_neigh_list_lock);
81
return found;
82
}
83
84
static void nr_remove_neigh(struct nr_neigh *);
85
86
/*
87
* Add a new route to a node, and in the process add the node and the
88
* neighbour if it is new.
89
*/
90
static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
91
ax25_address *ax25, ax25_digi *ax25_digi, struct net_device *dev,
92
int quality, int obs_count)
93
{
94
struct nr_node *nr_node;
95
struct nr_neigh *nr_neigh;
96
struct nr_route nr_route;
97
int i, found;
98
struct net_device *odev;
99
100
if ((odev=nr_dev_get(nr)) != NULL) { /* Can't add routes to ourself */
101
dev_put(odev);
102
return -EINVAL;
103
}
104
105
nr_node = nr_node_get(nr);
106
107
nr_neigh = nr_neigh_get_dev(ax25, dev);
108
109
/*
110
* The L2 link to a neighbour has failed in the past
111
* and now a frame comes from this neighbour. We assume
112
* it was a temporary trouble with the link and reset the
113
* routes now (and not wait for a node broadcast).
114
*/
115
if (nr_neigh != NULL && nr_neigh->failed != 0 && quality == 0) {
116
struct nr_node *nr_nodet;
117
struct hlist_node *node;
118
119
spin_lock_bh(&nr_node_list_lock);
120
nr_node_for_each(nr_nodet, node, &nr_node_list) {
121
nr_node_lock(nr_nodet);
122
for (i = 0; i < nr_nodet->count; i++)
123
if (nr_nodet->routes[i].neighbour == nr_neigh)
124
if (i < nr_nodet->which)
125
nr_nodet->which = i;
126
nr_node_unlock(nr_nodet);
127
}
128
spin_unlock_bh(&nr_node_list_lock);
129
}
130
131
if (nr_neigh != NULL)
132
nr_neigh->failed = 0;
133
134
if (quality == 0 && nr_neigh != NULL && nr_node != NULL) {
135
nr_neigh_put(nr_neigh);
136
nr_node_put(nr_node);
137
return 0;
138
}
139
140
if (nr_neigh == NULL) {
141
if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL) {
142
if (nr_node)
143
nr_node_put(nr_node);
144
return -ENOMEM;
145
}
146
147
nr_neigh->callsign = *ax25;
148
nr_neigh->digipeat = NULL;
149
nr_neigh->ax25 = NULL;
150
nr_neigh->dev = dev;
151
nr_neigh->quality = sysctl_netrom_default_path_quality;
152
nr_neigh->locked = 0;
153
nr_neigh->count = 0;
154
nr_neigh->number = nr_neigh_no++;
155
nr_neigh->failed = 0;
156
atomic_set(&nr_neigh->refcount, 1);
157
158
if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
159
nr_neigh->digipeat = kmemdup(ax25_digi,
160
sizeof(*ax25_digi),
161
GFP_KERNEL);
162
if (nr_neigh->digipeat == NULL) {
163
kfree(nr_neigh);
164
if (nr_node)
165
nr_node_put(nr_node);
166
return -ENOMEM;
167
}
168
}
169
170
spin_lock_bh(&nr_neigh_list_lock);
171
hlist_add_head(&nr_neigh->neigh_node, &nr_neigh_list);
172
nr_neigh_hold(nr_neigh);
173
spin_unlock_bh(&nr_neigh_list_lock);
174
}
175
176
if (quality != 0 && ax25cmp(nr, ax25) == 0 && !nr_neigh->locked)
177
nr_neigh->quality = quality;
178
179
if (nr_node == NULL) {
180
if ((nr_node = kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL) {
181
if (nr_neigh)
182
nr_neigh_put(nr_neigh);
183
return -ENOMEM;
184
}
185
186
nr_node->callsign = *nr;
187
strcpy(nr_node->mnemonic, mnemonic);
188
189
nr_node->which = 0;
190
nr_node->count = 1;
191
atomic_set(&nr_node->refcount, 1);
192
spin_lock_init(&nr_node->node_lock);
193
194
nr_node->routes[0].quality = quality;
195
nr_node->routes[0].obs_count = obs_count;
196
nr_node->routes[0].neighbour = nr_neigh;
197
198
nr_neigh_hold(nr_neigh);
199
nr_neigh->count++;
200
201
spin_lock_bh(&nr_node_list_lock);
202
hlist_add_head(&nr_node->node_node, &nr_node_list);
203
/* refcount initialized at 1 */
204
spin_unlock_bh(&nr_node_list_lock);
205
206
return 0;
207
}
208
nr_node_lock(nr_node);
209
210
if (quality != 0)
211
strcpy(nr_node->mnemonic, mnemonic);
212
213
for (found = 0, i = 0; i < nr_node->count; i++) {
214
if (nr_node->routes[i].neighbour == nr_neigh) {
215
nr_node->routes[i].quality = quality;
216
nr_node->routes[i].obs_count = obs_count;
217
found = 1;
218
break;
219
}
220
}
221
222
if (!found) {
223
/* We have space at the bottom, slot it in */
224
if (nr_node->count < 3) {
225
nr_node->routes[2] = nr_node->routes[1];
226
nr_node->routes[1] = nr_node->routes[0];
227
228
nr_node->routes[0].quality = quality;
229
nr_node->routes[0].obs_count = obs_count;
230
nr_node->routes[0].neighbour = nr_neigh;
231
232
nr_node->which++;
233
nr_node->count++;
234
nr_neigh_hold(nr_neigh);
235
nr_neigh->count++;
236
} else {
237
/* It must be better than the worst */
238
if (quality > nr_node->routes[2].quality) {
239
nr_node->routes[2].neighbour->count--;
240
nr_neigh_put(nr_node->routes[2].neighbour);
241
242
if (nr_node->routes[2].neighbour->count == 0 && !nr_node->routes[2].neighbour->locked)
243
nr_remove_neigh(nr_node->routes[2].neighbour);
244
245
nr_node->routes[2].quality = quality;
246
nr_node->routes[2].obs_count = obs_count;
247
nr_node->routes[2].neighbour = nr_neigh;
248
249
nr_neigh_hold(nr_neigh);
250
nr_neigh->count++;
251
}
252
}
253
}
254
255
/* Now re-sort the routes in quality order */
256
switch (nr_node->count) {
257
case 3:
258
if (nr_node->routes[1].quality > nr_node->routes[0].quality) {
259
switch (nr_node->which) {
260
case 0: nr_node->which = 1; break;
261
case 1: nr_node->which = 0; break;
262
default: break;
263
}
264
nr_route = nr_node->routes[0];
265
nr_node->routes[0] = nr_node->routes[1];
266
nr_node->routes[1] = nr_route;
267
}
268
if (nr_node->routes[2].quality > nr_node->routes[1].quality) {
269
switch (nr_node->which) {
270
case 1: nr_node->which = 2;
271
break;
272
273
case 2: nr_node->which = 1;
274
break;
275
276
default:
277
break;
278
}
279
nr_route = nr_node->routes[1];
280
nr_node->routes[1] = nr_node->routes[2];
281
nr_node->routes[2] = nr_route;
282
}
283
case 2:
284
if (nr_node->routes[1].quality > nr_node->routes[0].quality) {
285
switch (nr_node->which) {
286
case 0: nr_node->which = 1;
287
break;
288
289
case 1: nr_node->which = 0;
290
break;
291
292
default: break;
293
}
294
nr_route = nr_node->routes[0];
295
nr_node->routes[0] = nr_node->routes[1];
296
nr_node->routes[1] = nr_route;
297
}
298
case 1:
299
break;
300
}
301
302
for (i = 0; i < nr_node->count; i++) {
303
if (nr_node->routes[i].neighbour == nr_neigh) {
304
if (i < nr_node->which)
305
nr_node->which = i;
306
break;
307
}
308
}
309
310
nr_neigh_put(nr_neigh);
311
nr_node_unlock(nr_node);
312
nr_node_put(nr_node);
313
return 0;
314
}
315
316
static inline void __nr_remove_node(struct nr_node *nr_node)
317
{
318
hlist_del_init(&nr_node->node_node);
319
nr_node_put(nr_node);
320
}
321
322
#define nr_remove_node_locked(__node) \
323
__nr_remove_node(__node)
324
325
static void nr_remove_node(struct nr_node *nr_node)
326
{
327
spin_lock_bh(&nr_node_list_lock);
328
__nr_remove_node(nr_node);
329
spin_unlock_bh(&nr_node_list_lock);
330
}
331
332
static inline void __nr_remove_neigh(struct nr_neigh *nr_neigh)
333
{
334
hlist_del_init(&nr_neigh->neigh_node);
335
nr_neigh_put(nr_neigh);
336
}
337
338
#define nr_remove_neigh_locked(__neigh) \
339
__nr_remove_neigh(__neigh)
340
341
static void nr_remove_neigh(struct nr_neigh *nr_neigh)
342
{
343
spin_lock_bh(&nr_neigh_list_lock);
344
__nr_remove_neigh(nr_neigh);
345
spin_unlock_bh(&nr_neigh_list_lock);
346
}
347
348
/*
349
* "Delete" a node. Strictly speaking remove a route to a node. The node
350
* is only deleted if no routes are left to it.
351
*/
352
static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct net_device *dev)
353
{
354
struct nr_node *nr_node;
355
struct nr_neigh *nr_neigh;
356
int i;
357
358
nr_node = nr_node_get(callsign);
359
360
if (nr_node == NULL)
361
return -EINVAL;
362
363
nr_neigh = nr_neigh_get_dev(neighbour, dev);
364
365
if (nr_neigh == NULL) {
366
nr_node_put(nr_node);
367
return -EINVAL;
368
}
369
370
nr_node_lock(nr_node);
371
for (i = 0; i < nr_node->count; i++) {
372
if (nr_node->routes[i].neighbour == nr_neigh) {
373
nr_neigh->count--;
374
nr_neigh_put(nr_neigh);
375
376
if (nr_neigh->count == 0 && !nr_neigh->locked)
377
nr_remove_neigh(nr_neigh);
378
nr_neigh_put(nr_neigh);
379
380
nr_node->count--;
381
382
if (nr_node->count == 0) {
383
nr_remove_node(nr_node);
384
} else {
385
switch (i) {
386
case 0:
387
nr_node->routes[0] = nr_node->routes[1];
388
case 1:
389
nr_node->routes[1] = nr_node->routes[2];
390
case 2:
391
break;
392
}
393
nr_node_put(nr_node);
394
}
395
nr_node_unlock(nr_node);
396
397
return 0;
398
}
399
}
400
nr_neigh_put(nr_neigh);
401
nr_node_unlock(nr_node);
402
nr_node_put(nr_node);
403
404
return -EINVAL;
405
}
406
407
/*
408
* Lock a neighbour with a quality.
409
*/
410
static int __must_check nr_add_neigh(ax25_address *callsign,
411
ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
412
{
413
struct nr_neigh *nr_neigh;
414
415
nr_neigh = nr_neigh_get_dev(callsign, dev);
416
if (nr_neigh) {
417
nr_neigh->quality = quality;
418
nr_neigh->locked = 1;
419
nr_neigh_put(nr_neigh);
420
return 0;
421
}
422
423
if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL)
424
return -ENOMEM;
425
426
nr_neigh->callsign = *callsign;
427
nr_neigh->digipeat = NULL;
428
nr_neigh->ax25 = NULL;
429
nr_neigh->dev = dev;
430
nr_neigh->quality = quality;
431
nr_neigh->locked = 1;
432
nr_neigh->count = 0;
433
nr_neigh->number = nr_neigh_no++;
434
nr_neigh->failed = 0;
435
atomic_set(&nr_neigh->refcount, 1);
436
437
if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
438
nr_neigh->digipeat = kmemdup(ax25_digi, sizeof(*ax25_digi),
439
GFP_KERNEL);
440
if (nr_neigh->digipeat == NULL) {
441
kfree(nr_neigh);
442
return -ENOMEM;
443
}
444
}
445
446
spin_lock_bh(&nr_neigh_list_lock);
447
hlist_add_head(&nr_neigh->neigh_node, &nr_neigh_list);
448
/* refcount is initialized at 1 */
449
spin_unlock_bh(&nr_neigh_list_lock);
450
451
return 0;
452
}
453
454
/*
455
* "Delete" a neighbour. The neighbour is only removed if the number
456
* of nodes that may use it is zero.
457
*/
458
static int nr_del_neigh(ax25_address *callsign, struct net_device *dev, unsigned int quality)
459
{
460
struct nr_neigh *nr_neigh;
461
462
nr_neigh = nr_neigh_get_dev(callsign, dev);
463
464
if (nr_neigh == NULL) return -EINVAL;
465
466
nr_neigh->quality = quality;
467
nr_neigh->locked = 0;
468
469
if (nr_neigh->count == 0)
470
nr_remove_neigh(nr_neigh);
471
nr_neigh_put(nr_neigh);
472
473
return 0;
474
}
475
476
/*
477
* Decrement the obsolescence count by one. If a route is reduced to a
478
* count of zero, remove it. Also remove any unlocked neighbours with
479
* zero nodes routing via it.
480
*/
481
static int nr_dec_obs(void)
482
{
483
struct nr_neigh *nr_neigh;
484
struct nr_node *s;
485
struct hlist_node *node, *nodet;
486
int i;
487
488
spin_lock_bh(&nr_node_list_lock);
489
nr_node_for_each_safe(s, node, nodet, &nr_node_list) {
490
nr_node_lock(s);
491
for (i = 0; i < s->count; i++) {
492
switch (s->routes[i].obs_count) {
493
case 0: /* A locked entry */
494
break;
495
496
case 1: /* From 1 -> 0 */
497
nr_neigh = s->routes[i].neighbour;
498
499
nr_neigh->count--;
500
nr_neigh_put(nr_neigh);
501
502
if (nr_neigh->count == 0 && !nr_neigh->locked)
503
nr_remove_neigh(nr_neigh);
504
505
s->count--;
506
507
switch (i) {
508
case 0:
509
s->routes[0] = s->routes[1];
510
case 1:
511
s->routes[1] = s->routes[2];
512
case 2:
513
break;
514
}
515
break;
516
517
default:
518
s->routes[i].obs_count--;
519
break;
520
521
}
522
}
523
524
if (s->count <= 0)
525
nr_remove_node_locked(s);
526
nr_node_unlock(s);
527
}
528
spin_unlock_bh(&nr_node_list_lock);
529
530
return 0;
531
}
532
533
/*
534
* A device has been removed. Remove its routes and neighbours.
535
*/
536
void nr_rt_device_down(struct net_device *dev)
537
{
538
struct nr_neigh *s;
539
struct hlist_node *node, *nodet, *node2, *node2t;
540
struct nr_node *t;
541
int i;
542
543
spin_lock_bh(&nr_neigh_list_lock);
544
nr_neigh_for_each_safe(s, node, nodet, &nr_neigh_list) {
545
if (s->dev == dev) {
546
spin_lock_bh(&nr_node_list_lock);
547
nr_node_for_each_safe(t, node2, node2t, &nr_node_list) {
548
nr_node_lock(t);
549
for (i = 0; i < t->count; i++) {
550
if (t->routes[i].neighbour == s) {
551
t->count--;
552
553
switch (i) {
554
case 0:
555
t->routes[0] = t->routes[1];
556
case 1:
557
t->routes[1] = t->routes[2];
558
case 2:
559
break;
560
}
561
}
562
}
563
564
if (t->count <= 0)
565
nr_remove_node_locked(t);
566
nr_node_unlock(t);
567
}
568
spin_unlock_bh(&nr_node_list_lock);
569
570
nr_remove_neigh_locked(s);
571
}
572
}
573
spin_unlock_bh(&nr_neigh_list_lock);
574
}
575
576
/*
577
* Check that the device given is a valid AX.25 interface that is "up".
578
* Or a valid ethernet interface with an AX.25 callsign binding.
579
*/
580
static struct net_device *nr_ax25_dev_get(char *devname)
581
{
582
struct net_device *dev;
583
584
if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
585
return NULL;
586
587
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
588
return dev;
589
590
dev_put(dev);
591
return NULL;
592
}
593
594
/*
595
* Find the first active NET/ROM device, usually "nr0".
596
*/
597
struct net_device *nr_dev_first(void)
598
{
599
struct net_device *dev, *first = NULL;
600
601
rcu_read_lock();
602
for_each_netdev_rcu(&init_net, dev) {
603
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM)
604
if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
605
first = dev;
606
}
607
if (first)
608
dev_hold(first);
609
rcu_read_unlock();
610
611
return first;
612
}
613
614
/*
615
* Find the NET/ROM device for the given callsign.
616
*/
617
struct net_device *nr_dev_get(ax25_address *addr)
618
{
619
struct net_device *dev;
620
621
rcu_read_lock();
622
for_each_netdev_rcu(&init_net, dev) {
623
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM &&
624
ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) {
625
dev_hold(dev);
626
goto out;
627
}
628
}
629
dev = NULL;
630
out:
631
rcu_read_unlock();
632
return dev;
633
}
634
635
static ax25_digi *nr_call_to_digi(ax25_digi *digi, int ndigis,
636
ax25_address *digipeaters)
637
{
638
int i;
639
640
if (ndigis == 0)
641
return NULL;
642
643
for (i = 0; i < ndigis; i++) {
644
digi->calls[i] = digipeaters[i];
645
digi->repeated[i] = 0;
646
}
647
648
digi->ndigi = ndigis;
649
digi->lastrepeat = -1;
650
651
return digi;
652
}
653
654
/*
655
* Handle the ioctls that control the routing functions.
656
*/
657
int nr_rt_ioctl(unsigned int cmd, void __user *arg)
658
{
659
struct nr_route_struct nr_route;
660
struct net_device *dev;
661
ax25_digi digi;
662
int ret;
663
664
switch (cmd) {
665
case SIOCADDRT:
666
if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
667
return -EFAULT;
668
if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
669
return -EINVAL;
670
if (nr_route.ndigis < 0 || nr_route.ndigis > AX25_MAX_DIGIS) {
671
dev_put(dev);
672
return -EINVAL;
673
}
674
switch (nr_route.type) {
675
case NETROM_NODE:
676
ret = nr_add_node(&nr_route.callsign,
677
nr_route.mnemonic,
678
&nr_route.neighbour,
679
nr_call_to_digi(&digi, nr_route.ndigis,
680
nr_route.digipeaters),
681
dev, nr_route.quality,
682
nr_route.obs_count);
683
break;
684
case NETROM_NEIGH:
685
ret = nr_add_neigh(&nr_route.callsign,
686
nr_call_to_digi(&digi, nr_route.ndigis,
687
nr_route.digipeaters),
688
dev, nr_route.quality);
689
break;
690
default:
691
ret = -EINVAL;
692
}
693
dev_put(dev);
694
return ret;
695
696
case SIOCDELRT:
697
if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
698
return -EFAULT;
699
if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
700
return -EINVAL;
701
switch (nr_route.type) {
702
case NETROM_NODE:
703
ret = nr_del_node(&nr_route.callsign,
704
&nr_route.neighbour, dev);
705
break;
706
case NETROM_NEIGH:
707
ret = nr_del_neigh(&nr_route.callsign,
708
dev, nr_route.quality);
709
break;
710
default:
711
ret = -EINVAL;
712
}
713
dev_put(dev);
714
return ret;
715
716
case SIOCNRDECOBS:
717
return nr_dec_obs();
718
719
default:
720
return -EINVAL;
721
}
722
723
return 0;
724
}
725
726
/*
727
* A level 2 link has timed out, therefore it appears to be a poor link,
728
* then don't use that neighbour until it is reset.
729
*/
730
void nr_link_failed(ax25_cb *ax25, int reason)
731
{
732
struct nr_neigh *s, *nr_neigh = NULL;
733
struct hlist_node *node;
734
struct nr_node *nr_node = NULL;
735
736
spin_lock_bh(&nr_neigh_list_lock);
737
nr_neigh_for_each(s, node, &nr_neigh_list) {
738
if (s->ax25 == ax25) {
739
nr_neigh_hold(s);
740
nr_neigh = s;
741
break;
742
}
743
}
744
spin_unlock_bh(&nr_neigh_list_lock);
745
746
if (nr_neigh == NULL)
747
return;
748
749
nr_neigh->ax25 = NULL;
750
ax25_cb_put(ax25);
751
752
if (++nr_neigh->failed < sysctl_netrom_link_fails_count) {
753
nr_neigh_put(nr_neigh);
754
return;
755
}
756
spin_lock_bh(&nr_node_list_lock);
757
nr_node_for_each(nr_node, node, &nr_node_list) {
758
nr_node_lock(nr_node);
759
if (nr_node->which < nr_node->count &&
760
nr_node->routes[nr_node->which].neighbour == nr_neigh)
761
nr_node->which++;
762
nr_node_unlock(nr_node);
763
}
764
spin_unlock_bh(&nr_node_list_lock);
765
nr_neigh_put(nr_neigh);
766
}
767
768
/*
769
* Route a frame to an appropriate AX.25 connection. A NULL ax25_cb
770
* indicates an internally generated frame.
771
*/
772
int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
773
{
774
ax25_address *nr_src, *nr_dest;
775
struct nr_neigh *nr_neigh;
776
struct nr_node *nr_node;
777
struct net_device *dev;
778
unsigned char *dptr;
779
ax25_cb *ax25s;
780
int ret;
781
struct sk_buff *skbn;
782
783
784
nr_src = (ax25_address *)(skb->data + 0);
785
nr_dest = (ax25_address *)(skb->data + 7);
786
787
if (ax25 != NULL) {
788
ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
789
ax25->ax25_dev->dev, 0,
790
sysctl_netrom_obsolescence_count_initialiser);
791
if (ret)
792
return ret;
793
}
794
795
if ((dev = nr_dev_get(nr_dest)) != NULL) { /* Its for me */
796
if (ax25 == NULL) /* Its from me */
797
ret = nr_loopback_queue(skb);
798
else
799
ret = nr_rx_frame(skb, dev);
800
dev_put(dev);
801
return ret;
802
}
803
804
if (!sysctl_netrom_routing_control && ax25 != NULL)
805
return 0;
806
807
/* Its Time-To-Live has expired */
808
if (skb->data[14] == 1) {
809
return 0;
810
}
811
812
nr_node = nr_node_get(nr_dest);
813
if (nr_node == NULL)
814
return 0;
815
nr_node_lock(nr_node);
816
817
if (nr_node->which >= nr_node->count) {
818
nr_node_unlock(nr_node);
819
nr_node_put(nr_node);
820
return 0;
821
}
822
823
nr_neigh = nr_node->routes[nr_node->which].neighbour;
824
825
if ((dev = nr_dev_first()) == NULL) {
826
nr_node_unlock(nr_node);
827
nr_node_put(nr_node);
828
return 0;
829
}
830
831
/* We are going to change the netrom headers so we should get our
832
own skb, we also did not know until now how much header space
833
we had to reserve... - RXQ */
834
if ((skbn=skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC)) == NULL) {
835
nr_node_unlock(nr_node);
836
nr_node_put(nr_node);
837
dev_put(dev);
838
return 0;
839
}
840
kfree_skb(skb);
841
skb=skbn;
842
skb->data[14]--;
843
844
dptr = skb_push(skb, 1);
845
*dptr = AX25_P_NETROM;
846
847
ax25s = nr_neigh->ax25;
848
nr_neigh->ax25 = ax25_send_frame(skb, 256,
849
(ax25_address *)dev->dev_addr,
850
&nr_neigh->callsign,
851
nr_neigh->digipeat, nr_neigh->dev);
852
if (ax25s)
853
ax25_cb_put(ax25s);
854
855
dev_put(dev);
856
ret = (nr_neigh->ax25 != NULL);
857
nr_node_unlock(nr_node);
858
nr_node_put(nr_node);
859
860
return ret;
861
}
862
863
#ifdef CONFIG_PROC_FS
864
865
static void *nr_node_start(struct seq_file *seq, loff_t *pos)
866
{
867
spin_lock_bh(&nr_node_list_lock);
868
return seq_hlist_start_head(&nr_node_list, *pos);
869
}
870
871
static void *nr_node_next(struct seq_file *seq, void *v, loff_t *pos)
872
{
873
return seq_hlist_next(v, &nr_node_list, pos);
874
}
875
876
static void nr_node_stop(struct seq_file *seq, void *v)
877
{
878
spin_unlock_bh(&nr_node_list_lock);
879
}
880
881
static int nr_node_show(struct seq_file *seq, void *v)
882
{
883
char buf[11];
884
int i;
885
886
if (v == SEQ_START_TOKEN)
887
seq_puts(seq,
888
"callsign mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
889
else {
890
struct nr_node *nr_node = hlist_entry(v, struct nr_node,
891
node_node);
892
893
nr_node_lock(nr_node);
894
seq_printf(seq, "%-9s %-7s %d %d",
895
ax2asc(buf, &nr_node->callsign),
896
(nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
897
nr_node->which + 1,
898
nr_node->count);
899
900
for (i = 0; i < nr_node->count; i++) {
901
seq_printf(seq, " %3d %d %05d",
902
nr_node->routes[i].quality,
903
nr_node->routes[i].obs_count,
904
nr_node->routes[i].neighbour->number);
905
}
906
nr_node_unlock(nr_node);
907
908
seq_puts(seq, "\n");
909
}
910
return 0;
911
}
912
913
static const struct seq_operations nr_node_seqops = {
914
.start = nr_node_start,
915
.next = nr_node_next,
916
.stop = nr_node_stop,
917
.show = nr_node_show,
918
};
919
920
static int nr_node_info_open(struct inode *inode, struct file *file)
921
{
922
return seq_open(file, &nr_node_seqops);
923
}
924
925
const struct file_operations nr_nodes_fops = {
926
.owner = THIS_MODULE,
927
.open = nr_node_info_open,
928
.read = seq_read,
929
.llseek = seq_lseek,
930
.release = seq_release,
931
};
932
933
static void *nr_neigh_start(struct seq_file *seq, loff_t *pos)
934
{
935
spin_lock_bh(&nr_neigh_list_lock);
936
return seq_hlist_start_head(&nr_neigh_list, *pos);
937
}
938
939
static void *nr_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
940
{
941
return seq_hlist_next(v, &nr_neigh_list, pos);
942
}
943
944
static void nr_neigh_stop(struct seq_file *seq, void *v)
945
{
946
spin_unlock_bh(&nr_neigh_list_lock);
947
}
948
949
static int nr_neigh_show(struct seq_file *seq, void *v)
950
{
951
char buf[11];
952
int i;
953
954
if (v == SEQ_START_TOKEN)
955
seq_puts(seq, "addr callsign dev qual lock count failed digipeaters\n");
956
else {
957
struct nr_neigh *nr_neigh;
958
959
nr_neigh = hlist_entry(v, struct nr_neigh, neigh_node);
960
seq_printf(seq, "%05d %-9s %-4s %3d %d %3d %3d",
961
nr_neigh->number,
962
ax2asc(buf, &nr_neigh->callsign),
963
nr_neigh->dev ? nr_neigh->dev->name : "???",
964
nr_neigh->quality,
965
nr_neigh->locked,
966
nr_neigh->count,
967
nr_neigh->failed);
968
969
if (nr_neigh->digipeat != NULL) {
970
for (i = 0; i < nr_neigh->digipeat->ndigi; i++)
971
seq_printf(seq, " %s",
972
ax2asc(buf, &nr_neigh->digipeat->calls[i]));
973
}
974
975
seq_puts(seq, "\n");
976
}
977
return 0;
978
}
979
980
static const struct seq_operations nr_neigh_seqops = {
981
.start = nr_neigh_start,
982
.next = nr_neigh_next,
983
.stop = nr_neigh_stop,
984
.show = nr_neigh_show,
985
};
986
987
static int nr_neigh_info_open(struct inode *inode, struct file *file)
988
{
989
return seq_open(file, &nr_neigh_seqops);
990
}
991
992
const struct file_operations nr_neigh_fops = {
993
.owner = THIS_MODULE,
994
.open = nr_neigh_info_open,
995
.read = seq_read,
996
.llseek = seq_lseek,
997
.release = seq_release,
998
};
999
1000
#endif
1001
1002
/*
1003
* Free all memory associated with the nodes and routes lists.
1004
*/
1005
void __exit nr_rt_free(void)
1006
{
1007
struct nr_neigh *s = NULL;
1008
struct nr_node *t = NULL;
1009
struct hlist_node *node, *nodet;
1010
1011
spin_lock_bh(&nr_neigh_list_lock);
1012
spin_lock_bh(&nr_node_list_lock);
1013
nr_node_for_each_safe(t, node, nodet, &nr_node_list) {
1014
nr_node_lock(t);
1015
nr_remove_node_locked(t);
1016
nr_node_unlock(t);
1017
}
1018
nr_neigh_for_each_safe(s, node, nodet, &nr_neigh_list) {
1019
while(s->count) {
1020
s->count--;
1021
nr_neigh_put(s);
1022
}
1023
nr_remove_neigh_locked(s);
1024
}
1025
spin_unlock_bh(&nr_node_list_lock);
1026
spin_unlock_bh(&nr_neigh_list_lock);
1027
}
1028
1029