ipv4/route: Allow NULL flowinfo in rt_fill_info()
authorStefano Brivio <sbrivio@redhat.com>
Fri, 21 Jun 2019 15:45:22 +0000 (17:45 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 24 Jun 2019 17:18:48 +0000 (10:18 -0700)
In the next patch, we're going to use rt_fill_info() to dump exception
routes upon RTM_GETROUTE with NLM_F_ROOT, meaning userspace is requesting
a dump and not a specific route selection, which in turn implies the input
interface is not relevant. Update rt_fill_info() to handle a NULL
flowinfo.

v7: If fl4 is NULL, explicitly set r->rtm_tos to 0: it's not initialised
    otherwise (spotted by David Ahern)

v6: New patch

Suggested-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/route.c

index 66cbe8a7a168bf8d202ced43d51bc7830390e30c..b1628d25e828cdb888dbab70e405f6b4132b52ff 100644 (file)
@@ -2699,7 +2699,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
        r->rtm_family    = AF_INET;
        r->rtm_dst_len  = 32;
        r->rtm_src_len  = 0;
-       r->rtm_tos      = fl4->flowi4_tos;
+       r->rtm_tos      = fl4 ? fl4->flowi4_tos : 0;
        r->rtm_table    = table_id < 256 ? table_id : RT_TABLE_COMPAT;
        if (nla_put_u32(skb, RTA_TABLE, table_id))
                goto nla_put_failure;
@@ -2727,7 +2727,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
            nla_put_u32(skb, RTA_FLOW, rt->dst.tclassid))
                goto nla_put_failure;
 #endif
-       if (!rt_is_input_route(rt) &&
+       if (fl4 && !rt_is_input_route(rt) &&
            fl4->saddr != src) {
                if (nla_put_in_addr(skb, RTA_PREFSRC, fl4->saddr))
                        goto nla_put_failure;
@@ -2767,36 +2767,40 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
        if (rtnetlink_put_metrics(skb, metrics) < 0)
                goto nla_put_failure;
 
-       if (fl4->flowi4_mark &&
-           nla_put_u32(skb, RTA_MARK, fl4->flowi4_mark))
-               goto nla_put_failure;
-
-       if (!uid_eq(fl4->flowi4_uid, INVALID_UID) &&
-           nla_put_u32(skb, RTA_UID,
-                       from_kuid_munged(current_user_ns(), fl4->flowi4_uid)))
-               goto nla_put_failure;
+       if (fl4) {
+               if (fl4->flowi4_mark &&
+                   nla_put_u32(skb, RTA_MARK, fl4->flowi4_mark))
+                       goto nla_put_failure;
 
-       error = rt->dst.error;
+               if (!uid_eq(fl4->flowi4_uid, INVALID_UID) &&
+                   nla_put_u32(skb, RTA_UID,
+                               from_kuid_munged(current_user_ns(),
+                                                fl4->flowi4_uid)))
+                       goto nla_put_failure;
 
-       if (rt_is_input_route(rt)) {
+               if (rt_is_input_route(rt)) {
 #ifdef CONFIG_IP_MROUTE
-               if (ipv4_is_multicast(dst) && !ipv4_is_local_multicast(dst) &&
-                   IPV4_DEVCONF_ALL(net, MC_FORWARDING)) {
-                       int err = ipmr_get_route(net, skb,
-                                                fl4->saddr, fl4->daddr,
-                                                r, portid);
-
-                       if (err <= 0) {
-                               if (err == 0)
-                                       return 0;
-                               goto nla_put_failure;
-                       }
-               } else
+                       if (ipv4_is_multicast(dst) &&
+                           !ipv4_is_local_multicast(dst) &&
+                           IPV4_DEVCONF_ALL(net, MC_FORWARDING)) {
+                               int err = ipmr_get_route(net, skb,
+                                                        fl4->saddr, fl4->daddr,
+                                                        r, portid);
+
+                               if (err <= 0) {
+                                       if (err == 0)
+                                               return 0;
+                                       goto nla_put_failure;
+                               }
+                       } else
 #endif
-                       if (nla_put_u32(skb, RTA_IIF, fl4->flowi4_iif))
-                               goto nla_put_failure;
+                               if (nla_put_u32(skb, RTA_IIF, fl4->flowi4_iif))
+                                       goto nla_put_failure;
+               }
        }
 
+       error = rt->dst.error;
+
        if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires, error) < 0)
                goto nla_put_failure;