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