我是靠谱客的博主 靓丽小兔子,最近开发中收集的这篇文章主要介绍路由1【转载: route 源码分析之路由表初始化 】,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述


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 没找见路由表在哪初始化!!!

 

转载于:https://www.cnblogs.com/listenerln/p/6846302.html

最后

以上就是靓丽小兔子为你收集整理的路由1【转载: route 源码分析之路由表初始化 】的全部内容,希望文章能够帮你解决路由1【转载: route 源码分析之路由表初始化 】所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(77)

评论列表共有 0 条评论

立即
投稿
返回
顶部