summaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_semantics.c
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@gmail.com>2019-03-28 04:53:47 +0100
committerDavid S. Miller <davem@davemloft.net>2019-03-29 18:48:03 +0100
commit331c7a402358de6206232f6aab7aa48ec6c1088a (patch)
treedf3c9ac99ca90245fa32e9f5cd115f665eb2f117 /net/ipv4/fib_semantics.c
parentipv4: Define fib_get_nhs when CONFIG_IP_ROUTE_MULTIPATH is disabled (diff)
downloadlinux-331c7a402358de6206232f6aab7aa48ec6c1088a.tar.xz
linux-331c7a402358de6206232f6aab7aa48ec6c1088a.zip
ipv4: Move IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN to helper
in_dev lookup followed by IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN check is called in several places, some with the rcu lock and others with the rtnl held. Move the check to a helper similar to what IPv6 has. Since the helper can be invoked from either context use rcu_dereference_rtnl to dereference ip_ptr. Signed-off-by: David Ahern <dsahern@gmail.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_semantics.c')
-rw-r--r--net/ipv4/fib_semantics.c31
1 files changed, 7 insertions, 24 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index b5dbbdfd1e49..78631eb255f7 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -558,7 +558,6 @@ static void fib_rebalance(struct fib_info *fi)
{
int total;
int w;
- struct in_device *in_dev;
if (fi->fib_nhs < 2)
return;
@@ -568,10 +567,7 @@ static void fib_rebalance(struct fib_info *fi)
if (nh->nh_flags & RTNH_F_DEAD)
continue;
- in_dev = __in_dev_get_rtnl(nh->nh_dev);
-
- if (in_dev &&
- IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) &&
+ if (ip_ignore_linkdown(nh->nh_dev) &&
nh->nh_flags & RTNH_F_LINKDOWN)
continue;
@@ -582,12 +578,9 @@ static void fib_rebalance(struct fib_info *fi)
change_nexthops(fi) {
int upper_bound;
- in_dev = __in_dev_get_rtnl(nexthop_nh->nh_dev);
-
if (nexthop_nh->nh_flags & RTNH_F_DEAD) {
upper_bound = -1;
- } else if (in_dev &&
- IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) &&
+ } else if (ip_ignore_linkdown(nexthop_nh->nh_dev) &&
nexthop_nh->nh_flags & RTNH_F_LINKDOWN) {
upper_bound = -1;
} else {
@@ -1325,12 +1318,8 @@ 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) {
- 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))
+ if (ip_ignore_linkdown(fi->fib_nh->nh_dev))
rtm->rtm_flags |= RTNH_F_DEAD;
rcu_read_unlock();
}
@@ -1361,12 +1350,8 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
rtnh->rtnh_flags = nh->nh_flags & 0xFF;
if (nh->nh_flags & RTNH_F_LINKDOWN) {
- 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))
+ if (ip_ignore_linkdown(nh->nh_dev))
rtnh->rtnh_flags |= RTNH_F_DEAD;
rcu_read_unlock();
}
@@ -1433,7 +1418,7 @@ int fib_sync_down_addr(struct net_device *dev, __be32 local)
static int call_fib_nh_notifiers(struct fib_nh *fib_nh,
enum fib_event_type event_type)
{
- struct in_device *in_dev = __in_dev_get_rtnl(fib_nh->nh_dev);
+ bool ignore_link_down = ip_ignore_linkdown(fib_nh->nh_dev);
struct fib_nh_notifier_info info = {
.fib_nh = fib_nh,
};
@@ -1442,14 +1427,12 @@ static int call_fib_nh_notifiers(struct fib_nh *fib_nh,
case FIB_EVENT_NH_ADD:
if (fib_nh->nh_flags & RTNH_F_DEAD)
break;
- if (IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) &&
- fib_nh->nh_flags & RTNH_F_LINKDOWN)
+ if (ignore_link_down && fib_nh->nh_flags & RTNH_F_LINKDOWN)
break;
return call_fib4_notifiers(dev_net(fib_nh->nh_dev), event_type,
&info.info);
case FIB_EVENT_NH_DEL:
- if ((in_dev && IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) &&
- fib_nh->nh_flags & RTNH_F_LINKDOWN) ||
+ if ((ignore_link_down && fib_nh->nh_flags & RTNH_F_LINKDOWN) ||
(fib_nh->nh_flags & RTNH_F_DEAD))
return call_fib4_notifiers(dev_net(fib_nh->nh_dev),
event_type, &info.info);