aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-07-17 17:38:04 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-18 11:59:58 -0400
commitd3818c92afabecfe6b8e5d2e3734c8753522987c (patch)
treec23f13c54bd995910d023445ab9207e5d9cfdecb /net/ipv6
parent5abf7f7e0f6bdbfcac737f636497d7016d9507eb (diff)
ipv6: fix inet6_csk_xmit()
We should provide to inet6_csk_route_socket a struct flowi6 pointer, so that net6_csk_xmit() works correctly instead of sending garbage. Also add some consts Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: Yuchung Cheng <ycheng@google.com> Cc: Neal Cardwell <ncardwell@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/inet6_connection_sock.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 4a0c4d2d8b05..0251a6005be8 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -171,7 +171,8 @@ EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
171 171
172static inline 172static inline
173void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst, 173void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst,
174 struct in6_addr *daddr, struct in6_addr *saddr) 174 const struct in6_addr *daddr,
175 const struct in6_addr *saddr)
175{ 176{
176 __ip6_dst_store(sk, dst, daddr, saddr); 177 __ip6_dst_store(sk, dst, daddr, saddr);
177 178
@@ -203,31 +204,31 @@ struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
203 return dst; 204 return dst;
204} 205}
205 206
206static struct dst_entry *inet6_csk_route_socket(struct sock *sk) 207static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
208 struct flowi6 *fl6)
207{ 209{
208 struct inet_sock *inet = inet_sk(sk); 210 struct inet_sock *inet = inet_sk(sk);
209 struct ipv6_pinfo *np = inet6_sk(sk); 211 struct ipv6_pinfo *np = inet6_sk(sk);
210 struct in6_addr *final_p, final; 212 struct in6_addr *final_p, final;
211 struct dst_entry *dst; 213 struct dst_entry *dst;
212 struct flowi6 fl6;
213 214
214 memset(&fl6, 0, sizeof(fl6)); 215 memset(fl6, 0, sizeof(*fl6));
215 fl6.flowi6_proto = sk->sk_protocol; 216 fl6->flowi6_proto = sk->sk_protocol;
216 fl6.daddr = np->daddr; 217 fl6->daddr = np->daddr;
217 fl6.saddr = np->saddr; 218 fl6->saddr = np->saddr;
218 fl6.flowlabel = np->flow_label; 219 fl6->flowlabel = np->flow_label;
219 IP6_ECN_flow_xmit(sk, fl6.flowlabel); 220 IP6_ECN_flow_xmit(sk, fl6->flowlabel);
220 fl6.flowi6_oif = sk->sk_bound_dev_if; 221 fl6->flowi6_oif = sk->sk_bound_dev_if;
221 fl6.flowi6_mark = sk->sk_mark; 222 fl6->flowi6_mark = sk->sk_mark;
222 fl6.fl6_sport = inet->inet_sport; 223 fl6->fl6_sport = inet->inet_sport;
223 fl6.fl6_dport = inet->inet_dport; 224 fl6->fl6_dport = inet->inet_dport;
224 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); 225 security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
225 226
226 final_p = fl6_update_dst(&fl6, np->opt, &final); 227 final_p = fl6_update_dst(fl6, np->opt, &final);
227 228
228 dst = __inet6_csk_dst_check(sk, np->dst_cookie); 229 dst = __inet6_csk_dst_check(sk, np->dst_cookie);
229 if (!dst) { 230 if (!dst) {
230 dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); 231 dst = ip6_dst_lookup_flow(sk, fl6, final_p, false);
231 232
232 if (!IS_ERR(dst)) 233 if (!IS_ERR(dst))
233 __inet6_csk_dst_store(sk, dst, NULL, NULL); 234 __inet6_csk_dst_store(sk, dst, NULL, NULL);
@@ -243,7 +244,7 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused)
243 struct dst_entry *dst; 244 struct dst_entry *dst;
244 int res; 245 int res;
245 246
246 dst = inet6_csk_route_socket(sk); 247 dst = inet6_csk_route_socket(sk, &fl6);
247 if (IS_ERR(dst)) { 248 if (IS_ERR(dst)) {
248 sk->sk_err_soft = -PTR_ERR(dst); 249 sk->sk_err_soft = -PTR_ERR(dst);
249 sk->sk_route_caps = 0; 250 sk->sk_route_caps = 0;
@@ -265,12 +266,13 @@ EXPORT_SYMBOL_GPL(inet6_csk_xmit);
265 266
266struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu) 267struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu)
267{ 268{
268 struct dst_entry *dst = inet6_csk_route_socket(sk); 269 struct flowi6 fl6;
270 struct dst_entry *dst = inet6_csk_route_socket(sk, &fl6);
269 271
270 if (IS_ERR(dst)) 272 if (IS_ERR(dst))
271 return NULL; 273 return NULL;
272 dst->ops->update_pmtu(dst, sk, NULL, mtu); 274 dst->ops->update_pmtu(dst, sk, NULL, mtu);
273 275
274 return inet6_csk_route_socket(sk); 276 return inet6_csk_route_socket(sk, &fl6);
275} 277}
276EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu); 278EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu);