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