net: ipv4: refactor __ip_route_output_key_hash
authorDavid Ahern <dsahern@gmail.com>
Thu, 25 May 2017 17:42:33 +0000 (10:42 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 May 2017 18:12:49 +0000 (14:12 -0400)
A later patch wants access to the fib result on an output route lookup
with the rcu lock held. Refactor __ip_route_output_key_hash, pushing
the logic between rcu_read_lock ... rcu_read_unlock into a new helper
with the fib_result as an input arg.

To keep the name length under control remove the leading underscores
from the name and add _rcu to the name of the new helper indicating it
is called with the rcu read lock held.

Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/route.h
net/ipv4/icmp.c
net/ipv4/route.c

index 2cc0e14c63598ce3d3be88bb04d2fd433d676129..89e4028cd06379e19f4212ab6489d048f08a0c3b 100644 (file)
@@ -113,13 +113,16 @@ struct in_device;
 int ip_rt_init(void);
 void rt_cache_flush(struct net *net);
 void rt_flush_dev(struct net_device *dev);
-struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *flp,
-                                         const struct sk_buff *skb);
+struct rtable *ip_route_output_key_hash(struct net *net, struct flowi4 *flp,
+                                       const struct sk_buff *skb);
+struct rtable *ip_route_output_key_hash_rcu(struct net *net, struct flowi4 *flp,
+                                           struct fib_result *res,
+                                           const struct sk_buff *skb);
 
 static inline struct rtable *__ip_route_output_key(struct net *net,
                                                   struct flowi4 *flp)
 {
-       return __ip_route_output_key_hash(net, flp, NULL);
+       return ip_route_output_key_hash(net, flp, NULL);
 }
 
 struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
index 43318b5f56474bc15253e74e156962dd2c8df01f..5610971bf8599b7c4e23870a1d3b890e0fde66b1 100644 (file)
@@ -489,7 +489,7 @@ static struct rtable *icmp_route_lookup(struct net *net,
        fl4->flowi4_oif = l3mdev_master_ifindex(skb_dst(skb_in)->dev);
 
        security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4));
-       rt = __ip_route_output_key_hash(net, fl4, skb_in);
+       rt = ip_route_output_key_hash(net, fl4, skb_in);
        if (IS_ERR(rt))
                return rt;
 
index 655d9eebe43e16a59102edcd3ea4bc177c6b341d..c9b55cb0e316039046e17357f6107611be191425 100644 (file)
@@ -2246,29 +2246,40 @@ add:
  * Major route resolver routine.
  */
 
-struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
-                                         const struct sk_buff *skb)
+struct rtable *ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
+                                       const struct sk_buff *skb)
 {
-       struct net_device *dev_out = NULL;
        __u8 tos = RT_FL_TOS(fl4);
-       unsigned int flags = 0;
        struct fib_result res;
        struct rtable *rth;
-       int orig_oif;
-       int err = -ENETUNREACH;
 
        res.tclassid    = 0;
        res.fi          = NULL;
        res.table       = NULL;
 
-       orig_oif = fl4->flowi4_oif;
-
        fl4->flowi4_iif = LOOPBACK_IFINDEX;
        fl4->flowi4_tos = tos & IPTOS_RT_MASK;
        fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
                         RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
 
        rcu_read_lock();
+       rth = ip_route_output_key_hash_rcu(net, fl4, &res, skb);
+       rcu_read_unlock();
+
+       return rth;
+}
+EXPORT_SYMBOL_GPL(ip_route_output_key_hash);
+
+struct rtable *ip_route_output_key_hash_rcu(struct net *net, struct flowi4 *fl4,
+                                           struct fib_result *res,
+                                           const struct sk_buff *skb)
+{
+       struct net_device *dev_out = NULL;
+       int orig_oif = fl4->flowi4_oif;
+       unsigned int flags = 0;
+       struct rtable *rth;
+       int err = -ENETUNREACH;
+
        if (fl4->saddr) {
                rth = ERR_PTR(-EINVAL);
                if (ipv4_is_multicast(fl4->saddr) ||
@@ -2354,15 +2365,15 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
                        fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK);
                dev_out = net->loopback_dev;
                fl4->flowi4_oif = LOOPBACK_IFINDEX;
-               res.type = RTN_LOCAL;
+               res->type = RTN_LOCAL;
                flags |= RTCF_LOCAL;
                goto make_route;
        }
 
-       err = fib_lookup(net, fl4, &res, 0);
+       err = fib_lookup(net, fl4, res, 0);
        if (err) {
-               res.fi = NULL;
-               res.table = NULL;
+               res->fi = NULL;
+               res->table = NULL;
                if (fl4->flowi4_oif &&
                    (ipv4_is_multicast(fl4->daddr) ||
                    !netif_index_is_l3_master(net, fl4->flowi4_oif))) {
@@ -2387,43 +2398,41 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
                        if (fl4->saddr == 0)
                                fl4->saddr = inet_select_addr(dev_out, 0,
                                                              RT_SCOPE_LINK);
-                       res.type = RTN_UNICAST;
+                       res->type = RTN_UNICAST;
                        goto make_route;
                }
                rth = ERR_PTR(err);
                goto out;
        }
 
-       if (res.type == RTN_LOCAL) {
+       if (res->type == RTN_LOCAL) {
                if (!fl4->saddr) {
-                       if (res.fi->fib_prefsrc)
-                               fl4->saddr = res.fi->fib_prefsrc;
+                       if (res->fi->fib_prefsrc)
+                               fl4->saddr = res->fi->fib_prefsrc;
                        else
                                fl4->saddr = fl4->daddr;
                }
 
                /* L3 master device is the loopback for that domain */
-               dev_out = l3mdev_master_dev_rcu(FIB_RES_DEV(res)) ? :
+               dev_out = l3mdev_master_dev_rcu(FIB_RES_DEV(*res)) ? :
                        net->loopback_dev;
                fl4->flowi4_oif = dev_out->ifindex;
                flags |= RTCF_LOCAL;
                goto make_route;
        }
 
-       fib_select_path(net, &res, fl4, skb);
+       fib_select_path(net, res, fl4, skb);
 
-       dev_out = FIB_RES_DEV(res);
+       dev_out = FIB_RES_DEV(*res);
        fl4->flowi4_oif = dev_out->ifindex;
 
 
 make_route:
-       rth = __mkroute_output(&res, fl4, orig_oif, dev_out, flags);
+       rth = __mkroute_output(res, fl4, orig_oif, dev_out, flags);
 
 out:
-       rcu_read_unlock();
        return rth;
 }
-EXPORT_SYMBOL_GPL(__ip_route_output_key_hash);
 
 static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 cookie)
 {