}
 
        /* See ip_conntrack_proto_tcp.c */
-       if (hooknum != NF_IP_PRE_ROUTING)
-               goto checksum_skipped;
-
-       switch (skb->ip_summed) {
-       case CHECKSUM_HW:
-               if (!(u16)csum_fold(skb->csum)) 
-                       break;
-               /* fall through */
-       case CHECKSUM_NONE:
-               skb->csum = 0;
-               if (__skb_checksum_complete(skb)) {
-                       if (LOG_INVALID(IPPROTO_ICMP))
-                               nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
-                                             "ip_ct_icmp: bad ICMP checksum ");
-                       return -NF_ACCEPT;
-               }
+       if (hooknum == NF_IP_PRE_ROUTING &&
+           nf_ip_checksum(skb, hooknum, skb->nh.iph->ihl * 4, 0)) {
+               if (LOG_INVALID(IPPROTO_ICMP))
+                       nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
+                                     "ip_ct_icmp: bad ICMP checksum ");
+               return -NF_ACCEPT;
        }
 
-checksum_skipped:
        /*
         *      18 is the highest 'known' ICMP type. Anything else is a mystery
         *
 
         * and moreover root might send raw packets.
         */
        /* FIXME: Source route IP option packets --RR */
-       if (hooknum == NF_IP_PRE_ROUTING
-           && skb->ip_summed != CHECKSUM_UNNECESSARY
-           && csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP,
-                                skb->ip_summed == CHECKSUM_HW ? skb->csum
-                                : skb_checksum(skb, iph->ihl*4, tcplen, 0))) {
+       if (hooknum == NF_IP_PRE_ROUTING &&
+           nf_ip_checksum(skb, hooknum, iph->ihl * 4, IPPROTO_TCP)) {
                if (LOG_INVALID(IPPROTO_TCP))
                        nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
                                  "ip_ct_tcp: bad TCP checksum ");
 
         * because the semantic of CHECKSUM_HW is different there 
         * and moreover root might send raw packets.
         * FIXME: Source route IP option packets --RR */
-       if (hooknum == NF_IP_PRE_ROUTING
-           && skb->ip_summed != CHECKSUM_UNNECESSARY
-           && csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP,
-                                skb->ip_summed == CHECKSUM_HW ? skb->csum
-                                : skb_checksum(skb, iph->ihl*4, udplen, 0))) {
+       if (hooknum == NF_IP_PRE_ROUTING &&
+           nf_ip_checksum(skb, hooknum, iph->ihl * 4, IPPROTO_UDP)) {
                if (LOG_INVALID(IPPROTO_UDP))
                        nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
                                  "ip_ct_udp: bad UDP checksum ");
 
        struct rtable *rt;
        u_int16_t tmp_port;
        u_int32_t tmp_addr;
-       unsigned int tcplen;
        int needs_ack;
        int hh_len;
 
                return;
 
        /* Check checksum */
-       tcplen = oldskb->len - iph->ihl * 4;
-       if (((hook != NF_IP_LOCAL_IN && oldskb->ip_summed != CHECKSUM_HW) ||
-            (hook == NF_IP_LOCAL_IN &&
-             oldskb->ip_summed != CHECKSUM_UNNECESSARY)) &&
-           csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP,
-                             oldskb->ip_summed == CHECKSUM_HW ? oldskb->csum :
-                             skb_checksum(oldskb, iph->ihl * 4, tcplen, 0)))
+       if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP))
                return;
 
        if ((rt = route_reverse(oldskb, oth, hook)) == NULL)
 
        }
 
        /* See ip_conntrack_proto_tcp.c */
-       if (hooknum != NF_IP_PRE_ROUTING)
-               goto checksum_skipped;
-
-       switch (skb->ip_summed) {
-       case CHECKSUM_HW:
-               if (!(u16)csum_fold(skb->csum))
-                       break;
+       if (hooknum == NF_IP_PRE_ROUTING &&
+           nf_ip_checksum(skb, hooknum, dataoff, 0)) {
                if (LOG_INVALID(IPPROTO_ICMP))
                        nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
                                      "nf_ct_icmp: bad HW ICMP checksum ");
                return -NF_ACCEPT;
-       case CHECKSUM_NONE:
-               if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) {
-                       if (LOG_INVALID(IPPROTO_ICMP))
-                               nf_log_packet(PF_INET, 0, skb, NULL, NULL,
-                                             NULL,
-                                             "nf_ct_icmp: bad ICMP checksum ");
-                       return -NF_ACCEPT;
-               }
-       default:
-               break;
        }
 
-checksum_skipped:
        /*
         *      18 is the highest 'known' ICMP type. Anything else is a mystery
         *
 
                return -NF_ACCEPT;
        }
 
-       if (hooknum != NF_IP6_PRE_ROUTING)
-               goto skipped;
-
-       /* Ignore it if the checksum's bogus. */
-       if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
-                           skb->len - dataoff, IPPROTO_ICMPV6,
-                           skb_checksum(skb, dataoff,
-                                        skb->len - dataoff, 0))) {
+       if (hooknum == NF_IP6_PRE_ROUTING &&
+           nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
                nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
                              "nf_ct_icmpv6: ICMPv6 checksum failed\n");
                return -NF_ACCEPT;
        }
 
-skipped:
-
        /* is not error message ? */
        if (icmp6h->icmp6_type >= 128)
                return NF_ACCEPT;
 
                     unsigned int dataoff,
                     enum ip_conntrack_info *ctinfo,
                     int pf,
-                    unsigned int hooknum,
-                    int(*csum)(const struct sk_buff *,unsigned int))
+                    unsigned int hooknum)
 {
        struct tcphdr _tcph, *th;
        unsigned int tcplen = skb->len - dataoff;
         */
        /* FIXME: Source route IP option packets --RR */
        if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
-            (pf == PF_INET6 && hooknum  == NF_IP6_PRE_ROUTING))
-           && skb->ip_summed != CHECKSUM_UNNECESSARY
-           && csum(skb, dataoff)) {
+            (pf == PF_INET6 && hooknum  == NF_IP6_PRE_ROUTING)) &&
+           nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) {
                if (LOG_INVALID(IPPROTO_TCP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                  "nf_ct_tcp: bad TCP checksum ");
        return NF_ACCEPT;
 }
 
-static int csum4(const struct sk_buff *skb, unsigned int dataoff)
-{
-       return csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr,
-                                skb->len - dataoff, IPPROTO_TCP,
-                                skb->ip_summed == CHECKSUM_HW ? skb->csum
-                                : skb_checksum(skb, dataoff,
-                                               skb->len - dataoff, 0));
-}
-
-static int csum6(const struct sk_buff *skb, unsigned int dataoff)
-{
-       return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
-                              skb->len - dataoff, IPPROTO_TCP,
-                              skb->ip_summed == CHECKSUM_HW
-                              ? csum_sub(skb->csum,
-                                         skb_checksum(skb, 0, dataoff, 0))
-                              : skb_checksum(skb, dataoff, skb->len - dataoff,
-                                             0));
-}
-
-static int tcp_error4(struct sk_buff *skb,
-                     unsigned int dataoff,
-                     enum ip_conntrack_info *ctinfo,
-                     int pf,
-                     unsigned int hooknum)
-{
-       return tcp_error(skb, dataoff, ctinfo, pf, hooknum, csum4);
-}
-
-static int tcp_error6(struct sk_buff *skb,
-                     unsigned int dataoff,
-                     enum ip_conntrack_info *ctinfo,
-                     int pf,
-                     unsigned int hooknum)
-{
-       return tcp_error(skb, dataoff, ctinfo, pf, hooknum, csum6);
-}
-
 /* Returns verdict for packet, or -1 for invalid. */
 static int tcp_packet(struct nf_conn *conntrack,
                      const struct sk_buff *skb,
        .print_conntrack        = tcp_print_conntrack,
        .packet                 = tcp_packet,
        .new                    = tcp_new,
-       .error                  = tcp_error4,
+       .error                  = tcp_error,
 #if defined(CONFIG_NF_CT_NETLINK) || \
     defined(CONFIG_NF_CT_NETLINK_MODULE)
        .to_nfattr              = tcp_to_nfattr,
        .print_conntrack        = tcp_print_conntrack,
        .packet                 = tcp_packet,
        .new                    = tcp_new,
-       .error                  = tcp_error6,
+       .error                  = tcp_error,
 #if defined(CONFIG_NF_CT_NETLINK) || \
     defined(CONFIG_NF_CT_NETLINK_MODULE)
        .to_nfattr              = tcp_to_nfattr,
 
 static int udp_error(struct sk_buff *skb, unsigned int dataoff,
                     enum ip_conntrack_info *ctinfo,
                     int pf,
-                    unsigned int hooknum,
-                    int (*csum)(const struct sk_buff *, unsigned int))
+                    unsigned int hooknum)
 {
        unsigned int udplen = skb->len - dataoff;
        struct udphdr _hdr, *hdr;
         * and moreover root might send raw packets.
         * FIXME: Source route IP option packets --RR */
        if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
-            (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING))
-           && skb->ip_summed != CHECKSUM_UNNECESSARY
-           && csum(skb, dataoff)) {
+            (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING)) &&
+           nf_checksum(skb, hooknum, dataoff, IPPROTO_UDP, pf)) {
                if (LOG_INVALID(IPPROTO_UDP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                "nf_ct_udp: bad UDP checksum ");
        return NF_ACCEPT;
 }
 
-static int csum4(const struct sk_buff *skb, unsigned int dataoff)
-{
-       return csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr,
-                                skb->len - dataoff, IPPROTO_UDP,
-                                skb->ip_summed == CHECKSUM_HW ? skb->csum
-                                : skb_checksum(skb, dataoff,
-                                               skb->len - dataoff, 0));
-}
-
-static int csum6(const struct sk_buff *skb, unsigned int dataoff)
-{
-       return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
-                              skb->len - dataoff, IPPROTO_UDP,
-                              skb->ip_summed == CHECKSUM_HW
-                              ? csum_sub(skb->csum,
-                                         skb_checksum(skb, 0, dataoff, 0))
-                              : skb_checksum(skb, dataoff, skb->len - dataoff,
-                                             0));
-}
-
-static int udp_error4(struct sk_buff *skb,
-                     unsigned int dataoff,
-                     enum ip_conntrack_info *ctinfo,
-                     int pf,
-                     unsigned int hooknum)
-{
-       return udp_error(skb, dataoff, ctinfo, pf, hooknum, csum4);
-}
-
-static int udp_error6(struct sk_buff *skb,
-                     unsigned int dataoff,
-                     enum ip_conntrack_info *ctinfo,
-                     int pf,
-                     unsigned int hooknum)
-{
-       return udp_error(skb, dataoff, ctinfo, pf, hooknum, csum6);
-}
-
 struct nf_conntrack_protocol nf_conntrack_protocol_udp4 =
 {
        .l3proto                = PF_INET,
        .print_conntrack        = udp_print_conntrack,
        .packet                 = udp_packet,
        .new                    = udp_new,
-       .error                  = udp_error4,
+       .error                  = udp_error,
 #if defined(CONFIG_NF_CT_NETLINK) || \
     defined(CONFIG_NF_CT_NETLINK_MODULE)
        .tuple_to_nfattr        = nf_ct_port_tuple_to_nfattr,
        .print_conntrack        = udp_print_conntrack,
        .packet                 = udp_packet,
        .new                    = udp_new,
-       .error                  = udp_error6,
+       .error                  = udp_error,
 #if defined(CONFIG_NF_CT_NETLINK) || \
     defined(CONFIG_NF_CT_NETLINK_MODULE)
        .tuple_to_nfattr        = nf_ct_port_tuple_to_nfattr,