linux内核 策略路由之查找

来源:互联网 发布:淘宝不能好评返现了 编辑:程序博客网 时间:2024/05/17 10:05
4.4.1 策略路由查找
       策略规则的查找函数fib_rules_lookup

功能:

      (1)遍历rules_list链表;

      (2)调用fib_rule_match进行规则匹配
      (3)调用函数指针action,进行路由表项的查找;
      (4)将arg->rule指向该规则的首地址。
//通用规则的查找//ops 传入//arg 返回查找结果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) //遍历ops->rules_list的所有fib_rule节点    {        DEBUG_V4Route("\n%s-->table:%u ifindex:%d mark:0x%x mark_mask:0x%x  flags:0x%x\n",__FUNCTION__,\                rule->table,rule->ifindex,rule->mark,rule->mark_mask,rule->flags);jumped:        if (!fib_rule_match(rule, ops, fl, flags))//规则匹配            continue;                if (rule->action == FR_ACT_GOTO) {            struct fib_rule *target;            target = rcu_dereference(rule->ctarget);            if (target == NULL) {                continue;            } else {                rule = target;                goto jumped;            }        } else if (rule->action == FR_ACT_NOP)            continue;        else            err = ops->action(rule, fl, flags, arg);//fib4_rule_action 查找对应的路由表项        if (err != -EAGAIN) {            fib_rule_get(rule);            arg->rule = rule;//arg->rule赋值            goto out;        }    }    err = -ESRCH;out:    rcu_read_unlock();    return err;}

4.4.2 通用规则的匹配

功能:

      (1)对接口index、mark等匹配;

      (2)调用协议相关的match进行匹配。
static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,              struct flowi *fl, int flags){    int ret = 0;    //对于传入的fib_rule变量与传入的路由查找键值flowi变量比较    if (rule->ifindex && (rule->ifindex != fl->iif))//判断输入接口index是否相等        goto out;    if ((rule->mark ^ fl->mark) & rule->mark_mask)//mark是否相等        goto out;    ret = ops->match(rule, fl, flags);//协议规则的匹配,ipv4调用fib4_rule_match        DEBUG_V4Route("%s-->rule->flags:0x%x ret:%d\n",__FUNCTION__,rule->flags,ret);out:    return (rule->flags & FIB_RULE_INVERT) ? !ret : ret;//若fib_rule的规则是取反,则返回结果也取反}

4.4.2.1 协议相关规则的匹配

功能

      对源ip地址、目的ip地址以及tos的匹配操作

//ipv4协议相关的匹配//对源IP、目的IP、tos进行比较,相等返回1,不等返回0static 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;    //比较规则fib_rule 与 传入路由参数flowi 的值是否相等    if (((saddr ^ r->src) & r->srcmask) ||        ((daddr ^ r->dst) & r->dstmask))//源IP、目的IP是否相等        return 0;    if (r->tos && (r->tos != fl->fl4_tos))//tos是否相等        return 0;    return 1;}

4.4.3 查路由表项

功能:

      (1)获取到相应的路由表;

      (2)查找符合要求的路由项
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://策略规则并且与路由表ID相关联        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;    }        DEBUG_V4Route("%s-->table:%u\n",__FUNCTION__,rule->table);    if ((tbl = fib_get_table(rule->fr_net, rule->table)) == NULL)//根据id值,获取相应的路由表        goto errout;    err = tbl->tb_lookup(tbl, flp, (struct fib_result *) arg->result);//对应ipv4的查找函数fn_hash_lookup    if (err > 0)        err = -EAGAIN;errout:    return err;}


0 0