⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fib_rules.c

📁 一个基于linux的TCP/IP协议栈的实现
💻 C
字号:
/* fib_rules.c * linqianghe@163.com * 2006-11-07 */#include "fib_rules.h"#include "rtnetlink.h"#include "log.h"#include "ip_fib.h"#include <linux/if.h>#include <linux/netdevice.h>struct fib_rule{	struct fib_rule *r_next;	atomic_t	r_clntref;	u32		r_preference;	unsigned char	r_table;	unsigned char	r_action;	unsigned char	r_dst_len;	unsigned char	r_src_len;	u32		r_src;	u32		r_srcmask;	u32		r_dst;	u32		r_dstmask;	u32		r_srcmap;	u8		r_flags;	u8		r_tos;#ifdef CONFIG_IP_ROUTE_FWMARK	u32		r_fwmark;#endif	int		r_ifindex;#ifdef CONFIG_NET_CLS_ROUTE	__u32	r_tclassid;#endif	char	r_ifname[IFNAMSIZ];	int		r_dead;};static struct fib_rule mydefault_rule = {	.r_clntref =	ATOMIC_INIT(2),	.r_preference =	0x7FFF,	.r_table =	RT_TABLE_DEFAULT,	.r_action =	RTN_UNICAST,};static struct fib_rule mymain_rule = {	.r_next =	&mydefault_rule,	.r_clntref =	ATOMIC_INIT(2),	.r_preference =	0x7FFE,	.r_table =	RT_TABLE_MAIN,	.r_action =	RTN_UNICAST,};static struct fib_rule mylocal_rule = {	.r_next =	&mymain_rule,	.r_clntref =	ATOMIC_INIT(2),	.r_table =	RT_TABLE_LOCAL,	.r_action =	RTN_UNICAST,};static struct fib_rule *myfib_rules = &mylocal_rule;static DEFINE_RWLOCK( myfib_rules_lock );#ifdef CONFIG_NET_CLS_ROUTEu32 myfib_rules_tclass(struct fib_result *res){	if( res->r )		return res->r->r_tclassid;	return 0;}#endifstatic void myfib_rules_detach(struct net_device *dev){	struct fib_rule *r;	for( r = myfib_rules; r; r = r->r_next ){		if( r->r_ifindex == dev->ifindex ){			write_lock_bh( &myfib_rules_lock );			r->r_ifindex = -1;			write_unlock_bh( &myfib_rules_lock );		}	}}static void myfib_rules_attach( struct net_device *dev ){	struct fib_rule *r;	for( r = myfib_rules; r; r = r->r_next ){		if( r->r_ifindex == -1 && strcmp(dev->name, r->r_ifname) == 0 ) {			write_lock_bh( &myfib_rules_lock );			r->r_ifindex = dev->ifindex;			write_unlock_bh( &myfib_rules_lock );		}	}}int myfib_lookup(const struct flowi *flp, struct fib_result *res){	int err;	struct fib_rule *r, *policy;	struct fib_table *tb;	u32 daddr = flp->fl4_dst;	u32 saddr = flp->fl4_src;	PR_DEBUG("Lookup: %u.%u.%u.%u <- %u.%u.%u.%u ", NIPQUAD(flp->fl4_dst), NIPQUAD(flp->fl4_src));	read_lock(&myfib_rules_lock);	for( r = myfib_rules; r; r=r->r_next) {		if( ((saddr^r->r_src) & r->r_srcmask) || ((daddr^r->r_dst) & r->r_dstmask) ||						(r->r_tos && r->r_tos != flp->fl4_tos) ||#ifdef CONFIG_IP_ROUTE_FWMARK						(r->r_fwmark && r->r_fwmark != flp->fl4_fwmark) ||#endif						(r->r_ifindex && r->r_ifindex != flp->iif))			continue;		PR_DEBUG("tb %d r %d ", r->r_table, r->r_action);		switch (r->r_action) {		case RTN_UNICAST:			policy = r;			break;		case RTN_UNREACHABLE:			read_unlock( &myfib_rules_lock );			return -ENETUNREACH;		default:		case RTN_BLACKHOLE:			read_unlock( &myfib_rules_lock );			return -EINVAL;		case RTN_PROHIBIT:			read_unlock( &myfib_rules_lock );			return -EACCES;		}		if ((tb = myfib_get_table(r->r_table)) == NULL)			continue;		err = tb->tb_lookup( tb, flp, res );		if( err == 0 ){			res->r = policy;			if( policy )				atomic_inc(&policy->r_clntref);			read_unlock( &myfib_rules_lock );			return 0;		}		if (err < 0 && err != -EAGAIN) {			read_unlock( &myfib_rules_lock );			return err;		}	}	PR_DEBUG("FAILURE\n");	read_unlock( &myfib_rules_lock );	return -ENETUNREACH;}static int myfib_rules_event( struct notifier_block *this, unsigned long event, void *ptr ){	struct net_device *dev = ptr;	if( event == NETDEV_UNREGISTER )		myfib_rules_detach(dev);	else if( event == NETDEV_REGISTER )		myfib_rules_attach(dev);	return NOTIFY_DONE;}void myfib_select_default( const struct flowi *flp, struct fib_result *res ){	if( res->r && res->r->r_action == RTN_UNICAST &&					FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) {		struct fib_table *tb;		if ((tb = myfib_get_table(res->r->r_table)) != NULL)			tb->tb_select_default(tb, flp, res);	}}void myfib_rule_put(struct fib_rule *r){	if( atomic_dec_and_test(&r->r_clntref) ){		if( r->r_dead )			kfree(r);		else			PR_NOTICE("Freeing alive rule %p\n", r);	}}static struct notifier_block myfib_rules_notifier = {	.notifier_call = myfib_rules_event,};void __init myfib_rules_init(void){	register_netdevice_notifier( &myfib_rules_notifier );}void __exit myfib_rules_exit(void){	unregister_netdevice_notifier( &myfib_rules_notifier );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -