IP_DEFRAG_CALL_RA_CHAIN,
        IP_DEFRAG_CONNTRACK_IN,
        IP_DEFRAG_CONNTRACK_OUT,
-       IP_DEFRAG_NAT_OUT,
        IP_DEFRAG_VS_IN,
        IP_DEFRAG_VS_OUT,
        IP_DEFRAG_VS_FWD
 
 
 static inline int ip_finish_output(struct sk_buff *skb)
 {
-       struct net_device *dev = skb->dst->dev;
-
-       skb->dev = dev;
-       skb->protocol = htons(ETH_P_IP);
-
-       return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
-                      ip_finish_output2);
+       if (skb->len > dst_mtu(skb->dst) &&
+           !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
+               return ip_fragment(skb, ip_finish_output2);
+       else
+               return ip_finish_output2(skb);
 }
 
 int ip_mc_output(struct sk_buff *skb)
                                newskb->dev, ip_dev_loopback_xmit);
        }
 
-       if (skb->len > dst_mtu(&rt->u.dst))
-               return ip_fragment(skb, ip_finish_output);
-       else
-               return ip_finish_output(skb);
+       return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev,
+                      ip_finish_output);
 }
 
 int ip_output(struct sk_buff *skb)
 {
+       struct net_device *dev = skb->dst->dev;
+
        IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
 
-       if (skb->len > dst_mtu(skb->dst) &&
-               !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
-               return ip_fragment(skb, ip_finish_output);
-       else
-               return ip_finish_output(skb);
+       skb->dev = dev;
+       skb->protocol = htons(ETH_P_IP);
+
+       return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
+                      ip_finish_output);
 }
 
 int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
 
        return NF_ACCEPT;
 }
 
-static unsigned int ip_refrag(unsigned int hooknum,
-                             struct sk_buff **pskb,
-                             const struct net_device *in,
-                             const struct net_device *out,
-                             int (*okfn)(struct sk_buff *))
-{
-       struct rtable *rt = (struct rtable *)(*pskb)->dst;
-
-       /* We've seen it coming out the other side: confirm */
-       if (ip_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
-               return NF_DROP;
-
-       /* Local packets are never produced too large for their
-          interface.  We degfragment them at LOCAL_OUT, however,
-          so we have to refragment them here. */
-       if ((*pskb)->len > dst_mtu(&rt->u.dst) &&
-           !skb_shinfo(*pskb)->tso_size) {
-               /* No hook can be after us, so this should be OK. */
-               ip_fragment(*pskb, okfn);
-               return NF_STOLEN;
-       }
-       return NF_ACCEPT;
-}
-
 static unsigned int ip_conntrack_local(unsigned int hooknum,
                                       struct sk_buff **pskb,
                                       const struct net_device *in,
 
 /* Refragmenter; last chance. */
 static struct nf_hook_ops ip_conntrack_out_ops = {
-       .hook           = ip_refrag,
+       .hook           = ip_confirm,
        .owner          = THIS_MODULE,
        .pf             = PF_INET,
        .hooknum        = NF_IP_POST_ROUTING,
 
            || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
                return NF_ACCEPT;
 
-       /* We can hit fragment here; forwarded packets get
-          defragmented by connection tracking coming in, then
-          fragmented (grr) by the forward code.
-
-          In future: If we have nfct != NULL, AND we have NAT
-          initialized, AND there is no helper, then we can do full
-          NAPT on the head, and IP-address-only NAT on the rest.
-
-          I'm starting to have nightmares about fragments.  */
-
-       if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
-               *pskb = ip_ct_gather_frags(*pskb, IP_DEFRAG_NAT_OUT);
-
-               if (!*pskb)
-                       return NF_STOLEN;
-       }
-
        return ip_nat_fn(hooknum, pskb, in, out, okfn);
 }
 
 
        return NF_ACCEPT;
 }
 
-static unsigned int ipv4_refrag(unsigned int hooknum,
-                               struct sk_buff **pskb,
-                               const struct net_device *in,
-                               const struct net_device *out,
-                               int (*okfn)(struct sk_buff *))
-{
-       struct rtable *rt = (struct rtable *)(*pskb)->dst;
-
-       /* We've seen it coming out the other side: confirm */
-       if (ipv4_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
-               return NF_DROP;
-
-       /* Local packets are never produced too large for their
-          interface.  We degfragment them at LOCAL_OUT, however,
-          so we have to refragment them here. */
-       if ((*pskb)->len > dst_mtu(&rt->u.dst) &&
-           !skb_shinfo(*pskb)->tso_size) {
-               /* No hook can be after us, so this should be OK. */
-               ip_fragment(*pskb, okfn);
-               return NF_STOLEN;
-       }
-       return NF_ACCEPT;
-}
-
 static unsigned int ipv4_conntrack_in(unsigned int hooknum,
                                      struct sk_buff **pskb,
                                      const struct net_device *in,
 
 /* Refragmenter; last chance. */
 static struct nf_hook_ops ipv4_conntrack_out_ops = {
-       .hook           = ipv4_refrag,
+       .hook           = ipv4_confirm,
        .owner          = THIS_MODULE,
        .pf             = PF_INET,
        .hooknum        = NF_IP_POST_ROUTING,