linux内核 路由缓存表之数据结构

三、路由缓存表
3.1 基本结构

(1)路由缓存存放在全局散列表rt_hash_table中,类型为rt_hash_bucket,该成员变量指向缓存元素。
        struct rt_hash_bucket {
        struct rtable *chain;

        };


(2)rtable结构
        用来储存缓存中的路由表项,可以通过/proc/net/rt_cache查看
struct rtable
{
    union
    {
        struct dst_entry    dst;//独立于协议的信息
    } u;
    /* Cache lookup keys */
    struct flowi        fl;//缓存查询键值
    struct in_device    *idev;//输出网络设备的IP配置
    int         rt_genid;
    unsigned        rt_flags;//标识路由表项的特征
    __u16           rt_type;//路由的类型,
    __be32          rt_dst; /* Path destination */
    __be32          rt_src; /* Path source      */
    int         rt_iif; //输入设备的标识
    /* Info on neighbour */
    __be32          rt_gateway; //目的地址或下一跳网关
    /* Miscellaneous cached information */
    __be32          rt_spec_dst; /* RFC1122 specific destination */
    struct inet_peer    *peer; /* long-living peer info */
#if defined(CONFIG_MV_ETH_NFP_FIB_LEARN)
    bool            nfp;
#endif /* CONFIG_MV_ETH_NFP_FIB_LEARN */
};


(3)flowi结构

        根据诸如输入网络设备、输出网络设备、三层和四层协议报头中的参数等字段组合。
struct flowi {
    int oif;//输出网络设备索引
    int iif;//输入网络设备索引
    __u32   mark;

    union {
        struct {
            __be32          daddr;
            __be32          saddr;
            __u8            tos;
            __u8            scope;
        } ip4_u;
        
        struct {
            struct in6_addr     daddr;
            struct in6_addr     saddr;
            __be32          flowlabel;
        } ip6_u;

        struct {
            __le16          daddr;
            __le16          saddr;
            __u8            scope;
        } dn_u;
    } nl_u;//三层相关成员,地址联合体,针对IPV4/IPV6/DECnet
#define fld_dst     nl_u.dn_u.daddr
#define fld_src     nl_u.dn_u.saddr
#define fld_scope   nl_u.dn_u.scope
#define fl6_dst     nl_u.ip6_u.daddr
#define fl6_src     nl_u.ip6_u.saddr
#define fl6_flowlabel   nl_u.ip6_u.flowlabel
#define fl4_dst     nl_u.ip4_u.daddr
#define fl4_src     nl_u.ip4_u.saddr
#define fl4_tos     nl_u.ip4_u.tos
#define fl4_scope   nl_u.ip4_u.scope

    __u8    proto;//标识四层协议
    __u8    flags;
#define FLOWI_FLAG_ANYSRC 0x01
    union {
        struct {
            __be16  sport;
            __be16  dport;
        } ports;

        struct {
            __u8    type;
            __u8    code;
        } icmpt;

        struct {
            __le16  sport;
            __le16  dport;
        } dnports;

        __be32      spi;

        struct {
            __u8    type;
        } mht;
    } uli_u;//四层协议参数联合体,针对TCP/UDP/ICMP/DECnet/IPsec
#define fl_ip_sport uli_u.ports.sport
#define fl_ip_dport uli_u.ports.dport
#define fl_icmp_type    uli_u.icmpt.type
#define fl_icmp_code    uli_u.icmpt.code
#define fl_ipsec_spi    uli_u.spi
#define fl_mh_type  uli_u.mht.type
    __u32           secid;  /* used by xfrm; see secid.txt */
}

(4)dst_entry结构
        存储缓存路由项中独立于协议的信息。
struct dst_entry
{
    struct rcu_head     rcu_head;
    struct dst_entry    *child;
    struct net_device       *dev;//输出网络设备 
    short           error;//fib_lookup查找失败时的错误码
    short           obsolete;
    int         flags;
#define DST_HOST        1
#define DST_NOXFRM      2
#define DST_NOPOLICY        4
#define DST_NOHASH      8
    unsigned long       expires;//过期的时间戳

    unsigned short      header_len; /* more space at head required */
    unsigned short      trailer_len;    /* space to reserve at tail */

    unsigned int        rate_tokens;    //对ICMP消息限速
    unsigned long       rate_last;  /* rate limiting for ICMP */

    struct dst_entry    *path;

    struct neighbour    *neighbour;
    struct hh_cache     *hh;    //指向缓存的二层头部
#ifdef CONFIG_XFRM
    struct xfrm_state   *xfrm;
#else
    void            *__pad1;
#endif
    //暂时写下,后面再理解
    /*输入、输出相关的函数指针,当在函数ip_rcv_finish中,完成路由的查找后,
    根据input、output函数,传递数据包。
    本地接收的数据包,则其input指向函数ip_local_deliver,只用到input函数
    要转发的数据包,其input指向函数ip_forward,其output指向函数ip_output,两个都要用
    本地发出的数据包,只用到output  */
    int         (*input)(struct sk_buff*);
    int         (*output)(struct sk_buff*);

    struct  dst_ops         *ops;//用于处理dst_entry的函数集

    u32         metrics[RTAX_MAX]; //保存很多和对端通信时所需的数值,比如initcwnd、max_mtu等

#ifdef CONFIG_NET_CLS_ROUTE
    __u32           tclassid;
#else
    __u32           __pad2;
#endif


    /*
     * Align __refcnt to a 64 bytes alignment
     * (L1_CACHE_SIZE would be too much)
     */
#ifdef CONFIG_64BIT
    long            __pad_to_align_refcnt[2];
#else
    long            __pad_to_align_refcnt[1];
#endif
    /*
     * __refcnt wants to be on a different cache line from
     * input/output/ops or performance tanks badly
     */
    atomic_t        __refcnt;   /* client references    *///引用计数
    int         __use;
    unsigned long       lastuse;//最近一次使用该路由缓存的时间戳
    union {
        struct dst_entry *next;
        struct rtable    *rt_next;
        struct rt6_info   *rt6_next;
        struct dn_route  *dn_next;
    };
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值