zoukankan      html  css  js  c++  java
  • 路由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 没找见路由表在哪初始化!!!
  • 相关阅读:
    scrapy爬虫框架学习
    python:面向对象—— __slots__来限制实例的属性命名范围
    列表list 的常用操作
    python replace()用法
    python 字符串 空字符串 len()
    python 字符串 编码问题
    python中语句、函数、类、模块、包之间的关系
    matplotlib 绘制正玄余玄曲线
    Es6/CommonJs/AMD模块系统的差异以及用法
    BOM和DOM的区别
  • 原文地址:https://www.cnblogs.com/listenerln/p/6846302.html
Copyright © 2011-2022 走看看