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 之外,其他主機都使用移動運營商 ...