From: Arne Fitzenreiter Date: Sun, 12 Mar 2017 13:33:26 +0000 (+0100) Subject: netfilter: layer7 use own packet counter X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cdfa736f510d9380250563f016261d5bbe91ff1b;p=people%2Farne_f%2Fkernel.git netfilter: layer7 use own packet counter 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 --- diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 4ef9f9dea2bb8..55655f5ee4f21 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -130,6 +130,7 @@ struct nf_conn { */ char *app_data; unsigned int app_data_len; + unsigned int packets; } layer7; #endif diff --git a/net/netfilter/xt_layer7.c b/net/netfilter/xt_layer7.c index da421c5f8eeea..80460130083a3 100644 --- a/net/netfilter/xt_layer7.c +++ b/net/netfilter/xt_layer7.c @@ -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)){