aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip_fib.h39
-rw-r--r--net/ipv4/fib_frontend.c29
2 files changed, 40 insertions, 28 deletions
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 338d3ed10c31..249af662e897 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -120,16 +120,22 @@ struct fib_result_nl {
120 int err; 120 int err;
121}; 121};
122 122
123extern struct hlist_head fib_table_hash[];
124
123#ifdef CONFIG_IP_ROUTE_MULTIPATH 125#ifdef CONFIG_IP_ROUTE_MULTIPATH
124 126
125#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel]) 127#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
126#define FIB_RES_RESET(res) ((res).nh_sel = 0) 128#define FIB_RES_RESET(res) ((res).nh_sel = 0)
127 129
130#define FIB_TABLE_HASHSZ 2
131
128#else /* CONFIG_IP_ROUTE_MULTIPATH */ 132#else /* CONFIG_IP_ROUTE_MULTIPATH */
129 133
130#define FIB_RES_NH(res) ((res).fi->fib_nh[0]) 134#define FIB_RES_NH(res) ((res).fi->fib_nh[0])
131#define FIB_RES_RESET(res) 135#define FIB_RES_RESET(res)
132 136
137#define FIB_TABLE_HASHSZ 256
138
133#endif /* CONFIG_IP_ROUTE_MULTIPATH */ 139#endif /* CONFIG_IP_ROUTE_MULTIPATH */
134 140
135#define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res)) 141#define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res))
@@ -156,14 +162,17 @@ struct fib_table {
156 162
157#ifndef CONFIG_IP_MULTIPLE_TABLES 163#ifndef CONFIG_IP_MULTIPLE_TABLES
158 164
159extern struct fib_table *ip_fib_local_table; 165#define TABLE_LOCAL_INDEX 0
160extern struct fib_table *ip_fib_main_table; 166#define TABLE_MAIN_INDEX 1
161 167
162static inline struct fib_table *fib_get_table(u32 id) 168static inline struct fib_table *fib_get_table(u32 id)
163{ 169{
164 if (id != RT_TABLE_LOCAL) 170 struct hlist_head *ptr;
165 return ip_fib_main_table; 171
166 return ip_fib_local_table; 172 ptr = id == RT_TABLE_LOCAL ?
173 &fib_table_hash[TABLE_LOCAL_INDEX] :
174 &fib_table_hash[TABLE_MAIN_INDEX];
175 return hlist_entry(ptr->first, struct fib_table, tb_hlist);
167} 176}
168 177
169static inline struct fib_table *fib_new_table(u32 id) 178static inline struct fib_table *fib_new_table(u32 id)
@@ -173,16 +182,24 @@ static inline struct fib_table *fib_new_table(u32 id)
173 182
174static inline int fib_lookup(const struct flowi *flp, struct fib_result *res) 183static inline int fib_lookup(const struct flowi *flp, struct fib_result *res)
175{ 184{
176 if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) && 185 struct fib_table *table;
177 ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res)) 186
178 return -ENETUNREACH; 187 table = fib_get_table(RT_TABLE_LOCAL);
179 return 0; 188 if (!table->tb_lookup(table, flp, res))
189 return 0;
190
191 table = fib_get_table(RT_TABLE_MAIN);
192 if (!table->tb_lookup(table, flp, res))
193 return 0;
194 return -ENETUNREACH;
180} 195}
181 196
182static inline void fib_select_default(const struct flowi *flp, struct fib_result *res) 197static inline void fib_select_default(const struct flowi *flp,
198 struct fib_result *res)
183{ 199{
200 struct fib_table *table = fib_get_table(RT_TABLE_MAIN);
184 if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) 201 if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
185 ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res); 202 table->tb_select_default(table, flp, res);
186} 203}
187 204
188#else /* CONFIG_IP_MULTIPLE_TABLES */ 205#else /* CONFIG_IP_MULTIPLE_TABLES */
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 0484cae02736..9ff1e6669ef2 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -50,39 +50,34 @@
50#define FFprint(a...) printk(KERN_DEBUG a) 50#define FFprint(a...) printk(KERN_DEBUG a)
51 51
52static struct sock *fibnl; 52static struct sock *fibnl;
53struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
53 54
54#ifndef CONFIG_IP_MULTIPLE_TABLES 55#ifndef CONFIG_IP_MULTIPLE_TABLES
55 56
56struct fib_table *ip_fib_local_table;
57struct fib_table *ip_fib_main_table;
58
59#define FIB_TABLE_HASHSZ 1
60static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
61
62static int __net_init fib4_rules_init(struct net *net) 57static int __net_init fib4_rules_init(struct net *net)
63{ 58{
64 ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL); 59 struct fib_table *local_table, *main_table;
65 if (ip_fib_local_table == NULL) 60
61 local_table = fib_hash_init(RT_TABLE_LOCAL);
62 if (local_table == NULL)
66 return -ENOMEM; 63 return -ENOMEM;
67 64
68 ip_fib_main_table = fib_hash_init(RT_TABLE_MAIN); 65 main_table = fib_hash_init(RT_TABLE_MAIN);
69 if (ip_fib_main_table == NULL) 66 if (main_table == NULL)
70 goto fail; 67 goto fail;
71 68
72 hlist_add_head_rcu(&ip_fib_local_table->tb_hlist, &fib_table_hash[0]); 69 hlist_add_head_rcu(&local_table->tb_hlist,
73 hlist_add_head_rcu(&ip_fib_main_table->tb_hlist, &fib_table_hash[0]); 70 &fib_table_hash[TABLE_LOCAL_INDEX]);
71 hlist_add_head_rcu(&main_table->tb_hlist,
72 &fib_table_hash[TABLE_MAIN_INDEX]);
74 return 0; 73 return 0;
75 74
76fail: 75fail:
77 kfree(ip_fib_local_table); 76 kfree(local_table);
78 ip_fib_local_table = NULL;
79 return -ENOMEM; 77 return -ENOMEM;
80} 78}
81#else 79#else
82 80
83#define FIB_TABLE_HASHSZ 256
84static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
85
86struct fib_table *fib_new_table(u32 id) 81struct fib_table *fib_new_table(u32 id)
87{ 82{
88 struct fib_table *tb; 83 struct fib_table *tb;