linux核心 策略路由之新增

2021-07-16 22:27:59 字數 4001 閱讀 8262

4.3策略規則的新增

對於策略規則的新增,也可以抽象出通用規則介面函式,然後根據傳參進入協議相關的策略規則的介面函式;

4.3.1 通用規則的新增

在規則初始化時,會註冊新增函式fib_nl_newrule

rtnl_register(pf_unspec, rtm_newrule, fib_nl_newrule, null);

接下來,分析建立規則fib_nl_newrule函式

功能:(1)根據應用層傳遞的協議型別,找到相應的fib_rules_ops變數;

(2)解析應用層傳入的資料;

(3)針對源ip和目的ip,有效性檢查

(4)分配新的fib_rule快取,並對優先順序、介面index、介面名稱、mark值、action等賦值;

(5)呼叫協議對應的configure函式,對fib_rule的源ip、目的ip、掩碼、tos進行配置;

(6)將fib_rule新增到rule_lists中,並通過netlink通知其他程序。

static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)

//解析應用層傳入的資料nlh,放入tb中。

err = nlmsg_parse(nlh, sizeof(*frh), tb, fra_max, ops->policy);

if (err < 0)

goto errout;

//有效性檢查,針對源ip和目的ip

err = validate_rulemsg(frh, tb, ops);

if (err < 0)

goto errout;

//分配新的fib_rule快取

rule = kzalloc(ops->rule_size, gfp_kernel);

if (rule == null)

rule->fr_net = hold_net(net);//增加rule->net的引用計數

if (tb[fra_priority])

rule->pref = nla_get_u32(tb[fra_priority]);//設定優先順序

if (tb[fra_ifname])

if (tb[fra_fwmark])

if (tb[fra_fwmask])

rule->mark_mask = nla_get_u32(tb[fra_fwmask]);//mark掩碼值

//設定規則action,table id,實現規則與路由表的關聯

rule->action = frh->action;

rule->flags = frh->flags;

rule->table = frh_get_table(frh, tb);

//獲取預設優先順序為除0外的最高優先順序 ??怎麼理解

if (!rule->pref && ops->default_pref)

rule->pref = ops->default_pref(ops);

err = -einval;

if (tb[fra_goto])

}if (rule->ctarget == null)

unresolved = 1;

} else if (rule->action == fr_act_goto)

goto errout_free;

//呼叫協議對應的configure函式,這裡就是協議相關的新增

err = ops->configure(rule, skb, frh, tb);

if (err < 0)

goto errout_free;

//找到第乙個pref比新建立的fib_rule的pref值大的 fib_rule

//然後將新建立的fib_rule添到該規則之前

//若沒有找到,則新增到已有規則鍊錶之後

list_for_each_entry(r, &ops->rules_list, list)

fib_rule_get(rule);//增加fib_rule的引用計數

if (ops->unresolved_rules) }}

if (rule->action == fr_act_goto)

ops->nr_goto_rules++;

if (unresolved)

ops->unresolved_rules++;

//根據優先順序,將fib_rule添到rules_list鍊錶中

if (last)

list_add_rcu(&rule->list, &last->list);

else

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

//通過netlink通知其他程序

notify_rule_change(rtm_newrule, rule, ops, nlh, netlink_cb(skb).pid);

flush_route_cache(ops);//重新整理路由快取

rules_ops_put(ops);//將乙個特定模組module的引用計數減1

return 0;

errout_free:

release_net(rule->fr_net);//減少rule->net的引用計數

kfree(rule);

errout:

rules_ops_put(ops);

return err;

}

4.3.1.1 查詢fib_rule對應的ops

功能

根據協議簇 在鍊錶rules_ops中查詢符合要求的fib_rules_ops型別的變數;

對於ipv4,變數為fib4_rules_ops。

static struct fib_rules_ops *lookup_rules_ops(struct net *net, int family)

}rcu_read_unlock();

return null;

}

4.3.2 協議相關規則的配置

此處以ipv4協議型別為例,

功能:

ipv4的配置函式,根據應用層傳參,設定fib4_rule變數引數:源ip、目的ip、掩碼、路由表id、tos;

static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,

struct fib_rule_hdr *frh,

struct nlattr **tb)// tb 新增策略規則的可選屬性

rule->table = table->tb_id;}}

if (frh->src_len)

rule4->src = nla_get_be32(tb[fra_src]);

if (frh->dst_len)

rule4->dst = nla_get_be32(tb[fra_dst]);

#ifdef config_net_cls_route

if (tb[fra_flow])

rule4->tclassid = nla_get_u32(tb[fra_flow]);

#endif

rule4->src_len = frh->src_len;

rule4->srcmask = inet_make_mask(rule4->src_len);

rule4->dst_len = frh->dst_len;

rule4->dstmask = inet_make_mask(rule4->dst_len);

rule4->tos = frh->tos;

err = 0;

errout:

return err;

}

linux核心 策略路由之基本結構

四 linux策略規則 4.1 基本結構體 4.1.1策略規則結構體fib rule struct fib rule action各巨集含義 enum 4.1.2 策略操作函式fib rules ops 策略規則中協議相關的操作函式結構體fib rules ops struct fib rules ...

Linux 路由 策略路由

目錄二 ip策略 刪除ip策略規則 三 永久生效,寫入配置檔案 etc sysconfig network scripts rule ethx 注意 本文中使用 隔開的命令等價 從linux 2.2開始,核心把路由歸納到許多路由表中,這些表都進行了編號,編號數字的範圍是1到255。可以在路由表配置檔...

Linux策略路由

前面講的路由規則都是基於目標ip位址為匹配依據設定的路由規則,策略路由則更加靈活,它可以根據多個引數來配置路由。假設如下的使用場景 在192.168.10.0子網中,除了主機192.168.10.123要訪問網際網路時是通過電信運營商 192.168.20.0 24 之外,其他主機都使用移動運營商 ...