net: compat_mmsghdr must be used in sys_recvmmsg
[safe/jmp/linux-2.6] / net / netfilter / nf_conntrack_proto_udplite.c
index 7e116d5..0badedc 100644 (file)
 #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;
 
-static int udplite_pkt_to_tuple(const struct sk_buff *skb,
-                               unsigned int dataoff,
-                               struct nf_conntrack_tuple *tuple)
+static bool 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)
-               return 0;
+               return false;
 
        tuple->src.u.udp.port = hp->source;
        tuple->dst.u.udp.port = hp->dest;
-       return 1;
+       return true;
 }
 
-static int udplite_invert_tuple(struct nf_conntrack_tuple *tuple,
-                               const struct nf_conntrack_tuple *orig)
+static bool udplite_invert_tuple(struct nf_conntrack_tuple *tuple,
+                                const struct nf_conntrack_tuple *orig)
 {
        tuple->src.u.udp.port = orig->dst.u.udp.port;
        tuple->dst.u.udp.port = orig->src.u.udp.port;
-       return 1;
+       return true;
 }
 
 /* Print out the per-protocol part of the tuple. */
@@ -58,56 +60,51 @@ 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,
-                         int pf,
+                         u_int8_t pf,
                          unsigned int hooknum)
 {
        /* 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))
-                       nf_conntrack_event_cache(IPCT_STATUS, skb);
+               if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
+                       nf_conntrack_event_cache(IPCT_STATUS, ct);
        } 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,
-                      unsigned int dataoff)
+static bool udplite_new(struct nf_conn *ct, const struct sk_buff *skb,
+                       unsigned int dataoff)
 {
-       return 1;
+       return true;
 }
 
-static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
+static int udplite_error(struct net *net,
+                        struct sk_buff *skb,
+                        unsigned int dataoff,
                         enum ip_conntrack_info *ctinfo,
-                        int pf,
+                        u_int8_t pf,
                         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? */
        hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
        if (hdr == NULL) {
-               if (LOG_INVALID(IPPROTO_UDPLITE))
+               if (LOG_INVALID(net, IPPROTO_UDPLITE))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                      "nf_ct_udplite: short packet ");
                return -NF_ACCEPT;
@@ -117,7 +114,7 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
        if (cscov == 0)
                cscov = udplen;
        else if (cscov < sizeof(*hdr) || cscov > udplen) {
-               if (LOG_INVALID(IPPROTO_UDPLITE))
+               if (LOG_INVALID(net, IPPROTO_UDPLITE))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                "nf_ct_udplite: invalid checksum coverage ");
                return -NF_ACCEPT;
@@ -125,39 +122,20 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
 
        /* UDPLITE mandates checksums */
        if (!hdr->check) {
-               if (LOG_INVALID(IPPROTO_UDPLITE))
+               if (LOG_INVALID(net, IPPROTO_UDPLITE))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                      "nf_ct_udplite: checksum missing ");
                return -NF_ACCEPT;
        }
 
        /* Checksum invalid? Ignore. */
-       if (nf_conntrack_checksum && !skb_csum_unnecessary(skb) &&
-           hooknum == NF_INET_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 (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
+           nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP,
+                               pf)) {
+               if (LOG_INVALID(net, IPPROTO_UDPLITE))
+                       nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+                                     "nf_ct_udplite: bad UDPLite checksum ");
+               return -NF_ACCEPT;
        }
 
        return NF_ACCEPT;
@@ -173,7 +151,7 @@ static struct ctl_table udplite_sysctl_table[] = {
                .data           = &nf_ct_udplite_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -181,7 +159,7 @@ static struct ctl_table udplite_sysctl_table[] = {
                .data           = &nf_ct_udplite_timeout_stream,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = 0
@@ -197,12 +175,12 @@ 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_nlattr        = nf_ct_port_tuple_to_nlattr,
+       .nlattr_tuple_size      = nf_ct_port_nlattr_tuple_size,
        .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
        .nla_policy             = nf_ct_port_nla_policy,
 #endif
@@ -221,12 +199,12 @@ 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_nlattr        = nf_ct_port_tuple_to_nlattr,
+       .nlattr_tuple_size      = nf_ct_port_nlattr_tuple_size,
        .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
        .nla_policy             = nf_ct_port_nla_policy,
 #endif