linux 路由查找原则,Linux 路由 学习笔记 之七 策略规则的查找

上面分析了策略规则的添加,本文分析一下策略规则的查找。其实策略规则的存在就是为了实现策略路由功能的,而在策略路由的查找一节已经分析了策略规则的查找了,但为了在这一节单独分析策略规则,此处也一并再分析一下。

对于策略规则的功能模块来说,其查找函数是始于通用策略规则模块的fib_rules_lookup。

1 通用规则的查找函数

1.1 fib_rules_lookup

这个函数的功能是策略路由对应的路由查找函数

1.遍历传入的ops变量的rules_list链表,对于每一个fib_rule

a)调用fib_rule_match进行fib_rule规则匹配

i)当规则匹配后,则调用传入的ops变量的函数指针action进行

路由项的查找(对于ipv4,fib4_rules_ops->action即为fib4_rule_action),当路由

查找到后,则会调用fib_rule_get增加对匹配规则的引用计数,并

将arg->rule指向该规则的首地址

在fib_rule_match中,在完成了通用参数的match后,会调用协议相关的match函数,

对协议相关的参数进行match。而对于ipv4的match函数即为fib4_rule_match。

在match到相应的fib rule后,即会调用协议相关的action函数,进行action操作,对于ipv4而言,即是fib4_rule_action。

fib_rule的action有FR_ACT_TO_TBL、FR_ACT_BLACKHOLE等,而我们使用fib rule主要是进行策略路由的,

因此,其action一般都是 FR_ACT_TO_TBL。基于策略路由的功能,我们 可以猜测fib4_rule_action函数

主要是根据table id找到相应的路由表,然后再调用路由表的查找函数,根据传入的条件,

查找符合要求的路由,我们接着来分析一下fib4_rule_action是否与我们猜测的一样。

int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,

int flags, struct fib_lookup_arg *arg)

{

struct fib_rule *rule;

int err;

rcu_read_lock();

list_for_each_entry_rcu(rule, ops->rules_list, list) {

if (!fib_rule_match(rule, ops, fl, flags))

continue;

err = ops->action(rule, fl, flags, arg);

if (err != -EAGAIN) {

fib_rule_get(rule);

arg->rule = rule;

goto out;

}

}

err = -ESRCH;

out:

rcu_read_unlock();

return err;

}

上面函数在查找时,调用了通用规则的匹配函数,那下面我们就分析通用规则的匹配函数

1.2 通用规则的匹配

1.2.1 fib_rule_match

对于这个功能,是通过函数fib_rule_match实现的(其实该函数通过调用协议相关的match函数也完成了协议相关的参数的匹配,此处这样说有些不妥),下面分析这个函数

fib_rule_match函数首先会进行通用参数的match,主要是包括接口index、fwmark等match。接着才会调用协议相关的match函数,对协议相关的参数进行match操作。

这个函数完成的功能如下:

对于传入的struct fib_rule *结构的指针rule,与传入的路由查找相关的struct flowi *

结构的指针fl

1.判断输入接口的index是否相等

2.判断mark值是否相等

3.调用函数ops->match继续进行fib_rule规则的匹配,对于ipv4,即为函数fib4_rule_match

4.如果fib_rule的规则是取反时,则返回的结果也需要进行取反操作

(不过目前通过ip rule添加的规则是不允许使用取反的,所以第四个判断操作目前

来说均是返回ret)

*/

static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,

struct flowi *fl, int flags)

{

int ret = 0;

if (rule->ifindex && (rule->ifindex != fl->iif))

goto out;

if ((rule->mark ^ fl->mark) & rule->mark_mask)

goto out;

/*对于ipv4协议,其match函数为fib4_rule_match*/

ret = ops->match(rule, fl, flags);

out:

return (rule->flags & FIB_RULE_INVERT) ? !ret : ret;

}

1.3 协议相关的策略规则的匹配

上面函数的通用规则的匹配函数里,调用了协议相关的策略规则匹配函数,下面我们就分析下ipv4协议相关的策略规则的匹配

对于ipv4,其协议相关的match函数为fib4_rule_match函数,我们分析一下这个函数。

这个函数主要是对源ip地址、目的ip地址以及tos的匹配操作。

(fib rule的添加类似于如下命令:

# ip rule add fwmark 0x4/0x40004 from  192.168.1.1/32 to 192.168.33.9/24 tos 10

iif br0 table 231)

static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)

{

struct fib4_rule *r = (struct fib4_rule *) rule;

__be32 daddr = fl->fl4_dst;

__be32 saddr = fl->fl4_src;

if (((saddr ^ r->src) & r->srcmask) ||

((daddr ^ r->dst) & r->dstmask))

return 0;

if (r->tos && (r->tos != fl->fl4_tos))

return 0;

return 1;

}

在通用规则的查找函数里,当规则匹配成功后,就会调用协议相关的action函数,下面我们就分析一下这个函数。

1.4 协议相关的action

在分析v4协议相关的策略规则ops的action操作之前,我们先看下的策略规则的action类型有哪些

/*fib rule的action类型,FR_ACT_TO_TBL即该fib rule与路由表关联*/

enum

{

FR_ACT_UNSPEC,

FR_ACT_TO_TBL, /* Pass to fixed table */

FR_ACT_RES1,

FR_ACT_RES2,

FR_ACT_RES3,

FR_ACT_RES4,

FR_ACT_BLACKHOLE, /* Drop without notification */

FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */

FR_ACT_PROHIBIT, /* Drop with EACCES */

__FR_ACT_MAX,

};

当我们建立一个策略规则,且与路由表的id关联时,即是选择了action FR_ACT_TO_TBL,对于策略路由来说,肯定是这个action的。

下面分析下v4的action函数fib4_rule_action

1.根据rule的action规则决定后续操作,对于支持策略路由而言,我们建立fib rule的

action均是FR_ACT_TO_TBL,而对于FR_ACT_UNREACHABLE、

FR_ACT_PROHIBIT、FR_ACT_BLACKHOLE等均是返回相应的失败码。而对于 FR_ACT_TO_TBL,则需要进一步进行路由项的查找

2.对于FR_ACT_TO_TBL,则根据fib_rule->table的table id值,调用函数fib_get_table 获取相应的路由表,接着就是调用路由表的查找路由函数tb_lookup进行路由项的 查找,对于ipv4其路由表的tb_lookup即为函数fn_hash_lookup

static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp,

int flags, struct fib_lookup_arg *arg)

{

int err = -EAGAIN;

struct fib_table *tbl;

switch (rule->action) {

case FR_ACT_TO_TBL:

break;

case FR_ACT_UNREACHABLE:

err = -ENETUNREACH;

goto errout;

case FR_ACT_PROHIBIT:

err = -EACCES;

goto errout;

case FR_ACT_BLACKHOLE:

default:

err = -EINVAL;

goto errout;

}

if ((tbl = fib_get_table(rule->table)) == NULL)

goto errout;

err = tbl->tb_lookup(tbl, flp, (struct fib_result *) arg->result);

if (err > 0)

err = -EAGAIN;

errout:

return err;

}

这个函数会根据策略规则绑定的路由表id,通过函数fib_get_table找到相应的路由表,然后再根据路由表的tb_lookup函数进行路由项的匹配操作。而对于路由的查找,我们在上面已经分析过了,此处不再赘述。

至此,分析完了策略规则的匹配。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值