linux/net/netrom/nr_route.c
<<
>>
Prefs
   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
  37static unsigned int nr_neigh_no = 1;
  38
  39static HLIST_HEAD(nr_node_list);
  40static DEFINE_SPINLOCK(nr_node_list_lock);
  41static HLIST_HEAD(nr_neigh_list);
  42static DEFINE_SPINLOCK(nr_neigh_list_lock);
  43
  44static 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
  60static 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
  78static void nr_remove_neigh(struct nr_neigh *);
  79
  80/*      re-sort the routes in quality order.    */
  81static 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 */
  97static 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                fallthrough;
 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
 287static 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
 296static 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
 303static 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
 312static 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 */
 323static 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                                        fallthrough;
 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 */
 382static 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 */
 430static 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 */
 453static 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 */
 509void 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                                                        fallthrough;
 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 */
 554static 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 */
 571struct 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 */
 591struct 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;
 604out:
 605        rcu_read_unlock();
 606        return dev;
 607}
 608
 609static 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 */
 631int 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 */
 707void 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 */
 748int 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
 841static void *nr_node_start(struct seq_file *seq, loff_t *pos)
 842        __acquires(&nr_node_list_lock)
 843{
 844        spin_lock_bh(&nr_node_list_lock);
 845        return seq_hlist_start_head(&nr_node_list, *pos);
 846}
 847
 848static void *nr_node_next(struct seq_file *seq, void *v, loff_t *pos)
 849{
 850        return seq_hlist_next(v, &nr_node_list, pos);
 851}
 852
 853static void nr_node_stop(struct seq_file *seq, void *v)
 854        __releases(&nr_node_list_lock)
 855{
 856        spin_unlock_bh(&nr_node_list_lock);
 857}
 858
 859static int nr_node_show(struct seq_file *seq, void *v)
 860{
 861        char buf[11];
 862        int i;
 863
 864        if (v == SEQ_START_TOKEN)
 865                seq_puts(seq,
 866                         "callsign  mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
 867        else {
 868                struct nr_node *nr_node = hlist_entry(v, struct nr_node,
 869                                                      node_node);
 870
 871                nr_node_lock(nr_node);
 872                seq_printf(seq, "%-9s %-7s  %d %d",
 873                        ax2asc(buf, &nr_node->callsign),
 874                        (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
 875                        nr_node->which + 1,
 876                        nr_node->count);
 877
 878                for (i = 0; i < nr_node->count; i++) {
 879                        seq_printf(seq, "  %3d   %d %05d",
 880                                nr_node->routes[i].quality,
 881                                nr_node->routes[i].obs_count,
 882                                nr_node->routes[i].neighbour->number);
 883                }
 884                nr_node_unlock(nr_node);
 885
 886                seq_puts(seq, "\n");
 887        }
 888        return 0;
 889}
 890
 891const struct seq_operations nr_node_seqops = {
 892        .start = nr_node_start,
 893        .next = nr_node_next,
 894        .stop = nr_node_stop,
 895        .show = nr_node_show,
 896};
 897
 898static void *nr_neigh_start(struct seq_file *seq, loff_t *pos)
 899        __acquires(&nr_neigh_list_lock)
 900{
 901        spin_lock_bh(&nr_neigh_list_lock);
 902        return seq_hlist_start_head(&nr_neigh_list, *pos);
 903}
 904
 905static void *nr_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
 906{
 907        return seq_hlist_next(v, &nr_neigh_list, pos);
 908}
 909
 910static void nr_neigh_stop(struct seq_file *seq, void *v)
 911        __releases(&nr_neigh_list_lock)
 912{
 913        spin_unlock_bh(&nr_neigh_list_lock);
 914}
 915
 916static int nr_neigh_show(struct seq_file *seq, void *v)
 917{
 918        char buf[11];
 919        int i;
 920
 921        if (v == SEQ_START_TOKEN)
 922                seq_puts(seq, "addr  callsign  dev  qual lock count failed digipeaters\n");
 923        else {
 924                struct nr_neigh *nr_neigh;
 925
 926                nr_neigh = hlist_entry(v, struct nr_neigh, neigh_node);
 927                seq_printf(seq, "%05d %-9s %-4s  %3d    %d   %3d    %3d",
 928                        nr_neigh->number,
 929                        ax2asc(buf, &nr_neigh->callsign),
 930                        nr_neigh->dev ? nr_neigh->dev->name : "???",
 931                        nr_neigh->quality,
 932                        nr_neigh->locked,
 933                        nr_neigh->count,
 934                        nr_neigh->failed);
 935
 936                if (nr_neigh->digipeat != NULL) {
 937                        for (i = 0; i < nr_neigh->digipeat->ndigi; i++)
 938                                seq_printf(seq, " %s",
 939                                           ax2asc(buf, &nr_neigh->digipeat->calls[i]));
 940                }
 941
 942                seq_puts(seq, "\n");
 943        }
 944        return 0;
 945}
 946
 947const struct seq_operations nr_neigh_seqops = {
 948        .start = nr_neigh_start,
 949        .next = nr_neigh_next,
 950        .stop = nr_neigh_stop,
 951        .show = nr_neigh_show,
 952};
 953#endif
 954
 955/*
 956 *      Free all memory associated with the nodes and routes lists.
 957 */
 958void nr_rt_free(void)
 959{
 960        struct nr_neigh *s = NULL;
 961        struct nr_node  *t = NULL;
 962        struct hlist_node *nodet;
 963
 964        spin_lock_bh(&nr_neigh_list_lock);
 965        spin_lock_bh(&nr_node_list_lock);
 966        nr_node_for_each_safe(t, nodet, &nr_node_list) {
 967                nr_node_lock(t);
 968                nr_remove_node_locked(t);
 969                nr_node_unlock(t);
 970        }
 971        nr_neigh_for_each_safe(s, nodet, &nr_neigh_list) {
 972                while(s->count) {
 973                        s->count--;
 974                        nr_neigh_put(s);
 975                }
 976                nr_remove_neigh_locked(s);
 977        }
 978        spin_unlock_bh(&nr_node_list_lock);
 979        spin_unlock_bh(&nr_neigh_list_lock);
 980}
 981