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