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

 

posted on 2017-05-12 16:56  listenerln  阅读(1680)  评论(0编辑  收藏  举报