netfilter: net/ipv[46]/netfilter: Move && and || to end of previous line
[safe/jmp/linux-2.6] / net / ipv4 / netfilter / nf_conntrack_proto_icmp.c
index 9779104..e3dd936 100644 (file)
@@ -20,7 +20,7 @@
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_log.h>
 
-static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ;
+static unsigned int nf_ct_icmp_timeout __read_mostly = 30*HZ;
 
 static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
                              struct nf_conntrack_tuple *tuple)
@@ -54,8 +54,8 @@ static const u_int8_t invmap[] = {
 static bool icmp_invert_tuple(struct nf_conntrack_tuple *tuple,
                              const struct nf_conntrack_tuple *orig)
 {
-       if (orig->dst.u.icmp.type >= sizeof(invmap)
-           || !invmap[orig->dst.u.icmp.type])
+       if (orig->dst.u.icmp.type >= sizeof(invmap) ||
+           !invmap[orig->dst.u.icmp.type])
                return false;
 
        tuple->src.u.icmp.id = orig->src.u.icmp.id;
@@ -79,21 +79,13 @@ static int icmp_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)
 {
-       /* Try to delete connection immediately after all replies:
-          won't actually vanish as we still have skb, and del_timer
-          means this will only run once even if count hits zero twice
-          (theoretically possible with SMP) */
-       if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
-               if (atomic_dec_and_test(&ct->proto.icmp.count))
-                       nf_ct_kill_acct(ct, ctinfo, skb);
-       } else {
-               atomic_inc(&ct->proto.icmp.count);
-               nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
-               nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
-       }
+       /* Do not immediately delete the connection after the first
+          successful reply to avoid excessive conntrackd traffic
+          and also to handle correctly ICMP echo reply duplicates. */
+       nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
 
        return NF_ACCEPT;
 }
@@ -109,21 +101,20 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
                [ICMP_ADDRESS] = 1
        };
 
-       if (ct->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
-           || !valid_new[ct->tuplehash[0].tuple.dst.u.icmp.type]) {
+       if (ct->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) ||
+           !valid_new[ct->tuplehash[0].tuple.dst.u.icmp.type]) {
                /* Can't create a new ICMP `conn' with this. */
                pr_debug("icmp: can't create new conn with type %u\n",
                         ct->tuplehash[0].tuple.dst.u.icmp.type);
                nf_ct_dump_tuple_ip(&ct->tuplehash[0].tuple);
                return false;
        }
-       atomic_set(&ct->proto.icmp.count, 0);
        return true;
 }
 
 /* Returns conntrack if it dealt with ICMP, and filled in skb fields */
 static int
-icmp_error_message(struct sk_buff *skb,
+icmp_error_message(struct net *net, struct sk_buff *skb,
                 enum ip_conntrack_info *ctinfo,
                 unsigned int hooknum)
 {
@@ -155,7 +146,7 @@ icmp_error_message(struct sk_buff *skb,
 
        *ctinfo = IP_CT_RELATED;
 
-       h = nf_conntrack_find_get(&innertuple);
+       h = nf_conntrack_find_get(net, &innertuple);
        if (!h) {
                pr_debug("icmp_error_message: no match\n");
                return -NF_ACCEPT;
@@ -172,8 +163,8 @@ icmp_error_message(struct sk_buff *skb,
 
 /* Small and modified version of icmp_rcv */
 static int
-icmp_error(struct sk_buff *skb, unsigned int dataoff,
-          enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
+icmp_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
+          enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
 {
        const struct icmphdr *icmph;
        struct icmphdr _ih;
@@ -181,16 +172,16 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
        /* Not enough header? */
        icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih);
        if (icmph == NULL) {
-               if (LOG_INVALID(IPPROTO_ICMP))
+               if (LOG_INVALID(net, IPPROTO_ICMP))
                        nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
                                      "nf_ct_icmp: short packet ");
                return -NF_ACCEPT;
        }
 
        /* See ip_conntrack_proto_tcp.c */
-       if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
+       if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
            nf_ip_checksum(skb, hooknum, dataoff, 0)) {
-               if (LOG_INVALID(IPPROTO_ICMP))
+               if (LOG_INVALID(net, IPPROTO_ICMP))
                        nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
                                      "nf_ct_icmp: bad HW ICMP checksum ");
                return -NF_ACCEPT;
@@ -203,21 +194,21 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
         *                discarded.
         */
        if (icmph->type > NR_ICMP_TYPES) {
-               if (LOG_INVALID(IPPROTO_ICMP))
+               if (LOG_INVALID(net, IPPROTO_ICMP))
                        nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
                                      "nf_ct_icmp: invalid ICMP type ");
                return -NF_ACCEPT;
        }
 
        /* Need to track icmp error message? */
-       if (icmph->type != ICMP_DEST_UNREACH
-           && icmph->type != ICMP_SOURCE_QUENCH
-           && icmph->type != ICMP_TIME_EXCEEDED
-           && icmph->type != ICMP_PARAMETERPROB
-           && icmph->type != ICMP_REDIRECT)
+       if (icmph->type != ICMP_DEST_UNREACH &&
+           icmph->type != ICMP_SOURCE_QUENCH &&
+           icmph->type != ICMP_TIME_EXCEEDED &&
+           icmph->type != ICMP_PARAMETERPROB &&
+           icmph->type != ICMP_REDIRECT)
                return NF_ACCEPT;
 
-       return icmp_error_message(skb, ctinfo, hooknum);
+       return icmp_error_message(net, skb, ctinfo, hooknum);
 }
 
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
@@ -247,21 +238,26 @@ static const struct nla_policy icmp_nla_policy[CTA_PROTO_MAX+1] = {
 static int icmp_nlattr_to_tuple(struct nlattr *tb[],
                                struct nf_conntrack_tuple *tuple)
 {
-       if (!tb[CTA_PROTO_ICMP_TYPE]
-           || !tb[CTA_PROTO_ICMP_CODE]
-           || !tb[CTA_PROTO_ICMP_ID])
+       if (!tb[CTA_PROTO_ICMP_TYPE] ||
+           !tb[CTA_PROTO_ICMP_CODE] ||
+           !tb[CTA_PROTO_ICMP_ID])
                return -EINVAL;
 
        tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]);
        tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMP_CODE]);
        tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMP_ID]);
 
-       if (tuple->dst.u.icmp.type >= sizeof(invmap)
-           || !invmap[tuple->dst.u.icmp.type])
+       if (tuple->dst.u.icmp.type >= sizeof(invmap) ||
+           !invmap[tuple->dst.u.icmp.type])
                return -EINVAL;
 
        return 0;
 }
+
+static int icmp_nlattr_tuple_size(void)
+{
+       return nla_policy_len(icmp_nla_policy, CTA_PROTO_MAX + 1);
+}
 #endif
 
 #ifdef CONFIG_SYSCTL
@@ -272,7 +268,7 @@ static struct ctl_table icmp_sysctl_table[] = {
                .data           = &nf_ct_icmp_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name = 0
@@ -285,7 +281,7 @@ static struct ctl_table icmp_compat_sysctl_table[] = {
                .data           = &nf_ct_icmp_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name = 0
@@ -309,6 +305,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly =
        .me                     = NULL,
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
        .tuple_to_nlattr        = icmp_tuple_to_nlattr,
+       .nlattr_tuple_size      = icmp_nlattr_tuple_size,
        .nlattr_to_tuple        = icmp_nlattr_to_tuple,
        .nla_policy             = icmp_nla_policy,
 #endif