git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git]
/
net
/
ipv4
/
fib_hash.c
diff --git
a/net/ipv4/fib_hash.c
b/net/ipv4/fib_hash.c
index
4cbbdf8
..
c9b54bb
100644
(file)
--- a/
net/ipv4/fib_hash.c
+++ b/
net/ipv4/fib_hash.c
@@
-29,6
+29,7
@@
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/inet.h>
+#include <linux/inetdevice.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/proc_fs.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/proc_fs.h>
@@
-45,8
+46,8
@@
#include "fib_lookup.h"
#include "fib_lookup.h"
-static kmem_cache_t *fn_hash_kmem;
-static kmem_cache_t *fn_alias_kmem;
+static kmem_cache_t *fn_hash_kmem
__read_mostly
;
+static kmem_cache_t *fn_alias_kmem
__read_mostly
;
struct fib_node {
struct hlist_node fn_hash;
struct fib_node {
struct hlist_node fn_hash;
@@
-93,6
+94,7
@@
static inline u32 fz_key(u32 dst, struct fn_zone *fz)
}
static DEFINE_RWLOCK(fib_hash_lock);
}
static DEFINE_RWLOCK(fib_hash_lock);
+static unsigned int fib_hash_genid;
#define FZ_MAX_DIVISOR ((PAGE_SIZE<<MAX_ORDER) / sizeof(struct hlist_head))
#define FZ_MAX_DIVISOR ((PAGE_SIZE<<MAX_ORDER) / sizeof(struct hlist_head))
@@
-181,6
+183,7
@@
static void fn_rehash_zone(struct fn_zone *fz)
fz->fz_hashmask = new_hashmask;
fz->fz_divisor = new_divisor;
fn_rebuild_zone(fz, old_ht, old_divisor);
fz->fz_hashmask = new_hashmask;
fz->fz_divisor = new_divisor;
fn_rebuild_zone(fz, old_ht, old_divisor);
+ fib_hash_genid++;
write_unlock_bh(&fib_hash_lock);
fz_hash_free(old_ht, old_divisor);
write_unlock_bh(&fib_hash_lock);
fz_hash_free(old_ht, old_divisor);
@@
-236,6
+239,7
@@
fn_new_zone(struct fn_hash *table, int z)
table->fn_zones[i]->fz_next = fz;
}
table->fn_zones[z] = fz;
table->fn_zones[i]->fz_next = fz;
}
table->fn_zones[z] = fz;
+ fib_hash_genid++;
write_unlock_bh(&fib_hash_lock);
return fz;
}
write_unlock_bh(&fib_hash_lock);
return fz;
}
@@
-261,6
+265,7
@@
fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
err = fib_semantic_match(&f->fn_alias,
flp, res,
err = fib_semantic_match(&f->fn_alias,
flp, res,
+ f->fn_key, fz->fz_mask,
fz->fz_order);
if (err <= 0)
goto out;
fz->fz_order);
if (err <= 0)
goto out;
@@
-451,6
+456,7
@@
fn_hash_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
fa->fa_scope = r->rtm_scope;
state = fa->fa_state;
fa->fa_state &= ~FA_S_ACCESSED;
fa->fa_scope = r->rtm_scope;
state = fa->fa_state;
fa->fa_state &= ~FA_S_ACCESSED;
+ fib_hash_genid++;
write_unlock_bh(&fib_hash_lock);
fib_release_info(fi_drop);
write_unlock_bh(&fib_hash_lock);
fib_release_info(fi_drop);
@@
-515,6
+521,7
@@
fn_hash_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
fib_insert_node(fz, new_f);
list_add_tail(&new_fa->fa_list,
(fa ? &fa->fa_list : &f->fn_alias));
fib_insert_node(fz, new_f);
list_add_tail(&new_fa->fa_list,
(fa ? &fa->fa_list : &f->fn_alias));
+ fib_hash_genid++;
write_unlock_bh(&fib_hash_lock);
if (new_f)
write_unlock_bh(&fib_hash_lock);
if (new_f)
@@
-600,6
+607,7
@@
fn_hash_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
hlist_del(&f->fn_hash);
kill_fn = 1;
}
hlist_del(&f->fn_hash);
kill_fn = 1;
}
+ fib_hash_genid++;
write_unlock_bh(&fib_hash_lock);
if (fa->fa_state & FA_S_ACCESSED)
write_unlock_bh(&fib_hash_lock);
if (fa->fa_state & FA_S_ACCESSED)
@@
-637,6
+645,7
@@
static int fn_flush_list(struct fn_zone *fz, int idx)
hlist_del(&f->fn_hash);
kill_f = 1;
}
hlist_del(&f->fn_hash);
kill_f = 1;
}
+ fib_hash_genid++;
write_unlock_bh(&fib_hash_lock);
fn_free_alias(fa);
write_unlock_bh(&fib_hash_lock);
fn_free_alias(fa);
@@
-695,7
+704,8
@@
fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb,
&f->fn_key,
fz->fz_order,
fa->fa_tos,
&f->fn_key,
fz->fz_order,
fa->fa_tos,
- fa->fa_info) < 0) {
+ fa->fa_info,
+ NLM_F_MULTI) < 0) {
cb->args[3] = i;
return -1;
}
cb->args[3] = i;
return -1;
}
@@
-801,6
+811,9
@@
struct fib_iter_state {
struct hlist_head *hash_head;
struct fib_node *fn;
struct fib_alias *fa;
struct hlist_head *hash_head;
struct fib_node *fn;
struct fib_alias *fa;
+ loff_t pos;
+ unsigned int genid;
+ int valid;
};
static struct fib_alias *fib_get_first(struct seq_file *seq)
};
static struct fib_alias *fib_get_first(struct seq_file *seq)
@@
-812,6
+825,9
@@
static struct fib_alias *fib_get_first(struct seq_file *seq)
iter->hash_head = NULL;
iter->fn = NULL;
iter->fa = NULL;
iter->hash_head = NULL;
iter->fn = NULL;
iter->fa = NULL;
+ iter->pos = 0;
+ iter->genid = fib_hash_genid;
+ iter->valid = 1;
for (iter->zone = table->fn_zone_list; iter->zone;
iter->zone = iter->zone->fz_next) {
for (iter->zone = table->fn_zone_list; iter->zone;
iter->zone = iter->zone->fz_next) {
@@
-916,12
+932,20
@@
static struct fib_alias *fib_get_next(struct seq_file *seq)
}
}
out:
}
}
out:
+ iter->pos++;
return fa;
}
static struct fib_alias *fib_get_idx(struct seq_file *seq, loff_t pos)
{
return fa;
}
static struct fib_alias *fib_get_idx(struct seq_file *seq, loff_t pos)
{
- struct fib_alias *fa = fib_get_first(seq);
+ struct fib_iter_state *iter = seq->private;
+ struct fib_alias *fa;
+
+ if (iter->valid && pos >= iter->pos && iter->genid == fib_hash_genid) {
+ fa = iter->fa;
+ pos -= iter->pos;
+ } else
+ fa = fib_get_first(seq);
if (fa)
while (pos && (fa = fib_get_next(seq)))
if (fa)
while (pos && (fa = fib_get_next(seq)))
@@
-952,7
+976,7
@@
static void fib_seq_stop(struct seq_file *seq, void *v)
static unsigned fib_flag_trans(int type, u32 mask, struct fib_info *fi)
{
static unsigned fib_flag_trans(int type, u32 mask, struct fib_info *fi)
{
- static unsigned type2flags[RTN_MAX + 1] = {
+ static
const
unsigned type2flags[RTN_MAX + 1] = {
[7] = RTF_REJECT, [8] = RTF_REJECT,
};
unsigned flags = type2flags[type];
[7] = RTF_REJECT, [8] = RTF_REJECT,
};
unsigned flags = type2flags[type];