路由策略

路由策略处理相关的内核代码集中在的net/ipv4/fib_rules.c和net/core/fib_rules.c两个文件内。


路由策略的配置

独立的ip rule策略配置,可指定源地址、目的地址、入接口、出接口等,或者与iptables配合使用的策略rule。

ip rule add from 192.168.1.123 table 5
ip rule add to   192.168.1.1       table 5
ip rule add dev  eth1                table 5 
ip rule add tos  8                      table 5
ip rule add not from 192.168.100.100 table 5

iptables -t mangle -A FORWARD -i eth0 -p tcp --dport 23 -j MARK --set-mark 23   

ip rule add fwmark 23 table 5 


路由策略查找入口

在路由查找函数fib_lookup中,首先判断用户是否配置了路由策略(fib_has_custom_rules),如果为真进行路由策略查找(__fib_lookup),其最终调用函数fib_rules_lookup进行处理,内核将路由策略相关操作结构保存在了对应的网络命名空间成员(net->ipv4.rules_ops)内。rules_ops结构中的rules_list链表保存了内核配置的所有路由策略。

int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res)
{
    err = fib_rules_lookup(net->ipv4.rules_ops, flowi4_to_flowi(flp), 0, &arg);
}
static inline int fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res)
{
    if (net->ipv4.fib_has_custom_rules)
        return __fib_lookup(net, flp, res);
}


路由策略查找


函数fib_rule_lookup的查找过程,既是遍历rules_list链表,匹配其中的策略项,执行所定义的操作的过程。匹配过程由fib_rule_match函数完成,匹配需要满足以下条件:

1)如指定入接口,数据包的入接口必须和策略rule中指定的入接口相同;
2)如指定出接口,二者的出接口必须相同;
3)如指定流标记,二者的流标记必须相同;
4)如指定隧道ID,二者的隧道ID必须相同;

另外,针对IPv4协议:
5)策略rule中指定的源IP地址与数据包的源IP地址,与掩码进行位与操作,结果必须相同;
5)策略rule中指定的目的IP地址与数据包的目的IP地址,与掩码进行位与操作,结果必须相同;
7)如指定TOS值,二者的TOS值必须相同;

fib_rule_match函数在匹配是还可判断是否要取反操作,如前述的ip rule add not策略。

int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, int flags, struct fib_lookup_arg *arg)
{
    struct fib_rule *rule;

    list_for_each_entry_rcu(rule, &ops->rules_list, list) {
jumped:
        if (!fib_rule_match(rule, ops, fl, flags))
            continue;

        if (rule->action == FR_ACT_GOTO) {
        }
        else
            err = ops->action(rule, fl, flags, arg);
    }
}


路由策略执行

如前所述,策略路由主要的执行方向是控制匹配的数据流去查询策略中指定的路由表,在代码即FR_ACT_TO_TBL;其它的操作不累述。

static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp, int flags, struct fib_lookup_arg *arg)
{
    switch (rule->action) {
    case FR_ACT_TO_TBL:
        break;
    }
    tbl = fib_get_table(rule->fr_net, rule->table);
    if (tbl)
        err = fib_table_lookup(tbl, &flp->u.ip4, (struct fib_result *)arg->result, arg->flags);
}


内核版本

linux-3.10.0


阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_20184565/article/details/80354843
文章标签: 路由策略
个人分类: 路由
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

路由策略

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭