📄 myfib_rules.c
字号:
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 );extern struct fib_table *myfib_tables[RT_TABLE_MAX+1];static struct fib_table *myfib_get_table(int id);#ifdef CONFIG_NET_CLS_ROUTEu32 myfib_rules_tclass(struct fib_result *res){ if (res->r) return res->r->r_tclassid; return 0;}#endifstatic inline void myfib_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 = myfib_rules_tclass(res); if (*itag == 0) *itag = (rtag<<16); *itag |= (rtag>>16);#endif#endif}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; printk(KERN_INFO "Lookup: %u.%u.%u.%u <- %u.%u.%u.%u\n", 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; printk(KERN_INFO "tb %d r %d\n", 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; } printk(KERN_INFO "before get fib table!\n"); if( (tb =myfib_get_table(r->r_table)) == NULL ) continue; printk(KERN_INFO "fib get talbe done!\n"); err = tb->tb_lookup(tb, flp, res); if (err == 0) { printk("tb look up done!\n"); 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; } } read_unlock( &myfib_rules_lock ); return -ENETUNREACH;}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 fib_rule_put(struct fib_rule *r){}static 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); } }}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;}static struct notifier_block myfib_rules_notifier = { .notifier_call = myfib_rules_event,};void __init myfib_rules_init(void){ register_netdevice_notifier(&myfib_rules_notifier);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -