diff options
Diffstat (limited to 'net/dccp/ipv6.c')
-rw-r--r-- | net/dccp/ipv6.c | 23 |
1 files changed, 7 insertions, 16 deletions
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index fa9512d86f3..02162cfa504 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -165,6 +165,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
165 | } else | 165 | } else |
166 | dst_hold(dst); | 166 | dst_hold(dst); |
167 | 167 | ||
168 | dst->ops->update_pmtu(dst, ntohl(info)); | ||
169 | |||
168 | if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { | 170 | if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { |
169 | dccp_sync_mss(sk, dst_mtu(dst)); | 171 | dccp_sync_mss(sk, dst_mtu(dst)); |
170 | } /* else let the usual retransmit timer handle it */ | 172 | } /* else let the usual retransmit timer handle it */ |
@@ -237,7 +239,6 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, | |||
237 | struct inet6_request_sock *ireq6 = inet6_rsk(req); | 239 | struct inet6_request_sock *ireq6 = inet6_rsk(req); |
238 | struct ipv6_pinfo *np = inet6_sk(sk); | 240 | struct ipv6_pinfo *np = inet6_sk(sk); |
239 | struct sk_buff *skb; | 241 | struct sk_buff *skb; |
240 | struct ipv6_txoptions *opt = NULL; | ||
241 | struct in6_addr *final_p, final; | 242 | struct in6_addr *final_p, final; |
242 | struct flowi6 fl6; | 243 | struct flowi6 fl6; |
243 | int err = -1; | 244 | int err = -1; |
@@ -253,9 +254,8 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, | |||
253 | fl6.fl6_sport = inet_rsk(req)->loc_port; | 254 | fl6.fl6_sport = inet_rsk(req)->loc_port; |
254 | security_req_classify_flow(req, flowi6_to_flowi(&fl6)); | 255 | security_req_classify_flow(req, flowi6_to_flowi(&fl6)); |
255 | 256 | ||
256 | opt = np->opt; | ||
257 | 257 | ||
258 | final_p = fl6_update_dst(&fl6, opt, &final); | 258 | final_p = fl6_update_dst(&fl6, np->opt, &final); |
259 | 259 | ||
260 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); | 260 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); |
261 | if (IS_ERR(dst)) { | 261 | if (IS_ERR(dst)) { |
@@ -272,13 +272,11 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, | |||
272 | &ireq6->loc_addr, | 272 | &ireq6->loc_addr, |
273 | &ireq6->rmt_addr); | 273 | &ireq6->rmt_addr); |
274 | fl6.daddr = ireq6->rmt_addr; | 274 | fl6.daddr = ireq6->rmt_addr; |
275 | err = ip6_xmit(sk, skb, &fl6, opt, np->tclass); | 275 | err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); |
276 | err = net_xmit_eval(err); | 276 | err = net_xmit_eval(err); |
277 | } | 277 | } |
278 | 278 | ||
279 | done: | 279 | done: |
280 | if (opt != NULL && opt != np->opt) | ||
281 | sock_kfree_s(sk, opt, opt->tot_len); | ||
282 | dst_release(dst); | 280 | dst_release(dst); |
283 | return err; | 281 | return err; |
284 | } | 282 | } |
@@ -473,7 +471,6 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
473 | struct inet_sock *newinet; | 471 | struct inet_sock *newinet; |
474 | struct dccp6_sock *newdp6; | 472 | struct dccp6_sock *newdp6; |
475 | struct sock *newsk; | 473 | struct sock *newsk; |
476 | struct ipv6_txoptions *opt; | ||
477 | 474 | ||
478 | if (skb->protocol == htons(ETH_P_IP)) { | 475 | if (skb->protocol == htons(ETH_P_IP)) { |
479 | /* | 476 | /* |
@@ -518,7 +515,6 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
518 | return newsk; | 515 | return newsk; |
519 | } | 516 | } |
520 | 517 | ||
521 | opt = np->opt; | ||
522 | 518 | ||
523 | if (sk_acceptq_is_full(sk)) | 519 | if (sk_acceptq_is_full(sk)) |
524 | goto out_overflow; | 520 | goto out_overflow; |
@@ -530,7 +526,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
530 | memset(&fl6, 0, sizeof(fl6)); | 526 | memset(&fl6, 0, sizeof(fl6)); |
531 | fl6.flowi6_proto = IPPROTO_DCCP; | 527 | fl6.flowi6_proto = IPPROTO_DCCP; |
532 | fl6.daddr = ireq6->rmt_addr; | 528 | fl6.daddr = ireq6->rmt_addr; |
533 | final_p = fl6_update_dst(&fl6, opt, &final); | 529 | final_p = fl6_update_dst(&fl6, np->opt, &final); |
534 | fl6.saddr = ireq6->loc_addr; | 530 | fl6.saddr = ireq6->loc_addr; |
535 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 531 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
536 | fl6.fl6_dport = inet_rsk(req)->rmt_port; | 532 | fl6.fl6_dport = inet_rsk(req)->rmt_port; |
@@ -595,11 +591,8 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
595 | * Yes, keeping reference count would be much more clever, but we make | 591 | * Yes, keeping reference count would be much more clever, but we make |
596 | * one more one thing there: reattach optmem to newsk. | 592 | * one more one thing there: reattach optmem to newsk. |
597 | */ | 593 | */ |
598 | if (opt != NULL) { | 594 | if (np->opt != NULL) |
599 | newnp->opt = ipv6_dup_options(newsk, opt); | 595 | newnp->opt = ipv6_dup_options(newsk, np->opt); |
600 | if (opt != np->opt) | ||
601 | sock_kfree_s(sk, opt, opt->tot_len); | ||
602 | } | ||
603 | 596 | ||
604 | inet_csk(newsk)->icsk_ext_hdr_len = 0; | 597 | inet_csk(newsk)->icsk_ext_hdr_len = 0; |
605 | if (newnp->opt != NULL) | 598 | if (newnp->opt != NULL) |
@@ -625,8 +618,6 @@ out_nonewsk: | |||
625 | dst_release(dst); | 618 | dst_release(dst); |
626 | out: | 619 | out: |
627 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | 620 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); |
628 | if (opt != NULL && opt != np->opt) | ||
629 | sock_kfree_s(sk, opt, opt->tot_len); | ||
630 | return NULL; | 621 | return NULL; |
631 | } | 622 | } |
632 | 623 | ||