1 /*
2 * NET/ROM release 007
3 *
4 * This code REQUIRES 2.1.15 or higher/ NET3.038
5 *
6 * This module:
7 * This module is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 * History
13 * NET/ROM 001 Jonathan(G4KLX) First attempt.
14 * NET/ROM 003 Jonathan(G4KLX) Use SIOCADDRT/SIOCDELRT ioctl values
15 * for NET/ROM routes.
16 * Use '*' for a blank mnemonic in /proc/net/nr_nodes.
17 * Change default quality for new neighbour when same
18 * as node callsign.
19 * Alan Cox(GW4PTS) Added the firewall hooks.
20 * NET/ROM 006 Jonathan(G4KLX) Added the setting of digipeated neighbours.
21 * Tomi(OH2BNS) Routing quality and link failure changes.
22 * Device refcnt fixes.
23 */
24
25 #include <linux/errno.h>
26 #include <linux/types.h>
27 #include <linux/socket.h>
28 #include <linux/in.h>
29 #include <linux/kernel.h>
30 #include <linux/sched.h>
31 #include <linux/timer.h>
32 #include <linux/string.h>
33 #include <linux/sockios.h>
34 #include <linux/net.h>
35 #include <net/ax25.h>
36 #include <linux/inet.h>
37 #include <linux/netdevice.h>
38 #include <net/arp.h>
39 #include <linux/if_arp.h>
40 #include <linux/skbuff.h>
41 #include <net/sock.h>
42 #include <asm/uaccess.h>
43 #include <asm/system.h>
44 #include <linux/fcntl.h>
45 #include <linux/termios.h> /* For TIOCINQ/OUTQ */
46 #include <linux/mm.h>
47 #include <linux/interrupt.h>
48 #include <linux/notifier.h>
49 #include <linux/netfilter.h>
50 #include <linux/init.h>
51 #include <net/netrom.h>
52
53 static unsigned int nr_neigh_no = 1;
54
55 static struct nr_node *nr_node_list;
56 static struct nr_neigh *nr_neigh_list;
57
58 static void nr_remove_neigh(struct nr_neigh *);
59
60 /*
61 * Add a new route to a node, and in the process add the node and the
62 * neighbour if it is new.
63 */
nr_add_node(ax25_address * nr,const char * mnemonic,ax25_address * ax25,ax25_digi * ax25_digi,struct net_device * dev,int quality,int obs_count)64 static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax25,
65 ax25_digi *ax25_digi, struct net_device *dev, int quality, int obs_count)
66 {
67 struct nr_node *nr_node;
68 struct nr_neigh *nr_neigh;
69 struct nr_route nr_route;
70 struct net_device *tdev;
71 unsigned long flags;
72 int i, found;
73
74 /* Can't add routes to ourself */
75 if ((tdev = nr_dev_get(nr)) != NULL) {
76 dev_put(tdev);
77 return -EINVAL;
78 }
79
80 for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next)
81 if (ax25cmp(nr, &nr_node->callsign) == 0)
82 break;
83
84 for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next)
85 if (ax25cmp(ax25, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev)
86 break;
87
88 /*
89 * The L2 link to a neighbour has failed in the past
90 * and now a frame comes from this neighbour. We assume
91 * it was a temporary trouble with the link and reset the
92 * routes now (and not wait for a node broadcast).
93 */
94 if (nr_neigh != NULL && nr_neigh->failed != 0 && quality == 0) {
95 struct nr_node *node;
96
97 for (node = nr_node_list; node != NULL; node = node->next)
98 for (i = 0; i < node->count; i++)
99 if (node->routes[i].neighbour == nr_neigh)
100 if (i < node->which)
101 node->which = i;
102 }
103
104 if (nr_neigh != NULL)
105 nr_neigh->failed = 0;
106
107 if (quality == 0 && nr_neigh != NULL && nr_node != NULL)
108 return 0;
109
110 if (nr_neigh == NULL) {
111 if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL)
112 return -ENOMEM;
113
114 nr_neigh->callsign = *ax25;
115 nr_neigh->digipeat = NULL;
116 nr_neigh->ax25 = NULL;
117 nr_neigh->dev = dev;
118 nr_neigh->quality = sysctl_netrom_default_path_quality;
119 nr_neigh->locked = 0;
120 nr_neigh->count = 0;
121 nr_neigh->number = nr_neigh_no++;
122 nr_neigh->failed = 0;
123
124 if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
125 if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) {
126 kfree(nr_neigh);
127 return -ENOMEM;
128 }
129 memcpy(nr_neigh->digipeat, ax25_digi, sizeof(ax25_digi));
130 }
131
132 dev_hold(nr_neigh->dev);
133
134 save_flags(flags);
135 cli();
136
137 nr_neigh->next = nr_neigh_list;
138 nr_neigh_list = nr_neigh;
139
140 restore_flags(flags);
141 }
142
143 if (quality != 0 && ax25cmp(nr, ax25) == 0 && !nr_neigh->locked)
144 nr_neigh->quality = quality;
145
146 if (nr_node == NULL) {
147 if ((nr_node = kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL)
148 return -ENOMEM;
149
150 nr_node->callsign = *nr;
151 strcpy(nr_node->mnemonic, mnemonic);
152
153 nr_node->which = 0;
154 nr_node->count = 1;
155
156 nr_node->routes[0].quality = quality;
157 nr_node->routes[0].obs_count = obs_count;
158 nr_node->routes[0].neighbour = nr_neigh;
159
160 save_flags(flags);
161 cli();
162
163 nr_node->next = nr_node_list;
164 nr_node_list = nr_node;
165
166 restore_flags(flags);
167
168 nr_neigh->count++;
169
170 return 0;
171 }
172
173 if (quality != 0)
174 strcpy(nr_node->mnemonic, mnemonic);
175
176 for (found = 0, i = 0; i < nr_node->count; i++) {
177 if (nr_node->routes[i].neighbour == nr_neigh) {
178 nr_node->routes[i].quality = quality;
179 nr_node->routes[i].obs_count = obs_count;
180 found = 1;
181 break;
182 }
183 }
184
185 if (!found) {
186 /* We have space at the bottom, slot it in */
187 if (nr_node->count < 3) {
188 nr_node->routes[2] = nr_node->routes[1];
189 nr_node->routes[1] = nr_node->routes[0];
190
191 nr_node->routes[0].quality = quality;
192 nr_node->routes[0].obs_count = obs_count;
193 nr_node->routes[0].neighbour = nr_neigh;
194
195 nr_node->which++;
196 nr_node->count++;
197 nr_neigh->count++;
198 } else {
199 /* It must be better than the worst */
200 if (quality > nr_node->routes[2].quality) {
201 nr_node->routes[2].neighbour->count--;
202
203 if (nr_node->routes[2].neighbour->count == 0 && !nr_node->routes[2].neighbour->locked)
204 nr_remove_neigh(nr_node->routes[2].neighbour);
205
206 nr_node->routes[2].quality = quality;
207 nr_node->routes[2].obs_count = obs_count;
208 nr_node->routes[2].neighbour = nr_neigh;
209
210 nr_neigh->count++;
211 }
212 }
213 }
214
215 /* Now re-sort the routes in quality order */
216 switch (nr_node->count) {
217 case 3:
218 if (nr_node->routes[1].quality > nr_node->routes[0].quality) {
219 switch (nr_node->which) {
220 case 0: nr_node->which = 1; break;
221 case 1: nr_node->which = 0; break;
222 default: break;
223 }
224 nr_route = nr_node->routes[0];
225 nr_node->routes[0] = nr_node->routes[1];
226 nr_node->routes[1] = nr_route;
227 }
228 if (nr_node->routes[2].quality > nr_node->routes[1].quality) {
229 switch (nr_node->which) {
230 case 1: nr_node->which = 2; break;
231 case 2: nr_node->which = 1; break;
232 default: break;
233 }
234 nr_route = nr_node->routes[1];
235 nr_node->routes[1] = nr_node->routes[2];
236 nr_node->routes[2] = nr_route;
237 }
238 case 2:
239 if (nr_node->routes[1].quality > nr_node->routes[0].quality) {
240 switch (nr_node->which) {
241 case 0: nr_node->which = 1; break;
242 case 1: nr_node->which = 0; break;
243 default: break;
244 }
245 nr_route = nr_node->routes[0];
246 nr_node->routes[0] = nr_node->routes[1];
247 nr_node->routes[1] = nr_route;
248 }
249 case 1:
250 break;
251 }
252
253 for (i = 0; i < nr_node->count; i++) {
254 if (nr_node->routes[i].neighbour == nr_neigh) {
255 if (i < nr_node->which)
256 nr_node->which = i;
257 break;
258 }
259 }
260
261 return 0;
262 }
263
nr_remove_node(struct nr_node * nr_node)264 static void nr_remove_node(struct nr_node *nr_node)
265 {
266 struct nr_node *s;
267 unsigned long flags;
268
269 save_flags(flags);
270 cli();
271
272 if ((s = nr_node_list) == nr_node) {
273 nr_node_list = nr_node->next;
274 restore_flags(flags);
275 kfree(nr_node);
276 return;
277 }
278
279 while (s != NULL && s->next != NULL) {
280 if (s->next == nr_node) {
281 s->next = nr_node->next;
282 restore_flags(flags);
283 kfree(nr_node);
284 return;
285 }
286
287 s = s->next;
288 }
289
290 restore_flags(flags);
291 }
292
nr_remove_neigh(struct nr_neigh * nr_neigh)293 static void nr_remove_neigh(struct nr_neigh *nr_neigh)
294 {
295 struct nr_neigh *s;
296 unsigned long flags;
297
298 save_flags(flags);
299 cli();
300
301 if ((s = nr_neigh_list) == nr_neigh) {
302 nr_neigh_list = nr_neigh->next;
303 restore_flags(flags);
304 dev_put(nr_neigh->dev);
305 if (nr_neigh->digipeat != NULL)
306 kfree(nr_neigh->digipeat);
307 kfree(nr_neigh);
308 return;
309 }
310
311 while (s != NULL && s->next != NULL) {
312 if (s->next == nr_neigh) {
313 s->next = nr_neigh->next;
314 restore_flags(flags);
315 dev_put(nr_neigh->dev);
316 if (nr_neigh->digipeat != NULL)
317 kfree(nr_neigh->digipeat);
318 kfree(nr_neigh);
319 return;
320 }
321
322 s = s->next;
323 }
324
325 restore_flags(flags);
326 }
327
328 /*
329 * "Delete" a node. Strictly speaking remove a route to a node. The node
330 * is only deleted if no routes are left to it.
331 */
nr_del_node(ax25_address * callsign,ax25_address * neighbour,struct net_device * dev)332 static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct net_device *dev)
333 {
334 struct nr_node *nr_node;
335 struct nr_neigh *nr_neigh;
336 int i;
337
338 for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next)
339 if (ax25cmp(callsign, &nr_node->callsign) == 0)
340 break;
341
342 if (nr_node == NULL) return -EINVAL;
343
344 for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next)
345 if (ax25cmp(neighbour, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev)
346 break;
347
348 if (nr_neigh == NULL) return -EINVAL;
349
350 for (i = 0; i < nr_node->count; i++) {
351 if (nr_node->routes[i].neighbour == nr_neigh) {
352 nr_neigh->count--;
353
354 if (nr_neigh->count == 0 && !nr_neigh->locked)
355 nr_remove_neigh(nr_neigh);
356
357 nr_node->count--;
358
359 if (nr_node->count == 0) {
360 nr_remove_node(nr_node);
361 } else {
362 switch (i) {
363 case 0:
364 nr_node->routes[0] = nr_node->routes[1];
365 case 1:
366 nr_node->routes[1] = nr_node->routes[2];
367 case 2:
368 break;
369 }
370 }
371
372 return 0;
373 }
374 }
375
376 return -EINVAL;
377 }
378
379 /*
380 * Lock a neighbour with a quality.
381 */
nr_add_neigh(ax25_address * callsign,ax25_digi * ax25_digi,struct net_device * dev,unsigned int quality)382 static int nr_add_neigh(ax25_address *callsign, ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
383 {
384 struct nr_neigh *nr_neigh;
385 unsigned long flags;
386
387 for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next) {
388 if (ax25cmp(callsign, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev) {
389 nr_neigh->quality = quality;
390 nr_neigh->locked = 1;
391 return 0;
392 }
393 }
394
395 if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL)
396 return -ENOMEM;
397
398 nr_neigh->callsign = *callsign;
399 nr_neigh->digipeat = NULL;
400 nr_neigh->ax25 = NULL;
401 nr_neigh->dev = dev;
402 nr_neigh->quality = quality;
403 nr_neigh->locked = 1;
404 nr_neigh->count = 0;
405 nr_neigh->number = nr_neigh_no++;
406 nr_neigh->failed = 0;
407
408 if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
409 if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) {
410 kfree(nr_neigh);
411 return -ENOMEM;
412 }
413 memcpy(nr_neigh->digipeat, ax25_digi, sizeof(ax25_digi));
414 }
415
416 dev_hold(nr_neigh->dev);
417
418 save_flags(flags);
419 cli();
420
421 nr_neigh->next = nr_neigh_list;
422 nr_neigh_list = nr_neigh;
423
424 restore_flags(flags);
425
426 return 0;
427 }
428
429 /*
430 * "Delete" a neighbour. The neighbour is only removed if the number
431 * of nodes that may use it is zero.
432 */
nr_del_neigh(ax25_address * callsign,struct net_device * dev,unsigned int quality)433 static int nr_del_neigh(ax25_address *callsign, struct net_device *dev, unsigned int quality)
434 {
435 struct nr_neigh *nr_neigh;
436
437 for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next)
438 if (ax25cmp(callsign, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev)
439 break;
440
441 if (nr_neigh == NULL) return -EINVAL;
442
443 nr_neigh->quality = quality;
444 nr_neigh->locked = 0;
445
446 if (nr_neigh->count == 0)
447 nr_remove_neigh(nr_neigh);
448
449 return 0;
450 }
451
452 /*
453 * Decrement the obsolescence count by one. If a route is reduced to a
454 * count of zero, remove it. Also remove any unlocked neighbours with
455 * zero nodes routing via it.
456 */
nr_dec_obs(void)457 static int nr_dec_obs(void)
458 {
459 struct nr_neigh *nr_neigh;
460 struct nr_node *s, *nr_node;
461 int i;
462
463 nr_node = nr_node_list;
464
465 while (nr_node != NULL) {
466 s = nr_node;
467 nr_node = nr_node->next;
468
469 for (i = 0; i < s->count; i++) {
470 switch (s->routes[i].obs_count) {
471
472 case 0: /* A locked entry */
473 break;
474
475 case 1: /* From 1 -> 0 */
476 nr_neigh = s->routes[i].neighbour;
477
478 nr_neigh->count--;
479
480 if (nr_neigh->count == 0 && !nr_neigh->locked)
481 nr_remove_neigh(nr_neigh);
482
483 s->count--;
484
485 switch (i) {
486 case 0:
487 s->routes[0] = s->routes[1];
488 case 1:
489 s->routes[1] = s->routes[2];
490 case 2:
491 break;
492 }
493 break;
494
495 default:
496 s->routes[i].obs_count--;
497 break;
498
499 }
500 }
501
502 if (s->count <= 0)
503 nr_remove_node(s);
504 }
505
506 return 0;
507 }
508
509 /*
510 * A device has been removed. Remove its routes and neighbours.
511 */
nr_rt_device_down(struct net_device * dev)512 void nr_rt_device_down(struct net_device *dev)
513 {
514 struct nr_neigh *s, *nr_neigh = nr_neigh_list;
515 struct nr_node *t, *nr_node;
516 int i;
517
518 while (nr_neigh != NULL) {
519 s = nr_neigh;
520 nr_neigh = nr_neigh->next;
521
522 if (s->dev == dev) {
523 nr_node = nr_node_list;
524
525 while (nr_node != NULL) {
526 t = nr_node;
527 nr_node = nr_node->next;
528
529 for (i = 0; i < t->count; i++) {
530 if (t->routes[i].neighbour == s) {
531 t->count--;
532
533 switch (i) {
534 case 0:
535 t->routes[0] = t->routes[1];
536 case 1:
537 t->routes[1] = t->routes[2];
538 case 2:
539 break;
540 }
541 }
542 }
543
544 if (t->count <= 0)
545 nr_remove_node(t);
546 }
547
548 nr_remove_neigh(s);
549 }
550 }
551 }
552
553 /*
554 * Check that the device given is a valid AX.25 interface that is "up".
555 * Or a valid ethernet interface with an AX.25 callsign binding.
556 */
nr_ax25_dev_get(char * devname)557 static struct net_device *nr_ax25_dev_get(char *devname)
558 {
559 struct net_device *dev;
560
561 if ((dev = dev_get_by_name(devname)) == NULL)
562 return NULL;
563
564 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
565 return dev;
566
567 dev_put(dev);
568 return NULL;
569 }
570
571 /*
572 * Find the first active NET/ROM device, usually "nr0".
573 */
nr_dev_first(void)574 struct net_device *nr_dev_first(void)
575 {
576 struct net_device *dev, *first = NULL;
577
578 read_lock(&dev_base_lock);
579 for (dev = dev_base; dev != NULL; dev = dev->next) {
580 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM)
581 if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
582 first = dev;
583 }
584
585 if (first != NULL)
586 dev_hold(first);
587
588 read_unlock(&dev_base_lock);
589
590 return first;
591 }
592
593 /*
594 * Find the NET/ROM device for the given callsign.
595 */
nr_dev_get(ax25_address * addr)596 struct net_device *nr_dev_get(ax25_address *addr)
597 {
598 struct net_device *dev;
599
600 read_lock(&dev_base_lock);
601 for (dev = dev_base; dev != NULL; dev = dev->next) {
602 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM && ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) {
603 dev_hold(dev);
604 goto out;
605 }
606 }
607 out:
608 read_unlock(&dev_base_lock);
609 return dev;
610 }
611
nr_call_to_digi(int ndigis,ax25_address * digipeaters)612 static ax25_digi *nr_call_to_digi(int ndigis, ax25_address *digipeaters)
613 {
614 static ax25_digi ax25_digi;
615 int i;
616
617 if (ndigis == 0)
618 return NULL;
619
620 for (i = 0; i < ndigis; i++) {
621 ax25_digi.calls[i] = digipeaters[i];
622 ax25_digi.repeated[i] = 0;
623 }
624
625 ax25_digi.ndigi = ndigis;
626 ax25_digi.lastrepeat = -1;
627
628 return &ax25_digi;
629 }
630
631 /*
632 * Handle the ioctls that control the routing functions.
633 */
nr_rt_ioctl(unsigned int cmd,void * arg)634 int nr_rt_ioctl(unsigned int cmd, void *arg)
635 {
636 struct nr_route_struct nr_route;
637 struct net_device *dev;
638 int ret;
639
640 switch (cmd) {
641
642 case SIOCADDRT:
643 if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
644 return -EFAULT;
645 if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
646 return -EINVAL;
647 if (nr_route.ndigis < 0 || nr_route.ndigis > AX25_MAX_DIGIS) {
648 dev_put(dev);
649 return -EINVAL;
650 }
651 switch (nr_route.type) {
652 case NETROM_NODE:
653 ret = nr_add_node(&nr_route.callsign,
654 nr_route.mnemonic,
655 &nr_route.neighbour,
656 nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters),
657 dev, nr_route.quality,
658 nr_route.obs_count);
659 break;
660 case NETROM_NEIGH:
661 ret = nr_add_neigh(&nr_route.callsign,
662 nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters),
663 dev, nr_route.quality);
664 break;
665 default:
666 ret = -EINVAL;
667 break;
668 }
669 dev_put(dev);
670 return ret;
671
672 case SIOCDELRT:
673 if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
674 return -EFAULT;
675 if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
676 return -EINVAL;
677 switch (nr_route.type) {
678 case NETROM_NODE:
679 ret = nr_del_node(&nr_route.callsign,
680 &nr_route.neighbour, dev);
681 break;
682 case NETROM_NEIGH:
683 ret = nr_del_neigh(&nr_route.callsign,
684 dev, nr_route.quality);
685 break;
686 default:
687 ret = -EINVAL;
688 break;
689 }
690 dev_put(dev);
691 return ret;
692
693 case SIOCNRDECOBS:
694 return nr_dec_obs();
695
696 default:
697 return -EINVAL;
698 }
699
700 return 0;
701 }
702
703 /*
704 * A level 2 link has timed out, therefore it appears to be a poor link,
705 * then don't use that neighbour until it is reset.
706 */
nr_link_failed(ax25_cb * ax25,int reason)707 void nr_link_failed(ax25_cb *ax25, int reason)
708 {
709 struct nr_neigh *nr_neigh;
710 struct nr_node *nr_node;
711
712 for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next)
713 if (nr_neigh->ax25 == ax25)
714 break;
715
716 if (nr_neigh == NULL) return;
717
718 nr_neigh->ax25 = NULL;
719
720 if (++nr_neigh->failed < sysctl_netrom_link_fails_count) return;
721
722 for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next)
723 if (nr_node->which < nr_node->count && nr_node->routes[nr_node->which].neighbour == nr_neigh)
724 nr_node->which++;
725 }
726
727 /*
728 * Route a frame to an appropriate AX.25 connection. A NULL ax25_cb
729 * indicates an internally generated frame.
730 */
nr_route_frame(struct sk_buff * skb,ax25_cb * ax25)731 int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
732 {
733 ax25_address *nr_src, *nr_dest;
734 struct nr_neigh *nr_neigh;
735 struct nr_node *nr_node;
736 struct net_device *dev;
737 unsigned char *dptr;
738
739
740 nr_src = (ax25_address *)(skb->data + 0);
741 nr_dest = (ax25_address *)(skb->data + 7);
742
743 if (ax25 != NULL)
744 nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
745 ax25->ax25_dev->dev, 0, sysctl_netrom_obsolescence_count_initialiser);
746
747 if ((dev = nr_dev_get(nr_dest)) != NULL) { /* Its for me */
748 int ret;
749
750 if (ax25 == NULL) /* Its from me */
751 ret = nr_loopback_queue(skb);
752 else
753 ret = nr_rx_frame(skb, dev);
754
755 dev_put(dev);
756 return ret;
757 }
758
759 if (!sysctl_netrom_routing_control && ax25 != NULL)
760 return 0;
761
762 /* Its Time-To-Live has expired */
763 if (--skb->data[14] == 0)
764 return 0;
765
766 for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next)
767 if (ax25cmp(nr_dest, &nr_node->callsign) == 0)
768 break;
769
770 if (nr_node == NULL || nr_node->which >= nr_node->count)
771 return 0;
772
773 nr_neigh = nr_node->routes[nr_node->which].neighbour;
774
775 if ((dev = nr_dev_first()) == NULL)
776 return 0;
777
778 dptr = skb_push(skb, 1);
779 *dptr = AX25_P_NETROM;
780
781 nr_neigh->ax25 = ax25_send_frame(skb, 256, (ax25_address *)dev->dev_addr, &nr_neigh->callsign, nr_neigh->digipeat, nr_neigh->dev);
782
783 dev_put(dev);
784
785 return (nr_neigh->ax25 != NULL);
786 }
787
nr_nodes_get_info(char * buffer,char ** start,off_t offset,int length)788 int nr_nodes_get_info(char *buffer, char **start, off_t offset, int length)
789 {
790 struct nr_node *nr_node;
791 int len = 0;
792 off_t pos = 0;
793 off_t begin = 0;
794 int i;
795
796 cli();
797
798 len += sprintf(buffer, "callsign mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
799
800 for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next) {
801 len += sprintf(buffer + len, "%-9s %-7s %d %d",
802 ax2asc(&nr_node->callsign),
803 (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
804 nr_node->which + 1,
805 nr_node->count);
806
807 for (i = 0; i < nr_node->count; i++) {
808 len += sprintf(buffer + len, " %3d %d %05d",
809 nr_node->routes[i].quality,
810 nr_node->routes[i].obs_count,
811 nr_node->routes[i].neighbour->number);
812 }
813
814 len += sprintf(buffer + len, "\n");
815
816 pos = begin + len;
817
818 if (pos < offset) {
819 len = 0;
820 begin = pos;
821 }
822
823 if (pos > offset + length)
824 break;
825 }
826
827 sti();
828
829 *start = buffer + (offset - begin);
830 len -= (offset - begin);
831
832 if (len > length) len = length;
833
834 return len;
835 }
836
nr_neigh_get_info(char * buffer,char ** start,off_t offset,int length)837 int nr_neigh_get_info(char *buffer, char **start, off_t offset, int length)
838 {
839 struct nr_neigh *nr_neigh;
840 int len = 0;
841 off_t pos = 0;
842 off_t begin = 0;
843 int i;
844
845 cli();
846
847 len += sprintf(buffer, "addr callsign dev qual lock count failed digipeaters\n");
848
849 for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next) {
850 len += sprintf(buffer + len, "%05d %-9s %-4s %3d %d %3d %3d",
851 nr_neigh->number,
852 ax2asc(&nr_neigh->callsign),
853 nr_neigh->dev ? nr_neigh->dev->name : "???",
854 nr_neigh->quality,
855 nr_neigh->locked,
856 nr_neigh->count,
857 nr_neigh->failed);
858
859 if (nr_neigh->digipeat != NULL) {
860 for (i = 0; i < nr_neigh->digipeat->ndigi; i++)
861 len += sprintf(buffer + len, " %s", ax2asc(&nr_neigh->digipeat->calls[i]));
862 }
863
864 len += sprintf(buffer + len, "\n");
865
866 pos = begin + len;
867
868 if (pos < offset) {
869 len = 0;
870 begin = pos;
871 }
872
873 if (pos > offset + length)
874 break;
875 }
876
877 sti();
878
879 *start = buffer + (offset - begin);
880 len -= (offset - begin);
881
882 if (len > length) len = length;
883
884 return len;
885 }
886
887 /*
888 * Free all memory associated with the nodes and routes lists.
889 */
nr_rt_free(void)890 void __exit nr_rt_free(void)
891 {
892 struct nr_neigh *s, *nr_neigh = nr_neigh_list;
893 struct nr_node *t, *nr_node = nr_node_list;
894
895 while (nr_node != NULL) {
896 t = nr_node;
897 nr_node = nr_node->next;
898
899 nr_remove_node(t);
900 }
901
902 while (nr_neigh != NULL) {
903 s = nr_neigh;
904 nr_neigh = nr_neigh->next;
905
906 nr_remove_neigh(s);
907 }
908 }
909