[netfilter-cvslog] r3868 - in trunk/patch-o-matic-ng/ACCOUNT: . linux/include/linux/netfilter_ipv4 linux/net/ipv4/netfilter

laforge at netfilter.org laforge at netfilter.org
Fri Apr 15 17:58:59 CEST 2005


Author: laforge at netfilter.org
Date: 2005-04-15 17:58:59 +0200 (Fri, 15 Apr 2005)
New Revision: 3868

Modified:
   trunk/patch-o-matic-ng/ACCOUNT/info
   trunk/patch-o-matic-ng/ACCOUNT/linux/include/linux/netfilter_ipv4/ipt_ACCOUNT.h
   trunk/patch-o-matic-ng/ACCOUNT/linux/net/ipv4/netfilter/ipt_ACCOUNT.c
Log:
update to latest upstream version (Thomas Jarosch)


Modified: trunk/patch-o-matic-ng/ACCOUNT/info
===================================================================
--- trunk/patch-o-matic-ng/ACCOUNT/info	2005-04-15 15:56:21 UTC (rev 3867)
+++ trunk/patch-o-matic-ng/ACCOUNT/info	2005-04-15 15:58:59 UTC (rev 3868)
@@ -1,5 +1,4 @@
-Title: iptables ``account'' target
 Author: Intra2net AG <opensource at intra2net.com>
 Status: Beta
 Repository: extra
-Recompile: kernel, iptables
+Recompile: netfilter

Modified: trunk/patch-o-matic-ng/ACCOUNT/linux/include/linux/netfilter_ipv4/ipt_ACCOUNT.h
===================================================================
--- trunk/patch-o-matic-ng/ACCOUNT/linux/include/linux/netfilter_ipv4/ipt_ACCOUNT.h	2005-04-15 15:56:21 UTC (rev 3867)
+++ trunk/patch-o-matic-ng/ACCOUNT/linux/include/linux/netfilter_ipv4/ipt_ACCOUNT.h	2005-04-15 15:58:59 UTC (rev 3868)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2004-2005 by Intra2net AG                               *
+ *   Copyright (C) 2004 by Intra2net AG                                    *
  *   opensource at intra2net.com                                              *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *

Modified: trunk/patch-o-matic-ng/ACCOUNT/linux/net/ipv4/netfilter/ipt_ACCOUNT.c
===================================================================
--- trunk/patch-o-matic-ng/ACCOUNT/linux/net/ipv4/netfilter/ipt_ACCOUNT.c	2005-04-15 15:56:21 UTC (rev 3867)
+++ trunk/patch-o-matic-ng/ACCOUNT/linux/net/ipv4/netfilter/ipt_ACCOUNT.c	2005-04-15 15:58:59 UTC (rev 3868)
@@ -2,7 +2,7 @@
  *   This is a module which is used for counting packets.                  *
  *   See http://www.intra2net.com/opensource/ipt_account                   *
  *   for further information                                               *
- *                                                                         *
+ *                                                                         * 
  *   Copyright (C) 2004-2005 by Intra2net AG                               *
  *   opensource at intra2net.com                                              *
  *                                                                         *
@@ -82,7 +82,7 @@
             if (((struct ipt_acc_mask_8 *)data)->mask_16[a]) {
                 struct ipt_acc_mask_16 *mask_16 = (struct ipt_acc_mask_16*)
                                    ((struct ipt_acc_mask_8 *)data)->mask_16[a];
-
+                
                 for (b=0; b <= 255; b++) {
                     if (mask_16->mask_24[b]) {
                         free_page((unsigned long)mask_16->mask_24[b]);
@@ -95,12 +95,12 @@
         return;
     }
 
-    printk("ACCOUNT: ipt_acc_data_free called with unknown depth: %d\n",
+    printk("ACCOUNT: ipt_acc_data_free called with unknown depth: %d\n", 
            depth);
     return;
 }
 
-/* Look for existing table / insert new one.
+/* Look for existing table / insert new one. 
    Return internal ID or -1 on error */
 static int ipt_acc_table_insert(char *name, u_int32_t ip, u_int32_t netmask)
 {
@@ -111,18 +111,18 @@
 
     /* Look for existing table */
     for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
-        if (strncmp(ipt_acc_tables[i].name, name,
+        if (strncmp(ipt_acc_tables[i].name, name, 
                     ACCOUNT_TABLE_NAME_LEN) == 0) {
             DEBUGP("ACCOUNT: Found existing slot: %d - "
-                   "%u.%u.%u.%u/%u.%u.%u.%u\n", i,
-                   NIPQUAD(ipt_acc_tables[i].ip),
+                   "%u.%u.%u.%u/%u.%u.%u.%u\n", i, 
+                   NIPQUAD(ipt_acc_tables[i].ip), 
                    NIPQUAD(ipt_acc_tables[i].netmask));
 
-            if (ipt_acc_tables[i].ip != ip
+            if (ipt_acc_tables[i].ip != ip 
                 || ipt_acc_tables[i].netmask != netmask) {
                 printk("ACCOUNT: Table %s found, but IP/netmask mismatch. "
                        "IP/netmask found: %u.%u.%u.%u/%u.%u.%u.%u\n",
-                       name, NIPQUAD(ipt_acc_tables[i].ip),
+                       name, NIPQUAD(ipt_acc_tables[i].ip), 
                        NIPQUAD(ipt_acc_tables[i].netmask));
                 return -1;
             }
@@ -138,7 +138,7 @@
         /* Found free slot */
         if (ipt_acc_tables[i].name[0] == 0) {
             u_int32_t j, calc_mask, netsize=0;
-
+            
             DEBUGP("ACCOUNT: Found free slot: %d\n", i);
             strncpy (ipt_acc_tables[i].name, name, ACCOUNT_TABLE_NAME_LEN-1);
 
@@ -163,14 +163,14 @@
                 ipt_acc_tables[i].depth = 2;
 
             DEBUGP("ACCOUNT: calculated netsize: %u -> "
-                   "ipt_acc_table depth %u\n", netsize,
+                   "ipt_acc_table depth %u\n", netsize, 
                    ipt_acc_tables[i].depth);
 
             ipt_acc_tables[i].refcount++;
             if ((ipt_acc_tables[i].data
                 = (void *)get_zeroed_page(GFP_ATOMIC)) == NULL) {
                 printk("ACCOUNT: out of memory for data of table: %s\n", name);
-                memset(&ipt_acc_tables[i], 0,
+                memset(&ipt_acc_tables[i], 0, 
                        sizeof(struct ipt_acc_table));
                 return -1;
             }
@@ -200,20 +200,19 @@
         return 0;
     }
 
-    spin_lock_bh(&ipt_acc_lock);
+    LOCK_BH(&ipt_acc_lock);
     table_nr = ipt_acc_table_insert(info->table_name, info->net_ip,
                                                       info->net_mask);
+    UNLOCK_BH(&ipt_acc_lock);
+    
     if (table_nr == -1) {
         printk("ACCOUNT: Table insert problem. Aborting\n");
-        spin_unlock_bh(&ipt_acc_lock);
         return 0;
     }
-    /* Table nr caching so we don't have to do an extra string compare
+    /* Table nr caching so we don't have to do an extra string compare 
        for every packet */
     info->table_nr = table_nr;
 
-    spin_unlock_bh(&ipt_acc_lock);
-
     return 1;
 }
 
@@ -229,27 +228,27 @@
 
     LOCK_BH(&ipt_acc_lock);
 
-    DEBUGP("ACCOUNT: ipt_acc_deleteentry called for table: %s (#%d)\n",
+    DEBUGP("ACCOUNT: ipt_acc_deleteentry called for table: %s (#%d)\n", 
            info->table_name, info->table_nr);
 
     info->table_nr = -1;    /* Set back to original state */
 
     /* Look for table */
     for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
-        if (strncmp(ipt_acc_tables[i].name, info->table_name,
+        if (strncmp(ipt_acc_tables[i].name, info->table_name, 
                     ACCOUNT_TABLE_NAME_LEN) == 0) {
             DEBUGP("ACCOUNT: Found table at slot: %d\n", i);
 
             ipt_acc_tables[i].refcount--;
-            DEBUGP("ACCOUNT: Refcount left: %d\n",
+            DEBUGP("ACCOUNT: Refcount left: %d\n", 
                    ipt_acc_tables[i].refcount);
 
             /* Table not needed anymore? */
             if (ipt_acc_tables[i].refcount == 0) {
                 DEBUGP("ACCOUNT: Destroying table at slot: %d\n", i);
-                ipt_acc_data_free(ipt_acc_tables[i].data,
+                ipt_acc_data_free(ipt_acc_tables[i].data, 
                                       ipt_acc_tables[i].depth);
-                memset(&ipt_acc_tables[i], 0,
+                memset(&ipt_acc_tables[i], 0, 
                        sizeof(struct ipt_acc_table));
             }
 
@@ -264,15 +263,15 @@
 }
 
 static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
-                                  u_int32_t net_ip, u_int32_t netmask,
-                                  u_int32_t src_ip, u_int32_t dst_ip,
-                                  u_int32_t size, u_int32_t *itemcount)
+                               u_int32_t net_ip, u_int32_t netmask,
+                               u_int32_t src_ip, u_int32_t dst_ip,
+                               u_int32_t size, u_int32_t *itemcount)
 {
     unsigned char is_src = 0, is_dst = 0, src_slot, dst_slot;
     char is_src_new_ip = 0, is_dst_new_ip = 0; /* Check if this entry is new */
 
     DEBUGP("ACCOUNT: ipt_acc_depth0_insert: %u.%u.%u.%u/%u.%u.%u.%u "
-           "for net %u.%u.%u.%u/%u.%u.%u.%u, size: %u\n", NIPQUAD(src_ip),
+           "for net %u.%u.%u.%u/%u.%u.%u.%u, size: %u\n", NIPQUAD(src_ip), 
            NIPQUAD(dst_ip), NIPQUAD(net_ip), NIPQUAD(netmask), size);
 
     /* Check if src/dst is inside our network. */
@@ -286,7 +285,7 @@
 
     if (!is_src && !is_dst) {
         DEBUGP("ACCOUNT: Skipping packet %u.%u.%u.%u/%u.%u.%u.%u "
-               "for net %u.%u.%u.%u/%u.%u.%u.%u\n", NIPQUAD(src_ip),
+               "for net %u.%u.%u.%u/%u.%u.%u.%u\n", NIPQUAD(src_ip), 
                NIPQUAD(dst_ip), NIPQUAD(net_ip), NIPQUAD(netmask));
         return;
     }
@@ -299,7 +298,7 @@
     if (is_src) {
         /* Calculate network slot */
         DEBUGP("ACCOUNT: Calculated SRC 8 bit network slot: %d\n", src_slot);
-        if (!mask_24->ip[src_slot].src_packets
+        if (!mask_24->ip[src_slot].src_packets 
             && !mask_24->ip[src_slot].dst_packets)
             is_src_new_ip = 1;
 
@@ -308,7 +307,7 @@
     }
     if (is_dst) {
         DEBUGP("ACCOUNT: Calculated DST 8 bit network slot: %d\n", dst_slot);
-        if (!mask_24->ip[dst_slot].src_packets
+        if (!mask_24->ip[dst_slot].src_packets 
             && !mask_24->ip[dst_slot].dst_packets)
             is_dst_new_ip = 1;
 
@@ -320,7 +319,7 @@
     DEBUGP("ACCOUNT: Itemcounter before: %d\n", *itemcount);
     if (src_slot == dst_slot) {
         if (is_src_new_ip || is_dst_new_ip) {
-            DEBUGP("ACCOUNT: src_slot == dst_slot: %d, %d\n",
+            DEBUGP("ACCOUNT: src_slot == dst_slot: %d, %d\n", 
                    is_src_new_ip, is_dst_new_ip);
             (*itemcount)++;
         }
@@ -337,10 +336,10 @@
     DEBUGP("ACCOUNT: Itemcounter after: %d\n", *itemcount);
 }
 
-static void ipt_acc_depth1_insert(struct ipt_acc_mask_16 *mask_16,
-                                  u_int32_t net_ip, u_int32_t netmask,
-                                  u_int32_t src_ip, u_int32_t dst_ip,
-                                  u_int32_t size, u_int32_t *itemcount)
+static void ipt_acc_depth1_insert(struct ipt_acc_mask_16 *mask_16, 
+                               u_int32_t net_ip, u_int32_t netmask, 
+                               u_int32_t src_ip, u_int32_t dst_ip,
+                               u_int32_t size, u_int32_t *itemcount)
 {
     /* Do we need to process src IP? */
     if ((net_ip&netmask) == (src_ip&netmask)) {
@@ -348,7 +347,7 @@
         DEBUGP("ACCOUNT: Calculated SRC 16 bit network slot: %d\n", slot);
 
         /* Do we need to create a new mask_24 bucket? */
-        if (!mask_16->mask_24[slot] && (mask_16->mask_24[slot] =
+        if (!mask_16->mask_24[slot] && (mask_16->mask_24[slot] = 
              (void *)get_zeroed_page(GFP_ATOMIC)) == NULL) {
             printk("ACCOUNT: Can't process packet because out of memory!\n");
             return;
@@ -364,7 +363,7 @@
         DEBUGP("ACCOUNT: Calculated DST 16 bit network slot: %d\n", slot);
 
         /* Do we need to create a new mask_24 bucket? */
-        if (!mask_16->mask_24[slot] && (mask_16->mask_24[slot]
+        if (!mask_16->mask_24[slot] && (mask_16->mask_24[slot] 
             = (void *)get_zeroed_page(GFP_ATOMIC)) == NULL) {
             printk("ACCOUT: Can't process packet because out of memory!\n");
             return;
@@ -375,10 +374,10 @@
     }
 }
 
-static void ipt_acc_depth2_insert(struct ipt_acc_mask_8 *mask_8,
-                                  u_int32_t net_ip, u_int32_t netmask,
-                                  u_int32_t src_ip, u_int32_t dst_ip,
-                                  u_int32_t size, u_int32_t *itemcount)
+static void ipt_acc_depth2_insert(struct ipt_acc_mask_8 *mask_8, 
+                               u_int32_t net_ip, u_int32_t netmask,
+                               u_int32_t src_ip, u_int32_t dst_ip,
+                               u_int32_t size, u_int32_t *itemcount)
 {
     /* Do we need to process src IP? */
     if ((net_ip&netmask) == (src_ip&netmask)) {
@@ -386,7 +385,7 @@
         DEBUGP("ACCOUNT: Calculated SRC 24 bit network slot: %d\n", slot);
 
         /* Do we need to create a new mask_24 bucket? */
-        if (!mask_8->mask_16[slot] && (mask_8->mask_16[slot]
+        if (!mask_8->mask_16[slot] && (mask_8->mask_16[slot] 
             = (void *)get_zeroed_page(GFP_ATOMIC)) == NULL) {
             printk("ACCOUNT: Can't process packet because out of memory!\n");
             return;
@@ -402,7 +401,7 @@
         DEBUGP("ACCOUNT: Calculated DST 24 bit network slot: %d\n", slot);
 
         /* Do we need to create a new mask_24 bucket? */
-        if (!mask_8->mask_16[slot] && (mask_8->mask_16[slot]
+        if (!mask_8->mask_16[slot] && (mask_8->mask_16[slot] 
             = (void *)get_zeroed_page(GFP_ATOMIC)) == NULL) {
             printk("ACCOUNT: Can't process packet because out of memory!\n");
             return;
@@ -420,19 +419,19 @@
                                        const void *targinfo,
                                        void *userinfo)
 {
-    const struct ipt_acc_info *info =
+    const struct ipt_acc_info *info = 
         (const struct ipt_acc_info *)targinfo;
     u_int32_t src_ip = (*pskb)->nh.iph->saddr;
     u_int32_t dst_ip = (*pskb)->nh.iph->daddr;
     u_int32_t size = ntohs((*pskb)->nh.iph->tot_len);
 
-    spin_lock_bh(&ipt_acc_lock);
+    LOCK_BH(&ipt_acc_lock);
 
     if (ipt_acc_tables[info->table_nr].name[0] == 0) {
         printk("ACCOUNT: ipt_acc_target: Invalid table id %u. "
-               "IPs %u.%u.%u.%u/%u.%u.%u.%u\n", info->table_nr,
+               "IPs %u.%u.%u.%u/%u.%u.%u.%u\n", info->table_nr, 
                NIPQUAD(src_ip), NIPQUAD(dst_ip));
-        spin_unlock_bh(&ipt_acc_lock);
+        UNLOCK_BH(&ipt_acc_lock);
         return IPT_CONTINUE;
     }
 
@@ -441,7 +440,7 @@
         /* Count packet and check if the IP is new */
         ipt_acc_depth0_insert(
             (struct ipt_acc_mask_24 *)ipt_acc_tables[info->table_nr].data,
-            ipt_acc_tables[info->table_nr].ip,
+            ipt_acc_tables[info->table_nr].ip, 
             ipt_acc_tables[info->table_nr].netmask,
             src_ip, dst_ip, size, &ipt_acc_tables[info->table_nr].itemcount);
         UNLOCK_BH(&ipt_acc_lock);
@@ -452,7 +451,7 @@
     if (ipt_acc_tables[info->table_nr].depth == 1) {
         ipt_acc_depth1_insert(
             (struct ipt_acc_mask_16 *)ipt_acc_tables[info->table_nr].data,
-            ipt_acc_tables[info->table_nr].ip,
+            ipt_acc_tables[info->table_nr].ip, 
             ipt_acc_tables[info->table_nr].netmask,
             src_ip, dst_ip, size, &ipt_acc_tables[info->table_nr].itemcount);
         UNLOCK_BH(&ipt_acc_lock);
@@ -463,7 +462,7 @@
     if (ipt_acc_tables[info->table_nr].depth == 2) {
         ipt_acc_depth2_insert(
             (struct ipt_acc_mask_8 *)ipt_acc_tables[info->table_nr].data,
-            ipt_acc_tables[info->table_nr].ip,
+            ipt_acc_tables[info->table_nr].ip, 
             ipt_acc_tables[info->table_nr].netmask,
             src_ip, dst_ip, size, &ipt_acc_tables[info->table_nr].itemcount);
         UNLOCK_BH(&ipt_acc_lock);
@@ -471,7 +470,7 @@
     }
 
     printk("ACCOUNT: ipt_acc_target: Unable to process packet. "
-           "Table id %u. IPs %u.%u.%u.%u/%u.%u.%u.%u\n",
+           "Table id %u. IPs %u.%u.%u.%u/%u.%u.%u.%u\n", 
            info->table_nr, NIPQUAD(src_ip), NIPQUAD(dst_ip));
 
     UNLOCK_BH(&ipt_acc_lock);
@@ -481,11 +480,11 @@
 /*
     Functions dealing with "handles":
     Handles are snapshots of a accounting state.
-
+    
     read snapshots are only for debugging the code
     and are very expensive concerning speed/memory
     compared to read_and_flush.
-
+    
     The functions aren't protected by spinlocks themselves
     as this is done in the ioctl part of the code.
 */
@@ -502,7 +501,7 @@
     for (i = 0; i < ACCOUNT_MAX_HANDLES; i++) {
         /* Found free slot */
         if (ipt_acc_handles[i].data == NULL) {
-            /* Don't "mark" data as used as we are protected by a spinlock
+            /* Don't "mark" data as used as we are protected by a spinlock 
                by the calling function. handle_find_slot() is only a function
                to prevent code duplication. */
             return i;
@@ -523,7 +522,7 @@
         return -EINVAL;
     }
 
-    ipt_acc_data_free(ipt_acc_handles[handle].data,
+    ipt_acc_data_free(ipt_acc_handles[handle].data, 
                           ipt_acc_handles[handle].depth);
     memset (&ipt_acc_handles[handle], 0, sizeof (struct ipt_acc_handle));
     return 0;
@@ -531,92 +530,80 @@
 
 /* Prepare data for read without flush. Use only for debugging!
    Real applications should use read&flush as it's way more efficent */
-static int ipt_acc_handle_prepare_read(char *tablename, u_int32_t *count)
+static int ipt_acc_handle_prepare_read(char *tablename,
+         struct ipt_acc_handle *dest, u_int32_t *count)
 {
-    int handle, i, table_nr=-1;
+    int table_nr=-1;
     unsigned char depth;
 
-    for (i = 0; i < ACCOUNT_MAX_TABLES; i++)
-        if (strncmp(ipt_acc_tables[i].name, tablename,
-            ACCOUNT_TABLE_NAME_LEN) == 0) {
-            table_nr = i;
-            break;
-        }
+    for (table_nr = 0; table_nr < ACCOUNT_MAX_TABLES; table_nr++)
+        if (strncmp(ipt_acc_tables[table_nr].name, tablename, 
+            ACCOUNT_TABLE_NAME_LEN) == 0)
+                break;
 
-    if (table_nr == -1) {
+    if (table_nr == ACCOUNT_MAX_TABLES) {
         printk("ACCOUNT: ipt_acc_handle_prepare_read(): "
                "Table %s not found\n", tablename);
         return -1;
     }
 
-    /* Can't find a free handle slot? */
-    if ((handle = ipt_acc_handle_find_slot()) == -1)
-        return -1;
-
     /* Fill up handle structure */
-    ipt_acc_handles[handle].ip = ipt_acc_tables[table_nr].ip;
-    ipt_acc_handles[handle].depth = ipt_acc_tables[table_nr].depth;
-    ipt_acc_handles[handle].itemcount = ipt_acc_tables[table_nr].itemcount;
+    dest->ip = ipt_acc_tables[table_nr].ip;
+    dest->depth = ipt_acc_tables[table_nr].depth;
+    dest->itemcount = ipt_acc_tables[table_nr].itemcount;
 
     /* allocate "root" table */
-    if ((ipt_acc_handles[handle].data =
-         (void*)get_zeroed_page(GFP_ATOMIC)) == NULL) {
+    if ((dest->data = (void*)get_zeroed_page(GFP_ATOMIC)) == NULL) {
         printk("ACCOUNT: out of memory for root table "
                "in ipt_acc_handle_prepare_read()\n");
-        memset (&ipt_acc_handles[handle], 0,
-                sizeof(struct ipt_acc_handle));
         return -1;
     }
 
     /* Recursive copy of complete data structure */
-    depth = ipt_acc_handles[handle].depth;
+    depth = dest->depth;
     if (depth == 0) {
-        memcpy(ipt_acc_handles[handle].data,
-               ipt_acc_tables[table_nr].data,
+        memcpy(dest->data, 
+               ipt_acc_tables[table_nr].data, 
                sizeof(struct ipt_acc_mask_24));
     } else if (depth == 1) {
-        struct ipt_acc_mask_16 *src_16 =
+        struct ipt_acc_mask_16 *src_16 = 
             (struct ipt_acc_mask_16 *)ipt_acc_tables[table_nr].data;
         struct ipt_acc_mask_16 *network_16 =
-            (struct ipt_acc_mask_16 *)ipt_acc_handles[handle].data;
+            (struct ipt_acc_mask_16 *)dest->data;
         u_int32_t b;
 
         for (b = 0; b <= 255; b++) {
             if (src_16->mask_24[b]) {
-                if ((network_16->mask_24[b] =
+                if ((network_16->mask_24[b] = 
                      (void*)get_zeroed_page(GFP_ATOMIC)) == NULL) {
                     printk("ACCOUNT: out of memory during copy of 16 bit "
                            "network in ipt_acc_handle_prepare_read()\n");
-                    ipt_acc_data_free(ipt_acc_handles[handle].data, depth);
-                    memset (&ipt_acc_handles[handle], 0,
-                            sizeof(struct ipt_acc_handle));
+                    ipt_acc_data_free(dest->data, depth);
                     return -1;
                 }
 
-                memcpy(network_16->mask_24[b], src_16->mask_24[b],
+                memcpy(network_16->mask_24[b], src_16->mask_24[b], 
                        sizeof(struct ipt_acc_mask_24));
             }
         }
     } else if(depth == 2) {
-        struct ipt_acc_mask_8 *src_8 =
+        struct ipt_acc_mask_8 *src_8 = 
             (struct ipt_acc_mask_8 *)ipt_acc_tables[table_nr].data;
-        struct ipt_acc_mask_8 *network_8 =
-            (struct ipt_acc_mask_8 *)ipt_acc_handles[handle].data;
+        struct ipt_acc_mask_8 *network_8 = 
+            (struct ipt_acc_mask_8 *)dest->data;
         u_int32_t a;
 
         for (a = 0; a <= 255; a++) {
             if (src_8->mask_16[a]) {
-                if ((network_8->mask_16[a] =
+                if ((network_8->mask_16[a] = 
                      (void*)get_zeroed_page(GFP_ATOMIC)) == NULL) {
                     printk("ACCOUNT: out of memory during copy of 24 bit network"
                            " in ipt_acc_handle_prepare_read()\n");
-                    ipt_acc_data_free(ipt_acc_handles[handle].data, depth);
-                    memset (&ipt_acc_handles[handle], 0,
-                            sizeof(struct ipt_acc_handle));
+                    ipt_acc_data_free(dest->data, depth);
                     return -1;
                 }
 
-                memcpy(network_8->mask_16[a], src_8->mask_16[a],
+                memcpy(network_8->mask_16[a], src_8->mask_16[a], 
                        sizeof(struct ipt_acc_mask_16));
 
                 struct ipt_acc_mask_16 *src_16 = src_8->mask_16[a];
@@ -625,18 +612,15 @@
 
                 for (b = 0; b <= 255; b++) {
                     if (src_16->mask_24[b]) {
-                        if ((network_16->mask_24[b] =
+                        if ((network_16->mask_24[b] = 
                              (void*)get_zeroed_page(GFP_ATOMIC)) == NULL) {
                             printk("ACCOUNT: out of memory during copy of 16 bit"
                                    " network in ipt_acc_handle_prepare_read()\n");
-                            ipt_acc_data_free(ipt_acc_handles[handle].data,
-                                                  depth);
-                            memset (&ipt_acc_handles[handle], 0,
-                                    sizeof(struct ipt_acc_handle));
+                            ipt_acc_data_free(dest->data, depth);
                             return -1;
                         }
 
-                        memcpy(network_16->mask_24[b], src_16->mask_24[b],
+                        memcpy(network_16->mask_24[b], src_16->mask_24[b], 
                                sizeof(struct ipt_acc_mask_24));
                     }
                 }
@@ -645,32 +629,28 @@
     }
 
     *count = ipt_acc_tables[table_nr].itemcount;
-    return handle;
+    
+    return 0;
 }
 
 /* Prepare data for read and flush it */
-static int ipt_acc_handle_prepare_read_flush(char *tablename, u_int32_t *count)
+static int ipt_acc_handle_prepare_read_flush(char *tablename,
+               struct ipt_acc_handle *dest, u_int32_t *count)
 {
-    int handle, i, table_nr=-1;
+    int table_nr;
     void *new_data_page;
 
-    for (i = 0; i < ACCOUNT_MAX_TABLES; i++)
-        if (strncmp(ipt_acc_tables[i].name, tablename,
-                    ACCOUNT_TABLE_NAME_LEN) == 0) {
-            table_nr = i;
-            break;
-        }
+    for (table_nr = 0; table_nr < ACCOUNT_MAX_TABLES; table_nr++)
+        if (strncmp(ipt_acc_tables[table_nr].name, tablename, 
+            ACCOUNT_TABLE_NAME_LEN) == 0)
+                break;
 
-    if (table_nr == -1) {
+    if (table_nr == ACCOUNT_MAX_TABLES) {
         printk("ACCOUNT: ipt_acc_handle_prepare_read_flush(): "
                "Table %s not found\n", tablename);
         return -1;
     }
 
-    /* Can't find a free handle slot? */
-    if ((handle = ipt_acc_handle_find_slot()) == -1)
-        return -1;
-
     /* Try to allocate memory */
     if (!(new_data_page = (void*)get_zeroed_page(GFP_ATOMIC))) {
         printk("ACCOUNT: ipt_acc_handle_prepare_read_flush(): "
@@ -696,18 +676,18 @@
    We only copy entries != 0 to increase performance.
 */
 static int ipt_acc_handle_copy_data(void *to_user, u_int32_t *to_user_pos,
-                                  u_int32_t *tmpbuf_pos,
-                                    struct ipt_acc_mask_24 *data,
-                                    u_int32_t net_ip, u_int32_t net_OR_mask)
+                                  u_int32_t *tmpbuf_pos, 
+                                  struct ipt_acc_mask_24 *data,
+                                  u_int32_t net_ip, u_int32_t net_OR_mask)
 {
     struct ipt_acc_handle_ip handle_ip;
     u_int32_t handle_ip_size = sizeof (struct ipt_acc_handle_ip);
     u_int32_t i;
-
+    
     for (i = 0; i <= 255; i++) {
         if (data->ip[i].src_packets || data->ip[i].dst_packets) {
             handle_ip.ip = net_ip | net_OR_mask | (i<<24);
-
+            
             handle_ip.src_packets = data->ip[i].src_packets;
             handle_ip.src_bytes = data->ip[i].src_bytes;
             handle_ip.dst_packets = data->ip[i].dst_packets;
@@ -725,11 +705,11 @@
             *tmpbuf_pos += handle_ip_size;
         }
     }
-
+    
     return 0;
 }
-
-/* Copy the data from our internal structure
+   
+/* Copy the data from our internal structure 
    We only copy entries != 0 to increase performance.
    Overwrites ipt_acc_tmpbuf.
 */
@@ -754,12 +734,12 @@
 
     /* 8 bit network */
     if (depth == 0) {
-        struct ipt_acc_mask_24 *network =
+        struct ipt_acc_mask_24 *network = 
             (struct ipt_acc_mask_24*)ipt_acc_handles[handle].data;
         if (ipt_acc_handle_copy_data(to_user, &to_user_pos, &tmpbuf_pos,
                                      network, net_ip, 0))
             return -1;
-
+        
         /* Flush remaining data to userspace */
         if (tmpbuf_pos)
             if (copy_to_user(to_user+to_user_pos, ipt_acc_tmpbuf, tmpbuf_pos))
@@ -770,12 +750,12 @@
 
     /* 16 bit network */
     if (depth == 1) {
-        struct ipt_acc_mask_16 *network_16 =
+        struct ipt_acc_mask_16 *network_16 = 
             (struct ipt_acc_mask_16*)ipt_acc_handles[handle].data;
         u_int32_t b;
         for (b = 0; b <= 255; b++) {
             if (network_16->mask_24[b]) {
-                struct ipt_acc_mask_24 *network =
+                struct ipt_acc_mask_24 *network = 
                     (struct ipt_acc_mask_24*)network_16->mask_24[b];
                 if (ipt_acc_handle_copy_data(to_user, &to_user_pos,
                                       &tmpbuf_pos, network, net_ip, (b << 16)))
@@ -793,20 +773,20 @@
 
     /* 24 bit network */
     if (depth == 2) {
-        struct ipt_acc_mask_8 *network_8 =
+        struct ipt_acc_mask_8 *network_8 = 
             (struct ipt_acc_mask_8*)ipt_acc_handles[handle].data;
         u_int32_t a, b;
         for (a = 0; a <= 255; a++) {
             if (network_8->mask_16[a]) {
-                struct ipt_acc_mask_16 *network_16 =
+                struct ipt_acc_mask_16 *network_16 = 
                     (struct ipt_acc_mask_16*)network_8->mask_16[a];
                 for (b = 0; b <= 255; b++) {
                     if (network_16->mask_24[b]) {
-                        struct ipt_acc_mask_24 *network =
+                        struct ipt_acc_mask_24 *network = 
                             (struct ipt_acc_mask_24*)network_16->mask_24[b];
                         if (ipt_acc_handle_copy_data(to_user,
                                        &to_user_pos, &tmpbuf_pos,
-                                        network, net_ip, (a << 8) | (b << 16)))
+                                       network, net_ip, (a << 8) | (b << 16)))
                             return -1;
                     }
                 }
@@ -820,11 +800,11 @@
 
         return 0;
     }
-
+    
     return -1;
 }
 
-static int ipt_acc_set_ctl(struct sock *sk, int cmd,
+static int ipt_acc_set_ctl(struct sock *sk, int cmd, 
                                void *user, u_int32_t len)
 {
     struct ipt_acc_handle_sockopt handle;
@@ -837,7 +817,7 @@
     case IPT_SO_SET_ACCOUNT_HANDLE_FREE:
         if (len != sizeof(struct ipt_acc_handle_sockopt)) {
             printk("ACCOUNT: ipt_acc_set_ctl: wrong data size (%u != %u) "
-                   "for IPT_SO_SET_HANDLE_FREE\n",
+                   "for IPT_SO_SET_HANDLE_FREE\n", 
                    len, sizeof(struct ipt_acc_handle_sockopt));
             break;
         }
@@ -878,43 +858,52 @@
 
     switch (cmd) {
     case IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH:
-    case IPT_SO_GET_ACCOUNT_PREPARE_READ:
-        if (*len < sizeof(struct ipt_acc_handle_sockopt)) {
-            printk("ACCOUNT: ipt_acc_get_ctl: wrong data size (%u != %u) "
-                   "for IPT_SO_GET_ACCOUNT_PREPARE_READ/READ_FLUSH\n",
-                   *len, sizeof(struct ipt_acc_handle_sockopt));
-            break;
-        }
-
-        if (copy_from_user (&handle, user,
+    case IPT_SO_GET_ACCOUNT_PREPARE_READ: {
+            struct ipt_acc_handle dest;
+    
+            if (*len < sizeof(struct ipt_acc_handle_sockopt)) {
+                printk("ACCOUNT: ipt_acc_get_ctl: wrong data size (%u != %u) "
+                    "for IPT_SO_GET_ACCOUNT_PREPARE_READ/READ_FLUSH\n",
+                    *len, sizeof(struct ipt_acc_handle_sockopt));
+                break;
+            }
+    
+            if (copy_from_user (&handle, user, 
+                                sizeof(struct ipt_acc_handle_sockopt))) {
+                return -EFAULT;
+                break;
+            }
+    
+            LOCK_BH(&ipt_acc_lock);
+            if (cmd == IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH)
+                ret = ipt_acc_handle_prepare_read_flush(
+                                    handle.name, &dest, &handle.itemcount);
+            else
+                ret = ipt_acc_handle_prepare_read(
+                                    handle.name, &dest, &handle.itemcount);
+            UNLOCK_BH(&ipt_acc_lock);
+            // Error occured during prepare_read?
+           if (ret == -1)
+                return -EINVAL;
+            
+            /* Allocate a userspace handle */
+            down(&ipt_acc_userspace_mutex);
+            if ((handle.handle_nr = ipt_acc_handle_find_slot()) == -1) {
+                ipt_acc_data_free(dest.data, dest.depth);
+                return -EINVAL;
+            }
+            memcpy(&ipt_acc_handles[handle.handle_nr], &dest,
+                             sizeof(struct ipt_acc_handle));
+            up(&ipt_acc_userspace_mutex);
+            
+            if (copy_to_user(user, &handle, 
                             sizeof(struct ipt_acc_handle_sockopt))) {
-            return -EFAULT;
+                return -EFAULT;
+                break;
+            }
+            ret = 0;
             break;
         }
-
-        spin_lock_bh(&ipt_acc_lock);
-        spin_lock_bh(&ipt_acc_userspace_lock);
-        if (cmd == IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH)
-            handle.handle_nr = ipt_acc_handle_prepare_read_flush(
-                                   handle.name, &handle.itemcount);
-        else
-            handle.handle_nr = ipt_acc_handle_prepare_read(
-                                   handle.name, &handle.itemcount);
-        spin_unlock_bh(&ipt_acc_userspace_lock);
-        spin_unlock_bh(&ipt_acc_lock);
-
-        if (handle.handle_nr == -1) {
-            return -EINVAL;
-            break;
-        }
-
-        if (copy_to_user(user, &handle,
-                         sizeof(struct ipt_acc_handle_sockopt))) {
-            return -EFAULT;
-            break;
-        }
-        ret = 0;
-        break;
     case IPT_SO_GET_ACCOUNT_GET_DATA:
         if (*len < sizeof(struct ipt_acc_handle_sockopt)) {
             printk("ACCOUNT: ipt_acc_get_ctl: wrong data size (%u != %u)"
@@ -923,7 +912,7 @@
             break;
         }
 
-        if (copy_from_user (&handle, user,
+        if (copy_from_user (&handle, user, 
                             sizeof(struct ipt_acc_handle_sockopt))) {
             return -EFAULT;
             break;
@@ -972,7 +961,7 @@
                     handle.itemcount++;
             up(&ipt_acc_userspace_mutex);
 
-            if (copy_to_user(user, &handle,
+            if (copy_to_user(user, &handle, 
                              sizeof(struct ipt_acc_handle_sockopt))) {
                 return -EFAULT;
                 break;
@@ -981,10 +970,10 @@
             break;
         }
     case IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES: {
-            u_int32_t size = 0, i;
+            u_int32_t size = 0, i, name_len;
             char *tnames;
 
-            spin_lock_bh(&ipt_acc_lock);
+            LOCK_BH(&ipt_acc_lock);
 
             /* Determine size of table names */
             for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
@@ -1048,22 +1037,24 @@
 
 static int __init init(void)
 {
-    if ((ipt_acc_tables =
-         kmalloc(ACCOUNT_MAX_TABLES *
+    init_MUTEX(&ipt_acc_userspace_mutex);    
+
+    if ((ipt_acc_tables = 
+         kmalloc(ACCOUNT_MAX_TABLES * 
                  sizeof(struct ipt_acc_table), GFP_KERNEL)) == NULL) {
         printk("ACCOUNT: Out of memory allocating account_tables structure");
         goto error_cleanup;
     }
-    memset(ipt_acc_tables, 0,
+    memset(ipt_acc_tables, 0, 
            ACCOUNT_MAX_TABLES * sizeof(struct ipt_acc_table));
 
-    if ((ipt_acc_handles =
-         kmalloc(ACCOUNT_MAX_HANDLES *
+    if ((ipt_acc_handles = 
+         kmalloc(ACCOUNT_MAX_HANDLES * 
                  sizeof(struct ipt_acc_handle), GFP_KERNEL)) == NULL) {
         printk("ACCOUNT: Out of memory allocating account_handles structure");
         goto error_cleanup;
     }
-    memset(ipt_acc_handles, 0,
+    memset(ipt_acc_handles, 0, 
            ACCOUNT_MAX_HANDLES * sizeof(struct ipt_acc_handle));
 
     /* Allocate one page as temporary storage */
@@ -1080,9 +1071,9 @@
 
     if (ipt_register_target(&ipt_acc_reg))
         goto error_cleanup;
-
+        
     return 0;
-
+        
 error_cleanup:
     if(ipt_acc_tables)
         kfree(ipt_acc_tables);
@@ -1090,7 +1081,7 @@
         kfree(ipt_acc_handles);
     if (ipt_acc_tmpbuf)
         free_page((unsigned long)ipt_acc_tmpbuf);
-
+        
     return -EINVAL;
 }
 




More information about the netfilter-cvslog mailing list