1 开始学习Linux路由。管他对不对先从此函数开始:
2
3 void __init ip_fib_init(void)
4 {
5 /*注册与路由相关的rtnetlink 消息以及他的处理函数,主要处理路由添加删除*/
6 rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL);
7 rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL);
8 rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib);
9
10 /*注册协议栈子系统,也就是路由系统。 重点--fib_net_ops*/
11 register_pernet_subsys(&fib_net_ops);
12
13 /*register a network notifier block,主要是设备状态改变*/
14 register_netdevice_notifier(&fib_netdev_notifier);
15 /*修改设备的配置--IP地址*/
16 register_inetaddr_notifier(&fib_inetaddr_notifier);
17
18 /*为 fib_alias 和 fib_node 分配缓存*/
19 fib_hash_init();
20 }
21
22 蓝色的字体的部分还在ip_rt_init函数中注册过。针对一个消息注册了两个不同的处理函数,注册函数原型:
23 void rtnl_register(int protocol, int msgtype,
24 rtnl_doit_func doit, rtnl_dumpit_func dumpit)
25
26 忽略子系统这个东东,看一下fib_net_ops这个玩意:
27 定义:
28 struct pernet_operations {
29 struct list_head list;
30 int (*init)(struct net *net);
31 void (*exit)(struct net *net);
32 };
33 初始化:
34 static struct pernet_operations fib_net_ops = {
35 .init = fib_net_init,
36 .exit = fib_net_exit,
37 };
38
39 看来是函数指针,不用说这两个函数就是初始化和注销路由子系统的。Go on...
40 static int __net_init fib_net_init(struct net *net)
41 {
42 int error;
43
44 error = ip_fib_net_init(net);
45 if (error < 0)
46 goto out;
47 /*创建内核的netlink sock?, 暂时跳过*/
48 error = nl_fib_lookup_init(net);
49 if (error < 0)
50 goto out_nlfl;
51
52 /*创建初始化proc文件系统, 跳过*/
53 error = fib_proc_init(net);
54 if (error < 0)
55 goto out_proc;
56 out:
57 return error;
58
59 out_proc:
60 nl_fib_lookup_exit(net);
61 out_nlfl:
62 ip_fib_net_exit(net);
63 goto out;
64 }
65
66 没处下手,一个挨着一个看吧。不过多出来个net。看一下定义吧:
67 struct net {
68 atomic_t count; /* To decided when the network
69 * namespace should be freed.
70 */
71 #ifdef NETNS_REFCNT_DEBUG
72 atomic_t use_count; /* To track references we
73 * destroy on demand
74 */
75 #endif
76 struct list_head list; /* list of network namespaces */
77 struct work_struct work; /* work struct for freeing */
78
79 struct proc_dir_entry *proc_net;
80 struct proc_dir_entry *proc_net_stat;
81
82 #ifdef CONFIG_SYSCTL
83 struct ctl_table_set sysctls;
84 #endif
85
86 struct net_device *loopback_dev; /* The loopback */
87
88 struct list_head dev_base_head;
89 struct hlist_head *dev_name_head;
90 struct hlist_head *dev_index_head;
91
92 /* core fib_rules */
93 struct list_head rules_ops;
94 spinlock_t rules_mod_lock;
95
96 struct sock *rtnl; /* rtnetlink socket */
97
98 struct netns_core core;
99 struct netns_mib mib;
100 struct netns_packet packet;
101 struct netns_unix unx;
102 struct netns_ipv4 ipv4;
103 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
104 struct netns_ipv6 ipv6;
105 #endif
106 #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
107 struct netns_dccp dccp;
108 #endif
109 #ifdef CONFIG_NETFILTER
110 struct netns_xt xt;
111 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
112 struct netns_ct ct;
113 #endif
114 #endif
115 #ifdef CONFIG_XFRM
116 struct netns_xfrm xfrm;
117 #endif
118 struct net_generic *gen;
119 };
120
121 感觉很多东西都包在其中,是个大家伙。与路由关系密切。尤其是struct netns_ipv4 ipv4;。继续。
122 static int __net_init ip_fib_net_init(struct net *net)
123 {
124 int err;
125 unsigned int i;
126
127 /*终于出现表了256大小的hash表,其实每个hash表对应256个路由表*/
128 net->ipv4.fib_table_hash = kzalloc(
129 sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL);
130 if (net->ipv4.fib_table_hash == NULL)
131 return -ENOMEM;
132
133 /*初始化每个hash表的冲突链*/
134 for (i = 0; i < FIB_TABLE_HASHSZ; i++)
135 INIT_HLIST_HEAD(&net->ipv4.fib_table_hash[i]);
136
137 /*有了256个表,就得提一提Linux的查找路由表的规则, 也就是策略路由ip rule add/del ...*/
138 err = fib4_rules_init(net);
139 if (err < 0)
140 goto fail;
141 return 0;
142
143 fail:
144 kfree(net->ipv4.fib_table_hash);
145 return err;
146 }
147
148 /*有两个同名函数,我选择支持策略路由的这个函数*/
149 int __net_init fib4_rules_init(struct net *net)
150 {
151 int err;
152 struct fib_rules_ops *ops;
153
154 /*给ops分配空间,并以fib4_rules_ops_template初始化ops*/
155 ops = kmemdup(&fib4_rules_ops_template, sizeof(*ops), GFP_KERNEL);
156 if (ops == NULL)
157 return -ENOMEM;
158 INIT_LIST_HEAD(&ops->rules_list);
159 ops->fro_net = net;
160
161 /*把协议族不同的路由表规则链起来, 上一句的赋值ops->fro_net = net 泄漏了他要把这些个玩意 链到哪里 struct list_head rules_ops;*/
162 fib_rules_register(ops);
163
164 /*创建三个最基本的路由表local,main,default的规则表*/
165 err = fib_default_rules_init(ops);
166 if (err < 0)
167 goto fail;
168 net->ipv4.rules_ops = ops;
169 return 0;
170
171 fail:
172 /* also cleans all rules already added */
173 fib_rules_unregister(ops);
174 kfree(ops);
175 return err;
176 }
177
178 看一下
179 struct fib_rules_ops
180 {
181 int family;
182 struct list_head list;
183 int rule_size;
184 int addr_size;
185 int unresolved_rules;
186 int nr_goto_rules;
187
188 int (*action)(struct fib_rule *,
189 struct flowi *, int,
190 struct fib_lookup_arg *);
191 int (*match)(struct fib_rule *,
192 struct flowi *, int);
193 int (*configure)(struct fib_rule *,
194 struct sk_buff *,
195 struct nlmsghdr *,
196 struct fib_rule_hdr *,
197 struct nlattr **);
198 int (*compare)(struct fib_rule *,
199 struct fib_rule_hdr *,
200 struct nlattr **);
201 int (*fill)(struct fib_rule *, struct sk_buff *,
202 struct nlmsghdr *,
203 struct fib_rule_hdr *);
204 u32 (*default_pref)(struct fib_rules_ops *ops);
205 size_t (*nlmsg_payload)(struct fib_rule *);
206
207 /* Called after modifications to the rules set, must flush
208 * the route cache if one exists. */
209 void (*flush_cache)(struct fib_rules_ops *ops);
210
211 int nlgroup;
212 const struct nla_policy *policy;
213 /*针对各个路由表的规则链表*/
214 struct list_head rules_list;
215 struct module *owner;
216 /*net 和 ops之间的关系*/
217 struct net *fro_net;
218 };
219
220 看一下模板的初始值:
221 static struct fib_rules_ops fib4_rules_ops_template = {
222 .family = AF_INET,
223 .rule_size = sizeof(struct fib4_rule),
224 .addr_size = sizeof(u32),
225 .action = fib4_rule_action,
226 .match = fib4_rule_match,
227 .configure = fib4_rule_configure,
228 .compare = fib4_rule_compare,
229 .fill = fib4_rule_fill,
230 .default_pref = fib4_rule_default_pref,
231 .nlmsg_payload = fib4_rule_nlmsg_payload,
232 .flush_cache = fib4_rule_flush_cache,
233 .nlgroup = RTNLGRP_IPV4_RULE,
234 .policy = fib4_rule_policy,
235 .owner = THIS_MODULE,
236 };
237
238 static int fib_default_rules_init(struct fib_rules_ops *ops)
239 {
240 int err;
241
242 /*规则表都链入ops的rules_list,用路由表的id把表和规则联系起来*/
243 err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, FIB_RULE_PERMANENT);
244 if (err < 0)
245 return err;
246 err = fib_default_rule_add(ops, 0x7FFE, RT_TABLE_MAIN, 0);
247 if (err < 0)
248 return err;
249 err = fib_default_rule_add(ops, 0x7FFF, RT_TABLE_DEFAULT, 0);
250 if (err < 0)
251 return err;
252 return 0;
253 }
254
255 没找见路由表在哪初始化!!!