2005-04-17 02:20:36 +04:00
/*
* INET An implementation of the TCP / IP protocol suite for the LINUX
* operating system . INET is implemented using the BSD Socket
* interface as the means of communication with the user level .
*
* Definitions for the Forwarding Information Base .
*
* Authors : A . N . Kuznetsov , < kuznet @ ms2 . inr . ac . ru >
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*/
# ifndef _NET_IP_FIB_H
# define _NET_IP_FIB_H
# include <linux/config.h>
# include <net/flow.h>
# include <linux/seq_file.h>
/* WARNING: The ordering of these elements must match ordering
* of RTA_ * rtnetlink attribute numbers .
*/
struct kern_rta {
void * rta_dst ;
void * rta_src ;
int * rta_iif ;
int * rta_oif ;
void * rta_gw ;
u32 * rta_priority ;
void * rta_prefsrc ;
struct rtattr * rta_mx ;
struct rtattr * rta_mp ;
unsigned char * rta_protoinfo ;
u32 * rta_flow ;
struct rta_cacheinfo * rta_ci ;
struct rta_session * rta_sess ;
u32 * rta_mp_alg ;
} ;
struct fib_info ;
struct fib_nh {
struct net_device * nh_dev ;
struct hlist_node nh_hash ;
struct fib_info * nh_parent ;
unsigned nh_flags ;
unsigned char nh_scope ;
# ifdef CONFIG_IP_ROUTE_MULTIPATH
int nh_weight ;
int nh_power ;
# endif
# ifdef CONFIG_NET_CLS_ROUTE
__u32 nh_tclassid ;
# endif
int nh_oif ;
u32 nh_gw ;
} ;
/*
* This structure contains data shared by many of routes .
*/
struct fib_info {
struct hlist_node fib_hash ;
struct hlist_node fib_lhash ;
int fib_treeref ;
atomic_t fib_clntref ;
int fib_dead ;
unsigned fib_flags ;
int fib_protocol ;
u32 fib_prefsrc ;
u32 fib_priority ;
u32 fib_metrics [ RTAX_MAX ] ;
# define fib_mtu fib_metrics[RTAX_MTU-1]
# define fib_window fib_metrics[RTAX_WINDOW-1]
# define fib_rtt fib_metrics[RTAX_RTT-1]
# define fib_advmss fib_metrics[RTAX_ADVMSS-1]
int fib_nhs ;
# ifdef CONFIG_IP_ROUTE_MULTIPATH
int fib_power ;
# endif
# ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
u32 fib_mp_alg ;
# endif
struct fib_nh fib_nh [ 0 ] ;
# define fib_dev fib_nh[0].nh_dev
} ;
# ifdef CONFIG_IP_MULTIPLE_TABLES
struct fib_rule ;
# endif
struct fib_result {
unsigned char prefixlen ;
unsigned char nh_sel ;
unsigned char type ;
unsigned char scope ;
# ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
__u32 network ;
__u32 netmask ;
# endif
struct fib_info * fi ;
# ifdef CONFIG_IP_MULTIPLE_TABLES
struct fib_rule * r ;
# endif
} ;
2005-06-21 00:36:39 +04:00
struct fib_result_nl {
u32 fl_addr ; /* To be looked up*/
u32 fl_fwmark ;
unsigned char fl_tos ;
unsigned char fl_scope ;
unsigned char tb_id_in ;
unsigned char tb_id ; /* Results */
unsigned char prefixlen ;
unsigned char nh_sel ;
unsigned char type ;
unsigned char scope ;
int err ;
} ;
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_IP_ROUTE_MULTIPATH
# define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
# define FIB_RES_RESET(res) ((res).nh_sel = 0)
# else /* CONFIG_IP_ROUTE_MULTIPATH */
# define FIB_RES_NH(res) ((res).fi->fib_nh[0])
# define FIB_RES_RESET(res)
# endif /* CONFIG_IP_ROUTE_MULTIPATH */
# define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res))
# define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw)
# define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev)
# define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif)
# ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
# define FIB_RES_NETWORK(res) ((res).network)
# define FIB_RES_NETMASK(res) ((res).netmask)
# else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
# define FIB_RES_NETWORK(res) (0)
# define FIB_RES_NETMASK(res) (0)
# endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */
struct fib_table {
unsigned char tb_id ;
unsigned tb_stamp ;
int ( * tb_lookup ) ( struct fib_table * tb , const struct flowi * flp , struct fib_result * res ) ;
int ( * tb_insert ) ( struct fib_table * table , struct rtmsg * r ,
struct kern_rta * rta , struct nlmsghdr * n ,
struct netlink_skb_parms * req ) ;
int ( * tb_delete ) ( struct fib_table * table , struct rtmsg * r ,
struct kern_rta * rta , struct nlmsghdr * n ,
struct netlink_skb_parms * req ) ;
int ( * tb_dump ) ( struct fib_table * table , struct sk_buff * skb ,
struct netlink_callback * cb ) ;
int ( * tb_flush ) ( struct fib_table * table ) ;
void ( * tb_select_default ) ( struct fib_table * table ,
const struct flowi * flp , struct fib_result * res ) ;
unsigned char tb_data [ 0 ] ;
} ;
# ifndef CONFIG_IP_MULTIPLE_TABLES
extern struct fib_table * ip_fib_local_table ;
extern struct fib_table * ip_fib_main_table ;
static inline struct fib_table * fib_get_table ( int id )
{
if ( id ! = RT_TABLE_LOCAL )
return ip_fib_main_table ;
return ip_fib_local_table ;
}
static inline struct fib_table * fib_new_table ( int id )
{
return fib_get_table ( id ) ;
}
static inline int fib_lookup ( const struct flowi * flp , struct fib_result * res )
{
if ( ip_fib_local_table - > tb_lookup ( ip_fib_local_table , flp , res ) & &
ip_fib_main_table - > tb_lookup ( ip_fib_main_table , flp , res ) )
return - ENETUNREACH ;
return 0 ;
}
static inline void fib_select_default ( const struct flowi * flp , struct fib_result * res )
{
if ( FIB_RES_GW ( * res ) & & FIB_RES_NH ( * res ) . nh_scope = = RT_SCOPE_LINK )
ip_fib_main_table - > tb_select_default ( ip_fib_main_table , flp , res ) ;
}
# else /* CONFIG_IP_MULTIPLE_TABLES */
# define ip_fib_local_table (fib_tables[RT_TABLE_LOCAL])
# define ip_fib_main_table (fib_tables[RT_TABLE_MAIN])
extern struct fib_table * fib_tables [ RT_TABLE_MAX + 1 ] ;
extern int fib_lookup ( const struct flowi * flp , struct fib_result * res ) ;
extern struct fib_table * __fib_new_table ( int id ) ;
extern void fib_rule_put ( struct fib_rule * r ) ;
static inline struct fib_table * fib_get_table ( int id )
{
if ( id = = 0 )
id = RT_TABLE_MAIN ;
return fib_tables [ id ] ;
}
static inline struct fib_table * fib_new_table ( int id )
{
if ( id = = 0 )
id = RT_TABLE_MAIN ;
return fib_tables [ id ] ? : __fib_new_table ( id ) ;
}
extern void fib_select_default ( const struct flowi * flp , struct fib_result * res ) ;
# endif /* CONFIG_IP_MULTIPLE_TABLES */
/* Exported by fib_frontend.c */
extern void ip_fib_init ( void ) ;
extern int inet_rtm_delroute ( struct sk_buff * skb , struct nlmsghdr * nlh , void * arg ) ;
extern int inet_rtm_newroute ( struct sk_buff * skb , struct nlmsghdr * nlh , void * arg ) ;
extern int inet_rtm_getroute ( struct sk_buff * skb , struct nlmsghdr * nlh , void * arg ) ;
extern int inet_dump_fib ( struct sk_buff * skb , struct netlink_callback * cb ) ;
extern int fib_validate_source ( u32 src , u32 dst , u8 tos , int oif ,
struct net_device * dev , u32 * spec_dst , u32 * itag ) ;
extern void fib_select_multipath ( const struct flowi * flp , struct fib_result * res ) ;
/* Exported by fib_semantics.c */
extern int ip_fib_check_default ( u32 gw , struct net_device * dev ) ;
extern int fib_sync_down ( u32 local , struct net_device * dev , int force ) ;
extern int fib_sync_up ( struct net_device * dev ) ;
extern int fib_convert_rtentry ( int cmd , struct nlmsghdr * nl , struct rtmsg * rtm ,
struct kern_rta * rta , struct rtentry * r ) ;
extern u32 __fib_res_prefsrc ( struct fib_result * res ) ;
/* Exported by fib_hash.c */
extern struct fib_table * fib_hash_init ( int id ) ;
# ifdef CONFIG_IP_MULTIPLE_TABLES
/* Exported by fib_rules.c */
extern int inet_rtm_delrule ( struct sk_buff * skb , struct nlmsghdr * nlh , void * arg ) ;
extern int inet_rtm_newrule ( struct sk_buff * skb , struct nlmsghdr * nlh , void * arg ) ;
extern int inet_dump_rules ( struct sk_buff * skb , struct netlink_callback * cb ) ;
# ifdef CONFIG_NET_CLS_ROUTE
extern u32 fib_rules_tclass ( struct fib_result * res ) ;
# endif
extern void fib_rules_init ( void ) ;
# endif
static inline void fib_combine_itag ( u32 * itag , struct fib_result * res )
{
# ifdef CONFIG_NET_CLS_ROUTE
# ifdef CONFIG_IP_MULTIPLE_TABLES
u32 rtag ;
# endif
* itag = FIB_RES_NH ( * res ) . nh_tclassid < < 16 ;
# ifdef CONFIG_IP_MULTIPLE_TABLES
rtag = fib_rules_tclass ( res ) ;
if ( * itag = = 0 )
* itag = ( rtag < < 16 ) ;
* itag | = ( rtag > > 16 ) ;
# endif
# endif
}
extern void free_fib_info ( struct fib_info * fi ) ;
static inline void fib_info_put ( struct fib_info * fi )
{
if ( atomic_dec_and_test ( & fi - > fib_clntref ) )
free_fib_info ( fi ) ;
}
static inline void fib_res_put ( struct fib_result * res )
{
if ( res - > fi )
fib_info_put ( res - > fi ) ;
# ifdef CONFIG_IP_MULTIPLE_TABLES
if ( res - > r )
fib_rule_put ( res - > r ) ;
# endif
}
2005-08-16 09:18:02 +04:00
# ifdef CONFIG_PROC_FS
extern int fib_proc_init ( void ) ;
extern void fib_proc_exit ( void ) ;
# endif
2005-04-17 02:20:36 +04:00
# endif /* _NET_FIB_H */