Root/
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 | * Definitions for the Forwarding Information Base. |
7 | * |
8 | * Authors: A.N.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 | #ifndef _NET_IP_FIB_H |
17 | #define _NET_IP_FIB_H |
18 | |
19 | #include <net/flow.h> |
20 | #include <linux/seq_file.h> |
21 | #include <linux/rcupdate.h> |
22 | #include <net/fib_rules.h> |
23 | #include <net/inetpeer.h> |
24 | #include <linux/percpu.h> |
25 | |
26 | struct fib_config { |
27 | u8 fc_dst_len; |
28 | u8 fc_tos; |
29 | u8 fc_protocol; |
30 | u8 fc_scope; |
31 | u8 fc_type; |
32 | /* 3 bytes unused */ |
33 | u32 fc_table; |
34 | __be32 fc_dst; |
35 | __be32 fc_gw; |
36 | int fc_oif; |
37 | u32 fc_flags; |
38 | u32 fc_priority; |
39 | __be32 fc_prefsrc; |
40 | struct nlattr *fc_mx; |
41 | struct rtnexthop *fc_mp; |
42 | int fc_mx_len; |
43 | int fc_mp_len; |
44 | u32 fc_flow; |
45 | u32 fc_nlflags; |
46 | struct nl_info fc_nlinfo; |
47 | }; |
48 | |
49 | struct fib_info; |
50 | struct rtable; |
51 | |
52 | struct fib_nh_exception { |
53 | struct fib_nh_exception __rcu *fnhe_next; |
54 | int fnhe_genid; |
55 | __be32 fnhe_daddr; |
56 | u32 fnhe_pmtu; |
57 | __be32 fnhe_gw; |
58 | unsigned long fnhe_expires; |
59 | struct rtable __rcu *fnhe_rth_input; |
60 | struct rtable __rcu *fnhe_rth_output; |
61 | unsigned long fnhe_stamp; |
62 | }; |
63 | |
64 | struct fnhe_hash_bucket { |
65 | struct fib_nh_exception __rcu *chain; |
66 | }; |
67 | |
68 | #define FNHE_HASH_SIZE 2048 |
69 | #define FNHE_RECLAIM_DEPTH 5 |
70 | |
71 | struct fib_nh { |
72 | struct net_device *nh_dev; |
73 | struct hlist_node nh_hash; |
74 | struct fib_info *nh_parent; |
75 | unsigned int nh_flags; |
76 | unsigned char nh_scope; |
77 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
78 | int nh_weight; |
79 | int nh_power; |
80 | #endif |
81 | #ifdef CONFIG_IP_ROUTE_CLASSID |
82 | __u32 nh_tclassid; |
83 | #endif |
84 | int nh_oif; |
85 | __be32 nh_gw; |
86 | __be32 nh_saddr; |
87 | int nh_saddr_genid; |
88 | struct rtable __rcu * __percpu *nh_pcpu_rth_output; |
89 | struct rtable __rcu *nh_rth_input; |
90 | struct fnhe_hash_bucket *nh_exceptions; |
91 | }; |
92 | |
93 | /* |
94 | * This structure contains data shared by many of routes. |
95 | */ |
96 | |
97 | struct fib_info { |
98 | struct hlist_node fib_hash; |
99 | struct hlist_node fib_lhash; |
100 | struct net *fib_net; |
101 | int fib_treeref; |
102 | atomic_t fib_clntref; |
103 | unsigned int fib_flags; |
104 | unsigned char fib_dead; |
105 | unsigned char fib_protocol; |
106 | unsigned char fib_scope; |
107 | unsigned char fib_type; |
108 | __be32 fib_prefsrc; |
109 | u32 fib_priority; |
110 | u32 *fib_metrics; |
111 | #define fib_mtu fib_metrics[RTAX_MTU-1] |
112 | #define fib_window fib_metrics[RTAX_WINDOW-1] |
113 | #define fib_rtt fib_metrics[RTAX_RTT-1] |
114 | #define fib_advmss fib_metrics[RTAX_ADVMSS-1] |
115 | int fib_nhs; |
116 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
117 | int fib_power; |
118 | #endif |
119 | struct rcu_head rcu; |
120 | struct fib_nh fib_nh[0]; |
121 | #define fib_dev fib_nh[0].nh_dev |
122 | }; |
123 | |
124 | |
125 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
126 | struct fib_rule; |
127 | #endif |
128 | |
129 | struct fib_table; |
130 | struct fib_result { |
131 | unsigned char prefixlen; |
132 | unsigned char nh_sel; |
133 | unsigned char type; |
134 | unsigned char scope; |
135 | u32 tclassid; |
136 | struct fib_info *fi; |
137 | struct fib_table *table; |
138 | struct list_head *fa_head; |
139 | }; |
140 | |
141 | struct fib_result_nl { |
142 | __be32 fl_addr; /* To be looked up*/ |
143 | u32 fl_mark; |
144 | unsigned char fl_tos; |
145 | unsigned char fl_scope; |
146 | unsigned char tb_id_in; |
147 | |
148 | unsigned char tb_id; /* Results */ |
149 | unsigned char prefixlen; |
150 | unsigned char nh_sel; |
151 | unsigned char type; |
152 | unsigned char scope; |
153 | int err; |
154 | }; |
155 | |
156 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
157 | #define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel]) |
158 | #else /* CONFIG_IP_ROUTE_MULTIPATH */ |
159 | #define FIB_RES_NH(res) ((res).fi->fib_nh[0]) |
160 | #endif /* CONFIG_IP_ROUTE_MULTIPATH */ |
161 | |
162 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
163 | #define FIB_TABLE_HASHSZ 256 |
164 | #else |
165 | #define FIB_TABLE_HASHSZ 2 |
166 | #endif |
167 | |
168 | extern __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh); |
169 | |
170 | #define FIB_RES_SADDR(net, res) \ |
171 | ((FIB_RES_NH(res).nh_saddr_genid == \ |
172 | atomic_read(&(net)->ipv4.dev_addr_genid)) ? \ |
173 | FIB_RES_NH(res).nh_saddr : \ |
174 | fib_info_update_nh_saddr((net), &FIB_RES_NH(res))) |
175 | #define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw) |
176 | #define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev) |
177 | #define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif) |
178 | |
179 | #define FIB_RES_PREFSRC(net, res) ((res).fi->fib_prefsrc ? : \ |
180 | FIB_RES_SADDR(net, res)) |
181 | |
182 | struct fib_table { |
183 | struct hlist_node tb_hlist; |
184 | u32 tb_id; |
185 | int tb_default; |
186 | int tb_num_default; |
187 | unsigned long tb_data[0]; |
188 | }; |
189 | |
190 | extern int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, |
191 | struct fib_result *res, int fib_flags); |
192 | extern int fib_table_insert(struct fib_table *, struct fib_config *); |
193 | extern int fib_table_delete(struct fib_table *, struct fib_config *); |
194 | extern int fib_table_dump(struct fib_table *table, struct sk_buff *skb, |
195 | struct netlink_callback *cb); |
196 | extern int fib_table_flush(struct fib_table *table); |
197 | extern void fib_free_table(struct fib_table *tb); |
198 | |
199 | |
200 | |
201 | #ifndef CONFIG_IP_MULTIPLE_TABLES |
202 | |
203 | #define TABLE_LOCAL_INDEX 0 |
204 | #define TABLE_MAIN_INDEX 1 |
205 | |
206 | static inline struct fib_table *fib_get_table(struct net *net, u32 id) |
207 | { |
208 | struct hlist_head *ptr; |
209 | |
210 | ptr = id == RT_TABLE_LOCAL ? |
211 | &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX] : |
212 | &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX]; |
213 | return hlist_entry(ptr->first, struct fib_table, tb_hlist); |
214 | } |
215 | |
216 | static inline struct fib_table *fib_new_table(struct net *net, u32 id) |
217 | { |
218 | return fib_get_table(net, id); |
219 | } |
220 | |
221 | static inline int fib_lookup(struct net *net, const struct flowi4 *flp, |
222 | struct fib_result *res) |
223 | { |
224 | struct fib_table *table; |
225 | |
226 | table = fib_get_table(net, RT_TABLE_LOCAL); |
227 | if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF)) |
228 | return 0; |
229 | |
230 | table = fib_get_table(net, RT_TABLE_MAIN); |
231 | if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF)) |
232 | return 0; |
233 | return -ENETUNREACH; |
234 | } |
235 | |
236 | #else /* CONFIG_IP_MULTIPLE_TABLES */ |
237 | extern int __net_init fib4_rules_init(struct net *net); |
238 | extern void __net_exit fib4_rules_exit(struct net *net); |
239 | |
240 | extern struct fib_table *fib_new_table(struct net *net, u32 id); |
241 | extern struct fib_table *fib_get_table(struct net *net, u32 id); |
242 | |
243 | extern int __fib_lookup(struct net *net, struct flowi4 *flp, |
244 | struct fib_result *res); |
245 | |
246 | static inline int fib_lookup(struct net *net, struct flowi4 *flp, |
247 | struct fib_result *res) |
248 | { |
249 | if (!net->ipv4.fib_has_custom_rules) { |
250 | res->tclassid = 0; |
251 | if (net->ipv4.fib_local && |
252 | !fib_table_lookup(net->ipv4.fib_local, flp, res, |
253 | FIB_LOOKUP_NOREF)) |
254 | return 0; |
255 | if (net->ipv4.fib_main && |
256 | !fib_table_lookup(net->ipv4.fib_main, flp, res, |
257 | FIB_LOOKUP_NOREF)) |
258 | return 0; |
259 | if (net->ipv4.fib_default && |
260 | !fib_table_lookup(net->ipv4.fib_default, flp, res, |
261 | FIB_LOOKUP_NOREF)) |
262 | return 0; |
263 | return -ENETUNREACH; |
264 | } |
265 | return __fib_lookup(net, flp, res); |
266 | } |
267 | |
268 | #endif /* CONFIG_IP_MULTIPLE_TABLES */ |
269 | |
270 | /* Exported by fib_frontend.c */ |
271 | extern const struct nla_policy rtm_ipv4_policy[]; |
272 | extern void ip_fib_init(void); |
273 | extern __be32 fib_compute_spec_dst(struct sk_buff *skb); |
274 | extern int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, |
275 | u8 tos, int oif, struct net_device *dev, |
276 | struct in_device *idev, u32 *itag); |
277 | extern void fib_select_default(struct fib_result *res); |
278 | #ifdef CONFIG_IP_ROUTE_CLASSID |
279 | static inline int fib_num_tclassid_users(struct net *net) |
280 | { |
281 | return net->ipv4.fib_num_tclassid_users; |
282 | } |
283 | #else |
284 | static inline int fib_num_tclassid_users(struct net *net) |
285 | { |
286 | return 0; |
287 | } |
288 | #endif |
289 | |
290 | /* Exported by fib_semantics.c */ |
291 | extern int ip_fib_check_default(__be32 gw, struct net_device *dev); |
292 | extern int fib_sync_down_dev(struct net_device *dev, int force); |
293 | extern int fib_sync_down_addr(struct net *net, __be32 local); |
294 | extern int fib_sync_up(struct net_device *dev); |
295 | extern void fib_select_multipath(struct fib_result *res); |
296 | |
297 | /* Exported by fib_trie.c */ |
298 | extern void fib_trie_init(void); |
299 | extern struct fib_table *fib_trie_table(u32 id); |
300 | |
301 | static inline void fib_combine_itag(u32 *itag, const struct fib_result *res) |
302 | { |
303 | #ifdef CONFIG_IP_ROUTE_CLASSID |
304 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
305 | u32 rtag; |
306 | #endif |
307 | *itag = FIB_RES_NH(*res).nh_tclassid<<16; |
308 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
309 | rtag = res->tclassid; |
310 | if (*itag == 0) |
311 | *itag = (rtag<<16); |
312 | *itag |= (rtag>>16); |
313 | #endif |
314 | #endif |
315 | } |
316 | |
317 | extern void free_fib_info(struct fib_info *fi); |
318 | |
319 | static inline void fib_info_put(struct fib_info *fi) |
320 | { |
321 | if (atomic_dec_and_test(&fi->fib_clntref)) |
322 | free_fib_info(fi); |
323 | } |
324 | |
325 | #ifdef CONFIG_PROC_FS |
326 | extern int __net_init fib_proc_init(struct net *net); |
327 | extern void __net_exit fib_proc_exit(struct net *net); |
328 | #else |
329 | static inline int fib_proc_init(struct net *net) |
330 | { |
331 | return 0; |
332 | } |
333 | static inline void fib_proc_exit(struct net *net) |
334 | { |
335 | } |
336 | #endif |
337 | |
338 | #endif /* _NET_FIB_H */ |
339 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9