summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2012-12-04 01:03:07 +0000
committerDavid S. Miller <davem@davemloft.net>2012-12-07 12:24:33 -0500
commit8caaf7b608ae27f7e7d5f5df6f87039db556d4bb (patch)
treea2df2bfcc8e549e633cda4e3958d61aeb975b994 /net/ipv4
parente3d8fabee3b66ce158b2603f270479b84b6e4ba7 (diff)
downloadlinux-8caaf7b608ae27f7e7d5f5df6f87039db556d4bb.tar.gz
linux-8caaf7b608ae27f7e7d5f5df6f87039db556d4bb.tar.bz2
linux-8caaf7b608ae27f7e7d5f5df6f87039db556d4bb.zip
ipv4/route/rtnl: get mcast attributes when dst is multicast
Commit f1ce3062c538 (ipv4: Remove 'rt_dst' from 'struct rtable') removes the call to ipmr_get_route(), which will get multicast parameters of the route. I revert the part of the patch that remove this call. I think the goal was only to get rid of rt_dst field. The patch is only compiled-tested. My first idea was to remove ipmr_get_route() because rt_fill_info() was the only user, but it seems the previous patch cleans the code a bit too much ;-) Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/route.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index baa9b289d7ab..844a9ef60dbd 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2232,8 +2232,27 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
error = rt->dst.error;
if (rt_is_input_route(rt)) {
- if (nla_put_u32(skb, RTA_IIF, rt->rt_iif))
- goto nla_put_failure;
+#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, nowait);
+ if (err <= 0) {
+ if (!nowait) {
+ if (err == 0)
+ return 0;
+ goto nla_put_failure;
+ } else {
+ if (err == -EMSGSIZE)
+ goto nla_put_failure;
+ error = err;
+ }
+ }
+ } else
+#endif
+ if (nla_put_u32(skb, RTA_IIF, rt->rt_iif))
+ goto nla_put_failure;
}
if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires, error) < 0)