Skip to content

IPv4 FIB 路由结构

1. 模块架构

1.1 功能概述

FIB (Forwarding Information Base) 是内核用于快速查找路由的数据结构。

1.2 关键源文件

文件作用
net/ipv4/fib_frontend.cFIB 前端
net/ipv4/fib_semantics.cFIB 语义
net/ipv4/fib_lookup.hFIB 查找接口
net/ipv4/fib_trie.cFIB Trie 实现

2. 核心数据结构

2.1 struct fib_table

c
// include/net/ip_fib.h:180
struct fib_table {
    struct hlist_node tb_hlist;      // 哈希链表
    u32             tb_id;          // 表 ID (AS number)
    unsigned int    tb_data_size;    // 数据大小
    unsigned char   tb_stamp;        // 时间戳
    int             (*tb_lookup)(struct fib_table *, const struct flowi4 *,
                                 struct fib_result *);
    int             (*tb_insert)(struct fib_table *, struct fib_result *,
                                 struct fib_info *, int);
    int             (*tb_delete)(struct fib_table *, struct fib_result *,
                                 struct fib_info *);
    void            (*tb_flush)(struct fib_table *);
    void            (*tb_select_default)(struct fib_table *,
                                        const struct flowi4 *,
                                        struct fib_result *);
    void            *tb_data;
};

2.2 struct fib_result

c
// include/net/ip_fib.h:150
struct fib_result {
    __be32          prefix;          // 前缀
    unsigned char   prefixlen;       // 前缀长度
    unsigned char   nh_sel;          // 下一跳选择
    unsigned char   type;            // 路由类型
    unsigned char   scope;           // 范围
    struct fib_info *fi;             // 路由信息
    struct fib_info *fib_info;
};

2.3 struct fib_info

c
// include/net/ip_fib.h:80
struct fib_info {
    struct hlist_node   fib_hash;     // 哈希链表
    struct list_head    fib_list;     // 路由信息链表
    struct net_device   *fib_dev;     // 关联设备
    struct fib_nh_common fib_nhc;

    unsigned int        fib_priority; // 优先级
    unsigned int        fib_prefsrc;  // 优选源地址
    unsigned int        fib_metrics[RTAX_MAX];

    u32                 fib_nh_genid;  // 代际号
};

2.4 struct fib_nh

c
// include/net/ip_fib.h:50
struct fib_nh {
    struct net_device   *nh_device;    // 下一跳设备
    __be32              nh_gw;        // 下一跳地址
    unsigned int        nh_oif;       // 输出接口索引
    unsigned int        nh_weight;    // 权重
    int                 nh_parent;    // 父结构
};

3. Trie 结构

3.1 struct trie

c
// net/ipv4/fib_trie.c:100
struct trie {
    struct node *trie;                // Trie 根节点
    size_t size;                       // Trie 大小
    struct rcu_head rcu;
};

3.2 struct key_vector

c
// net/ipv4/fib_trie.c:80
struct key_vector {
    unsigned long bits;               // 关键位
    struct rcu_head rcu;

    // 子节点
    struct key_vector *children[0];
};

4. 查找流程

4.1 fib_lookup()

c
// net/ipv4/fib_frontend.c:120
int fib_lookup(struct net *net, const struct flowi4 *flp,
               struct fib_result *res)
{
    struct fib_table *table;

    // 获取主表
    table = fib_get_table(net, RT_TABLE_MAIN);
    if (!table)
        return -ENETUNREACH;

    // 调用表特定查找
    return table->tb_lookup(table, flp, res);
}

4.2 fib_table_lookup()

c
// net/ipv4/fib_trie.c:400
static int fib_table_lookup(struct fib_table *tb,
                           struct flowi4 *flp,
                           struct fib_result *res)
{
    struct key_vector *n, *pn;
    struct trie *t = (struct trie *)tb->tb_data;

    // 从根节点开始
    n = rcu_dereference(t->trie);

    // 按位遍历
    while (n) {
        int bit = key_extract(n->key, flp->daddr);

        // 精确匹配
        if (tkey_equals(n->key, flp->daddr))
            break;

        // 移动到子节点
        pn = n;
        n = rcu_dereference(n->children[bit]);
    }

    // 返回结果
    return fib_result_assign(res, n);
}

5. 路由优先级

5.1 多路径路由

c
// fib_trie.c:500
static int fib_select_multipath(struct fib_result *res, int w)
{
    struct fib_info *fi = res->fi;
    int n, k;

    // 基于权重选择
    for (n = 0, k = 0; n < fi->fib_nhs; n++) {
        k += fi->fib_nh[n].nh_weight;
        if (k >= w)
            return n;
    }
}

5.2 最短路径优先

c
// 基于协议优先级选择
// 1. RTN_UNICAST (单播)
// 2. RTN_LOCAL (本地)
// 3. RTN_BROADCAST (广播)
// ...

6. FIB 维护

6.1 fib_add()

c
// net/ipv4/fib_semantics.c:300
int fib_add(struct fib_table *table, struct fib_config *cfg)
{
    struct fib_info *fi;

    // 1. 创建 fib_info
    fi = fib_create_info(cfg);

    // 2. 插入 trie
    hlist_del_rcu(&fi->fib_hash);
    insertbia insert_update(&table->tb_gc, fi);

    // 3. 发送变更通知
    fib_notify(FIB_EVENT_ENTRY_ADD, net, ...);
}

6.2 fib_sync_up()

c
// net/ipv4/fib_semantics.c:600
void fib_sync_up(struct net_device *dev)
{
    // 同步设备状态到路由
    struct fib_nh *fib_nh;

    // 更新所有受影响路由的设备
}

基于 VitePress 构建