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 <asm/system.h>
  30#include <linux/fcntl.h>
  31#include <linux/termios.h>      /* For TIOCINQ/OUTQ */
  32#include <linux/mm.h>
  33#include <linux/interrupt.h>
  34#include <linux/notifier.h>
  35#include <linux/netfilter.h>
  36#include <linux/init.h>
  37#include <linux/spinlock.h>
  38#include <net/netrom.h>
  39#include <linux/seq_file.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        struct hlist_node *node;
  53
  54        spin_lock_bh(&nr_node_list_lock);
  55        nr_node_for_each(nr_node, node, &nr_node_list)
  56                if (ax25cmp(callsign, &nr_node->callsign) == 0) {
  57                        nr_node_hold(nr_node);
  58                        found = nr_node;
  59                        break;
  60                }
  61        spin_unlock_bh(&nr_node_list_lock);
  62        return found;
  63}
  64
  65static struct nr_neigh *nr_neigh_get_dev(ax25_address *callsign,
  66                                         struct net_device *dev)
  67{
  68        struct nr_neigh *found = NULL;
  69        struct nr_neigh *nr_neigh;
  70        struct hlist_node *node;
  71
  72        spin_lock_bh(&nr_neigh_list_lock);
  73        nr_neigh_for_each(nr_neigh, node, &nr_neigh_list)
  74                if (ax25cmp(callsign, &nr_neigh->callsign) == 0 &&
  75                    nr_neigh->dev == dev) {
  76                        nr_neigh_hold(nr_neigh);
  77                        found = nr_neigh;
  78                        break;
  79                }
  80        spin_unlock_bh(&nr_neigh_list_lock);
  81        return found;
  82}
  83
  84static void nr_remove_neigh(struct nr_neigh *);
  85
  86/*
  87 *      Add a new route to a node, and in the process add the node and the
  88 *      neighbour if it is new.
  89 */
  90static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
  91        ax25_address *ax25, ax25_digi *ax25_digi, struct net_device *dev,
  92        int quality, int obs_count)
  93{
  94        struct nr_node  *nr_node;
  95        struct nr_neigh *nr_neigh;
  96        struct nr_route nr_route;
  97        int i, found;
  98        struct net_device *odev;
  99
 100        if ((odev=nr_dev_get(nr)) != NULL) {    /* Can't add routes to ourself */
 101                dev_put(odev);
 102                return -EINVAL;
 103        }
 104
 105        nr_node = nr_node_get(nr);
 106
 107        nr_neigh = nr_neigh_get_dev(ax25, dev);
 108
 109        /*
 110         * The L2 link to a neighbour has failed in the past
 111         * and now a frame comes from this neighbour. We assume
 112         * it was a temporary trouble with the link and reset the
 113         * routes now (and not wait for a node broadcast).
 114         */
 115        if (nr_neigh != NULL && nr_neigh->failed != 0 && quality == 0) {
 116                struct nr_node *nr_nodet;
 117                struct hlist_node *node;
 118
 119                spin_lock_bh(&nr_node_list_lock);
 120                nr_node_for_each(nr_nodet, node, &nr_node_list) {
 121                        nr_node_lock(nr_nodet);
 122                        for (i = 0; i < nr_nodet->count; i++)
 123                                if (nr_nodet->routes[i].neighbour == nr_neigh)
 124                                        if (i < nr_nodet->which)
 125                                                nr_nodet->which = i;
 126                        nr_node_unlock(nr_nodet);
 127                }
 128                spin_unlock_bh(&nr_node_list_lock);
 129        }
 130
 131        if (nr_neigh != NULL)
 132                nr_neigh->failed = 0;
 133
 134        if (quality == 0 && nr_neigh != NULL && nr_node != NULL) {
 135                nr_neigh_put(nr_neigh);
 136                nr_node_put(nr_node);
 137                return 0;
 138        }
 139
 140        if (nr_neigh == NULL) {
 141                if ((nr_neigh = kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL) {
 142                        if (nr_node)
 143                                nr_node_put(nr_node);
 144                        return -ENOMEM;
 145                }
 146
 147                nr_neigh->callsign = *ax25;
 148                nr_neigh->digipeat = NULL;
 149                nr_neigh->ax25     = NULL;
 150                nr_neigh->dev      = dev;
 151                nr_neigh->quality  = sysctl_netrom_default_path_quality;
 152                nr_neigh->locked   = 0;
 153                nr_neigh->count    = 0;
 154                nr_neigh->number   = nr_neigh_no++;
 155                nr_neigh->failed   = 0;
 156                atomic_set(&nr_neigh->refcount, 1);
 157
 158                if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
 159                        nr_neigh->digipeat = kmemdup(ax25_digi,
 160                                                     sizeof(*ax25_digi),
 161                                                     GFP_KERNEL);
 162                        if (nr_neigh->digipeat == NULL) {
 163                                kfree(nr_neigh);
 164                                if (nr_node)
 165                                        nr_node_put(nr_node);
 166                                return -ENOMEM;
 167                        }
 168                }
 169
 170                spin_lock_bh(&nr_neigh_list_lock);
 171                hlist_add_head(&nr_neigh->neigh_node, &nr_neigh_list);
 172                nr_neigh_hold(nr_neigh);
 173                spin_unlock_bh(&nr_neigh_list_lock);
 174        }
 175
 176        if (quality != 0 && ax25cmp(nr, ax25) == 0 && !nr_neigh->locked)
 177                nr_neigh->quality = quality;
 178
 179        if (nr_node == NULL) {
 180                if ((nr_node = kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL) {
 181                        if (nr_neigh)
 182                                nr_neigh_put(nr_neigh);
 183                        return -ENOMEM;
 184                }
 185
 186                nr_node->callsign = *nr;
 187                strcpy(nr_node->mnemonic, mnemonic);
 188
 189                nr_node->which = 0;
 190                nr_node->count = 1;
 191                atomic_set(&nr_node->refcount, 1);
 192                spin_lock_init(&nr_node->node_lock);
 193
 194                nr_node->routes[0].quality   = quality;
 195                nr_node->routes[0].obs_count = obs_count;
 196                nr_node->routes[0].neighbour = nr_neigh;
 197
 198                nr_neigh_hold(nr_neigh);
 199                nr_neigh->count++;
 200
 201                spin_lock_bh(&nr_node_list_lock);
 202                hlist_add_head(&nr_node->node_node, &nr_node_list);
 203                /* refcount initialized at 1 */
 204                spin_unlock_bh(&nr_node_list_lock);
 205
 206                return 0;
 207        }
 208        nr_node_lock(nr_node);
 209
 210        if (quality != 0)
 211                strcpy(nr_node->mnemonic, mnemonic);
 212
 213        for (found = 0, i = 0; i < nr_node->count; i++) {
 214                if (nr_node->routes[i].neighbour == nr_neigh) {
 215                        nr_node->routes[i].quality   = quality;
 216                        nr_node->routes[i].obs_count = obs_count;
 217                        found = 1;
 218                        break;
 219                }
 220        }
 221
 222        if (!found) {
 223                /* We have space at the bottom, slot it in */
 224                if (nr_node->count < 3) {
 225                        nr_node->routes[2] = nr_node->routes[1];
 226                        nr_node->routes[1] = nr_node->routes[0];
 227
 228                        nr_node->routes[0].quality   = quality;
 229                        nr_node->routes[0].obs_count = obs_count;
 230                        nr_node->routes[0].neighbour = nr_neigh;
 231
 232                        nr_node->which++;
 233                        nr_node->count++;
 234                        nr_neigh_hold(nr_neigh);
 235                        nr_neigh->count++;
 236                } else {
 237                        /* It must be better than the worst */
 238                        if (quality > nr_node->routes[2].quality) {
 239                                nr_node->routes[2].neighbour->count--;
 240                                nr_neigh_put(nr_node->routes[2].neighbour);
 241
 242                                if (nr_node->routes[2].neighbour->count == 0 && !nr_node->routes[2].neighbour->locked)
 243                                        nr_remove_neigh(nr_node->routes[2].neighbour);
 244
 245                                nr_node->routes[2].quality   = quality;
 246                                nr_node->routes[2].obs_count = obs_count;
 247                                nr_node->routes[2].neighbour = nr_neigh;
 248
 249                                nr_neigh_hold(nr_neigh);
 250                                nr_neigh->count++;
 251                        }
 252                }
 253        }
 254
 255        /* Now re-sort the routes in quality order */
 256        switch (nr_node->count) {
 257        case 3:
 258                if (nr_node->routes[1].quality > nr_node->routes[0].quality) {
 259                        switch (nr_node->which) {
 260                                case 0:  nr_node->which = 1; break;
 261                                case 1:  nr_node->which = 0; break;
 262                                default: 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 *node, *nodet;
 486        int i;
 487
 488        spin_lock_bh(&nr_node_list_lock);
 489        nr_node_for_each_safe(s, node, 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                                        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 *node, *nodet, *node2, *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, node, nodet, &nr_neigh_list) {
 545                if (s->dev == dev) {
 546                        spin_lock_bh(&nr_node_list_lock);
 547                        nr_node_for_each_safe(t, node2, 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 ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
 669                        return -EINVAL;
 670                if (nr_route.ndigis < 0 || nr_route.ndigis > AX25_MAX_DIGIS) {
 671                        dev_put(dev);
 672                        return -EINVAL;
 673                }
 674                switch (nr_route.type) {
 675                case NETROM_NODE:
 676                        ret = nr_add_node(&nr_route.callsign,
 677                                nr_route.mnemonic,
 678                                &nr_route.neighbour,
 679                                nr_call_to_digi(&digi, nr_route.ndigis,
 680                                                nr_route.digipeaters),
 681                                dev, nr_route.quality,
 682                                nr_route.obs_count);
 683                        break;
 684                case NETROM_NEIGH:
 685                        ret = nr_add_neigh(&nr_route.callsign,
 686                                nr_call_to_digi(&digi, nr_route.ndigis,
 687                                                nr_route.digipeaters),
 688                                dev, nr_route.quality);
 689                        break;
 690                default:
 691                        ret = -EINVAL;
 692                }
 693                dev_put(dev);
 694                return ret;
 695
 696        case SIOCDELRT:
 697                if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
 698                        return -EFAULT;
 699                if ((dev = nr_ax25_dev_get(nr_route.device)) == NULL)
 700                        return -EINVAL;
 701                switch (nr_route.type) {
 702                case NETROM_NODE:
 703                        ret = nr_del_node(&nr_route.callsign,
 704                                &nr_route.neighbour, dev);
 705                        break;
 706                case NETROM_NEIGH:
 707                        ret = nr_del_neigh(&nr_route.callsign,
 708                                dev, nr_route.quality);
 709                        break;
 710                default:
 711                        ret = -EINVAL;
 712                }
 713                dev_put(dev);
 714                return ret;
 715
 716        case SIOCNRDECOBS:
 717                return nr_dec_obs();
 718
 719        default:
 720                return -EINVAL;
 721        }
 722
 723        return 0;
 724}
 725
 726/*
 727 *      A level 2 link has timed out, therefore it appears to be a poor link,
 728 *      then don't use that neighbour until it is reset.
 729 */
 730void nr_link_failed(ax25_cb *ax25, int reason)
 731{
 732        struct nr_neigh *s, *nr_neigh = NULL;
 733        struct hlist_node *node;
 734        struct nr_node  *nr_node = NULL;
 735
 736        spin_lock_bh(&nr_neigh_list_lock);
 737        nr_neigh_for_each(s, node, &nr_neigh_list) {
 738                if (s->ax25 == ax25) {
 739                        nr_neigh_hold(s);
 740                        nr_neigh = s;
 741                        break;
 742                }
 743        }
 744        spin_unlock_bh(&nr_neigh_list_lock);
 745
 746        if (nr_neigh == NULL)
 747                return;
 748
 749        nr_neigh->ax25 = NULL;
 750        ax25_cb_put(ax25);
 751
 752        if (++nr_neigh->failed < sysctl_netrom_link_fails_count) {
 753                nr_neigh_put(nr_neigh);
 754                return;
 755        }
 756        spin_lock_bh(&nr_node_list_lock);
 757        nr_node_for_each(nr_node, node, &nr_node_list) {
 758                nr_node_lock(nr_node);
 759                if (nr_node->which < nr_node->count &&
 760                    nr_node->routes[nr_node->which].neighbour == nr_neigh)
 761                        nr_node->which++;
 762                nr_node_unlock(nr_node);
 763        }
 764        spin_unlock_bh(&nr_node_list_lock);
 765        nr_neigh_put(nr_neigh);
 766}
 767
 768/*
 769 *      Route a frame to an appropriate AX.25 connection. A NULL ax25_cb
 770 *      indicates an internally generated frame.
 771 */
 772int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
 773{
 774        ax25_address *nr_src, *nr_dest;
 775        struct nr_neigh *nr_neigh;
 776        struct nr_node  *nr_node;
 777        struct net_device *dev;
 778        unsigned char *dptr;
 779        ax25_cb *ax25s;
 780        int ret;
 781        struct sk_buff *skbn;
 782
 783
 784        nr_src  = (ax25_address *)(skb->data + 0);
 785        nr_dest = (ax25_address *)(skb->data + 7);
 786
 787        if (ax25 != NULL) {
 788                ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
 789                                  ax25->ax25_dev->dev, 0,
 790                                  sysctl_netrom_obsolescence_count_initialiser);
 791                if (ret)
 792                        return ret;
 793        }
 794
 795        if ((dev = nr_dev_get(nr_dest)) != NULL) {      /* Its for me */
 796                if (ax25 == NULL)                       /* Its from me */
 797                        ret = nr_loopback_queue(skb);
 798                else
 799                        ret = nr_rx_frame(skb, dev);
 800                dev_put(dev);
 801                return ret;
 802        }
 803
 804        if (!sysctl_netrom_routing_control && ax25 != NULL)
 805                return 0;
 806
 807        /* Its Time-To-Live has expired */
 808        if (skb->data[14] == 1) {
 809                return 0;
 810        }
 811
 812        nr_node = nr_node_get(nr_dest);
 813        if (nr_node == NULL)
 814                return 0;
 815        nr_node_lock(nr_node);
 816
 817        if (nr_node->which >= nr_node->count) {
 818                nr_node_unlock(nr_node);
 819                nr_node_put(nr_node);
 820                return 0;
 821        }
 822
 823        nr_neigh = nr_node->routes[nr_node->which].neighbour;
 824
 825        if ((dev = nr_dev_first()) == NULL) {
 826                nr_node_unlock(nr_node);
 827                nr_node_put(nr_node);
 828                return 0;
 829        }
 830
 831        /* We are going to change the netrom headers so we should get our
 832           own skb, we also did not know until now how much header space
 833           we had to reserve... - RXQ */
 834        if ((skbn=skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC)) == NULL) {
 835                nr_node_unlock(nr_node);
 836                nr_node_put(nr_node);
 837                dev_put(dev);
 838                return 0;
 839        }
 840        kfree_skb(skb);
 841        skb=skbn;
 842        skb->data[14]--;
 843
 844        dptr  = skb_push(skb, 1);
 845        *dptr = AX25_P_NETROM;
 846
 847        ax25s = nr_neigh->ax25;
 848        nr_neigh->ax25 = ax25_send_frame(skb, 256,
 849                                         (ax25_address *)dev->dev_addr,
 850                                         &nr_neigh->callsign,
 851                                         nr_neigh->digipeat, nr_neigh->dev);
 852        if (ax25s)
 853                ax25_cb_put(ax25s);
 854
 855        dev_put(dev);
 856        ret = (nr_neigh->ax25 != NULL);
 857        nr_node_unlock(nr_node);
 858        nr_node_put(nr_node);
 859
 860        return ret;
 861}
 862
 863#ifdef CONFIG_PROC_FS
 864
 865static void *nr_node_start(struct seq_file *seq, loff_t *pos)
 866{
 867        spin_lock_bh(&nr_node_list_lock);
 868        return seq_hlist_start_head(&nr_node_list, *pos);
 869}
 870
 871static void *nr_node_next(struct seq_file *seq, void *v, loff_t *pos)
 872{
 873        return seq_hlist_next(v, &nr_node_list, pos);
 874}
 875
 876static void nr_node_stop(struct seq_file *seq, void *v)
 877{
 878        spin_unlock_bh(&nr_node_list_lock);
 879}
 880
 881static int nr_node_show(struct seq_file *seq, void *v)
 882{
 883        char buf[11];
 884        int i;
 885
 886        if (v == SEQ_START_TOKEN)
 887                seq_puts(seq,
 888                         "callsign  mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
 889        else {
 890                struct nr_node *nr_node = hlist_entry(v, struct nr_node,
 891                                                      node_node);
 892
 893                nr_node_lock(nr_node);
 894                seq_printf(seq, "%-9s %-7s  %d %d",
 895                        ax2asc(buf, &nr_node->callsign),
 896                        (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
 897                        nr_node->which + 1,
 898                        nr_node->count);
 899
 900                for (i = 0; i < nr_node->count; i++) {
 901                        seq_printf(seq, "  %3d   %d %05d",
 902                                nr_node->routes[i].quality,
 903                                nr_node->routes[i].obs_count,
 904                                nr_node->routes[i].neighbour->number);
 905                }
 906                nr_node_unlock(nr_node);
 907
 908                seq_puts(seq, "\n");
 909        }
 910        return 0;
 911}
 912
 913static const struct seq_operations nr_node_seqops = {
 914        .start = nr_node_start,
 915        .next = nr_node_next,
 916        .stop = nr_node_stop,
 917        .show = nr_node_show,
 918};
 919
 920static int nr_node_info_open(struct inode *inode, struct file *file)
 921{
 922        return seq_open(file, &nr_node_seqops);
 923}
 924
 925const struct file_operations nr_nodes_fops = {
 926        .owner = THIS_MODULE,
 927        .open = nr_node_info_open,
 928        .read = seq_read,
 929        .llseek = seq_lseek,
 930        .release = seq_release,
 931};
 932
 933static void *nr_neigh_start(struct seq_file *seq, loff_t *pos)
 934{
 935        spin_lock_bh(&nr_neigh_list_lock);
 936        return seq_hlist_start_head(&nr_neigh_list, *pos);
 937}
 938
 939static void *nr_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
 940{
 941        return seq_hlist_next(v, &nr_neigh_list, pos);
 942}
 943
 944static void nr_neigh_stop(struct seq_file *seq, void *v)
 945{
 946        spin_unlock_bh(&nr_neigh_list_lock);
 947}
 948
 949static int nr_neigh_show(struct seq_file *seq, void *v)
 950{
 951        char buf[11];
 952        int i;
 953
 954        if (v == SEQ_START_TOKEN)
 955                seq_puts(seq, "addr  callsign  dev  qual lock count failed digipeaters\n");
 956        else {
 957                struct nr_neigh *nr_neigh;
 958
 959                nr_neigh = hlist_entry(v, struct nr_neigh, neigh_node);
 960                seq_printf(seq, "%05d %-9s %-4s  %3d    %d   %3d    %3d",
 961                        nr_neigh->number,
 962                        ax2asc(buf, &nr_neigh->callsign),
 963                        nr_neigh->dev ? nr_neigh->dev->name : "???",
 964                        nr_neigh->quality,
 965                        nr_neigh->locked,
 966                        nr_neigh->count,
 967                        nr_neigh->failed);
 968
 969                if (nr_neigh->digipeat != NULL) {
 970                        for (i = 0; i < nr_neigh->digipeat->ndigi; i++)
 971                                seq_printf(seq, " %s",
 972                                           ax2asc(buf, &nr_neigh->digipeat->calls[i]));
 973                }
 974
 975                seq_puts(seq, "\n");
 976        }
 977        return 0;
 978}
 979
 980static const struct seq_operations nr_neigh_seqops = {
 981        .start = nr_neigh_start,
 982        .next = nr_neigh_next,
 983        .stop = nr_neigh_stop,
 984        .show = nr_neigh_show,
 985};
 986
 987static int nr_neigh_info_open(struct inode *inode, struct file *file)
 988{
 989        return seq_open(file, &nr_neigh_seqops);
 990}
 991
 992const struct file_operations nr_neigh_fops = {
 993        .owner = THIS_MODULE,
 994        .open = nr_neigh_info_open,
 995        .read = seq_read,
 996        .llseek = seq_lseek,
 997        .release = seq_release,
 998};
 999
1000#endif
1001
1002/*
1003 *      Free all memory associated with the nodes and routes lists.
1004 */
1005void __exit nr_rt_free(void)
1006{
1007        struct nr_neigh *s = NULL;
1008        struct nr_node  *t = NULL;
1009        struct hlist_node *node, *nodet;
1010
1011        spin_lock_bh(&nr_neigh_list_lock);
1012        spin_lock_bh(&nr_node_list_lock);
1013        nr_node_for_each_safe(t, node, nodet, &nr_node_list) {
1014                nr_node_lock(t);
1015                nr_remove_node_locked(t);
1016                nr_node_unlock(t);
1017        }
1018        nr_neigh_for_each_safe(s, node, nodet, &nr_neigh_list) {
1019                while(s->count) {
1020                        s->count--;
1021                        nr_neigh_put(s);
1022                }
1023                nr_remove_neigh_locked(s);
1024        }
1025        spin_unlock_bh(&nr_node_list_lock);
1026        spin_unlock_bh(&nr_neigh_list_lock);
1027}
1028