• 路由fib 数据结构


    •  全局散列表net->ipv4.fib_table_hash中,存放所有的路由表fib_table;

    结构体fib_alias

            相同网段的每一条路由表项有各自的fib_alias结构;多个fib_alias可以共享一个fib_info结构;

            struct fib_alias

    struct list_head fa_list;

    //将所有fib_alias组成的链表

    struct fib_info *fa_info;

    //指向fib_info,储存如何处理路由信息

    u8 fa_tos;

    //路由的服务类型比特位字段

    u8 fa_type;

    //路由表项的类型,间接定义了当路由查找匹配时,应采取的动作

    u8 fa_scope;

    //路由表项的作用范围

    u8 fa_state;

    //一些标志位,目前只有FA_S_ACCESSED。表示该表项已经被访问过。

    结构体fib_info

            结构体Fib_info存储真正重要路由信息,即如何到达目的地。

            struct fib_info

    struct hlist_node fib_hash;

    //所有fib_info组成的散列表,该表为全局散列表fib_info_hash

    struct hlist_node fib_lhash;

    //当存在首源地址时,才会将fib_info插入该散列表,该表为全局散列表fib_info_laddrhash

    struct net *fib_net;

    Int fib_treeref;

    //使用该fib_info结构的fib_node的数目

    atomic_t fib_clntref;

    //引用计数。路由查找成功而被持有的引用计数

    Int fib_dead;

    //标记路由表项正在被删除的标志,当该标志被设置为1时,警告该数据结构将被删除而不能再使用

    Unsigned fib_flags;

    //当前使用的唯一标志是RTNH_F_DEAD,表示下一跳已无效

    Int fib_protocol;

    //设置路由的协议

    __be32 fib_prefsrc;

    //首选源IP地址

    u32 fib_priority;

    //路由优先级,默认为0,值越小优先级越高

    u32 fib_metrics[RTAX_MAX];

    //与路由相关的度量值

    Int fib_nhs;

    //可用的下一跳数量,通常为1.只有支持多路径路由时,才大于1

    struct fib_nh fib_nh[0];

    //表示路由的下一跳

    结构体fib_nh

             该结构体中存放着下一跳路由的地址nh_gw。

            struct fib_nh

    struct net_device *nh_dev;

    //该路由表项输出网络设备

    struct hlist_node nh_hash;

    //fib_nh组成的散列表

    struct fib_info *nh_parent;

    //指向所属fib_info结构体

    struct fib_info *nh_parent;

    Unsigned nh_flags;

    unsigned char nh_scope;

    Int nh_oif;

    //输出网络设备索引

    __be32 nh_gw;

    //网关地址

     策略规则结构体fib_rule

    struct fib_rule {
        struct list_head    list;
        int            iifindex;//接 口 index
        int            oifindex;// out 接口index
        u32            mark;//mark 值
        u32            mark_mask;//mark 掩 码 值
        u32            flags;
        u32            table;//路由表id
        u8            action;//规则
        /* 3 bytes hole, try to use */
        u32            target;
        __be64            tun_id;
        struct fib_rule __rcu    *ctarget;
        struct net        *fr_net;
    
        atomic_t        refcnt;//引 用 计 数
        u32            pref;//优先级, 值越小优先级越大
        int            suppress_ifgroup;
        int            suppress_prefixlen;
        char            iifname[IFNAMSIZ];//入接 口 名 称
        char            oifname[IFNAMSIZ];//出接 口 名 称
        struct rcu_head        rcu;
    };

    策略操作函数fib_rules_ops

    struct fib_rules_ops {
        int            family;//对应协议簇
        struct list_head    list;//将注册到系统的fib_rules_ops链接到链表rules_ops
        int            rule_size;//一个策略规则所占用的内存大小
        int            addr_size;//协议相关的地址长度
        int            unresolved_rules;
        int            nr_goto_rules;
        //action函数,策略规则匹配后,所调用的action函数,执行后续的操作。
            //一般是获取到相应的路由表,查找符合要求的路由项
        int            (*action)(struct fib_rule *,
                          struct flowi *, int,
                          struct fib_lookup_arg *);
        bool            (*suppress)(struct fib_rule *,
                            struct fib_lookup_arg *);
        
    //规则匹配函数,对于策略规则的匹配,首先是通用匹配,待通用匹配完成后,
     //则会调用该函数,进行协议相关参数(源、目的地址等)的匹配
        int            (*match)(struct fib_rule *,
                         struct flowi *, int);
        //协议相关的配置参数
        int            (*configure)(struct fib_rule *,
                             struct sk_buff *,
                             struct fib_rule_hdr *,
                             struct nlattr **);
        int            (*delete)(struct fib_rule *);
        int            (*compare)(struct fib_rule *,
                           struct fib_rule_hdr *,
                           struct nlattr **);
        int            (*fill)(struct fib_rule *, struct sk_buff *,
                        struct fib_rule_hdr *);
        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;//将该协议簇已添加的所有fib_rule规则链接在一起
        struct module        *owner;
        struct net        *fro_net;
        struct rcu_head        rcu;
    };

     ipv4类型的策略规则       

    IPV4协议相关的fib4_rule结构,该结构包含了基础的fib_rule,增加源IP、目的IP、tos等相关IPV4成员

    struct fib4_rule//ipv4相关的结构
    {
        struct fib_rule     common;
        u8          dst_len;
        u8          src_len;
        u8          tos;
        __be32          src;//源ip
        __be32          srcmask;
        __be32          dst;//目的ip
        __be32          dstmask;
    #ifdef CONFIG_NET_CLS_ROUTE
        u32         tclassid;
    #endif
    };
        rule4->src_len = frh->src_len;
        rule4->srcmask = inet_make_mask(rule4->src_len);
        rule4->dst_len = frh->dst_len;
        rule4->dstmask = inet_make_mask(rule4->dst_len);
        rule4->tos = frh->tos;    

    路由策略初始化

    IPV4协议相关初始化fib4_rules_init
    功能:(1)注册fib4_rules_ops
    (2)创建local、main、default规则表,添到rules_list
    (3)将fib4_rules_ops添到rules_ops中。

    static const struct fib_rules_ops __net_initconst fib4_rules_ops_template = {
        .family        = AF_INET,
        .rule_size    = sizeof(struct fib4_rule),
        .addr_size    = sizeof(u32),
        .action        = fib4_rule_action,
        .suppress    = fib4_rule_suppress,
        .match        = fib4_rule_match,
        .configure    = fib4_rule_configure,
        .delete        = fib4_rule_delete,
        .compare    = fib4_rule_compare,
        .fill        = fib4_rule_fill,
        .nlmsg_payload    = fib4_rule_nlmsg_payload,
        .flush_cache    = fib4_rule_flush_cache,
        .nlgroup    = RTNLGRP_IPV4_RULE,
        .policy        = fib4_rule_policy,
        .owner        = THIS_MODULE,
    };
    int __net_init fib4_rules_init(struct net *net)
    {
        int err;
        struct fib_rules_ops *ops;
    
        ops = fib_rules_register(&fib4_rules_ops_template, net);  //执行kdump-memcpy 拷贝一份fib4_rules_ops_template 同时list 到net->rules_ops上去
        err = fib_default_rules_init(ops);/*创建 local main default 对应的 fib_rule,最后list 到 fib_rules_ops->rules-list 链表上去,
        也就是ipv4 只有一个rules-ops 但是有很多table fiber_rule*/
        net->ipv4.rules_ops = ops;
        net->ipv4.fib_has_custom_rules = false;
        return 0;
    
    }
    static int fib_default_rules_init(struct fib_rules_ops *ops)
    {
        int err;
        err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, 0);
        err = fib_default_rule_add(ops, 0x7FFE, RT_TABLE_MAIN, 0);
        err = fib_default_rule_add(ops, 0x7FFF, RT_TABLE_DEFAULT, 0);
    }
    int fib_default_rule_add(struct fib_rules_ops *ops,
                 u32 pref, u32 table, u32 flags)
    {
        struct fib_rule *r;
    
        r = kzalloc(ops->rule_size, GFP_KERNEL);
        atomic_set(&r->refcnt, 1);
        r->action = FR_ACT_TO_TBL;
        r->pref = pref;
        r->table = table;
        r->flags = flags;
        r->fr_net = ops->fro_net;
    
        r->suppress_prefixlen = -1;
        r->suppress_ifgroup = -1;
    
        /* The lock is not required here, the list in unreacheable
         * at the moment this function is called */
        list_add_tail(&r->list, &ops->rules_list);
        return 0;
    }
  • 相关阅读:
    SQL Server的Execute As与连接池结合使用的测试
    为什么SQL语句Where 1=1 and在SQL Server中不影响性能
    [转]NGINX下配置CACHE-CONTROL
    ls列出当前目录包含子目录下面的所有文件的绝对路径
    [转]无法滚动到溢出容器的Flex项的顶部
    align-items和align-content的区别
    go实现快速排序
    [转]linux超级服务器inetd详解
    makefile 小记
    [转]gcc
  • 原文地址:https://www.cnblogs.com/codestack/p/15961154.html
Copyright © 2020-2023  润新知