]> git.ipfire.org Git - people/arne_f/kernel.git/commitdiff
netfilter: layer7 use own packet counter
authorArne Fitzenreiter <arne_f@ipfire.org>
Sun, 12 Mar 2017 13:33:26 +0000 (14:33 +0100)
committerArne Fitzenreiter <arne_f@ipfire.org>
Mon, 13 Nov 2017 06:26:12 +0000 (07:26 +0100)
sometimes ct has already seen more packets than the handled to
the layer7 match and the detection was skipped too early.

Signed-off-by: Arne Fitzenreiter <arne_f@ipfire.org>
include/net/netfilter/nf_conntrack.h
net/netfilter/xt_layer7.c

index 7a6e29fb6b59aa65824902aab2fc794a10e063b1..f24a6ac8fe9d243bf09f02b425ca94332b689de9 100644 (file)
@@ -109,6 +109,7 @@ struct nf_conn {
                 */
                char *app_data;
                unsigned int app_data_len;
+               unsigned int packets;
        } layer7;
 #endif
 
index da421c5f8eeea6aa9f855f488984c2e246923cd1..80460130083a3e8f17410ef8c132f39a202c622e 100644 (file)
@@ -68,22 +68,6 @@ static struct proto_cache {
 
 DEFINE_SPINLOCK(l7_lock);
 
-static int total_acct_packets(struct nf_conn *ct)
-{
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
-       BUG_ON(ct == NULL);
-       return (ct->counters[IP_CT_DIR_ORIGINAL].packets + ct->counters[IP_CT_DIR_REPLY].packets);
-#else
-       struct nf_conn_counter *acct;
-
-       BUG_ON(ct == NULL);
-       acct = nf_conn_acct_find(ct);
-       if (!acct)
-               return 0;
-        return (atomic64_read(&acct[IP_CT_DIR_ORIGINAL].packets) + atomic64_read(&acct[IP_CT_DIR_REPLY].packets));
-#endif
-}
-
 #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
 /* Converts an unfriendly string into a friendly one by
 replacing unprintables with periods and all whitespace with " ". */
@@ -320,7 +304,7 @@ static int match_no_append(struct nf_conn * conntrack,
                          hex_print(master_conntrack->layer7.app_data);
                        DPRINTK("\nl7-filter gave up after %d bytes "
                                "(%d packets):\n%s\n",
-                               strlen(f), total_acct_packets(master_conntrack), f);
+                               strlen(f), master_conntrack->layer7.packets, f);
                        kfree(f);
                        DPRINTK("In hex: %s\n", g);
                        kfree(g);
@@ -492,7 +476,7 @@ match(const struct sk_buff *skbin,
        }
 
        /* if we've classified it or seen too many packets */
-       if(total_acct_packets(master_conntrack) > num_packets ||
+       if( master_conntrack->layer7.packets >= num_packets ||
           master_conntrack->layer7.app_proto) {
 
                pattern_result = match_no_append(conntrack, master_conntrack, 
@@ -521,8 +505,8 @@ match(const struct sk_buff *skbin,
        /* the return value gets checked later, when we're ready to use it */
        comppattern = compile_and_cache(info->pattern, info->protocol);
 
-       /* On the first packet of a connection, allocate space for app data */
-       if(total_acct_packets(master_conntrack) == 1 && !skb->layer7_flags[0] && 
+       /* allocate space for app data if not done */
+       if(master_conntrack->packets < num_packets && 
           !master_conntrack->layer7.app_data){
                master_conntrack->layer7.app_data = 
                        kmalloc(maxdatalen, GFP_ATOMIC);
@@ -537,15 +521,9 @@ match(const struct sk_buff *skbin,
                master_conntrack->layer7.app_data[0] = '\0';
        }
 
-       /* Can be here, but unallocated, if numpackets is increased near
-       the beginning of a connection */
-       if(master_conntrack->layer7.app_data == NULL){
-               spin_unlock_bh(&l7_lock);
-               return info->invert; /* unmatched */
-       }
-
        if(!skb->layer7_flags[0]){
                int newbytes;
+               master_conntrack->layer7.packets++;
                newbytes = add_data(master_conntrack, app_data, appdatalen);
                if(newbytes == 0) { /* didn't add any data */
                        skb->layer7_flags[0] = 1;
@@ -565,7 +543,7 @@ match(const struct sk_buff *skbin,
                pattern_result = 2;
                DPRINTK("layer7: matched unset: not yet classified "
                        "(%d/%d packets)\n",
-                        total_acct_packets(master_conntrack), num_packets);
+                        master_conntrack->layer7.packets, num_packets);
        /* If the regexp failed to compile, don't bother running it */
        } else if(comppattern && 
                  regexec(comppattern, master_conntrack->layer7.app_data)){