]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/netfilter/nf_conntrack_proto_udplite.c
[NETFILTER]: Add partial checksum validation helper
[linux-2.6-omap-h63xx.git] / net / netfilter / nf_conntrack_proto_udplite.c
index b906b413997c8db589df41f97561c9e668aa9d93..c3eaee6afffd12d32819d7d58b3ba4d3a710a228 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/netfilter_ipv6.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
+#include <net/netfilter/nf_log.h>
 
 static unsigned int nf_ct_udplite_timeout __read_mostly = 30*HZ;
 static unsigned int nf_ct_udplite_timeout_stream __read_mostly = 180*HZ;
@@ -30,7 +31,8 @@ static int udplite_pkt_to_tuple(const struct sk_buff *skb,
                                unsigned int dataoff,
                                struct nf_conntrack_tuple *tuple)
 {
-       struct udphdr _hdr, *hp;
+       const struct udphdr *hp;
+       struct udphdr _hdr;
 
        hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
        if (hp == NULL)
@@ -58,15 +60,8 @@ static int udplite_print_tuple(struct seq_file *s,
                          ntohs(tuple->dst.u.udp.port));
 }
 
-/* Print out the private part of the conntrack. */
-static int udplite_print_conntrack(struct seq_file *s,
-                                  const struct nf_conn *conntrack)
-{
-       return 0;
-}
-
 /* Returns verdict for packet, and may modify conntracktype */
-static int udplite_packet(struct nf_conn *conntrack,
+static int udplite_packet(struct nf_conn *ct,
                          const struct sk_buff *skb,
                          unsigned int dataoff,
                          enum ip_conntrack_info ctinfo,
@@ -75,21 +70,20 @@ static int udplite_packet(struct nf_conn *conntrack,
 {
        /* If we've seen traffic both ways, this is some kind of UDP
           stream.  Extend timeout. */
-       if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
-               nf_ct_refresh_acct(conntrack, ctinfo, skb,
+       if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
+               nf_ct_refresh_acct(ct, ctinfo, skb,
                                   nf_ct_udplite_timeout_stream);
                /* Also, more likely to be important, and not a probe */
-               if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
+               if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
                        nf_conntrack_event_cache(IPCT_STATUS, skb);
        } else
-               nf_ct_refresh_acct(conntrack, ctinfo, skb,
-                                  nf_ct_udplite_timeout);
+               nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udplite_timeout);
 
        return NF_ACCEPT;
 }
 
 /* Called when a new connection for this protocol found. */
-static int udplite_new(struct nf_conn *conntrack, const struct sk_buff *skb,
+static int udplite_new(struct nf_conn *ct, const struct sk_buff *skb,
                       unsigned int dataoff)
 {
        return 1;
@@ -101,7 +95,8 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
                         unsigned int hooknum)
 {
        unsigned int udplen = skb->len - dataoff;
-       struct udphdr _hdr, *hdr;
+       const struct udphdr *hdr;
+       struct udphdr _hdr;
        unsigned int cscov;
 
        /* Header is too small? */
@@ -132,33 +127,13 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
        }
 
        /* Checksum invalid? Ignore. */
-       if (nf_conntrack_checksum && !skb_csum_unnecessary(skb) &&
-           ((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
-            (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING))) {
-               if (pf == PF_INET) {
-                       struct iphdr *iph = ip_hdr(skb);
-
-                       skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
-                                                      udplen, IPPROTO_UDPLITE, 0);
-               } else {
-                       struct ipv6hdr *ipv6h = ipv6_hdr(skb);
-                       __wsum hsum = skb_checksum(skb, 0, dataoff, 0);
-
-                       skb->csum = ~csum_unfold(
-                               csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
-                                               udplen, IPPROTO_UDPLITE,
-                                               csum_sub(0, hsum)));
-               }
-
-               skb->ip_summed = CHECKSUM_NONE;
-               if (__skb_checksum_complete_head(skb, dataoff + cscov)) {
-                       if (LOG_INVALID(IPPROTO_UDPLITE))
-                               nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
-                                             "nf_ct_udplite: bad UDPLite "
-                                             "checksum ");
-                       return -NF_ACCEPT;
-               }
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
+       if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
+           nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP,
+                               pf)) {
+               if (LOG_INVALID(IPPROTO_UDPLITE))
+                       nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+                                     "nf_ct_udplite: bad UDPLite checksum ");
+               return -NF_ACCEPT;
        }
 
        return NF_ACCEPT;
@@ -198,13 +173,13 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
        .pkt_to_tuple           = udplite_pkt_to_tuple,
        .invert_tuple           = udplite_invert_tuple,
        .print_tuple            = udplite_print_tuple,
-       .print_conntrack        = udplite_print_conntrack,
        .packet                 = udplite_packet,
        .new                    = udplite_new,
        .error                  = udplite_error,
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
-       .tuple_to_nfattr        = nf_ct_port_tuple_to_nfattr,
-       .nfattr_to_tuple        = nf_ct_port_nfattr_to_tuple,
+       .tuple_to_nlattr        = nf_ct_port_tuple_to_nlattr,
+       .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
+       .nla_policy             = nf_ct_port_nla_policy,
 #endif
 #ifdef CONFIG_SYSCTL
        .ctl_table_users        = &udplite_sysctl_table_users,
@@ -221,13 +196,13 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
        .pkt_to_tuple           = udplite_pkt_to_tuple,
        .invert_tuple           = udplite_invert_tuple,
        .print_tuple            = udplite_print_tuple,
-       .print_conntrack        = udplite_print_conntrack,
        .packet                 = udplite_packet,
        .new                    = udplite_new,
        .error                  = udplite_error,
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
-       .tuple_to_nfattr        = nf_ct_port_tuple_to_nfattr,
-       .nfattr_to_tuple        = nf_ct_port_nfattr_to_tuple,
+       .tuple_to_nlattr        = nf_ct_port_tuple_to_nlattr,
+       .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
+       .nla_policy             = nf_ct_port_nla_policy,
 #endif
 #ifdef CONFIG_SYSCTL
        .ctl_table_users        = &udplite_sysctl_table_users,