source: trunk/target/linux/generic-2.4/patches/610-netfilter_connbytes.patch @ 16144

Last change on this file since 16144 was 16144, checked in by florian, 8 years ago

[brcm-2.4] update to 2.4.37, tested on wrt54gs (#4766)

  • Property svn:eol-style set to native
File size: 15.9 KB
  • net/ipv4/netfilter/Config.in

    a b if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; 
    1111  dep_tristate '  Amanda protocol support' CONFIG_IP_NF_AMANDA $CONFIG_IP_NF_CONNTRACK 
    1212  dep_tristate '  TFTP protocol support' CONFIG_IP_NF_TFTP $CONFIG_IP_NF_CONNTRACK 
    1313  dep_tristate '  IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK 
     14  dep_tristate '  Connection tracking flow accounting' CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK 
     15  dep_tristate '  Connection byte counter support' CONFIG_IP_NF_MATCH_CONNBYTES $CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES 
    1416  dep_tristate '  GRE protocol support' CONFIG_IP_NF_CT_PROTO_GRE $CONFIG_IP_NF_CONNTRACK 
    1517  dep_tristate '   PPTP protocol support' CONFIG_IP_NF_PPTP $CONFIG_IP_NF_CT_PROTO_GRE 
    1618fi 
  • net/ipv4/netfilter/Makefile

    a b obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_ 
    106106obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o 
    107107obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o 
    108108obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o 
     109obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o 
    109110obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o 
    110111obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o 
    111112obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o 
  • net/ipv4/netfilter/ip_conntrack_amanda.c

    a b static int help(const struct iphdr *iph, 
    7575 
    7676        /* increase the UDP timeout of the master connection as replies from 
    7777         * Amanda clients to the server can be quite delayed */ 
    78         ip_ct_refresh(ct, master_timeout * HZ); 
     78        ip_ct_refresh_acct(ct,ctinfo,NULL, master_timeout * HZ); 
    7979         
    8080        /* Search for "CONNECT " string */ 
    8181        do { 
  • net/ipv4/netfilter/ip_conntrack_proto_tcp.c

    a b static int tcp_packet(struct ip_conntrac 
    211211                        set_bit(IPS_ASSURED_BIT, &conntrack->status); 
    212212 
    213213                WRITE_UNLOCK(&tcp_lock); 
    214                 ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]); 
     214                ip_ct_refresh_acct(conntrack,ctinfo,iph, *tcp_timeouts[newconntrack]); 
    215215        } 
    216216 
    217217        return NF_ACCEPT; 
  • net/ipv4/netfilter/ip_conntrack_proto_udp.c

    a b static unsigned int udp_print_conntrack( 
    4747/* Returns verdict for packet, and may modify conntracktype */ 
    4848static int udp_packet(struct ip_conntrack *conntrack, 
    4949                      struct iphdr *iph, size_t len, 
    50                       enum ip_conntrack_info conntrackinfo) 
     50                      enum ip_conntrack_info ctinfo) 
    5151{ 
    5252        /* If we've seen traffic both ways, this is some kind of UDP 
    5353           stream.  Extend timeout. */ 
    5454        if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) { 
    55                 ip_ct_refresh(conntrack, ip_ct_udp_timeout_stream); 
     55                ip_ct_refresh_acct(conntrack,ctinfo,iph,ip_ct_udp_timeout_stream); 
    5656                /* Also, more likely to be important, and not a probe */ 
    5757                set_bit(IPS_ASSURED_BIT, &conntrack->status); 
    5858        } else 
    59                 ip_ct_refresh(conntrack, ip_ct_udp_timeout); 
     59                ip_ct_refresh_acct(conntrack,ctinfo,iph, ip_ct_udp_timeout); 
    6060 
    6161        return NF_ACCEPT; 
    6262} 
  • net/ipv4/netfilter/ip_conntrack_standalone.c

    a b print_expect(char *buffer, const struct  
    7979        return len; 
    8080} 
    8181 
     82#if defined(CONFIG_IP_NF_CT_ACCT) || \ 
     83        defined(CONFIG_IP_NF_CT_ACCT_MODULE) 
     84static unsigned int 
     85print_counters(char *buffer, struct ip_conntrack_counter *counter) 
     86{ 
     87       return sprintf(buffer, "packets=%llu bytes=%llu ",  
     88                       counter->packets, counter->bytes); 
     89} 
     90#else 
     91#define print_counters(x, y)   0 
     92#endif 
     93 
    8294static unsigned int 
    8395print_conntrack(char *buffer, struct ip_conntrack *conntrack) 
    8496{ 
    print_conntrack(char *buffer, struct ip_ 
    98110        len += print_tuple(buffer + len, 
    99111                           &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 
    100112                           proto); 
     113        len += print_counters(buffer + len,  
     114                           &conntrack->counters[IP_CT_DIR_ORIGINAL]); 
    101115        if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status))) 
    102116                len += sprintf(buffer + len, "[UNREPLIED] "); 
    103117        len += print_tuple(buffer + len, 
    104118                           &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple, 
    105119                           proto); 
     120        len += print_counters(buffer + len,  
     121                           &conntrack->counters[IP_CT_DIR_REPLY]); 
    106122        if (test_bit(IPS_ASSURED_BIT, &conntrack->status)) 
    107123                len += sprintf(buffer + len, "[ASSURED] "); 
    108124        len += sprintf(buffer + len, "use=%u ", 
    EXPORT_SYMBOL(ip_conntrack_get); 
    481497EXPORT_SYMBOL(ip_conntrack_helper_register); 
    482498EXPORT_SYMBOL(ip_conntrack_helper_unregister); 
    483499EXPORT_SYMBOL(ip_ct_iterate_cleanup); 
    484 EXPORT_SYMBOL(ip_ct_refresh); 
     500EXPORT_SYMBOL(ip_ct_refresh_acct); 
    485501EXPORT_SYMBOL(ip_ct_find_proto); 
    486502EXPORT_SYMBOL(__ip_ct_find_proto); 
    487503EXPORT_SYMBOL(ip_ct_find_helper); 
  • net/ipv4/netfilter/ip_conntrack_proto_generic.c

    a b static unsigned int generic_print_conntr 
    4141/* Returns verdict for packet, or -1 for invalid. */ 
    4242static int established(struct ip_conntrack *conntrack, 
    4343                       struct iphdr *iph, size_t len, 
    44                        enum ip_conntrack_info conntrackinfo) 
     44                       enum ip_conntrack_info ctinfo) 
    4545{ 
    46         ip_ct_refresh(conntrack, ip_ct_generic_timeout); 
     46        ip_ct_refresh_acct(conntrack, ctinfo,iph,ip_ct_generic_timeout); 
    4747        return NF_ACCEPT; 
    4848} 
    4949 
  • net/ipv4/netfilter/ip_conntrack_proto_icmp.c

    a b static int icmp_packet(struct ip_conntra 
    8282                        ct->timeout.function((unsigned long)ct); 
    8383        } else { 
    8484                atomic_inc(&ct->proto.icmp.count); 
    85                 ip_ct_refresh(ct, ip_ct_icmp_timeout); 
     85                ip_ct_refresh_acct(ct,ctinfo,iph, ip_ct_icmp_timeout); 
    8686        } 
    8787 
    8888        return NF_ACCEPT; 
  • net/ipv4/netfilter/ip_conntrack_core.c

    a b void ip_conntrack_helper_unregister(stru 
    11961196 
    11971197        MOD_DEC_USE_COUNT; 
    11981198} 
     1199static inline void ct_add_counters(struct ip_conntrack *ct, 
     1200                                enum ip_conntrack_info ctinfo, 
     1201                                 const struct iphdr *iph) 
     1202{ 
     1203#if defined(CONFIG_IP_NF_CT_ACCT) || \ 
     1204        defined(CONFIG_IP_NF_CT_ACCT_MODULE) 
     1205     if (iph) { 
     1206            ct->counters[CTINFO2DIR(ctinfo)].packets++; 
     1207            ct->counters[CTINFO2DIR(ctinfo)].bytes +=  
     1208                                ntohs(iph->tot_len); 
     1209   } 
     1210#endif 
     1211} 
    11991212 
    12001213/* Refresh conntrack for this many jiffies. */ 
    1201 void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies) 
     1214void ip_ct_refresh_acct(struct ip_conntrack *ct,  
     1215                       enum ip_conntrack_info ctinfo, 
     1216                       const struct iphdr *iph, 
     1217                       unsigned long extra_jiffies) 
    12021218{ 
    12031219        IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct); 
    12041220 
    12051221        WRITE_LOCK(&ip_conntrack_lock); 
    12061222        /* If not in hash table, timer will not be active yet */ 
    1207         if (!is_confirmed(ct)) 
     1223        if (!is_confirmed(ct)) { 
    12081224                ct->timeout.expires = extra_jiffies; 
    1209         else { 
     1225                ct_add_counters(ct, ctinfo,iph); 
     1226        } else { 
    12101227                /* Need del_timer for race avoidance (may already be dying). */ 
    12111228                if (del_timer(&ct->timeout)) { 
    12121229                        ct->timeout.expires = jiffies + extra_jiffies; 
    12131230                        add_timer(&ct->timeout); 
    12141231                } 
     1232                ct_add_counters(ct, ctinfo, iph); 
    12151233        } 
    12161234        WRITE_UNLOCK(&ip_conntrack_lock); 
    12171235} 
  • include/linux/netfilter_ipv4/ip_conntrack.h

    a b struct ip_conntrack_expect 
    164164        union ip_conntrack_expect_help help; 
    165165}; 
    166166 
     167struct ip_conntrack_counter 
     168{ 
     169       u_int64_t packets; 
     170       u_int64_t bytes; 
     171}; 
     172 
    167173struct ip_conntrack_helper; 
    168174 
    169175struct ip_conntrack 
    struct ip_conntrack 
    181187        /* Timer function; drops refcnt when it goes off. */ 
    182188        struct timer_list timeout; 
    183189 
     190#if defined(CONFIG_IP_NF_CT_ACCT) || \ 
     191        defined(CONFIG_IP_NF_CT_ACCT_MODULE) 
     192       /* Accounting Information (same cache line as other written members) */ 
     193       struct ip_conntrack_counter counters[IP_CT_DIR_MAX]; 
     194#endif 
     195 
    184196        /* If we're expecting another related connection, this will be 
    185197           in expected linked list */ 
    186198        struct list_head sibling_list; 
    extern int invert_tuplepr(struct ip_conn 
    264276                          const struct ip_conntrack_tuple *orig); 
    265277 
    266278/* Refresh conntrack for this many jiffies */ 
    267 extern void ip_ct_refresh(struct ip_conntrack *ct, 
    268                           unsigned long extra_jiffies); 
     279extern void ip_ct_refresh_acct(struct ip_conntrack *ct, 
     280                              enum ip_conntrack_info ctinfo, 
     281                              const struct iphdr *iph, 
     282                              unsigned long extra_jiffies); 
    269283 
    270284/* These are for NAT.  Icky. */ 
    271285/* Call me when a conntrack is destroyed. */ 
  • new file net/ipv4/netfilter/ipt_connbytes.c

    - +  
     1/* Kernel module to match connection tracking byte counter. 
     2 * GPL (C) 2002 Martin Devera (devik@cdi.cz). 
     3 * 
     4 * 2004-07-20 Harald Welte <laforge at netfilter.org> 
     5 *      - reimplemented to use per-connection accounting counters 
     6 *      - add functionality to match number of packets 
     7 *      - add functionality to match average packet size 
     8 *      - add support to match directions seperately 
     9 * 
     10 * 2004-10-24 Piotr Chytla <pch at fouk.org> 
     11 *      - Connbytes with per-connection accouting backported to 2.4 
     12 *       
     13 */ 
     14 
     15#include <linux/module.h> 
     16#include <linux/skbuff.h> 
     17#include <linux/types.h> 
     18#include <linux/netfilter_ipv4/ip_conntrack.h> 
     19#include <linux/netfilter_ipv4/ip_tables.h> 
     20#include <linux/netfilter_ipv4/ipt_connbytes.h> 
     21 
     22#include <asm/div64.h> 
     23 
     24static u_int64_t mydiv(u_int64_t arg1,u_int32_t arg2) 
     25{ 
     26        do_div(arg1,arg2); 
     27        return arg1; 
     28} 
     29 
     30static int 
     31match(const struct sk_buff *skb, 
     32      const struct net_device *in, 
     33      const struct net_device *out, 
     34      const void *matchinfo, 
     35      int offset, 
     36      const void *hdr, 
     37      u_int16_t datalen, 
     38      int *hotdrop) 
     39{ 
     40        static u_int64_t what; 
     41        const struct ipt_connbytes_info *sinfo = matchinfo; 
     42        enum ip_conntrack_info ctinfo; 
     43        struct ip_conntrack *ct; 
     44 
     45        if (!(ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo))) 
     46                return 0; /* no match */ 
     47        switch (sinfo->what) { 
     48        case IPT_CONNBYTES_PKTS: 
     49                switch (sinfo->direction) { 
     50                case IPT_CONNBYTES_DIR_ORIGINAL: 
     51                        what = ct->counters[IP_CT_DIR_ORIGINAL].packets; 
     52                        break; 
     53                case IPT_CONNBYTES_DIR_REPLY: 
     54                        what = ct->counters[IP_CT_DIR_REPLY].packets; 
     55                        break; 
     56                case IPT_CONNBYTES_DIR_BOTH: 
     57                        what = ct->counters[IP_CT_DIR_ORIGINAL].packets; 
     58                        what += ct->counters[IP_CT_DIR_REPLY].packets; 
     59                        break; 
     60                } 
     61                break; 
     62        case IPT_CONNBYTES_BYTES: 
     63                switch (sinfo->direction) { 
     64                case IPT_CONNBYTES_DIR_ORIGINAL: 
     65                        what = ct->counters[IP_CT_DIR_ORIGINAL].bytes; 
     66                        break; 
     67                case IPT_CONNBYTES_DIR_REPLY: 
     68                        what = ct->counters[IP_CT_DIR_REPLY].bytes; 
     69                        break; 
     70                case IPT_CONNBYTES_DIR_BOTH: 
     71                        what = ct->counters[IP_CT_DIR_ORIGINAL].bytes; 
     72                        what += ct->counters[IP_CT_DIR_REPLY].bytes; 
     73                        break; 
     74                } 
     75                break; 
     76        case IPT_CONNBYTES_AVGPKT: 
     77                switch (sinfo->direction) { 
     78                case IPT_CONNBYTES_DIR_ORIGINAL: 
     79                        { 
     80                                u_int32_t pkts32; 
     81 
     82                                if (ct->counters[IP_CT_DIR_ORIGINAL].packets > 0xfffffffff) 
     83                                        pkts32 = 0xffffffff; 
     84                                else 
     85                                        pkts32 = ct->counters[IP_CT_DIR_ORIGINAL].packets; 
     86                                what = mydiv(ct->counters[IP_CT_DIR_ORIGINAL].bytes,pkts32); 
     87                        } 
     88                        break; 
     89                case IPT_CONNBYTES_DIR_REPLY: 
     90                        { 
     91                                u_int32_t pkts32; 
     92 
     93                                if (ct->counters[IP_CT_DIR_REPLY].packets > 0xffffffff) 
     94                                        pkts32 = 0xffffffff; 
     95                                else 
     96                                        pkts32 = ct->counters[IP_CT_DIR_REPLY].packets; 
     97                                what = mydiv(ct->counters[IP_CT_DIR_REPLY].bytes,pkts32); 
     98                        } 
     99                        break; 
     100                case IPT_CONNBYTES_DIR_BOTH: 
     101                        { 
     102                                u_int64_t bytes; 
     103                                u_int64_t pkts; 
     104                                u_int32_t pkts32; 
     105                                bytes = ct->counters[IP_CT_DIR_ORIGINAL].bytes + 
     106                                        ct->counters[IP_CT_DIR_REPLY].bytes; 
     107                                pkts = ct->counters[IP_CT_DIR_ORIGINAL].packets + 
     108                                        ct->counters[IP_CT_DIR_REPLY].packets; 
     109                                if (pkts > 0xffffffff) 
     110                                        pkts32 =  0xffffffff; 
     111                                else 
     112                                        pkts32 = pkts; 
     113                                what = mydiv(bytes,pkts); 
     114                        } 
     115                        break; 
     116                } 
     117                break; 
     118        } 
     119        if (sinfo->count.to) 
     120                return (what <= sinfo->count.to && what >= sinfo->count.from); 
     121        else 
     122                return (what >= sinfo->count.from); 
     123} 
     124 
     125static int check(const char *tablename, 
     126                 const struct ipt_ip *ip, 
     127                 void *matchinfo, 
     128                 unsigned int matchsize, 
     129                 unsigned int hook_mask) 
     130{ 
     131        const struct ipt_connbytes_info *sinfo = matchinfo; 
     132 
     133        if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info))) 
     134                return 0; 
     135        if (sinfo->what != IPT_CONNBYTES_PKTS && 
     136                        sinfo->what != IPT_CONNBYTES_BYTES && 
     137                        sinfo->what != IPT_CONNBYTES_AVGPKT) 
     138                        return 0; 
     139 
     140        if (sinfo->direction != IPT_CONNBYTES_DIR_ORIGINAL && 
     141                        sinfo->direction != IPT_CONNBYTES_DIR_REPLY && 
     142                        sinfo->direction != IPT_CONNBYTES_DIR_BOTH) 
     143                        return 0; 
     144 
     145        return 1; 
     146} 
     147 
     148static struct ipt_match state_match 
     149= { { NULL, NULL }, "connbytes", &match, &check, NULL, THIS_MODULE }; 
     150 
     151static int __init init(void) 
     152{ 
     153        return ipt_register_match(&state_match); 
     154} 
     155 
     156static void __exit fini(void) 
     157{ 
     158        ipt_unregister_match(&state_match); 
     159} 
     160 
     161module_init(init); 
     162module_exit(fini); 
     163MODULE_LICENSE("GPL"); 
  • new file include/linux/netfilter_ipv4/ipt_connbytes.h

    - +  
     1#ifndef _IPT_CONNBYTES_H 
     2#define _IPT_CONNBYTES_H 
     3enum ipt_connbytes_what { 
     4                IPT_CONNBYTES_PKTS, 
     5                IPT_CONNBYTES_BYTES, 
     6                IPT_CONNBYTES_AVGPKT, 
     7}; 
     8 
     9enum ipt_connbytes_direction { 
     10                IPT_CONNBYTES_DIR_ORIGINAL, 
     11                IPT_CONNBYTES_DIR_REPLY, 
     12                IPT_CONNBYTES_DIR_BOTH, 
     13}; 
     14 
     15struct ipt_connbytes_info 
     16{ 
     17        struct { 
     18                u_int64_t from; /* count to be matched */ 
     19                u_int64_t to;   /* count to be matched */ 
     20        } count; 
     21        u_int8_t what;          /* ipt_connbytes_what */ 
     22        u_int8_t direction;     /* ipt_connbytes_direction */ 
     23}; 
     24 
     25#endif 
  • net/ipv4/netfilter/ip_conntrack_proto_gre.c

    a b static unsigned int gre_print_conntrack( 
    237237/* Returns verdict for packet, and may modify conntrack */ 
    238238static int gre_packet(struct ip_conntrack *ct, 
    239239                      struct iphdr *iph, size_t len, 
    240                       enum ip_conntrack_info conntrackinfo) 
     240                      enum ip_conntrack_info ctinfo) 
    241241{ 
    242242        /* If we've seen traffic both ways, this is a GRE connection. 
    243243         * Extend timeout. */ 
    244244        if (ct->status & IPS_SEEN_REPLY) { 
    245                 ip_ct_refresh_acct(ct, ct->proto.gre.stream_timeout); 
     245                ip_ct_refresh_acct(ct, ctinfo, iph, ct->proto.gre.stream_timeout); 
    246246                /* Also, more likely to be important, and not a probe. */ 
    247247                set_bit(IPS_ASSURED_BIT, &ct->status); 
    248248        } else 
    249                 ip_ct_refresh_acct(ct, ct->proto.gre.timeout); 
     249                ip_ct_refresh_acct(ct, ctinfo, iph, ct->proto.gre.timeout); 
    250250         
    251251        return NF_ACCEPT; 
    252252} 
Note: See TracBrowser for help on using the repository browser.