在策略路由的初始化過程中,它只監聽了網絡設備狀態變化事件,用於當網絡設備狀態發生變化時,能夠更新策略路由規則中網絡接口相關的信息,這篇筆記就來看看這個過程是如何處理的。
源代碼路徑 | 說明 |
---|---|
net/core/fib_rules.c | 策略路由非協議相關實現 |
1. 初始化
初始化fib_rules_init()中向網絡設備接口層註冊了事件回調:
static struct notifier_block fib_rules_notifier = {
.notifier_call = fib_rules_event,
};
static int __init fib_rules_init(void)
{
...
//項netdevice通知鏈註冊一個回調,當網絡設備狀態變化時,做一些響應的處理,類似於路由數據庫
err = register_netdevice_notifier(&fib_rules_notifier);
if (err < 0)
goto fail;
...
}
2. 網卡狀態變化回調: fib_rules_event()
static int fib_rules_event(struct notifier_block *this, unsigned long event,
void *ptr)
{
struct net_device *dev = ptr;
struct net *net = dev->nd_net;
struct fib_rules_ops *ops;
ASSERT_RTNL();
rcu_read_lock();
//監聽了網卡的註冊和去註冊兩個事件,當事件發生時,分別對每個協議族的策略路由規則列表
//調用attach_rules()和detach_rules()進行處理
switch (event) {
case NETDEV_REGISTER:
list_for_each_entry(ops, &net->rules_ops, list)
attach_rules(&ops->rules_list, dev);
break;
case NETDEV_UNREGISTER:
list_for_each_entry(ops, &net->rules_ops, list)
detach_rules(&ops->rules_list, dev);
break;
}
rcu_read_unlock();
return NOTIFY_DONE;
}
2.1 網卡註冊事件處理: attach_rules()
//入參已經是某個協議族的策略路由規則鏈表了
static void attach_rules(struct list_head *rules, struct net_device *dev)
{
struct fib_rule *rule;
//遍歷策略路由規則列表,如果指定規則的網卡名字和註冊網絡設備匹配,但是其網卡ID爲-1(表示無效),
//那麼激活該網卡索引
list_for_each_entry(rule, rules, list) {
if (rule->ifindex == -1 && strcmp(dev->name, rule->ifname) == 0)
rule->ifindex = dev->ifindex;
}
}
2.2 網卡去註冊事件處理: detach_rules()
static void detach_rules(struct list_head *rules, struct net_device *dev)
{
struct fib_rule *rule;
//將策略路由規則中網卡和當前網絡設備匹配的規則的索引設置爲-1,這將禁用該規則
list_for_each_entry(rule, rules, list)
if (rule->ifindex == dev->ifindex)
rule->ifindex = -1;
}