linux-bk/net/rose/rose_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 (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
   8 * Copyright (C) Terry Dawson VK2KTJ (terry@animats.net)
   9 */
  10#include <linux/errno.h>
  11#include <linux/types.h>
  12#include <linux/socket.h>
  13#include <linux/in.h>
  14#include <linux/kernel.h>
  15#include <linux/sched.h>
  16#include <linux/timer.h>
  17#include <linux/string.h>
  18#include <linux/sockios.h>
  19#include <linux/net.h>
  20#include <net/ax25.h>
  21#include <linux/inet.h>
  22#include <linux/netdevice.h>
  23#include <net/arp.h>
  24#include <linux/if_arp.h>
  25#include <linux/skbuff.h>
  26#include <net/sock.h>
  27#include <net/tcp.h>
  28#include <asm/system.h>
  29#include <asm/uaccess.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 <net/rose.h>
  38#include <linux/seq_file.h>
  39
  40static unsigned int rose_neigh_no = 1;
  41
  42static struct rose_node  *rose_node_list;
  43static DEFINE_SPINLOCK(rose_node_list_lock);
  44static struct rose_neigh *rose_neigh_list;
  45static DEFINE_SPINLOCK(rose_neigh_list_lock);
  46static struct rose_route *rose_route_list;
  47static DEFINE_SPINLOCK(rose_route_list_lock);
  48
  49struct rose_neigh *rose_loopback_neigh;
  50
  51static void rose_remove_neigh(struct rose_neigh *);
  52
  53/*
  54 *      Add a new route to a node, and in the process add the node and the
  55 *      neighbour if it is new.
  56 */
  57static int rose_add_node(struct rose_route_struct *rose_route,
  58        struct net_device *dev)
  59{
  60        struct rose_node  *rose_node, *rose_tmpn, *rose_tmpp;
  61        struct rose_neigh *rose_neigh;
  62        int i, res = 0;
  63
  64        spin_lock_bh(&rose_node_list_lock);
  65        spin_lock_bh(&rose_neigh_list_lock);
  66
  67        rose_node = rose_node_list;
  68        while (rose_node != NULL) {
  69                if ((rose_node->mask == rose_route->mask) &&
  70                    (rosecmpm(&rose_route->address, &rose_node->address,
  71                              rose_route->mask) == 0))
  72                        break;
  73                rose_node = rose_node->next;
  74        }
  75
  76        if (rose_node != NULL && rose_node->loopback) {
  77                res = -EINVAL;
  78                goto out;
  79        }
  80
  81        rose_neigh = rose_neigh_list;
  82        while (rose_neigh != NULL) {
  83                if (ax25cmp(&rose_route->neighbour, &rose_neigh->callsign) == 0
  84                    && rose_neigh->dev == dev)
  85                        break;
  86                rose_neigh = rose_neigh->next;
  87        }
  88
  89        if (rose_neigh == NULL) {
  90                rose_neigh = kmalloc(sizeof(*rose_neigh), GFP_ATOMIC);
  91                if (rose_neigh == NULL) {
  92                        res = -ENOMEM;
  93                        goto out;
  94                }
  95
  96                rose_neigh->callsign  = rose_route->neighbour;
  97                rose_neigh->digipeat  = NULL;
  98                rose_neigh->ax25      = NULL;
  99                rose_neigh->dev       = dev;
 100                rose_neigh->count     = 0;
 101                rose_neigh->use       = 0;
 102                rose_neigh->dce_mode  = 0;
 103                rose_neigh->loopback  = 0;
 104                rose_neigh->number    = rose_neigh_no++;
 105                rose_neigh->restarted = 0;
 106
 107                skb_queue_head_init(&rose_neigh->queue);
 108
 109                init_timer(&rose_neigh->ftimer);
 110                init_timer(&rose_neigh->t0timer);
 111
 112                if (rose_route->ndigis != 0) {
 113                        if ((rose_neigh->digipeat = kmalloc(sizeof(ax25_digi), GFP_KERNEL)) == NULL) {
 114                                kfree(rose_neigh);
 115                                res = -ENOMEM;
 116                                goto out;
 117                        }
 118
 119                        rose_neigh->digipeat->ndigi      = rose_route->ndigis;
 120                        rose_neigh->digipeat->lastrepeat = -1;
 121
 122                        for (i = 0; i < rose_route->ndigis; i++) {
 123                                rose_neigh->digipeat->calls[i]    =
 124                                        rose_route->digipeaters[i];
 125                                rose_neigh->digipeat->repeated[i] = 0;
 126                        }
 127                }
 128
 129                rose_neigh->next = rose_neigh_list;
 130                rose_neigh_list  = rose_neigh;
 131        }
 132
 133        /*
 134         * This is a new node to be inserted into the list. Find where it needs
 135         * to be inserted into the list, and insert it. We want to be sure
 136         * to order the list in descending order of mask size to ensure that
 137         * later when we are searching this list the first match will be the
 138         * best match.
 139         */
 140        if (rose_node == NULL) {
 141                rose_tmpn = rose_node_list;
 142                rose_tmpp = NULL;
 143
 144                while (rose_tmpn != NULL) {
 145                        if (rose_tmpn->mask > rose_route->mask) {
 146                                rose_tmpp = rose_tmpn;
 147                                rose_tmpn = rose_tmpn->next;
 148                        } else {
 149                                break;
 150                        }
 151                }
 152
 153                /* create new node */
 154                rose_node = kmalloc(sizeof(*rose_node), GFP_ATOMIC);
 155                if (rose_node == NULL) {
 156                        res = -ENOMEM;
 157                        goto out;
 158                }
 159
 160                rose_node->address      = rose_route->address;
 161                rose_node->mask         = rose_route->mask;
 162                rose_node->count        = 1;
 163                rose_node->loopback     = 0;
 164                rose_node->neighbour[0] = rose_neigh;
 165
 166                if (rose_tmpn == NULL) {
 167                        if (rose_tmpp == NULL) {        /* Empty list */
 168                                rose_node_list  = rose_node;
 169                                rose_node->next = NULL;
 170                        } else {
 171                                rose_tmpp->next = rose_node;
 172                                rose_node->next = NULL;
 173                        }
 174                } else {
 175                        if (rose_tmpp == NULL) {        /* 1st node */
 176                                rose_node->next = rose_node_list;
 177                                rose_node_list  = rose_node;
 178                        } else {
 179                                rose_tmpp->next = rose_node;
 180                                rose_node->next = rose_tmpn;
 181                        }
 182                }
 183                rose_neigh->count++;
 184
 185                goto out;
 186        }
 187
 188        /* We have space, slot it in */
 189        if (rose_node->count < 3) {
 190                rose_node->neighbour[rose_node->count] = rose_neigh;
 191                rose_node->count++;
 192                rose_neigh->count++;
 193        }
 194
 195out:
 196        spin_unlock_bh(&rose_neigh_list_lock);
 197        spin_unlock_bh(&rose_node_list_lock);
 198
 199        return res;
 200}
 201
 202/*
 203 * Caller is holding rose_node_list_lock.
 204 */
 205static void rose_remove_node(struct rose_node *rose_node)
 206{
 207        struct rose_node *s;
 208
 209        if ((s = rose_node_list) == rose_node) {
 210                rose_node_list = rose_node->next;
 211                kfree(rose_node);
 212                return;
 213        }
 214
 215        while (s != NULL && s->next != NULL) {
 216                if (s->next == rose_node) {
 217                        s->next = rose_node->next;
 218                        kfree(rose_node);
 219                        return;
 220                }
 221
 222                s = s->next;
 223        }
 224}
 225
 226/*
 227 * Caller is holding rose_neigh_list_lock.
 228 */
 229static void rose_remove_neigh(struct rose_neigh *rose_neigh)
 230{
 231        struct rose_neigh *s;
 232
 233        rose_stop_ftimer(rose_neigh);
 234        rose_stop_t0timer(rose_neigh);
 235
 236        skb_queue_purge(&rose_neigh->queue);
 237
 238        spin_lock_bh(&rose_neigh_list_lock);
 239
 240        if ((s = rose_neigh_list) == rose_neigh) {
 241                rose_neigh_list = rose_neigh->next;
 242                spin_unlock_bh(&rose_neigh_list_lock);
 243                if (rose_neigh->digipeat != NULL)
 244                        kfree(rose_neigh->digipeat);
 245                kfree(rose_neigh);
 246                return;
 247        }
 248
 249        while (s != NULL && s->next != NULL) {
 250                if (s->next == rose_neigh) {
 251                        s->next = rose_neigh->next;
 252                        spin_unlock_bh(&rose_neigh_list_lock);
 253                        if (rose_neigh->digipeat != NULL)
 254                                kfree(rose_neigh->digipeat);
 255                        kfree(rose_neigh);
 256                        return;
 257                }
 258
 259                s = s->next;
 260        }
 261        spin_unlock_bh(&rose_neigh_list_lock);
 262}
 263
 264/*
 265 * Caller is holding rose_route_list_lock.
 266 */
 267static void rose_remove_route(struct rose_route *rose_route)
 268{
 269        struct rose_route *s;
 270
 271        if (rose_route->neigh1 != NULL)
 272                rose_route->neigh1->use--;
 273
 274        if (rose_route->neigh2 != NULL)
 275                rose_route->neigh2->use--;
 276
 277        if ((s = rose_route_list) == rose_route) {
 278                rose_route_list = rose_route->next;
 279                kfree(rose_route);
 280                return;
 281        }
 282
 283        while (s != NULL && s->next != NULL) {
 284                if (s->next == rose_route) {
 285                        s->next = rose_route->next;
 286                        kfree(rose_route);
 287                        return;
 288                }
 289
 290                s = s->next;
 291        }
 292}
 293
 294/*
 295 *      "Delete" a node. Strictly speaking remove a route to a node. The node
 296 *      is only deleted if no routes are left to it.
 297 */
 298static int rose_del_node(struct rose_route_struct *rose_route,
 299        struct net_device *dev)
 300{
 301        struct rose_node  *rose_node;
 302        struct rose_neigh *rose_neigh;
 303        int i, err = 0;
 304
 305        spin_lock_bh(&rose_node_list_lock);
 306        spin_lock_bh(&rose_neigh_list_lock);
 307
 308        rose_node = rose_node_list;
 309        while (rose_node != NULL) {
 310                if ((rose_node->mask == rose_route->mask) &&
 311                    (rosecmpm(&rose_route->address, &rose_node->address,
 312                              rose_route->mask) == 0))
 313                        break;
 314                rose_node = rose_node->next;
 315        }
 316
 317        if (rose_node == NULL || rose_node->loopback) {
 318                err = -EINVAL;
 319                goto out;
 320        }
 321
 322        rose_neigh = rose_neigh_list;
 323        while (rose_neigh != NULL) {
 324                if (ax25cmp(&rose_route->neighbour, &rose_neigh->callsign) == 0
 325                    && rose_neigh->dev == dev)
 326                        break;
 327                rose_neigh = rose_neigh->next;
 328        }
 329
 330        if (rose_neigh == NULL) {
 331                err = -EINVAL;
 332                goto out;
 333        }
 334
 335        for (i = 0; i < rose_node->count; i++) {
 336                if (rose_node->neighbour[i] == rose_neigh) {
 337                        rose_neigh->count--;
 338
 339                        if (rose_neigh->count == 0 && rose_neigh->use == 0)
 340                                rose_remove_neigh(rose_neigh);
 341
 342                        rose_node->count--;
 343
 344                        if (rose_node->count == 0) {
 345                                rose_remove_node(rose_node);
 346                        } else {
 347                                switch (i) {
 348                                case 0:
 349                                        rose_node->neighbour[0] =
 350                                                rose_node->neighbour[1];
 351                                case 1:
 352                                        rose_node->neighbour[1] =
 353                                                rose_node->neighbour[2];
 354                                case 2:
 355                                        break;
 356                                }
 357                        }
 358                        goto out;
 359                }
 360        }
 361        err = -EINVAL;
 362
 363out:
 364        spin_unlock_bh(&rose_neigh_list_lock);
 365        spin_unlock_bh(&rose_node_list_lock);
 366
 367        return err;
 368}
 369
 370/*
 371 *      Add the loopback neighbour.
 372 */
 373int rose_add_loopback_neigh(void)
 374{
 375        if ((rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_ATOMIC)) == NULL)
 376                return -ENOMEM;
 377
 378        rose_loopback_neigh->callsign  = null_ax25_address;
 379        rose_loopback_neigh->digipeat  = NULL;
 380        rose_loopback_neigh->ax25      = NULL;
 381        rose_loopback_neigh->dev       = NULL;
 382        rose_loopback_neigh->count     = 0;
 383        rose_loopback_neigh->use       = 0;
 384        rose_loopback_neigh->dce_mode  = 1;
 385        rose_loopback_neigh->loopback  = 1;
 386        rose_loopback_neigh->number    = rose_neigh_no++;
 387        rose_loopback_neigh->restarted = 1;
 388
 389        skb_queue_head_init(&rose_loopback_neigh->queue);
 390
 391        init_timer(&rose_loopback_neigh->ftimer);
 392        init_timer(&rose_loopback_neigh->t0timer);
 393
 394        spin_lock_bh(&rose_neigh_list_lock);
 395        rose_loopback_neigh->next = rose_neigh_list;
 396        rose_neigh_list           = rose_loopback_neigh;
 397        spin_unlock_bh(&rose_neigh_list_lock);
 398
 399        return 0;
 400}
 401
 402/*
 403 *      Add a loopback node.
 404 */
 405int rose_add_loopback_node(rose_address *address)
 406{
 407        struct rose_node *rose_node;
 408        unsigned int err = 0;
 409
 410        spin_lock_bh(&rose_node_list_lock);
 411
 412        rose_node = rose_node_list;
 413        while (rose_node != NULL) {
 414                if ((rose_node->mask == 10) &&
 415                     (rosecmpm(address, &rose_node->address, 10) == 0) &&
 416                     rose_node->loopback)
 417                        break;
 418                rose_node = rose_node->next;
 419        }
 420
 421        if (rose_node != NULL)
 422                goto out;
 423
 424        if ((rose_node = kmalloc(sizeof(*rose_node), GFP_ATOMIC)) == NULL) {
 425                err = -ENOMEM;
 426                goto out;
 427        }
 428
 429        rose_node->address      = *address;
 430        rose_node->mask         = 10;
 431        rose_node->count        = 1;
 432        rose_node->loopback     = 1;
 433        rose_node->neighbour[0] = rose_loopback_neigh;
 434
 435        /* Insert at the head of list. Address is always mask=10 */
 436        rose_node->next = rose_node_list;
 437        rose_node_list  = rose_node;
 438
 439        rose_loopback_neigh->count++;
 440
 441out:
 442        spin_unlock_bh(&rose_node_list_lock);
 443
 444        return 0;
 445}
 446
 447/*
 448 *      Delete a loopback node.
 449 */
 450void rose_del_loopback_node(rose_address *address)
 451{
 452        struct rose_node *rose_node;
 453
 454        spin_lock_bh(&rose_node_list_lock);
 455
 456        rose_node = rose_node_list;
 457        while (rose_node != NULL) {
 458                if ((rose_node->mask == 10) &&
 459                    (rosecmpm(address, &rose_node->address, 10) == 0) &&
 460                    rose_node->loopback)
 461                        break;
 462                rose_node = rose_node->next;
 463        }
 464
 465        if (rose_node == NULL)
 466                goto out;
 467
 468        rose_remove_node(rose_node);
 469
 470        rose_loopback_neigh->count--;
 471
 472out:
 473        spin_unlock_bh(&rose_node_list_lock);
 474}
 475
 476/*
 477 *      A device has been removed. Remove its routes and neighbours.
 478 */
 479void rose_rt_device_down(struct net_device *dev)
 480{
 481        struct rose_neigh *s, *rose_neigh;
 482        struct rose_node  *t, *rose_node;
 483        int i;
 484
 485        spin_lock_bh(&rose_node_list_lock);
 486        spin_lock_bh(&rose_neigh_list_lock);
 487        rose_neigh = rose_neigh_list;
 488        while (rose_neigh != NULL) {
 489                s          = rose_neigh;
 490                rose_neigh = rose_neigh->next;
 491
 492                if (s->dev != dev)
 493                        continue;
 494
 495                rose_node = rose_node_list;
 496
 497                while (rose_node != NULL) {
 498                        t         = rose_node;
 499                        rose_node = rose_node->next;
 500
 501                        for (i = 0; i < t->count; i++) {
 502                                if (t->neighbour[i] != s)
 503                                        continue;
 504
 505                                t->count--;
 506
 507                                switch (i) {
 508                                case 0:
 509                                        t->neighbour[0] = t->neighbour[1];
 510                                case 1:
 511                                        t->neighbour[1] = t->neighbour[2];
 512                                case 2:
 513                                        break;
 514                                }
 515                        }
 516
 517                        if (t->count <= 0)
 518                                rose_remove_node(t);
 519                }
 520
 521                rose_remove_neigh(s);
 522        }
 523        spin_unlock_bh(&rose_neigh_list_lock);
 524        spin_unlock_bh(&rose_node_list_lock);
 525}
 526
 527#if 0 /* Currently unused */
 528/*
 529 *      A device has been removed. Remove its links.
 530 */
 531void rose_route_device_down(struct net_device *dev)
 532{
 533        struct rose_route *s, *rose_route;
 534
 535        spin_lock_bh(&rose_route_list_lock);
 536        rose_route = rose_route_list;
 537        while (rose_route != NULL) {
 538                s          = rose_route;
 539                rose_route = rose_route->next;
 540
 541                if (s->neigh1->dev == dev || s->neigh2->dev == dev)
 542                        rose_remove_route(s);
 543        }
 544        spin_unlock_bh(&rose_route_list_lock);
 545}
 546#endif
 547
 548/*
 549 *      Clear all nodes and neighbours out, except for neighbours with
 550 *      active connections going through them.
 551 *  Do not clear loopback neighbour and nodes.
 552 */
 553static int rose_clear_routes(void)
 554{
 555        struct rose_neigh *s, *rose_neigh;
 556        struct rose_node  *t, *rose_node;
 557
 558        spin_lock_bh(&rose_node_list_lock);
 559        spin_lock_bh(&rose_neigh_list_lock);
 560
 561        rose_neigh = rose_neigh_list;
 562        rose_node  = rose_node_list;
 563
 564        while (rose_node != NULL) {
 565                t         = rose_node;
 566                rose_node = rose_node->next;
 567                if (!t->loopback)
 568                        rose_remove_node(t);
 569        }
 570
 571        while (rose_neigh != NULL) {
 572                s          = rose_neigh;
 573                rose_neigh = rose_neigh->next;
 574
 575                if (s->use == 0 && !s->loopback) {
 576                        s->count = 0;
 577                        rose_remove_neigh(s);
 578                }
 579        }
 580
 581        spin_unlock_bh(&rose_neigh_list_lock);
 582        spin_unlock_bh(&rose_node_list_lock);
 583
 584        return 0;
 585}
 586
 587/*
 588 *      Check that the device given is a valid AX.25 interface that is "up".
 589 */
 590static struct net_device *rose_ax25_dev_get(char *devname)
 591{
 592        struct net_device *dev;
 593
 594        if ((dev = dev_get_by_name(devname)) == NULL)
 595                return NULL;
 596
 597        if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
 598                return dev;
 599
 600        dev_put(dev);
 601        return NULL;
 602}
 603
 604/*
 605 *      Find the first active ROSE device, usually "rose0".
 606 */
 607struct net_device *rose_dev_first(void)
 608{
 609        struct net_device *dev, *first = NULL;
 610
 611        read_lock(&dev_base_lock);
 612        for (dev = dev_base; dev != NULL; dev = dev->next) {
 613                if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE)
 614                        if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
 615                                first = dev;
 616        }
 617        read_unlock(&dev_base_lock);
 618
 619        return first;
 620}
 621
 622/*
 623 *      Find the ROSE device for the given address.
 624 */
 625struct net_device *rose_dev_get(rose_address *addr)
 626{
 627        struct net_device *dev;
 628
 629        read_lock(&dev_base_lock);
 630        for (dev = dev_base; dev != NULL; dev = dev->next) {
 631                if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) {
 632                        dev_hold(dev);
 633                        goto out;
 634                }
 635        }
 636out:
 637        read_unlock(&dev_base_lock);
 638        return dev;
 639}
 640
 641static int rose_dev_exists(rose_address *addr)
 642{
 643        struct net_device *dev;
 644
 645        read_lock(&dev_base_lock);
 646        for (dev = dev_base; dev != NULL; dev = dev->next) {
 647                if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0)
 648                        goto out;
 649        }
 650out:
 651        read_unlock(&dev_base_lock);
 652        return dev != NULL;
 653}
 654
 655
 656
 657
 658struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neigh)
 659{
 660        struct rose_route *rose_route;
 661
 662        for (rose_route = rose_route_list; rose_route != NULL; rose_route = rose_route->next)
 663                if ((rose_route->neigh1 == neigh && rose_route->lci1 == lci) ||
 664                    (rose_route->neigh2 == neigh && rose_route->lci2 == lci))
 665                        return rose_route;
 666
 667        return NULL;
 668}
 669
 670/*
 671 *      Find a neighbour given a ROSE address.
 672 */
 673struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
 674        unsigned char *diagnostic)
 675{
 676        struct rose_neigh *res = NULL;
 677        struct rose_node *node;
 678        int failed = 0;
 679        int i;
 680
 681        spin_lock_bh(&rose_node_list_lock);
 682        for (node = rose_node_list; node != NULL; node = node->next) {
 683                if (rosecmpm(addr, &node->address, node->mask) == 0) {
 684                        for (i = 0; i < node->count; i++) {
 685                                if (!rose_ftimer_running(node->neighbour[i])) {
 686                                        res = node->neighbour[i];
 687                                        goto out;
 688                                } else
 689                                        failed = 1;
 690                        }
 691                        break;
 692                }
 693        }
 694
 695        if (failed) {
 696                *cause      = ROSE_OUT_OF_ORDER;
 697                *diagnostic = 0;
 698        } else {
 699                *cause      = ROSE_NOT_OBTAINABLE;
 700                *diagnostic = 0;
 701        }
 702
 703out:
 704        spin_unlock_bh(&rose_node_list_lock);
 705
 706        return res;
 707}
 708
 709/*
 710 *      Handle the ioctls that control the routing functions.
 711 */
 712int rose_rt_ioctl(unsigned int cmd, void __user *arg)
 713{
 714        struct rose_route_struct rose_route;
 715        struct net_device *dev;
 716        int err;
 717
 718        switch (cmd) {
 719        case SIOCADDRT:
 720                if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
 721                        return -EFAULT;
 722                if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL)
 723                        return -EINVAL;
 724                if (rose_dev_exists(&rose_route.address)) { /* Can't add routes to ourself */
 725                        dev_put(dev);
 726                        return -EINVAL;
 727                }
 728                if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
 729                        return -EINVAL;
 730
 731                err = rose_add_node(&rose_route, dev);
 732                dev_put(dev);
 733                return err;
 734
 735        case SIOCDELRT:
 736                if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
 737                        return -EFAULT;
 738                if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL)
 739                        return -EINVAL;
 740                err = rose_del_node(&rose_route, dev);
 741                dev_put(dev);
 742                return err;
 743
 744        case SIOCRSCLRRT:
 745                return rose_clear_routes();
 746
 747        default:
 748                return -EINVAL;
 749        }
 750
 751        return 0;
 752}
 753
 754static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
 755{
 756        struct rose_route *rose_route, *s;
 757
 758        rose_neigh->restarted = 0;
 759
 760        rose_stop_t0timer(rose_neigh);
 761        rose_start_ftimer(rose_neigh);
 762
 763        skb_queue_purge(&rose_neigh->queue);
 764
 765        spin_lock_bh(&rose_route_list_lock);
 766
 767        rose_route = rose_route_list;
 768
 769        while (rose_route != NULL) {
 770                if ((rose_route->neigh1 == rose_neigh && rose_route->neigh2 == rose_neigh) ||
 771                    (rose_route->neigh1 == rose_neigh && rose_route->neigh2 == NULL)       ||
 772                    (rose_route->neigh2 == rose_neigh && rose_route->neigh1 == NULL)) {
 773                        s = rose_route->next;
 774                        rose_remove_route(rose_route);
 775                        rose_route = s;
 776                        continue;
 777                }
 778
 779                if (rose_route->neigh1 == rose_neigh) {
 780                        rose_route->neigh1->use--;
 781                        rose_route->neigh1 = NULL;
 782                        rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
 783                }
 784
 785                if (rose_route->neigh2 == rose_neigh) {
 786                        rose_route->neigh2->use--;
 787                        rose_route->neigh2 = NULL;
 788                        rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
 789                }
 790
 791                rose_route = rose_route->next;
 792        }
 793        spin_unlock_bh(&rose_route_list_lock);
 794}
 795
 796/*
 797 *      A level 2 link has timed out, therefore it appears to be a poor link,
 798 *      then don't use that neighbour until it is reset. Blow away all through
 799 *      routes and connections using this route.
 800 */
 801void rose_link_failed(ax25_cb *ax25, int reason)
 802{
 803        struct rose_neigh *rose_neigh;
 804
 805        spin_lock_bh(&rose_neigh_list_lock);
 806        rose_neigh = rose_neigh_list;
 807        while (rose_neigh != NULL) {
 808                if (rose_neigh->ax25 == ax25)
 809                        break;
 810                rose_neigh = rose_neigh->next;
 811        }
 812
 813        if (rose_neigh != NULL) {
 814                rose_neigh->ax25 = NULL;
 815
 816                rose_del_route_by_neigh(rose_neigh);
 817                rose_kill_by_neigh(rose_neigh);
 818        }
 819        spin_unlock_bh(&rose_neigh_list_lock);
 820}
 821
 822/*
 823 *      A device has been "downed" remove its link status. Blow away all
 824 *      through routes and connections that use this device.
 825 */
 826void rose_link_device_down(struct net_device *dev)
 827{
 828        struct rose_neigh *rose_neigh;
 829
 830        for (rose_neigh = rose_neigh_list; rose_neigh != NULL; rose_neigh = rose_neigh->next) {
 831                if (rose_neigh->dev == dev) {
 832                        rose_del_route_by_neigh(rose_neigh);
 833                        rose_kill_by_neigh(rose_neigh);
 834                }
 835        }
 836}
 837
 838/*
 839 *      Route a frame to an appropriate AX.25 connection.
 840 */
 841int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
 842{
 843        struct rose_neigh *rose_neigh, *new_neigh;
 844        struct rose_route *rose_route;
 845        struct rose_facilities_struct facilities;
 846        rose_address *src_addr, *dest_addr;
 847        struct sock *sk;
 848        unsigned short frametype;
 849        unsigned int lci, new_lci;
 850        unsigned char cause, diagnostic;
 851        struct net_device *dev;
 852        int len, res = 0;
 853
 854#if 0
 855        if (call_in_firewall(PF_ROSE, skb->dev, skb->data, NULL, &skb) != FW_ACCEPT)
 856                return res;
 857#endif
 858
 859        frametype = skb->data[2];
 860        lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
 861        src_addr  = (rose_address *)(skb->data + 9);
 862        dest_addr = (rose_address *)(skb->data + 4);
 863
 864        spin_lock_bh(&rose_node_list_lock);
 865        spin_lock_bh(&rose_neigh_list_lock);
 866        spin_lock_bh(&rose_route_list_lock);
 867
 868        rose_neigh = rose_neigh_list;
 869        while (rose_neigh != NULL) {
 870                if (ax25cmp(&ax25->dest_addr, &rose_neigh->callsign) == 0 &&
 871                    ax25->ax25_dev->dev == rose_neigh->dev)
 872                        break;
 873                rose_neigh = rose_neigh->next;
 874        }
 875
 876        if (rose_neigh == NULL) {
 877                printk("rose_route : unknown neighbour or device %s\n",
 878                       ax2asc(&ax25->dest_addr));
 879                goto out;
 880        }
 881
 882        /*
 883         *      Obviously the link is working, halt the ftimer.
 884         */
 885        rose_stop_ftimer(rose_neigh);
 886
 887        /*
 888         *      LCI of zero is always for us, and its always a restart
 889         *      frame.
 890         */
 891        if (lci == 0) {
 892                rose_link_rx_restart(skb, rose_neigh, frametype);
 893                goto out;
 894        }
 895
 896        /*
 897         *      Find an existing socket.
 898         */
 899        if ((sk = rose_find_socket(lci, rose_neigh)) != NULL) {
 900                if (frametype == ROSE_CALL_REQUEST) {
 901                        rose_cb *rose = rose_sk(sk);
 902                        /* Remove an existing unused socket */
 903                        rose_clear_queues(sk);
 904                        rose->cause      = ROSE_NETWORK_CONGESTION;
 905                        rose->diagnostic = 0;
 906                        rose->neighbour->use--;
 907                        rose->neighbour  = NULL;
 908                        rose->lci        = 0;
 909                        rose->state      = ROSE_STATE_0;
 910                        sk->sk_state     = TCP_CLOSE;
 911                        sk->sk_err       = 0;
 912                        sk->sk_shutdown  |= SEND_SHUTDOWN;
 913                        if (!sock_flag(sk, SOCK_DEAD)) {
 914                                sk->sk_state_change(sk);
 915                                sock_set_flag(sk, SOCK_DEAD);
 916                        }
 917                }
 918                else {
 919                        skb->h.raw = skb->data;
 920                        res = rose_process_rx_frame(sk, skb);
 921                        goto out;
 922                }
 923        }
 924
 925        /*
 926         *      Is is a Call Request and is it for us ?
 927         */
 928        if (frametype == ROSE_CALL_REQUEST)
 929                if ((dev = rose_dev_get(dest_addr)) != NULL) {
 930                        res = rose_rx_call_request(skb, dev, rose_neigh, lci);
 931                        dev_put(dev);
 932                        goto out;
 933                }
 934
 935        if (!sysctl_rose_routing_control) {
 936                rose_transmit_clear_request(rose_neigh, lci, ROSE_NOT_OBTAINABLE, 0);
 937                goto out;
 938        }
 939
 940        /*
 941         *      Route it to the next in line if we have an entry for it.
 942         */
 943        rose_route = rose_route_list;
 944        while (rose_route != NULL) {
 945                if (rose_route->lci1 == lci &&
 946                    rose_route->neigh1 == rose_neigh) {
 947                        if (frametype == ROSE_CALL_REQUEST) {
 948                                /* F6FBB - Remove an existing unused route */
 949                                rose_remove_route(rose_route);
 950                                break;
 951                        } else if (rose_route->neigh2 != NULL) {
 952                                skb->data[0] &= 0xF0;
 953                                skb->data[0] |= (rose_route->lci2 >> 8) & 0x0F;
 954                                skb->data[1]  = (rose_route->lci2 >> 0) & 0xFF;
 955                                rose_transmit_link(skb, rose_route->neigh2);
 956                                if (frametype == ROSE_CLEAR_CONFIRMATION)
 957                                        rose_remove_route(rose_route);
 958                                res = 1;
 959                                goto out;
 960                        } else {
 961                                if (frametype == ROSE_CLEAR_CONFIRMATION)
 962                                        rose_remove_route(rose_route);
 963                                goto out;
 964                        }
 965                }
 966                if (rose_route->lci2 == lci &&
 967                    rose_route->neigh2 == rose_neigh) {
 968                        if (frametype == ROSE_CALL_REQUEST) {
 969                                /* F6FBB - Remove an existing unused route */
 970                                rose_remove_route(rose_route);
 971                                break;
 972                        } else if (rose_route->neigh1 != NULL) {
 973                                skb->data[0] &= 0xF0;
 974                                skb->data[0] |= (rose_route->lci1 >> 8) & 0x0F;
 975                                skb->data[1]  = (rose_route->lci1 >> 0) & 0xFF;
 976                                rose_transmit_link(skb, rose_route->neigh1);
 977                                if (frametype == ROSE_CLEAR_CONFIRMATION)
 978                                        rose_remove_route(rose_route);
 979                                res = 1;
 980                                goto out;
 981                        } else {
 982                                if (frametype == ROSE_CLEAR_CONFIRMATION)
 983                                        rose_remove_route(rose_route);
 984                                goto out;
 985                        }
 986                }
 987                rose_route = rose_route->next;
 988        }
 989
 990        /*
 991         *      We know that:
 992         *      1. The frame isn't for us,
 993         *      2. It isn't "owned" by any existing route.
 994         */
 995        if (frametype != ROSE_CALL_REQUEST)     /* XXX */
 996                return 0;
 997
 998        len  = (((skb->data[3] >> 4) & 0x0F) + 1) / 2;
 999        len += (((skb->data[3] >> 0) & 0x0F) + 1) / 2;
1000
1001        memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
1002
1003        if (!rose_parse_facilities(skb->data + len + 4, &facilities)) {
1004                rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76);
1005                goto out;
1006        }
1007
1008        /*
1009         *      Check for routing loops.
1010         */
1011        rose_route = rose_route_list;
1012        while (rose_route != NULL) {
1013                if (rose_route->rand == facilities.rand &&
1014                    rosecmp(src_addr, &rose_route->src_addr) == 0 &&
1015                    ax25cmp(&facilities.dest_call, &rose_route->src_call) == 0 &&
1016                    ax25cmp(&facilities.source_call, &rose_route->dest_call) == 0) {
1017                        rose_transmit_clear_request(rose_neigh, lci, ROSE_NOT_OBTAINABLE, 120);
1018                        goto out;
1019                }
1020                rose_route = rose_route->next;
1021        }
1022
1023        if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic)) == NULL) {
1024                rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic);
1025                goto out;
1026        }
1027
1028        if ((new_lci = rose_new_lci(new_neigh)) == 0) {
1029                rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
1030                goto out;
1031        }
1032
1033        if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
1034                rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
1035                goto out;
1036        }
1037
1038        rose_route->lci1      = lci;
1039        rose_route->src_addr  = *src_addr;
1040        rose_route->dest_addr = *dest_addr;
1041        rose_route->src_call  = facilities.dest_call;
1042        rose_route->dest_call = facilities.source_call;
1043        rose_route->rand      = facilities.rand;
1044        rose_route->neigh1    = rose_neigh;
1045        rose_route->lci2      = new_lci;
1046        rose_route->neigh2    = new_neigh;
1047
1048        rose_route->neigh1->use++;
1049        rose_route->neigh2->use++;
1050
1051        rose_route->next = rose_route_list;
1052        rose_route_list  = rose_route;
1053
1054        skb->data[0] &= 0xF0;
1055        skb->data[0] |= (rose_route->lci2 >> 8) & 0x0F;
1056        skb->data[1]  = (rose_route->lci2 >> 0) & 0xFF;
1057
1058        rose_transmit_link(skb, rose_route->neigh2);
1059        res = 1;
1060
1061out:
1062        spin_unlock_bh(&rose_route_list_lock);
1063        spin_unlock_bh(&rose_neigh_list_lock);
1064        spin_unlock_bh(&rose_node_list_lock);
1065
1066        return res;
1067}
1068
1069#ifdef CONFIG_PROC_FS
1070
1071static void *rose_node_start(struct seq_file *seq, loff_t *pos)
1072{
1073        struct rose_node *rose_node;
1074        int i = 1;
1075
1076        spin_lock_bh(&rose_neigh_list_lock);
1077        if (*pos == 0)
1078                return SEQ_START_TOKEN;
1079
1080        for (rose_node = rose_node_list; rose_node && i < *pos; 
1081             rose_node = rose_node->next, ++i);
1082
1083        return (i == *pos) ? rose_node : NULL;
1084}
1085
1086static void *rose_node_next(struct seq_file *seq, void *v, loff_t *pos)
1087{
1088        ++*pos;
1089        
1090        return (v == SEQ_START_TOKEN) ? rose_node_list 
1091                : ((struct rose_node *)v)->next;
1092}
1093
1094static void rose_node_stop(struct seq_file *seq, void *v)
1095{
1096        spin_unlock_bh(&rose_neigh_list_lock);
1097}
1098
1099static int rose_node_show(struct seq_file *seq, void *v)
1100{
1101        int i;
1102
1103        if (v == SEQ_START_TOKEN)
1104                seq_puts(seq, "address    mask n neigh neigh neigh\n");
1105        else {
1106                const struct rose_node *rose_node = v;
1107                /* if (rose_node->loopback) {
1108                        seq_printf(seq, "%-10s %04d 1 loopback\n",
1109                                rose2asc(&rose_node->address),
1110                                rose_node->mask);
1111                } else { */
1112                        seq_printf(seq, "%-10s %04d %d",
1113                                rose2asc(&rose_node->address),
1114                                rose_node->mask,
1115                                rose_node->count);
1116
1117                        for (i = 0; i < rose_node->count; i++)
1118                                seq_printf(seq, " %05d",
1119                                        rose_node->neighbour[i]->number);
1120
1121                        seq_puts(seq, "\n");
1122                /* } */
1123        }
1124        return 0;
1125}
1126
1127static struct seq_operations rose_node_seqops = {
1128        .start = rose_node_start,
1129        .next = rose_node_next,
1130        .stop = rose_node_stop,
1131        .show = rose_node_show,
1132};
1133
1134static int rose_nodes_open(struct inode *inode, struct file *file)
1135{
1136        return seq_open(file, &rose_node_seqops);
1137}
1138
1139struct file_operations rose_nodes_fops = {
1140        .owner = THIS_MODULE,
1141        .open = rose_nodes_open,
1142        .read = seq_read,
1143        .llseek = seq_lseek,
1144        .release = seq_release,
1145};
1146
1147static void *rose_neigh_start(struct seq_file *seq, loff_t *pos)
1148{
1149        struct rose_neigh *rose_neigh;
1150        int i = 1;
1151
1152        spin_lock_bh(&rose_neigh_list_lock);
1153        if (*pos == 0)
1154                return SEQ_START_TOKEN;
1155
1156        for (rose_neigh = rose_neigh_list; rose_neigh && i < *pos; 
1157             rose_neigh = rose_neigh->next, ++i);
1158
1159        return (i == *pos) ? rose_neigh : NULL;
1160}
1161
1162static void *rose_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
1163{
1164        ++*pos;
1165        
1166        return (v == SEQ_START_TOKEN) ? rose_neigh_list 
1167                : ((struct rose_neigh *)v)->next;
1168}
1169
1170static void rose_neigh_stop(struct seq_file *seq, void *v)
1171{
1172        spin_unlock_bh(&rose_neigh_list_lock);
1173}
1174
1175static int rose_neigh_show(struct seq_file *seq, void *v)
1176{
1177        int i;
1178
1179        if (v == SEQ_START_TOKEN)
1180                seq_puts(seq, 
1181                         "addr  callsign  dev  count use mode restart  t0  tf digipeaters\n");
1182        else {
1183                struct rose_neigh *rose_neigh = v;
1184
1185                /* if (!rose_neigh->loopback) { */
1186                seq_printf(seq, "%05d %-9s %-4s   %3d %3d  %3s     %3s %3lu %3lu",
1187                           rose_neigh->number,
1188                           (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(&rose_neigh->callsign),
1189                           rose_neigh->dev ? rose_neigh->dev->name : "???",
1190                           rose_neigh->count,
1191                           rose_neigh->use,
1192                           (rose_neigh->dce_mode) ? "DCE" : "DTE",
1193                           (rose_neigh->restarted) ? "yes" : "no",
1194                           ax25_display_timer(&rose_neigh->t0timer) / HZ,
1195                           ax25_display_timer(&rose_neigh->ftimer)  / HZ);
1196
1197                if (rose_neigh->digipeat != NULL) {
1198                        for (i = 0; i < rose_neigh->digipeat->ndigi; i++)
1199                                seq_printf(seq, " %s", ax2asc(&rose_neigh->digipeat->calls[i]));
1200                }
1201
1202                seq_puts(seq, "\n");
1203        }
1204        return 0;
1205}
1206
1207
1208static struct seq_operations rose_neigh_seqops = {
1209        .start = rose_neigh_start,
1210        .next = rose_neigh_next,
1211        .stop = rose_neigh_stop,
1212        .show = rose_neigh_show,
1213};
1214
1215static int rose_neigh_open(struct inode *inode, struct file *file)
1216{
1217        return seq_open(file, &rose_neigh_seqops);
1218}
1219
1220struct file_operations rose_neigh_fops = {
1221        .owner = THIS_MODULE,
1222        .open = rose_neigh_open,
1223        .read = seq_read,
1224        .llseek = seq_lseek,
1225        .release = seq_release,
1226};
1227
1228
1229static void *rose_route_start(struct seq_file *seq, loff_t *pos)
1230{
1231        struct rose_route *rose_route;
1232        int i = 1;
1233
1234        spin_lock_bh(&rose_route_list_lock);
1235        if (*pos == 0)
1236                return SEQ_START_TOKEN;
1237
1238        for (rose_route = rose_route_list; rose_route && i < *pos; 
1239             rose_route = rose_route->next, ++i);
1240
1241        return (i == *pos) ? rose_route : NULL;
1242}
1243
1244static void *rose_route_next(struct seq_file *seq, void *v, loff_t *pos)
1245{
1246        ++*pos;
1247        
1248        return (v == SEQ_START_TOKEN) ? rose_route_list 
1249                : ((struct rose_route *)v)->next;
1250}
1251
1252static void rose_route_stop(struct seq_file *seq, void *v)
1253{
1254        spin_unlock_bh(&rose_route_list_lock);
1255}
1256
1257static int rose_route_show(struct seq_file *seq, void *v)
1258{
1259        if (v == SEQ_START_TOKEN)
1260                seq_puts(seq, 
1261                         "lci  address     callsign   neigh  <-> lci  address     callsign   neigh\n");
1262        else {
1263                struct rose_route *rose_route = v;
1264
1265                if (rose_route->neigh1) 
1266                        seq_printf(seq,
1267                                   "%3.3X  %-10s  %-9s  %05d      ",
1268                                   rose_route->lci1,
1269                                   rose2asc(&rose_route->src_addr),
1270                                   ax2asc(&rose_route->src_call),
1271                                   rose_route->neigh1->number);
1272                else 
1273                        seq_puts(seq, 
1274                                 "000  *           *          00000      ");
1275
1276                if (rose_route->neigh2) 
1277                        seq_printf(seq,
1278                                   "%3.3X  %-10s  %-9s  %05d\n",
1279                                rose_route->lci2,
1280                                rose2asc(&rose_route->dest_addr),
1281                                ax2asc(&rose_route->dest_call),
1282                                rose_route->neigh2->number);
1283                 else 
1284                         seq_puts(seq,
1285                                  "000  *           *          00000\n");
1286                }
1287        return 0;
1288}
1289
1290static struct seq_operations rose_route_seqops = {
1291        .start = rose_route_start,
1292        .next = rose_route_next,
1293        .stop = rose_route_stop,
1294        .show = rose_route_show,
1295};
1296
1297static int rose_route_open(struct inode *inode, struct file *file)
1298{
1299        return seq_open(file, &rose_route_seqops);
1300}
1301
1302struct file_operations rose_routes_fops = {
1303        .owner = THIS_MODULE,
1304        .open = rose_route_open,
1305        .read = seq_read,
1306        .llseek = seq_lseek,
1307        .release = seq_release,
1308};
1309
1310#endif /* CONFIG_PROC_FS */
1311
1312/*
1313 *      Release all memory associated with ROSE routing structures.
1314 */
1315void __exit rose_rt_free(void)
1316{
1317        struct rose_neigh *s, *rose_neigh = rose_neigh_list;
1318        struct rose_node  *t, *rose_node  = rose_node_list;
1319        struct rose_route *u, *rose_route = rose_route_list;
1320
1321        while (rose_neigh != NULL) {
1322                s          = rose_neigh;
1323                rose_neigh = rose_neigh->next;
1324
1325                rose_remove_neigh(s);
1326        }
1327
1328        while (rose_node != NULL) {
1329                t         = rose_node;
1330                rose_node = rose_node->next;
1331
1332                rose_remove_node(t);
1333        }
1334
1335        while (rose_route != NULL) {
1336                u          = rose_route;
1337                rose_route = rose_route->next;
1338
1339                rose_remove_route(u);
1340        }
1341}
1342
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.