diff options
author | David S. Miller <davem@davemloft.net> | 2012-07-16 06:44:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-16 06:44:56 -0400 |
commit | 35ad9b9cf7d8a2e6259a0d24022e910adb6f3489 (patch) | |
tree | d9772467e072f3f1d142aa0ce2fc56ef69c57cb7 /net/ipv6/inet6_connection_sock.c | |
parent | 80d0a69fc57715dc9080c0567df1ed911b78abea (diff) |
ipv6: Add helper inet6_csk_update_pmtu().
This is the ipv6 version of inet_csk_update_pmtu().
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/inet6_connection_sock.c')
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index bceb14450a1d..62539a4b2dc7 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -203,15 +203,13 @@ struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie) | |||
203 | return dst; | 203 | return dst; |
204 | } | 204 | } |
205 | 205 | ||
206 | int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) | 206 | static struct dst_entry *inet6_csk_route_socket(struct sock *sk) |
207 | { | 207 | { |
208 | struct sock *sk = skb->sk; | ||
209 | struct inet_sock *inet = inet_sk(sk); | 208 | struct inet_sock *inet = inet_sk(sk); |
210 | struct ipv6_pinfo *np = inet6_sk(sk); | 209 | struct ipv6_pinfo *np = inet6_sk(sk); |
211 | struct flowi6 fl6; | ||
212 | struct dst_entry *dst; | ||
213 | struct in6_addr *final_p, final; | 210 | struct in6_addr *final_p, final; |
214 | int res; | 211 | struct dst_entry *dst; |
212 | struct flowi6 fl6; | ||
215 | 213 | ||
216 | memset(&fl6, 0, sizeof(fl6)); | 214 | memset(&fl6, 0, sizeof(fl6)); |
217 | fl6.flowi6_proto = sk->sk_protocol; | 215 | fl6.flowi6_proto = sk->sk_protocol; |
@@ -228,18 +226,29 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) | |||
228 | final_p = fl6_update_dst(&fl6, np->opt, &final); | 226 | final_p = fl6_update_dst(&fl6, np->opt, &final); |
229 | 227 | ||
230 | dst = __inet6_csk_dst_check(sk, np->dst_cookie); | 228 | dst = __inet6_csk_dst_check(sk, np->dst_cookie); |
231 | 229 | if (!dst) { | |
232 | if (dst == NULL) { | ||
233 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); | 230 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); |
234 | 231 | ||
235 | if (IS_ERR(dst)) { | 232 | if (!IS_ERR(dst)) |
236 | sk->sk_err_soft = -PTR_ERR(dst); | 233 | __inet6_csk_dst_store(sk, dst, NULL, NULL); |
237 | sk->sk_route_caps = 0; | 234 | } |
238 | kfree_skb(skb); | 235 | return dst; |
239 | return PTR_ERR(dst); | 236 | } |
240 | } | ||
241 | 237 | ||
242 | __inet6_csk_dst_store(sk, dst, NULL, NULL); | 238 | int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) |
239 | { | ||
240 | struct sock *sk = skb->sk; | ||
241 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
242 | struct flowi6 fl6; | ||
243 | struct dst_entry *dst; | ||
244 | int res; | ||
245 | |||
246 | dst = inet6_csk_route_socket(sk); | ||
247 | if (IS_ERR(dst)) { | ||
248 | sk->sk_err_soft = -PTR_ERR(dst); | ||
249 | sk->sk_route_caps = 0; | ||
250 | kfree_skb(skb); | ||
251 | return PTR_ERR(dst); | ||
243 | } | 252 | } |
244 | 253 | ||
245 | rcu_read_lock(); | 254 | rcu_read_lock(); |
@@ -253,3 +262,15 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) | |||
253 | return res; | 262 | return res; |
254 | } | 263 | } |
255 | EXPORT_SYMBOL_GPL(inet6_csk_xmit); | 264 | EXPORT_SYMBOL_GPL(inet6_csk_xmit); |
265 | |||
266 | struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu) | ||
267 | { | ||
268 | struct dst_entry *dst = inet6_csk_route_socket(sk); | ||
269 | |||
270 | if (IS_ERR(dst)) | ||
271 | return NULL; | ||
272 | dst->ops->update_pmtu(dst, mtu); | ||
273 | |||
274 | return inet6_csk_route_socket(sk); | ||
275 | } | ||
276 | EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu); | ||