diff options
author | Eric Dumazet <edumazet@google.com> | 2012-07-17 17:38:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-18 11:59:58 -0400 |
commit | d3818c92afabecfe6b8e5d2e3734c8753522987c (patch) | |
tree | c23f13c54bd995910d023445ab9207e5d9cfdecb /net/ipv6 | |
parent | 5abf7f7e0f6bdbfcac737f636497d7016d9507eb (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.c | 40 |
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 | ||
172 | static inline | 172 | static inline |
173 | void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst, | 173 | void __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 | ||
206 | static struct dst_entry *inet6_csk_route_socket(struct sock *sk) | 207 | static 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 | ||
266 | struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu) | 267 | struct 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 | } |
276 | EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu); | 278 | EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu); |