Skip to content

Commit 4895c77

Browse files
committed
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>
1 parent 6700c27 commit 4895c77

File tree

3 files changed

+266
-31
lines changed

3 files changed

+266
-31
lines changed

include/net/ip_fib.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <net/flow.h>
2020
#include <linux/seq_file.h>
21+
#include <linux/rcupdate.h>
2122
#include <net/fib_rules.h>
2223
#include <net/inetpeer.h>
2324

@@ -46,6 +47,22 @@ struct fib_config {
4647

4748
struct fib_info;
4849

50+
struct fib_nh_exception {
51+
struct fib_nh_exception __rcu *fnhe_next;
52+
__be32 fnhe_daddr;
53+
u32 fnhe_pmtu;
54+
u32 fnhe_gw;
55+
unsigned long fnhe_expires;
56+
unsigned long fnhe_stamp;
57+
};
58+
59+
struct fnhe_hash_bucket {
60+
struct fib_nh_exception __rcu *chain;
61+
};
62+
63+
#define FNHE_HASH_SIZE 2048
64+
#define FNHE_RECLAIM_DEPTH 5
65+
4966
struct fib_nh {
5067
struct net_device *nh_dev;
5168
struct hlist_node nh_hash;
@@ -63,6 +80,7 @@ struct fib_nh {
6380
__be32 nh_gw;
6481
__be32 nh_saddr;
6582
int nh_saddr_genid;
83+
struct fnhe_hash_bucket *nh_exceptions;
6684
};
6785

6886
/*

net/ipv4/fib_semantics.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,27 @@ const struct fib_prop fib_props[RTN_MAX + 1] = {
140140
},
141141
};
142142

143+
static void free_nh_exceptions(struct fib_nh *nh)
144+
{
145+
struct fnhe_hash_bucket *hash = nh->nh_exceptions;
146+
int i;
147+
148+
for (i = 0; i < FNHE_HASH_SIZE; i++) {
149+
struct fib_nh_exception *fnhe;
150+
151+
fnhe = rcu_dereference(hash[i].chain);
152+
while (fnhe) {
153+
struct fib_nh_exception *next;
154+
155+
next = rcu_dereference(fnhe->fnhe_next);
156+
kfree(fnhe);
157+
158+
fnhe = next;
159+
}
160+
}
161+
kfree(hash);
162+
}
163+
143164
/* Release a nexthop info record */
144165
static void free_fib_info_rcu(struct rcu_head *head)
145166
{
@@ -148,6 +169,8 @@ static void free_fib_info_rcu(struct rcu_head *head)
148169
change_nexthops(fi) {
149170
if (nexthop_nh->nh_dev)
150171
dev_put(nexthop_nh->nh_dev);
172+
if (nexthop_nh->nh_exceptions)
173+
free_nh_exceptions(nexthop_nh);
151174
} endfor_nexthops(fi);
152175

153176
release_net(fi->fib_net);

0 commit comments

Comments
 (0)