Showing error 1475

User: Jiri Slaby
Error type: Leaving function in locked state
Error type description: Some lock is not unlocked on all paths of a function, so it is leaked
File location: net/ipv4/fib_hash.c
Line in file: 965
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2012-05-21 20:30:05 UTC


Source:

   1/*
   2 * INET                An implementation of the TCP/IP protocol suite for the LINUX
   3 *                operating system.  INET is implemented using the  BSD Socket
   4 *                interface as the means of communication with the user level.
   5 *
   6 *                IPv4 FIB: lookup engine and maintenance routines.
   7 *
   8 * Authors:        Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
   9 *
  10 *                This program is free software; you can redistribute it and/or
  11 *                modify it under the terms of the GNU General Public License
  12 *                as published by the Free Software Foundation; either version
  13 *                2 of the License, or (at your option) any later version.
  14 */
  15
  16#include <asm/uaccess.h>
  17#include <asm/system.h>
  18#include <linux/bitops.h>
  19#include <linux/types.h>
  20#include <linux/kernel.h>
  21#include <linux/mm.h>
  22#include <linux/string.h>
  23#include <linux/socket.h>
  24#include <linux/sockios.h>
  25#include <linux/errno.h>
  26#include <linux/in.h>
  27#include <linux/inet.h>
  28#include <linux/inetdevice.h>
  29#include <linux/netdevice.h>
  30#include <linux/if_arp.h>
  31#include <linux/proc_fs.h>
  32#include <linux/skbuff.h>
  33#include <linux/netlink.h>
  34#include <linux/init.h>
  35
  36#include <net/net_namespace.h>
  37#include <net/ip.h>
  38#include <net/protocol.h>
  39#include <net/route.h>
  40#include <net/tcp.h>
  41#include <net/sock.h>
  42#include <net/ip_fib.h>
  43
  44#include "fib_lookup.h"
  45
  46static struct kmem_cache *fn_hash_kmem __read_mostly;
  47static struct kmem_cache *fn_alias_kmem __read_mostly;
  48
  49struct fib_node {
  50        struct hlist_node        fn_hash;
  51        struct list_head        fn_alias;
  52        __be32                        fn_key;
  53        struct fib_alias        fn_embedded_alias;
  54};
  55
  56struct fn_zone {
  57        struct fn_zone                *fz_next;        /* Next not empty zone        */
  58        struct hlist_head        *fz_hash;        /* Hash table pointer        */
  59        int                        fz_nent;        /* Number of entries        */
  60
  61        int                        fz_divisor;        /* Hash divisor                */
  62        u32                        fz_hashmask;        /* (fz_divisor - 1)        */
  63#define FZ_HASHMASK(fz)                ((fz)->fz_hashmask)
  64
  65        int                        fz_order;        /* Zone order                */
  66        __be32                        fz_mask;
  67#define FZ_MASK(fz)                ((fz)->fz_mask)
  68};
  69
  70/* NOTE. On fast computers evaluation of fz_hashmask and fz_mask
  71 * can be cheaper than memory lookup, so that FZ_* macros are used.
  72 */
  73
  74struct fn_hash {
  75        struct fn_zone        *fn_zones[33];
  76        struct fn_zone        *fn_zone_list;
  77};
  78
  79static inline u32 fn_hash(__be32 key, struct fn_zone *fz)
  80{
  81        u32 h = ntohl(key)>>(32 - fz->fz_order);
  82        h ^= (h>>20);
  83        h ^= (h>>10);
  84        h ^= (h>>5);
  85        h &= FZ_HASHMASK(fz);
  86        return h;
  87}
  88
  89static inline __be32 fz_key(__be32 dst, struct fn_zone *fz)
  90{
  91        return dst & FZ_MASK(fz);
  92}
  93
  94static DEFINE_RWLOCK(fib_hash_lock);
  95static unsigned int fib_hash_genid;
  96
  97#define FZ_MAX_DIVISOR ((PAGE_SIZE<<MAX_ORDER) / sizeof(struct hlist_head))
  98
  99static struct hlist_head *fz_hash_alloc(int divisor)
 100{
 101        unsigned long size = divisor * sizeof(struct hlist_head);
 102
 103        if (size <= PAGE_SIZE) {
 104                return kzalloc(size, GFP_KERNEL);
 105        } else {
 106                return (struct hlist_head *)
 107                        __get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(size));
 108        }
 109}
 110
 111/* The fib hash lock must be held when this is called. */
 112static inline void fn_rebuild_zone(struct fn_zone *fz,
 113                                   struct hlist_head *old_ht,
 114                                   int old_divisor)
 115{
 116        int i;
 117
 118        for (i = 0; i < old_divisor; i++) {
 119                struct hlist_node *node, *n;
 120                struct fib_node *f;
 121
 122                hlist_for_each_entry_safe(f, node, n, &old_ht[i], fn_hash) {
 123                        struct hlist_head *new_head;
 124
 125                        hlist_del(&f->fn_hash);
 126
 127                        new_head = &fz->fz_hash[fn_hash(f->fn_key, fz)];
 128                        hlist_add_head(&f->fn_hash, new_head);
 129                }
 130        }
 131}
 132
 133static void fz_hash_free(struct hlist_head *hash, int divisor)
 134{
 135        unsigned long size = divisor * sizeof(struct hlist_head);
 136
 137        if (size <= PAGE_SIZE)
 138                kfree(hash);
 139        else
 140                free_pages((unsigned long)hash, get_order(size));
 141}
 142
 143static void fn_rehash_zone(struct fn_zone *fz)
 144{
 145        struct hlist_head *ht, *old_ht;
 146        int old_divisor, new_divisor;
 147        u32 new_hashmask;
 148
 149        old_divisor = fz->fz_divisor;
 150
 151        switch (old_divisor) {
 152        case 16:
 153                new_divisor = 256;
 154                break;
 155        case 256:
 156                new_divisor = 1024;
 157                break;
 158        default:
 159                if ((old_divisor << 1) > FZ_MAX_DIVISOR) {
 160                        printk(KERN_CRIT "route.c: bad divisor %d!\n", old_divisor);
 161                        return;
 162                }
 163                new_divisor = (old_divisor << 1);
 164                break;
 165        }
 166
 167        new_hashmask = (new_divisor - 1);
 168
 169#if RT_CACHE_DEBUG >= 2
 170        printk(KERN_DEBUG "fn_rehash_zone: hash for zone %d grows from %d\n",
 171               fz->fz_order, old_divisor);
 172#endif
 173
 174        ht = fz_hash_alloc(new_divisor);
 175
 176        if (ht)        {
 177                write_lock_bh(&fib_hash_lock);
 178                old_ht = fz->fz_hash;
 179                fz->fz_hash = ht;
 180                fz->fz_hashmask = new_hashmask;
 181                fz->fz_divisor = new_divisor;
 182                fn_rebuild_zone(fz, old_ht, old_divisor);
 183                fib_hash_genid++;
 184                write_unlock_bh(&fib_hash_lock);
 185
 186                fz_hash_free(old_ht, old_divisor);
 187        }
 188}
 189
 190static inline void fn_free_node(struct fib_node * f)
 191{
 192        kmem_cache_free(fn_hash_kmem, f);
 193}
 194
 195static inline void fn_free_alias(struct fib_alias *fa, struct fib_node *f)
 196{
 197        fib_release_info(fa->fa_info);
 198        if (fa == &f->fn_embedded_alias)
 199                fa->fa_info = NULL;
 200        else
 201                kmem_cache_free(fn_alias_kmem, fa);
 202}
 203
 204static struct fn_zone *
 205fn_new_zone(struct fn_hash *table, int z)
 206{
 207        int i;
 208        struct fn_zone *fz = kzalloc(sizeof(struct fn_zone), GFP_KERNEL);
 209        if (!fz)
 210                return NULL;
 211
 212        if (z) {
 213                fz->fz_divisor = 16;
 214        } else {
 215                fz->fz_divisor = 1;
 216        }
 217        fz->fz_hashmask = (fz->fz_divisor - 1);
 218        fz->fz_hash = fz_hash_alloc(fz->fz_divisor);
 219        if (!fz->fz_hash) {
 220                kfree(fz);
 221                return NULL;
 222        }
 223        fz->fz_order = z;
 224        fz->fz_mask = inet_make_mask(z);
 225
 226        /* Find the first not empty zone with more specific mask */
 227        for (i=z+1; i<=32; i++)
 228                if (table->fn_zones[i])
 229                        break;
 230        write_lock_bh(&fib_hash_lock);
 231        if (i>32) {
 232                /* No more specific masks, we are the first. */
 233                fz->fz_next = table->fn_zone_list;
 234                table->fn_zone_list = fz;
 235        } else {
 236                fz->fz_next = table->fn_zones[i]->fz_next;
 237                table->fn_zones[i]->fz_next = fz;
 238        }
 239        table->fn_zones[z] = fz;
 240        fib_hash_genid++;
 241        write_unlock_bh(&fib_hash_lock);
 242        return fz;
 243}
 244
 245static int
 246fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
 247{
 248        int err;
 249        struct fn_zone *fz;
 250        struct fn_hash *t = (struct fn_hash*)tb->tb_data;
 251
 252        read_lock(&fib_hash_lock);
 253        for (fz = t->fn_zone_list; fz; fz = fz->fz_next) {
 254                struct hlist_head *head;
 255                struct hlist_node *node;
 256                struct fib_node *f;
 257                __be32 k = fz_key(flp->fl4_dst, fz);
 258
 259                head = &fz->fz_hash[fn_hash(k, fz)];
 260                hlist_for_each_entry(f, node, head, fn_hash) {
 261                        if (f->fn_key != k)
 262                                continue;
 263
 264                        err = fib_semantic_match(&f->fn_alias,
 265                                                 flp, res,
 266                                                 f->fn_key, fz->fz_mask,
 267                                                 fz->fz_order);
 268                        if (err <= 0)
 269                                goto out;
 270                }
 271        }
 272        err = 1;
 273out:
 274        read_unlock(&fib_hash_lock);
 275        return err;
 276}
 277
 278static void
 279fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
 280{
 281        int order, last_idx;
 282        struct hlist_node *node;
 283        struct fib_node *f;
 284        struct fib_info *fi = NULL;
 285        struct fib_info *last_resort;
 286        struct fn_hash *t = (struct fn_hash*)tb->tb_data;
 287        struct fn_zone *fz = t->fn_zones[0];
 288
 289        if (fz == NULL)
 290                return;
 291
 292        last_idx = -1;
 293        last_resort = NULL;
 294        order = -1;
 295
 296        read_lock(&fib_hash_lock);
 297        hlist_for_each_entry(f, node, &fz->fz_hash[0], fn_hash) {
 298                struct fib_alias *fa;
 299
 300                list_for_each_entry(fa, &f->fn_alias, fa_list) {
 301                        struct fib_info *next_fi = fa->fa_info;
 302
 303                        if (fa->fa_scope != res->scope ||
 304                            fa->fa_type != RTN_UNICAST)
 305                                continue;
 306
 307                        if (next_fi->fib_priority > res->fi->fib_priority)
 308                                break;
 309                        if (!next_fi->fib_nh[0].nh_gw ||
 310                            next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
 311                                continue;
 312                        fa->fa_state |= FA_S_ACCESSED;
 313
 314                        if (fi == NULL) {
 315                                if (next_fi != res->fi)
 316                                        break;
 317                        } else if (!fib_detect_death(fi, order, &last_resort,
 318                                                &last_idx, tb->tb_default)) {
 319                                fib_result_assign(res, fi);
 320                                tb->tb_default = order;
 321                                goto out;
 322                        }
 323                        fi = next_fi;
 324                        order++;
 325                }
 326        }
 327
 328        if (order <= 0 || fi == NULL) {
 329                tb->tb_default = -1;
 330                goto out;
 331        }
 332
 333        if (!fib_detect_death(fi, order, &last_resort, &last_idx,
 334                                tb->tb_default)) {
 335                fib_result_assign(res, fi);
 336                tb->tb_default = order;
 337                goto out;
 338        }
 339
 340        if (last_idx >= 0)
 341                fib_result_assign(res, last_resort);
 342        tb->tb_default = last_idx;
 343out:
 344        read_unlock(&fib_hash_lock);
 345}
 346
 347/* Insert node F to FZ. */
 348static inline void fib_insert_node(struct fn_zone *fz, struct fib_node *f)
 349{
 350        struct hlist_head *head = &fz->fz_hash[fn_hash(f->fn_key, fz)];
 351
 352        hlist_add_head(&f->fn_hash, head);
 353}
 354
 355/* Return the node in FZ matching KEY. */
 356static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key)
 357{
 358        struct hlist_head *head = &fz->fz_hash[fn_hash(key, fz)];
 359        struct hlist_node *node;
 360        struct fib_node *f;
 361
 362        hlist_for_each_entry(f, node, head, fn_hash) {
 363                if (f->fn_key == key)
 364                        return f;
 365        }
 366
 367        return NULL;
 368}
 369
 370static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
 371{
 372        struct fn_hash *table = (struct fn_hash *) tb->tb_data;
 373        struct fib_node *new_f = NULL;
 374        struct fib_node *f;
 375        struct fib_alias *fa, *new_fa;
 376        struct fn_zone *fz;
 377        struct fib_info *fi;
 378        u8 tos = cfg->fc_tos;
 379        __be32 key;
 380        int err;
 381
 382        if (cfg->fc_dst_len > 32)
 383                return -EINVAL;
 384
 385        fz = table->fn_zones[cfg->fc_dst_len];
 386        if (!fz && !(fz = fn_new_zone(table, cfg->fc_dst_len)))
 387                return -ENOBUFS;
 388
 389        key = 0;
 390        if (cfg->fc_dst) {
 391                if (cfg->fc_dst & ~FZ_MASK(fz))
 392                        return -EINVAL;
 393                key = fz_key(cfg->fc_dst, fz);
 394        }
 395
 396        fi = fib_create_info(cfg);
 397        if (IS_ERR(fi))
 398                return PTR_ERR(fi);
 399
 400        if (fz->fz_nent > (fz->fz_divisor<<1) &&
 401            fz->fz_divisor < FZ_MAX_DIVISOR &&
 402            (cfg->fc_dst_len == 32 ||
 403             (1 << cfg->fc_dst_len) > fz->fz_divisor))
 404                fn_rehash_zone(fz);
 405
 406        f = fib_find_node(fz, key);
 407
 408        if (!f)
 409                fa = NULL;
 410        else
 411                fa = fib_find_alias(&f->fn_alias, tos, fi->fib_priority);
 412
 413        /* Now fa, if non-NULL, points to the first fib alias
 414         * with the same keys [prefix,tos,priority], if such key already
 415         * exists or to the node before which we will insert new one.
 416         *
 417         * If fa is NULL, we will need to allocate a new one and
 418         * insert to the head of f.
 419         *
 420         * If f is NULL, no fib node matched the destination key
 421         * and we need to allocate a new one of those as well.
 422         */
 423
 424        if (fa && fa->fa_tos == tos &&
 425            fa->fa_info->fib_priority == fi->fib_priority) {
 426                struct fib_alias *fa_first, *fa_match;
 427
 428                err = -EEXIST;
 429                if (cfg->fc_nlflags & NLM_F_EXCL)
 430                        goto out;
 431
 432                /* We have 2 goals:
 433                 * 1. Find exact match for type, scope, fib_info to avoid
 434                 * duplicate routes
 435                 * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
 436                 */
 437                fa_match = NULL;
 438                fa_first = fa;
 439                fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
 440                list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
 441                        if (fa->fa_tos != tos)
 442                                break;
 443                        if (fa->fa_info->fib_priority != fi->fib_priority)
 444                                break;
 445                        if (fa->fa_type == cfg->fc_type &&
 446                            fa->fa_scope == cfg->fc_scope &&
 447                            fa->fa_info == fi) {
 448                                fa_match = fa;
 449                                break;
 450                        }
 451                }
 452
 453                if (cfg->fc_nlflags & NLM_F_REPLACE) {
 454                        struct fib_info *fi_drop;
 455                        u8 state;
 456
 457                        fa = fa_first;
 458                        if (fa_match) {
 459                                if (fa == fa_match)
 460                                        err = 0;
 461                                goto out;
 462                        }
 463                        write_lock_bh(&fib_hash_lock);
 464                        fi_drop = fa->fa_info;
 465                        fa->fa_info = fi;
 466                        fa->fa_type = cfg->fc_type;
 467                        fa->fa_scope = cfg->fc_scope;
 468                        state = fa->fa_state;
 469                        fa->fa_state &= ~FA_S_ACCESSED;
 470                        fib_hash_genid++;
 471                        write_unlock_bh(&fib_hash_lock);
 472
 473                        fib_release_info(fi_drop);
 474                        if (state & FA_S_ACCESSED)
 475                                rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
 476                        rtmsg_fib(RTM_NEWROUTE, key, fa, cfg->fc_dst_len, tb->tb_id,
 477                                  &cfg->fc_nlinfo, NLM_F_REPLACE);
 478                        return 0;
 479                }
 480
 481                /* Error if we find a perfect match which
 482                 * uses the same scope, type, and nexthop
 483                 * information.
 484                 */
 485                if (fa_match)
 486                        goto out;
 487
 488                if (!(cfg->fc_nlflags & NLM_F_APPEND))
 489                        fa = fa_first;
 490        }
 491
 492        err = -ENOENT;
 493        if (!(cfg->fc_nlflags & NLM_F_CREATE))
 494                goto out;
 495
 496        err = -ENOBUFS;
 497
 498        if (!f) {
 499                new_f = kmem_cache_zalloc(fn_hash_kmem, GFP_KERNEL);
 500                if (new_f == NULL)
 501                        goto out;
 502
 503                INIT_HLIST_NODE(&new_f->fn_hash);
 504                INIT_LIST_HEAD(&new_f->fn_alias);
 505                new_f->fn_key = key;
 506                f = new_f;
 507        }
 508
 509        new_fa = &f->fn_embedded_alias;
 510        if (new_fa->fa_info != NULL) {
 511                new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
 512                if (new_fa == NULL)
 513                        goto out;
 514        }
 515        new_fa->fa_info = fi;
 516        new_fa->fa_tos = tos;
 517        new_fa->fa_type = cfg->fc_type;
 518        new_fa->fa_scope = cfg->fc_scope;
 519        new_fa->fa_state = 0;
 520
 521        /*
 522         * Insert new entry to the list.
 523         */
 524
 525        write_lock_bh(&fib_hash_lock);
 526        if (new_f)
 527                fib_insert_node(fz, new_f);
 528        list_add_tail(&new_fa->fa_list,
 529                 (fa ? &fa->fa_list : &f->fn_alias));
 530        fib_hash_genid++;
 531        write_unlock_bh(&fib_hash_lock);
 532
 533        if (new_f)
 534                fz->fz_nent++;
 535        rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
 536
 537        rtmsg_fib(RTM_NEWROUTE, key, new_fa, cfg->fc_dst_len, tb->tb_id,
 538                  &cfg->fc_nlinfo, 0);
 539        return 0;
 540
 541out:
 542        if (new_f)
 543                kmem_cache_free(fn_hash_kmem, new_f);
 544        fib_release_info(fi);
 545        return err;
 546}
 547
 548
 549static int fn_hash_delete(struct fib_table *tb, struct fib_config *cfg)
 550{
 551        struct fn_hash *table = (struct fn_hash*)tb->tb_data;
 552        struct fib_node *f;
 553        struct fib_alias *fa, *fa_to_delete;
 554        struct fn_zone *fz;
 555        __be32 key;
 556
 557        if (cfg->fc_dst_len > 32)
 558                return -EINVAL;
 559
 560        if ((fz  = table->fn_zones[cfg->fc_dst_len]) == NULL)
 561                return -ESRCH;
 562
 563        key = 0;
 564        if (cfg->fc_dst) {
 565                if (cfg->fc_dst & ~FZ_MASK(fz))
 566                        return -EINVAL;
 567                key = fz_key(cfg->fc_dst, fz);
 568        }
 569
 570        f = fib_find_node(fz, key);
 571
 572        if (!f)
 573                fa = NULL;
 574        else
 575                fa = fib_find_alias(&f->fn_alias, cfg->fc_tos, 0);
 576        if (!fa)
 577                return -ESRCH;
 578
 579        fa_to_delete = NULL;
 580        fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
 581        list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
 582                struct fib_info *fi = fa->fa_info;
 583
 584                if (fa->fa_tos != cfg->fc_tos)
 585                        break;
 586
 587                if ((!cfg->fc_type ||
 588                     fa->fa_type == cfg->fc_type) &&
 589                    (cfg->fc_scope == RT_SCOPE_NOWHERE ||
 590                     fa->fa_scope == cfg->fc_scope) &&
 591                    (!cfg->fc_protocol ||
 592                     fi->fib_protocol == cfg->fc_protocol) &&
 593                    fib_nh_match(cfg, fi) == 0) {
 594                        fa_to_delete = fa;
 595                        break;
 596                }
 597        }
 598
 599        if (fa_to_delete) {
 600                int kill_fn;
 601
 602                fa = fa_to_delete;
 603                rtmsg_fib(RTM_DELROUTE, key, fa, cfg->fc_dst_len,
 604                          tb->tb_id, &cfg->fc_nlinfo, 0);
 605
 606                kill_fn = 0;
 607                write_lock_bh(&fib_hash_lock);
 608                list_del(&fa->fa_list);
 609                if (list_empty(&f->fn_alias)) {
 610                        hlist_del(&f->fn_hash);
 611                        kill_fn = 1;
 612                }
 613                fib_hash_genid++;
 614                write_unlock_bh(&fib_hash_lock);
 615
 616                if (fa->fa_state & FA_S_ACCESSED)
 617                        rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
 618                fn_free_alias(fa, f);
 619                if (kill_fn) {
 620                        fn_free_node(f);
 621                        fz->fz_nent--;
 622                }
 623
 624                return 0;
 625        }
 626        return -ESRCH;
 627}
 628
 629static int fn_flush_list(struct fn_zone *fz, int idx)
 630{
 631        struct hlist_head *head = &fz->fz_hash[idx];
 632        struct hlist_node *node, *n;
 633        struct fib_node *f;
 634        int found = 0;
 635
 636        hlist_for_each_entry_safe(f, node, n, head, fn_hash) {
 637                struct fib_alias *fa, *fa_node;
 638                int kill_f;
 639
 640                kill_f = 0;
 641                list_for_each_entry_safe(fa, fa_node, &f->fn_alias, fa_list) {
 642                        struct fib_info *fi = fa->fa_info;
 643
 644                        if (fi && (fi->fib_flags&RTNH_F_DEAD)) {
 645                                write_lock_bh(&fib_hash_lock);
 646                                list_del(&fa->fa_list);
 647                                if (list_empty(&f->fn_alias)) {
 648                                        hlist_del(&f->fn_hash);
 649                                        kill_f = 1;
 650                                }
 651                                fib_hash_genid++;
 652                                write_unlock_bh(&fib_hash_lock);
 653
 654                                fn_free_alias(fa, f);
 655                                found++;
 656                        }
 657                }
 658                if (kill_f) {
 659                        fn_free_node(f);
 660                        fz->fz_nent--;
 661                }
 662        }
 663        return found;
 664}
 665
 666static int fn_hash_flush(struct fib_table *tb)
 667{
 668        struct fn_hash *table = (struct fn_hash *) tb->tb_data;
 669        struct fn_zone *fz;
 670        int found = 0;
 671
 672        for (fz = table->fn_zone_list; fz; fz = fz->fz_next) {
 673                int i;
 674
 675                for (i = fz->fz_divisor - 1; i >= 0; i--)
 676                        found += fn_flush_list(fz, i);
 677        }
 678        return found;
 679}
 680
 681
 682static inline int
 683fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb,
 684                     struct fib_table *tb,
 685                     struct fn_zone *fz,
 686                     struct hlist_head *head)
 687{
 688        struct hlist_node *node;
 689        struct fib_node *f;
 690        int i, s_i;
 691
 692        s_i = cb->args[4];
 693        i = 0;
 694        hlist_for_each_entry(f, node, head, fn_hash) {
 695                struct fib_alias *fa;
 696
 697                list_for_each_entry(fa, &f->fn_alias, fa_list) {
 698                        if (i < s_i)
 699                                goto next;
 700
 701                        if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
 702                                          cb->nlh->nlmsg_seq,
 703                                          RTM_NEWROUTE,
 704                                          tb->tb_id,
 705                                          fa->fa_type,
 706                                          fa->fa_scope,
 707                                          f->fn_key,
 708                                          fz->fz_order,
 709                                          fa->fa_tos,
 710                                          fa->fa_info,
 711                                          NLM_F_MULTI) < 0) {
 712                                cb->args[4] = i;
 713                                return -1;
 714                        }
 715                next:
 716                        i++;
 717                }
 718        }
 719        cb->args[4] = i;
 720        return skb->len;
 721}
 722
 723static inline int
 724fn_hash_dump_zone(struct sk_buff *skb, struct netlink_callback *cb,
 725                   struct fib_table *tb,
 726                   struct fn_zone *fz)
 727{
 728        int h, s_h;
 729
 730        if (fz->fz_hash == NULL)
 731                return skb->len;
 732        s_h = cb->args[3];
 733        for (h = s_h; h < fz->fz_divisor; h++) {
 734                if (hlist_empty(&fz->fz_hash[h]))
 735                        continue;
 736                if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h]) < 0) {
 737                        cb->args[3] = h;
 738                        return -1;
 739                }
 740                memset(&cb->args[4], 0,
 741                       sizeof(cb->args) - 4*sizeof(cb->args[0]));
 742        }
 743        cb->args[3] = h;
 744        return skb->len;
 745}
 746
 747static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb)
 748{
 749        int m, s_m;
 750        struct fn_zone *fz;
 751        struct fn_hash *table = (struct fn_hash*)tb->tb_data;
 752
 753        s_m = cb->args[2];
 754        read_lock(&fib_hash_lock);
 755        for (fz = table->fn_zone_list, m=0; fz; fz = fz->fz_next, m++) {
 756                if (m < s_m) continue;
 757                if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) {
 758                        cb->args[2] = m;
 759                        read_unlock(&fib_hash_lock);
 760                        return -1;
 761                }
 762                memset(&cb->args[3], 0,
 763                       sizeof(cb->args) - 3*sizeof(cb->args[0]));
 764        }
 765        read_unlock(&fib_hash_lock);
 766        cb->args[2] = m;
 767        return skb->len;
 768}
 769
 770void __init fib_hash_init(void)
 771{
 772        fn_hash_kmem = kmem_cache_create("ip_fib_hash", sizeof(struct fib_node),
 773                                         0, SLAB_PANIC, NULL);
 774
 775        fn_alias_kmem = kmem_cache_create("ip_fib_alias", sizeof(struct fib_alias),
 776                                          0, SLAB_PANIC, NULL);
 777
 778}
 779
 780struct fib_table *fib_hash_table(u32 id)
 781{
 782        struct fib_table *tb;
 783
 784        tb = kmalloc(sizeof(struct fib_table) + sizeof(struct fn_hash),
 785                     GFP_KERNEL);
 786        if (tb == NULL)
 787                return NULL;
 788
 789        tb->tb_id = id;
 790        tb->tb_default = -1;
 791        tb->tb_lookup = fn_hash_lookup;
 792        tb->tb_insert = fn_hash_insert;
 793        tb->tb_delete = fn_hash_delete;
 794        tb->tb_flush = fn_hash_flush;
 795        tb->tb_select_default = fn_hash_select_default;
 796        tb->tb_dump = fn_hash_dump;
 797        memset(tb->tb_data, 0, sizeof(struct fn_hash));
 798        return tb;
 799}
 800
 801/* ------------------------------------------------------------------------ */
 802#ifdef CONFIG_PROC_FS
 803
 804struct fib_iter_state {
 805        struct seq_net_private p;
 806        struct fn_zone        *zone;
 807        int                bucket;
 808        struct hlist_head *hash_head;
 809        struct fib_node *fn;
 810        struct fib_alias *fa;
 811        loff_t pos;
 812        unsigned int genid;
 813        int valid;
 814};
 815
 816static struct fib_alias *fib_get_first(struct seq_file *seq)
 817{
 818        struct fib_iter_state *iter = seq->private;
 819        struct fib_table *main_table;
 820        struct fn_hash *table;
 821
 822        main_table = fib_get_table(seq_file_net(seq), RT_TABLE_MAIN);
 823        table = (struct fn_hash *)main_table->tb_data;
 824
 825        iter->bucket    = 0;
 826        iter->hash_head = NULL;
 827        iter->fn        = NULL;
 828        iter->fa        = NULL;
 829        iter->pos        = 0;
 830        iter->genid        = fib_hash_genid;
 831        iter->valid        = 1;
 832
 833        for (iter->zone = table->fn_zone_list; iter->zone;
 834             iter->zone = iter->zone->fz_next) {
 835                int maxslot;
 836
 837                if (!iter->zone->fz_nent)
 838                        continue;
 839
 840                iter->hash_head = iter->zone->fz_hash;
 841                maxslot = iter->zone->fz_divisor;
 842
 843                for (iter->bucket = 0; iter->bucket < maxslot;
 844                     ++iter->bucket, ++iter->hash_head) {
 845                        struct hlist_node *node;
 846                        struct fib_node *fn;
 847
 848                        hlist_for_each_entry(fn,node,iter->hash_head,fn_hash) {
 849                                struct fib_alias *fa;
 850
 851                                list_for_each_entry(fa,&fn->fn_alias,fa_list) {
 852                                        iter->fn = fn;
 853                                        iter->fa = fa;
 854                                        goto out;
 855                                }
 856                        }
 857                }
 858        }
 859out:
 860        return iter->fa;
 861}
 862
 863static struct fib_alias *fib_get_next(struct seq_file *seq)
 864{
 865        struct fib_iter_state *iter = seq->private;
 866        struct fib_node *fn;
 867        struct fib_alias *fa;
 868
 869        /* Advance FA, if any. */
 870        fn = iter->fn;
 871        fa = iter->fa;
 872        if (fa) {
 873                BUG_ON(!fn);
 874                list_for_each_entry_continue(fa, &fn->fn_alias, fa_list) {
 875                        iter->fa = fa;
 876                        goto out;
 877                }
 878        }
 879
 880        fa = iter->fa = NULL;
 881
 882        /* Advance FN. */
 883        if (fn) {
 884                struct hlist_node *node = &fn->fn_hash;
 885                hlist_for_each_entry_continue(fn, node, fn_hash) {
 886                        iter->fn = fn;
 887
 888                        list_for_each_entry(fa, &fn->fn_alias, fa_list) {
 889                                iter->fa = fa;
 890                                goto out;
 891                        }
 892                }
 893        }
 894
 895        fn = iter->fn = NULL;
 896
 897        /* Advance hash chain. */
 898        if (!iter->zone)
 899                goto out;
 900
 901        for (;;) {
 902                struct hlist_node *node;
 903                int maxslot;
 904
 905                maxslot = iter->zone->fz_divisor;
 906
 907                while (++iter->bucket < maxslot) {
 908                        iter->hash_head++;
 909
 910                        hlist_for_each_entry(fn, node, iter->hash_head, fn_hash) {
 911                                list_for_each_entry(fa, &fn->fn_alias, fa_list) {
 912                                        iter->fn = fn;
 913                                        iter->fa = fa;
 914                                        goto out;
 915                                }
 916                        }
 917                }
 918
 919                iter->zone = iter->zone->fz_next;
 920
 921                if (!iter->zone)
 922                        goto out;
 923
 924                iter->bucket = 0;
 925                iter->hash_head = iter->zone->fz_hash;
 926
 927                hlist_for_each_entry(fn, node, iter->hash_head, fn_hash) {
 928                        list_for_each_entry(fa, &fn->fn_alias, fa_list) {
 929                                iter->fn = fn;
 930                                iter->fa = fa;
 931                                goto out;
 932                        }
 933                }
 934        }
 935out:
 936        iter->pos++;
 937        return fa;
 938}
 939
 940static struct fib_alias *fib_get_idx(struct seq_file *seq, loff_t pos)
 941{
 942        struct fib_iter_state *iter = seq->private;
 943        struct fib_alias *fa;
 944
 945        if (iter->valid && pos >= iter->pos && iter->genid == fib_hash_genid) {
 946                fa   = iter->fa;
 947                pos -= iter->pos;
 948        } else
 949                fa = fib_get_first(seq);
 950
 951        if (fa)
 952                while (pos && (fa = fib_get_next(seq)))
 953                        --pos;
 954        return pos ? NULL : fa;
 955}
 956
 957static void *fib_seq_start(struct seq_file *seq, loff_t *pos)
 958        __acquires(fib_hash_lock)
 959{
 960        void *v = NULL;
 961
 962        read_lock(&fib_hash_lock);
 963        if (fib_get_table(seq_file_net(seq), RT_TABLE_MAIN))
 964                v = *pos ? fib_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
 965        return v;
 966}
 967
 968static void *fib_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 969{
 970        ++*pos;
 971        return v == SEQ_START_TOKEN ? fib_get_first(seq) : fib_get_next(seq);
 972}
 973
 974static void fib_seq_stop(struct seq_file *seq, void *v)
 975        __releases(fib_hash_lock)
 976{
 977        read_unlock(&fib_hash_lock);
 978}
 979
 980static unsigned fib_flag_trans(int type, __be32 mask, struct fib_info *fi)
 981{
 982        static const unsigned type2flags[RTN_MAX + 1] = {
 983                [7] = RTF_REJECT, [8] = RTF_REJECT,
 984        };
 985        unsigned flags = type2flags[type];
 986
 987        if (fi && fi->fib_nh->nh_gw)
 988                flags |= RTF_GATEWAY;
 989        if (mask == htonl(0xFFFFFFFF))
 990                flags |= RTF_HOST;
 991        flags |= RTF_UP;
 992        return flags;
 993}
 994
 995/*
 996 *        This outputs /proc/net/route.
 997 *
 998 *        It always works in backward compatibility mode.
 999 *        The format of the file is not supposed to be changed.
1000 */
1001static int fib_seq_show(struct seq_file *seq, void *v)
1002{
1003        struct fib_iter_state *iter;
1004        int len;
1005        __be32 prefix, mask;
1006        unsigned flags;
1007        struct fib_node *f;
1008        struct fib_alias *fa;
1009        struct fib_info *fi;
1010
1011        if (v == SEQ_START_TOKEN) {
1012                seq_printf(seq, "%-127s\n", "Iface\tDestination\tGateway "
1013                           "\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU"
1014                           "\tWindow\tIRTT");
1015                goto out;
1016        }
1017
1018        iter        = seq->private;
1019        f        = iter->fn;
1020        fa        = iter->fa;
1021        fi        = fa->fa_info;
1022        prefix        = f->fn_key;
1023        mask        = FZ_MASK(iter->zone);
1024        flags        = fib_flag_trans(fa->fa_type, mask, fi);
1025        if (fi)
1026                seq_printf(seq,
1027                         "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u%n",
1028                         fi->fib_dev ? fi->fib_dev->name : "*", prefix,
1029                         fi->fib_nh->nh_gw, flags, 0, 0, fi->fib_priority,
1030                         mask, (fi->fib_advmss ? fi->fib_advmss + 40 : 0),
1031                         fi->fib_window,
1032                         fi->fib_rtt >> 3, &len);
1033        else
1034                seq_printf(seq,
1035                         "*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u%n",
1036                         prefix, 0, flags, 0, 0, 0, mask, 0, 0, 0, &len);
1037
1038        seq_printf(seq, "%*s\n", 127 - len, "");
1039out:
1040        return 0;
1041}
1042
1043static const struct seq_operations fib_seq_ops = {
1044        .start  = fib_seq_start,
1045        .next   = fib_seq_next,
1046        .stop   = fib_seq_stop,
1047        .show   = fib_seq_show,
1048};
1049
1050static int fib_seq_open(struct inode *inode, struct file *file)
1051{
1052        return seq_open_net(inode, file, &fib_seq_ops,
1053                            sizeof(struct fib_iter_state));
1054}
1055
1056static const struct file_operations fib_seq_fops = {
1057        .owner                = THIS_MODULE,
1058        .open           = fib_seq_open,
1059        .read           = seq_read,
1060        .llseek         = seq_lseek,
1061        .release        = seq_release_net,
1062};
1063
1064int __net_init fib_proc_init(struct net *net)
1065{
1066        if (!proc_net_fops_create(net, "route", S_IRUGO, &fib_seq_fops))
1067                return -ENOMEM;
1068        return 0;
1069}
1070
1071void __net_exit fib_proc_exit(struct net *net)
1072{
1073        proc_net_remove(net, "route");
1074}
1075#endif /* CONFIG_PROC_FS */