aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Haley <brian.haley@hp.com>2008-08-14 18:33:21 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-14 18:33:21 -0400
commit191cd582500f49b32a63040fedeebb0168c720af (patch)
tree173ce9682d77798c6e4ca7e14af57ea2f46c55b8
parent0eb8b1fe9238ca4c1797e4c105d5790abda1726f (diff)
netns: Add network namespace argument to rt6_fill_node() and ipv6_dev_get_saddr()
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: Brian Haley <brian.haley@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/addrconf.h3
-rw-r--r--include/net/ip6_route.h1
-rw-r--r--net/ipv6/addrconf.c3
-rw-r--r--net/ipv6/fib6_rules.c3
-rw-r--r--net/ipv6/ip6_fib.c1
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/ipv6/ndisc.c2
-rw-r--r--net/ipv6/route.c12
-rw-r--r--net/ipv6/xfrm6_policy.c4
-rw-r--r--net/sctp/ipv6.c3
10 files changed, 21 insertions, 13 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 06b28142b3ab..c216de528b08 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -80,7 +80,8 @@ extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
80 struct net_device *dev, 80 struct net_device *dev,
81 int strict); 81 int strict);
82 82
83extern int ipv6_dev_get_saddr(struct net_device *dev, 83extern int ipv6_dev_get_saddr(struct net *net,
84 struct net_device *dev,
84 const struct in6_addr *daddr, 85 const struct in6_addr *daddr,
85 unsigned int srcprefs, 86 unsigned int srcprefs,
86 struct in6_addr *saddr); 87 struct in6_addr *saddr);
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index bc391ba101e9..5f53db7e4e57 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -107,6 +107,7 @@ struct rt6_rtnl_dump_arg
107{ 107{
108 struct sk_buff *skb; 108 struct sk_buff *skb;
109 struct netlink_callback *cb; 109 struct netlink_callback *cb;
110 struct net *net;
110}; 111};
111 112
112extern int rt6_dump_route(struct rt6_info *rt, void *p_arg); 113extern int rt6_dump_route(struct rt6_info *rt, void *p_arg);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a7842c54f58a..e2d3b7580b76 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1106,13 +1106,12 @@ out:
1106 return ret; 1106 return ret;
1107} 1107}
1108 1108
1109int ipv6_dev_get_saddr(struct net_device *dst_dev, 1109int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
1110 const struct in6_addr *daddr, unsigned int prefs, 1110 const struct in6_addr *daddr, unsigned int prefs,
1111 struct in6_addr *saddr) 1111 struct in6_addr *saddr)
1112{ 1112{
1113 struct ipv6_saddr_score scores[2], 1113 struct ipv6_saddr_score scores[2],
1114 *score = &scores[0], *hiscore = &scores[1]; 1114 *score = &scores[0], *hiscore = &scores[1];
1115 struct net *net = dev_net(dst_dev);
1116 struct ipv6_saddr_dst dst; 1115 struct ipv6_saddr_dst dst;
1117 struct net_device *dev; 1116 struct net_device *dev;
1118 int dst_type; 1117 int dst_type;
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 8d05527524e3..f5de3f9dc692 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -93,7 +93,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
93 if (flags & RT6_LOOKUP_F_SRCPREF_COA) 93 if (flags & RT6_LOOKUP_F_SRCPREF_COA)
94 srcprefs |= IPV6_PREFER_SRC_COA; 94 srcprefs |= IPV6_PREFER_SRC_COA;
95 95
96 if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev, 96 if (ipv6_dev_get_saddr(net,
97 ip6_dst_idev(&rt->u.dst)->dev,
97 &flp->fl6_dst, srcprefs, 98 &flp->fl6_dst, srcprefs,
98 &saddr)) 99 &saddr))
99 goto again; 100 goto again;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 52dddc25d3e6..29c7c99e69f7 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -378,6 +378,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
378 378
379 arg.skb = skb; 379 arg.skb = skb;
380 arg.cb = cb; 380 arg.cb = cb;
381 arg.net = net;
381 w->args = &arg; 382 w->args = &arg;
382 383
383 for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) { 384 for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index a4402de425d9..0e844c2736a7 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -934,7 +934,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
934 goto out_err_release; 934 goto out_err_release;
935 935
936 if (ipv6_addr_any(&fl->fl6_src)) { 936 if (ipv6_addr_any(&fl->fl6_src)) {
937 err = ipv6_dev_get_saddr(ip6_dst_idev(*dst)->dev, 937 err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
938 &fl->fl6_dst, 938 &fl->fl6_dst,
939 sk ? inet6_sk(sk)->srcprefs : 0, 939 sk ? inet6_sk(sk)->srcprefs : 0,
940 &fl->fl6_src); 940 &fl->fl6_src);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index beb48e3f038a..f1c62ba0f56b 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -549,7 +549,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
549 override = 0; 549 override = 0;
550 in6_ifa_put(ifp); 550 in6_ifa_put(ifp);
551 } else { 551 } else {
552 if (ipv6_dev_get_saddr(dev, daddr, 552 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
553 inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs, 553 inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
554 &tmpaddr)) 554 &tmpaddr))
555 return; 555 return;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 41b165ffb369..9af6115f0f50 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2106,7 +2106,8 @@ static inline size_t rt6_nlmsg_size(void)
2106 + nla_total_size(sizeof(struct rta_cacheinfo)); 2106 + nla_total_size(sizeof(struct rta_cacheinfo));
2107} 2107}
2108 2108
2109static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, 2109static int rt6_fill_node(struct net *net,
2110 struct sk_buff *skb, struct rt6_info *rt,
2110 struct in6_addr *dst, struct in6_addr *src, 2111 struct in6_addr *dst, struct in6_addr *src,
2111 int iif, int type, u32 pid, u32 seq, 2112 int iif, int type, u32 pid, u32 seq,
2112 int prefix, int nowait, unsigned int flags) 2113 int prefix, int nowait, unsigned int flags)
@@ -2189,7 +2190,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2189 } else if (dst) { 2190 } else if (dst) {
2190 struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst); 2191 struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst);
2191 struct in6_addr saddr_buf; 2192 struct in6_addr saddr_buf;
2192 if (ipv6_dev_get_saddr(idev ? idev->dev : NULL, 2193 if (ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
2193 dst, 0, &saddr_buf) == 0) 2194 dst, 0, &saddr_buf) == 0)
2194 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); 2195 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
2195 } 2196 }
@@ -2234,7 +2235,8 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
2234 } else 2235 } else
2235 prefix = 0; 2236 prefix = 0;
2236 2237
2237 return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, 2238 return rt6_fill_node(arg->net,
2239 arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
2238 NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, 2240 NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
2239 prefix, 0, NLM_F_MULTI); 2241 prefix, 0, NLM_F_MULTI);
2240} 2242}
@@ -2300,7 +2302,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2300 rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl); 2302 rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl);
2301 skb->dst = &rt->u.dst; 2303 skb->dst = &rt->u.dst;
2302 2304
2303 err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, 2305 err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
2304 RTM_NEWROUTE, NETLINK_CB(in_skb).pid, 2306 RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
2305 nlh->nlmsg_seq, 0, 0, 0); 2307 nlh->nlmsg_seq, 0, 0, 0);
2306 if (err < 0) { 2308 if (err < 0) {
@@ -2327,7 +2329,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2327 if (skb == NULL) 2329 if (skb == NULL)
2328 goto errout; 2330 goto errout;
2329 2331
2330 err = rt6_fill_node(skb, rt, NULL, NULL, 0, 2332 err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
2331 event, info->pid, seq, 0, 0, 0); 2333 event, info->pid, seq, 0, 0, 0);
2332 if (err < 0) { 2334 if (err < 0) {
2333 /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ 2335 /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 8f1e0543b3c4..08e4cbbe3f04 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -52,12 +52,14 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr,
52static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr) 52static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
53{ 53{
54 struct dst_entry *dst; 54 struct dst_entry *dst;
55 struct net_device *dev;
55 56
56 dst = xfrm6_dst_lookup(0, NULL, daddr); 57 dst = xfrm6_dst_lookup(0, NULL, daddr);
57 if (IS_ERR(dst)) 58 if (IS_ERR(dst))
58 return -EHOSTUNREACH; 59 return -EHOSTUNREACH;
59 60
60 ipv6_dev_get_saddr(ip6_dst_idev(dst)->dev, 61 dev = ip6_dst_idev(dst)->dev;
62 ipv6_dev_get_saddr(dev_net(dev), dev,
61 (struct in6_addr *)&daddr->a6, 0, 63 (struct in6_addr *)&daddr->a6, 0,
62 (struct in6_addr *)&saddr->a6); 64 (struct in6_addr *)&saddr->a6);
63 dst_release(dst); 65 dst_release(dst);
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 483a01d0740a..47f91afa0211 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -319,7 +319,8 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
319 __func__, asoc, dst, NIP6(daddr->v6.sin6_addr)); 319 __func__, asoc, dst, NIP6(daddr->v6.sin6_addr));
320 320
321 if (!asoc) { 321 if (!asoc) {
322 ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, 322 ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)),
323 dst ? ip6_dst_idev(dst)->dev : NULL,
323 &daddr->v6.sin6_addr, 324 &daddr->v6.sin6_addr,
324 inet6_sk(&sk->inet.sk)->srcprefs, 325 inet6_sk(&sk->inet.sk)->srcprefs,
325 &saddr->v6.sin6_addr); 326 &saddr->v6.sin6_addr);