diff options
author | David S. Miller <davem@davemloft.net> | 2012-07-17 04:19:00 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-17 08:48:50 -0700 |
commit | 4895c771c7f006b4b90f9d6b1d2210939ba57b38 (patch) | |
tree | 66b132799e33a215b88bf3945965fefa7a0cde24 /net/ipv4/fib_semantics.c | |
parent | 6700c2709c08d74ae2c3c29b84a30da012dbc7f1 (diff) | |
download | linux-stable-4895c771c7f006b4b90f9d6b1d2210939ba57b38.tar.gz linux-stable-4895c771c7f006b4b90f9d6b1d2210939ba57b38.tar.bz2 linux-stable-4895c771c7f006b4b90f9d6b1d2210939ba57b38.zip |
ipv4: Add FIB nexthop exceptions.
In a regime where we have subnetted route entries, we need a way to
store persistent storage about destination specific learned values
such as redirects and PMTU values.
This is implemented here via nexthop exceptions.
The initial implementation is a 2048 entry hash table with relaiming
starting at chain length 5. A more sophisticated scheme can be
devised if that proves necessary.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_semantics.c')
-rw-r--r-- | net/ipv4/fib_semantics.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index d71bfbdc0bf4..1e09852df512 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -140,6 +140,27 @@ const struct fib_prop fib_props[RTN_MAX + 1] = { }, }; +static void free_nh_exceptions(struct fib_nh *nh) +{ + struct fnhe_hash_bucket *hash = nh->nh_exceptions; + int i; + + for (i = 0; i < FNHE_HASH_SIZE; i++) { + struct fib_nh_exception *fnhe; + + fnhe = rcu_dereference(hash[i].chain); + while (fnhe) { + struct fib_nh_exception *next; + + next = rcu_dereference(fnhe->fnhe_next); + kfree(fnhe); + + fnhe = next; + } + } + kfree(hash); +} + /* Release a nexthop info record */ static void free_fib_info_rcu(struct rcu_head *head) { @@ -148,6 +169,8 @@ static void free_fib_info_rcu(struct rcu_head *head) change_nexthops(fi) { if (nexthop_nh->nh_dev) dev_put(nexthop_nh->nh_dev); + if (nexthop_nh->nh_exceptions) + free_nh_exceptions(nexthop_nh); } endfor_nexthops(fi); release_net(fi->fib_net); |