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