}
 }
 
+static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
+                         struct inet6_cork *v6_cork,
+                         int hlimit, int tclass, struct ipv6_txoptions *opt,
+                         struct rt6_info *rt, struct flowi6 *fl6)
+{
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       unsigned int mtu;
+
+       /*
+        * setup for corking
+        */
+       if (opt) {
+               if (WARN_ON(v6_cork->opt))
+                       return -EINVAL;
+
+               v6_cork->opt = kzalloc(opt->tot_len, sk->sk_allocation);
+               if (unlikely(v6_cork->opt == NULL))
+                       return -ENOBUFS;
+
+               v6_cork->opt->tot_len = opt->tot_len;
+               v6_cork->opt->opt_flen = opt->opt_flen;
+               v6_cork->opt->opt_nflen = opt->opt_nflen;
+
+               v6_cork->opt->dst0opt = ip6_opt_dup(opt->dst0opt,
+                                                   sk->sk_allocation);
+               if (opt->dst0opt && !v6_cork->opt->dst0opt)
+                       return -ENOBUFS;
+
+               v6_cork->opt->dst1opt = ip6_opt_dup(opt->dst1opt,
+                                                   sk->sk_allocation);
+               if (opt->dst1opt && !v6_cork->opt->dst1opt)
+                       return -ENOBUFS;
+
+               v6_cork->opt->hopopt = ip6_opt_dup(opt->hopopt,
+                                                  sk->sk_allocation);
+               if (opt->hopopt && !v6_cork->opt->hopopt)
+                       return -ENOBUFS;
+
+               v6_cork->opt->srcrt = ip6_rthdr_dup(opt->srcrt,
+                                                   sk->sk_allocation);
+               if (opt->srcrt && !v6_cork->opt->srcrt)
+                       return -ENOBUFS;
+
+               /* need source address above miyazawa*/
+       }
+       dst_hold(&rt->dst);
+       cork->base.dst = &rt->dst;
+       cork->fl.u.ip6 = *fl6;
+       v6_cork->hop_limit = hlimit;
+       v6_cork->tclass = tclass;
+       if (rt->dst.flags & DST_XFRM_TUNNEL)
+               mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
+                     rt->dst.dev->mtu : dst_mtu(&rt->dst);
+       else
+               mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
+                     rt->dst.dev->mtu : dst_mtu(rt->dst.path);
+       if (np->frag_size < mtu) {
+               if (np->frag_size)
+                       mtu = np->frag_size;
+       }
+       cork->base.fragsize = mtu;
+       if (dst_allfrag(rt->dst.path))
+               cork->base.flags |= IPCORK_ALLFRAG;
+       cork->base.length = 0;
+
+       return 0;
+}
+
 int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
        int offset, int len, int odd, struct sk_buff *skb),
        void *from, int length, int transhdrlen,
                /*
                 * setup for corking
                 */
-               if (opt) {
-                       if (WARN_ON(np->cork.opt))
-                               return -EINVAL;
-
-                       np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation);
-                       if (unlikely(np->cork.opt == NULL))
-                               return -ENOBUFS;
-
-                       np->cork.opt->tot_len = opt->tot_len;
-                       np->cork.opt->opt_flen = opt->opt_flen;
-                       np->cork.opt->opt_nflen = opt->opt_nflen;
-
-                       np->cork.opt->dst0opt = ip6_opt_dup(opt->dst0opt,
-                                                           sk->sk_allocation);
-                       if (opt->dst0opt && !np->cork.opt->dst0opt)
-                               return -ENOBUFS;
-
-                       np->cork.opt->dst1opt = ip6_opt_dup(opt->dst1opt,
-                                                           sk->sk_allocation);
-                       if (opt->dst1opt && !np->cork.opt->dst1opt)
-                               return -ENOBUFS;
-
-                       np->cork.opt->hopopt = ip6_opt_dup(opt->hopopt,
-                                                          sk->sk_allocation);
-                       if (opt->hopopt && !np->cork.opt->hopopt)
-                               return -ENOBUFS;
-
-                       np->cork.opt->srcrt = ip6_rthdr_dup(opt->srcrt,
-                                                           sk->sk_allocation);
-                       if (opt->srcrt && !np->cork.opt->srcrt)
-                               return -ENOBUFS;
-
-                       /* need source address above miyazawa*/
-               }
-               dst_hold(&rt->dst);
-               cork->dst = &rt->dst;
-               inet->cork.fl.u.ip6 = *fl6;
-               np->cork.hop_limit = hlimit;
-               np->cork.tclass = tclass;
-               if (rt->dst.flags & DST_XFRM_TUNNEL)
-                       mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
-                             rt->dst.dev->mtu : dst_mtu(&rt->dst);
-               else
-                       mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
-                             rt->dst.dev->mtu : dst_mtu(rt->dst.path);
-               if (np->frag_size < mtu) {
-                       if (np->frag_size)
-                               mtu = np->frag_size;
-               }
-               cork->fragsize = mtu;
-               if (dst_allfrag(rt->dst.path))
-                       cork->flags |= IPCORK_ALLFRAG;
-               cork->length = 0;
+               err = ip6_setup_cork(sk, &inet->cork, &np->cork, hlimit,
+                                    tclass, opt, rt, fl6);
+               if (err)
+                       return err;
                exthdrlen = (opt ? opt->opt_flen : 0);
                length += exthdrlen;
                transhdrlen += exthdrlen;
                transhdrlen = 0;
                exthdrlen = 0;
                dst_exthdrlen = 0;
-               mtu = cork->fragsize;
        }
+       mtu = cork->fragsize;
        orig_mtu = mtu;
 
        hh_len = LL_RESERVED_SPACE(rt->dst.dev);
 }
 EXPORT_SYMBOL_GPL(ip6_append_data);
 
-static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np)
+static void ip6_cork_release(struct inet_cork_full *cork,
+                            struct inet6_cork *v6_cork)
 {
-       if (np->cork.opt) {
-               kfree(np->cork.opt->dst0opt);
-               kfree(np->cork.opt->dst1opt);
-               kfree(np->cork.opt->hopopt);
-               kfree(np->cork.opt->srcrt);
-               kfree(np->cork.opt);
-               np->cork.opt = NULL;
+       if (v6_cork->opt) {
+               kfree(v6_cork->opt->dst0opt);
+               kfree(v6_cork->opt->dst1opt);
+               kfree(v6_cork->opt->hopopt);
+               kfree(v6_cork->opt->srcrt);
+               kfree(v6_cork->opt);
+               v6_cork->opt = NULL;
        }
 
-       if (inet->cork.base.dst) {
-               dst_release(inet->cork.base.dst);
-               inet->cork.base.dst = NULL;
-               inet->cork.base.flags &= ~IPCORK_ALLFRAG;
+       if (cork->base.dst) {
+               dst_release(cork->base.dst);
+               cork->base.dst = NULL;
+               cork->base.flags &= ~IPCORK_ALLFRAG;
        }
-       memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
+       memset(&cork->fl, 0, sizeof(cork->fl));
 }
 
 int ip6_push_pending_frames(struct sock *sk)
        }
 
 out:
-       ip6_cork_release(inet, np);
+       ip6_cork_release(&inet->cork, &np->cork);
        return err;
 error:
        IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
                kfree_skb(skb);
        }
 
-       ip6_cork_release(inet_sk(sk), inet6_sk(sk));
+       ip6_cork_release(&inet_sk(sk)->cork, &inet6_sk(sk)->cork);
 }
 EXPORT_SYMBOL_GPL(ip6_flush_pending_frames);