当前位置:网站首页>策略路由下发

策略路由下发

2022-08-02 14:55:00 redwingz

在文件iproute2-5.12.0/ip/iprule.c中,策略路由指定的路由表ID,有两种下发方式。在路由器ID小于256时,使用fib_rule_hdr结构成员table下发;在大于等于256时,使用netlink消息的属性FRA_TABLE下发,此时将fib_rule_hdr结构成员table的值设置为RT_TABLE_UNSPEC。

static int iprule_modify(int cmd, int argc, char **argv)
{
    __u32 tid = 0;
    struct {
        struct nlmsghdr n;
        struct fib_rule_hdr frh;
        char            buf[1024];
    } req

    while (argc > 0) {
        } else if (matches(*argv, "table") == 0 ||
               strcmp(*argv, "lookup") == 0) {
            NEXT_ARG();
            if (rtnl_rttable_a2n(&tid, *argv))
                invarg("invalid table ID\n", *argv);
            if (tid < 256)
                req.frh.table = tid;
            else {
                req.frh.table = RT_TABLE_UNSPEC;
                addattr32(&req.n, sizeof(req), FRA_TABLE, tid);
            }

路由表数量

如下,路由表数量为U32表示的最大值。

enum rt_class_t {
    RT_TABLE_UNSPEC=0,
/* User defined values */
    RT_TABLE_COMPAT=252,
    RT_TABLE_DEFAULT=253,
    RT_TABLE_MAIN=254,
    RT_TABLE_LOCAL=255,
    RT_TABLE_MAX=0xFFFFFFFF
};

如下iproute2-5.12.0/ip/iproute.c文件中代码,在添加路由时,如果指定的路由表ID小于256,使用rtmsg中的成员rtm_table(u8类型变量)下发;否则,大于256,使用netlink属性RTA_TABLE进行内核下发,此时需要将rtm_table设置为RT_TABLE_UNSPEC。

static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv)
{
    struct {
        struct nlmsghdr n;
        struct rtmsg        r;
        char            buf[4096];
    } req

    while (argc > 0) {
        } else if (matches(*argv, "table") == 0) {
            __u32 tid;

            NEXT_ARG();
            if (rtnl_rttable_a2n(&tid, *argv))
                invarg("\"table\" value is invalid\n", *argv);
            if (tid < 256)
                req.r.rtm_table = tid;
            else {
                req.r.rtm_table = RT_TABLE_UNSPEC;
                addattr32(&req.n, sizeof(req), RTA_TABLE, tid);
            }

规则优先级

初始化时,默认的三个路由表local,main,default的优先级分别指定为0,0x7ffe和0x7fff。

static int fib_default_rules_init(struct fib_rules_ops *ops)
{
    int err;

    err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, 0);
    if (err < 0)
        return err;
    err = fib_default_rule_add(ops, 0x7FFE, RT_TABLE_MAIN, 0);
    if (err < 0)
        return err;
    err = fib_default_rule_add(ops, 0x7FFF, RT_TABLE_DEFAULT, 0);
    if (err < 0)
        return err;
    return 0;

如下默认的路由规则表,优先级数值越小,优先级越高。

/ # ip rule
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

之后添加的路由规则,如果没有显示指定优先级,将使用第一个非零的优先级数值递减一,作为新规则的优先级。

static u32 fib_default_rule_pref(struct fib_rules_ops *ops)
{
    struct list_head *pos;
    struct fib_rule *rule;

    if (!list_empty(&ops->rules_list)) {
        pos = ops->rules_list.next;
        if (pos->next != &ops->rules_list) {
            rule = list_entry(pos->next, struct fib_rule, list);
            if (rule->pref)
                return rule->pref - 1;
        }
    }
    return 0;

如下,添加优先级为1的规则,之后添加另外一条不指定优先级的规则,其优先级系统指定为零。

# ip rule add pref 1 from 11.0.1.3 lookup 9
# ip rule add from 12.0.1.3 lookup 9 
#
# ip rule show
0:      from all lookup local
0:      from 12.0.1.3 lookup 9
1:      from 11.0.1.3 lookup 9
32766:  from all lookup main
32767:  from all lookup default

之后,再添加的路由规则优先级都为0,但是注意,此时添加的规则都添加到了优先级为1的规则之前。

# ip rule add from 15.0.1.3 lookup 30 
# ip rule add from 16.0.1.3 lookup 50 
# 
# ip rule show
0:      from all lookup local
0:      from 12.0.1.3 lookup 9
0:      from 15.0.1.3 lookup 30
0:      from 16.0.1.3 lookup 50
1:      from 11.0.1.3 lookup 9
32766:  from all lookup main
32767:  from all lookup default

如下,新路由规则添加在优先级值大于其值的规则之前。路由规则优先级的范围为:[0, 32767]。

int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
           struct netlink_ext_ack *extack)
{

    list_for_each_entry(r, &ops->rules_list, list) {
        if (r->pref > rule->pref)
            break;
        last = r;
    }

    if (last)
        list_add_rcu(&rule->list, &last->list);
    else
        list_add_rcu(&rule->list, &ops->rules_list);

内核版本 5.10

原网站

版权声明
本文为[redwingz]所创,转载请带上原文链接,感谢
https://redwingz.blog.csdn.net/article/details/126079186