root/net/netrom/nr_route.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nr_node_get
  2. nr_neigh_get_dev
  3. re_sort_routes
  4. nr_add_node
  5. __nr_remove_node
  6. nr_remove_node
  7. __nr_remove_neigh
  8. nr_remove_neigh
  9. nr_del_node
  10. nr_add_neigh
  11. nr_del_neigh
  12. nr_dec_obs
  13. nr_rt_device_down
  14. nr_ax25_dev_get
  15. nr_dev_first
  16. nr_dev_get
  17. nr_call_to_digi
  18. nr_rt_ioctl
  19. nr_link_failed
  20. nr_route_frame
  21. nr_node_start
  22. nr_node_next
  23. nr_node_stop
  24. nr_node_show
  25. nr_neigh_start
  26. nr_neigh_next
  27. nr_neigh_stop
  28. nr_neigh_show
  29. nr_rt_free

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *
   4  * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
   5  * Copyright Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
   6  * Copyright Tomi Manninen OH2BNS (oh2bns@sral.fi)
   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  = 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                 strcpy(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                 strcpy(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                 /* fall through */
 267         case 2:
 268                 re_sort_routes(nr_node, 0, 1);
 269         case 1:
 270                 break;
 271         }
 272 
 273         for (i = 0; i < nr_node->count; i++) {
 274                 if (nr_node->routes[i].neighbour == nr_neigh) {
 275                         if (i < nr_node->which)
 276                                 nr_node->which = i;
 277                         break;
 278                 }
 279         }
 280 
 281         nr_neigh_put(nr_neigh);
 282         nr_node_unlock(nr_node);
 283         nr_node_put(nr_node);
 284         return 0;
 285 }
 286 
 287 static inline void __nr_remove_node(struct nr_node *nr_node)
 288 {
 289         hlist_del_init(&nr_node->node_node);
 290         nr_node_put(nr_node);
 291 }
 292 
 293 #define nr_remove_node_locked(__node) \
 294         __nr_remove_node(__node)
 295 
 296 static void nr_remove_node(struct nr_node *nr_node)
 297 {
 298         spin_lock_bh(&nr_node_list_lock);
 299         __nr_remove_node(nr_node);
 300         spin_unlock_bh(&nr_node_list_lock);
 301 }
 302 
 303 static inline void __nr_remove_neigh(struct nr_neigh *nr_neigh)
 304 {
 305         hlist_del_init(&nr_neigh->neigh_node);
 306         nr_neigh_put(nr_neigh);
 307 }
 308 
 309 #define nr_remove_neigh_locked(__neigh) \
 310         __nr_remove_neigh(__neigh)
 311 
 312 static void nr_remove_neigh(struct nr_neigh *nr_neigh)
 313 {
 314         spin_lock_bh(&nr_neigh_list_lock);
 315         __nr_remove_neigh(nr_neigh);
 316         spin_unlock_bh(&nr_neigh_list_lock);
 317 }
 318 
 319 /*
 320  *      "Delete" a node. Strictly speaking remove a route to a node. The node
 321  *      is only deleted if no routes are left to it.
 322  */
 323 static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct net_device *dev)
 324 {
 325         struct nr_node  *nr_node;
 326         struct nr_neigh *nr_neigh;
 327         int i;
 328 
 329         nr_node = nr_node_get(callsign);
 330 
 331         if (nr_node == NULL)
 332                 return -EINVAL;
 333 
 334         nr_neigh = nr_neigh_get_dev(neighbour, dev);
 335 
 336         if (nr_neigh == NULL) {
 337                 nr_node_put(nr_node);
 338                 return -EINVAL;
 339         }
 340 
 341         nr_node_lock(nr_node);
 342         for (i = 0; i < nr_node->count; i++) {
 343                 if (nr_node->routes[i].neighbour == nr_neigh) {
 344                         nr_neigh->count--;
 345                         nr_neigh_put(nr_neigh);
 346 
 347                         if (nr_neigh->count == 0 && !nr_neigh->locked)
 348                                 nr_remove_neigh(nr_neigh);
 349                         nr_neigh_put(nr_neigh);
 350 
 351                         nr_node->count--;
 352 
 353                         if (nr_node->count == 0) {
 354                                 nr_remove_node(nr_node);
 355                         } else {
 356                                 switch (i) {
 357                                 case 0:
 358                                         nr_node->routes[0] = nr_node->routes[1];
 359                                         /* fall through */
 360                                 case 1:
 361                                         nr_node->routes[1] = nr_node->routes[2];
 362                                 case 2:
 363                                         break;
 364                                 }
 365                                 nr_node_put(nr_node);
 366                         }
 367                         nr_node_unlock(nr_node);
 368 
 369                         return 0;
 370                 }
 371         }
 372         nr_neigh_put(nr_neigh);
 373         nr_node_unlock(nr_node);
 374         nr_node_put(nr_node);
 375 
 376         return -EINVAL;
 377 }
 378 
 379 /*
 380  *      Lock a neighbour with a quality.
 381  */
 382 static int __must_check nr_add_neigh(ax25_address *callsign,
 383         ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
 384 {
 385         struct nr_neigh *nr_neigh;
 386 
 387         nr_neigh = nr_neigh_get_dev(callsign, dev);
 388         if (nr_neigh) {
 389                 nr_neigh->quality = quality;
 390                 nr_neigh->locked  = 1;
 391                 nr_neigh_put(nr_neigh);
 392                 return 0;
 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         refcount_set(&nr_neigh->refcount, 1);
 408 
 409         if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
 410                 nr_neigh->digipeat = kmemdup(ax25_digi, sizeof(*ax25_digi),
 411                                              GFP_KERNEL);
 412                 if (nr_neigh->digipeat == NULL) {
 413                         kfree(nr_neigh);
 414                         return -ENOMEM;
 415                 }
 416         }
 417 
 418         spin_lock_bh(&nr_neigh_list_lock);
 419         hlist_add_head(&nr_neigh->neigh_node, &nr_neigh_list);
 420         /* refcount is initialized at 1 */
 421         spin_unlock_bh(&nr_neigh_list_lock);
 422 
 423         return 0;
 424 }
 425 
 426 /*
 427  *      "Delete" a neighbour. The neighbour is only removed if the number
 428  *      of nodes that may use it is zero.
 429  */
 430 static int nr_del_neigh(ax25_address *callsign, struct net_device *dev, unsigned int quality)
 431 {
 432         struct nr_neigh *nr_neigh;
 433 
 434         nr_neigh = nr_neigh_get_dev(callsign, dev);
 435 
 436         if (nr_neigh == NULL) return -EINVAL;
 437 
 438         nr_neigh->quality = quality;
 439         nr_neigh->locked  = 0;
 440 
 441         if (nr_neigh->count == 0)
 442                 nr_remove_neigh(nr_neigh);
 443         nr_neigh_put(nr_neigh);
 444 
 445         return 0;
 446 }
 447 
 448 /*
 449  *      Decrement the obsolescence count by one. If a route is reduced to a
 450  *      count of zero, remove it. Also remove any unlocked neighbours with
 451  *      zero nodes routing via it.
 452  */
 453 static int nr_dec_obs(void)
 454 {
 455         struct nr_neigh *nr_neigh;
 456         struct nr_node  *s;
 457         struct hlist_node *nodet;
 458         int i;
 459 
 460         spin_lock_bh(&nr_node_list_lock);
 461         nr_node_for_each_safe(s, nodet, &nr_node_list) {
 462                 nr_node_lock(s);
 463                 for (i = 0; i < s->count; i++) {
 464                         switch (s->routes[i].obs_count) {
 465                         case 0:         /* A locked entry */
 466                                 break;
 467 
 468                         case 1:         /* From 1 -> 0 */
 469                                 nr_neigh = s->routes[i].neighbour;
 470 
 471                                 nr_neigh->count--;
 472                                 nr_neigh_put(nr_neigh);
 473 
 474                                 if (nr_neigh->count == 0 && !nr_neigh->locked)
 475                                         nr_remove_neigh(nr_neigh);
 476 
 477                                 s->count--;
 478 
 479                                 switch (i) {
 480                                 case 0:
 481                                         s->routes[0] = s->routes[1];
 482                                         /* Fallthrough */
 483                                 case 1:
 484                                         s->routes[1] = s->routes[2];
 485                                 case 2:
 486                                         break;
 487                                 }
 488                                 break;
 489 
 490                         default:
 491                                 s->routes[i].obs_count--;
 492                                 break;
 493 
 494                         }
 495                 }
 496 
 497                 if (s->count <= 0)
 498                         nr_remove_node_locked(s);
 499                 nr_node_unlock(s);
 500         }
 501         spin_unlock_bh(&nr_node_list_lock);
 502 
 503         return 0;
 504 }
 505 
 506 /*
 507  *      A device has been removed. Remove its routes and neighbours.
 508  */
 509 void nr_rt_device_down(struct net_device *dev)
 510 {
 511         struct nr_neigh *s;
 512         struct hlist_node *nodet, *node2t;
 513         struct nr_node  *t;
 514         int i;
 515 
 516         spin_lock_bh(&nr_neigh_list_lock);
 517         nr_neigh_for_each_safe(s, nodet, &nr_neigh_list) {
 518                 if (s->dev == dev) {
 519                         spin_lock_bh(&nr_node_list_lock);
 520                         nr_node_for_each_safe(t, node2t, &nr_node_list) {
 521                                 nr_node_lock(t);
 522                                 for (i = 0; i < t->count; i++) {
 523                                         if (t->routes[i].neighbour == s) {
 524                                                 t->count--;
 525 
 526                                                 switch (i) {
 527                                                 case 0:
 528                                                         t->routes[0] = t->routes[1];
 529                                                         /* fall through */
 530                                                 case 1:
 531                                                         t->routes[1] = t->routes[2];
 532                                                 case 2:
 533                                                         break;
 534                                                 }
 535                                         }
 536                                 }
 537 
 538                                 if (t->count <= 0)
 539                                         nr_remove_node_locked(t);
 540                                 nr_node_unlock(t);
 541                         }
 542                         spin_unlock_bh(&nr_node_list_lock);
 543 
 544                         nr_remove_neigh_locked(s);
 545                 }
 546         }
 547         spin_unlock_bh(&nr_neigh_list_lock);
 548 }
 549 
 550 /*
 551  *      Check that the device given is a valid AX.25 interface that is "up".
 552  *      Or a valid ethernet interface with an AX.25 callsign binding.
 553  */
 554 static struct net_device *nr_ax25_dev_get(char *devname)
 555 {
 556         struct net_device *dev;
 557 
 558         if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
 559                 return NULL;
 560 
 561         if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
 562                 return dev;
 563 
 564         dev_put(dev);
 565         return NULL;
 566 }
 567 
 568 /*
 569  *      Find the first active NET/ROM device, usually "nr0".
 570  */
 571 struct net_device *nr_dev_first(void)
 572 {
 573         struct net_device *dev, *first = NULL;
 574 
 575         rcu_read_lock();
 576         for_each_netdev_rcu(&init_net, dev) {
 577                 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM)
 578                         if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
 579                                 first = dev;
 580         }
 581         if (first)
 582                 dev_hold(first);
 583         rcu_read_unlock();
 584 
 585         return first;
 586 }
 587 
 588 /*
 589  *      Find the NET/ROM device for the given callsign.
 590  */
 591 struct net_device *nr_dev_get(ax25_address *addr)
 592 {
 593         struct net_device *dev;
 594 
 595         rcu_read_lock();
 596         for_each_netdev_rcu(&init_net, dev) {
 597                 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM &&
 598                     ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) {
 599                         dev_hold(dev);
 600                         goto out;
 601                 }
 602         }
 603         dev = NULL;
 604 out:
 605         rcu_read_unlock();
 606         return dev;
 607 }
 608 
 609 static ax25_digi *nr_call_to_digi(ax25_digi *digi, int ndigis,
 610         ax25_address *digipeaters)
 611 {
 612         int i;
 613 
 614         if (ndigis == 0)
 615                 return NULL;
 616 
 617         for (i = 0; i < ndigis; i++) {
 618                 digi->calls[i]    = digipeaters[i];
 619                 digi->repeated[i] = 0;
 620         }
 621 
 622         digi->ndigi      = ndigis;
 623         digi->lastrepeat = -1;
 624 
 625         return digi;
 626 }
 627 
 628 /*
 629  *      Handle the ioctls that control the routing functions.
 630  */
 631 int nr_rt_ioctl(unsigned int cmd, void __user *arg)
 632 {
 633         struct nr_route_struct nr_route;
 634         struct net_device *dev;
 635         ax25_digi digi;
 636         int ret;
 637 
 638         switch (cmd) {
 639         case SIOCADDRT:
 640                 if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
 641                         return -EFAULT;
 642                 if (nr_route.ndigis > AX25_MAX_DIGIS)
 643                         return -EINVAL;
 644                 if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
 645                         return -EINVAL;
 646                 switch (nr_route.type) {
 647                 case NETROM_NODE:
 648                         if (strnlen(nr_route.mnemonic, 7) == 7) {
 649                                 ret = -EINVAL;
 650                                 break;
 651                         }
 652 
 653                         ret = nr_add_node(&nr_route.callsign,
 654                                 nr_route.mnemonic,
 655                                 &nr_route.neighbour,
 656                                 nr_call_to_digi(&digi, nr_route.ndigis,
 657                                                 nr_route.digipeaters),
 658                                 dev, nr_route.quality,
 659                                 nr_route.obs_count);
 660                         break;
 661                 case NETROM_NEIGH:
 662                         ret = nr_add_neigh(&nr_route.callsign,
 663                                 nr_call_to_digi(&digi, nr_route.ndigis,
 664                                                 nr_route.digipeaters),
 665                                 dev, nr_route.quality);
 666                         break;
 667                 default:
 668                         ret = -EINVAL;
 669                 }
 670                 dev_put(dev);
 671                 return ret;
 672 
 673         case SIOCDELRT:
 674                 if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
 675                         return -EFAULT;
 676                 if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
 677                         return -EINVAL;
 678                 switch (nr_route.type) {
 679                 case NETROM_NODE:
 680                         ret = nr_del_node(&nr_route.callsign,
 681                                 &nr_route.neighbour, dev);
 682                         break;
 683                 case NETROM_NEIGH:
 684                         ret = nr_del_neigh(&nr_route.callsign,
 685                                 dev, nr_route.quality);
 686                         break;
 687                 default:
 688                         ret = -EINVAL;
 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  */
 707 void nr_link_failed(ax25_cb *ax25, int reason)
 708 {
 709         struct nr_neigh *s, *nr_neigh = NULL;
 710         struct nr_node  *nr_node = NULL;
 711 
 712         spin_lock_bh(&nr_neigh_list_lock);
 713         nr_neigh_for_each(s, &nr_neigh_list) {
 714                 if (s->ax25 == ax25) {
 715                         nr_neigh_hold(s);
 716                         nr_neigh = s;
 717                         break;
 718                 }
 719         }
 720         spin_unlock_bh(&nr_neigh_list_lock);
 721 
 722         if (nr_neigh == NULL)
 723                 return;
 724 
 725         nr_neigh->ax25 = NULL;
 726         ax25_cb_put(ax25);
 727 
 728         if (++nr_neigh->failed < sysctl_netrom_link_fails_count) {
 729                 nr_neigh_put(nr_neigh);
 730                 return;
 731         }
 732         spin_lock_bh(&nr_node_list_lock);
 733         nr_node_for_each(nr_node, &nr_node_list) {
 734                 nr_node_lock(nr_node);
 735                 if (nr_node->which < nr_node->count &&
 736                     nr_node->routes[nr_node->which].neighbour == nr_neigh)
 737                         nr_node->which++;
 738                 nr_node_unlock(nr_node);
 739         }
 740         spin_unlock_bh(&nr_node_list_lock);
 741         nr_neigh_put(nr_neigh);
 742 }
 743 
 744 /*
 745  *      Route a frame to an appropriate AX.25 connection. A NULL ax25_cb
 746  *      indicates an internally generated frame.
 747  */
 748 int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
 749 {
 750         ax25_address *nr_src, *nr_dest;
 751         struct nr_neigh *nr_neigh;
 752         struct nr_node  *nr_node;
 753         struct net_device *dev;
 754         unsigned char *dptr;
 755         ax25_cb *ax25s;
 756         int ret;
 757         struct sk_buff *skbn;
 758 
 759 
 760         nr_src  = (ax25_address *)(skb->data + 0);
 761         nr_dest = (ax25_address *)(skb->data + 7);
 762 
 763         if (ax25 != NULL) {
 764                 ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
 765                                   ax25->ax25_dev->dev, 0,
 766                                   sysctl_netrom_obsolescence_count_initialiser);
 767                 if (ret)
 768                         return ret;
 769         }
 770 
 771         if ((dev = nr_dev_get(nr_dest)) != NULL) {      /* Its for me */
 772                 if (ax25 == NULL)                       /* Its from me */
 773                         ret = nr_loopback_queue(skb);
 774                 else
 775                         ret = nr_rx_frame(skb, dev);
 776                 dev_put(dev);
 777                 return ret;
 778         }
 779 
 780         if (!sysctl_netrom_routing_control && ax25 != NULL)
 781                 return 0;
 782 
 783         /* Its Time-To-Live has expired */
 784         if (skb->data[14] == 1) {
 785                 return 0;
 786         }
 787 
 788         nr_node = nr_node_get(nr_dest);
 789         if (nr_node == NULL)
 790                 return 0;
 791         nr_node_lock(nr_node);
 792 
 793         if (nr_node->which >= nr_node->count) {
 794                 nr_node_unlock(nr_node);
 795                 nr_node_put(nr_node);
 796                 return 0;
 797         }
 798 
 799         nr_neigh = nr_node->routes[nr_node->which].neighbour;
 800 
 801         if ((dev = nr_dev_first()) == NULL) {
 802                 nr_node_unlock(nr_node);
 803                 nr_node_put(nr_node);
 804                 return 0;
 805         }
 806 
 807         /* We are going to change the netrom headers so we should get our
 808            own skb, we also did not know until now how much header space
 809            we had to reserve... - RXQ */
 810         if ((skbn=skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC)) == NULL) {
 811                 nr_node_unlock(nr_node);
 812                 nr_node_put(nr_node);
 813                 dev_put(dev);
 814                 return 0;
 815         }
 816         kfree_skb(skb);
 817         skb=skbn;
 818         skb->data[14]--;
 819 
 820         dptr  = skb_push(skb, 1);
 821         *dptr = AX25_P_NETROM;
 822 
 823         ax25s = nr_neigh->ax25;
 824         nr_neigh->ax25 = ax25_send_frame(skb, 256,
 825                                          (ax25_address *)dev->dev_addr,
 826                                          &nr_neigh->callsign,
 827                                          nr_neigh->digipeat, nr_neigh->dev);
 828         if (ax25s)
 829                 ax25_cb_put(ax25s);
 830 
 831         dev_put(dev);
 832         ret = (nr_neigh->ax25 != NULL);
 833         nr_node_unlock(nr_node);
 834         nr_node_put(nr_node);
 835 
 836         return ret;
 837 }
 838 
 839 #ifdef CONFIG_PROC_FS
 840 
 841 static void *nr_node_start(struct seq_file *seq, loff_t *pos)
 842 {
 843         spin_lock_bh(&nr_node_list_lock);
 844         return seq_hlist_start_head(&nr_node_list, *pos);
 845 }
 846 
 847 static void *nr_node_next(struct seq_file *seq, void *v, loff_t *pos)
 848 {
 849         return seq_hlist_next(v, &nr_node_list, pos);
 850 }
 851 
 852 static void nr_node_stop(struct seq_file *seq, void *v)
 853 {
 854         spin_unlock_bh(&nr_node_list_lock);
 855 }
 856 
 857 static int nr_node_show(struct seq_file *seq, void *v)
 858 {
 859         char buf[11];
 860         int i;
 861 
 862         if (v == SEQ_START_TOKEN)
 863                 seq_puts(seq,
 864                          "callsign  mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
 865         else {
 866                 struct nr_node *nr_node = hlist_entry(v, struct nr_node,
 867                                                       node_node);
 868 
 869                 nr_node_lock(nr_node);
 870                 seq_printf(seq, "%-9s %-7s  %d %d",
 871                         ax2asc(buf, &nr_node->callsign),
 872                         (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
 873                         nr_node->which + 1,
 874                         nr_node->count);
 875 
 876                 for (i = 0; i < nr_node->count; i++) {
 877                         seq_printf(seq, "  %3d   %d %05d",
 878                                 nr_node->routes[i].quality,
 879                                 nr_node->routes[i].obs_count,
 880                                 nr_node->routes[i].neighbour->number);
 881                 }
 882                 nr_node_unlock(nr_node);
 883 
 884                 seq_puts(seq, "\n");
 885         }
 886         return 0;
 887 }
 888 
 889 const struct seq_operations nr_node_seqops = {
 890         .start = nr_node_start,
 891         .next = nr_node_next,
 892         .stop = nr_node_stop,
 893         .show = nr_node_show,
 894 };
 895 
 896 static void *nr_neigh_start(struct seq_file *seq, loff_t *pos)
 897 {
 898         spin_lock_bh(&nr_neigh_list_lock);
 899         return seq_hlist_start_head(&nr_neigh_list, *pos);
 900 }
 901 
 902 static void *nr_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
 903 {
 904         return seq_hlist_next(v, &nr_neigh_list, pos);
 905 }
 906 
 907 static void nr_neigh_stop(struct seq_file *seq, void *v)
 908 {
 909         spin_unlock_bh(&nr_neigh_list_lock);
 910 }
 911 
 912 static int nr_neigh_show(struct seq_file *seq, void *v)
 913 {
 914         char buf[11];
 915         int i;
 916 
 917         if (v == SEQ_START_TOKEN)
 918                 seq_puts(seq, "addr  callsign  dev  qual lock count failed digipeaters\n");
 919         else {
 920                 struct nr_neigh *nr_neigh;
 921 
 922                 nr_neigh = hlist_entry(v, struct nr_neigh, neigh_node);
 923                 seq_printf(seq, "%05d %-9s %-4s  %3d    %d   %3d    %3d",
 924                         nr_neigh->number,
 925                         ax2asc(buf, &nr_neigh->callsign),
 926                         nr_neigh->dev ? nr_neigh->dev->name : "???",
 927                         nr_neigh->quality,
 928                         nr_neigh->locked,
 929                         nr_neigh->count,
 930                         nr_neigh->failed);
 931 
 932                 if (nr_neigh->digipeat != NULL) {
 933                         for (i = 0; i < nr_neigh->digipeat->ndigi; i++)
 934                                 seq_printf(seq, " %s",
 935                                            ax2asc(buf, &nr_neigh->digipeat->calls[i]));
 936                 }
 937 
 938                 seq_puts(seq, "\n");
 939         }
 940         return 0;
 941 }
 942 
 943 const struct seq_operations nr_neigh_seqops = {
 944         .start = nr_neigh_start,
 945         .next = nr_neigh_next,
 946         .stop = nr_neigh_stop,
 947         .show = nr_neigh_show,
 948 };
 949 #endif
 950 
 951 /*
 952  *      Free all memory associated with the nodes and routes lists.
 953  */
 954 void nr_rt_free(void)
 955 {
 956         struct nr_neigh *s = NULL;
 957         struct nr_node  *t = NULL;
 958         struct hlist_node *nodet;
 959 
 960         spin_lock_bh(&nr_neigh_list_lock);
 961         spin_lock_bh(&nr_node_list_lock);
 962         nr_node_for_each_safe(t, nodet, &nr_node_list) {
 963                 nr_node_lock(t);
 964                 nr_remove_node_locked(t);
 965                 nr_node_unlock(t);
 966         }
 967         nr_neigh_for_each_safe(s, nodet, &nr_neigh_list) {
 968                 while(s->count) {
 969                         s->count--;
 970                         nr_neigh_put(s);
 971                 }
 972                 nr_remove_neigh_locked(s);
 973         }
 974         spin_unlock_bh(&nr_node_list_lock);
 975         spin_unlock_bh(&nr_neigh_list_lock);
 976 }

/* [<][>][^][v][top][bottom][index][help] */