遇到一個路由轉發問題,如下路由表,在ens40網卡鏈路斷開的時候,目的地址爲192.168.3.0/24網段的報文,還是走ens40網卡,而不是默認路由,導致報文被丟棄。
$ ip route
default via 192.168.9.1 dev ens39
192.168.3.0/24 dev ens40 proto kernel scope link src 192.168.3.248
192.168.9.0/24 dev ens39 proto kernel scope link src 192.168.9.10
如下,雖然ens40的直連路由被設置了linkdown標誌,但是在路由查找中依然生效。
$ ip route
default via 192.168.9.1 dev ens39
192.168.3.0/24 dev ens40 proto kernel scope link src 192.168.3.248 linkdown
192.168.9.0/24 dev ens39 proto kernel scope link src 192.168.9.10
查看內核路由查找函數fib_table_lookup,發現即使設置了RTNH_F_LINKDOWN標誌的路由項,如果沒有設置IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN,內核還是會使用的。
int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
struct fib_result *res, int fib_flags)
{
/* Step 3: Process the leaf, if that fails fall back to backtracing */
hlist_for_each_entry_rcu(fa, &n->leaf, fa_list) {
struct fib_info *fi = fa->fa_info;
...
if (fi->fib_flags & RTNH_F_DEAD)
continue;
for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) {
const struct fib_nh *nh = &fi->fib_nh[nhsel];
struct in_device *in_dev = __in_dev_get_rcu(nh->nh_dev);
if (nh->nh_flags & RTNH_F_DEAD)
continue;
if (in_dev &&
IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) &&
nh->nh_flags & RTNH_F_LINKDOWN &&
!(fib_flags & FIB_LOOKUP_IGNORE_LINKSTATE))
continue;
如下,網絡設備ens40的PROC文件ignore_routes_with_linkdown值爲零,隨後將其設置爲1,恢復正常,報文由默認路由發出。
$ cat /proc/sys/net/ipv4/conf/ens40/ignore_routes_with_linkdown
0