|
@@ -1365,8 +1365,6 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
|
|
|
nla_put_in_addr(skb, RTA_PREFSRC, fi->fib_prefsrc))
|
|
|
goto nla_put_failure;
|
|
|
if (fi->fib_nhs == 1) {
|
|
|
- struct in_device *in_dev;
|
|
|
-
|
|
|
if (fi->fib_nh->nh_gw &&
|
|
|
nla_put_in_addr(skb, RTA_GATEWAY, fi->fib_nh->nh_gw))
|
|
|
goto nla_put_failure;
|
|
@@ -1374,10 +1372,14 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
|
|
|
nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif))
|
|
|
goto nla_put_failure;
|
|
|
if (fi->fib_nh->nh_flags & RTNH_F_LINKDOWN) {
|
|
|
- in_dev = __in_dev_get_rtnl(fi->fib_nh->nh_dev);
|
|
|
+ struct in_device *in_dev;
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+ in_dev = __in_dev_get_rcu(fi->fib_nh->nh_dev);
|
|
|
if (in_dev &&
|
|
|
IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev))
|
|
|
rtm->rtm_flags |= RTNH_F_DEAD;
|
|
|
+ rcu_read_unlock();
|
|
|
}
|
|
|
if (fi->fib_nh->nh_flags & RTNH_F_OFFLOAD)
|
|
|
rtm->rtm_flags |= RTNH_F_OFFLOAD;
|
|
@@ -1400,18 +1402,20 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
for_nexthops(fi) {
|
|
|
- struct in_device *in_dev;
|
|
|
-
|
|
|
rtnh = nla_reserve_nohdr(skb, sizeof(*rtnh));
|
|
|
if (!rtnh)
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
rtnh->rtnh_flags = nh->nh_flags & 0xFF;
|
|
|
if (nh->nh_flags & RTNH_F_LINKDOWN) {
|
|
|
- in_dev = __in_dev_get_rtnl(nh->nh_dev);
|
|
|
+ struct in_device *in_dev;
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+ in_dev = __in_dev_get_rcu(nh->nh_dev);
|
|
|
if (in_dev &&
|
|
|
IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev))
|
|
|
rtnh->rtnh_flags |= RTNH_F_DEAD;
|
|
|
+ rcu_read_unlock();
|
|
|
}
|
|
|
rtnh->rtnh_hops = nh->nh_weight - 1;
|
|
|
rtnh->rtnh_ifindex = nh->nh_oif;
|