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