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