route 源码分析之路由表初始化
时间:2010-09-28 来源:shelcod
开始学习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);
/*Device notifier 这两个注册函数暂且不管*/
register_inetaddr_notifier(&fib_inetaddr_notifier);
/*为 fib_alias 和 fib_node 分配缓存*/
fib_hash_init();
}
忽略子系统这个东东,看一下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;
}
没找见路由表在哪初始化!!!!
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);
/*Device notifier 这两个注册函数暂且不管*/
register_inetaddr_notifier(&fib_inetaddr_notifier);
/*为 fib_alias 和 fib_node 分配缓存*/
fib_hash_init();
}
忽略子系统这个东东,看一下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;
}
没找见路由表在哪初始化!!!!
相关阅读 更多 +