netfilter: conntrack: avoid using ->error callback if possible
[linux-2.6-block.git] / net / netfilter / nf_conntrack_proto_dccp.c
index fdea305c7aa599d147838b788b333ae634241375..1b9e600f707db591949cd6df09513ee38c19d81f 100644 (file)
@@ -435,6 +435,48 @@ static u64 dccp_ack_seq(const struct dccp_hdr *dh)
                     ntohl(dhack->dccph_ack_nr_low);
 }
 
+static bool dccp_error(const struct dccp_hdr *dh,
+                      struct sk_buff *skb, unsigned int dataoff,
+                      const struct nf_hook_state *state)
+{
+       unsigned int dccp_len = skb->len - dataoff;
+       unsigned int cscov;
+       const char *msg;
+
+       if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
+           dh->dccph_doff * 4 > dccp_len) {
+               msg = "nf_ct_dccp: truncated/malformed packet ";
+               goto out_invalid;
+       }
+
+       cscov = dccp_len;
+       if (dh->dccph_cscov) {
+               cscov = (dh->dccph_cscov - 1) * 4;
+               if (cscov > dccp_len) {
+                       msg = "nf_ct_dccp: bad checksum coverage ";
+                       goto out_invalid;
+               }
+       }
+
+       if (state->hook == NF_INET_PRE_ROUTING &&
+           state->net->ct.sysctl_checksum &&
+           nf_checksum_partial(skb, state->hook, dataoff, cscov,
+                               IPPROTO_DCCP, state->pf)) {
+               msg = "nf_ct_dccp: bad checksum ";
+               goto out_invalid;
+       }
+
+       if (dh->dccph_type >= DCCP_PKT_INVALID) {
+               msg = "nf_ct_dccp: reserved packet type ";
+               goto out_invalid;
+       }
+       return false;
+out_invalid:
+       nf_l4proto_log_invalid(skb, state->net, state->pf,
+                              IPPROTO_DCCP, "%s", msg);
+       return true;
+}
+
 static int dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
                       unsigned int dataoff, enum ip_conntrack_info ctinfo,
                       const struct nf_hook_state *state)
@@ -449,6 +491,9 @@ static int dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
        if (!dh)
                return NF_DROP;
 
+       if (dccp_error(dh, skb, dataoff, state))
+               return -NF_ACCEPT;
+
        type = dh->dccph_type;
        if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh))
                return -NF_ACCEPT;
@@ -529,57 +574,6 @@ static int dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
        return NF_ACCEPT;
 }
 
-static int dccp_error(struct nf_conn *tmpl,
-                     struct sk_buff *skb, unsigned int dataoff,
-                     const struct nf_hook_state *state)
-{
-       struct dccp_hdr _dh, *dh;
-       unsigned int dccp_len = skb->len - dataoff;
-       unsigned int cscov;
-       const char *msg;
-
-       dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
-       if (dh == NULL) {
-               msg = "nf_ct_dccp: short packet ";
-               goto out_invalid;
-       }
-
-       if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
-           dh->dccph_doff * 4 > dccp_len) {
-               msg = "nf_ct_dccp: truncated/malformed packet ";
-               goto out_invalid;
-       }
-
-       cscov = dccp_len;
-       if (dh->dccph_cscov) {
-               cscov = (dh->dccph_cscov - 1) * 4;
-               if (cscov > dccp_len) {
-                       msg = "nf_ct_dccp: bad checksum coverage ";
-                       goto out_invalid;
-               }
-       }
-
-       if (state->hook == NF_INET_PRE_ROUTING &&
-           state->net->ct.sysctl_checksum &&
-           nf_checksum_partial(skb, state->hook, dataoff, cscov,
-                               IPPROTO_DCCP, state->pf)) {
-               msg = "nf_ct_dccp: bad checksum ";
-               goto out_invalid;
-       }
-
-       if (dh->dccph_type >= DCCP_PKT_INVALID) {
-               msg = "nf_ct_dccp: reserved packet type ";
-               goto out_invalid;
-       }
-
-       return NF_ACCEPT;
-
-out_invalid:
-       nf_l4proto_log_invalid(skb, state->net, state->pf,
-                              IPPROTO_DCCP, "%s", msg);
-       return -NF_ACCEPT;
-}
-
 static bool dccp_can_early_drop(const struct nf_conn *ct)
 {
        switch (ct->proto.dccp.state) {
@@ -852,7 +846,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 = {
        .l3proto                = AF_INET,
        .l4proto                = IPPROTO_DCCP,
        .packet                 = dccp_packet,
-       .error                  = dccp_error,
        .can_early_drop         = dccp_can_early_drop,
 #ifdef CONFIG_NF_CONNTRACK_PROCFS
        .print_conntrack        = dccp_print_conntrack,
@@ -884,7 +877,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 = {
        .l3proto                = AF_INET6,
        .l4proto                = IPPROTO_DCCP,
        .packet                 = dccp_packet,
-       .error                  = dccp_error,
        .can_early_drop         = dccp_can_early_drop,
 #ifdef CONFIG_NF_CONNTRACK_PROCFS
        .print_conntrack        = dccp_print_conntrack,