当前位置:网站首页>策略路由下发
策略路由下发
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的简单运用-where、update、delete、like、union
esp32之arduino配置下载提速
Qt | 鼠标事件和滚轮事件 QMouseEvent、QWheelEvent
Qt | QWidget 的一些总结
H5中的拖放(Drag 和 Drop)
codeforces Linova and Kingdom
高并发 MySQL 性能优化指南,自取
【go-zero】go-zero 框架踩坑指南 Q&A (持续更新中)
Qt | Qt 的项目文件.pro 文件详解
2022 Low Voltage Electrician Exam Questions and Online Mock Exam
Linux系统中mysql数据库的基本管理
祝蔡徐坤生日快乐!
兆骑科创双创服务平台,创业赛事活动,投融资对接平台
CS5210的参数详情资料分享
【无标题】
太帅了!我用炫酷大屏展示爬虫数据!
MySQL 视图(详解)
PAT serie a 1137 final grades
servlet交互过程图详解,servlet的常见问题,创建web项目(一)
【无标题】