diff --git a/include/linux/mroute.h b/include/linux/mroute.h index 46caaf44339d6e..4e364bb6d1aafe 100644 --- a/include/linux/mroute.h +++ b/include/linux/mroute.h @@ -245,7 +245,7 @@ struct mfc_cache { struct rtmsg; extern int ipmr_get_route(struct net *net, struct sk_buff *skb, __be32 saddr, __be32 daddr, - struct rtmsg *rtm, int nowait); + struct rtmsg *rtm, int nowait, u32 portid); #endif #endif diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h index a3759cb0ac1056..9b30150c973a2a 100644 --- a/include/linux/mroute6.h +++ b/include/linux/mroute6.h @@ -228,7 +228,7 @@ struct mfc6_cache { #ifdef __KERNEL__ struct rtmsg; extern int ip6mr_get_route(struct net *net, struct sk_buff *skb, - struct rtmsg *rtm, int nowait); + struct rtmsg *rtm, int nowait, u32 portid); #ifdef CONFIG_IPV6_MROUTE extern struct sock *mroute6_socket(struct net *net, struct sk_buff *skb); diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 95b47ff4ce6fef..6558a9182793a5 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -2058,7 +2058,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, int ipmr_get_route(struct net *net, struct sk_buff *skb, __be32 saddr, __be32 daddr, - struct rtmsg *rtm, int nowait) + struct rtmsg *rtm, int nowait, u32 portid) { struct mfc_cache *cache; struct mr_table *mrt; @@ -2098,6 +2098,7 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb, return -ENOMEM; } + NETLINK_CB(skb2).pid = portid; skb_push(skb2, sizeof(struct iphdr)); skb_reset_network_header(skb2); iph = ip_hdr(skb2); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 8e79a9e04276c7..3026b65f9a8455 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -3077,7 +3077,8 @@ static int rt_fill_info(struct net *net, IPV4_DEVCONF_ALL(net, MC_FORWARDING)) { int err = ipmr_get_route(net, skb, rt->rt_src, rt->rt_dst, - r, nowait); + r, nowait, pid); + if (err <= 0) { if (!nowait) { if (err == 0) diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 02b3c827dfe02f..7a3923b3e8282f 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -2137,8 +2137,8 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, return -EMSGSIZE; } -int ip6mr_get_route(struct net *net, - struct sk_buff *skb, struct rtmsg *rtm, int nowait) +int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm, + int nowait, u32 portid) { int err; struct mr6_table *mrt; @@ -2176,6 +2176,7 @@ int ip6mr_get_route(struct net *net, return -ENOMEM; } + NETLINK_CB(skb2).pid = portid; skb_reset_transport_header(skb2); skb_put(skb2, sizeof(struct ipv6hdr)); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 3a8776d9b89542..d4059fa595480a 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2416,7 +2416,9 @@ static int rt6_fill_node(struct net *net, if (iif) { #ifdef CONFIG_IPV6_MROUTE if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) { - int err = ip6mr_get_route(net, skb, rtm, nowait); + int err = ip6mr_get_route(net, skb, rtm, nowait, + pid); + if (err <= 0) { if (!nowait) { if (err == 0)