当前位置:网站首页>策略路由下发
策略路由下发
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
边栏推荐
猜你喜欢
随机推荐
MySQL 高级(进阶) SQL 语句 (一)
2022 Security Officer-A Certificate Exam Questions and Mock Exam
codeforces k-Tree (dp仍然不会耶)
8大软件供应链攻击事件概述
vim的高级用法配置
PAT甲级 1019 普通回文数
MySQL查询
MySQL (2)
QT基础第四天(4)qt事件机制:事件基础概念,常见事件机制,事件处理以及事件的重写
Traverse Heap PAT Class A 1155 Heap Path
BSC链智能合约模式系统开发功能逻辑分析
OneFlow源码解析:Op、Kernel与解释器
【Untitled】
PAT甲级 1130 中缀表达式
2022年低压电工考试试题及在线模拟考试
Qt | 关于如何使用事件过滤器 eventFilter
软件成分分析:华为云重磅发布开源软件治理服务
剑指Offer 49.丑数 动态规划
机械键盘失灵
【深度学习】关于处理过拟合的一点心得