Chinaunix首页 | 论坛 | 博客
  • 博客访问: 192933
  • 博文数量: 16
  • 博客积分: 552
  • 博客等级: 中士
  • 技术积分: 236
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-28 16:41
文章分类

全部博文(16)

文章存档

2012年(1)

2011年(12)

2010年(3)

分类: LINUX

2010-09-28 18:00:28

开始学习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);
    /*修改设备的配置--IP地址*/
    register_inetaddr_notifier(&fib_inetaddr_notifier);

    /*为 fib_alias 和 fib_node 分配缓存*/
    fib_hash_init();
}

蓝色的字体的部分还在ip_rt_init函数中注册过。针对一个消息注册了两个不同的处理函数,注册函数原型:
void rtnl_register(int protocol, int msgtype,
           rtnl_doit_func doit, rtnl_dumpit_func dumpit)

忽略子系统这个东东,看一下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;
}

没找见路由表在哪初始化!!!!


阅读(6298) | 评论(1) | 转发(0) |
0

上一篇:没有了

下一篇:再议路由初始化

给主人留下些什么吧!~~

chinaunix网友2010-09-29 12:56:04

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com