Commit 7b29aece authored by Brian Haley's avatar Brian Haley Committed by Greg Kroah-Hartman

netns: Add network namespace argument to rt6_fill_node() and ipv6_dev_get_saddr()

[ Upstream commit 191cd582 ]

ipv6_dev_get_saddr() blindly de-references dst_dev to get the network
namespace, but some callers might pass NULL.  Change callers to pass a
namespace pointer instead.
Signed-off-by: default avatarBrian Haley <brian.haley@hp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 2b02f3dd
...@@ -80,7 +80,8 @@ extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, ...@@ -80,7 +80,8 @@ extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
struct net_device *dev, struct net_device *dev,
int strict); int strict);
extern int ipv6_dev_get_saddr(struct net_device *dev, extern int ipv6_dev_get_saddr(struct net *net,
struct net_device *dev,
const struct in6_addr *daddr, const struct in6_addr *daddr,
unsigned int srcprefs, unsigned int srcprefs,
struct in6_addr *saddr); struct in6_addr *saddr);
......
...@@ -112,6 +112,7 @@ struct rt6_rtnl_dump_arg ...@@ -112,6 +112,7 @@ struct rt6_rtnl_dump_arg
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct netlink_callback *cb; struct netlink_callback *cb;
struct net *net;
}; };
extern int rt6_dump_route(struct rt6_info *rt, void *p_arg); extern int rt6_dump_route(struct rt6_info *rt, void *p_arg);
......
...@@ -1076,13 +1076,12 @@ out: ...@@ -1076,13 +1076,12 @@ out:
return ret; return ret;
} }
int ipv6_dev_get_saddr(struct net_device *dst_dev, int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
const struct in6_addr *daddr, unsigned int prefs, const struct in6_addr *daddr, unsigned int prefs,
struct in6_addr *saddr) struct in6_addr *saddr)
{ {
struct ipv6_saddr_score scores[2], struct ipv6_saddr_score scores[2],
*score = &scores[0], *hiscore = &scores[1]; *score = &scores[0], *hiscore = &scores[1];
struct net *net = dev_net(dst_dev);
struct ipv6_saddr_dst dst; struct ipv6_saddr_dst dst;
struct net_device *dev; struct net_device *dev;
int dst_type; int dst_type;
......
...@@ -93,7 +93,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, ...@@ -93,7 +93,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
if (flags & RT6_LOOKUP_F_SRCPREF_COA) if (flags & RT6_LOOKUP_F_SRCPREF_COA)
srcprefs |= IPV6_PREFER_SRC_COA; srcprefs |= IPV6_PREFER_SRC_COA;
if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev, if (ipv6_dev_get_saddr(net,
ip6_dst_idev(&rt->u.dst)->dev,
&flp->fl6_dst, srcprefs, &flp->fl6_dst, srcprefs,
&saddr)) &saddr))
goto again; goto again;
......
...@@ -380,6 +380,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -380,6 +380,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
arg.skb = skb; arg.skb = skb;
arg.cb = cb; arg.cb = cb;
arg.net = net;
w->args = &arg; w->args = &arg;
for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) { for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
......
...@@ -925,7 +925,7 @@ static int ip6_dst_lookup_tail(struct sock *sk, ...@@ -925,7 +925,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
goto out_err_release; goto out_err_release;
if (ipv6_addr_any(&fl->fl6_src)) { if (ipv6_addr_any(&fl->fl6_src)) {
err = ipv6_dev_get_saddr(ip6_dst_idev(*dst)->dev, err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
&fl->fl6_dst, &fl->fl6_dst,
sk ? inet6_sk(sk)->srcprefs : 0, sk ? inet6_sk(sk)->srcprefs : 0,
&fl->fl6_src); &fl->fl6_src);
......
...@@ -549,7 +549,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, ...@@ -549,7 +549,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
override = 0; override = 0;
in6_ifa_put(ifp); in6_ifa_put(ifp);
} else { } else {
if (ipv6_dev_get_saddr(dev, daddr, if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs, inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
&tmpaddr)) &tmpaddr))
return; return;
......
...@@ -2098,7 +2098,8 @@ static inline size_t rt6_nlmsg_size(void) ...@@ -2098,7 +2098,8 @@ static inline size_t rt6_nlmsg_size(void)
+ nla_total_size(sizeof(struct rta_cacheinfo)); + nla_total_size(sizeof(struct rta_cacheinfo));
} }
static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, static int rt6_fill_node(struct net *net,
struct sk_buff *skb, struct rt6_info *rt,
struct in6_addr *dst, struct in6_addr *src, struct in6_addr *dst, struct in6_addr *src,
int iif, int type, u32 pid, u32 seq, int iif, int type, u32 pid, u32 seq,
int prefix, int nowait, unsigned int flags) int prefix, int nowait, unsigned int flags)
...@@ -2181,7 +2182,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, ...@@ -2181,7 +2182,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
} else if (dst) { } else if (dst) {
struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst); struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst);
struct in6_addr saddr_buf; struct in6_addr saddr_buf;
if (ipv6_dev_get_saddr(idev ? idev->dev : NULL, if (ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
dst, 0, &saddr_buf) == 0) dst, 0, &saddr_buf) == 0)
NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
} }
...@@ -2226,7 +2227,8 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg) ...@@ -2226,7 +2227,8 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
} else } else
prefix = 0; prefix = 0;
return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, return rt6_fill_node(arg->net,
arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
prefix, 0, NLM_F_MULTI); prefix, 0, NLM_F_MULTI);
} }
...@@ -2292,7 +2294,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void ...@@ -2292,7 +2294,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl); rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl);
skb->dst = &rt->u.dst; skb->dst = &rt->u.dst;
err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
RTM_NEWROUTE, NETLINK_CB(in_skb).pid, RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
nlh->nlmsg_seq, 0, 0, 0); nlh->nlmsg_seq, 0, 0, 0);
if (err < 0) { if (err < 0) {
...@@ -2319,7 +2321,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) ...@@ -2319,7 +2321,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
if (skb == NULL) if (skb == NULL)
goto errout; goto errout;
err = rt6_fill_node(skb, rt, NULL, NULL, 0, err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
event, info->pid, seq, 0, 0, 0); event, info->pid, seq, 0, 0, 0);
if (err < 0) { if (err < 0) {
/* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
......
...@@ -52,12 +52,14 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr, ...@@ -52,12 +52,14 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr,
static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr) static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
{ {
struct dst_entry *dst; struct dst_entry *dst;
struct net_device *dev;
dst = xfrm6_dst_lookup(0, NULL, daddr); dst = xfrm6_dst_lookup(0, NULL, daddr);
if (IS_ERR(dst)) if (IS_ERR(dst))
return -EHOSTUNREACH; return -EHOSTUNREACH;
ipv6_dev_get_saddr(ip6_dst_idev(dst)->dev, dev = ip6_dst_idev(dst)->dev;
ipv6_dev_get_saddr(dev_net(dev), dev,
(struct in6_addr *)&daddr->a6, 0, (struct in6_addr *)&daddr->a6, 0,
(struct in6_addr *)&saddr->a6); (struct in6_addr *)&saddr->a6);
dst_release(dst); dst_release(dst);
......
...@@ -317,7 +317,8 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk, ...@@ -317,7 +317,8 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
__func__, asoc, dst, NIP6(daddr->v6.sin6_addr)); __func__, asoc, dst, NIP6(daddr->v6.sin6_addr));
if (!asoc) { if (!asoc) {
ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)),
dst ? ip6_dst_idev(dst)->dev : NULL,
&daddr->v6.sin6_addr, &daddr->v6.sin6_addr,
inet6_sk(&sk->inet.sk)->srcprefs, inet6_sk(&sk->inet.sk)->srcprefs,
&saddr->v6.sin6_addr); &saddr->v6.sin6_addr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment