1 |
1275 |
phoenix |
/*
|
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 <linux/config.h>
|
20 |
|
|
|
21 |
|
|
struct kern_rta
|
22 |
|
|
{
|
23 |
|
|
void *rta_dst;
|
24 |
|
|
void *rta_src;
|
25 |
|
|
int *rta_iif;
|
26 |
|
|
int *rta_oif;
|
27 |
|
|
void *rta_gw;
|
28 |
|
|
u32 *rta_priority;
|
29 |
|
|
void *rta_prefsrc;
|
30 |
|
|
struct rtattr *rta_mx;
|
31 |
|
|
struct rtattr *rta_mp;
|
32 |
|
|
unsigned char *rta_protoinfo;
|
33 |
|
|
unsigned char *rta_flow;
|
34 |
|
|
struct rta_cacheinfo *rta_ci;
|
35 |
|
|
};
|
36 |
|
|
|
37 |
|
|
struct fib_nh
|
38 |
|
|
{
|
39 |
|
|
struct net_device *nh_dev;
|
40 |
|
|
unsigned nh_flags;
|
41 |
|
|
unsigned char nh_scope;
|
42 |
|
|
#ifdef CONFIG_IP_ROUTE_MULTIPATH
|
43 |
|
|
int nh_weight;
|
44 |
|
|
int nh_power;
|
45 |
|
|
#endif
|
46 |
|
|
#ifdef CONFIG_NET_CLS_ROUTE
|
47 |
|
|
__u32 nh_tclassid;
|
48 |
|
|
#endif
|
49 |
|
|
int nh_oif;
|
50 |
|
|
u32 nh_gw;
|
51 |
|
|
};
|
52 |
|
|
|
53 |
|
|
/*
|
54 |
|
|
* This structure contains data shared by many of routes.
|
55 |
|
|
*/
|
56 |
|
|
|
57 |
|
|
struct fib_info
|
58 |
|
|
{
|
59 |
|
|
struct fib_info *fib_next;
|
60 |
|
|
struct fib_info *fib_prev;
|
61 |
|
|
int fib_treeref;
|
62 |
|
|
atomic_t fib_clntref;
|
63 |
|
|
int fib_dead;
|
64 |
|
|
unsigned fib_flags;
|
65 |
|
|
int fib_protocol;
|
66 |
|
|
u32 fib_prefsrc;
|
67 |
|
|
u32 fib_priority;
|
68 |
|
|
unsigned fib_metrics[RTAX_MAX];
|
69 |
|
|
#define fib_mtu fib_metrics[RTAX_MTU-1]
|
70 |
|
|
#define fib_window fib_metrics[RTAX_WINDOW-1]
|
71 |
|
|
#define fib_rtt fib_metrics[RTAX_RTT-1]
|
72 |
|
|
#define fib_advmss fib_metrics[RTAX_ADVMSS-1]
|
73 |
|
|
int fib_nhs;
|
74 |
|
|
#ifdef CONFIG_IP_ROUTE_MULTIPATH
|
75 |
|
|
int fib_power;
|
76 |
|
|
#endif
|
77 |
|
|
struct fib_nh fib_nh[0];
|
78 |
|
|
#define fib_dev fib_nh[0].nh_dev
|
79 |
|
|
};
|
80 |
|
|
|
81 |
|
|
|
82 |
|
|
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
83 |
|
|
struct fib_rule;
|
84 |
|
|
#endif
|
85 |
|
|
|
86 |
|
|
struct fib_result
|
87 |
|
|
{
|
88 |
|
|
unsigned char prefixlen;
|
89 |
|
|
unsigned char nh_sel;
|
90 |
|
|
unsigned char type;
|
91 |
|
|
unsigned char scope;
|
92 |
|
|
struct fib_info *fi;
|
93 |
|
|
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
94 |
|
|
struct fib_rule *r;
|
95 |
|
|
#endif
|
96 |
|
|
};
|
97 |
|
|
|
98 |
|
|
|
99 |
|
|
#ifdef CONFIG_IP_ROUTE_MULTIPATH
|
100 |
|
|
|
101 |
|
|
#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
|
102 |
|
|
#define FIB_RES_RESET(res) ((res).nh_sel = 0)
|
103 |
|
|
|
104 |
|
|
#else /* CONFIG_IP_ROUTE_MULTIPATH */
|
105 |
|
|
|
106 |
|
|
#define FIB_RES_NH(res) ((res).fi->fib_nh[0])
|
107 |
|
|
#define FIB_RES_RESET(res)
|
108 |
|
|
|
109 |
|
|
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
|
110 |
|
|
|
111 |
|
|
#define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res))
|
112 |
|
|
#define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw)
|
113 |
|
|
#define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev)
|
114 |
|
|
#define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif)
|
115 |
|
|
|
116 |
|
|
struct fib_table
|
117 |
|
|
{
|
118 |
|
|
unsigned char tb_id;
|
119 |
|
|
unsigned tb_stamp;
|
120 |
|
|
int (*tb_lookup)(struct fib_table *tb, const struct rt_key *key, struct fib_result *res);
|
121 |
|
|
int (*tb_insert)(struct fib_table *table, struct rtmsg *r,
|
122 |
|
|
struct kern_rta *rta, struct nlmsghdr *n,
|
123 |
|
|
struct netlink_skb_parms *req);
|
124 |
|
|
int (*tb_delete)(struct fib_table *table, struct rtmsg *r,
|
125 |
|
|
struct kern_rta *rta, struct nlmsghdr *n,
|
126 |
|
|
struct netlink_skb_parms *req);
|
127 |
|
|
int (*tb_dump)(struct fib_table *table, struct sk_buff *skb,
|
128 |
|
|
struct netlink_callback *cb);
|
129 |
|
|
int (*tb_flush)(struct fib_table *table);
|
130 |
|
|
int (*tb_get_info)(struct fib_table *table, char *buf,
|
131 |
|
|
int first, int count);
|
132 |
|
|
void (*tb_select_default)(struct fib_table *table,
|
133 |
|
|
const struct rt_key *key, struct fib_result *res);
|
134 |
|
|
|
135 |
|
|
unsigned char tb_data[0];
|
136 |
|
|
};
|
137 |
|
|
|
138 |
|
|
#ifndef CONFIG_IP_MULTIPLE_TABLES
|
139 |
|
|
|
140 |
|
|
extern struct fib_table *local_table;
|
141 |
|
|
extern struct fib_table *main_table;
|
142 |
|
|
|
143 |
|
|
static inline struct fib_table *fib_get_table(int id)
|
144 |
|
|
{
|
145 |
|
|
if (id != RT_TABLE_LOCAL)
|
146 |
|
|
return main_table;
|
147 |
|
|
return local_table;
|
148 |
|
|
}
|
149 |
|
|
|
150 |
|
|
static inline struct fib_table *fib_new_table(int id)
|
151 |
|
|
{
|
152 |
|
|
return fib_get_table(id);
|
153 |
|
|
}
|
154 |
|
|
|
155 |
|
|
static inline int fib_lookup(const struct rt_key *key, struct fib_result *res)
|
156 |
|
|
{
|
157 |
|
|
if (local_table->tb_lookup(local_table, key, res) &&
|
158 |
|
|
main_table->tb_lookup(main_table, key, res))
|
159 |
|
|
return -ENETUNREACH;
|
160 |
|
|
return 0;
|
161 |
|
|
}
|
162 |
|
|
|
163 |
|
|
static inline void fib_select_default(const struct rt_key *key, struct fib_result *res)
|
164 |
|
|
{
|
165 |
|
|
if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
|
166 |
|
|
main_table->tb_select_default(main_table, key, res);
|
167 |
|
|
}
|
168 |
|
|
|
169 |
|
|
#else /* CONFIG_IP_MULTIPLE_TABLES */
|
170 |
|
|
#define local_table (fib_tables[RT_TABLE_LOCAL])
|
171 |
|
|
#define main_table (fib_tables[RT_TABLE_MAIN])
|
172 |
|
|
|
173 |
|
|
extern struct fib_table * fib_tables[RT_TABLE_MAX+1];
|
174 |
|
|
extern int fib_lookup(const struct rt_key *key, struct fib_result *res);
|
175 |
|
|
extern struct fib_table *__fib_new_table(int id);
|
176 |
|
|
extern void fib_rule_put(struct fib_rule *r);
|
177 |
|
|
|
178 |
|
|
static inline struct fib_table *fib_get_table(int id)
|
179 |
|
|
{
|
180 |
|
|
if (id == 0)
|
181 |
|
|
id = RT_TABLE_MAIN;
|
182 |
|
|
|
183 |
|
|
return fib_tables[id];
|
184 |
|
|
}
|
185 |
|
|
|
186 |
|
|
static inline struct fib_table *fib_new_table(int id)
|
187 |
|
|
{
|
188 |
|
|
if (id == 0)
|
189 |
|
|
id = RT_TABLE_MAIN;
|
190 |
|
|
|
191 |
|
|
return fib_tables[id] ? : __fib_new_table(id);
|
192 |
|
|
}
|
193 |
|
|
|
194 |
|
|
extern void fib_select_default(const struct rt_key *key, struct fib_result *res);
|
195 |
|
|
|
196 |
|
|
#endif /* CONFIG_IP_MULTIPLE_TABLES */
|
197 |
|
|
|
198 |
|
|
/* Exported by fib_frontend.c */
|
199 |
|
|
extern void ip_fib_init(void);
|
200 |
|
|
extern void fib_flush(void);
|
201 |
|
|
extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
|
202 |
|
|
extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
|
203 |
|
|
extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
|
204 |
|
|
extern int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb);
|
205 |
|
|
extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
|
206 |
|
|
struct net_device *dev, u32 *spec_dst, u32 *itag);
|
207 |
|
|
extern void fib_select_multipath(const struct rt_key *key, struct fib_result *res);
|
208 |
|
|
|
209 |
|
|
/* Exported by fib_semantics.c */
|
210 |
|
|
extern int ip_fib_check_default(u32 gw, struct net_device *dev);
|
211 |
|
|
extern void fib_release_info(struct fib_info *);
|
212 |
|
|
extern int fib_semantic_match(int type, struct fib_info *,
|
213 |
|
|
const struct rt_key *, struct fib_result*);
|
214 |
|
|
extern struct fib_info *fib_create_info(const struct rtmsg *r, struct kern_rta *rta,
|
215 |
|
|
const struct nlmsghdr *, int *err);
|
216 |
|
|
extern int fib_nh_match(struct rtmsg *r, struct nlmsghdr *, struct kern_rta *rta, struct fib_info *fi);
|
217 |
|
|
extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
|
218 |
|
|
u8 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos,
|
219 |
|
|
struct fib_info *fi);
|
220 |
|
|
extern int fib_sync_down(u32 local, struct net_device *dev, int force);
|
221 |
|
|
extern int fib_sync_up(struct net_device *dev);
|
222 |
|
|
extern int fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm,
|
223 |
|
|
struct kern_rta *rta, struct rtentry *r);
|
224 |
|
|
extern void fib_node_get_info(int type, int dead, struct fib_info *fi, u32 prefix, u32 mask, char *buffer);
|
225 |
|
|
extern u32 __fib_res_prefsrc(struct fib_result *res);
|
226 |
|
|
|
227 |
|
|
/* Exported by fib_hash.c */
|
228 |
|
|
extern struct fib_table *fib_hash_init(int id);
|
229 |
|
|
|
230 |
|
|
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
231 |
|
|
/* Exported by fib_rules.c */
|
232 |
|
|
|
233 |
|
|
extern int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
|
234 |
|
|
extern int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
|
235 |
|
|
extern int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb);
|
236 |
|
|
extern u32 fib_rules_map_destination(u32 daddr, struct fib_result *res);
|
237 |
|
|
#ifdef CONFIG_NET_CLS_ROUTE
|
238 |
|
|
extern u32 fib_rules_tclass(struct fib_result *res);
|
239 |
|
|
#endif
|
240 |
|
|
extern u32 fib_rules_policy(u32 saddr, struct fib_result *res, unsigned *flags);
|
241 |
|
|
extern void fib_rules_init(void);
|
242 |
|
|
#endif
|
243 |
|
|
|
244 |
|
|
static inline void fib_combine_itag(u32 *itag, struct fib_result *res)
|
245 |
|
|
{
|
246 |
|
|
#ifdef CONFIG_NET_CLS_ROUTE
|
247 |
|
|
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
248 |
|
|
u32 rtag;
|
249 |
|
|
#endif
|
250 |
|
|
*itag = FIB_RES_NH(*res).nh_tclassid<<16;
|
251 |
|
|
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
252 |
|
|
rtag = fib_rules_tclass(res);
|
253 |
|
|
if (*itag == 0)
|
254 |
|
|
*itag = (rtag<<16);
|
255 |
|
|
*itag |= (rtag>>16);
|
256 |
|
|
#endif
|
257 |
|
|
#endif
|
258 |
|
|
}
|
259 |
|
|
|
260 |
|
|
extern void free_fib_info(struct fib_info *fi);
|
261 |
|
|
|
262 |
|
|
static inline void fib_info_put(struct fib_info *fi)
|
263 |
|
|
{
|
264 |
|
|
if (atomic_dec_and_test(&fi->fib_clntref))
|
265 |
|
|
free_fib_info(fi);
|
266 |
|
|
}
|
267 |
|
|
|
268 |
|
|
static inline void fib_res_put(struct fib_result *res)
|
269 |
|
|
{
|
270 |
|
|
if (res->fi)
|
271 |
|
|
fib_info_put(res->fi);
|
272 |
|
|
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
273 |
|
|
if (res->r)
|
274 |
|
|
fib_rule_put(res->r);
|
275 |
|
|
#endif
|
276 |
|
|
}
|
277 |
|
|
|
278 |
|
|
|
279 |
|
|
#endif /* _NET_FIB_H */
|