开始学习Linux路由。管他对不对先从此函数开始:
void __init ip_fib_init(void)
{
/*注册与路由相关的rtnetlink 消息以及他的处理函数,主要处理路由添加删除*/
rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL);
rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL);
rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib); /*注册协议栈子系统,也就是路由系统。 重点--fib_net_ops*/
register_pernet_subsys(&fib_net_ops);
/*register a network notifier block,主要是设备状态改变*/
register_netdevice_notifier(&fib_netdev_notifier);
/*修改设备的配置--IP地址*/
register_inetaddr_notifier(&fib_inetaddr_notifier);
/*为 fib_alias 和 fib_node 分配缓存*/
fib_hash_init();
}
蓝色的字体的部分还在ip_rt_init函数中注册过。针对一个消息注册了两个不同的处理函数,注册函数原型:
void rtnl_register(int protocol, int msgtype,
rtnl_doit_func doit, rtnl_dumpit_func dumpit)
忽略子系统这个东东,看一下fib_net_ops这个玩意:
定义:
struct pernet_operations {
struct list_head list;
int (*init)(struct net *net);
void (*exit)(struct net *net);
};
初始化:
static struct pernet_operations fib_net_ops = {
.init = fib_net_init,
.exit = fib_net_exit,
};
看来是函数指针,不用说这两个函数就是初始化和注销路由子系统的。Go on...
static int __net_init fib_net_init(struct net *net)
{
int error;
error =
ip_fib_net_init(net); if (error < 0)
goto out;
/*创建内核的netlink sock?, 暂时跳过*/
error =
nl_fib_lookup_init(net);
if (error < 0)
goto out_nlfl;
/*创建初始化proc文件系统, 跳过*/
error =
fib_proc_init(net); if (error < 0)
goto out_proc;
out:
return error;
out_proc:
nl_fib_lookup_exit(net);
out_nlfl:
ip_fib_net_exit(net);
goto out;
}
没处下手,一个挨着一个看吧。不过多出来个net。看一下定义吧:
struct net {
atomic_t count; /* To decided when the network
* namespace should be freed.
*/
#ifdef NETNS_REFCNT_DEBUG
atomic_t use_count; /* To track references we
* destroy on demand
*/
#endif
struct list_head list; /* list of network namespaces */
struct work_struct work; /* work struct for freeing */
struct proc_dir_entry *proc_net;
struct proc_dir_entry *proc_net_stat;
#ifdef CONFIG_SYSCTL
struct ctl_table_set sysctls;
#endif
struct net_device *loopback_dev; /* The loopback */
struct list_head dev_base_head;
struct hlist_head *dev_name_head;
struct hlist_head *dev_index_head;
/* core fib_rules */
struct list_head rules_ops; spinlock_t rules_mod_lock;
struct sock *rtnl; /* rtnetlink socket */
struct netns_core core;
struct netns_mib mib;
struct netns_packet packet;
struct netns_unix unx;
struct netns_ipv4 ipv4;#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct netns_ipv6 ipv6;
#endif
#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
struct netns_dccp dccp;
#endif
#ifdef CONFIG_NETFILTER
struct netns_xt xt;
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct netns_ct ct;
#endif
#endif
#ifdef CONFIG_XFRM
struct netns_xfrm xfrm;
#endif
struct net_generic *gen;
};
感觉很多东西都包在其中,是个大家伙。与路由关系密切。尤其是struct netns_ipv4 ipv4;。继续。
static int __net_init ip_fib_net_init(struct net *net){ int err; unsigned int i; /*终于出现表了256大小的hash表,其实每个hash表对应256个路由表*/
net->ipv4.fib_table_hash = kzalloc( sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL); if (net->ipv4.fib_table_hash == NULL) return -ENOMEM; /*初始化每个hash表的冲突链*/
for (i = 0; i < FIB_TABLE_HASHSZ; i++) INIT_HLIST_HEAD(&net->ipv4.fib_table_hash[i]); /*有了256个表,就得提一提Linux的查找路由表的规则, 也就是策略路由ip rule add/del ...*/
err = fib4_rules_init(net); if (err < 0) goto fail; return 0;fail: kfree(net->ipv4.fib_table_hash); return err;}/*有两个同名函数,我选择支持策略路由的这个函数*/
int __net_init fib4_rules_init(struct net *net){ int err; struct fib_rules_ops *ops; /*给ops分配空间,并以
fib4_rules_ops_template初始化ops*/
ops = kmemdup(&fib4_rules_ops_template, sizeof(*ops), GFP_KERNEL); if (ops == NULL) return -ENOMEM; INIT_LIST_HEAD(&ops->rules_list); ops->fro_net = net; /*把协议族不同的路由表规则链起来, 上一句的赋值
ops->fro_net = net 泄漏了他要把这些个玩意 链到哪里 struct list_head rules_ops;*/
fib_rules_register(ops); /*创建三个最基本的路由表local,main,default的规则表*/
err = fib_default_rules_init(ops); if (err < 0) goto fail; net->ipv4.rules_ops = ops; return 0;fail: /* also cleans all rules already added */ fib_rules_unregister(ops); kfree(ops); return err;}看一下
struct fib_rules_ops
{
int family;
struct list_head list;
int rule_size;
int addr_size;
int unresolved_rules;
int nr_goto_rules;
int (*action)(struct fib_rule *,
struct flowi *, int,
struct fib_lookup_arg *);
int (*match)(struct fib_rule *,
struct flowi *, int);
int (*configure)(struct fib_rule *,
struct sk_buff *,
struct nlmsghdr *,
struct fib_rule_hdr *,
struct nlattr **);
int (*compare)(struct fib_rule *,
struct fib_rule_hdr *,
struct nlattr **);
int (*fill)(struct fib_rule *, struct sk_buff *,
struct nlmsghdr *,
struct fib_rule_hdr *);
u32 (*default_pref)(struct fib_rules_ops *ops);
size_t (*nlmsg_payload)(struct fib_rule *);
/* Called after modifications to the rules set, must flush
* the route cache if one exists. */
void (*flush_cache)(struct fib_rules_ops *ops);
int nlgroup;
const struct nla_policy *policy;
/*针对各个路由表的规则链表*/
struct list_head rules_list; struct module *owner;
/*net 和 ops之间的关系*/
struct net *fro_net;};
看一下模板的初始值:
static struct fib_rules_ops fib4_rules_ops_template = {
.
family = AF_INET,
.rule_size = sizeof(struct fib4_rule),
.addr_size = sizeof(u32),
.action = fib4_rule_action,
.match = fib4_rule_match,
.configure = fib4_rule_configure,
.compare = fib4_rule_compare,
.fill = fib4_rule_fill,
.default_pref = fib4_rule_default_pref,
.nlmsg_payload = fib4_rule_nlmsg_payload,
.flush_cache = fib4_rule_flush_cache,
.nlgroup = RTNLGRP_IPV4_RULE,
.policy = fib4_rule_policy,
.owner = THIS_MODULE,
};
static int fib_default_rules_init(struct fib_rules_ops *ops){ int err; /*规则表都链入ops的
rules_list,用路由表的id把表和规则联系起来*/
err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, FIB_RULE_PERMANENT); if (err < 0) return err; err = fib_default_rule_add(ops, 0x7FFE, RT_TABLE_MAIN, 0); if (err < 0) return err; err = fib_default_rule_add(ops, 0x7FFF, RT_TABLE_DEFAULT, 0); if (err < 0) return err; return 0;}
没找见路由表在哪初始化!!!!