1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * INET An implementation of the TCP/IP protocol suite for the LINUX 3*1da177e4SLinus Torvalds * operating system. INET is implemented using the BSD Socket 4*1da177e4SLinus Torvalds * interface as the means of communication with the user level. 5*1da177e4SLinus Torvalds * 6*1da177e4SLinus Torvalds * Definitions for the Forwarding Information Base. 7*1da177e4SLinus Torvalds * 8*1da177e4SLinus Torvalds * Authors: A.N.Kuznetsov, <[email protected]> 9*1da177e4SLinus Torvalds * 10*1da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or 11*1da177e4SLinus Torvalds * modify it under the terms of the GNU General Public License 12*1da177e4SLinus Torvalds * as published by the Free Software Foundation; either version 13*1da177e4SLinus Torvalds * 2 of the License, or (at your option) any later version. 14*1da177e4SLinus Torvalds */ 15*1da177e4SLinus Torvalds 16*1da177e4SLinus Torvalds #ifndef _NET_IP_FIB_H 17*1da177e4SLinus Torvalds #define _NET_IP_FIB_H 18*1da177e4SLinus Torvalds 19*1da177e4SLinus Torvalds #include <linux/config.h> 20*1da177e4SLinus Torvalds #include <net/flow.h> 21*1da177e4SLinus Torvalds #include <linux/seq_file.h> 22*1da177e4SLinus Torvalds 23*1da177e4SLinus Torvalds /* WARNING: The ordering of these elements must match ordering 24*1da177e4SLinus Torvalds * of RTA_* rtnetlink attribute numbers. 25*1da177e4SLinus Torvalds */ 26*1da177e4SLinus Torvalds struct kern_rta { 27*1da177e4SLinus Torvalds void *rta_dst; 28*1da177e4SLinus Torvalds void *rta_src; 29*1da177e4SLinus Torvalds int *rta_iif; 30*1da177e4SLinus Torvalds int *rta_oif; 31*1da177e4SLinus Torvalds void *rta_gw; 32*1da177e4SLinus Torvalds u32 *rta_priority; 33*1da177e4SLinus Torvalds void *rta_prefsrc; 34*1da177e4SLinus Torvalds struct rtattr *rta_mx; 35*1da177e4SLinus Torvalds struct rtattr *rta_mp; 36*1da177e4SLinus Torvalds unsigned char *rta_protoinfo; 37*1da177e4SLinus Torvalds u32 *rta_flow; 38*1da177e4SLinus Torvalds struct rta_cacheinfo *rta_ci; 39*1da177e4SLinus Torvalds struct rta_session *rta_sess; 40*1da177e4SLinus Torvalds u32 *rta_mp_alg; 41*1da177e4SLinus Torvalds }; 42*1da177e4SLinus Torvalds 43*1da177e4SLinus Torvalds struct fib_info; 44*1da177e4SLinus Torvalds 45*1da177e4SLinus Torvalds struct fib_nh { 46*1da177e4SLinus Torvalds struct net_device *nh_dev; 47*1da177e4SLinus Torvalds struct hlist_node nh_hash; 48*1da177e4SLinus Torvalds struct fib_info *nh_parent; 49*1da177e4SLinus Torvalds unsigned nh_flags; 50*1da177e4SLinus Torvalds unsigned char nh_scope; 51*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH 52*1da177e4SLinus Torvalds int nh_weight; 53*1da177e4SLinus Torvalds int nh_power; 54*1da177e4SLinus Torvalds #endif 55*1da177e4SLinus Torvalds #ifdef CONFIG_NET_CLS_ROUTE 56*1da177e4SLinus Torvalds __u32 nh_tclassid; 57*1da177e4SLinus Torvalds #endif 58*1da177e4SLinus Torvalds int nh_oif; 59*1da177e4SLinus Torvalds u32 nh_gw; 60*1da177e4SLinus Torvalds }; 61*1da177e4SLinus Torvalds 62*1da177e4SLinus Torvalds /* 63*1da177e4SLinus Torvalds * This structure contains data shared by many of routes. 64*1da177e4SLinus Torvalds */ 65*1da177e4SLinus Torvalds 66*1da177e4SLinus Torvalds struct fib_info { 67*1da177e4SLinus Torvalds struct hlist_node fib_hash; 68*1da177e4SLinus Torvalds struct hlist_node fib_lhash; 69*1da177e4SLinus Torvalds int fib_treeref; 70*1da177e4SLinus Torvalds atomic_t fib_clntref; 71*1da177e4SLinus Torvalds int fib_dead; 72*1da177e4SLinus Torvalds unsigned fib_flags; 73*1da177e4SLinus Torvalds int fib_protocol; 74*1da177e4SLinus Torvalds u32 fib_prefsrc; 75*1da177e4SLinus Torvalds u32 fib_priority; 76*1da177e4SLinus Torvalds u32 fib_metrics[RTAX_MAX]; 77*1da177e4SLinus Torvalds #define fib_mtu fib_metrics[RTAX_MTU-1] 78*1da177e4SLinus Torvalds #define fib_window fib_metrics[RTAX_WINDOW-1] 79*1da177e4SLinus Torvalds #define fib_rtt fib_metrics[RTAX_RTT-1] 80*1da177e4SLinus Torvalds #define fib_advmss fib_metrics[RTAX_ADVMSS-1] 81*1da177e4SLinus Torvalds int fib_nhs; 82*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH 83*1da177e4SLinus Torvalds int fib_power; 84*1da177e4SLinus Torvalds #endif 85*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 86*1da177e4SLinus Torvalds u32 fib_mp_alg; 87*1da177e4SLinus Torvalds #endif 88*1da177e4SLinus Torvalds struct fib_nh fib_nh[0]; 89*1da177e4SLinus Torvalds #define fib_dev fib_nh[0].nh_dev 90*1da177e4SLinus Torvalds }; 91*1da177e4SLinus Torvalds 92*1da177e4SLinus Torvalds 93*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES 94*1da177e4SLinus Torvalds struct fib_rule; 95*1da177e4SLinus Torvalds #endif 96*1da177e4SLinus Torvalds 97*1da177e4SLinus Torvalds struct fib_result { 98*1da177e4SLinus Torvalds unsigned char prefixlen; 99*1da177e4SLinus Torvalds unsigned char nh_sel; 100*1da177e4SLinus Torvalds unsigned char type; 101*1da177e4SLinus Torvalds unsigned char scope; 102*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 103*1da177e4SLinus Torvalds __u32 network; 104*1da177e4SLinus Torvalds __u32 netmask; 105*1da177e4SLinus Torvalds #endif 106*1da177e4SLinus Torvalds struct fib_info *fi; 107*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES 108*1da177e4SLinus Torvalds struct fib_rule *r; 109*1da177e4SLinus Torvalds #endif 110*1da177e4SLinus Torvalds }; 111*1da177e4SLinus Torvalds 112*1da177e4SLinus Torvalds 113*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH 114*1da177e4SLinus Torvalds 115*1da177e4SLinus Torvalds #define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel]) 116*1da177e4SLinus Torvalds #define FIB_RES_RESET(res) ((res).nh_sel = 0) 117*1da177e4SLinus Torvalds 118*1da177e4SLinus Torvalds #else /* CONFIG_IP_ROUTE_MULTIPATH */ 119*1da177e4SLinus Torvalds 120*1da177e4SLinus Torvalds #define FIB_RES_NH(res) ((res).fi->fib_nh[0]) 121*1da177e4SLinus Torvalds #define FIB_RES_RESET(res) 122*1da177e4SLinus Torvalds 123*1da177e4SLinus Torvalds #endif /* CONFIG_IP_ROUTE_MULTIPATH */ 124*1da177e4SLinus Torvalds 125*1da177e4SLinus Torvalds #define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res)) 126*1da177e4SLinus Torvalds #define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw) 127*1da177e4SLinus Torvalds #define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev) 128*1da177e4SLinus Torvalds #define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif) 129*1da177e4SLinus Torvalds 130*1da177e4SLinus Torvalds #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 131*1da177e4SLinus Torvalds #define FIB_RES_NETWORK(res) ((res).network) 132*1da177e4SLinus Torvalds #define FIB_RES_NETMASK(res) ((res).netmask) 133*1da177e4SLinus Torvalds #else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ 134*1da177e4SLinus Torvalds #define FIB_RES_NETWORK(res) (0) 135*1da177e4SLinus Torvalds #define FIB_RES_NETMASK(res) (0) 136*1da177e4SLinus Torvalds #endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */ 137*1da177e4SLinus Torvalds 138*1da177e4SLinus Torvalds struct fib_table { 139*1da177e4SLinus Torvalds unsigned char tb_id; 140*1da177e4SLinus Torvalds unsigned tb_stamp; 141*1da177e4SLinus Torvalds int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res); 142*1da177e4SLinus Torvalds int (*tb_insert)(struct fib_table *table, struct rtmsg *r, 143*1da177e4SLinus Torvalds struct kern_rta *rta, struct nlmsghdr *n, 144*1da177e4SLinus Torvalds struct netlink_skb_parms *req); 145*1da177e4SLinus Torvalds int (*tb_delete)(struct fib_table *table, struct rtmsg *r, 146*1da177e4SLinus Torvalds struct kern_rta *rta, struct nlmsghdr *n, 147*1da177e4SLinus Torvalds struct netlink_skb_parms *req); 148*1da177e4SLinus Torvalds int (*tb_dump)(struct fib_table *table, struct sk_buff *skb, 149*1da177e4SLinus Torvalds struct netlink_callback *cb); 150*1da177e4SLinus Torvalds int (*tb_flush)(struct fib_table *table); 151*1da177e4SLinus Torvalds void (*tb_select_default)(struct fib_table *table, 152*1da177e4SLinus Torvalds const struct flowi *flp, struct fib_result *res); 153*1da177e4SLinus Torvalds 154*1da177e4SLinus Torvalds unsigned char tb_data[0]; 155*1da177e4SLinus Torvalds }; 156*1da177e4SLinus Torvalds 157*1da177e4SLinus Torvalds #ifndef CONFIG_IP_MULTIPLE_TABLES 158*1da177e4SLinus Torvalds 159*1da177e4SLinus Torvalds extern struct fib_table *ip_fib_local_table; 160*1da177e4SLinus Torvalds extern struct fib_table *ip_fib_main_table; 161*1da177e4SLinus Torvalds 162*1da177e4SLinus Torvalds static inline struct fib_table *fib_get_table(int id) 163*1da177e4SLinus Torvalds { 164*1da177e4SLinus Torvalds if (id != RT_TABLE_LOCAL) 165*1da177e4SLinus Torvalds return ip_fib_main_table; 166*1da177e4SLinus Torvalds return ip_fib_local_table; 167*1da177e4SLinus Torvalds } 168*1da177e4SLinus Torvalds 169*1da177e4SLinus Torvalds static inline struct fib_table *fib_new_table(int id) 170*1da177e4SLinus Torvalds { 171*1da177e4SLinus Torvalds return fib_get_table(id); 172*1da177e4SLinus Torvalds } 173*1da177e4SLinus Torvalds 174*1da177e4SLinus Torvalds static inline int fib_lookup(const struct flowi *flp, struct fib_result *res) 175*1da177e4SLinus Torvalds { 176*1da177e4SLinus Torvalds if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) && 177*1da177e4SLinus Torvalds ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res)) 178*1da177e4SLinus Torvalds return -ENETUNREACH; 179*1da177e4SLinus Torvalds return 0; 180*1da177e4SLinus Torvalds } 181*1da177e4SLinus Torvalds 182*1da177e4SLinus Torvalds static inline void fib_select_default(const struct flowi *flp, struct fib_result *res) 183*1da177e4SLinus Torvalds { 184*1da177e4SLinus Torvalds if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) 185*1da177e4SLinus Torvalds ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res); 186*1da177e4SLinus Torvalds } 187*1da177e4SLinus Torvalds 188*1da177e4SLinus Torvalds #else /* CONFIG_IP_MULTIPLE_TABLES */ 189*1da177e4SLinus Torvalds #define ip_fib_local_table (fib_tables[RT_TABLE_LOCAL]) 190*1da177e4SLinus Torvalds #define ip_fib_main_table (fib_tables[RT_TABLE_MAIN]) 191*1da177e4SLinus Torvalds 192*1da177e4SLinus Torvalds extern struct fib_table * fib_tables[RT_TABLE_MAX+1]; 193*1da177e4SLinus Torvalds extern int fib_lookup(const struct flowi *flp, struct fib_result *res); 194*1da177e4SLinus Torvalds extern struct fib_table *__fib_new_table(int id); 195*1da177e4SLinus Torvalds extern void fib_rule_put(struct fib_rule *r); 196*1da177e4SLinus Torvalds 197*1da177e4SLinus Torvalds static inline struct fib_table *fib_get_table(int id) 198*1da177e4SLinus Torvalds { 199*1da177e4SLinus Torvalds if (id == 0) 200*1da177e4SLinus Torvalds id = RT_TABLE_MAIN; 201*1da177e4SLinus Torvalds 202*1da177e4SLinus Torvalds return fib_tables[id]; 203*1da177e4SLinus Torvalds } 204*1da177e4SLinus Torvalds 205*1da177e4SLinus Torvalds static inline struct fib_table *fib_new_table(int id) 206*1da177e4SLinus Torvalds { 207*1da177e4SLinus Torvalds if (id == 0) 208*1da177e4SLinus Torvalds id = RT_TABLE_MAIN; 209*1da177e4SLinus Torvalds 210*1da177e4SLinus Torvalds return fib_tables[id] ? : __fib_new_table(id); 211*1da177e4SLinus Torvalds } 212*1da177e4SLinus Torvalds 213*1da177e4SLinus Torvalds extern void fib_select_default(const struct flowi *flp, struct fib_result *res); 214*1da177e4SLinus Torvalds 215*1da177e4SLinus Torvalds #endif /* CONFIG_IP_MULTIPLE_TABLES */ 216*1da177e4SLinus Torvalds 217*1da177e4SLinus Torvalds /* Exported by fib_frontend.c */ 218*1da177e4SLinus Torvalds extern void ip_fib_init(void); 219*1da177e4SLinus Torvalds extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); 220*1da177e4SLinus Torvalds extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); 221*1da177e4SLinus Torvalds extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); 222*1da177e4SLinus Torvalds extern int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb); 223*1da177e4SLinus Torvalds extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif, 224*1da177e4SLinus Torvalds struct net_device *dev, u32 *spec_dst, u32 *itag); 225*1da177e4SLinus Torvalds extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res); 226*1da177e4SLinus Torvalds 227*1da177e4SLinus Torvalds /* Exported by fib_semantics.c */ 228*1da177e4SLinus Torvalds extern int ip_fib_check_default(u32 gw, struct net_device *dev); 229*1da177e4SLinus Torvalds extern int fib_sync_down(u32 local, struct net_device *dev, int force); 230*1da177e4SLinus Torvalds extern int fib_sync_up(struct net_device *dev); 231*1da177e4SLinus Torvalds extern int fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm, 232*1da177e4SLinus Torvalds struct kern_rta *rta, struct rtentry *r); 233*1da177e4SLinus Torvalds extern u32 __fib_res_prefsrc(struct fib_result *res); 234*1da177e4SLinus Torvalds 235*1da177e4SLinus Torvalds /* Exported by fib_hash.c */ 236*1da177e4SLinus Torvalds extern struct fib_table *fib_hash_init(int id); 237*1da177e4SLinus Torvalds 238*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES 239*1da177e4SLinus Torvalds /* Exported by fib_rules.c */ 240*1da177e4SLinus Torvalds 241*1da177e4SLinus Torvalds extern int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); 242*1da177e4SLinus Torvalds extern int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); 243*1da177e4SLinus Torvalds extern int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb); 244*1da177e4SLinus Torvalds #ifdef CONFIG_NET_CLS_ROUTE 245*1da177e4SLinus Torvalds extern u32 fib_rules_tclass(struct fib_result *res); 246*1da177e4SLinus Torvalds #endif 247*1da177e4SLinus Torvalds extern void fib_rules_init(void); 248*1da177e4SLinus Torvalds #endif 249*1da177e4SLinus Torvalds 250*1da177e4SLinus Torvalds static inline void fib_combine_itag(u32 *itag, struct fib_result *res) 251*1da177e4SLinus Torvalds { 252*1da177e4SLinus Torvalds #ifdef CONFIG_NET_CLS_ROUTE 253*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES 254*1da177e4SLinus Torvalds u32 rtag; 255*1da177e4SLinus Torvalds #endif 256*1da177e4SLinus Torvalds *itag = FIB_RES_NH(*res).nh_tclassid<<16; 257*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES 258*1da177e4SLinus Torvalds rtag = fib_rules_tclass(res); 259*1da177e4SLinus Torvalds if (*itag == 0) 260*1da177e4SLinus Torvalds *itag = (rtag<<16); 261*1da177e4SLinus Torvalds *itag |= (rtag>>16); 262*1da177e4SLinus Torvalds #endif 263*1da177e4SLinus Torvalds #endif 264*1da177e4SLinus Torvalds } 265*1da177e4SLinus Torvalds 266*1da177e4SLinus Torvalds extern void free_fib_info(struct fib_info *fi); 267*1da177e4SLinus Torvalds 268*1da177e4SLinus Torvalds static inline void fib_info_put(struct fib_info *fi) 269*1da177e4SLinus Torvalds { 270*1da177e4SLinus Torvalds if (atomic_dec_and_test(&fi->fib_clntref)) 271*1da177e4SLinus Torvalds free_fib_info(fi); 272*1da177e4SLinus Torvalds } 273*1da177e4SLinus Torvalds 274*1da177e4SLinus Torvalds static inline void fib_res_put(struct fib_result *res) 275*1da177e4SLinus Torvalds { 276*1da177e4SLinus Torvalds if (res->fi) 277*1da177e4SLinus Torvalds fib_info_put(res->fi); 278*1da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTIPLE_TABLES 279*1da177e4SLinus Torvalds if (res->r) 280*1da177e4SLinus Torvalds fib_rule_put(res->r); 281*1da177e4SLinus Torvalds #endif 282*1da177e4SLinus Torvalds } 283*1da177e4SLinus Torvalds 284*1da177e4SLinus Torvalds #endif /* _NET_FIB_H */ 285